21 void MinResQLPSymOrtho(T
const a, T
const b, T &c, T &s, T &r)
60 Base::initIteration(rhs,x);
64 resvec.setZero(m_max_iters+1,1);
65 Aresvec.setZero(m_max_iters+1,1);
75 m_precond->apply(r2, r3);
76 beta1 = r2.col(0).dot(r3.col(0));
78 beta1 = math::sqrt(beta1);
80 tau = 0; taul = 0; gmin = 0;
81 phi = beta1; betan = beta1;
82 cs = -1; cr1 = -1; cr2 = -1;
83 sn = 0; sr1 = 0; sr2 = 0;
84 deltan = 0; epsilonn = 0;
85 gamma = 0; gammal = 0; gammal2 = 0;
86 eta = 0; etal = 0; etal2 = 0;
87 vepln = 0; veplnl = 0; veplnl2 = 0; ul3= 0;
88 ul2 = 0; ul = 0; u = 0; rnorm = betan;
94 x.setZero(n,m); w.setZero(n,m); wl.setZero(n,m);
101 m_error = r2.norm() / m_rhs_norm;
118 r3 = r3 - (beta/betal)*r1;
120 alpha = T (r3.col(0).dot(v.col(0)));
121 r3 = r3 - (alpha/beta)*r2;
125 m_precond->apply(r2,r3);
126 betan = r2.col(0).dot(r3.col(0));
127 GISMO_ASSERT(betan > 0,
"Preconditioner is indefinite");
128 betan = math::sqrt(betan);
131 pnorm = math::sqrt(alpha*alpha + betal*betal + betan*betan);
134 delta = cs*dbar + sn*alpha;
136 gbar = sn*dbar - cs*alpha;
143 MinResQLPSymOrtho(gbar, betan, cs, sn, gamma);
148 Axnorm = math::sqrt(Axnorm*Axnorm + tau*tau);
157 real_t delta_tmp = sr2*vepln - cr2*delta;
158 veplnl = cr2*vepln + sr2*delta;
165 MinResQLPSymOrtho(gammal, delta, cr1, sr1, gammal);
175 ul2 = (taul2 - etal2*ul4 - veplnl2*ul3) / gammal2;
179 ul = ( taul - etal *ul3 - veplnl *ul2) / gammal;
181 real_t xnorm_tmp = math::sqrt(xl2norm*xl2norm + ul2*ul2 + ul*ul);
182 if (
math::abs(gamma) > std::numeric_limits<real_t>::min() && xnorm_tmp < maxxnorm)
184 u = (tau - eta*ul2 - vepln*ul) / gamma;
185 if ( math::sqrt(xnorm_tmp*xnorm_tmp + u*u) > maxxnorm)
194 xl2norm = math::sqrt(xl2norm*xl2norm + ul2*ul2);
196 xnorm = math::sqrt(xl2norm*xl2norm + ul*ul + u*u);
204 xl2.setZero(m_mat->cols(),1);
209 wl2 = gammal3*wl2 + veplnl2*wl + etal*w;
213 wl = gammal_QLP*wl + vepln_QLP*w;
216 xl2 = x - wl*ul_QLP - w*u_QLP;
225 else if (m_num_iter ==2)
236 wl2 = wl2*cr2 + v*sr2;
242 x = xl2 + wl *ul + w*u;
244 real_t gammal_tmp = gammal;
245 MinResQLPSymOrtho(gammal, epsilonn, cr2, sr2, gammal);
247 gammal_QLP = gammal_tmp;
255 real_t tmp_max = std::max(gammal, abs_gamma);
256 Anorm = std::max(Anorm, pnorm);
257 Anorm = std::max(Anorm, tmp_max);
263 else if (m_num_iter > 1)
268 gmin = std::min(gminl2, gammal);
269 gmin = std::min(gmin, abs_gamma);
277 relres = rnorm / (Anorm*xnorm + beta1);
278 rootl = math::sqrt(gbar*gbar + deltan*deltan);
279 Arnorml = rnorml*rootl;
280 relAresl = rootl / Anorm;
284 if (m_inexact_residual)
290 m_mat->apply(x,negResidual);
292 m_error = r1_tmp.norm()/m_rhs_norm;
298 resvec(m_num_iter, 0) = rnorm;
299 Aresvec(m_num_iter-1, 0) = Arnorml;
308 m_mat->apply(x,negResidual);
309 r1 = m_rhs - negResidual;
311 m_mat->apply(r1, negResidual);
312 Arnorm = negResidual.norm();
314 relres = rnorm/(Anorm*xnorm + beta1);
317 if(rnorm > std::numeric_limits<real_t>::min())
319 relAres = Arnorm / (Anorm*rnorm);
321 Aresvec(m_num_iter, 0) = Arnorm;
322 Aresvec.conservativeResize(m_num_iter+1,1);
323 resvec.conservativeResize(m_num_iter+1,1);
324 r1.clear(); r2.clear(); r3.clear();
326 negResidual.clear(); v.clear();
328 wl.clear(); w.clear();
bool step(VectorType &x)
Perform one step, requires initIteration.
Definition: gsMinResQLP.hpp:109
void finalizeIteration(VectorType &x)
Some post-processing might be required.
Definition: gsMinResQLP.hpp:306
int getSign(T val)
Returns the sign of val.
Definition: gsMath.h:325
#define index_t
Definition: gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
bool initIteration(const VectorType &rhs, VectorType &x)
Init the iteration.
Definition: gsMinResQLP.hpp:57
EIGEN_STRONG_INLINE abs_expr< E > abs(const E &u)
Absolute value.
Definition: gsExpressions.h:4488