diff options
author | Gael Guennebaud <g.gael@free.fr> | 2010-06-02 10:12:13 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2010-06-02 10:12:13 +0200 |
commit | 143e6ab9d0a86407763e3608ef60f8c9c69a33fd (patch) | |
tree | ceb91f35a72b6c8d1b46d7f8ad41a2fcbbb41e51 | |
parent | 4ebb80490ab24c41e066c6a3082b29777adbb6e5 (diff) |
improve aliasing detection for inverse and add unit test
-rw-r--r-- | Eigen/src/LU/Inverse.h | 6 | ||||
-rw-r--r-- | test/inverse.cpp | 13 |
2 files changed, 17 insertions, 2 deletions
diff --git a/Eigen/src/LU/Inverse.h b/Eigen/src/LU/Inverse.h index e1276c6a3..5ccc59a32 100644 --- a/Eigen/src/LU/Inverse.h +++ b/Eigen/src/LU/Inverse.h @@ -295,8 +295,10 @@ struct ei_inverse_impl : public ReturnByValue<ei_inverse_impl<MatrixType> > template<typename Dest> inline void evalTo(Dest& dst) const { - // FIXME this is a naive aliasing check that could be improved. It only catches x = x.inverse(); - ei_assert(&dst != (Dest*)(&m_matrix) && "Aliasing problem detected in inverse(), you need to do inverse().eval() here."); + const int Size = EIGEN_ENUM_MIN(MatrixType::ColsAtCompileTime,Dest::ColsAtCompileTime); + ei_assert(( (Size<=1) || (Size>4) || (ei_extract_data(m_matrix)!=ei_extract_data(dst))) + && "Aliasing problem detected in inverse(), you need to do inverse().eval() here."); + ei_compute_inverse<MatrixTypeNestedCleaned, Dest>::run(m_matrix, dst); } }; diff --git a/test/inverse.cpp b/test/inverse.cpp index 1e567ad14..4d9297eb4 100644 --- a/test/inverse.cpp +++ b/test/inverse.cpp @@ -82,6 +82,19 @@ template<typename MatrixType> void inverse(const MatrixType& m) m3.computeInverseWithCheck(m4, invertible); VERIFY( rows==1 ? invertible : !invertible ); #endif + + // check in-place inversion + if(MatrixType::RowsAtCompileTime>=2 && MatrixType::RowsAtCompileTime<=4) + { + // in-place is forbidden + VERIFY_RAISES_ASSERT(m1 = m1.inverse()); + } + else + { + m2 = m1.inverse(); + m1 = m1.inverse(); + VERIFY_IS_APPROX(m1,m2); + } } void test_inverse() |