2011-04-07 97 views
2

这个矩阵乘法我有2矩阵A(n×m个)和B(NXD),并希望相乘逐元素 A的各列与 B的行有M列B中的A和n 1xd向量,所以结果是m×n×d矩阵。然后,我想总结(result_i,1)以获得m个1xd向量,我想应用vertcat来获取mxd矩阵。我正在使用for循环执行这个操作,而且它很慢,因为n和d很大。我如何在matlab中对此进行矢量化以使其更快?谢谢。如何向量化在Matlab

编辑:
你没事:我被我自己的问题弄糊涂了。我的意思是“乘以元素明智的 A的每列和一行B”是将A中列的n个元素与对应的n行B相乘。我想对一列A做什么为遵循(和我重复此为A的m列,然后vertcat的C的矢量合力得到一个MXD矩阵):

column_of_A = 

    3 
    3 
    1 


B = 

    3  1  3  3 
    2  2  1  2 
    1  3  3  3 


C = sum(diag(column_of_A)*B, 1) 

    16 12 15 18 
+2

如果将'A'的每一列与'B'的每一行相乘,则得到m * n个矩阵,而不是m。如果不是,那么你如何从'B'中选择一行作为'A'的给定列?它是提前给出的吗? – 2011-04-07 12:13:59

+0

@Itamar Katz:我应该说将A_elementwise_的m列的每个元素与B的每一行相乘,即[1 2 3]'* [1 1] = [1 1; 2 2; 3 3]。 – Martin08 2011-04-07 12:36:29

+0

这不是单元乘法,而是矩阵乘法。 – Jonas 2011-04-07 13:06:19

回答

6

您可以通过以下方法矢量化您的操作。但请注意,矢量化的代价是更高的内存使用量,因此解决方案可能最终无法为您工作。

%# multiply nxm A with nx1xd B to create a nxmxd array 
tmp = bsxfun(@times,A,permute(B,[1 3 2])); 

%# sum and turn into mxd 
out = squeeze(sum(tmp,1)); 

你可能想要做的一切在一条线,这可以帮助Matlab的JIT编译器,以节省内存。

编辑

下面就来取代第一线的方式,如果你没有bsxfun

[n,m] = size(A); 
[n,d] = size(B); 
tmp = repmat(A,[1 1 d]) .* repmat(permute(B,[1 3 2]),[1,m,1]); 
+0

@Jonas这似乎不会产生一个'mxd'矩阵。它给了我一个'nxd'(与'B'相同的尺寸)。这或我正在做一些非常愚蠢的事情(很有可能)。 – Darhuuk 2011-04-07 14:53:16

+0

@达鲁​​克:哦,我总结了错误的层面。感谢您的提醒! – Jonas 2011-04-07 15:00:11

+0

@Jonas没问题:)。好的方法,不知道'bsxfun',似乎比我在我测试的小矩阵上提出的要快3-10倍。 – Darhuuk 2011-04-07 15:02:24

1

这是丑陋的,但就我所看到的,它的工作原理。我不确定它会比你的循环更快,而且它有很大的内存开销。总之,这里所谓:

A_3D = repmat(reshape(A, size(A, 1), 1, size(A, 2)), 1, size(B, 2)); 
B_3D = repmat(B, [ 1 1 size(A, 2)]); 
result_3D = sum(A_3D .* B_3D, 1); 
result = reshape(result_3D, size(A, 2), size(B, 2)) 

它的作用是:在第三维的每个索引制作成大小为N×1×米的三维矩阵,所以一列。然后我们重复这个矩阵,所以我们得到一个n x d x m的矩阵。我们也在第三维中重复B.然后,我们对所有元素进行分段乘法并对它们进行求和。得到的矩阵是1×d×m矩阵。我们将其重塑为一个m×d矩阵。

我很确定我在解释中转换了几次尺寸的大小,但我希望你能得到一般的要点。

乘以一个对角矩阵看起来至少有两倍的速度,但我找不到使用diag的方法,因为它需要一个矢量或二维矩阵作为输入。我今晚可能会再试一次,我觉得必须有更快的方式:)。

[编辑]将部分命令拆分为至少使其具有一点可读性。

0

做,这是我会做这样的方式:

总和( repmat(A,1,4)。* B)

如果你不知道B的列数:

总和(A,1 repmat(,大小(B,2))* B)