Convert array elements to single number [duplicate] - matlab

This question already has answers here:
Return vector elements as a single integer
(2 answers)
Closed 8 years ago.
I have an array A=[1,0,1,1,1,0]. I want to convert it to a decimal number B = 101110. I have tried all the conversion functions, but couldn't find an appropriate solution.

This can be done quite simply this way:
B = sum(A.*10.^(numel(A)-1:-1:0))
B =
101110
What it does is take each number in A and multiply it with 10^n where n corresponds to the value appropriated with that place in the vector. By taking the sum of this new vector you'll get your answer.
It's the equivalent of:
1*10^5 + 0*10^4 + 1*10^3 + 1*10^2 + 1*10^1 + 0*10^0
As Luis commented, it can also be done as
B = 10.^(numel(A)-1:-1:0) * A(:);

you can make a function
function decimal = array2dec(A)
nA = length(A);
decimal = 0;
for i = 1:nA
decimal = decimal + A(i)*10^(nA-i);
end
save this.
>> A = [1,0,1,1,1,0];
>> dec = array2dec(A)
>> dec =
>> 101110

Yet another approach. Probably not very fast, though:
base2dec(A+'0',10)

Related

A faster way to convert a large array from binary to decimal in Matlab?

I have an array which consists of around 35 million (M) rows, each of which contain a 32 digit binary number. The idea of this portion of the code is to take each 32 digit row and convert it back to 3 separate decimal numbers, based on the their position within the binary digit. For instance, the first 8 digits are converted to the number 'yval' the next 8 are converted to 'xval' and the next 12 are converted to 'binval' This is currently in a for loop and runs around 35 million times - once for each row. It then outputs the decimal numbers into 'lidarcube'. Basically, Im wondering if there is a quicker way to do this? It currently takes around an hour to process and I would ideally like to cut this down. Apologies if this is poorly explained, im new to Matlab and coding in general.
for count = 1:M
yval = 1+bi2de(no_frame(count,1:8));
xval = 1+bi2de(no_frame(count,9:16));
binval = 1+bi2de(no_frame(count,17:28));
lidarcube(xval,yval,binval) = lidarcube(xval,yval,binval)+1;
end
save('test.mat','lidarcube')
For an 8 digit binary array, the decimal equivalent can be calculated by multiplying by the corresponding powers of 2 and summing the total. This can be easily implemented as a vectorised operation.
% generate some sample data
rng(0);
no_frame = randi([0,1],3,32); % 3 rows, 32 cols, all zero or one
% Define custom binary 2 decimal conversion function
fb2d = #(x) sum( x .* (2.^((size(x,2)-1):-1:0)), 2 );
% Calculate the decimal values in column blocks of 8
yval = fb2d( no_frame(:,1:8) );
xval = fb2d( no_frame(:,9:16) );
binval = fb2d( no_frame(:,17:28) );
The remaining loop is probably not too slow as long as lidarcube is preallocated.
for count = 1:M
i_yval = 1 + yval(count);
i_xval = 1 + xval(count);
i_binval = 1 + binval(count);
lidarcube(i_xval,i_yval,i_binval) = lidarcube(i_xval,i_yval,i_binval) + 1;
end

Multiplication in matlab [duplicate]

This question already has an answer here:
Displaying rational numbers in Matlab
(1 answer)
Closed 1 year ago.
4.082*2118
When I write this multiplication in MATLAB software, I get this answer: 1.705868e+04
but I want to show the answer like this: 17058.68
what is my wrong?
In the Matlab console, type format rational. Example:
>> 4.082 * 2118
ans =
8.6457e+03
>> format rational
>> 4.082 * 2118
ans =
319890/37
You can also use the rat and rats functions. The rat function can also give you the numerator and the denominator as numbers:
>> [num, denom] = rat(4.082 * 2118)
num =
319890
denom =
37
Note that the result is only an approximation. You can improve it by decreasing the tolerance:
>> [num, denom] = rat(4.082 * 2118, 0)
num =
2161419
denom =
250

how to pass parameters by reference in matlab function

i'm a beginner in matlab and i want to calculate the sum of product of every possible combination of elements of a (3*n) matrix that are picked from different row.
for example if the matrix is x = [1 2 3 , 4 5 6] i want the result of
D = 1*4 + 1*5 + 1*6 + 2*4 + 2*5 + 2*6 + 3*4 + 3*5 + 3*6.
I wrote the following recursive code but i'm having problem with passing a variable by reference.
function combination(n,A,x) % n= number of rows ,A= empty array, x = the matrix
if n == 0
D = D + prod(A);
else
for i = 1:1:3
A = [A x(n,i)];
combination(n-1,A,x);
if length(A)>=1
A = A(1:length(A)-1);
end
end
end
end
i need the D parameter but when i declare D as global it doesn't help.
is there anyway in matlab that i could pass D by reference in function and get the result at the end?
thanks in advance.
sorry for my english.
Can you just use prod(sum(x,2))? I think if you rearrange the terms in your sum, you'll see that you can just multiply the sums of your rows together and you'll get the same thing. (But perhaps I've misunderstood exactly what you're looking for).
For example:
>> x=[1 2 3 ; 4 5 6; 7,8,9]
x =
1 2 3
4 5 6
7 8 9
>> prod(sum(x,2))
ans =
2160
>> 1*4*7 + 1*4*8 + 1*4*9 + 1*5*7 + 1*5*8 + 1*5*9 + 1*6*7 + 1*6*8 + 1*6*9 + 2*4*7 + 2*4*8 + 2*4*9 + 2*5*7 + 2*5*8 + 2*5*9 + 2*6*7 + 2*6*8 + 2*6*9 + 3*4*7 + 3*4*8 + 3*4*9 + 3*5*7 + 3*5*8 + 3*5*9 + 3*6*7 + 3*6*8 + 3*6*9
ans =
2160
If you really need to do this recursively, using a combinatory approach, you should be able to just pass in D as an input and also return it as an output of your function, something like this:
function D = combination(n,A,x, D) % n= number of rows ,A= empty array, x = the matrix
if n == 0
D = D + prod(A);
else
for i = 1:1:3
A = [A x(n,i)];
D = combination(n-1,A,x, D);
if length(A)>=1
A = A(1:length(A)-1);
end
end
end
end
and then call it initially with D equal to zero.
Don't worry about passing by reference here. MATLAB doesn't have pass by reference (it has variables that have reference semantics, but that's a different thing), but it uses copy-on-write, and has special optimizations for calculations that can be done in-place, as your calculation with D can here.
Declaring it as global does the job, however, you should pass it as input, and return it as output.
MATLAB will take care of not making a copy if your code does not need a copy of it.
If you write in the function definition:
function D = combination(n,A,x,D)
D = D + something
end
your function can be called by:
output = combination(n_in,A_in,x_in
the recursion follows the same so instead of calling
combination(n-1, A,x)
you write
D = combination(n-1,A,x,D)
and go on in your code.
I hope this helps you, and maybe there is a Matlab own function that can handle this task already but I am not sure.

reflecting random walk in matlab? [duplicate]

This question already has answers here:
Matlab -- random walk with boundaries, vectorized
(2 answers)
Closed 8 years ago.
I have a array of 10 vectors 'x' with as below (for simulating 1D random walk):
r=rand(10,1000);
r(r>.5)=1;
r(r<=.5)=-1;
x=cumsum(r);
The image of the one vector will be like:
If I consider 2 values in the sequence , say +10 and -10, then I would like to reflect the sequence 'x' when it reaches those values. How to achieve this?
Before answering your question, a should point that your code is broken. By default cumsum accumulate data across first dimension, to change this behavior you should specify dim parameter:
x = cumsum(r,2);
And, answering your question, you could simply invert all data above threshold:
threshold = 10;
nsteps = ceil( max(abs(x(:))) / (2*threshold) - 0.5 );
for ii = 1:nsteps
ind = abs(x) > 10;
x(ind) = 20 * sign(x(ind)) - x(ind);
end

Generate random number between 1 and 10 with the exception of a single number in matlab

I would like to generate a random number between 1 and 10 using for example randi([1,10]) but I would like to exclude a single number, say 7 - this number would always change and be specified in a variable called b.
Is that possible to do somehow?
Use randsample. For instance, to generate a number between 1 and 10, excluding 7, do the following:
b = 7;
x = randsample(setdiff(1:10, b), 1);
Here setdiff is used to exclude the value of b from the vector 1:10.
If you don't have the Statistics Toolbox installed, you won't be able to use randsample, so use rand:
v = setdiff(1:10, b);
x = v(ceil(numel(v) * rand));
For those without the statistics toolbox:
b = 7;
pop = 1:10;
pop(b) = [];
then
pop(randperm(9,1))
or for n random integers from the population:
pop(randi(numel(pop), 1, n))
As #EitanT mentioned, you can use randsample to do so, but I think that doing so in a simpler manner should do for you:
>> b = 7;
>> randsample([1:b-1,b+1:10],1)
This simply samples a random value from the array [1:b-1,b+1:10] which would here be
1 2 3 4 5 6 8 9 10
Or similarly, if the `randsample' function is unavailable as #EitanT had mentioned,
v = [1:b-1,b+1:10];
x = v(ceil(numel(v) * rand));