From 5bc944a3efaf19ecff71b11c52fb531b6821ecc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damiano=20Franz=C3=B2?= Date: Wed, 8 Oct 2025 00:41:26 +0200 Subject: [PATCH] Fix jacobi svd for TriangularBase --- Eigen/src/SVD/JacobiSVD.h | 19 +++++++++++++++++++ test/jacobisvd.cpp | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/Eigen/src/SVD/JacobiSVD.h b/Eigen/src/SVD/JacobiSVD.h index da2f29593..dfcb6df5e 100644 --- a/Eigen/src/SVD/JacobiSVD.h +++ b/Eigen/src/SVD/JacobiSVD.h @@ -571,6 +571,11 @@ class JacobiSVD : public SVDBase > { compute_impl(matrix, internal::get_computation_options(Options)); } + template + explicit JacobiSVD(const TriangularBase& matrix) { + compute_impl(matrix, internal::get_computation_options(Options)); + } + /** \brief Constructor performing the decomposition of given matrix using specified options * for computing unitaries. * @@ -601,6 +606,11 @@ class JacobiSVD : public SVDBase > { return compute_impl(matrix, m_computationOptions); } + template + JacobiSVD& compute(const TriangularBase& matrix) { + return compute_impl(matrix, m_computationOptions); + } + /** \brief Method performing the decomposition of given matrix, as specified by * the `computationOptions` parameter. * @@ -638,6 +648,8 @@ class JacobiSVD : public SVDBase > { } private: + template + JacobiSVD& compute_impl(const TriangularBase& matrix, unsigned int computationOptions); template JacobiSVD& compute_impl(const MatrixBase& matrix, unsigned int computationOptions); @@ -676,6 +688,13 @@ class JacobiSVD : public SVDBase > { WorkMatrixType m_workMatrix; }; +template +template +JacobiSVD& JacobiSVD::compute_impl(const TriangularBase& matrix, + unsigned int computationOptions) { + return compute_impl(matrix.toDenseMatrix(), computationOptions); +} + template template JacobiSVD& JacobiSVD::compute_impl(const MatrixBase& matrix, diff --git a/test/jacobisvd.cpp b/test/jacobisvd.cpp index cf5cc5fdb..7a6d4906f 100644 --- a/test/jacobisvd.cpp +++ b/test/jacobisvd.cpp @@ -94,6 +94,19 @@ void jacobisvd_verify_inputs(const MatrixType& input = MatrixType()) { (int)ColPivHouseholderQRPreconditioner)); } +template +void svd_triangular_matrix(const MatrixType& input = MatrixType()) { + MatrixType matrix(input.rows(), input.cols()); + svd_fill_random(matrix); + // Make sure that we only consider the 'Lower' part of the matrix. + MatrixType matrix_self_adj = matrix.template selfadjointView().toDenseMatrix(); + + JacobiSVD svd_triangular(matrix.template selfadjointView()); + JacobiSVD svd_full(matrix_self_adj); + + VERIFY_IS_APPROX(svd_triangular.singularValues(), svd_full.singularValues()); +} + namespace Foo { // older compiler require a default constructor for Bar // cf: https://stackoverflow.com/questions/7411515/ @@ -211,5 +224,10 @@ EIGEN_DECLARE_TEST(jacobisvd) { CALL_SUBTEST_55(svd_underoverflow()); + // Check that the TriangularBase constructor works + CALL_SUBTEST_56((svd_triangular_matrix())); + CALL_SUBTEST_57((svd_triangular_matrix())); + CALL_SUBTEST_58((svd_triangular_matrix>())); + msvc_workaround(); } -- GitLab