我有2个矩阵A(nxm)和B(nxd)并希望将逐个元素与A的每一列相乘一行 B.有m个A中的列和B中的n个1xd向量,因此结果是m nxd矩阵。然后我想求和(result_i,1)得到m 1xd向量,我想应用vertcat来获得mxd矩阵。我正在使用for循环执行此操作,并且它很慢,因为n和d很大。如何在matlab中对其进行矢量化以使其更快?谢谢。
修改
你没事:我对自己的问题感到困惑。我的意思是“将逐个元素 A的每一列与一行B”相乘是将A中列的n个元素与B的相应n行相乘。我想要做什么A的一列如下(我对A的m列重复此操作,然后将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
答案 0 :(得分: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]);
答案 1 :(得分: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))
它的作用是:将A制作成尺寸为n x 1 x m的3D矩阵,因此在第3维的每个索引中都有一列。然后我们重复矩阵,这样我们得到一个n x d x m矩阵。我们也在第三维中重复B.然后,我们对所有元素进行分段乘法并对它们求和。得到的矩阵是1×d×m矩阵。我们将其重塑为m x d矩阵。
我很确定在我的解释中我几次调整尺寸大小,但我希望你能得到一般的要点。
乘以对角矩阵似乎至少快两倍,但我找不到使用diag的方法,因为它需要矢量或2D矩阵作为输入。我今晚可能会再试一次,我觉得必须有更快的方法:)。
[编辑] 将命令分成几部分,至少让它有点可读。
答案 2 :(得分:0)
这是我这样做的方式:
和(repmat(A,1,4)。* B)
如果你不知道B的列数:
和(repmat(A,1,大小(B,2))。* B)