Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Perl PDL to rotate a matrix

Tags:

matrix

perl

pdl

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.

like image 382
Steve Bident Avatar asked Jan 29 '14 14:01

Steve Bident


2 Answers

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]
]
like image 130
Diab Jerius Avatar answered Nov 18 '22 03:11

Diab Jerius


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.

like image 6
beaker Avatar answered Nov 18 '22 02:11

beaker