This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
How do I do multiple assignment in MATLAB?
Is there anything like deal() for normal MATLAB arrays?
I want to put values of a vector in 2 variables, but it doesn't work.
vec = [2 3];
[m n] = vec;
I expected:
m = 2
n = 3
But I got an error.
It's a syntax problem or I can't do that?
There are many ways to assign values of a vector to different variables, but you cannot do it like that.
Easy way:
vec = [ 2 3 ];
m = vec(1);
n = vec(2);
Just another variation using an anonymous function.
vec = [2 3];
tuple = #(x) deal(x(1), x(2))
[m n] = tuple(vec)
Related
This question already has answers here:
Define multiple variables at the same time in MATLAB
(2 answers)
Closed 7 years ago.
I wanna assign values to multiple symbolic variables at the same time.
For example,
syms a b c
% for several reasons, I have to define a, b, c as symbolic variables.
x = [a, b, c];
y = [1, 2, 3];
When I define matrix x and y like above,
I wanna get following answer.
a = 1
b = 2
c = 3
% Assign values to symbolic variables.
Of course, simply I can get this answer by using following code.
[a, b, c] = deal(1, 2, 3);
But I have to use matrix x and y instead of [a, b, c] and (1, 2, 3).
Because actually there are so many symbolic variables in matrix x when I calculate.
So I wanna use matrix.
In this case, if I use matrix x and y
x = deal(y);
The answer is just
x = 1 2 3
But I wanna get the answer,
a = 1
b = 2
c = 3
What should I do to assign values to variables by using matrix x and y?
Please answer my question.
Thank you.
I don't think you should be trying to do this, I am sure there must be some other choices you could make earlier to avoid this problem. But it can be done, probably more nicely than I have done.
syms a b c
x=[a b c]
y=[1 2 3]
%// We want to get the name of the variable from x, and the value from y
arrayfun(#(i) assignin('caller',char(x(i)),y(i)),1:length(x))
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).'));
This question already has answers here:
Element-wise array replication according to a count [duplicate]
(4 answers)
Closed 8 years ago.
I would like to vectorize the creation of the following vector:
For example-
Let A be a vector [5 3 2 1]
And let B be a vector [1 2 3 4]
I would like C to be the vector [1 1 1 1 1 2 2 2 3 3 4]
Meaning- each element i in B is duplicated A(i) times in C.
I haven't found a way to vectorize the creation of this, any ideas?
Thanks in advance!
Ronen
Approach #1
Here's one approach if B doesn't have any zeros -
C = nonzeros(bsxfun(#times,bsxfun(#le,[1:max(A)]',A),B))
Approach #2
A general case solution -
mask = bsxfun(#le,[1:max(A)]',A) %//'
B_ext = bsxfun(#times,mask,B)
C = B_ext(mask)
Approach #3
cumsum based approach and must be pretty efficient one -
idx = [1 cumsum(A(1:end-1))+1] %// indices where each new B values start
C = zeros(sum(A),1) %// storage for output
C(idx) = diff([0 B]) %// put those values, but offseted
C = cumsum(C) %// finally get the output
This question already has answers here:
Get different column in each row
(2 answers)
Closed 8 years ago.
This is an issue i commonly find myself trying to solve. I have the following:
A = [1 2;
3 4;
5 6;
7 8;
9 10];
B = [1,2,1,2,2];
On each row (i) of A, i want to return the value of the column specified in B(i). I currently solve the problem using a loop:
result = zeros(size(B));
for i=1:length(B)
result(i) = A(i,B(i));
end
Where result = [1 4 5 8 10]
But this seems inelegant to me. Is there a one-liner?
You could get the correct linear indices using sub2ind:
rows = (1:numel(B))'
cols = B(:);
ind = sub2ind(size(A), rows, cols);
A(ind)
or in a one-liner
A(sub2ind(size(A), (1:numel(B))', B(:)))
or a more elegant method (taken from the 2nd answer to the duplicate question)
diag(A(:,B))
I can't tell you about performance though...
This question already has an answer here:
effective way of transformation from 2D to 1D vector
(1 answer)
Closed 9 years ago.
I would like to use the (:) operator and the transpose at the same time. Is this possible? Basically I would like to do something like
output = A'(:)
except that this does not work. Does anyone know a workaround?
Thanks!
Immo
The : operator in this case is shorthand for reshaping the matrix into a vector. You can work around the limitation of where you use the operator by using the reshape function explicitly:
octave> A = [1 2;3 4]
A =
1 2
3 4
octave> B=A'
B =
1 3
2 4
octave> C=B(:)
C =
1
2
3
4
octave> D=reshape(A',[],1) #% vectorize transpose in one line
D =
1
2
3
4
Try with:
output = reshape( A.', numel(A), 1);
>> A = rand(4,3);
>> output = reshape( A.', numel(A), 1);
A =
0.447213 0.046896 0.679087
0.903294 0.768745 0.651481
0.701071 0.122534 0.611390
0.535844 0.478595 0.772810
output =
0.447213
0.046896
0.679087
0.903294
0.768745
0.651481
0.701071
0.122534
0.611390
0.535844
0.478595
0.772810
Beware that reshape reads the matrices accessing along columns so you may not need to transpose the matrix A.
Also, remember that the operator ' is the hermitian operator, namely, conjugated of the transposed, whereas .' is simply transposition, which you could also get by transpose(A).
You may want to do everything in a single line without re-typing all every time. One solution is creating a function handles as boop:
>> boop = #(x) reshape( transpose(x), numel(x), 1)
>> output = boop(A)
output =
0.447213
0.046896
0.679087
0.903294
0.768745
0.651481
0.701071
0.122534
0.611390
0.535844
0.478595
0.772810