Imath
<navlinks>
<page>

# Matrix Functions

    #include <Imath/ImathMatrixAlgo.h>

Functions that operate on matrices

template<class T>
bool Imath::extractScaling(const Matrix44<T> &mat, Vec3<T> &scl, bool exc = true)

  Extract the scaling component of the given 4x4 matrix.

  Parameters:

    - mat – [in] The input matrix

    - scl – [out] The extracted scale, i.e. the output value

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

  Returns:

    True if the scale could be extracted, false if the matrix is degenerate.

template<class T>
Matrix44<T> Imath::sansScaling(const Matrix44<T> &mat, bool exc = true)

  Return the given 4x4 matrix with scaling removed.

  Parameters:

    - mat – [in] The input matrix

    - exc – [in] If true, throw an exception if the scaling in `mat`

template<class T>
bool Imath::removeScaling(Matrix44<T> &mat, bool exc = true)

  Remove scaling from the given 4x4 matrix in place.

  Return true if the scale could be successfully extracted, false if the matrix is degenerate.

  Parameters:

    - mat – [in] The matrix to operate on

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

  Returns:

    True if the scale could be extracted, false if the matrix is degenerate.

template<class T>
bool Imath::extractScalingAndShear(const Matrix44<T> &mat, Vec3<T> &scl, Vec3<T> &shr, bool exc = true)

  Extract the scaling and shear components of the given 4x4 matrix.

  Return true if the scale could be successfully extracted, false if the matrix is degenerate.

  Parameters:

    - mat – [in] The input matrix

    - scl – [out] The extracted scale

    - shr – [out] The extracted shear

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

  Returns:

    True if the scale could be extracted, false if the matrix is degenerate.

template<class T>
Matrix44<T> Imath::sansScalingAndShear(const Matrix44<T> &mat, bool exc = true)

  Return the given 4x4 matrix with scaling and shear removed.

  Parameters:

    - mat – [in] The input matrix

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

template<class T>
void Imath::sansScalingAndShear(Matrix44<T> &result, const Matrix44<T> &mat, bool exc = true)

  Extract scaling and shear from the given 4x4 matrix in-place.

  Parameters:

    - result – [inout] The output matrix

    - mat – [in] The return value if `result` is degenerate

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

template<class T>
bool Imath::removeScalingAndShear(Matrix44<T> &mat, bool exc = true)

  Remove scaling and shear from the given 4x4 matrix in place.

  Parameters:

    - mat – [inout] The matrix to operate on

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

  Returns:

    True if the scale could be extracted, false if the matrix is degenerate.

template<class T>
bool Imath::extractAndRemoveScalingAndShear(Matrix44<T> &mat, Vec3<T> &scl, Vec3<T> &shr, bool exc = true)

  Remove scaling and shear from the given 4x4 matrix in place, returning the extracted values.

  Parameters:

    - mat – [inout] The matrix to operate on

    - scl – [out] The extracted scale

    - shr – [out] The extracted shear

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

  Returns:

    True if the scale could be extracted, false if the matrix is degenerate.

template<class T>
void Imath::extractEulerXYZ(const Matrix44<T> &mat, Vec3<T> &rot)

  Extract the rotation from the given 4x4 matrix in the form of XYZ euler angles.

  Parameters:

    - mat – [in] The input matrix

    - rot – [out] The extracted XYZ euler angle vector

template<class T>
void Imath::extractEulerZYX(const Matrix44<T> &mat, Vec3<T> &rot)

  Extract the rotation from the given 4x4 matrix in the form of ZYX euler angles.

  Parameters:

    - mat – [in] The input matrix

    - rot – [out] The extracted ZYX euler angle vector

template<class T>
Quat<T> Imath::extractQuat(const Matrix44<T> &mat)

  Extract the rotation from the given 4x4 matrix in the form of a quaternion.

  Parameters:

    mat – [in] The input matrix

  Returns:

    The extracted quaternion

template<class T>
bool Imath::extractSHRT(const Matrix44<T> &mat, Vec3<T> &s, Vec3<T> &h, Vec3<T> &r, Vec3<T> &t, bool exc, typename Euler<T>::Order rOrder)

  Extract the scaling, shear, rotation, and translation components of the given 4x4 matrix.

  The values are such that:

      M = S * H * R * T

  Parameters:

    - mat – [in] The input matrix

    - s – [out] The extracted scale

    - h – [out] The extracted shear

    - r – [out] The extracted rotation

    - t – [out] The extracted translation

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

    - rOrder – [in] The order with which to extract the rotation

  Returns:

    True if the values could be extracted, false if the matrix is degenerate.

template<class T>
bool Imath::extractSHRT(const Matrix44<T> &mat, Vec3<T> &s, Vec3<T> &h, Vec3<T> &r, Vec3<T> &t, bool exc = true)

  Extract the scaling, shear, rotation, and translation components of the given 4x4 matrix.

  Parameters:

    - mat – [in] The input matrix

    - s – [out] The extracted scale

    - h – [out] The extracted shear

    - r – [out] The extracted rotation, in XYZ euler angles

    - t – [out] The extracted translation

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

  Returns:

    True if the values could be extracted, false if the matrix is degenerate.

template<class T>
bool Imath::extractSHRT(const Matrix44<T> &mat, Vec3<T> &s, Vec3<T> &h, Euler<T> &r, Vec3<T> &t, bool exc = true)

  Extract the scaling, shear, rotation, and translation components of the given 4x4 matrix.

  Parameters:

    - mat – [in] The input matrix

    - s – [out] The extracted scale

    - h – [out] The extracted shear

    - r – [out] The extracted rotation, in Euler angles

    - t – [out] The extracted translation

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

  Returns:

    True if the values could be extracted, false if the matrix is degenerate.

template<class T>
bool Imath::checkForZeroScaleInRow(const T &scl, const Vec3<T> &row, bool exc = true)

  Return true if the given scale can be removed from the given row matrix, false if `scl` is small enough that the operation would overflow.

  If `exc` is true, throw an exception on overflow.

template<class T>
Matrix44<T> Imath::outerProduct(const Vec4<T> &a, const Vec4<T> &b)

  Return the 4x4 outer product two 4-vectors.

template<class T>
Matrix44<T> Imath::rotationMatrix(const Vec3<T> &fromDirection, const Vec3<T> &toDirection)

  Return a 4x4 matrix that rotates the vector `fromDirection` to `toDirection`.

template<class T>
Matrix44<T> Imath::rotationMatrixWithUpDir(const Vec3<T> &fromDir, const Vec3<T> &toDir, const Vec3<T> &upDir)

  Return a 4x4 matrix that rotates the `fromDir` vector so that it points towards `toDir1.`

  You may also specify that you want the up vector to be pointing in a certain direction 1upDir.

template<class T>
void Imath::alignZAxisWithTargetDir(Matrix44<T> &result, Vec3<T> targetDir, Vec3<T> upDir)

  Construct a 4x4 matrix that rotates the z-axis so that it points towards `targetDir`.

  You must also specify that you want the up vector to be pointing in a certain direction `upDir`.

  Notes: The following degenerate cases are handled: (a) when the directions given by `toDir` and `upDir` are parallel or opposite (the direction vectors must have a non-zero cross product); (b) when any of the given direction vectors have zero length

  Parameters:

    - result – [out] The output matrix

    - targetDir – [in] The target direction vector

    - upDir – [in] The up direction vector

template<class T>
Matrix44<T> Imath::computeLocalFrame(const Vec3<T> &p, const Vec3<T> &xDir, const Vec3<T> &normal)

  Compute an orthonormal direct 4x4 frame from a position, an x axis direction and a normal to the y axis.

  If the x axis and normal are perpendicular, then the normal will have the same direction as the z axis.

  Parameters:

    - p – [in] The position of the frame

    - xDir – [in] The x axis direction of the frame

    - normal – [in] A normal to the y axis of the frame

  Returns:

    The orthonormal frame

template<class T>
Matrix44<T> Imath::addOffset(const Matrix44<T> &inMat, const Vec3<T> &tOffset, const Vec3<T> &rOffset, const Vec3<T> &sOffset, const Vec3<T> &ref)

  Add a translate/rotate/scale offset to a 4x4 input frame and put it in another frame of reference.

  Parameters:

    - inMat – [in] Input frame

    - tOffset – [in] Translation offset

    - rOffset – [in] Rotation offset in degrees

    - sOffset – [in] Scale offset

    - ref – [in] Frame of reference

  Returns:

    The offsetted frame

template<class T>
Matrix44<T> Imath::computeRSMatrix(bool keepRotateA, bool keepScaleA, const Matrix44<T> &A, const Matrix44<T> &B)

  Compute 4x4 translate/rotate/scale matrix from `A` with the rotate/scale of `B`.

  Parameters:

    - keepRotateA – [in] If true, keep rotate from matrix `A`, use `B` otherwise

    - keepScaleA – [in] If true, keep scale from matrix `A`, use `B` otherwise

    - A – [in] Matrix A

    - B – [in] Matrix B

  Returns:

    Matrix `A` with tweaked rotation/scale

template<class T>
bool Imath::extractScaling(const Matrix33<T> &mat, Vec2<T> &scl, bool exc = true)

  Extract the scaling component of the given 3x3 matrix.

  Parameters:

    - mat – [in] The input matrix

    - scl – [out] The extracted scale, i.e. the output value

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

  Returns:

    True if the scale could be extracted, false if the matrix is degenerate.

template<class T>
Matrix33<T> Imath::sansScaling(const Matrix33<T> &mat, bool exc = true)

  Return the given 3x3 matrix with scaling removed.

  Parameters:

    - mat – [in] The input matrix

    - exc – [in] If true, throw an exception if the scaling in `mat`

template<class T>
bool Imath::removeScaling(Matrix33<T> &mat, bool exc = true)

  Remove scaling from the given 3x3 matrix in place.

  Return true if the scale could be successfully extracted, false if the matrix is degenerate.

  Parameters:

    - mat – [in] The matrix to operate on

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

  Returns:

    True if the scale could be extracted, false if the matrix is degenerate.

template<class T>
bool Imath::extractScalingAndShear(const Matrix33<T> &mat, Vec2<T> &scl, T &shr, bool exc = true)

  Extract the scaling and shear components of the given 3x3 matrix.

  Return true if the scale could be successfully extracted, false if the matrix is degenerate.

  Parameters:

    - mat – [in] The input matrix

    - scl – [out] The extracted scale

    - shr – [out] The extracted shear

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

  Returns:

    True if the scale could be extracted, false if the matrix is degenerate.

template<class T>
Matrix33<T> Imath::sansScalingAndShear(const Matrix33<T> &mat, bool exc = true)

  Return the given 3x3 matrix with scaling and shear removed.

  Parameters:

    - mat – [in] The input matrix

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

template<class T>
bool Imath::removeScalingAndShear(Matrix33<T> &mat, bool exc = true)

  Remove scaling and shear from the given 3x3e matrix in place.

  Parameters:

    - mat – [inout] The matrix to operate on

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

  Returns:

    True if the scale could be extracted, false if the matrix is degenerate.

template<class T>
bool Imath::extractAndRemoveScalingAndShear(Matrix33<T> &mat, Vec2<T> &scl, T &shr, bool exc = true)

  Remove scaling and shear from the given 3x3 matrix in place, returning the extracted values.

  Parameters:

    - mat – [inout] The matrix to operate on

    - scl – [out] The extracted scale

    - shr – [out] The extracted shear

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

  Returns:

    True if the scale could be extracted, false if the matrix is degenerate.

template<class T>
void Imath::extractEuler(const Matrix22<T> &mat, T &rot)

  Extract the rotation from the given 2x2 matrix.

  Parameters:

    - mat – [in] The input matrix

    - rot – [out] The extracted rotation value

template<class T>
void Imath::extractEuler(const Matrix33<T> &mat, T &rot)

  Extract the rotation from the given 3x3 matrix.

  Parameters:

    - mat – [in] The input matrix

    - rot – [out] The extracted rotation value

template<class T>
bool Imath::extractSHRT(const Matrix33<T> &mat, Vec2<T> &s, T &h, T &r, Vec2<T> &t, bool exc = true)

  Extract the scaling, shear, rotation, and translation components of the given 3x3 matrix.

  The values are such that:

      M = S * H * R * T

  Parameters:

    - mat – [in] The input matrix

    - s – [out] The extracted scale

    - h – [out] The extracted shear

    - r – [out] The extracted rotation

    - t – [out] The extracted translation

    - exc – [in] If true, throw an exception if the scaling in `mat` is very close to zero.

  Returns:

    True if the values could be extracted, false if the matrix is degenerate.

template<class T>
bool Imath::checkForZeroScaleInRow(const T &scl, const Vec2<T> &row, bool exc = true)

  Return true if the given scale can be removed from the given row matrix, false if `scl` is small enough that the operation would overflow.

  If `exc` is true, throw an exception on overflow.

template<class T>
Matrix33<T> Imath::outerProduct(const Vec3<T> &a, const Vec3<T> &b)

  Return the 3xe outer product two 3-vectors.

template<typename T>
M44d Imath::procrustesRotationAndTranslation(const Vec3<T> *A, const Vec3<T> *B, const T *weights, const size_t numPoints, const bool doScaling = false)

  Computes the translation and rotation that brings the ‘from’ points as close as possible to the ‘to’ points under the Frobenius norm.

  To be more specific, let x be the matrix of ‘from’ points and y be the matrix of ‘to’ points, we want to find the matrix A of the form [ R t ] [ 0 1 ] that minimizes || (A*x - y)^T * W * (A*x - y) ||_F If doScaling is true, then a uniform scale is allowed also.

  Parameters:

    - A – From points

    - B – To points

    - weights – Per-point weights

    - numPoints – The number of points in `A`, `B`, and `weights` (must be equal)

    - doScaling – If true, include a scaling transformation

  Returns:

    The procrustes transformation

template<typename T>
M44d Imath::procrustesRotationAndTranslation(const Vec3<T> *A, const Vec3<T> *B, const size_t numPoints, const bool doScaling = false)

  Computes the translation and rotation that brings the ‘from’ points as close as possible to the ‘to’ points under the Frobenius norm.

  To be more specific, let x be the matrix of ‘from’ points and y be the matrix of ‘to’ points, we want to find the matrix A of the form [ R t ] [ 0 1 ] that minimizes || (A*x - y)^T * W * (A*x - y) ||_F If doScaling is true, then a uniform scale is allowed also.

  Parameters:

    - A – From points

    - B – To points

    - numPoints – The number of points in `A` and `B` (must be equal)

    - doScaling – If true, include a scaling transformation

  Returns:

    The procrustes transformation

template<typename T>
void Imath::jacobiSVD(const Matrix33<T> &A, Matrix33<T> &U, Vec3<T> &S, Matrix33<T> &V, const T tol = std::numeric_limits<T>::epsilon(), const bool forcePositiveDeterminant = false)

  Compute the SVD of a 3x3 matrix using Jacobi transformations.

  This method should be quite accurate (competitive with LAPACK) even for poorly conditioned matrices, and because it has been written specifically for the 3x3/4x4 case it is much faster than calling out to LAPACK.

  The SVD of a 3x3/4x4 matrix A is defined as follows: A = U * S * V^T where S is the diagonal matrix of singular values and both U and V are orthonormal. By convention, the entries S are all positive and sorted from the largest to the smallest. However, some uses of this function may require that the matrix U*V^T have positive determinant; in this case, we may make the smallest singular value negative to ensure that this is satisfied.

  Currently only available for single- and double-precision matrices.

template<typename T>
void Imath::jacobiSVD(const Matrix44<T> &A, Matrix44<T> &U, Vec4<T> &S, Matrix44<T> &V, const T tol = std::numeric_limits<T>::epsilon(), const bool forcePositiveDeterminant = false)

  Compute the SVD of a 3x3 matrix using Jacobi transformations.

  This method should be quite accurate (competitive with LAPACK) even for poorly conditioned matrices, and because it has been written specifically for the 3x3/4x4 case it is much faster than calling out to LAPACK.

  The SVD of a 3x3/4x4 matrix A is defined as follows: A = U * S * V^T where S is the diagonal matrix of singular values and both U and V are orthonormal. By convention, the entries S are all positive and sorted from the largest to the smallest. However, some uses of this function may require that the matrix U*V^T have positive determinant; in this case, we may make the smallest singular value negative to ensure that this is satisfied.

  Currently only available for single- and double-precision matrices.

template<typename T>
void Imath::jacobiEigenSolver(Matrix33<T> &A, Vec3<T> &S, Matrix33<T> &V, const T tol)

  Compute the eigenvalues (S) and the eigenvectors (V) of a real symmetric matrix using Jacobi transformation, using a given tolerance `tol`.

  Jacobi transformation of a 3x3/4x4 matrix A outputs S and V: A = V * S * V^T where V is orthonormal and S is the diagonal matrix of eigenvalues. Input matrix A must be symmetric. A is also modified during the computation so that upper diagonal entries of A become zero.

template<typename T>
inline void Imath::jacobiEigenSolver(Matrix33<T> &A, Vec3<T> &S, Matrix33<T> &V)

  Compute the eigenvalues (S) and the eigenvectors (V) of a real symmetric matrix using Jacobi transformation.

  Jacobi transformation of a 3x3/4x4 matrix A outputs S and V: A = V * S * V^T where V is orthonormal and S is the diagonal matrix of eigenvalues. Input matrix A must be symmetric. A is also modified during the computation so that upper diagonal entries of A become zero.

template<typename T>
void Imath::jacobiEigenSolver(Matrix44<T> &A, Vec4<T> &S, Matrix44<T> &V, const T tol)

  Compute the eigenvalues (S) and the eigenvectors (V) of a real symmetric matrix using Jacobi transformation, using a given tolerance `tol`.

  Jacobi transformation of a 3x3/4x4 matrix A outputs S and V: A = V * S * V^T where V is orthonormal and S is the diagonal matrix of eigenvalues. Input matrix A must be symmetric. A is also modified during the computation so that upper diagonal entries of A become zero.

template<typename T>
inline void Imath::jacobiEigenSolver(Matrix44<T> &A, Vec4<T> &S, Matrix44<T> &V)

  Compute the eigenvalues (S) and the eigenvectors (V) of a real symmetric matrix using Jacobi transformation.

  Jacobi transformation of a 3x3/4x4 matrix A outputs S and V: A = V * S * V^T where V is orthonormal and S is the diagonal matrix of eigenvalues. Input matrix A must be symmetric. A is also modified during the computation so that upper diagonal entries of A become zero.

template<typename TM, typename TV>
void Imath::maxEigenVector(TM &A, TV &S)

  Compute a eigenvector corresponding to the abs max eigenvalue of a real symmetric matrix using Jacobi transformation.

template<typename TM, typename TV>
void Imath::minEigenVector(TM &A, TV &S)

  Compute a eigenvector corresponding to the abs min eigenvalue of a real symmetric matrix using Jacobi transformation.

</page>