假设我有一个像这样的元素矩阵:
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
我想有效地计算外部产品的3D矩阵,这样输出矩阵的i th 切片是i th 列的外积。 A
与自己。如果u
和v
都是列向量,则两个向量u*v.'
和u
之间的外部产品只是v
。
因此,此输出矩阵B
的每个切片都应该构造成:
B(:,:,1) = A(:,1) * A(:,1).';
B(:,:,2) = A(:,2) * A(:,2).';
...
...
B(:,:,5) = A(:,5) * A(:,5).';
我目前的方法如下。我尝试使用arrayfun
和cell2mat
:
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));
我只是在1
和A
中的多列之间循环一个线性索引数组,对于这个数组中的每个元素,我访问相应的列并计算外部产品。因此输出将给出1D单元格,然后我将其转换回2D矩阵,然后重塑为3D矩阵以找到外部产品的3D矩阵。
但是,对于大型矩阵,这很慢。我还尝试在kron
调用中使用kron(A(:,x), A(:,x))
(即arrayfun
)替换矩阵产品,但这对我来说仍然很慢。
有谁知道以这种方式计算外部产品3D矩阵的有效方法?
答案 0 :(得分:8)
这比Divakar's answer略有改进。它更快一些,因为它用2D阵列置换代替了3D阵列置换:
B = bsxfun(@times, permute(A, [1 3 2]), permute(A, [3 1 2]));
答案 1 :(得分:7)
说明一点,你试过一个简单的for循环:
[m,n] = size(A);
B = zeros(m,m,n);
for i=1:n
B(:,:,i) = A(:,i) * A(:,i).';
end
你会惊讶地发现它的速度有多快。
答案 2 :(得分:3)
这 -
B = permute(bsxfun(@times,A,permute(A,[3 2 1])),[1 3 2])