MATLAB: element-wise multiplication of two matrices over one index? - matlab

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]))

Related

How to multiply two matrix in matlab without loop

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

Matlab create matrix by iterating the same command several times without for loop

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

MATLAB: Efficient (vectorized) way to apply function on two matrices?

I have two matrices X and Y, both of order mxn. I want to create a new matrix O of order mxm such that each i,j th entry in this new matrix is computed by applying a function to ith and jth row of X and Y respectively. In my case m = 10000 and n = 500. I tried using a loop but it takes forever. Is there an efficient way to do it?
I am targeting two functions dot product -- dot(row_i, row_j) and exp(-1*norm(row_i-row_j)). But I was wondering if there is a general way so that I can plugin any function.
Solution #1
For the first case, it looks like you can simply use matrix multiplication after transposing Y -
X*Y'
If you are dealing with complex numbers -
conj(X*ctranspose(Y))
Solution #2
For the second case, you need to do a little more work. You need to use bsxfun with permute to re-arrange dimensions and employ the raw form of norm calculations and finally squeeze to get a 2D array output -
squeeze(exp(-1*sqrt(sum(bsxfun(#minus,X,permute(Y,[3 2 1])).^2,2)))
If you would like to avoid squeeze, you can use two permute's -
exp(-1*sqrt(sum(bsxfun(#minus,permute(X,[1 3 2]),permute(Y,[3 1 2])).^2,3)))
I would also advise you to look into this problem - Efficiently compute pairwise squared Euclidean distance in Matlab.
In conclusion, there isn't a common most efficient way that could be employed for every function to ith and jth row of X. If you are still hell bent on that, you can use anonymous function handles with bsxfun, but I am afraid it won't be the most efficient technique.
For the second part, you could also use pdist2:
result = exp(-pdist2(X,Y));

Ignore real value of imfilter in matlab

I am using imfilter in matlab to calculate convolution between two matrix A and H. My code is
B=imfilter(A,H,'replicate');
But the result B appears some complex value (Ex: 1+3i). And I want to remove complex values from matrix B (but dimemsion of B is not changed). So, my question is how to remove complex value of matrix B in matlab or similar way how to ignore them when I calculate B+C where C is input real matrix (I only want to calculate sum of real values in two matrix B and C)
You can take the real value of B using real(B).
If you want the magnitude of the entries (rather than just the real part) you can use abs(B).
To get the imaginary part you can use imag(B).
So for a complex matrix B you can decompose it using either
B = real(B) + j*imag(B);
or
B = abs(B).*exp( j*angle(B) );

Converting 'labels' of matrices to matrices in Matlab

I'm trying to write a short Matlab code to perform a certain mathematical function. The code generates a vector H which has entries of either 1, 2 or 3 (and size dependent on other factors). (In my mind), the numbers 1, 2 and 3 correspond to three particular matrices. Once my program has calculated H, I would like it to be able to multiply together all the matrices represented by its entries. To clarify, if H = [1 2 3 2], I'd like my code to calculate A*B*C*B. What is the simplest way of doing this? I thought about creating a vector with entries that are matrices, and using a function that gives the product of the entries of the vector, but I couldn't get that to work (and don't know if it can work - I'm very new to Matlab).
Ideally I'd rather not rewrite the rest of my code - if there's a way to get this to work with what I've done so far then that'd be great. I'm looking for functionality as opposed to slick coding - it doesn't matter if it's clumsy, as long as it works.
#zuloos answer might be problematic if the sizes of matrices are not the same - especially if number of rows are different. Should work if you put the matrices in cells.
matrices = {A,B,C,D};
result = matrices{H(1)};
for i=2:numel(H)
result = result * matrices{H(i)};
end
put all your matrices in another matice then you can use values of H as a the key to choose the right matrice matices = [A, B, C, D]. you would then go throug H one by one and multiply it with the result of the last operation. you will start with a diagonal matrice of the same dimensions as the other matrices and multiply this in each round of the loop with the matrice in matrices coreesponding to the value of H
matrices = [A, B, C, D]
// d is dimension of your matrices (i guess they are square)
erg = diag(d)
for i=length(H):1
// supposed your matices are 2d
erg = matrices(H(i),:,:)*init
end
i dont know if it makes sense here to multiply each step from left (like you would do in openGL) but i thought this allows you split up the operation in steps (like its done in openGL)