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 Gael Guennebaud <gael.guennebaud@inria.fr> 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "main.h" 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include <Eigen/LU> 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType> void inverse(const MatrixType& m) 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez using std::abs; 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixType::Index Index; 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /* this test covers the following files: 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Inverse.h 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index rows = m.rows(); 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index cols = m.cols(); 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixType::Scalar Scalar; 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MatrixType m1(rows, cols), 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m2(rows, cols), 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath identity = MatrixType::Identity(rows, rows); 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath createRandomPIMatrixOfRank(rows,rows,rows,m1); 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m2 = m1.inverse(); 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m1, m2.inverse() ); 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX((Scalar(2)*m2).inverse(), m2.inverse()*Scalar(0.5)); 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(identity, m1.inverse() * m1 ); 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(identity, m1 * m1.inverse() ); 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m1, m1.inverse().inverse() ); 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // since for the general case we implement separately row-major and col-major, test that 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(MatrixType(m1.transpose().inverse()), MatrixType(m1.inverse().transpose())); 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#if !defined(EIGEN_TEST_PART_5) && !defined(EIGEN_TEST_PART_6) 447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename NumTraits<Scalar>::Real RealScalar; 457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType; 467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //computeInverseAndDetWithCheck tests 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //First: an invertible matrix 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool invertible; 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar det; 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m2.setZero(); 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m1.computeInverseAndDetWithCheck(m2, det, invertible); 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY(invertible); 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(identity, m1*m2); 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(det, m1.determinant()); 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m2.setZero(); 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m1.computeInverseWithCheck(m2, invertible); 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY(invertible); 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(identity, m1*m2); 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //Second: a rank one matrix (not invertible, except for 1x1 matrices) 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VectorType v3 = VectorType::Random(rows); 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MatrixType m3 = v3*v3.transpose(), m4(rows,cols); 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m3.computeInverseAndDetWithCheck(m4, det, invertible); 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY( rows==1 ? invertible : !invertible ); 687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_MUCH_SMALLER_THAN(abs(det-m3.determinant()), RealScalar(1)); 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m3.computeInverseWithCheck(m4, invertible); 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY( rows==1 ? invertible : !invertible ); 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // check in-place inversion 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(MatrixType::RowsAtCompileTime>=2 && MatrixType::RowsAtCompileTime<=4) 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // in-place is forbidden 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_RAISES_ASSERT(m1 = m1.inverse()); 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m2 = m1.inverse(); 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m1 = m1.inverse(); 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m1,m2); 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid test_inverse() 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez int s = 0; 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(int i = 0; i < g_repeat; i++) { 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_1( inverse(Matrix<double,1,1>()) ); 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_2( inverse(Matrix2d()) ); 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_3( inverse(Matrix3f()) ); 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_4( inverse(Matrix4f()) ); 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_4( inverse(Matrix<float,4,4,DontAlign>()) ); 967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez s = internal::random<int>(50,320); 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_5( inverse(MatrixXf(s,s)) ); 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s = internal::random<int>(25,100); 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_6( inverse(MatrixXcd(s,s)) ); 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_7( inverse(Matrix4d()) ); 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_7( inverse(Matrix<double,4,4,DontAlign>()) ); 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 1037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez TEST_SET_BUT_UNUSED_VARIABLE(s) 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 105