From 41a20994cce4d7e2c49bbb958a43c9ed69473f7f Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Mon, 8 Dec 2014 17:56:33 +0100 Subject: [PATCH] In simplicial cholesky: avoid deep copy of the input matrix is this later can be used readily --- Eigen/src/SparseCholesky/SimplicialCholesky.h | 68 +++++++++++++++---- 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/Eigen/src/SparseCholesky/SimplicialCholesky.h b/Eigen/src/SparseCholesky/SimplicialCholesky.h index 1928670a3..22325d7f4 100644 --- a/Eigen/src/SparseCholesky/SimplicialCholesky.h +++ b/Eigen/src/SparseCholesky/SimplicialCholesky.h @@ -17,6 +17,27 @@ enum SimplicialCholeskyMode { SimplicialCholeskyLDLT }; +namespace internal { + template + struct simplicial_cholesky_grab_input { + typedef CholMatrixType const * ConstCholMatrixPtr; + static void run(const InputMatrixType& input, ConstCholMatrixPtr &pmat, CholMatrixType &tmp) + { + tmp = input; + pmat = &tmp; + } + }; + + template + struct simplicial_cholesky_grab_input { + typedef MatrixType const * ConstMatrixPtr; + static void run(const MatrixType& input, ConstMatrixPtr &pmat, MatrixType &/*tmp*/) + { + pmat = &input; + } + }; +} // end namespace internal + /** \ingroup SparseCholesky_Module * \brief A direct sparse Cholesky factorizations * @@ -46,6 +67,7 @@ class SimplicialCholeskyBase : public SparseSolverBase typedef typename MatrixType::RealScalar RealScalar; typedef typename MatrixType::Index Index; typedef SparseMatrix CholMatrixType; + typedef CholMatrixType const * ConstCholMatrixPtr; typedef Matrix VectorType; public: @@ -169,10 +191,11 @@ class SimplicialCholeskyBase : public SparseSolverBase { eigen_assert(matrix.rows()==matrix.cols()); Index size = matrix.cols(); - CholMatrixType ap(size,size); - ordering(matrix, ap); - analyzePattern_preordered(ap, DoLDLT); - factorize_preordered(ap); + CholMatrixType tmp(size,size); + ConstCholMatrixPtr pmat; + ordering(matrix, pmat, tmp); + analyzePattern_preordered(*pmat, DoLDLT); + factorize_preordered(*pmat); } template @@ -180,9 +203,21 @@ class SimplicialCholeskyBase : public SparseSolverBase { eigen_assert(a.rows()==a.cols()); int size = a.cols(); - CholMatrixType ap(size,size); - ap.template selfadjointView() = a.template selfadjointView().twistedBy(m_P); - factorize_preordered(ap); + CholMatrixType tmp(size,size); + ConstCholMatrixPtr pmat; + + if(m_P.size()==0 && (UpLo&Upper)==Upper) + { + // If there is no ordering, try to directly use the input matrix without any copy + internal::simplicial_cholesky_grab_input::run(a, pmat, tmp); + } + else + { + tmp.template selfadjointView() = a.template selfadjointView().twistedBy(m_P); + pmat = &tmp; + } + + factorize_preordered(*pmat); } template @@ -192,13 +227,14 @@ class SimplicialCholeskyBase : public SparseSolverBase { eigen_assert(a.rows()==a.cols()); int size = a.cols(); - CholMatrixType ap(size,size); - ordering(a, ap); - analyzePattern_preordered(ap,doLDLT); + CholMatrixType tmp(size,size); + ConstCholMatrixPtr pmat; + ordering(a, pmat, tmp); + analyzePattern_preordered(*pmat,doLDLT); } void analyzePattern_preordered(const CholMatrixType& a, bool doLDLT); - void ordering(const MatrixType& a, CholMatrixType& ap); + void ordering(const MatrixType& a, ConstCholMatrixPtr &pmat, CholMatrixType& ap); /** keeps off-diagonal entries; drops diagonal entries */ struct keep_diag { @@ -603,10 +639,11 @@ public: }; template -void SimplicialCholeskyBase::ordering(const MatrixType& a, CholMatrixType& ap) +void SimplicialCholeskyBase::ordering(const MatrixType& a, ConstCholMatrixPtr &pmat, CholMatrixType& ap) { eigen_assert(a.rows()==a.cols()); const Index size = a.rows(); + pmat = ≈ // Note that ordering methods compute the inverse permutation if(!internal::is_same >::value) { @@ -628,13 +665,14 @@ void SimplicialCholeskyBase::ordering(const MatrixType& a, CholMatrixTy { m_Pinv.resize(0); m_P.resize(0); - if(UpLo==Lower) + if(UpLo==Lower || MatrixType::IsRowMajor) { + // we have to transpose the lower part to to the upper one ap.resize(size,size); - ap.template selfadjointView() = a.template selfadjointView().twistedBy(m_P); + ap.template selfadjointView() = a.template selfadjointView(); } else - ap = a.template triangularView(); + internal::simplicial_cholesky_grab_input::run(a, pmat, ap); } }