SCBuergel
SCBuergel

Reputation: 1653

Efficient bit shuffling of vector of binary numbers

I have recorded data containing a vector of bit-sequences, which I would like to re-arrange efficiently. One value in the vector of data could look like this:

bit0, bit1, bit2, ... bit7

I would like to re-arrange this bit-sequence into this order:

bit0, bit7, bit1, bit6, bit2, bit5, bit3, bit4

If I had only one value this would work nicely via:

sum(uint32(bitset(0,1:8,bitget(uint32(X), [1 8 2 7 3 6 4 5]))))

Unfortunately bitset and bitget are not capable of handling vectors of bit-sequences. Since I have a fairly large dataset I am interested in efficient solutions.

Any help would be appreciated, thanks!

Upvotes: 5

Views: 561

Answers (3)

The most efficient way is probably to use bitget and bitset as you did in your question, although you only need an 8-bit integer. Suppose you have a uint8 array X which describes your recorded data (for the example below, X = uint8([169;5]), for no particular reason. We can inspect the bits by creating a useful anonymous function:

>> dispbits = @(W) arrayfun(@(X) disp(bitget(X,1:8)),W)
>> dispbits = 

@(W)arrayfun(@(X)disp(bitget(X,1:8)),W)
>> dispbits(X)
    1    0    0    1    0    1    0    1

    1    0    1    0    0    0    0    0

and suppose you have some pattern pattern according to which you want to reorder the bits stored in this vector of integers:

>> pattern

pattern =

     1     8     2     7     3     6     4     5

You can use arrayfun and find to reorder the bits according to pattern:

Y = arrayfun(@(X) uint8(sum(bitset(uint8(0),find(bitget(X,pattern))))), X)

Y =

   99
   17

We get the desired answer stored efficiently in a vector of 8 bit integers:

>> class(Y)

ans =

uint8

>> dispbits(Y)
    1    1    0    0    0    1    1    0

    1    0    0    0    1    0    0    0

Upvotes: 0

Robert Seifert
Robert Seifert

Reputation: 25232

I don't know if I may get the question wrong, but isn't it just solvable by indexing wrapped into cellfun?

%// example data
BIN{1} = dec2bin(84,8)
BIN{2} = dec2bin(42,8)

%// pattern and reordering
pattern = [1 8 2 7 3 6 4 5];
output = cellfun(@(x) x(pattern), BIN, 'uni', 0)

Or what is the format of you input and desired output?


BIN = 

    '01010100'    '00101010'


output = 

    '00100110'    '00011001'

Upvotes: 1

Daniel
Daniel

Reputation: 36710

dec2bin and bin2dec can process vectors, you can input all numbers at once and permute the matrix:

input=1:23;
pattern = [1 8 2 7 3 6 4 5];
bit=dec2bin(input(:),numel(pattern));
if size(bit,2)>numel(pattern)
    warning('input numbers to large for pattern, leading bits will be cut off')
end
output=bin2dec(bit(:,pattern));

if available, I would use de2bi and bi2de instead.

Upvotes: 3

Related Questions