Используйте Perl PDL для вращения матрицы

Я хотел бы использовать Perl и PDL для достижения поворота матрицы 3х3 (если это возможно)

Т.е. оригинальная матрица

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

Я хотел бы повернуть, около 5, чтобы он стал новой матрицей

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

По сути, это то же самое, что и Как вы вращаете двумерный массив? но я бы хотел использовать Perl и PDL.

Спасибо за вашу помощь заранее.

3 ответа

Решение

Возможно, не самый оптимизированный способ сделать это:

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

Тупые Матричные Трюки

Возможно, это не тот ответ, который вы искали, но я думаю, что это интересно. Это чисто математическое решение, так как мои навыки работы с 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-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]

Ну, я думаю, что это не полностью завершено, так как мы можем также делать отражения и повороты отражений, также используя матрицу подкачки и транспонирование матрицы, но мы пока оставим это там.

Более глупые матричные трюки

Я также не знаком с PDL, но если вы можете "нарезать" 2d матрицу на "виртуальный" вектор из 9 элементов, что выглядит возможным при кратком чтении документации, то вы можете реализовать любую перестановку (включая вращение) исходной 3x3 как матрицы перестановок 9x9, умножьте 1d срез на эту матрицу, а затем обратитесь к исходной 3x3 pdl, чтобы увидеть результат.

Если у меня будет время, я постараюсь выучить достаточно PDL, чтобы проверить эту идею.

Другие вопросы по тегам