我使用此3D矩阵的最后两个维度作为2D矩阵。所以我只想将Matrix1(i,:,:)
(i
- by - i
)的结果与矢量Matrix2(i,:).')
(1
- 的结果相乘 - 由 - i
)
我能做到的唯一方法是使用一个辅助矩阵,从3D矩阵中拾取2维中的所有数字:
matrixAux(:,:) = Matrix1(1,:,:)
然后我做了乘法:
matrixAux * (Matrix2(i,:).')
它有效。但是,这很慢,因为我需要将所有3D矩阵复制到很多辅助矩阵中,我需要加速我的代码,因为我多次进行相同的操作。
如何更有效地完成这项工作,而无需复制矩阵?
答案 0 :(得分:0)
bsxfun
乘法一种方法是将bsxfun
的输出与@times
一起使用,您可以使用其值而不是在循环中计算矩阵乘法结果 -
sum(bsxfun(@times,Matrix1,permute(Matrix2,[1 3 2])),3).'
示例
例如,我们假设Matrix1
和Matrix2
定义如下 -
nrows = 3;
p = 6;
ncols = 2;
Matrix1 = rand(nrows,ncols,p)
Matrix2 = rand(nrows,p)
然后,你有这样的循环 -
for i = 1:size(Matrix1,1)
matrixAux(:,:) = Matrix1(i,:,:);
matrix_mult1 = matrixAux * (Matrix2(i,:).') %//'
end
因此,您可以直接计算矩阵乘法结果 - 而不是循环 -
matrix_mult2 = sum(bsxfun(@times,Matrix1,permute(Matrix2,[1 3 2])),3).'
因此,matrix_mult2
的每一列在循环的每次迭代中都代表matrix_mult1
,因为代码的输出会使它更清晰 -
matrix_mult1 =
0.7693
0.8690
matrix_mult1 =
1.0649
1.2574
matrix_mult1 =
1.2949
0.6222
matrix_mult2 =
0.7693 1.0649 1.2949
0.8690 1.2574 0.6222
现在,这一定是令人兴奋的!那么你也可以利用MATLAB的快速矩阵乘法来再次获得中间矩阵乘法结果而不需要循环。如果Matrix1
为nrows x p x ncols
,您可以将其重新整形为nrows*p x ncols
,然后将其与Matrix2
进行矩阵乘法运算。然后,要获得等效的matrix_mult2
,您需要从乘法结果中选择索引。这正是在这里实现的 -
%// Get size of Matrix1 to be used regularly inside the codes later on
[m1,n1,p1] = size(Matrix1);
%// Convert 3D Matrix1 to 2D and thus perform "full" matrix multiplication
fmult = reshape(Matrix1,m1*n1,p1)*Matrix2'; %//'
%// Get valid indices
ind = bsxfun(@plus,[1:m1:size(fmult,1)]',[0:nrows-1]*(size(fmult,1)+1)); %//'
%// Get values from the full matrix multiplication result
matrix_mult3 = fmult(ind);
此处,matrix_mult3
必须与matrix_mult2
相同。
观察:由于我们没有使用从全矩阵乘法计算的所有值,而是将其索引到其中并选择其中的一些元素,因此这种方法在某些方面的性能优于其他方法情况。当nrows
是一个较小的值时,这种方法似乎是最好的方法,因为在这种情况下我们将使用来自全矩阵乘法输出的更多元素。
针对这三种方法测试了两个案例,测试结果似乎支持我们之前讨论过的假设。
案例1
Matrix 1
为400 x 400 x 400
,运行时为 -
--------------- With Loops
Elapsed time is 2.253536 seconds.
--------------- With BSXFUN
Elapsed time is 0.910104 seconds.
--------------- With Full Matrix Multiplication
Elapsed time is 4.361342 seconds.
案例2
Matrix 1
为40 x 2000 x 2000
,运行时为 -
--------------- With Loops
Elapsed time is 5.402487 seconds.
--------------- With BSXFUN
Elapsed time is 2.585860 seconds.
--------------- With Full Matrix Multiplication
Elapsed time is 1.516682 seconds.