11#ifndef EIGEN_LEAST_SQUARE_CONJUGATE_GRADIENT_H
12#define EIGEN_LEAST_SQUARE_CONJUGATE_GRADIENT_H
15#include "./InternalHeaderCheck.h"
30template <
typename MatrixType,
typename Rhs,
typename Dest,
typename Preconditioner>
31EIGEN_DONT_INLINE
void least_square_conjugate_gradient(
const MatrixType& mat,
const Rhs& rhs, Dest& x,
32 const Preconditioner& precond, Index& iters,
33 typename Dest::RealScalar& tol_error) {
35 using RealScalar =
typename Dest::RealScalar;
36 using Scalar =
typename Dest::Scalar;
37 using VectorType = Matrix<Scalar, Dynamic, 1>;
39 RealScalar tol = tol_error;
40 Index maxIters = iters;
42 Index m = mat.rows(), n = mat.cols();
44 VectorType residual = rhs - mat * x;
45 VectorType normal_residual = mat.adjoint() * residual;
46 VectorType normal_rhs = mat.adjoint() * rhs;
48 RealScalar rhsNorm = normal_rhs.stableNorm();
55 RealScalar threshold = tol * rhsNorm;
56 RealScalar residualNorm = normal_residual.stableNorm();
57 if (residualNorm == 0 || residualNorm < threshold) {
59 tol_error = residualNorm / rhsNorm;
64 const RealScalar residualScale = internal::iterative_solver_scaling_factor(residualNorm);
65 normal_residual /= residualScale;
66 threshold /= residualScale;
69 p = precond.solve(normal_residual);
71 VectorType z(n), tmp(m);
72 RealScalar absNew = numext::real(normal_residual.dot(p));
74 while (i < maxIters) {
75 tmp.noalias() = mat * p;
77 Scalar alpha = absNew / tmp.squaredNorm();
78 x += (residualScale * alpha) * p;
79 residual -= (residualScale * alpha) * tmp;
80 normal_residual.noalias() = mat.adjoint() * residual;
81 normal_residual /= residualScale;
83 residualNorm = normal_residual.stableNorm();
84 if (residualNorm < threshold)
break;
86 z = precond.solve(normal_residual);
88 RealScalar absOld = absNew;
89 absNew = numext::real(normal_residual.dot(z));
90 RealScalar beta = absNew / absOld;
94 tol_error = residualNorm / (rhsNorm / residualScale);
100template <
typename MatrixType_,
106template <
typename MatrixType_,
typename Preconditioner_>
107struct traits<LeastSquaresConjugateGradient<MatrixType_, Preconditioner_> > {
108 using MatrixType = MatrixType_;
109 using Preconditioner = Preconditioner_;
152template <
typename MatrixType_,
typename Preconditioner_>
154 :
public IterativeSolverBase<LeastSquaresConjugateGradient<MatrixType_, Preconditioner_> > {
159 using Base::m_isInitialized;
160 using Base::m_iterations;
164 using MatrixType = MatrixType_;
165 using Scalar =
typename MatrixType::Scalar;
166 using RealScalar =
typename MatrixType::RealScalar;
167 using Preconditioner = Preconditioner_;
183 template <
typename MatrixDerived>
187 template <
typename Rhs,
typename Dest>
188 void _solve_vector_with_guess_impl(
const Rhs& b, Dest& x)
const {
190 m_error = Base::m_tolerance;
192 internal::least_square_conjugate_gradient(matrix(), b, x, Base::m_preconditioner, m_iterations, m_error);
IterativeSolverBase()
Definition IterativeSolverBase.h:136
Index maxIterations() const
Definition IterativeSolverBase.h:245
Jacobi preconditioner for LeastSquaresConjugateGradient.
Definition BasicPreconditioners.h:122
A conjugate gradient solver for sparse (or dense) least-square problems.
Definition LeastSquareConjugateGradient.h:154
LeastSquaresConjugateGradient()
Definition LeastSquareConjugateGradient.h:171
LeastSquaresConjugateGradient(const EigenBase< MatrixDerived > &A)
Definition LeastSquareConjugateGradient.h:184
@ Success
Definition Constants.h:457
@ NoConvergence
Definition Constants.h:461
Definition EigenBase.h:34