【问题标题】:Use Perl PDL to rotate a matrix使用 Perl PDL 旋转矩阵
【发布时间】:2014-02-21 09:22:44
【问题描述】:

我想使用 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。

感谢您的帮助。

【问题讨论】:

    标签: perl matrix pdl


    【解决方案1】:

    也许不是最优化的方法:

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

    【讨论】:

    • 正如此处所指出的 (mailman.jach.hawaii.edu/pipermail/pdl-porters/2014-February/…),此解决方案并未反映旋转的全部成本,因为切片操作实际上并未移动任何数据。为此,请将 sever 方法应用于切片返回的 piddle。是否在实际代码中执行此操作取决于如何使用结果。
    【解决方案2】:

    愚蠢的矩阵技巧

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

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

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

    W 是交换矩阵。 (不知道为什么我把它叫做 W 而不是 S,但你去吧。)如果你有另一个 3x3 矩阵 M 并乘以 W x M,它会交换 @987654326 的 rows @。如果您将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-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]
    

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

    【讨论】:

      【解决方案3】:

      更多愚蠢的矩阵技巧

      我也不精通 PDL,但如果您可以将二维矩阵“切片”为“虚拟”的 9 元素向量(粗略阅读文档中看起来可能),那么您可以实现任何排列(包括旋转)将原 3x3 转换为 9x9 置换矩阵,将 1d 切片乘以该矩阵,然后参考原 3x3 pdl 即可查看结果。

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

      【讨论】:

        猜你喜欢
        • 2014-10-30
        • 2019-07-13
        • 2019-11-17
        • 2015-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-08
        相关资源
        最近更新 更多