From 1d21d62fbc1431c00c6dd7e65f1b35cea30bd872 Mon Sep 17 00:00:00 2001 From: Pavel Guzenfeld Date: Sat, 21 Mar 2026 15:38:27 +0000 Subject: [PATCH] Fix computeInverseAndDetWithCheck for dynamic result matrices libeigen/eigen!2312 Closes #2917 --- Eigen/src/LU/InverseImpl.h | 5 ++--- test/inverse.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Eigen/src/LU/InverseImpl.h b/Eigen/src/LU/InverseImpl.h index 5c24dfec1..58ac305bc 100644 --- a/Eigen/src/LU/InverseImpl.h +++ b/Eigen/src/LU/InverseImpl.h @@ -308,8 +308,9 @@ inline void MatrixBase::computeInverseAndDetWithCheck(ResultType& inver typename ResultType::Scalar& determinant, bool& invertible, const RealScalar& absDeterminantThreshold) const { - // i'd love to put some static assertions there, but SFINAE means that they have no effect... + EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived, ResultType) eigen_assert(rows() == cols()); + inverse.resize(rows(), cols()); // for 2x2, it's worth giving a chance to avoid evaluating. // for larger sizes, evaluating has negligible cost and limits code size. typedef std::conditional_t inline void MatrixBase::computeInverseWithCheck(ResultType& inverse, bool& invertible, const RealScalar& absDeterminantThreshold) const { Scalar determinant; - // i'd love to put some static assertions there, but SFINAE means that they have no effect... - eigen_assert(rows() == cols()); computeInverseAndDetWithCheck(inverse, determinant, invertible, absDeterminantThreshold); } diff --git a/test/inverse.cpp b/test/inverse.cpp index d564db404..367bf24ed 100644 --- a/test/inverse.cpp +++ b/test/inverse.cpp @@ -58,6 +58,32 @@ void inverse_for_fixed_size(const MatrixType& m1, std::enable_if_t()), m2.inverse()); } + + // check that computeInverseAndDetWithCheck resizes dynamic result matrix (issue #2917) + { + typedef Matrix DynamicMatrix; + DynamicMatrix m_dyn_inv; + Scalar det_dyn; + bool inv_dyn; + m1.computeInverseAndDetWithCheck(m_dyn_inv, det_dyn, inv_dyn); + VERIFY(inv_dyn); + VERIFY_IS_EQUAL(m_dyn_inv.rows(), m1.rows()); + VERIFY_IS_EQUAL(m_dyn_inv.cols(), m1.cols()); + VERIFY_IS_APPROX(identity, m1 * m_dyn_inv); + VERIFY_IS_APPROX(det_dyn, m1.determinant()); + } + + // check that computeInverseWithCheck resizes dynamic result matrix + { + typedef Matrix DynamicMatrix; + DynamicMatrix m_dyn_inv; + bool inv_dyn; + m1.computeInverseWithCheck(m_dyn_inv, inv_dyn); + VERIFY(inv_dyn); + VERIFY_IS_EQUAL(m_dyn_inv.rows(), m1.rows()); + VERIFY_IS_EQUAL(m_dyn_inv.cols(), m1.cols()); + VERIFY_IS_APPROX(identity, m1 * m_dyn_inv); + } } template