1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> 5 // 6 // This Source Code Form is subject to the terms of the Mozilla 7 // Public License v. 2.0. If a copy of the MPL was not distributed 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10 #ifndef EIGEN_SPARSE_SOLVE_H 11 #define EIGEN_SPARSE_SOLVE_H 12 13 namespace Eigen { 14 15 namespace internal { 16 17 template<typename _DecompositionType, typename Rhs> struct sparse_solve_retval_base; 18 template<typename _DecompositionType, typename Rhs> struct sparse_solve_retval; 19 20 template<typename DecompositionType, typename Rhs> 21 struct traits<sparse_solve_retval_base<DecompositionType, Rhs> > 22 { 23 typedef typename DecompositionType::MatrixType MatrixType; 24 typedef SparseMatrix<typename Rhs::Scalar, Rhs::Options, typename Rhs::Index> ReturnType; 25 }; 26 27 template<typename _DecompositionType, typename Rhs> struct sparse_solve_retval_base 28 : public ReturnByValue<sparse_solve_retval_base<_DecompositionType, Rhs> > 29 { 30 typedef typename remove_all<typename Rhs::Nested>::type RhsNestedCleaned; 31 typedef _DecompositionType DecompositionType; 32 typedef ReturnByValue<sparse_solve_retval_base> Base; 33 typedef typename Base::Index Index; 34 35 sparse_solve_retval_base(const DecompositionType& dec, const Rhs& rhs) 36 : m_dec(dec), m_rhs(rhs) 37 {} 38 39 inline Index rows() const { return m_dec.cols(); } 40 inline Index cols() const { return m_rhs.cols(); } 41 inline const DecompositionType& dec() const { return m_dec; } 42 inline const RhsNestedCleaned& rhs() const { return m_rhs; } 43 44 template<typename Dest> inline void evalTo(Dest& dst) const 45 { 46 static_cast<const sparse_solve_retval<DecompositionType,Rhs>*>(this)->evalTo(dst); 47 } 48 49 protected: 50 template<typename DestScalar, int DestOptions, typename DestIndex> 51 inline void defaultEvalTo(SparseMatrix<DestScalar,DestOptions,DestIndex>& dst) const 52 { 53 // we process the sparse rhs per block of NbColsAtOnce columns temporarily stored into a dense matrix. 54 static const int NbColsAtOnce = 4; 55 int rhsCols = m_rhs.cols(); 56 int size = m_rhs.rows(); 57 Eigen::Matrix<DestScalar,Dynamic,Dynamic> tmp(size,rhsCols); 58 Eigen::Matrix<DestScalar,Dynamic,Dynamic> tmpX(size,rhsCols); 59 for(int k=0; k<rhsCols; k+=NbColsAtOnce) 60 { 61 int actualCols = std::min<int>(rhsCols-k, NbColsAtOnce); 62 tmp.leftCols(actualCols) = m_rhs.middleCols(k,actualCols); 63 tmpX.leftCols(actualCols) = m_dec.solve(tmp.leftCols(actualCols)); 64 dst.middleCols(k,actualCols) = tmpX.leftCols(actualCols).sparseView(); 65 } 66 } 67 const DecompositionType& m_dec; 68 typename Rhs::Nested m_rhs; 69 }; 70 71 #define EIGEN_MAKE_SPARSE_SOLVE_HELPERS(DecompositionType,Rhs) \ 72 typedef typename DecompositionType::MatrixType MatrixType; \ 73 typedef typename MatrixType::Scalar Scalar; \ 74 typedef typename MatrixType::RealScalar RealScalar; \ 75 typedef typename MatrixType::Index Index; \ 76 typedef Eigen::internal::sparse_solve_retval_base<DecompositionType,Rhs> Base; \ 77 using Base::dec; \ 78 using Base::rhs; \ 79 using Base::rows; \ 80 using Base::cols; \ 81 sparse_solve_retval(const DecompositionType& dec, const Rhs& rhs) \ 82 : Base(dec, rhs) {} 83 84 85 86 template<typename DecompositionType, typename Rhs, typename Guess> struct solve_retval_with_guess; 87 88 template<typename DecompositionType, typename Rhs, typename Guess> 89 struct traits<solve_retval_with_guess<DecompositionType, Rhs, Guess> > 90 { 91 typedef typename DecompositionType::MatrixType MatrixType; 92 typedef Matrix<typename Rhs::Scalar, 93 MatrixType::ColsAtCompileTime, 94 Rhs::ColsAtCompileTime, 95 Rhs::PlainObject::Options, 96 MatrixType::MaxColsAtCompileTime, 97 Rhs::MaxColsAtCompileTime> ReturnType; 98 }; 99 100 template<typename DecompositionType, typename Rhs, typename Guess> struct solve_retval_with_guess 101 : public ReturnByValue<solve_retval_with_guess<DecompositionType, Rhs, Guess> > 102 { 103 typedef typename DecompositionType::Index Index; 104 105 solve_retval_with_guess(const DecompositionType& dec, const Rhs& rhs, const Guess& guess) 106 : m_dec(dec), m_rhs(rhs), m_guess(guess) 107 {} 108 109 inline Index rows() const { return m_dec.cols(); } 110 inline Index cols() const { return m_rhs.cols(); } 111 112 template<typename Dest> inline void evalTo(Dest& dst) const 113 { 114 dst = m_guess; 115 m_dec._solveWithGuess(m_rhs,dst); 116 } 117 118 protected: 119 const DecompositionType& m_dec; 120 const typename Rhs::Nested m_rhs; 121 const typename Guess::Nested m_guess; 122 }; 123 124 } // namepsace internal 125 126 } // end namespace Eigen 127 128 #endif // EIGEN_SPARSE_SOLVE_H 129