1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr> 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_ITERATIVE_SOLVER_BASE_H 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_ITERATIVE_SOLVER_BASE_H 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen { 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \ingroup IterativeLinearSolvers_Module 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \brief Base class for linear iterative solvers 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate< typename Derived> 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass IterativeSolverBase : internal::noncopyable 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpublic: 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::traits<Derived>::MatrixType MatrixType; 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::traits<Derived>::Preconditioner Preconditioner; 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixType::Scalar Scalar; 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixType::Index Index; 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixType::RealScalar RealScalar; 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpublic: 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Derived& derived() { return *static_cast<Derived*>(this); } 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Derived& derived() const { return *static_cast<const Derived*>(this); } 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Default constructor. */ 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath IterativeSolverBase() 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : mp_matrix(0) 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath init(); 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Initialize the solver with matrix \a A for further \c Ax=b solving. 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This constructor is a shortcut for the default constructor followed 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * by a call to compute(). 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \warning this class stores a reference to the matrix A as well as some 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * precomputed values that depend on it. Therefore, if \a A is changed 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * this class becomes invalid. Call compute() to update it with the new 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * matrix A, or modify a copy of A. 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath IterativeSolverBase(const MatrixType& A) 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath init(); 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath compute(A); 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ~IterativeSolverBase() {} 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Initializes the iterative solver for the sparcity pattern of the matrix \a A for further solving \c Ax=b problems. 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Currently, this function mostly call analyzePattern on the preconditioner. In the future 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * we might, for instance, implement column reodering for faster matrix vector products. 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Derived& analyzePattern(const MatrixType& A) 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_preconditioner.analyzePattern(A); 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_isInitialized = true; 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_analysisIsOk = true; 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_info = Success; 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return derived(); 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Initializes the iterative solver with the numerical values of the matrix \a A for further solving \c Ax=b problems. 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Currently, this function mostly call factorize on the preconditioner. 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \warning this class stores a reference to the matrix A as well as some 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * precomputed values that depend on it. Therefore, if \a A is changed 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * this class becomes invalid. Call compute() to update it with the new 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * matrix A, or modify a copy of A. 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Derived& factorize(const MatrixType& A) 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mp_matrix = &A; 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_preconditioner.factorize(A); 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_factorizationIsOk = true; 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_info = Success; 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return derived(); 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Initializes the iterative solver with the matrix \a A for further solving \c Ax=b problems. 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Currently, this function mostly initialized/compute the preconditioner. In the future 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * we might, for instance, implement column reodering for faster matrix vector products. 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \warning this class stores a reference to the matrix A as well as some 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * precomputed values that depend on it. Therefore, if \a A is changed 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * this class becomes invalid. Call compute() to update it with the new 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * matrix A, or modify a copy of A. 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Derived& compute(const MatrixType& A) 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mp_matrix = &A; 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_preconditioner.compute(A); 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_isInitialized = true; 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_analysisIsOk = true; 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_factorizationIsOk = true; 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_info = Success; 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return derived(); 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal */ 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index rows() const { return mp_matrix ? mp_matrix->rows() : 0; } 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal */ 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index cols() const { return mp_matrix ? mp_matrix->cols() : 0; } 118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the tolerance threshold used by the stopping criteria */ 120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar tolerance() const { return m_tolerance; } 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Sets the tolerance threshold used by the stopping criteria */ 1237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Derived& setTolerance(const RealScalar& tolerance) 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_tolerance = tolerance; 126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return derived(); 127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns a read-write reference to the preconditioner for custom configuration. */ 130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Preconditioner& preconditioner() { return m_preconditioner; } 131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns a read-only reference to the preconditioner. */ 133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Preconditioner& preconditioner() const { return m_preconditioner; } 134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the max number of iterations */ 136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int maxIterations() const 137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return (mp_matrix && m_maxIterations<0) ? mp_matrix->cols() : m_maxIterations; 139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Sets the max number of iterations */ 142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Derived& setMaxIterations(int maxIters) 143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_maxIterations = maxIters; 145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return derived(); 146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the number of iterations performed during the last solve */ 149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int iterations() const 150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "ConjugateGradient is not initialized."); 152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_iterations; 153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the tolerance error reached during the last solve */ 156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar error() const 157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "ConjugateGradient is not initialized."); 159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_error; 160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. 163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa compute() 165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename Rhs> inline const internal::solve_retval<Derived, Rhs> 167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath solve(const MatrixBase<Rhs>& b) const 168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized."); 170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(rows()==b.rows() 171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath && "IterativeSolverBase::solve(): invalid number of rows of the right hand side matrix b"); 172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return internal::solve_retval<Derived, Rhs>(derived(), b.derived()); 173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. 176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa compute() 178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename Rhs> 180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline const internal::sparse_solve_retval<IterativeSolverBase, Rhs> 181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath solve(const SparseMatrixBase<Rhs>& b) const 182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized."); 184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(rows()==b.rows() 185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath && "IterativeSolverBase::solve(): invalid number of rows of the right hand side matrix b"); 186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return internal::sparse_solve_retval<IterativeSolverBase, Rhs>(*this, b.derived()); 187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns Success if the iterations converged, and NoConvergence otherwise. */ 190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ComputationInfo info() const 191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized."); 193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_info; 194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal */ 197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename Rhs, typename DestScalar, int DestOptions, typename DestIndex> 198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void _solve_sparse(const Rhs& b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const 199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(rows()==b.rows()); 201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int rhsCols = b.cols(); 203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int size = b.rows(); 204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Eigen::Matrix<DestScalar,Dynamic,1> tb(size); 205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Eigen::Matrix<DestScalar,Dynamic,1> tx(size); 206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(int k=0; k<rhsCols; ++k) 207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath tb = b.col(k); 209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath tx = derived().solve(tb); 210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dest.col(k) = tx.sparseView(0); 211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathprotected: 215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void init() 216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_isInitialized = false; 218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_analysisIsOk = false; 219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_factorizationIsOk = false; 220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_maxIterations = -1; 221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_tolerance = NumTraits<Scalar>::epsilon(); 222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const MatrixType* mp_matrix; 224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Preconditioner m_preconditioner; 225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int m_maxIterations; 227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar m_tolerance; 228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mutable RealScalar m_error; 230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mutable int m_iterations; 231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mutable ComputationInfo m_info; 232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mutable bool m_isInitialized, m_analysisIsOk, m_factorizationIsOk; 233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal { 236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived, typename Rhs> 238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct sparse_solve_retval<IterativeSolverBase<Derived>, Rhs> 239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : sparse_solve_retval_base<IterativeSolverBase<Derived>, Rhs> 240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef IterativeSolverBase<Derived> Dec; 242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) 243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename Dest> void evalTo(Dest& dst) const 245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dec().derived()._solve_sparse(rhs(),dst); 247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal 251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen 253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_ITERATIVE_SOLVER_BASE_H 255