Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何在matlab中实现矩阵乘法的矢量化_Arrays_Matlab_Matrix - Fatal编程技术网

Arrays 如何在matlab中实现矩阵乘法的矢量化

Arrays 如何在matlab中实现矩阵乘法的矢量化,arrays,matlab,matrix,Arrays,Matlab,Matrix,我有两个矩阵A(nxm)和B(nxd),我想将A的每一列按元素乘以一行B。A中有m列,B中有n 1xd向量,所以结果是m nxd矩阵。然后我想求和(结果_I,1)得到m1xd向量,我想用vertcat得到mxd矩阵。我用for循环做这个运算,速度很慢,因为n和d都很大。如何在matlab中对其进行矢量化以使其更快?多谢各位 编辑: 你说得对:我被自己的问题弄糊涂了。我所说的“将A中的每列元素乘以B行”是指将A中一列的n个元素乘以B中相应的n行。我想对A中的一列执行以下操作(我对A中的m列重复此操

我有两个矩阵A(nxm)和B(nxd),我想将A的每一列按元素乘以一行B。A中有m列,B中有n 1xd向量,所以结果是m nxd矩阵。然后我想求和(结果_I,1)得到m1xd向量,我想用vertcat得到mxd矩阵。我用for循环做这个运算,速度很慢,因为n和d都很大。如何在matlab中对其进行矢量化以使其更快?多谢各位

编辑:
你说得对:我被自己的问题弄糊涂了。我所说的“将A中的每列元素乘以B行”是指将A中一列的n个元素乘以B中相应的n行。我想对A中的一列执行以下操作(我对A中的m列重复此操作,然后将C的向量相加,得到一个mxd矩阵):


它很难看,但据我所知,它很管用。我不确定它是否会比你的循环快,而且它有很大的内存开销。不管怎样,下面是:

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转换成一个大小为nx1 x m的3D矩阵,这样在第三维的每个索引中就有一列。然后我们重复这个矩阵,得到一个nxddxm矩阵。我们也在第三维重复B。然后我们对所有元素进行分段乘法并求和。得到的矩阵是1 x d x m矩阵。我们将其重塑为一个mxd矩阵

我敢肯定,在我的解释中,我对维度的大小进行了几次转换,但我希望你能理解其中的要点

与对角矩阵相乘似乎至少快一倍,但我找不到使用diag的方法,因为它需要向量或2D矩阵作为输入。今晚晚些时候我可能会再试一次,我觉得一定有更快的办法:)


[Edit]将命令分成若干部分,至少使其可读一点。

您可以通过以下方式对操作进行矢量化。但是,请注意,矢量化是以更高的内存使用率为代价的,因此解决方案可能最终不适合您

%# 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]);

我会这样做:

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

如果您不知道B的列数:

总和(repmat(A,1,size(B,2)).*B)


如果将
A
的每一列与
B
的每一行相乘,则得到m*n矩阵,而不是m。如果不是,那么如何从
B
中为
a
的给定列选择一行?它是预先给出的吗?@Itamar Katz:我应该说将A元素的m列中的每个元素与B的每行相乘,即[1 2 3]'*[1 1]=[1;2 2;3 3]。这不是元素相乘,而是,这是一个矩阵乘法,只是为了重申@Itamar Katz所说的:假设你将a的第一列与B的第一行相乘,得到一个mxd数组。然后将A的第一列与B的第二行相乘,然后将A的第一列与B的第三行相乘,依此类推。然后开始将A的第二列与B的第一行相乘,以此类推。因此,最终将得到大小为mxd的m*n数组。@Jonas这似乎不会生成
mxd
矩阵。它给我一个
nxd
(与
B
大小相同)。或者我正在做一些非常愚蠢的事情(很有可能)。@Darhuuk:哦,我总结错了维度。谢谢你的提醒@乔纳斯:没问题:)。不错的方法,不知道bsxfun,似乎比我在测试小矩阵时提出的方法快3-10倍。@Jonas:谢谢。你能解释一下你是如何选择排列顺序的吗?谢谢。@Martin08:我想把nxd阵列变成nx1xd阵列。因此,我需要将维度#2转换为维度#3。Permute允许我对矩阵的维度重新排序,所以我想写
Permute(B[1,X,2])
。对于X,我可以选择长度为1的B的任意维数。其中一个是当前维度3(因为B是nxdx1数组),但我也可以将
X
设置为4(因为B是nxdx1数组)。
[n,m] = size(A);
[n,d] = size(B);
tmp = repmat(A,[1 1 d]) .* repmat(permute(B,[1 3 2]),[1,m,1]);