92   template <
typename Matrix, 
typename Vector, 
typename VectorB,
 
   94   void qmr(
const Matrix &A, Vector &x, 
const VectorB &b, 
const Precond1 &M1,
 
   97     typedef typename linalg_traits<Vector>::value_type T;
 
   98     typedef typename number_traits<T>::magnitude_type R;
 
  100     T delta(0), ep(0), beta(0), theta_1(0), gamma_1(0);
 
  101     T theta(0), gamma(1), eta(-1);
 
  104     typedef typename temporary_vector<Vector>::vector_type TmpVec;
 
  105     size_type nn = vect_size(x);
 
  106     TmpVec r(nn), v_tld(nn), y(nn), w_tld(nn), z(nn), v(nn), w(nn);
 
  107     TmpVec y_tld(nn), z_tld(nn), p(nn), q(nn), p_tld(nn), d(nn), s(nn);
 
  110     if (iter.get_rhsnorm() == 0.0) { 
clear(x); 
return; }
 
  112     gmm::mult(A, gmm::scaled(x, T(-1)), b, r);
 
  115     gmm::left_mult(M1, v_tld, y);
 
  119     gmm::transposed_right_mult(M1, w_tld, z);
 
  122     while (! iter.finished_vect(r)) {
 
  124       if (rho == R(0) || xi == R(0)) {
 
  125         if (iter.get_maxiter() == size_type(-1)) 
 
  126           { GMM_ASSERT1(
false, 
"QMR failed to converge"); }
 
  127         else { GMM_WARNING1(
"QMR failed to converge"); 
return; }
 
  129       gmm::copy(gmm::scaled(v_tld, T(R(1)/rho)), v);
 
  130       gmm::scale(y, T(R(1)/rho));
 
  132       gmm::copy(gmm::scaled(w_tld, T(R(1)/xi)), w);
 
  133       gmm::scale(z, T(R(1)/xi));
 
  137         if (iter.get_maxiter() == size_type(-1)) 
 
  138           { GMM_ASSERT1(
false, 
"QMR failed to converge"); }
 
  139         else { GMM_WARNING1(
"QMR failed to converge"); 
return; }
 
  141       gmm::right_mult(M1, y, y_tld);            
 
  142       gmm::transposed_left_mult(M1, z, z_tld);
 
  148         gmm::add(y_tld, gmm::scaled(p, -(T(xi  * delta) / ep)), p);
 
  149         gmm::add(z_tld, gmm::scaled(q, -(T(rho * delta) / ep)), q);
 
  156         if (iter.get_maxiter() == size_type(-1)) 
 
  157           { GMM_ASSERT1(
false, 
"QMR failed to converge"); }
 
  158         else { GMM_WARNING1(
"QMR failed to converge"); 
return; }
 
  162         if (iter.get_maxiter() == size_type(-1)) 
 
  163           { GMM_ASSERT1(
false, 
"QMR failed to converge"); }
 
  164         else { GMM_WARNING1(
"QMR failed to converge"); 
return; }
 
  166       gmm::add(p_tld, gmm::scaled(v, -beta), v_tld);
 
  167       gmm::left_mult(M1, v_tld, y);
 
  173       gmm::add(w_tld, gmm::scaled(w, -beta), w_tld);
 
  174       gmm::transposed_right_mult(M1, w_tld, z);
 
  181       theta = rho / (gamma_1 * beta);
 
  182       gamma = T(1) / gmm::sqrt(T(1) + gmm::sqr(theta));
 
  185         if (iter.get_maxiter() == size_type(-1)) 
 
  186           { GMM_ASSERT1(
false, 
"QMR failed to converge"); }
 
  187         else { GMM_WARNING1(
"QMR failed to converge"); 
return; }
 
  189       eta = -eta * T(rho_1) * gmm::sqr(gamma) / (beta * gmm::sqr(gamma_1));
 
  195         T tmp = gmm::sqr(theta_1 * gamma);
 
  196         gmm::add(gmm::scaled(p, eta), gmm::scaled(d, tmp), d);
 
  197         gmm::add(gmm::scaled(p_tld, eta), gmm::scaled(s, tmp), s);
 
The Iteration object calculates whether the solution has reached the desired accuracy,...
 
void copy(const L1 &l1, L2 &l2)
*/
 
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
 
void clear(L &l)
clear (fill with zeros) a vector or matrix.
 
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
 
strongest_value_type< V1, V2 >::value_type vect_sp(const V1 &v1, const V2 &v2)
*/
 
void add(const L1 &l1, L2 &l2)
*/
 
Include the base gmm files.
 
void qmr(const Matrix &A, Vector &x, const VectorB &b, const Precond1 &M1, iteration &iter)
Quasi-Minimal Residual.