我想使用Perl和PDL来实现3x3矩阵的旋转(如果可能的话)
原始矩阵
[ 1, 2, 3 ]
[ 4, 5, 6 ]
[ 7, 8, 9 ]
我想旋转,大约5,所以它变成了新的矩阵
[ 3, 6, 9 ]
[ 2, 5, 8 ]
[ 1, 4, 7 ]
实际上这与How do you rotate a two dimensional array?相同,但我想使用Perl和PDL。
先谢谢你的帮助。
答案 0 :(得分:10)
也许不是最优化的方式:
pdl> $m = sequence(3,3)+1
pdl> p $m
[
[1 2 3]
[4 5 6]
[7 8 9]
]
pdl> p $m->transpose->slice( ':', '-1:0' )
[
[3 6 9]
[2 5 8]
[1 4 7]
]
答案 1 :(得分:5)
这可能不是你想要的答案,但我认为这很有趣。这是一个纯粹的数学解决方案,因为我的pdl技能很小(哈!我打赌每个人都使用这个笑话),因此我没有做任何基准测试,看看它是否比双循环更快。
让我们像这样定义一个矩阵W
:
[0 0 1]
W = [0 1 0]
[1 0 0]
W
是交换矩阵。 (不知道为什么我称之为W而不是S,但是你去了。)如果你有另一个3x3矩阵M
并乘以W x M
,它会交换行 M
。如果您乘以M x W
(更改顺序),则会交换M
的列。
使用上面的矩阵我们可以像这样交换行:
[0 0 1] [1 2 3] [7 8 9]
W x M = [0 1 0] x [4 5 6] = [4 5 6]
[1 0 0] [7 8 9] [1 2 3]
所以要逆时针旋转原始矩阵90°我们知道我们需要转置它然后交换行(M'
是M
- 转置):
[0 0 1] [1 4 7] [3 6 9]
W x M' = [0 1 0] x [2 5 8] = [2 5 8]
[1 0 0] [3 6 9] [1 4 7]
正如我之前所说,乘以M x W
会交换M
的列:
[1 2 3] [0 0 1] [3 2 1]
M x W = [4 5 6] x [0 1 0] = [6 5 4]
[7 8 9] [1 0 0] [9 8 7]
恰好是之前结果W x M'
的转置!采取最后一步,我们有:
[1 4 7] [0 0 1] [7 4 1]
M' x W = [2 5 8] x [0 1 0] = [8 5 2]
[3 6 9] [1 0 0] [9 6 3]
现在我们顺时针旋转了M
90°。但这只是我们原始结果W x M
的转置。
对于我们的90°旋转,我们有两种方法来生成每个结果:
Rotate counterclockwise: W x M' = (M x W)'
Rotate clockwise: M' x W = (W x M)'
最后,为了完整起见,要将矩阵旋转180°,您可以交换行和列:
[0 0 1] [1 2 3] [0 0 1] [7 8 9] [0 0 1] [9 8 7]
W x M x W = [0 1 0] x [4 5 6] x [0 1 0] = [4 5 6] x [0 1 0] = [6 5 4]
[1 0 0] [7 8 9] [1 0 0] [1 2 3] [1 0 0] [3 2 1]
嗯,我猜它不是完全完成,因为我们也可以使用交换矩阵和矩阵转置进行反射和旋转反射,但我们暂时将它留在那里。
答案 2 :(得分:0)
更愚蠢的矩阵技巧
我也不熟悉PDL,但是如果你可以将2d矩阵“切片”为“虚拟”,9元素向量,在粗略阅读文档时看起来可能,那么你可以实现任何排列(包括旋转)原始3x3作为9x9置换矩阵,将1d切片乘以该矩阵,然后参考原始的3x3 pdl以查看结果。
如果我有时间,我会尝试学习足够的PDL来测试这个想法。