diff options
author | 2015-03-04 09:34:27 +0100 | |
---|---|---|
committer | 2015-03-04 09:34:27 +0100 | |
commit | 05274219a7c5fdf04bfda089dc3f9eb2923fcc7e (patch) | |
tree | 1f5faca59ebd457ccf1d4beb9dbbb69a448f9376 /Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h | |
parent | f8390995127f9f73f2376c43f93eaa27bbad3675 (diff) |
Add a CG-based solver for rectangular least-square problems (bug #975).
Diffstat (limited to 'Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h')
-rw-r--r-- | Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h | 70 |
1 files changed, 67 insertions, 3 deletions
diff --git a/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h b/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h index a09f81225..6da423cf6 100644 --- a/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +++ b/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h @@ -17,9 +17,9 @@ namespace Eigen { * * This class allows to approximately solve for A.x = b problems assuming A is a diagonal matrix. * In other words, this preconditioner neglects all off diagonal entries and, in Eigen's language, solves for: - * \code - * A.diagonal().asDiagonal() . x = b - * \endcode + \code + A.diagonal().asDiagonal() . x = b + \endcode * * \tparam _Scalar the type of the scalar. * @@ -28,6 +28,7 @@ namespace Eigen { * * \note A variant that has yet to be implemented would attempt to preserve the norm of each column. * + * \sa class LeastSquareDiagonalPreconditioner, class ConjugateGradient */ template <typename _Scalar> class DiagonalPreconditioner @@ -100,6 +101,69 @@ class DiagonalPreconditioner bool m_isInitialized; }; +/** \ingroup IterativeLinearSolvers_Module + * \brief Jacobi preconditioner for LSCG + * + * This class allows to approximately solve for A' A x = A' b problems assuming A' A is a diagonal matrix. + * In other words, this preconditioner neglects all off diagonal entries and, in Eigen's language, solves for: + \code + (A.adjoint() * A).diagonal().asDiagonal() * x = b + \endcode + * + * \tparam _Scalar the type of the scalar. + * + * The diagonal entries are pre-inverted and stored into a dense vector. + * + * \sa class LSCG, class DiagonalPreconditioner + */ +template <typename _Scalar> +class LeastSquareDiagonalPreconditioner : public DiagonalPreconditioner<_Scalar> +{ + typedef _Scalar Scalar; + typedef typename NumTraits<Scalar>::Real RealScalar; + typedef DiagonalPreconditioner<_Scalar> Base; + using Base::m_invdiag; + public: + + LeastSquareDiagonalPreconditioner() : Base() {} + + template<typename MatType> + explicit LeastSquareDiagonalPreconditioner(const MatType& mat) : Base() + { + compute(mat); + } + + template<typename MatType> + LeastSquareDiagonalPreconditioner& analyzePattern(const MatType& ) + { + return *this; + } + + template<typename MatType> + LeastSquareDiagonalPreconditioner& factorize(const MatType& mat) + { + // Compute the inverse squared-norm of each column of mat + m_invdiag.resize(mat.cols()); + for(Index j=0; j<mat.outerSize(); ++j) + { + RealScalar sum = mat.innerVector(j).squaredNorm(); + if(sum>0) + m_invdiag(j) = RealScalar(1)/sum; + else + m_invdiag(j) = RealScalar(1); + } + Base::m_isInitialized = true; + return *this; + } + + template<typename MatType> + LeastSquareDiagonalPreconditioner& compute(const MatType& mat) + { + return factorize(mat); + } + + protected: +}; /** \ingroup IterativeLinearSolvers_Module * \brief A naive preconditioner which approximates any matrix as the identity matrix |