有效地计算外部产品的3D矩阵 - MATLAB

ray*_*ica 6 matlab matrix vectorization

假设我有一个像这样的元素矩阵:

A = reshape(1:25, 5, 5)

A =

 1     6    11    16    21
 2     7    12    17    22
 3     8    13    18    23
 4     9    14    19    24
 5    10    15    20    25
Run Code Online (Sandbox Code Playgroud)

我想有效地计算外积,使得第i的3D矩阵这个输出矩阵的片段为i的外积的列A与自身.两个向量之间的外积uv仅仅是u*v.'如果uv都列向量.

因此,此输出矩阵的每个切片B应构造为:

B(:,:,1) = A(:,1) * A(:,1).';
B(:,:,2) = A(:,2) * A(:,2).';
        ...
        ...
B(:,:,5) = A(:,5) * A(:,5).';
Run Code Online (Sandbox Code Playgroud)

我目前的方法如下.我尝试这样做使用arrayfuncell2mat:

cellmatr = arrayfun(@(x) A(:,x) * A(:,x).', 1:size(A,2), 'uni', 0);
out = reshape(cell2mat(cellmatr), size(A,1), size(A,1), size(A,2));
Run Code Online (Sandbox Code Playgroud)

我只是在1我们所拥有的列之间循环一个线性索引数组A,并且对于这个数组中的每个元素,我访问相应的列并计算外部产品.因此输出将给出一维单元网格,然后我将其转换回二维矩阵,然后重塑为三维矩阵以找到外部产品的三维矩阵.

但是,对于大型矩阵,这非常慢.我也尝试用kron(即kron(A(:,x), A(:,x)))在我的arrayfun调用中替换矩阵产品,但对于我的目的来说这仍然很慢.


有谁知道以这种方式计算外部产品的3D矩阵的有效方法?

Lui*_*ndo 10

这只是对Divakar答案的一个小改进.它更快一些,因为它用2D阵列置换替换了3D阵列置换:

B = bsxfun(@times, permute(A, [1 3 2]), permute(A, [3 1 2]));
Run Code Online (Sandbox Code Playgroud)


Amr*_*mro 7

说明显而易见,您是否尝试过一个简单的for循环:

[m,n] = size(A);
B = zeros(m,m,n);
for i=1:n
    B(:,:,i) = A(:,i) * A(:,i).';
end
Run Code Online (Sandbox Code Playgroud)

你会惊讶地发现它的速度有多快.

  • +1 amro,有时候明显的需求也会提到.我也比bsxfun更喜欢这个,更具可读性...... (3认同)