37 template <
class Matrix,
class Vector,
class Preconditioner1,
38 class Preconditioner2,
class Real >
41 const Preconditioner2 &M2, int64_t &max_iter, Real &
tol)
45 Vector rho(1), rho_1(1), xi(1),
gamma(1), gamma_1(1), theta(1), theta_1(1);
46 Vector eta(1), delta(1), ep(1), beta(1);
48 Vector r, v_tld, y, w_tld, z;
62 if ((resid = norm(r) / normb) <= tol) {
73 z = M2.trans_solve(w_tld);
80 for (int64_t i = 1; i <= max_iter; i++) {
88 v = (1. / rho(0)) * v_tld;
89 y = (1. / rho(0)) * y;
91 w = (1. / xi(0)) * w_tld;
99 z_tld = M1.trans_solve(z);
102 p = y_tld - (xi(0) * delta(0) / ep(0)) * p;
103 q = z_tld - (rho(0) * delta(0) / ep(0)) * q;
110 ep(0) = dot(q, p_tld);
114 beta(0) = ep(0) / delta(0);
118 v_tld = p_tld - beta(0) * v;
123 w_tld = A.trans_mult(q) - beta(0) * w;
124 z = M2.trans_solve(w_tld);
128 gamma_1(0) =
gamma(0);
129 theta_1(0) = theta(0);
131 theta(0) = rho(0) / (gamma_1(0) * beta(0));
132 gamma(0) = 1.0 /
sqrt(1.0 + theta(0) * theta(0));
137 eta(0) = -eta(0) * rho_1(0) *
gamma(0) *
gamma(0) /
138 (beta(0) * gamma_1(0) * gamma_1(0));
141 d = eta(0) * p + (theta_1(0) * theta_1(0) *
gamma(0) *
gamma(0)) * d;
142 s = eta(0) * p_tld + (theta_1(0) * theta_1(0) *
gamma(0) *
gamma(0)) * s;
151 if ((resid = norm(r) / normb) <= tol) {
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ sqrt
int QMR(const Matrix &A, Vector &x, const Vector &b, const Preconditioner1 &M1, const Preconditioner2 &M2, int64_t &max_iter, Real &tol)
QMR solves the unsymmetric linear system using the Quasi-Minimal Residual method.
long double gamma(unsigned int n)
Evaluate the factorial of a integer.