Матричное умножение MATLAB (лучший вычислительный подход)

10

Я должен сделать преобразование координат между двумя системами отсчета (осями). Для этого необходимо умножить три матрицы ( ) из-за использования некоторых промежуточных осей. Я думал о двух подходах, чтобы решить эту проблему:3×3

Способ № 1 : Выполнение умножения напрямую, то есть

vf=R1 R2 R3 vi

Способ № 2 : разделить на этапы:

  1. v3i=R3 vi
  2. v23=R2 v3i
  3. vf=R1 v23

где:

R1 , и - матрицыR2R33×3

vf , , , являются векторамиviv3iv233×1

Я хотел бы знать, какой метод является более эффективным в вычислительном отношении (меньше времени), чтобы сделать преобразование (это будет сделано много раз).

julianfperez
источник
4
Используйте кватернионы .
Крис Тейлор
@ChrisTaylor: Большое спасибо за ваше предложение.
julianfperez
2
Пожалуйста, не кросспост
Сорвал
2
Обратите внимание, что здесь были добавлены два вопроса и StackOverflow. Вопросы, их комментарии и ответы были объединены в этот.
Арон Ахмадиа
@Will и AronAhmadia: извините. Я не знал, что кросспостинг запрещен. Я всегда публиковал свои вопросы в StackOverflow, но сегодня я нашел этот новый сайт и подумал, что, возможно, смогу найти здесь помощь.
julianfperez

Ответы:

17

Matlab интерпретирует последовательности умножений и / или делений слева направо. Следовательно, намного дороже, чем , поскольку вместо трех продуктов матрицы-вектора у вас есть два матричных произведения и один матрично-векторный продукт.A ( B ( C v ) )ABCvA(B(Cv))

С другой стороны, должно быть немного быстрее, чем если вы сохраните промежуточные продукты в отдельных векторах, как предполагает ваш второй метод.A(B(Cv))

Чтобы узнать, как измерить влияние небольших различий в программировании на крупномасштабные вычисления, напишите в приглашении Matlab «Справочный профиль».

Арнольд Ноймайер
источник
Спасибо за интересную информацию, приведенную в вашем ответе.
julianfperez
Почему это быстрее, если вы сохраняете промежуточные продукты?
Федерико Полони,
@FedericoPoloni: я написал, что это немного быстрее, чтобы не сохранить промежуточные звенья .
Арнольд
@ArnoldNeumaier Ой, извините, я неправильно прочитал. :)
Федерико Полони
14

Для начала я бы не использовал промежуточные переменные, а только скобки. Если, конечно, вы заинтересованы в промежуточных результатах, но я думаю, нет.

Я попробовал следующее в Matlab:

>> N = 500;                                             
>> A = rand(N); B = rand(N); C = rand(N); v = rand(N,1);

>> tic, for k=1:100, A*B*C*v; end; toc
Elapsed time is 3.207299 seconds.

>> tic, for k=1:100, A*(B*(C*v)); end; toc
Elapsed time is 0.108095 seconds.

Я должен сказать, однако, что это довольно страшно. Я всегда предполагал, что Matlab будет умно относиться к порядку умножения матриц, поскольку это известная проблема с простыми и эффективными решениями.

Pedro
источник
Вы пропустили ту часть, где матрицы 3х3? :)
Арон Ахмадиа
2
@AronAhmadia: Упс ... Пропустил это, спасибо. Я предполагаю, что для этих размеров матрицы вся проблема спорная, но я все еще удивлен результатами для больших N.
Педро
7
Я предполагаю, что MATLAB следует правилам приоритета C для вычисления выражений, потому что математика с плавающей запятой не ассоциативна, и они должны предположить, что вы знаете, что делаете :)
Aron Ahmadia
2
@Pedro: Спасибо за ваш ответ. Для размерности матрицы 3x3 я проверил, что ваше решение также лучше, чем обычное (без скобок) умножение матрицы.
julianfperez
+1 спасибо, что показали простой и легкий способ измерить время выполнения
Стивен Магана-Зук
14

Поскольку матрицы настолько малы, все затраты будут связаны с накладными расходами. Если вы будете выполнять преобразование много раз, будет быстрее выполнить предварительный расчет D=A*B*Cодин раз, а затем для каждого вектора применить v_f=D*v_i. Вы также можете рассмотреть возможность переноса этого в мекс файл.

Арон Ахмадия
источник
Спасибо за ваш ответ. В моем случае матрицы являются вращательными (они зависят от углового значения, и это изменяется), поэтому произведение A B C не всегда одинаково.
julianfperez