matlab vector addition like multiplication, without for loop - matlab

Normally when one adds two vectors this is what happens
[1 4] + [2 5] = [3 9]
I want it to do this:
[1 4] + [2 5] = 3 6
6 9
So basically addition like how multiplication happens. But without using for-loops.
Thanks so much!

This is one of the poster cases for using bsxfun
x = [1 4];
y = [2 5];
bsxfun(#plus,x,y')

One way to do it is with meshgrid.
x = [1 4];
y = [2 5];
[a, b] = meshgrid(y,x);
a + b

Related

Matlab, combinations of all cells [duplicate]

This question already has answers here:
Generate a matrix containing all combinations of elements taken from n vectors
(4 answers)
Closed 7 years ago.
I need to combine all data of n (random) arrays with different lengths.
ex:
a=[1 3 2 7 8], b=[2 5 3 9] and c=[5 6] and maybe we have d, e, f etc....
I need the combination of all elements like:
M={[1 2 5], [1 2 6], [1 5 5], [1 5 6], [1 3 5], [1 3 6] ....}.
Solution for 3 arrays:
[A,B,C] = meshgrid(a, b, c);
M = [A(:), B(:), C(:)];
Solution for n arrays iterating over the short dimension n:
a=[1 3 2 7 8];
b=[2 5 3 9];
c=[5 6];
d=[1 3 5];
arrays = { a, b, c, d };
M = a';
for i = 2:length(arrays)
A1 = M;
A2 = arrays{i}';
[i1, i2] = meshgrid(1:length(A1), 1:length(A2));
M = [A1(i1(:), :) A2(i2(:))];
end

Got confused with a vector indexed by a matrix, in Matlab

The following codes runs in Matlab:
a = [1 2 3 4]
b = [ 1 2 3; 1 2 3; 1 2 3]
a(b)
The result of a(b) is a matrix:
[ 1 2 3; 1 2 3; 1 2 3]
Can anyone explain what happened here? Why a vector can be indexed by a matrix, how to interpret the result?
That's a very standard MATLAB operation that you're doing. When you have a vector or a matrix, you can provide another vector or matrix in order to access specific values. Accessing values in MATLAB is not just limited to single indices (i.e. A(1), A(2) and so on).
For example, what you have there is a vector of a = [1 2 3 4]. When you try to use b to access the vector, what you are essentially doing is a lookup. The output is basically the same size as b, and what you are doing is creating a matrix where there are 3 rows, and each element accesses the first, second and third element. Not only can you do this for a vector, but you can do this for a matrix as well.
Bear in mind that when you're doing this for a matrix, you access the elements in column major format. For example, supposing we had this matrix:
A = [1 2
3 4
5 6
7 8]
A(1) would be 1, A(2) would be 3, A(3) would be 5 and so on. You would start with the first column, and increasing indices will traverse down the first column. Once you hit the 5th index, it skips over to the next column. So A(5) would be 2, A(6) would be 4 and so on.
Here are some examples to further your understanding. Let's define a matrix A such that:
A = [5 1 3
7 8 0
4 6 2]
Here is some MATLAB code to strengthen your understanding for this kind of indexing:
A = [5 1 3; 7 8 0; 4 6 2]; % 3 x 3 matrix
B = [1 2 3 4];
C = A(B); % C should give [5 7 4 1]
D = [5 6 7; 1 2 3; 4 5 6];
E = A(D); % E should give [8 6 3; 5 7 4; 1 8 6]
F = [9 8; 7 6; 1 2];
G = A(F); % G should give [2 0; 3 6; 5 7]
As such, the output when you access elements this way is whatever the size of the vector or matrix that you specify as the argument.
In order to be complete, let's do this for a vector:
V = [-1 9 7 3 0 5]; % A 6 x 1 vector
B = [1 2 3 4];
C = V(B); % C should give [-1 9 7 3]
D = [1 3 5 2];
E = V(D); % E should give [-1 7 0 9]
F = [1 2; 4 5; 6 3];
G = V(F); % G should give [-1 9; 3 0; 5 7]
NB: You have to make sure that you are not providing indexes that would make the accessing out of bounds. For example if you tried to specify the index of 5 in your example, it would give you an error. Also, if you tried anything bigger than 9 in my example, it would also give you an error. There are 9 elements in that 3 x 3 matrix, so specifying a column major index of anything bigger than 9 will give you an out of bounds error.
Notice that the return value of a(b) is the same size as b.
a(b) simply takes each element of b, call it b(i,j), as an index and returns the outputs a(b(i,j)) as a matrix the same size as b. You should play around with other examples to get a more intuitive feel for this:
b = [4 4 4; 4 4 4];
a(b) % Will return [4 4 4; 4 4 4]
c = [5; 5];
a(c) % Will error as 5 is out of a's index range

Reshape 3d matrix in z direction

we have a = [1 2; 3 4]; and b = [5 6;7 8]; and z = cat(3,a,b). I want to vectorize the 3d matrix so the reresult would be c = [1 5; 2 6; 3 7; 4 8 ]? I know it is related to reshape but I can not find the way:)
Thanks.
If you need to go via z:
c = reshape(permute(z,[2 1 3]),[],2)
Otherwise,
c = [reshape(a',[],1),reshape(b',[],1)];
reshape(permute(z,[2 1 3]), 4, 2)

Find the minimum positive difference between elements in vector

A = [1 3 5 8]
B = [1 2 3 4 5 6 7 8]
I would like to create a vector C which returns the rownumber of the element in vector A with the smallest non-negative difference to each element in vector B.
So, given the example above, it should return:
C = [1 2 2 3 3 4 4 4]
I'm sure there are many ways to do this. Here's one:
A = [1 3 5 8]
B = [1 2 3 4 5 6 7 8]
%create matrices of the values to subtract
[a,b] = meshgrid(A,B);
%subtract
aLessB = a-b;
%make sure we don't use the negative values
aLessB(aLessB < 0) = Inf;
%sort the subtracted matrix
[dum, idx] = sort(aLessB, 2, 'ascend');
idx(:,1) is the solution you are looking for.
An alternative solution:
D = bsxfun(#minus, A', B);
D(D < 0) = Inf;
[~, C] = min(D, [], 1);

Changing multiple elements (of known coordinates) of a matrix without a for loop

I have a matrix say
Z = [1 2 3;
4 5 6;
7 8 9]
I have to change its values, say at positions (2,2) and (3,1), to some specified value. I have two matrices rowNos and colNos which contain these positions:
rowNos = [2, 3]
colNos = [2, 1]
Let's say I want to change the value of elements at these positions to 0.
How can I do it without using for loop?
Use sub2ind, it'll convert your sub-indices to linear indices, which is a number pointing at one exact spot in the matrix (more info).
Z = [ 1 2 3 ; 4 5 6 ; 7 8 9];
rowNos = [2, 3];
colNos = [2, 1];
lin_idcs = sub2ind(size(Z), rowNos, colNos)
If you want to operate on all elements on a specific row and column (elements in higher dimensions that is), you can also address them using linear indexing. It only becomes a bit trickier of calculating them:
Z = reshape(1:4*4*3,[4 4 3]);
rowNos = [2, 3];
colNos = [2, 1];
siz = size(Z);
lin_idcs = sub2ind(siz, rowNos, colNos,ones(size(rowNos))); % just the first element of the remaining dimensions
lin_idcs_all = bsxfun(#plus,lin_idcs',prod(siz(1:2))*(0:prod(siz(3:end))-1)); % all of them
lin_idcs_all = lin_idcs_all(:);
Z(lin_idcs_all) = 0;
experiment a bit with sub2ind, and go through my code step-by-step to understand it.
It would've been easier if it was the first dimension you wanted to take all elements off, then you could have used the colon operator :
Z = reshape(1:3*4*4,[3 4 4]);
rowNos = [2, 3];
colNos = [2, 1];
siz = size(Z);
lin_idcs = sub2ind(siz(2:end),rowNos,colNos);
Z(:,lin_idcs) = 0;
Use sub2ind with multiple entries for rows and columns
Z(sub2ind(size(Z), rowNos, colNos))=0
Example:
Z = [1 2 3;
4 5 6;
7 8 9];
rowNos = [2, 3];
colNos = [2, 1];
Z(sub2ind(size(Z), rowNos, colNos))=0
Z =
1 2 3
4 0 6
0 8 9
You would like to do this
z(rowNos, colNos)
but you can not - MATLAB does a Cartesian product of the indices. You can do this trick
idx=(colNos-1)*size(z, 1)+rowNos;
z(idx)=0
Flatten the z-matrix and access it through a linear index, which is a combination of rowNos and colNos. Remember that MATLAB flattens the matrix by columns (column-based matrix storage).