Given two 100x3 matrix A and B. How do I multiple them in Matlab without loop such that the output matrix is (sorry for the bad format).
a11*b11 a12*b12 a13*b13
a21*b21 a22*b22 a23*b23
...
If we say output matrix is C, then: C = A.*B
use a dot for element wise multiplication A.*B
Related
I am working on matlab with a matrix. I would like to reproduce this matrix and apply sum for elements in rows.
I have two vectors defined by this code:
unitsvector=1:5;
reordervector=1:3;
Then, I create an empty matrix to store the values:
resultvec=zeros(size(unitsvector,2)*size(reordervector,2),3);
Finally, here is the loop I use but it is not working:
for a=1:length(resultvec)
for b=reordervector
for c=unitsvector
resultvec(a,1)=b;
resultvec(a,2)=c;
resultvec(a,3)=b+c;
end
end
end
How could I reproduce this matrix in matlab. Thanks for your help.
You can use meshgrid for this without a for loop.
[a,b] = meshgrid(1:5,1:3);
M = [a(:) b(:)];
M(:,3) = sum(M,2); % Create third column by summing first two
Why are you looping at all? sum actually has vector support; a simple resultvec = [a(:,1),a(:,2),sum(a,2)] would work.
As to your code: of course it doesn't work. What do you expect to be the contents of a? You create a as a loop index, which runs over the range 1:length(resultvec). Ergo, within each loop iteration a is a scalar. You try to call it like it is a three-element vector. Nor do you define b and c. This might be possible in R, judging where you're coming from, but not in MATLAB.
I have a code like this:
A = [sparse(round(rand(4,4)))];
B = [sparse(round(rand(1,4)))];
C = [bsxfun(#minus,A(1,:),B); bsxfun(#minus,A(2,:),B); bsxfun(#minus,A(3,:),B); bsxfun(#minus,A(4,:),B);]
Is is possible to somehow define C this way for a large amount rows (so that I cannot physically print the command this way) WITHOUT a loop (because a loop would take an excessively long time)?
One another options:
If you prefer to keep a sparse matrix:
C = A - repmat(B,size(A,1),1); %but slower than the bsxfun version.
If you pass a matrix and a row vector to bsxfun, it will automatically apply the vector to all rows of the matrix, so just use:
C = bsxfun(#minus, A, B);
This will substract the row vector B to all rows of matrix A, no matter how many rows you have.
EDIT: If you have two matrices instead of a Matrix and a Vector, you can either use permutations or arrayfun. Take a look at:
Multiply all columns of one matrix by another matrix with bsxfun
I attempted to use the solution from this post: Multiply a 3D matrix with a 2D matrix, to vectorize the multiplication of a one dimensional with a three dimensional, but to no avail. Any help would be greatly appreciated!
for s = 1: s_length
for a = 1: a_length
for g = g_length
two_dim(s,a) = two_dim(s,a) + one_dim(g) * three_dim(s,a,g);
end
end
end
I think this does what you want.
two_dim = reshape(three_dim, [], size(three_dim,3))*one_dim(:);
two_dim = reshape(two_dim, size(three_dim,1), size(three_dim,2));
This works as follows:
First line reshapes your 3D array into a matrix, collapsing the first two dimensions into one. That way the operation you want is standard multiplication of the resulting matrix times a column vector.
Second line reshapes the result into matrix shape.
mtimes does not work with inputs with dimension larger than 2, so you have to find a way to do the multiplication by yourself. The solution of Luis Mendo is a nice solution; here is another one using bsxfun:
two_dim = two_dim + squeeze(sum(bsxfun(#times, three_dim, reshape(one_dim,[1 1 g_length])),3));
Here is how it works:
reshape makes the vector one_dim looking like a 3D array. This must be done because the multiplication between the vector and the 3D array is performed along the 3rd dimension, so Matlab need a hint on sizes.
bsxfun perfoms the element-wise multiplcation, so the result must be sumed up along the 3rd dimension (and squeezed to be compliant with a 2D matrix format)
I'm trying to figure out if there's a native way of obtaining a certain kind of element-wise product of two matrices in Matlab.
The product that I'm looking for takes two matrices, A and B say, and returns there product C, whose elements are given by
C(i,j,k) = A(i,j)*B(j,k)
Naturally, the number of columns of A is assumed be the same as the number of rows of B.
Right now, I'm using the following for-loop (assuming size(A,2)==size(B,1) is true). First, I initialize C:
C = zeros(size(A,1), size(A,2), size(B,2));
And then I perform element-wise multiplication via:
for i=1:size(A,2)
C(:,i,:) = A(:,i)*B(i,:);
end
So, my question is: Is there a native way to this sort of thing in Matlab?
You need to "shift" the first two dimensions of B into second and third dimensions respectively with permute and then use bsxfun with #times option to operate on A and the shifted dimension version of B -
C = bsxfun(#times,A,permute(B,[3 1 2]))
I want to sum all elements of matrix in Matlab. If I had a matrix called A, then I can sum all elements by calling
sum(A(:));
But I would like to sum elements returning from a function like this:
sum(gammaln(A)) % where gammaln is the logarithm of gamma function
Of course I can do this in two steps:
B = gammaln(A);
sum(B(:));
But here I create a B matrix, which I don't need at all. And also I can do it this way:
sum(sum(gammaln(A)))
But, the number of sum's will be equal to the dimension of my matrix. It looks ugly, and the matrix dimension may change.
I'm curious if there is any way of doing this.
use reshape instead of (:) operator:
sum(reshape(gammaln(A),[],1))