I'm fairly new to MATLAB. Normal matrix multiplication of a M x K matrix by an K x N matrix -- C = A * B
-- has c_ij = sum(a_ik * b_kj, k = 1:K)
. What if I want this to be instead c_ij = sum(op(a_ik, b_kj), k = 1:K)
for some simple binary operation op
? Is there any nice way to vectorize this in MATLAB (or maybe even a built-in function)?
EDIT: This is currently the best I can do.
% A is M x K, B is K x N
% op is min
C = zeros(M, N);
for i = 1:M:
C(i, :) = sum(bsxfun(@min, A(i, :)', B));
end
Listed in this post is a vectorized approach that persists with bsxfun
by using permute
to create singleton dimensions as needed by bsxfun
to let the singleton-expansion
do its work and thus essentially replacing the loop in the original post. Please be reminded that bsxfun
is a memory hungry implementation, so expect speedup with it only until it is stretched too far. Here's the final solution code -
op = @min; %// Edit this with your own function/ operation
C = sum(bsxfun(op, permute(A,[1 3 2]),permute(B,[3 2 1])),3)
NB - The above solution was inspired by Removing four nested loops in Matlab.
if the operator can operate element-by-element (like .*
):
if(size(A,2)~=size(B,1))
error(blah, blah, blah...);
end
C = zeros(size(A,1),size(B,2));
for i = 1:size(A,1)
for j = 1:size(B,2)
C(i,j) = sum(binaryOp(A(i,:)',B(:,j)));
end
end
You can always write the loops yourself:
A = rand(2,3);
B = rand(3,4);
op = @times; %# use your own function here
C = zeros(size(A,1),size(B,2));
for i=1:size(A,1)
for j=1:size(B,2)
for k=1:size(A,2)
C(i,j) = C(i,j) + op(A(i,k),B(k,j));
end
end
end
isequal(C,A*B)
Depending on your specific needs, you may be able to use bsxfun in 3D to trick the binary operator. See this answer for more infos: https://stackoverflow.com/a/23808285/1121352
Another alternative would be to use cellfun with a custom function:
http://matlabgeeks.com/tips-tutorials/computation-using-cellfun/