2016-07-13 2 views
3

В MATLAB У меня есть серия 2x2-матриц, уложенных в трехмерный тензор, и я бы хотел выполнить умножение матрицы для каждого экземпляра матриц.эффективная реализация тензорного точечного произведения в matlab

так что мой C = A * B определяются как

C_ijk = sum(a_ilk * b_ljk, over all l) 

моя текущая реализация выглядит следующим образом

function mats = mul3D(A, B) 
     % given a list of 2D matrices (e.g. rotation matrices) applies 
     % the matrix product for each instance along the third dimension 
     % mats(:,:,i) = A(:,:,i) * B(:,:,i) for all i 
     % for this to succeed matrix dimensions must agree. 
     mats = zeros(size(A,1), size(B,2), size(B,3)); 
     for i=1:size(B, 3) 
      mats(:,:,i) = A(:,:,i) * B(:,:,i); 
     end 
    end 

, который очень легко читать, но я помню, кто-то говорил, что MATLAB не как для петель.

Так вы можете думать о лучшей реализации, которая не потребляет больше памяти, чем эта, будучи быстрее? мой код тратит около 50% времени выполнения в этом цикле.

редактировать

спасибо за ваши предложения. К сожалению, я не могу представить новые зависимости от стороннего кода.

На основании ваших вопросов у меня возникла идея использовать структуру 2 x 2 x n тензоров. Моя последняя реализация выглядит так:

function mats = mul3D(A, B) 
     % given a list of 2D matrices (e.g. rotation matrices) applies 
     % the matrix product for each instance along the third dimension 
     % mats(:,:,i) = A(:,:,i) * B(:,:,i) for all i 
     % for this to succeed matrix dimensions must agree. 
     mats = zeros(size(A,1), size(B,2), size(B,3)); 

     mats(1,1,:) = A(1,1,:) .* B(1,1,:) + A(1,2,:) .* B(2,1,:); 
     mats(2,1,:) = A(2,1,:) .* B(1,1,:) + A(2,2,:) .* B(2,1,:); 
     if(size(mats,2) > 1) 
      mats(1,2,:) = A(1,1,:) .* B(1,2,:) + A(1,2,:) .* B(2,2,:); 
      mats(2,2,:) = A(2,1,:) .* B(1,2,:) + A(2,2,:) .* B(2,2,:); 
     end 
    end 

любые дальнейшие предложения приветствуются!

+0

Для произвольных размеров это можно сделать с помощью 'bsxfun' и' permute', но это займет больше памяти, и неясно, будет ли оно быстрее. В последних версиях Matlab циклы не так медленны, как раньше. Если какой-то размер исправлен, возможно, это может быть использовано. Какие размеры (размеры) фиксированы и какова их ценность? –

+0

Каковы типичные формы 'A' и' B'? – Divakar

+0

Я нашел оптимизированную библиотеку здесь: [link] (https://www.mathworks.com/matlabcentral/answers/62382-matrix-multiply-slices-of-3d-matricies). У меня были проблемы с его созданием. – Rotem

ответ

1

Я рекомендую вам использовать mtimesx.
См здесь: https://www.mathworks.com/matlabcentral/answers/62382-matrix-multiply-slices-of-3d-matricies

mtimesx использует оптимизированную MEX файла сделать "Матрицу умножать ломтики 3d матриц,".

mtimesx использует BLAST library (библиотека BLAST является частью установки Matlab).

Скачать mtimesx исходного код здесь: http://www.mathworks.com/matlabcentral/fileexchange/25977-mtimesx-fast-matrix-multiply-with-multi-dimensional-support

У меня был проблема, строящей MEX файла в Matalb r2014b.
Проблема в том, что версии Matlab выше r2014a не имеют файла mexopts.bat.
Сценарий сценария mex использует mexopts.bat.

Я решил это, загрузив mexopts.bat.
Я использую компилятор Visual Studio 2010 и нашел соответствие mexopts.bat здесь: http://www.dynare.org/DynareWiki/ConfigureMatlabWindowsForMexCompilation

Я скопировал mexopts.bat в локальную папку: c:\Users\Rotem\AppData\Roaming\MathWorks\MATLAB\R2014b\

В конце концов, что mtimesx работает достаточно хорошо ...
Использование mex-файла должно быть намного быстрее, чем использование цикла.

Смежные вопросы