【问题标题】:Matlab matrices dimensionMatlab矩阵维度
【发布时间】:2013-08-02 08:24:55
【问题描述】:

我是 matlab 新手,想知道你们是否可以帮我解决这个问题。

例如,我有两个矩阵:

A = [X1 X2 X3 X4]

B = [Y1; Y2; Y3]

现在我真正想要实现的是以这种方式将这两个矩阵相乘:

[X1Y1 X2Y1 X3Y1 X4Y1; 
 X1Y2 X2Y2 X3Y2 X4Y2;
 X1Y3 X2Y3 X3Y3 X4Y3;
 .... and so on]

我尝试使用A(1,:).*B(:,1),但 matlab 说矩阵尺寸必须一致。

我只是不知道如何在 matlab 上操作这个,但在 excel 中是可能的。

【问题讨论】:

  • 你试过从右边乘以 A 吗? B().A()

标签: matlab matrix


【解决方案1】:

这是一个简单的外部产品。不需要 kron (尽管它会起作用。) bsxfun 是野蛮的矫枉过正,虽然会产生你所要求的。 repmat 是不合适的,因为虽然它会帮助你做你想做的事,但它会复制内存中的数组,使用比需要更多的资源。 (当您可以立即使用好的编程风格时,请避免使用低效的编程风格。)

您只需要使用简单的 * 运算符。

A 是行向量。 B 列向量。

C = B*A

将产生结果 C(i,j)=B(i)*A(j),这正是您要寻找的。请注意,这是可行的,因为 B 是 3x1 而 A 是 1x4,所以 B 和 A 的“内部”尺寸确实符合。

在 MATLAB 中,如果您不确定某些功能是否有效,请尝试一下!

A = [1 2 3 4];
B = [1;2;3];
C = B*A
ans =
     1     2     3     4
     2     4     6     8
     3     6     9    12

看到 kron 确实有效,尽管我敢打赌,在这里使用 kron 的效率可能低于简单的外积相乘。

C = kron(B,A)
C =
     1     2     3     4
     2     4     6     8
     3     6     9    12

同样,bsxfun 也可以在这里工作,尽管由于我们使用通用工具来完成基本操作员会做的事情,我敢打赌它的效率会稍低。

C = bsxfun(@times,B,A)
C =
     1     2     3     4
     2     4     6     8
     3     6     9    12

最糟糕的选择是 repmat。同样,由于它首先人为地复制内存中的向量,因此在大向量的情况下,它必须出去并抢占大块内存。

C = repmat(B,1,4).*repmat(A,3,1)
C =
     1     2     3     4
     2     4     6     8
     3     6     9    12

我想为了完整起见,您也可以使用 meshgrid 或 ndgrid。看到它正在做的正是 repmat 所做的,但在这里它明确地创建了新矩阵。同样,当有很好的工具可以完全按照您的意愿行事时,这是一种糟糕的编程风格。

[BB,AA] = ndgrid(B,A)
BB =
     1     1     1     1
     2     2     2     2
     3     3     3     3
AA =
     1     2     3     4
     1     2     3     4
     1     2     3     4

C = BB.*AA
C =
     1     2     3     4
     2     4     6     8
     3     6     9    12

您需要了解的是为什么这些工具都可以用于这项工作,以及它们为何不同。

【讨论】:

  • +1,特别是对于语句 在 MATLAB 中,如果您不确定某些东西是否可行,请尝试一下! SO 似乎被那些宁愿花 20几分钟写一个问题,几个小时等待答案,而不是花 20 分钟玩弄自己并找出答案。
【解决方案2】:

在 Matlab 中有*.*,它们非常不同。

* 是正常的矩阵乘法,这是你想要的,即B*A,注意B 必须排在第一位,因为内部维度必须匹配。您可以将列乘以行,但不能将行乘以列(除非它们具有相同数量的元素)。

.* 是逐元素乘法,在这种情况下,矩阵的大小和形状必须完全相同,例如 [1 2 3].*[4 5 6] = [1*4 2*5 3*6 ] = [4 10 18]

【讨论】:

  • @HighPerformanceMark 不,你绝对不能。试试这个:A=[1,2,3,4];B=[1;2;3];A*B; 你会得到错误 Inner matrix dimensions must agree.B*A 会运行良好。这是因为在第二种情况下,内部维度都是 1,但在第一种情况下,您尝试乘以 4x3,而矩阵乘法的定义无法做到这一点。
  • @HighPerformanceMark 是的,您是对的,如果(但仅当)它们具有相同数量的元素时,您可以这样做。我会修改答案。但在这个例子中你不能。
【解决方案3】:

不要使用“.*”。你应该做一个“*”。 “.*”用于索引乘法,如果它们的向量大小相等,应该给你 [X1Y1 X2Y2 X3Y3]。 如果你做正则乘法“*”,这实际上是矩阵乘法。

【讨论】:

    【解决方案4】:

    我认为您只需要转置其中一个向量。您将列向量 (A(1,:)) 与行向量 (B(:,1)) 相乘。这应该有效:

    C = A(1,:).*B(:,1)';
    

    【讨论】:

    • 您可以对行和列进行逐个元素的乘法运算,Matlab 不介意这一点(我认为,我实际上并不是 100% 对此进行测试,也不是围绕 matlab 进行测试。八度广播所以不能用它来检查)。但在这种情况下,问题是A 有 4 个元素,而B 只有 3 个元素。OP 所追求的是传统的矩阵乘法,即B*A
    • 我实际上确实在 matlab 会话 (2010A) 中尝试过此操作,但在尝试执行 A(1,:).*B(:,1) 时确实遇到了错误。但你是对的,看来 OP 的意思是别的 :)