next up previous contents
Next: Fixed size matrix inverse Up: Fixed size matrices Previous: Fixed size matrix/vector multiplication   Contents

Fixed size matrix/matrix multiplication

Most useful matrix product combinations are supported by Gandalf. Here we describe all the combinations involving $3\times 4$ matrices. The first functions to describe are those which involve multiplication by a $3\times 3$ on the left or $4\times 4$ matrix on the right, the square matrix optionally being (implicitly) transposed, the product producing another $3\times 4$ matrix. The operator combinations are

\begin{displaymath}D_{3\times 4} = B_{3\times 3} A_{3\times 4},\;\;\;
D_{3\time...
... 4},\;\;\;
D_{3\times 4} = A_{3\times 4} C_{4\times 4}^{\top}
\end{displaymath}

which are implemented in Gandalf using the macros
      Gan_Matrix34 m34A, m34D;
      Gan_Matrix33 m33B;
      Gan_Matrix44 m44C;

      /* ... set up m34A, m33B and m44C ... */
      gan_mat34_lmultm33_q  ( &m34A, &m33B, &m34D ); /* D = B*A   */
      gan_mat34_lmultm33T_q ( &m34A, &m33B, &m34D ); /* D = B*A^T */
      gan_mat34_rmultm44_q  ( &m34A, &m44C, &m34D ); /* D = A*C   */
      gan_mat34_rmultm44T_q ( &m34A, &m44C, &m34D ); /* D = A*C^T */
Equivalent function calls are available:
      m34D = gan_mat34_lmultm33_s  ( &m34A, &m33B ); /* D = B*A   */
      m34D = gan_mat34_lmultm33T_s ( &m34A, &m33B ); /* D = B*A^T */
      m34D = gan_mat34_rmultm44_s  ( &m34A, &m44C ); /* D = A*C   */
      m34D = gan_mat34_rmultm44T_s ( &m34A, &m44C ); /* D = A*C^T */
Note that although by and large the functions described here for $3\times 4$ matrices are repeated for square matrices, there is redundancy because in the case of $3\times 3$ matrices the routines
      m33D = gan_mat33_lmultm33_s  ( &m33A, &m33B ); /* D = B*A   */
      m33D = gan_mat33_rmultm33_s  ( &m33B, &m33A ); /* D = B*A   */
would be equivalent, so in fact only the routines gan_mat33_rmultm33_[qs]() are defined.

The square matrix may be symmetric or triangular, for which cases there are specific Gandalf functions. Firstly for multiplying by symmetric matrices we have the routines

      Gan_Matrix34 m34A, m34B;
      Gan_SquMatrix33 sm33S;
      Gan_SquMatrix44 sm44S;

      /* ... set up m34A, symmetric sm33S and sm44S ... */
      gan_mat34_lmults33_q ( &m34A, &sm33S, &m34B ); /* B = S*A, macro */
      gan_mat34_rmults44_q ( &m34A, &sm44S, &m34B ); /* B = A*S, macro */
with equivalent function calls
      m34B = gan_mat34_lmults33_q ( &m34A, &sm33S ); /* B = S*A, function call */
      m34B = gan_mat34_rmults44_q ( &m34A, &sm44S ); /* B = A*S, function call */
When multiplying by a triangular matrix, there are also options of implicit transpose and inverse, as described in the introduction to this chapter. Gandalf also supports in-place operations in this case. So there is a whole family of functions covering multiplication of a matrix by a triangular matrix. Mathematically the operations are

\begin{displaymath}B=LA, \;\;\; B=L^{\top}A, \;\;\; B=L^{-1}A, \;\;\; B=L^{-\top}A
\end{displaymath}


\begin{displaymath}B=AL, \;\;\; B=AL^{\top}, \;\;\; B=AL^{-1}, \;\;\; B=AL^{-\top}
\end{displaymath}

Gandalf macro routines to implement these operations are
      Gan_Matrix34 m34A, m34B;
      Gan_SquMatrix33 sm33L;
      Gan_SquMatrix44 sm44L;

      /* ... set up m34A, lower triangular sm33L and sm44L ... */
      gan_mat34_lmultl33_q   ( &m34A, &sm33L, &m34B ); /* B = L*A,    macro */
      gan_mat34_lmultl33T_q  ( &m34A, &sm33L, &m34B ); /* B = L^T*A,  macro */
      gan_mat34_lmultl33I_q  ( &m34A, &sm33L, &m34B ); /* B = L^-1*A, macro */
      gan_mat34_lmultl33IT_q ( &m34A, &sm33L, &m34B ); /* B = L^-T*A, macro */
      gan_mat34_rmultl44_q   ( &m34A, &sm44L, &m34B ); /* B = A*L,    macro */
      gan_mat34_rmultl44T_q  ( &m34A, &sm44L, &m34B ); /* B = A*L^T,  macro */
      gan_mat34_rmultl44I_q  ( &m34A, &sm44L, &m34B ); /* B = A*L^-1, macro */
      gan_mat34_rmultl44IT_q ( &m34A, &sm44L, &m34B ); /* B = A*L^-T, macro */
There are also function calls to implement the same operations:
      m34B = gan_mat34_lmultl33_s   ( &m34A, &sm33L ); /* B = L*A,    function call */
      m34B = gan_mat34_lmultl33T_s  ( &m34A, &sm33L ); /* B = L^T*A,  function call */
      m34B = gan_mat34_lmultl33I_s  ( &m34A, &sm33L ); /* B = L^-1*A, function call */
      m34B = gan_mat34_lmultl33IT_s ( &m34A, &sm33L ); /* B = L^-T*A, function call */
      m34B = gan_mat34_rmultl44_s   ( &m34A, &sm44L ); /* B = A*L,    function call */
      m34B = gan_mat34_rmultl44T_s  ( &m34A, &sm44L ); /* B = A*L^T,  function call */
      m34B = gan_mat34_rmultl44I_s  ( &m34A, &sm44L ); /* B = A*L^-1, function call */
      m34B = gan_mat34_rmultl44IT_s ( &m34A, &sm44L ); /* B = A*L^-T, function call */
Finally there is a set of macros for writing the result in-place into the $3\times 4$ matrix $A$.
      gan_mat34_lmultl33_i   ( &m34A, &sm33L ); /* A = L*A,    macro */
      gan_mat34_lmultl33T_i  ( &m34A, &sm33L ); /* A = L^T*A,  macro */
      gan_mat34_lmultl33I_i  ( &m34A, &sm33L ); /* A = L^-1*A, macro */
      gan_mat34_lmultl33IT_i ( &m34A, &sm33L ); /* A = L^-T*A, macro */
      gan_mat34_rmultl44_i   ( &m34A, &sm44L ); /* A = A*L,    macro */
      gan_mat34_rmultl44T_i  ( &m34A, &sm44L ); /* A = A*L^T,  macro */
      gan_mat34_rmultl44I_i  ( &m34A, &sm44L ); /* A = A*L^-1, macro */
      gan_mat34_rmultl44IT_i ( &m34A, &sm44L ); /* A = A*L^-T, macro */

The next set of functions deals with multiplying a matrix by itself in transpose, resulting in a symmetric matrix. These operations have the form

\begin{displaymath}S_{4\times 4} = A_{3\times 4}^{\top}A_{3\times 4}\;\;\;\;\mbox{OR}\;\;\;\;
S_{3\times 3} = A_{3\times 4} A_{3\times 4}^{\top}
\end{displaymath}

The Gandalf macro routines to implement these operations are
      Gan_Matrix34 m34A;
      Gan_SquMatrix33 sm33S;
      Gan_SquMatrix44 sm44S;

      /* ... set up m34A using e.g. gan_mat34_fill_q() ... */
      gan_mat34_slmultT_q ( &m34A, &sm44S ); /* S = A^T*A */
      gan_mat34_srmultT_q ( &m34A, &sm33S ); /* S = A*A^T */
with equivalent function calls
      sm44S = gan_mat34_slmultT_s ( &m34A ); /* S = A^T*A */
      sm33S = gan_mat34_srmultT_s ( &m34A ); /* S = A*A^T */
There are similar routines for general $3\times 3$ matrices. For triangular matrices the functions are
      Gan_SquMatrix33 sm33L, sm33S;

      /* ... set up sm33L using e.g. gan_ltmat33_fill_q()... */
      gan_ltmat33_slmultT_q ( &sm33L, &sm33S ); /* S = L^T*L, macro */
      sm33S = gan_ltmat33_slmultT_s ( &sm33L ); /* S = L^T*L, function call */
      gan_ltmat33_srmultT_q ( &sm33L, &sm33S ); /* S = L*L^T, macro */
      sm33S = gan_ltmat33_srmultT_s ( &sm33L ); /* S = L*L^T, function call */
In the case of triangular matrices the operation ``multiply by transposed self'' can also be done in-place, so we also have the macro routines
      Gan_SquMatrix33 sm33A;

      /* ... set up sm33A as triangular using e.g. gan_ltmat33_fill_q()... */
      gan_ltmat33_slmultT_i ( &sm33A ); /* A = A^T*A, macro */
      gan_ltmat33_srmultT_i ( &sm33A ); /* A = A*A^T, macro */

There are also routines to multiply a matrix by the transpose of another matrix of the same size, where the result is assumed to be a symmetric matrix. So mathematically the operations have the form

\begin{displaymath}S_{4\times 4} = A_{3\times 4}^{\top}B_{3\times 4}\;\;\;\;\mbox{OR}\;\;\;\;
S_{3\times 3} = A_{3\times 4} B_{3\times 4}^{\top}
\end{displaymath}

The Gandalf macro routines to implement these operations are
      Gan_Matrix34 m34A, m34B;
      Gan_SquMatrix33 sm33S;
      Gan_SquMatrix44 sm44S;

      /* ... set up m34A, m34B using e.g. gan_mat34_fill_q() ... */
      gan_mat34_rmultm34T_sym_q ( &m34A, &m34B, &sm33S ); /* S = A*B^T */
      gan_mat34_lmultm34T_sym_q ( &m34B, &m34A, &sm44S ); /* S = A^T*B */
with equivalent function calls
      sm33S = gan_mat34_rmultm34T_sym_s ( &m34A, &m34B ); /* S = A*B^T */
      sm44S = gan_mat34_lmultm34T_sym_s ( &m34B, &m34A ); /* S = A^T*B */

A common operation is to multiply a symmetric matrix on left and right by a matrix and its transpose, producing another symmetric matrix. Gandalf supports all combinations of these operations. Those involving $3\times 4$ matrices are

      Gan_SquMatrix33 sm33Sa;
      Gan_SquMatrix44 sm44Sb;
      Gan_Matrix34 m34A;

      gan_symmat33_lrmultm34T_q ( &sm33Sa, &m34A, &sm44Sb ); /* Sb = A^T*Sa*A, macro */
      sm44Sb = gan_symmat33_lrmultm34T_s ( &sm33Sa, &m34A ); /* Sb = A^T*Sa*A, function call */
      gan_symmat44_lrmultm34_q ( &sm44Sb, &m34A, &sm33Sa ); /* Sa = A*Sb*A^T, macro */
      sm33Sa = gan_symmat44_lrmultm34_s ( &sm44Sb, &m34A ); /* Sa = A*Sb*A^T, function call */

Error detection: If implicit inverse is used (e.g. the ...multl33I_[qsi]() or ...multl33IT_[qsi]() routines), the matrix must be non-singular, which for triangular matrices means that none of the diagonal elements should be zero. If the matrix was produced by successful Cholesky factorisation of a symmetric matrix (see Section 3.1.2.12) the matrix is guaranteed to be non-singular. This is the normal method of creating a triangular matrix, and Gandalf uses assert() to check for the singularity of the matrix.


next up previous contents
Next: Fixed size matrix inverse Up: Fixed size matrices Previous: Fixed size matrix/vector multiplication   Contents
2006-03-17