36#include "./InternalHeaderCheck.h"
76template <
typename MatrixType,
typename Rhs,
typename Dest,
typename Preconditioner>
77EIGEN_DONT_INLINE Index lsmr(
const MatrixType& mat,
const Rhs& rhs, Dest& x,
const Preconditioner& precond,
78 Index& iters,
typename Dest::RealScalar& tol_error,
const typename Dest::RealScalar& atol,
79 const typename Dest::RealScalar& btol,
const typename Dest::RealScalar& lambda,
80 const typename Dest::RealScalar& conlim) {
83 using RealScalar =
typename Dest::RealScalar;
84 using Scalar =
typename Dest::Scalar;
85 using VectorType = Matrix<Scalar, Dynamic, 1>;
87 const RealScalar zero(0);
88 const RealScalar one(1);
90 const Index n = mat.cols();
91 const Index maxIters = iters;
94 VectorType v(n), Atu(n);
98 VectorType u = rhs - mat * x;
99 RealScalar alpha = zero;
100 RealScalar beta = u.stableNorm();
103 Atu.noalias() = mat.adjoint() * u;
104 v = precond.solve(Atu);
105 alpha = v.stableNorm();
106 if (alpha > zero) v /= alpha;
112 if (alpha * beta == zero) {
119 VectorType dx = VectorType::Zero(n);
121 VectorType hbar = VectorType::Zero(n);
125 RealScalar alphabar = alpha;
126 RealScalar zetabar = alpha * beta;
127 RealScalar rho = one;
128 RealScalar rhobar = one;
129 RealScalar cbar = one;
130 RealScalar sbar = zero;
133 RealScalar betadd = beta;
134 RealScalar betad = zero;
135 RealScalar rhodold = one;
136 RealScalar tautildeold = zero;
137 RealScalar thetatilde = zero;
138 RealScalar zeta = zero;
142 RealScalar normA2 = alpha * alpha;
143 RealScalar maxrbar = zero;
144 RealScalar minrbar = NumTraits<RealScalar>::highest();
146 const RealScalar normb = beta;
147 const RealScalar ctol = conlim > zero ? one / conlim : zero;
148 RealScalar test2 = zero;
159 t = precond.solve(v);
161 u.noalias() += mat * t;
162 beta = u.stableNorm();
165 Atu.noalias() = mat.adjoint() * u;
166 t = precond.solve(Atu);
168 alpha = v.stableNorm();
169 if (alpha > zero) v /= alpha;
173 const RealScalar alphahat = numext::hypot(alphabar, lambda);
174 const RealScalar chat = alphabar / alphahat;
175 const RealScalar shat = lambda / alphahat;
178 const RealScalar rhoold = rho;
179 rho = numext::hypot(alphahat, beta);
180 const RealScalar c = alphahat / rho;
181 const RealScalar s = beta / rho;
182 const RealScalar thetanew = s * alpha;
183 alphabar = c * alpha;
186 const RealScalar rhobarold = rhobar;
187 const RealScalar zetaold = zeta;
188 const RealScalar thetabar = sbar * rho;
189 const RealScalar rhotemp = cbar * rho;
190 rhobar = numext::hypot(cbar * rho, thetanew);
191 cbar = cbar * rho / rhobar;
192 sbar = thetanew / rhobar;
193 zeta = cbar * zetabar;
194 zetabar = -sbar * zetabar;
197 hbar = h - (thetabar * rho / (rhoold * rhobarold)) * hbar;
198 dx += (zeta / (rho * rhobar)) * hbar;
199 h = v - (thetanew / rho) * h;
202 const RealScalar betaacute = chat * betadd;
203 const RealScalar betacheck = -shat * betadd;
204 const RealScalar betahat = c * betaacute;
205 betadd = -s * betaacute;
207 const RealScalar thetatildeold = thetatilde;
208 const RealScalar rhotildeold = numext::hypot(rhodold, thetabar);
209 const RealScalar ctildeold = rhodold / rhotildeold;
210 const RealScalar stildeold = thetabar / rhotildeold;
211 thetatilde = stildeold * rhobar;
212 rhodold = ctildeold * rhobar;
213 betad = -stildeold * betad + ctildeold * betahat;
215 tautildeold = (zetaold - thetatildeold * tautildeold) / rhotildeold;
216 const RealScalar taud = (zeta - thetatilde * tautildeold) / rhodold;
217 d += betacheck * betacheck;
218 const RealScalar normr = sqrt(d + numext::abs2(betad - taud) + numext::abs2(betadd));
221 normA2 += beta * beta;
222 const RealScalar normA = sqrt(normA2);
223 normA2 += alpha * alpha;
226 maxrbar = numext::maxi(maxrbar, rhobarold);
227 if (itn > 1) minrbar = numext::mini(minrbar, rhobarold);
228 const RealScalar condA = numext::maxi(maxrbar, rhotemp) / numext::mini(minrbar, rhotemp);
231 const RealScalar normAr = abs(zetabar);
232 const RealScalar normx = dx.stableNorm();
234 const RealScalar test1 = normr / normb;
235 test2 = (normA * normr > zero) ? normAr / (normA * normr) : zero;
236 const RealScalar test3 = one / condA;
237 const RealScalar t1 = test1 / (one + normA * normx / normb);
238 const RealScalar rtol = btol + atol * normA * normx / normb;
247 else if (test2 <= atol)
249 else if (test3 <= ctol)
251 else if (one + t1 <= one)
253 else if (one + test2 <= one)
255 else if (one + test3 <= one)
257 else if (itn >= maxIters)
262 t = precond.solve(dx);
272template <
typename MatrixType_,
typename Preconditioner_ = IdentityPreconditioner>
277template <
typename MatrixType_,
typename Preconditioner_>
278struct traits<LSMR<MatrixType_, Preconditioner_> > {
279 using MatrixType = MatrixType_;
280 using Preconditioner = Preconditioner_;
353template <
typename MatrixType_,
typename Preconditioner_>
359 using Base::m_isInitialized;
360 using Base::m_iterations;
364 using MatrixType = MatrixType_;
365 using Scalar =
typename MatrixType::Scalar;
366 using RealScalar =
typename MatrixType::RealScalar;
367 using Preconditioner = Preconditioner_;
382 template <
typename MatrixDerived>
400 RealScalar
damping()
const {
return m_lambda; }
407 m_conditionLimit = conlim;
425 RealScalar
toleranceA()
const {
return m_atol >= RealScalar(0) ? m_atol : Base::m_tolerance; }
438 RealScalar
toleranceB()
const {
return m_btol >= RealScalar(0) ? m_btol : Base::m_tolerance; }
441 template <
typename Rhs,
typename Dest>
442 void _solve_vector_with_guess_impl(
const Rhs& b, Dest& x)
const {
445 Index istop = internal::lsmr(matrix(), b, x, Base::m_preconditioner, m_iterations, m_error,
toleranceA(),
455 RealScalar m_lambda = RealScalar(0);
456 RealScalar m_conditionLimit = RealScalar(0);
458 RealScalar m_atol = RealScalar(-1);
459 RealScalar m_btol = RealScalar(-1);
IterativeSolverBase()
Definition IterativeSolverBase.h:136
Index maxIterations() const
Definition IterativeSolverBase.h:245
An LSMR solver for sparse (or dense) least-squares problems.
Definition LSMR.h:354
LSMR(const EigenBase< MatrixDerived > &A)
Definition LSMR.h:383
LSMR()
Definition LSMR.h:370
LSMR & setConditionLimit(const RealScalar &conlim)
Definition LSMR.h:406
LSMR & setDamping(const RealScalar &lambda)
Definition LSMR.h:394
LSMR & setToleranceB(const RealScalar &btol)
Definition LSMR.h:431
RealScalar conditionLimit() const
Definition LSMR.h:412
RealScalar damping() const
Definition LSMR.h:400
RealScalar toleranceB() const
Definition LSMR.h:438
LSMR & setToleranceA(const RealScalar &atol)
Definition LSMR.h:418
RealScalar toleranceA() const
Definition LSMR.h:425
@ Success
Definition Constants.h:457
@ NoConvergence
Definition Constants.h:461
Definition EigenBase.h:34