Как вычислить быстрое внешнее произведение между двумя матрицами в Matlab?

У меня есть две матрицы размером n на m, A и B. Я хочу создать новую матрицу C, которая выглядит примерно так:

for i = 1:n
    C = C + outerProduct(A(i,:), B(i,:));
end

т.е. C - это матрица размера m x m, сумма всех внешних произведений строк A и B.

Есть ли быстрый способ сделать это без цикла for (учитывая, что циклы for заведомо медленные в Matlab)?


person kloop    schedule 10.01.2012    source источник


Ответы (3)


Выполняемая вами операция (сумма внешних произведений строки) эквивалентна умножению транспонированной версии A на B:

C = A.'*B;

Вы можете убедиться в этом на следующем примере:

>> mat = magic(5);  %# A sample 5-by-5 matrix
>> A = mat(1:4,:);  %# Create a 4-by-5 matrix
>> B = mat(2:5,:);  %# Create another 4-by-5 matrix

>> C = zeros(5);  %# Initialize C to be 5-by-5
>> for i = 1:4, C = C + A(i,:).'*B(i,:); end;  %'# Calculate C as you are now

>> isequal(C, A.'*B)  %'# Test for equality with the shorter solution

ans =

     1  %# Equal!
person gnovice    schedule 10.01.2012
comment
Нет, этого не было бы - здесь используется внутренний продукт для каждой ячейки. - person kloop; 10.01.2012
comment
$ C_ {ij} = \ sum_k A_ {ki} B_ {kj} = \ sum_k A ^ T_ {ik} B_ {kj} = A ^ T * B $ - person Nzbuu; 10.01.2012

Вы профилировали свой for код цикла и обнаружили, что он слишком медленный? Если нет, сделайте это, прежде чем потратите слишком много времени на мучения по поводу штрафа за петлю.

Ваш for цикл не особенно плох, потому что вы выполняете цикл только n раз, но выполняете O(n*m) работу в каждом цикле. Поскольку на каждой итерации вы выполняете много работы, штраф за цикл не так сильно сказывается. Действительно плохие ситуации - это вложенные циклы, например. если вы рассчитали и внешние продукты с вложенными for циклами.

person japreiss    schedule 10.01.2012
comment
Использование циклов For очень не рекомендуется при работе с Matlab. Это стандартное практическое правило не только в Matlab, но и во всех языках программирования, которые используются в числовых вычислениях и связанных областях. Если вы можете векторизовать свои операции, некоторые оптимизации могут быть выполнены, и ваш код может работать, например на GPU более эффективно. - person nbro; 14.05.2018

Возможно, я ошибаюсь, но я считаю, что вы ищете

C = A*B';
person lsfinn    schedule 12.01.2012
comment
Это даст результат n на n, а не результат m на m. - person gnovice; 12.01.2012