Faster alternative to `repmat` and `permute` in 3d matrix?

Viewed 119

I'm running the following code

a = normrnd(0,1,5000, 300);
b = normrnd(0, 1, 5000, 50);
tic
 xp = repmat(a,1,1,50) .* permute(repmat(b, 1,1, 300), [1 3 2]);
toc

which outputs

Elapsed time is 0.425773 seconds.

Apparently the vast majority of execution time is spent on the repmat and permute part. I thought some alternative implementation with bsxfun might help to speed it up quite a bit, but I don't see exactly how. Is there any better way of dealing with this? Thank you!

1 Answers

You can reduce running time if instead of repmat you use singleton expansion, either implicit (requires Matlab R2016b or newer):

xp = a .* permute(b, [1 3 2]);

or explicit with bsxfun:

xp = bsxfun(@times, a , permute(b, [1 3 2]));

Results on my machine, using timeit (which is more accurate than tic, toc):

>> a = normrnd(0,1,5000, 300);
>> b = normrnd(0, 1, 5000, 50);
>> timeit(@() repmat(a,1,1,50) .* permute(repmat(b, 1, 1, 300), [1 3 2]))
ans =
   0.706580436900000
>> timeit(@() a .* permute(b, [1 3 2]))
ans =
   0.167270436900000
>> timeit(@() bsxfun(@times, a , permute(b, [1 3 2])))
ans =
   0.161594036900000

The likely explanation of these reduced times is that in the repmat approach the extended arrays are explicitly constructed, which requires memory allocation.

Related