2 #ifndef _SOLVER_SQMR_H_ 3 #define _SOLVER_SQMR_H_ 9 template<
class el_type,
class mat_type >
10 void solver<el_type, mat_type> :: sqmr(
int max_iter,
double stop_tol) {
18 vector<el_type> x(n), q(n), t(n), r(n), tmp(n);
28 double norm_rhs = norm(rhs, 2.0);
30 double res = norm_rhs;
34 auto Minv = [&](vector<el_type>& in, vector<el_type>& out) {
37 L.forwardsolve(tmp, out);
42 double tau = norm(t, 2.0);
46 double rho = dot_product(r, q);
48 double sigma, alpha, thet1, c2, rho1, beta;
52 while (res/norm_rhs > stop_tol && k <= max_iter) {
56 sigma = dot_product(q, t);
60 vector_sum(1, r, -alpha, t, r);
66 thet = norm(t, 2.0)/tau;
68 c2 = 1.0/(1 + thet*thet);
70 tau = tau * thet * sqrt(c2);
73 for (
int i = 0; i < n; i++) {
74 d[i] = c2 * alpha * q[i];
78 vector_sum(c2 * thet1 * thet1, d, c2 * alpha, q, d);
82 vector_sum(1, x, 1, d, x);
99 rho = dot_product(r, t);
101 vector_sum(1, t, beta, q, q);
107 std::string iter_str =
"iterations";
108 if (k-1 == 1) iter_str =
"iteration";
110 if (msg_lvl) printf(
"SQMR took %i %s and got down to relative residual %e.\n", k-1, iter_str.c_str(), resmin/norm_rhs);
114 #endif // _SOLVER_SQMR_H_