Операция умножения матрицы на матрицу. Есть операция которая принимает на вход две матрицы и выдаёт одну.
Пусть даны две прямоугольные матрицы <math>A </math> и <math>B </math> размерности <math>m \times n </math> и <math>n \times q </math> соответственно:
<math>
A =
\begin{bmatrix} a_{11} & a_{12} & \cdots & a_{1n} \\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \cdots & a_{mn} \end{bmatrix},\;
B =
\begin{bmatrix} b_{11} & b_{12} & \cdots & b_{1q} \\ b_{21} & b_{22} & \cdots & b_{2q} \\ \vdots & \vdots & \ddots & \vdots \\ b_{n1} & b_{n2} & \cdots & b_{nq} \end{bmatrix}.
</math>
Тогда матрица <math>C </math> размерностью <math>m \times q </math> называется их произведением
:
<math>
C =
\begin{bmatrix} c_{11} & c_{12} & \cdots & c_{1q} \\ c_{21} & c_{22} & \cdots & c_{2q} \\ \vdots & \vdots & \ddots & \vdots \\ c_{m1} & c_{m2} & \cdots & c_{mq} \end{bmatrix}
</math>;
где:
<math> c_{ij} = \sum_{k=1}^n a_{ik}b_{kj} \;\;\; \left(i=1, 2, \ldots m;\; j=1, 2, \ldots q \right) </math>.
Операция умножения двух матриц выполнима только в том случае, если число столбцов в первом сомножителе равно числу строк во втором; в этом случае говорят, что форма матриц согласована
. В частности, умножение всегда выполнимо, если оба сомножителя являются квадратными матрицами одного и того же порядка.
Следует заметить, что из существования произведения <math>AB </math> вовсе не следует существование произведения <math>BA </math>.
Сочетательное свойство
:
<math>\mathbf{A} ( \mathbf{B C} ) = ( \mathbf{A B} ) \mathbf{C}</math>;
<math>\lambda (\mathbf{AB}) = (\lambda\mathbf{A}) \mathbf{B} = \mathbf{A}(\lambda\mathbf{B})</math>.
Распределительное свойство
:
<math>\mathbf{A} ( \mathbf{B} + \mathbf{C} ) = \mathbf{A B} + \mathbf{AC}</math>;
<math>( \mathbf{A} + \mathbf{B} ) \mathbf{C} = \mathbf{A C} + \mathbf{B C}</math>.
Произведение матрицы на единичную матрицу <math>\mathbf{I}</math> подходящего порядка равно самой матрице:
<math>\mathbf{IA} = \mathbf{A}</math>;
<math>\mathbf{AI} = \mathbf{A}</math>.
Произведение матрицы на нулевую матрицу <math>\mathbf{0}</math> подходящей размерности равно нулевой матрице:
<math>\mathbf{0A} = \mathbf{0}</math>;
<math>\mathbf{A0} = \mathbf{0}</math>.
Если <math>\mathbf{A}</math> и <math>\mathbf{B}</math> — квадратные матрицы одного и того же порядка, то произведение матриц обладает ещё рядом свойств.
Умножение матриц в целом некоммутативно:
<math>\mathbf{AB} \ne \mathbf{BA}</math>.
Если <math>\mathbf{AB} = \mathbf{BA}</math>, то матрицы <math>\mathbf{A}</math> и <math>\mathbf{B}</math> называются перестановочными или коммутирующими между собой.
Определитель и след произведения не зависят от порядка умножения матриц:
<math>\det(\mathbf{AB}) = \det(\mathbf{BA}) = \det \mathbf{A} \cdot \det\mathbf{B}</math>;
<math>\mbox{tr}(\mathbf{AB}) = \mbox{tr}(\mathbf{BA})</math>.
Если матрица не вырождена, то у неё есть обратная матрица. Такая что произведение исходной и обратной даёт единичную матрицу.
<math> AA^{-1} = A^{-1}A = I</math>.
Существует большое число алгоритмов умножения. И целый ряд быстрых алгоритмов основанных на группировки операций.
procedure Mul_Base(Var R:TMatrixNM; A:TMatrixNM; B:TMatrixNM); var i, j, k: Integer; N,M,Q:Integer; Tmp:Real; begin M:=RowsCount(A); N:=ColumnsCount(A); Q:=ColumnsCount(B); for i:=0 to M-1 do for j:=0 to Q-1 do begin Tmp:=0; for k:=0 to N-1 do Tmp:=Tmp+A[i,k]*B[k,j]; R[i,j]:=Tmp; end; end;
Входные параметры:
Выходные параметры:
Примечание:
Описание:
Идея алгоритма в том, что-бы ускорить умножения предварительно транспонировать вторую матрицу. Тогда обращение к элементам второй матрицы будет линейно по памяти, что даёт прирост. См. быстрый(блочный) алгоритм транспонирования.
Помимо ускорения за счёт более оптимального использования доступа к памяти. Возможно использовать аппаратное распараллеливание при помощи команд SIMD(одна инструкция много данных)для ускорения обработки, обрабатывая за раз 4 числа.
В DirectX матрицы мира и вида хранятся и задаются в транспонированном виде. Поэтому во время работы программы матрицы уже транспонированы и их не надо транспонировать.
procedure Transpose_Mul(Var R:TMatrixNM; A:TMatrixNM; B:TMatrixNM); var i, j, k: Integer; N,M,Q:Integer; Tmp:Real; C:TMatrixNM; begin if IsMatrixTranspose(B) then C:=B else FastTranspose(C,B); M:=RowsCount(A); N:=ColumnsCount(A); Q:=RowsCount(С); for i:=0 to M-1 do for j:=0 to Q-1 do begin Tmp:=0; for k:=0 to N-1 do Tmp:=Tmp+A[i,k]*C[j,k]; R[i,j]:=Tmp; end; end;
Строки:
Tmp:=0; for k:=0 to N-1 do Tmp:=Tmp+A[i,k]*C[j,k]; R[i,j]:=Tmp;
можно заменить векторным умножением
R[i,j]:=DotProduct(A[i],B[j]);
Строки:
if IsMatrixTranspose(B) then C:=B else FastTranspose(C,B);
Если на перёд известно, что матрица транспонирована, то достаточно вместо этих 2-х строк переименовать C в B.
<math>A=\left[\begin{array}{ccccc} A_1 & A_2
A_3 & A_4
\end{array}\right]</math>;
<math>B=\left[\begin{array}{ccccc} B_1 & B_2
B_3 & B_4
\end{array}\right]</math>;
<math>C=A*B</math>;
<math>C=\left[\begin{array}{ccccc} A_1*B_1+A_2*B_3 & A_1*B_2+A_2*B_4
A_3*B_1+A_4*B_3 & A_3*B_2+A_4*B_4
\end{array}\right]</math>;
Список литературы:
[1] http://ru.wikipedia.org/wiki/Умножение_матриц
[2] Р. Блейхут Быстрые алгоритмы цифровой обработки сигналов
[3] http://www.youtube.com/watch?v=llwuoLzPbdE
[4] http://msdn.microsoft.com/en-us/library/windows/desktop/bb206269(v=vs.85).aspx