Reputation: 196
Is there an easy way to have a scaled repmat in matlab?
The idea is, given matrices A
and B
result = [A*B(1, 1) A*B(1, 2) A*B(1, 3) ...
A*B(1, n); A*B(2, 1)...];
Right now I accomplish this by using permute and reshape, but the permutation operation is 90% of my script time.
Upvotes: 1
Views: 119
Reputation: 221624
You are probably performing the elementwise multiplications that results in a huge array and then permuting. Now, permute
on a big array would incur heavy data transfers, which won't be efficient. So, I am guessing you are doing something along these lines :
reshape(permute(bsxfun(@times,A,permute(B,[3,4,1,2])),[1,3,2,4]),N,[])
^ (kills performance)
The alternative is to perform permute
on A
and B
before performing elementwise multiplications between the input arrays, such that finally we would just need a reshape
. Permuting on comparatively A
and B
should be much more efficient.
So, one efficient solution would be -
n = size(A,1)*size(B,1);
out = reshape(bsxfun(@times,permute(A,[1,3,2]),permute(B,[3,1,4,2])),n,[]);
Runtime test
Let's time the two approaches to verify our performance improvements and also include kron
based method as suggested in @Shai's post, which seems like a clean solution -
% Max sized input arrays that my system could handle
A = randi(9,70,70);
B = randi(9,70,70);
disp('-------------- With permute on A and B and finally reshaping')
tic
n = size(A,1)*size(B,1);
out0 = reshape(bsxfun(@times,permute(A,[1,3,2]),permute(B,[3,1,4,2])),n,[]);
toc, clear out0 n
disp('-------------- With permute on elementwise result')
tic
n = size(A,1)*size(B,1);
out1 = reshape(permute(bsxfun(@times,A,permute(B,[3,4,1,2])),[1,3,2,4]),n,[]);
toc, clear out1 n
disp('-------------- With kron from @Shai post')
tic,
result1 = kron(B, A);
toc
Timings -
-------------- With permute on A and B and finally reshaping
Elapsed time is 0.161598 seconds.
-------------- With permute on elementwise result
Elapsed time is 0.413746 seconds.
-------------- With kron from @Shai post
Elapsed time is 0.612825 seconds.
Upvotes: 2