1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008-2010 Benoit Jacob <jacob.benoit.1@gmail.com> 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_INVERSE_H 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_INVERSE_H 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen { 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal { 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/********************************** 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*** General case implementation *** 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath**********************************/ 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, typename ResultType, int Size = MatrixType::RowsAtCompileTime> 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct compute_inverse 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static inline void run(const MatrixType& matrix, ResultType& result) 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result = matrix.partialPivLu().inverse(); 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, typename ResultType, int Size = MatrixType::RowsAtCompileTime> 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct compute_inverse_and_det_with_check { /* nothing! general case not supported. */ }; 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/**************************** 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*** Size 1 implementation *** 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************/ 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, typename ResultType> 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct compute_inverse<MatrixType, ResultType, 1> 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static inline void run(const MatrixType& matrix, ResultType& result) 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixType::Scalar Scalar; 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(0,0) = Scalar(1) / matrix.coeff(0,0); 44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, typename ResultType> 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct compute_inverse_and_det_with_check<MatrixType, ResultType, 1> 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static inline void run( 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const MatrixType& matrix, 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const typename MatrixType::RealScalar& absDeterminantThreshold, 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ResultType& result, 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename ResultType::Scalar& determinant, 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool& invertible 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ) 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez using std::abs; 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath determinant = matrix.coeff(0,0); 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath invertible = abs(determinant) > absDeterminantThreshold; 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(invertible) result.coeffRef(0,0) = typename ResultType::Scalar(1) / determinant; 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/**************************** 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*** Size 2 implementation *** 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************/ 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, typename ResultType> 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline void compute_inverse_size2_helper( 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const MatrixType& matrix, const typename ResultType::Scalar& invdet, 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ResultType& result) 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(0,0) = matrix.coeff(1,1) * invdet; 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(1,0) = -matrix.coeff(1,0) * invdet; 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(0,1) = -matrix.coeff(0,1) * invdet; 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(1,1) = matrix.coeff(0,0) * invdet; 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, typename ResultType> 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct compute_inverse<MatrixType, ResultType, 2> 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static inline void run(const MatrixType& matrix, ResultType& result) 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename ResultType::Scalar Scalar; 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Scalar invdet = typename MatrixType::Scalar(1) / matrix.determinant(); 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath compute_inverse_size2_helper(matrix, invdet, result); 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, typename ResultType> 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct compute_inverse_and_det_with_check<MatrixType, ResultType, 2> 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static inline void run( 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const MatrixType& matrix, 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const typename MatrixType::RealScalar& absDeterminantThreshold, 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ResultType& inverse, 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename ResultType::Scalar& determinant, 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool& invertible 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ) 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez using std::abs; 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename ResultType::Scalar Scalar; 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath determinant = matrix.determinant(); 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath invertible = abs(determinant) > absDeterminantThreshold; 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(!invertible) return; 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Scalar invdet = Scalar(1) / determinant; 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath compute_inverse_size2_helper(matrix, invdet, inverse); 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/**************************** 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*** Size 3 implementation *** 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************/ 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, int i, int j> 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline typename MatrixType::Scalar cofactor_3x3(const MatrixType& m) 118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath i1 = (i+1) % 3, 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath i2 = (i+2) % 3, 122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath j1 = (j+1) % 3, 123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath j2 = (j+2) % 3 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m.coeff(i1, j1) * m.coeff(i2, j2) 126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath - m.coeff(i1, j2) * m.coeff(i2, j1); 127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, typename ResultType> 130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline void compute_inverse_size3_helper( 131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const MatrixType& matrix, 132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const typename ResultType::Scalar& invdet, 133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Matrix<typename ResultType::Scalar,3,1>& cofactors_col0, 134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ResultType& result) 135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.row(0) = cofactors_col0 * invdet; 137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(1,0) = cofactor_3x3<MatrixType,0,1>(matrix) * invdet; 138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(1,1) = cofactor_3x3<MatrixType,1,1>(matrix) * invdet; 139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(1,2) = cofactor_3x3<MatrixType,2,1>(matrix) * invdet; 140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(2,0) = cofactor_3x3<MatrixType,0,2>(matrix) * invdet; 141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(2,1) = cofactor_3x3<MatrixType,1,2>(matrix) * invdet; 142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(2,2) = cofactor_3x3<MatrixType,2,2>(matrix) * invdet; 143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, typename ResultType> 146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct compute_inverse<MatrixType, ResultType, 3> 147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static inline void run(const MatrixType& matrix, ResultType& result) 149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename ResultType::Scalar Scalar; 151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Matrix<typename MatrixType::Scalar,3,1> cofactors_col0; 152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath cofactors_col0.coeffRef(0) = cofactor_3x3<MatrixType,0,0>(matrix); 153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath cofactors_col0.coeffRef(1) = cofactor_3x3<MatrixType,1,0>(matrix); 154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath cofactors_col0.coeffRef(2) = cofactor_3x3<MatrixType,2,0>(matrix); 155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Scalar det = (cofactors_col0.cwiseProduct(matrix.col(0))).sum(); 156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Scalar invdet = Scalar(1) / det; 157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath compute_inverse_size3_helper(matrix, invdet, cofactors_col0, result); 158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, typename ResultType> 162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct compute_inverse_and_det_with_check<MatrixType, ResultType, 3> 163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static inline void run( 165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const MatrixType& matrix, 166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const typename MatrixType::RealScalar& absDeterminantThreshold, 167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ResultType& inverse, 168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename ResultType::Scalar& determinant, 169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool& invertible 170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ) 171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez using std::abs; 173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename ResultType::Scalar Scalar; 174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Matrix<Scalar,3,1> cofactors_col0; 175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath cofactors_col0.coeffRef(0) = cofactor_3x3<MatrixType,0,0>(matrix); 176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath cofactors_col0.coeffRef(1) = cofactor_3x3<MatrixType,1,0>(matrix); 177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath cofactors_col0.coeffRef(2) = cofactor_3x3<MatrixType,2,0>(matrix); 178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath determinant = (cofactors_col0.cwiseProduct(matrix.col(0))).sum(); 179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath invertible = abs(determinant) > absDeterminantThreshold; 180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(!invertible) return; 181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Scalar invdet = Scalar(1) / determinant; 182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath compute_inverse_size3_helper(matrix, invdet, cofactors_col0, inverse); 183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/**************************** 187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*** Size 4 implementation *** 188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath****************************/ 189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived> 191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline const typename Derived::Scalar general_det3_helper 192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath(const MatrixBase<Derived>& matrix, int i1, int i2, int i3, int j1, int j2, int j3) 193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return matrix.coeff(i1,j1) 195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * (matrix.coeff(i2,j2) * matrix.coeff(i3,j3) - matrix.coeff(i2,j3) * matrix.coeff(i3,j2)); 196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, int i, int j> 199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline typename MatrixType::Scalar cofactor_4x4(const MatrixType& matrix) 200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath i1 = (i+1) % 4, 203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath i2 = (i+2) % 4, 204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath i3 = (i+3) % 4, 205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath j1 = (j+1) % 4, 206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath j2 = (j+2) % 4, 207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath j3 = (j+3) % 4 208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return general_det3_helper(matrix, i1, i2, i3, j1, j2, j3) 210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath + general_det3_helper(matrix, i2, i3, i1, j1, j2, j3) 211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath + general_det3_helper(matrix, i3, i1, i2, j1, j2, j3); 212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int Arch, typename Scalar, typename MatrixType, typename ResultType> 215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct compute_inverse_size4 216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void run(const MatrixType& matrix, ResultType& result) 218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(0,0) = cofactor_4x4<MatrixType,0,0>(matrix); 220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(1,0) = -cofactor_4x4<MatrixType,0,1>(matrix); 221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(2,0) = cofactor_4x4<MatrixType,0,2>(matrix); 222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(3,0) = -cofactor_4x4<MatrixType,0,3>(matrix); 223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(0,2) = cofactor_4x4<MatrixType,2,0>(matrix); 224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(1,2) = -cofactor_4x4<MatrixType,2,1>(matrix); 225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(2,2) = cofactor_4x4<MatrixType,2,2>(matrix); 226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(3,2) = -cofactor_4x4<MatrixType,2,3>(matrix); 227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(0,1) = -cofactor_4x4<MatrixType,1,0>(matrix); 228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(1,1) = cofactor_4x4<MatrixType,1,1>(matrix); 229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(2,1) = -cofactor_4x4<MatrixType,1,2>(matrix); 230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(3,1) = cofactor_4x4<MatrixType,1,3>(matrix); 231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(0,3) = -cofactor_4x4<MatrixType,3,0>(matrix); 232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(1,3) = cofactor_4x4<MatrixType,3,1>(matrix); 233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(2,3) = -cofactor_4x4<MatrixType,3,2>(matrix); 234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.coeffRef(3,3) = cofactor_4x4<MatrixType,3,3>(matrix); 235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result /= (matrix.col(0).cwiseProduct(result.row(0).transpose())).sum(); 236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, typename ResultType> 240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct compute_inverse<MatrixType, ResultType, 4> 241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : compute_inverse_size4<Architecture::Target, typename MatrixType::Scalar, 242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MatrixType, ResultType> 243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, typename ResultType> 247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct compute_inverse_and_det_with_check<MatrixType, ResultType, 4> 248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static inline void run( 250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const MatrixType& matrix, 251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const typename MatrixType::RealScalar& absDeterminantThreshold, 252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ResultType& inverse, 253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename ResultType::Scalar& determinant, 254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool& invertible 255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ) 256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 2577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez using std::abs; 258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath determinant = matrix.determinant(); 259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath invertible = abs(determinant) > absDeterminantThreshold; 260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(invertible) compute_inverse<MatrixType, ResultType>::run(matrix, inverse); 261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/************************* 265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*** MatrixBase methods *** 266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*************************/ 267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType> 269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct traits<inverse_impl<MatrixType> > 270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixType::PlainObject ReturnType; 272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType> 275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct inverse_impl : public ReturnByValue<inverse_impl<MatrixType> > 276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixType::Index Index; 278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::eval<MatrixType>::type MatrixTypeNested; 279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned; 280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MatrixTypeNested m_matrix; 281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inverse_impl(const MatrixType& matrix) 283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_matrix(matrix) 284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath {} 285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index rows() const { return m_matrix.rows(); } 287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index cols() const { return m_matrix.cols(); } 288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename Dest> inline void evalTo(Dest& dst) const 290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const int Size = EIGEN_PLAIN_ENUM_MIN(MatrixType::ColsAtCompileTime,Dest::ColsAtCompileTime); 292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_ONLY_USED_FOR_DEBUG(Size); 293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(( (Size<=1) || (Size>4) || (extract_data(m_matrix)!=extract_data(dst))) 294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath && "Aliasing problem detected in inverse(), you need to do inverse().eval() here."); 295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath compute_inverse<MatrixTypeNestedCleaned, Dest>::run(m_matrix, dst); 297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal 301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \lu_module 303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \returns the matrix inverse of this matrix. 305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * For small fixed sizes up to 4x4, this method uses cofactors. 307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * In the general case, this method uses class PartialPivLU. 308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \note This matrix must be invertible, otherwise the result is undefined. If you need an 310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * invertibility check, do the following: 311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \li for fixed sizes up to 4x4, use computeInverseAndDetWithCheck(). 312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \li for the general case, use class FullPivLU. 313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Example: \include MatrixBase_inverse.cpp 315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Output: \verbinclude MatrixBase_inverse.out 316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa computeInverseAndDetWithCheck() 318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived> 320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline const internal::inverse_impl<Derived> MatrixBase<Derived>::inverse() const 321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsInteger,THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES) 323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(rows() == cols()); 324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return internal::inverse_impl<Derived>(derived()); 325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 327c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \lu_module 328c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 329c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Computation of matrix inverse and determinant, with invertibility check. 330c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 331c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This is only for fixed-size square matrices of size up to 4x4. 332c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \param inverse Reference to the matrix in which to store the inverse. 3347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \param determinant Reference to the variable in which to store the determinant. 335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \param invertible Reference to the bool variable in which to store whether the matrix is invertible. 336c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \param absDeterminantThreshold Optional parameter controlling the invertibility check. 337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * The matrix will be declared invertible if the absolute value of its 338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * determinant is greater than this threshold. 339c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Example: \include MatrixBase_computeInverseAndDetWithCheck.cpp 341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Output: \verbinclude MatrixBase_computeInverseAndDetWithCheck.out 342c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 343c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa inverse(), computeInverseWithCheck() 344c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 345c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived> 346c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename ResultType> 347c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline void MatrixBase<Derived>::computeInverseAndDetWithCheck( 348c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ResultType& inverse, 349c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename ResultType::Scalar& determinant, 350c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool& invertible, 351c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const RealScalar& absDeterminantThreshold 352c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ) const 353c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 354c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // i'd love to put some static assertions there, but SFINAE means that they have no effect... 355c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(rows() == cols()); 356c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // for 2x2, it's worth giving a chance to avoid evaluating. 357c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // for larger sizes, evaluating has negligible cost and limits code size. 358c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::conditional< 359c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowsAtCompileTime == 2, 360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename internal::remove_all<typename internal::nested<Derived, 2>::type>::type, 361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath PlainObject 362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath >::type MatrixType; 363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath internal::compute_inverse_and_det_with_check<MatrixType, ResultType>::run 364c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath (derived(), absDeterminantThreshold, inverse, determinant, invertible); 365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 366c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 367c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \lu_module 368c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 369c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Computation of matrix inverse, with invertibility check. 370c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 371c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This is only for fixed-size square matrices of size up to 4x4. 372c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 373c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \param inverse Reference to the matrix in which to store the inverse. 374c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \param invertible Reference to the bool variable in which to store whether the matrix is invertible. 375c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \param absDeterminantThreshold Optional parameter controlling the invertibility check. 376c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * The matrix will be declared invertible if the absolute value of its 377c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * determinant is greater than this threshold. 378c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 379c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Example: \include MatrixBase_computeInverseWithCheck.cpp 380c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Output: \verbinclude MatrixBase_computeInverseWithCheck.out 381c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 382c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa inverse(), computeInverseAndDetWithCheck() 383c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 384c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived> 385c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename ResultType> 386c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline void MatrixBase<Derived>::computeInverseWithCheck( 387c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ResultType& inverse, 388c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool& invertible, 389c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const RealScalar& absDeterminantThreshold 390c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ) const 391c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 392c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar determinant; 393c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // i'd love to put some static assertions there, but SFINAE means that they have no effect... 394c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(rows() == cols()); 395c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath computeInverseAndDetWithCheck(inverse,determinant,invertible,absDeterminantThreshold); 396c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 397c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 398c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen 399c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 400c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_INVERSE_H 401