Use Perl PDL to rotate a matrix
Asked Answered
S

3

5

I would like to use Perl and PDL to achieve a rotation of a 3x3 matrix (if possible)

I.e original matrix

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

I would like to rotate, around 5, so it becomes new matrix

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

Effectively this is the same as How do you rotate a two dimensional array? but I'd like to use Perl and PDL.

Thanks for your help up front.

Sholapur answered 29/1, 2014 at 14:3 Comment(0)
I
10

Perhaps not the most optimized way to do it:

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]
]
Inspiratory answered 1/2, 2014 at 3:17 Comment(2)
As was pointed out here (mailman.jach.hawaii.edu/pipermail/pdl-porters/2014-February/…) this solution doesn't reflect the full cost of the rotation, as the slice operation doesn't actually move any data around. To do so, apply the sever method to the piddle returned by the slice. Whether to do this in real code depends upon how the result will be used.Inspiratory
That URL has gone, but is available on the Wayback Machine. The reference to "full cost" is confusing for me; the transpose and slice respectively change the order of dimensions, and reorder indices, which are very cheap operations. Only sever if you want to mutate the rotated information but not the original, or vice versa.Marceline
D
6

Stupid Matrix Tricks

This might not be the answer you were looking for, but I think it's interesting. It's a purely mathematical solution since my pdl skills are piddling (ha! I bet everyone uses that joke) and as such I haven't done any benchmarking to see if it's even any faster than a double loop.

Let's define a matrix W like so:

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

W is the swap matrix. (Don't know why I called it W instead of S, but there you go.) If you have a another 3x3 matrix M and multiply W x M, it swaps the rows of M. If you multiply M x W (changing the order), it swaps the columns of M.

Using your matrix above we can swap the rows like so:

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

So to rotate the original matrix 90° counterclockwise we know we need to transpose it and then swap rows (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]

As I said before, multiplying M x W will swap the columns of 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]

Which just happens to be the transpose of the previous result W x M'! Taking the final step, we have:

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

Now we've rotated M 90° clockwise. But this is just the transpose of our original result W x M.

For our 90° rotations we then have two ways to generate each result:

Rotate counterclockwise: W  x M' = (M x W)'  
Rotate clockwise:        M' x W  = (W x M)'

Finally, for the sake of completeness, to rotate the matrix 180° you swap both the rows and the columns:

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

Well, I guess it's not totally complete since we can also do reflections and rotations of reflections as well using the swap matrix and matrix transposes, but we'll leave it there for now.

Dock answered 6/2, 2014 at 2:36 Comment(0)
H
0

More stupid matrix tricks

I'm not conversant in PDL either, but if you can "slice" the 2d matrix to a "virtual", 9 element vector, which looks possible in a cursory read of the documentation, then you can implement any permutation (including rotation) of the original 3x3 as a 9x9 permutation matrix, multiply the 1d slice by this matrix, and then refer to the original 3x3 pdl to see the result.

If I have some time I will try to learn enough of PDL to test this idea.

Hermitage answered 7/2, 2014 at 4:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.