bitget for array (count no. of bits)

Hi everyone,
How to take bitget of an array. Let say:
a = 7;
s = sum(bitget(a,1:8));
will return 3 as there are three bits on in number 7. If I have any array
a = [1 2 7 6];
then how can I do the similar bit count operation for each element in a.

 Accepted Answer

Matt Fig
Matt Fig on 7 Aug 2012
Edited: Matt Fig on 8 Aug 2012
ARRAYFUN might be useful here.
arrayfun(@(x) sum(bitget(x,1:8)),[1 2 7 6])
This is much faster for larger row vectors. D is the number of bits (8 in the above formula):
sum(rem(floor(bsxfun(@times,x',pow2(1-D:0))),2),2);

8 Comments

Thanks Matt. It works.
Could you please tell me if there is any other way to do it which is faster also. I have to run this to compute the time so I want to do it fast.
I hope you can tell me some trick to do it very fast for very large matrix.
I added another method that is faster.
Thanks Matt,
It is working. Last thing, could you please tell me how can I extend this to a matrix instead of an array.
A general method that works in many cases like this, is to first convert your matrix into a vector by using (:), processing the vector, and then reshaping it back into a matrix. Here I used a slightly different algorithm than Matt, but the strategy is the same regardless.
%%Making some random data
x = randi([0 255],[5 5])
D = floor(log2(max(x(:)))) + 1; %Maximum number of bits needed
szX = size(x);
bits = sum(bsxfun(@ge, bsxfun(@mod,x(:)',(2.^(1:D)')) , 2.^(0:D-1)'));
bits = reshape(bits,szX)
Thanks Teja,
in my case my X is uint8 array (matrix). and it returns me the error : ??? Error using ==> bsxfun Mixed integer class inputs are not supported.
I don't want to change my x into double. is it possible to continue with uint8 ??
Thanks Teja,
in my case my X is uint8 array (matrix). and it returns me the error : ??? Error using ==> bsxfun Mixed integer class inputs are not supported.
I don't want to change my x into double. is it possible to continue with uint8 ??
Note carefully that the algorithm Teja gave you will automatically return all bits. I understood you to want to specify the bits to sum up. Either way, whether you specify D or calculate it using
D = floor(log2(max(x(:)))) + 1;
you can simply use reshape like Teja did to work the algorithm on a matrix. As for the uint8 part, there is no need to change your actual matrix to double, just change the copy used by the algorithm. For example:
x = uint8(round(rand(10,20)*255)); % Your matrix: we preserve this.
S = double(x(:)); % Only temporary. Overwritten below.
D = floor(log2(max(S))) + 1; % Or specify D! (As you need.)
S = reshape(sum(rem(floor(bsxfun(@times,S,pow2(1-D:0))),2),2),size(x));
Thanks Matt

Sign in to comment.

More Answers (1)

Oliver Woodford
Oliver Woodford on 22 Nov 2013
I assume from your question that you actually want to do a vectorized bitcount, rather than a vectorized bitget. If that is correct then I suggest you use the bitcount submission on the File Exchange.

Products

Asked:

on 7 Aug 2012

Answered:

on 22 Nov 2013

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!