5

我想使用 Perl 和 PDL 来实现 3x3 矩阵的旋转(如果可能)

即原始矩阵

[ 1, 2, 3 ]
[ 4, 5, 6 ]
[ 7, 8, 9 ]

我想旋转 5 左右,所以它变成了新的矩阵

[ 3, 6, 9 ]
[ 2, 5, 8 ]
[ 1, 4, 7 ]

实际上,这与如何旋转二维数组?但我想使用 Perl 和 PDL。

感谢您的帮助。

4

3 回答 3

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]
]
于 2014-02-01T03:17:32.437 回答
5

愚蠢的矩阵技巧

这可能不是您要寻找的答案,但我认为这很有趣。这是一个纯粹的数学解决方案,因为我的 pdl 技能很无聊(哈!我打赌每个人都在开玩笑),因此我没有做任何基准测试来看看它是否比双循环更快。

让我们像这样定义一个矩阵W

    [0 0 1]
W = [0 1 0]
    [1 0 0]

W是交换矩阵。(不知道为什么我称它为 W 而不是 S,但你去了。)如果你有另一个 3x3 矩阵multiply MW x M它交换. 如果乘法(更改顺序),它会交换.MM x WM

使用上面的矩阵,我们可以像这样交换行:

        [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'is M-transpose):

         [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]

好吧,我想这还不是完全完整的,因为我们也可以使用交换矩阵和矩阵转置来进行反射和反射旋转,但我们暂时将其留在那里。

于 2014-02-06T02:36:44.100 回答
0

更多愚蠢的矩阵技巧

我也不熟悉 PDL,但是如果您可以将 2d 矩阵“切片”为“虚拟”的 9 元素向量,在粗略阅读文档时看起来可能,那么您可以实现任何排列(包括旋转)将原来的 3x3 作为 9x9 置换矩阵,将 1d 切片乘以这个矩阵,然后参考原来的 3x3 pdl 看看结果。

如果我有时间,我会尝试学习足够多的 PDL 来测试这个想法。

于 2014-02-07T04:38:29.697 回答