Reputation: 79
I have the following three arrays in Matlab:
A size: 2xMxN
B size: MxN
C size: 2xN
Is there any way to remove the following loop to speed things up?
D = zeros(2,N);
for i=1:N
D(:,i) = A(:,:,i) * ( B(:,i) - A(:,:,i)' * C(:,i) );
end
Thanks
Upvotes: 2
Views: 2335
Reputation: 1
You may find that the following
D=tprod(A,[1 -3 2],B-tprod(A,[-3 1 2],C,[-3 2]),[-3 2]);
cuts the time taken. I did a few tests and found the time was cut in about half.
tprod is available at http://www.mathworks.com/matlabcentral/fileexchange/16275
tprod requires that A, B and C are full (not sparse).
Upvotes: 0
Reputation: 8467
Yes, it is possible to do without the for
loop, but whether this leads to a speed-up depends on the values of M
and N
.
Your idea of a generalized matrix multiplication is interesting, but it is not exactly to the point here, because through the repeated use of the index i
you effectively take a generalized diagonal of a generalized product, which means that most of the multiplication results are not needed.
The trick to implement the computation without a loop is to a) match matrix dimensions through reshape
, b) obtain the matrix product through bsxfun(@times, …)
and sum
, and c) get rid of the resulting singleton dimensions through reshape
:
par = B - reshape(sum(bsxfun(@times, A, reshape(C, 2, 1, N)), 1), M, N);
D = reshape(sum(bsxfun(@times, A, reshape(par, 1, M, N)), 2), 2, N);
par
is the value of the inner expression in parentheses, D
the final result.
As said, the timing depends on the exact values. For M = 100
and N = 1000000
I find a speed-up by about a factor of two, for M = 10000
and N = 10000
the loop-less implementation is actually a bit slower.
Upvotes: 2