2

我遇到了一个似乎无法通过矢量化实现的操作。

假设我想找到由定义的应用程序的矩阵

h: X -> 交叉(V,X)

其中 V 是预定向量(X 和 V 都是 3×1 向量)。

在 Matlab 中,我会做类似的事情

M= cross(repmat(V,1,3),eye(3,3)) 

得到这个矩阵。例如,V=[1;2;3] 产生

M =

 0    -3     2
 3     0    -1
-2     1     0

现在假设我有一个 3×N 矩阵

V=[V_1,V_2...V_N]

每一列都定义了自己的叉积运算。对于 N=2,这是一个天真的尝试找到 V 的列定义的两个叉积矩阵

 V=[1,2,3;4,5,6]'
M=cross(repmat(V,1,3),repmat(eye(3,3),1,2))

结果是

V =

     1     4
     2     5
     3     6


M =

     0    -6     2     0    -3     5
     3     0    -1     6     0    -4
    -2     4     0    -5     1     0

在我期待的时候

M =

 0    -3     2     0    -6     5
 3     0    -1     6     0    -4
-2     1     0    -5     4     0

2列倒置。

有没有办法在没有 for 循环的情况下实现这一目标?

谢谢!

4

1 回答 1

1

首先,确保cross在处理矩阵时非常仔细地阅读文档:

它说:

C = cross(A,B,DIM), where A and B are N-D arrays, returns the cross
product of vectors in the dimension DIM of A and B. A and B must
have the same size, and both SIZE(A,DIM) and SIZE(B,DIM) must be 3.

请记住,如果您不指定DIM,它会自动假定为 1,因此您将沿着列进行操作。在您的第一种情况下,您将输入A和都指定B为 3 x 3 矩阵。因此,由于假设 ,输出将是每DIM=1独立的叉积。因此,您希望输出的第 i 列包含第 i 列A和第 i列的叉积,B并且行数预计为 3,并且列数需要匹配A和之间B

你得到了你所期望的,因为第一个输入A[1;2;3]列上正确复制了三次。从您的第二段代码中,您期望V的第一个输入 ( A) 看起来像这样:

V =

     1     1     1     4     4     4
     2     2     2     5     5     5
     3     3     3     6     6     6

然而,当你这样做时repmat,你实际上是在每列之间交替。事实上,你得到了这个:

V = 

     1     4     1     4     1     4
     2     5     2     5     2     5
     3     6     3     6     3     6

repmat将矩阵平铺在一起,并且您指定要V水平平铺三次。这显然是不正确的。这解释了为什么要交换列,因为V实际上应该出现在最后三列的第二、第四和第六列。因此,输入列的顺序是输出出现交换的原因。

因此,您需要重新排序V,以便前三个向量是[1;2;3],然后是接下来的三个向量[4;5;6]。因此,您可以先生成原始V矩阵,然后创建一个新矩阵,使得奇数列在一组三个中排在第一位,然后是偶数列在一组三个中排在后面:

>> V = [1,2,3;4,5,6].';
>> V = V(:, [1 1 1 2 2 2])

V =

     1     1     1     4     4     4
     2     2     2     5     5     5
     3     3     3     6     6     6

现在使用Vcross保持相同的第二个输入:

>> M = cross(V, repmat(eye(3), 1, 2))

M =

     0    -3     2     0    -6     5
     3     0    -1     6     0    -4
    -2     1     0    -5     4     0

在我看来很好!

于 2015-04-27T20:19:59.543 回答