diff --git a/Eigen/src/SVD/JacobiSVD.h b/Eigen/src/SVD/JacobiSVD.h index da2f295930542229ed26e52530c2e95bcde41167..dfcb6df5e135d4671e35af14995e2475fbb1285b 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 cf5cc5fdba1ac0751df60a3ab3c7cdb34f961cb8..7a6d4906f4273d72363e0668a3e99234c2006d8f 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(); }