Умножьте каждый субблок на матрицу в MATLAB

Я хотел бы умножить каждый подблок матрицы A mxn на матрицу B pxq. Например, A можно разделить на k субблоков, каждый размером mxp.

A = [A_1 A_2 ... A_k]

В результате матрица будет C = [A_1 * B A_2 * B ... A_k * B], и я хотел бы сделать это эффективно.

До сих пор я пробовал:

С = А * крон (глаз (к), В)

Отредактировано: Даниэль, я думаю, вы правы. Я пробовал 3 разных способа. Вычисление продукта кронекера кажется плохой идеей. Даже решение с изменением формы работает быстрее, чем более компактное решение в кронах.

tic 
for i=1:k
C1(:,(i-1)*q+1:i*q) = A(:,(i-1)*p+1:i*p)*B;
end
toc

tic
C2 = A*kron(eye(k),B);
toc

tic
A = reshape(permute(reshape(A,m,p,[]),[1 3 2]),m*k,[]);
C3 = A*B;
C3 = reshape(permute(reshape(C3,m,k,[]),[1 3 2]),m,[]);
toc

person zSt    schedule 14.02.2016    source источник
comment
Блоки от A_1 до A_k имеют размер mxp?   -  person Daniel    schedule 15.02.2016
comment
да. Кроме того, m n и p могут быть очень большими.   -  person zSt    schedule 15.02.2016
comment
Вы пробовали простой цикл for? Насколько мне известно, в данном случае это самый быстрый вариант.   -  person Daniel    schedule 15.02.2016


Ответы (1)


Когда я смотрю на ваш код умножения матриц, у вас есть идеально оптимизированный код внутри цикла. Вы не можете победить матричное умножение. Все, что вы могли бы сократить, - это накладные расходы на итерацию, но по сравнению с длительным временем выполнения матричного умножения накладные расходы абсолютно не влияют.

То, что вы пытались сделать, было бы правильной стратегией, когда операция внутри цикла тривиальна, но цикл повторяется много раз. Если вы выберете следующие параметры, вы заметите, что ваше permute решение действительно имеет свои преимущества, но не для размеров вашей проблемы:

q=1;p=1;n=1;m=1;
k=10^6

Крон полностью терпит неудачу. Ваше решение перестановки занимает 0.006s, а цикл занимает 1.512s

person Daniel    schedule 15.02.2016