2

I need to create Boolean/Binary arrays with rows representing the binary form of each number in given a range. Each column hold values for a given bit position. The range is determined by the bit-width and binary encoding scheme. Then I need to count the number of cells in a column that do not match the preceding cell.

I believe the counting process is simply XORing the array with itself shifted down one row. The sum of each column in the XOR result is my transition count.

I need to do this for each combination of [signed, unsigned] values encoded as [hexadecimal, octal, decimal]. Mismatches between the encoding scheme and available bits results in unusable bits.
e.g. A 4-bit unsigned octal array would still only have 8 rows. However, if it is signed then that 4th bit is used for sign and the array is the full 16 rows.

The ultimate goal is to create labeled set of summary n-grams for the number of transitions at each bit position for various bit widths, encoding, and use of sign. The summary n-gram for example 1 would be {3-bit, octal, unsigned, [1, 3, 7]}. The summary n-gram for example 3 is {4-bit, octal, signed, [1, 2, 6, 13]}. Example 4 is {4-bit, hexadecimal, signed, [1, 2, 6, 13]}.

Examples:
1) 8x3 Binary array of all possible 3-bit unsigned octal values:
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1

2) 8x4 Binary array of all possible 4-bit unsigned octal values:
Same as #1 except with an additional leftmost column of all zeros

3) 16x4 Binary array of all possible 4-bit signed octal values:
Note: It's ok to double count zero (-0 and +0) 1 1 1 1
1 1 1 0
1 1 0 1
1 1 0 0
1 0 1 1
1 0 1 0
1 0 0 1
1 0 0 0
0 0 0 0
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
0 1 0 1
0 1 1 0
0 1 1 1

4) 16x4 Binary array of all possible 4-bit signed hexadecimal values:
Same as #3

1 Answer 1

3

You can use np.unpackbits, for example

np.unpackbits(np.arange(8).astype(np.uint8)[:, None], axis = 1)

Output:

array([[0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 1],
       [0, 0, 0, 0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0, 0, 1, 1],
       [0, 0, 0, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0, 1, 0, 1],
       [0, 0, 0, 0, 0, 1, 1, 0],
       [0, 0, 0, 0, 0, 1, 1, 1]], dtype=uint8)

Slice off unwanted zeros:

np.unpackbits(np.arange(8).astype(np.uint8)[:, None], axis = 1)[:, -3:]

Result:

array([[0, 0, 0],
       [0, 0, 1],
       [0, 1, 0],
       [0, 1, 1],
       [1, 0, 0],
       [1, 0, 1],
       [1, 1, 0],
       [1, 1, 1]], dtype=uint8)

Use modulo for signed values:

np.unpackbits((np.arange(-4, 4)%8).astype(np.uint8)[:, None], axis = 1)[:, -3:]

Or view casting from signed to unsigned:

np.unpackbits(np.arange(-4, 4).astype(np.int8).view(np.uint8)[:, None], axis = 1)[:, -3:]

Result:

array([[1, 0, 0],
       [1, 0, 1],
       [1, 1, 0],
       [1, 1, 1],
       [0, 0, 0],
       [0, 0, 1],
       [0, 1, 0],
       [0, 1, 1]], dtype=uint8)

Transition count:

x = np.unpackbits(np.arange(-4, 4).astype(np.int8).view(np.uint8)[:, None], axis = 1)[:, -3:]
np.abs(np.diff(x.view(np.int8), axis=0)).sum(axis=1)

Result:

array([1, 2, 1, 3, 1, 2, 1])

Or using your xor method:

(x[1:]^x[:-1]).sum(axis=1)

Result:

array([1, 2, 1, 3, 1, 2, 1], dtype=uint64)
Sign up to request clarification or add additional context in comments.

1 Comment

Nice. I didn't know about unpack bits.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.