2013-07-18 6 views
2

В математике умножаются три матрицы: «A», «B» и «C», так что четвертая матрица «D = A * B * C», тогда порядок должен быть равен вычислено справа налево. Используя круглые скобки для уточнения, предыдущий оператор в точности эквивалентен следующему; 'D = (A * (B * C))'.Порядок умножения матрицы C/C++

Вы можете видеть, как это применимо для выражения '{M = A * B * C * D} == {M = (A * (B * (C * (D))))}', которое другой пример.

В C, C++ я провел тест с использованием деления, чтобы проверить порядок выполнения операций на C и C++.

Существует, вероятно, лучший способ сделать это мой компиляции кода сборки, однако:

float a = 1.0; 
float b = 2.0; 
float c = 2.0; 
float ans = a/b/c; 
printf("answer is %f\n", ans); 

Это дает выход:

answer is 0.25 

Это говорит мне, что если бы я, чтобы создать класс для представления матрицы, то порядок умножения будет слева направо, в обратном направлении от желаемого, так как пример операций и деления с плавающей запятой оценивается слева направо, поскольку три операции имеют equa l приоритет.

В библиотеке математики OpenGL операторы матрицы GLM вычисляются в правильном порядке без необходимости в круглых скобках.

Как оператор *() должен вести себя таким образом?

Редактировать

Err, да, так что это на самом деле не важно, как это было указано мне. В этом случае мой вопрос становится «можно ли изменить порядок»? (Может быть, я сон?)

+3

Я думаю, что вы ошибаетесь в отношении умножения матрицы, это на самом деле ассоциативный. [Wikipedia link] (http://en.wikipedia.org/wiki/Matrix_multiplication#General). –

+2

Да, но это непросто. Посмотрите шаблоны выражений: в основном сохраняйте дерево выражений и оценивайте его только при назначении, позволяя произвольные преобразования дерева. – Yakk

ответ

6

Операторы C++ / и двоичные * являются ассоциативными как слева направо. Конец истории - нет способа изменить это.

Matrix multiplication is associative, хотя, чтобы это не повлияло на вас.

+0

+1 Так очень краткий – chux

3

Причина проста: матричное умножение ассоциативно; скалярное деление не. (A/(B/C)) - это не то же самое, что и ((A/B)/C). Но (A * (B * C)) - это то же, что и ((A * B) * C), как для матричного, так и для скалярного умножения.

Так что порядок, при котором C++ вызывает операторы, просто не имеет значения для матричного умножения.

+2

Умножения C++ (и glsl) и умножение матрицы НЕ являются ассоциативными, так как умножение операнда в другом порядке может изменить результаты из-за приближений и точности. '(A * (B * C))' совпадает с '((A * B) * C)' в математике, но не в C++, ни в glsl. Более того, если C - вектор вместо матрицы, то два решения будут иметь различное количество умножений. –

Смежные вопросы