Matlab 中矢量定义的叉积应用矩阵和矢量化
Vector-defined cross product application matrix and vectorization in Matlab
我 运行 进入了一个我似乎无法通过矢量化实现的操作。
假设我想找到
定义的应用程序矩阵
h: X -> cross(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 循环实现的方法?
谢谢!
首先,确保在处理矩阵时非常仔细地阅读 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 列包含 A
的第 i 列和 B
的第 i 列的叉积,行数预计为为 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
现在使用 V
和 cross
并保持相同的第二个输入:
>> 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
我觉得不错!
我 运行 进入了一个我似乎无法通过矢量化实现的操作。
假设我想找到
定义的应用程序矩阵h: X -> cross(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 循环实现的方法?
谢谢!
首先,确保在处理矩阵时非常仔细地阅读 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 列包含 A
的第 i 列和 B
的第 i 列的叉积,行数预计为为 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
现在使用 V
和 cross
并保持相同的第二个输入:
>> 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
我觉得不错!