Avoid unnecessary matrix copy in BDCSVD and JacobiSVD

This commit is contained in:
Damiano Franzò 2025-05-01 23:17:21 +00:00 committed by Rasmus Munk Larsen
parent d6b23a2256
commit fb2fca90be
2 changed files with 40 additions and 13 deletions

View File

@ -165,7 +165,8 @@ class BDCSVD : public SVDBase<BDCSVD<MatrixType_, Options_> > {
* *
* \param matrix the matrix to decompose * \param matrix the matrix to decompose
*/ */
BDCSVD(const MatrixType& matrix) : m_algoswap(16), m_numIters(0) { template <typename Derived>
BDCSVD(const MatrixBase<Derived>& matrix) : m_algoswap(16), m_numIters(0) {
compute_impl(matrix, internal::get_computation_options(Options)); compute_impl(matrix, internal::get_computation_options(Options));
} }
@ -193,7 +194,10 @@ class BDCSVD : public SVDBase<BDCSVD<MatrixType_, Options_> > {
* *
* \param matrix the matrix to decompose * \param matrix the matrix to decompose
*/ */
BDCSVD& compute(const MatrixType& matrix) { return compute_impl(matrix, m_computationOptions); } template <typename Derived>
BDCSVD& compute(const MatrixBase<Derived>& matrix) {
return compute_impl(matrix, m_computationOptions);
}
/** \brief Method performing the decomposition of given matrix, as specified by /** \brief Method performing the decomposition of given matrix, as specified by
* the `computationOptions` parameter. * the `computationOptions` parameter.
@ -204,7 +208,8 @@ class BDCSVD : public SVDBase<BDCSVD<MatrixType_, Options_> > {
* \deprecated Will be removed in the next major Eigen version. Options should * \deprecated Will be removed in the next major Eigen version. Options should
* be specified in the \a Options template parameter. * be specified in the \a Options template parameter.
*/ */
EIGEN_DEPRECATED BDCSVD& compute(const MatrixType& matrix, unsigned int computationOptions) { template <typename Derived>
EIGEN_DEPRECATED BDCSVD& compute(const MatrixBase<Derived>& matrix, unsigned int computationOptions) {
internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, matrix.rows(), matrix.cols()); internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, matrix.rows(), matrix.cols());
return compute_impl(matrix, computationOptions); return compute_impl(matrix, computationOptions);
} }
@ -215,7 +220,8 @@ class BDCSVD : public SVDBase<BDCSVD<MatrixType_, Options_> > {
} }
private: private:
BDCSVD& compute_impl(const MatrixType& matrix, unsigned int computationOptions); template <typename Derived>
BDCSVD& compute_impl(const MatrixBase<Derived>& matrix, unsigned int computationOptions);
void divide(Index firstCol, Index lastCol, Index firstRowW, Index firstColW, Index shift); void divide(Index firstCol, Index lastCol, Index firstRowW, Index firstColW, Index shift);
void computeSVDofM(Index firstCol, Index n, MatrixXr& U, VectorType& singVals, MatrixXr& V); void computeSVDofM(Index firstCol, Index n, MatrixXr& U, VectorType& singVals, MatrixXr& V);
void computeSingVals(const ArrayRef& col0, const ArrayRef& diag, const IndicesRef& perm, VectorType& singVals, void computeSingVals(const ArrayRef& col0, const ArrayRef& diag, const IndicesRef& perm, VectorType& singVals,
@ -307,8 +313,13 @@ void BDCSVD<MatrixType, Options>::allocate(Index rows, Index cols, unsigned int
} // end allocate } // end allocate
template <typename MatrixType, int Options> template <typename MatrixType, int Options>
BDCSVD<MatrixType, Options>& BDCSVD<MatrixType, Options>::compute_impl(const MatrixType& matrix, template <typename Derived>
BDCSVD<MatrixType, Options>& BDCSVD<MatrixType, Options>::compute_impl(const MatrixBase<Derived>& matrix,
unsigned int computationOptions) { unsigned int computationOptions) {
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived, MatrixType);
EIGEN_STATIC_ASSERT((std::is_same<typename Derived::Scalar, typename MatrixType::Scalar>::value),
Input matrix must have the same Scalar type as the BDCSVD object.);
#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
std::cout << "\n\n\n=================================================================================================" std::cout << "\n\n\n================================================================================================="
"=====================\n\n\n"; "=====================\n\n\n";

View File

@ -565,7 +565,10 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options_> > {
* *
* \param matrix the matrix to decompose * \param matrix the matrix to decompose
*/ */
explicit JacobiSVD(const MatrixType& matrix) { compute_impl(matrix, internal::get_computation_options(Options)); } template <typename Derived>
explicit JacobiSVD(const MatrixBase<Derived>& matrix) {
compute_impl(matrix, internal::get_computation_options(Options));
}
/** \brief Constructor performing the decomposition of given matrix using specified options /** \brief Constructor performing the decomposition of given matrix using specified options
* for computing unitaries. * for computing unitaries.
@ -580,8 +583,10 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options_> > {
* be specified in the \a Options template parameter. * be specified in the \a Options template parameter.
*/ */
// EIGEN_DEPRECATED // TODO(cantonios): re-enable after fixing a few 3p libraries that error on deprecation warnings. // EIGEN_DEPRECATED // TODO(cantonios): re-enable after fixing a few 3p libraries that error on deprecation warnings.
JacobiSVD(const MatrixType& matrix, unsigned int computationOptions) { template <typename Derived>
internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, matrix.rows(), matrix.cols()); JacobiSVD(const MatrixBase<Derived>& matrix, unsigned int computationOptions) {
internal::check_svd_options_assertions<MatrixBase<Derived>, Options>(computationOptions, matrix.rows(),
matrix.cols());
compute_impl(matrix, computationOptions); compute_impl(matrix, computationOptions);
} }
@ -590,7 +595,10 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options_> > {
* *
* \param matrix the matrix to decompose * \param matrix the matrix to decompose
*/ */
JacobiSVD& compute(const MatrixType& matrix) { return compute_impl(matrix, m_computationOptions); } template <typename Derived>
JacobiSVD& compute(const MatrixBase<Derived>& matrix) {
return compute_impl(matrix, m_computationOptions);
}
/** \brief Method performing the decomposition of given matrix, as specified by /** \brief Method performing the decomposition of given matrix, as specified by
* the `computationOptions` parameter. * the `computationOptions` parameter.
@ -601,8 +609,10 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options_> > {
* \deprecated Will be removed in the next major Eigen version. Options should * \deprecated Will be removed in the next major Eigen version. Options should
* be specified in the \a Options template parameter. * be specified in the \a Options template parameter.
*/ */
EIGEN_DEPRECATED JacobiSVD& compute(const MatrixType& matrix, unsigned int computationOptions) { template <typename Derived>
internal::check_svd_options_assertions<MatrixType, Options>(m_computationOptions, matrix.rows(), matrix.cols()); EIGEN_DEPRECATED JacobiSVD& compute(const MatrixBase<Derived>& matrix, unsigned int computationOptions) {
internal::check_svd_options_assertions<MatrixBase<Derived>, Options>(m_computationOptions, matrix.rows(),
matrix.cols());
return compute_impl(matrix, computationOptions); return compute_impl(matrix, computationOptions);
} }
@ -626,7 +636,8 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options_> > {
} }
private: private:
JacobiSVD& compute_impl(const MatrixType& matrix, unsigned int computationOptions); template <typename Derived>
JacobiSVD& compute_impl(const MatrixBase<Derived>& matrix, unsigned int computationOptions);
protected: protected:
using Base::m_computationOptions; using Base::m_computationOptions;
@ -664,8 +675,13 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options_> > {
}; };
template <typename MatrixType, int Options> template <typename MatrixType, int Options>
JacobiSVD<MatrixType, Options>& JacobiSVD<MatrixType, Options>::compute_impl(const MatrixType& matrix, template <typename Derived>
JacobiSVD<MatrixType, Options>& JacobiSVD<MatrixType, Options>::compute_impl(const MatrixBase<Derived>& matrix,
unsigned int computationOptions) { unsigned int computationOptions) {
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived, MatrixType);
EIGEN_STATIC_ASSERT((std::is_same<typename Derived::Scalar, typename MatrixType::Scalar>::value),
Input matrix must have the same Scalar type as the BDCSVD object.);
using std::abs; using std::abs;
allocate(matrix.rows(), matrix.cols(), computationOptions); allocate(matrix.rows(), matrix.cols(), computationOptions);