The Gandalf routines involving a matrix for the first of these (no transpose of ) is

Gan_Vector4 v4x; Gan_Vector3 v3y; Gan_Matrix34 m34A; /* ... set up m34A and v4x ... */ gan_mat34_multv4_q ( &m34A, &v4x, &v3y ); /* macro, or */ v3y = gan_mat34_multv4_s ( &m34A, &v4x ); /* function call */while if is to be transposed then the routines are

Gan_Vector3 v3x; Gan_Vector4 v4y; Gan_Matrix34 m34A; /* ... set up m34A and v3x ... */ gan_mat34T_multv3_q ( &m34A, &v3x, &v4y ); /* macro, or */ v4y = gan_mat34T_multv3_s ( &m34A, &v3x ); /* function call */There are similar routines

Gan_Vector3 v3x, v3y; Gan_SquMatrix33 sm33S; /* ... set up sm33S using e.g. gan_symmat33_fill_q(), and v3x ... */ gan_symmat33_multv3_q ( &sm33S, &v3x, &v3y ); /* macro, or */ v3y = gan_symmat33_multv3_s ( &sm33S, &v3x ); /* function call */In the case that matrix is triangular, Gandalf also supports multiplication of vectors by the inverse of . In this case the result may be computed in-place in the input vector, So the complete set of matrix/vector multiplication routines for triangular matrices is

Gan_Vector3 v3x, v3y; Gan_SquMatrix33 sm33L; /* ... set up sm33L using e.g. gan_ltmat33_fill_q(), and v3x ... */ /* multiply vector by lower triangular matrix */ gan_ltmat33_multv3_q ( &sm33L, &v3x, &v3y ); /* macro, or */ v3y = gan_ltmat33_multv3_s ( &sm33L, &v3x ); /* function call, or */ gan_ltmat33_multv3_i ( &sm33L, &v3x ); /* macro, in-place in v3x */ /* multiply vector by upper triangular matrix */ gan_ltmat33T_multv3_q ( &sm33L, &v3x, &v3y ); /* macro, or */ v3y = gan_ltmat33T_multv3_s ( &sm33L, &v3x ); /* function call, or */ gan_ltmat33T_multv3_i ( &sm33L, &v3x ); /* macro, in-place in v3x */ /* multiply vector by inverse of lower triangular matrix */ gan_ltmat33I_multv3_q ( &sm33L, &v3x, &v3y ); /* macro, or */ v3y = gan_ltmat33I_multv3_s ( &sm33L, &v3x ); /* function call, or */ gan_ltmat33I_multv3_i ( &sm33L, &v3x ); /* macro, in-place in v3x */ /* multiply vector by inverse of upper triangular matrix */ gan_ltmat33IT_multv3_q ( &sm33L, &v3x, &v3y ); /* macro, or */ v3y = gan_ltmat33IT_multv3_s ( &sm33L, &v3x ); /* function call, or */ gan_ltmat33IT_multv3_i ( &sm33L, &v3x ); /* macro, in-place in v3x */

**Error detection:** If implicit inverse is used (the `...I_multv...()`
or `...IT_multv...()` 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.