How to convert array of bits to integer in Matlab? [duplicate] - matlab

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Converting binary to decimal without using loop
I'm looking for the simplest and fastest solution. I tried documentation but could find anything.
I have an array of bits like [0, 1, 1, 1] and I want to convert it to simple int number 7. I get this array with bitget(x, 1:3), where x is an integer.

Just as a pedagogical alternative to #Edwin and #Azim's solution's (which are better for production), try
b = [1 0 0 1]; % or whatever
sum(b.*(2.^[length(b)-1 : -1 : 0])) % => 9 for the above
We create the basis elements with 2.^[length(b)-1 : -1 : 0] = [8 4 2 1], multiply each element by the binary value to get [8 0 0 1], then sum to get the final answer.

#Edwin's answer uses binvec2dec which is part of the Data Acquisition Toolbox. This toobox is an additional toolbox (developed by Mathworks) but not part of the base MATLAB package.
Here is a solution that does not depend on this toolbox.
Use num2str to convert the binary array to a string
str=num2str(bin_vec);
use bin2dec to get decimal value
dec_num=bin2dec(str);

A little rusty on Matlab, but this should work.
% This assumes you're using a vector of dimension 1 x n (i.e. horizontal vector)
% Otherwise, use flipud instead of fliplr
function [dec_num] = convert(bin_vec)
bin_vec = fliplr(bin_vec);
dec_num = binvec2dec(bin_vec);
% EDIT: This should still work
num = convert(bitget(x, 1:3);
For future reference, if this is about homework, use the homework tag.
binvec2dec Documentation
fliplr Documentation
flipud Documentation

Related

matlab: filling matrix diagonalwise [duplicate]

This question already has answers here:
adding values to diagonals of matrix using element-wise addition in matlab
(3 answers)
Closed 7 years ago.
I have an (2n-1)-by-1 vector with certain values and I want to obtain an n-n matrix with the diagonals filled using the same value.
Eg. if I have
a = [1; 2; 3; 4; 5];
I want to obtain
A = [[3 4 5];[2 3 4];[1 2 3]]
= 3 4 5
2 3 4
1 2 3
My matrix dimensions are a lot bigger so I'd want this as efficient as possible. I already found following solutions:
n = 3;
A = toeplitz(a);
A = A(1:n,end-n+1:end)
and
A = a(n)*eye(n);
for j=1:n-1
A(1+j:n+1:end-j*n) = a(n-j);
A(j*n+1:n+1:end) = a(n+j);
end
I wonder if there are more efficient ways to obtain this result, keeping in mind that I am working with huge matrices and really need the speed.
ix=bsxfun(#plus,[1:n],[n-1:-1:0]'); %generate indices
A=a(ix);
or
A=hankel(a) %might be faster than toeplitz because half the matrix is zero
A(n:-1:1,1:n)
here is what hankel does internally (at least in ML R2013a), adapted to this problem:
c=[1:n];
r=[n-1:-1:0]';
idx=c(ones(n,1),:)+r(:,ones(n,1));
A=a(ix);
I guess the bsxfun solution and what thewaywewalk supposed is the fastest (it's basically the same)
Go with:
n = (numel(a)+1)/2;
A = a(bsxfun(#minus, n+1:n+n, (1:n).'));

frequency of each vector value in another vector matlab

I need to calculate the frequency of each value in another vector in MATLAB.
I can use something like
for i=1:length(pdata)
gt(i)=length(find(pf_test(:,1)==pdata(i,1)));
end
But I prefer not to use loop because my dataset is quite large. Is there anything like histc (which is used to find the frequency of values in one vector) to find the frequency of one vector value in another vector?
If your values are only integers, you could do the following:
range = min(pf_test):max(pf_test);
count = histc(pf_test,range);
gt = count(ismember(range,a));
gt(~ismember(unique(a),b)) = 0;
If you can't guarantee that the values are integers, it's a bit more complicated. One possible method of it would be the following:
%restrict yourself to values that appear in the second vector
filter = ismember(pf_test,pdata);
% sort your first vector (ignore this if it is already sorted)
spf_test = sort(pf_test);
% Find the first and last occurrence of each element
[~,last] = unique(spf_test(filter));
[~,first] = unique(spf_test(filter),'first');
% Initialise gt
gt = zeros(length(pf_test));
% Fill gt
gt(filter) = (last-first)+1;
EDIT: Note that I may have got the vectors the wrong way around - if this doesn't work as expected, switch pf_test and pdata. It wasn't immediately clear to me which was which.
You mention histc. Why are you not using it (in its version with two input parameters)?
>> pdata = [1 1 3 2 3 1 4 4 5];
>> pf_test = 1:6;
>> histc(pdata,pf_test)
ans =
3 1 2 2 1 0

Statistical error computing Matlab

I have two vectors of values and I want to compare them statistically. For simplicity assume A = [2 3 5 10 15] and B = [2.5 3.1 4.8 10 18]. I want to compute the standard deviation, the root mean square error (RMSE), the mean, and present conveniently, maybe as histogram. Can you please help me how to do it so that I understand? I know question is probably simple, but I am new into this. Many thanks!
edited:
This is how I wanted to implement RMSE.
dt = 1;
for k=1:numel(A)
err(k)=sqrt(sum(A(1,1:k)-B(1,1:k))^2/k);
t(k) = dt*k;
end
However it gives me bigger values than I expect, since e.g. 3 and 3.1 differ only in 0.1.
This is how I calculate error between reference value of each cycle with corresponding estimated in that cycle.
Can you tell me, am I doing right, or what's wrong?
abs_err = A-B;
The way you are looping through the vectors is not element by element but rather by increasing the vector length, that is, you are comparing the following at each iteration:
A(1,1:k) B(1,1:k)
-------- --------
k=1 [2] [2.5]
=2 [2 3] [2.5 3.1]
=3 [2 3 5] [2.5 3.1 4.8]
....
At no point do you compare only 2 and 2.1!
Assuming A and B are vectors of identical length (and both are either column or row vectors), then you want functions std(A-B), mean(A-B), and if you look in matlab exchange, you will find a user-contributed rmse(A-B) but you can also compute the RMSE as sqrt(mean((A-B).^2)). As for displaying a histogram, try hist(A-B).
In your case:
dt = 1;
for k=1:numel(A)
stdab(k) = std(A(1,1:k)-B(1,1:k));
meanab(k) = mean(A(1,1:k)-B(1,1:k));
err(k)=sqrt(mean((A(1,1:k)-B(1,1:k)).^2));
t(k) = dt*k;
end
You can also include hist(A(1,1:k)-B(1,1:k)) in the loop if you want to compute histograms for every vector pair difference A(1,1:k)-B(1,1:k).

Hamming weight for a list of integers in Matlab [duplicate]

This question already has answers here:
Calculating Hamming weight efficiently in matlab
(9 answers)
Closed 9 years ago.
Quite a simple problem: I have a list of integers, e.g.,
a = [7 8]
Now I want to have a seperate list, that contains the Hamming Weight (that is the
number of 1 bits in the binary represenation) for each of the integers in the list. That means the result for the integer list above should look as follows:
res = [3 1]
Anyone an idea how I could do this quickly?
This is a little hacky, but it works:
res = sum( dec2bin(a).' == '1' );
It converts a to binary representation, looks at how many characters in that representation are '1', and sums up those numbers.
#% Quickly for a few or quickly for millions?
#% A quick method for a 32 bit int requires a 16 bit look-up table
#% Ideally the table is created once and passed to the function for usage
#% vectorized
vt=randi(2^32,[4096*4096,1])-1; #% input vector vt
num_ones=uint8(zeros(65536,1));
for i=0:65535
num_ones(i+1)=length( find( bitget( i, 1:32 ) ) ) ;
end % 0.43 sec to create table
v=num_ones(mod(vt,65536)+1)+num_ones(floor(vt/65536)+1); #% 0.85 sec
% dec2bin is 1000 times slower

Efficient way of finding average difference between elements in array

Hope title isn't confusing. It's simple to show by example. I have a row vector like so: [1 5 6]. I want to find the average difference between each element. The differences in this example are 4 and 1 so the average is 2.5. This is a small example. My row vectors might be very large. I'm new to MatLab so is there some efficient way of using MATLAB's efficient matrix/array manipulation to do this nicely?
There is a similar question on SOF already but this question is specifically for MATLAB!
Thanks :)
EDIT: As queried by #gnovice, I wanted the absolute difference.
Simple solution using diff and mean
aveDiff = mean(diff(myVector)) %#(1)
Example
>> v=[1 5 6]
v =
1 5 6
>> mean(diff(v))
ans =
2.5000
This works but #Jonas' answer is the correct solution.
Edit
From #gnovice, #vivid-colours and #sevenless comments.
The mean of the absolute value of the difference can be found by inserting abs into (1)
aveDiff = mean(abs(diff(myVector))) %#(2)
If you have an array array, then the average difference is
(array(end) - array(1))/(length(array)-1)
because diff(array), where array = [a b c d], is [b-a c-b d-c]. The average of that is (b-a+c-b+d-c)/3, which simplifies to (d-a)/3.
In your example
array = [1 5 6];
(array(end)-array(1))/2
ans =
2.5
If X is your vector, you can do
mean( X(2:end) - X(1:end-1) )