Более быстрая альтернатива `repmat` и` permute` в 3d матрице? - PullRequest
2 голосов
/ 26 октября 2019

Я использую следующий код

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

, который выводит

Elapsed time is 0.425773 seconds.

Очевидно, что подавляющее большинство времени выполнения тратится на части repmat и permute. Я думал, что какая-то альтернативная реализация с bsxfun может помочь немного ускорить его, но я не знаю, как именно. Есть ли лучший способ справиться с этим? Спасибо!

1 Ответ

3 голосов
/ 26 октября 2019

Вы можете уменьшить время выполнения, если вместо repmat вы используете одноэлементное расширение, либо неявное (требуется Matlab R2016b или новее):

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

или явное с bsxfun:

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

Результаты на моей машине с использованием timeit (что более точно, чем 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

Вероятное объяснение этого сокращенного времени состоит в том, что в подходе repmat расширенные массивы создаются явно, что требует выделения памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...