TBCI Numerical high perf. C++ Library  2.8.0
qmr.h
Go to the documentation of this file.
1 
7 #ifndef TBCI_SOLVER_QMR_H
8 #define TBCI_SOLVER_QMR_H
9 
10 #include "tbci/basics.h"
11 
13 
14 
15 INST3(template <typename T, Matrix<T>, Vector<T> > class NN friend \
16 int QMR (const Matrix<T>&, Vector<T>&, const Vector<T>&,\
17  const Preconditioner_Sig<T, Matrix<T> >&, const Preconditioner_Sig<T, Matrix<T> >&, unsigned int&, double&);)
18 INST3(template <typename T, BdMatrix<T>, Vector<T> > class NN friend \
19 int QMR (const BdMatrix<T>&, Vector<T>&, const Vector<T>&,\
20  const Preconditioner_Sig<T, BdMatrix<T> >&, const Preconditioner_Sig<T, BdMatrix<T> >&, unsigned int&, double&);)
21 
22 
57 //Aenderung Marco:
58 template < typename T,typename SysMatrix,typename SysVector >
59 int QMR(const SysMatrix &A, SysVector &x, const SysVector &b,
61  unsigned int &max_iter, double &tol)
62 {
63  double rho, rho_1, xi;
64  // KG, 2001-06-27: Probably some of these should be double instead of complex
65  // resulting in fabs to be used instead of abs. Maybe fabssqr() as optimization?
66  // KG, 2002-07-24: OK, converted things ...
67  // The solver now seems to work for complex variables.
68  double gamma, gamma_1;
69  //typename SysVector::value_type gamma, gamma_1;
70  typename SysVector::value_type theta, theta_1;
71  //double theta, theta_1;
72  typename SysVector::value_type eta, delta, beta;
73  typename SysVector::value_type ep = (typename SysVector::value_type)0;
74 
75  const unsigned int dim = A.rows();
76  // KG, 2001-06-27: A few of those should be optimised away ...
77  SysVector r(dim), v_tld(dim), y(dim), w_tld(dim), z(dim);
78  SysVector v(dim), w(dim), y_tld(dim), z_tld(dim);
79  SysVector p(dim), q(dim), p_tld(dim), d(dim), s(dim);
80 
81  double residsqr;
82  double normbsqr = b.fabssqr();
83  if (normbsqr < 1e-32)
84  normbsqr = 1e32;
85  else
86  normbsqr = 1.0/normbsqr;
87  const double tolsqr = sqr(tol);
88 
89  int err = 1;
90 
91  r = b - A * x;
92 
93 #define QMR_OUT(r) do { err = r; goto qmr_out; } while(0)
94 
95  unsigned i = 0;
96  if ((residsqr = r.fabssqr() * normbsqr) <= tolsqr)
97  QMR_OUT (0);
98 
99  //M1.update(A);
100  //M2.update(A);
101 
102  v_tld = r;
103  y = M1.solve(v_tld);
104  rho = /*(typename SysVector::value_type)*/ y.fabs();
105 
106  w_tld = r;
107  z = M2.transSolve(w_tld);
108  xi = /*(typename SysVector::value_type)*/ z.fabs();
109 
110  gamma = /*(typename SysVector::value_type)*/ 1.0;
111  eta = (typename SysVector::value_type)-1.0;
112  theta = (typename SysVector::value_type) 0.0;
113 
114  for (i = 1; i <= max_iter; i++)
115  {
116  if (rho == 0.0)
117  QMR_OUT(2); // return on breakdown
118 
119  if (xi == 0.0)
120  QMR_OUT(7); // return on breakdown
121 
122  v = v_tld * (1. / rho);
123  y = y * (1. / rho);
124 
125  w = w_tld * (1. / xi);
126  z = z * (1. / xi);
127 
128  //delta = dot(z, y);
129  delta = z * y;
130  if (delta == 0.0)
131  QMR_OUT(5); // return on breakdown
132 
133  y_tld = M2.solve(y); // apply preconditioners
134  z_tld = M1.transSolve(z);
135 
136  if (i > 1) {
137  p = y_tld - (typename SysVector::value_type)(xi * delta / ep) * p;
138  q = z_tld - (typename SysVector::value_type)(rho* delta / ep) * q;
139  } else {
140  p = y_tld;
141  q = z_tld;
142  }
143 
144  p_tld = A * p;
145  //ep = dot(q, p_tld);
146  ep = q * p_tld;
147  if (ep == 0.0)
148  QMR_OUT(6); // return on breakdown
149 
150  beta = ep / delta;
151  if (beta == 0.0)
152  QMR_OUT(3); // return on breakdown
153 
154  v_tld = p_tld - beta * v;
155  //v_tld = p_tld - CPLX__ conj(beta) * v;
156  y = M1.solve(v_tld);
157 
158  rho_1 = rho;
159  rho = /*(typename SysVector::value_type)*/ y.fabs();
160  w_tld = A.transMult(q) - beta * w;
161  //w_tld = A.transMult(q) - CPLX__ conj(beta) * w;
162  z = M2.transSolve(w_tld);
163 
164  xi = /*(typename SysVector::value_type)*/ z.fabs();
165 
166  gamma_1 = gamma;
167  theta_1 = theta;
168  theta = rho / (gamma_1 * beta);
169  //theta = rho / dot(gamma_1, beta);
170 
171 #ifdef _MSC_VER /* STD__ != MATH__ */
172 // typename SysVector::value_type (1.0 + theta*theta); // dot (theta, theta) ??
173  double c(1.0 + fabssqr(theta));
174  {
175  using std::sqrt; using ::sqrt;
176  gamma = sqrt(c); // dot (theta, theta) ??
177  }
178 #else
179 # ifdef HAVE_LIBC_NEQ_CPLX_BUG
180 # if !defined(_SGI_SOURCE) || !defined(_COMPILER_VERSION)
181  using STD__ sqrt;
182 # endif
183  using MATH__ sqrt;
184  gamma = 1.0 / sqrt(1.0 + fabssqr(theta)); // dot (theta, theta) ??
185 # else
186  gamma = 1.0 / MATH__ sqrt(1.0 + fabssqr(theta)); // dot (theta, theta) ??
187 # endif
188 #endif
189 
190  if (gamma == 0.0)
191  QMR_OUT(4); // return on breakdown
192 
193 #if defined(USE_BUILTIN_CPLX) && defined(TYPE)
194  eta = -hcplx(eta)* rho_1 * gamma * gamma /
195  (beta * gamma_1 * gamma_1);
196 #else
197  eta = -eta * rho_1 * gamma * gamma /
198  (beta * gamma_1 * gamma_1);
199 #endif
200 
201  if (i > 1) {
202  const typename SysVector::value_type _tmp = fabssqr(theta_1) * fabssqr(gamma);
203  d = eta * p + _tmp * d;
204  s = eta * p_tld + _tmp * s;
205  } else {
206  d = eta * p;
207  s = eta * p_tld;
208  }
209 
210  x += d; // update approximation vector
211  r -= s; // compute residual
212 
213  if ((residsqr = r.fabssqr() * normbsqr) <= tolsqr)
214  QMR_OUT(0);
215  }
216 
217  qmr_out:
218  max_iter = i;
219  tol = MATH__ sqrt(residsqr);
220  return err; // no convergence
221 }
222 
224 
225 #endif /* TBCI_SOLVER_QMR_H */
const Vector< T > const Vector< T > & x
Definition: LM_fit.h:97
Abstract base class for all Preconditioners.
Definition: precond.h:40
const Vector< T > const Vector< T > const Vector< T > & p
Definition: LM_fit.h:97
The class BdMatrix is an implementation to store and do operations on sparse Matrices with a band str...
Definition: band_matrix.h:103
return c
Definition: f_matrix.h:760
virtual TVector< T > transSolve(const Vector< T > &) const =0
#define NAMESPACE_TBCI
Definition: basics.h:317
NAMESPACE_TBCI Vector< T > class NN friend int QMR(const BdMatrix< T > &, Vector< T > &, const Vector< T > &, const Preconditioner_Sig< T, BdMatrix< T > > &, const Preconditioner_Sig< T, BdMatrix< T > > &, unsigned int &, double &)
cplx< double > gamma(const cplx< double > &z)
Definition: specfun.cpp:39
#define QMR_OUT(r)
const Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > & z
Definition: LM_fit.h:172
double sqrt(const int a)
Definition: basics.h:1216
cplx< T > sqr(const cplx< T > &c)
Definition: cplx.h:449
F_TMatrix< T > b
Definition: f_matrix.h:736
#define INST3(x, y, z)
Definition: basics.h:240
Definition: bvector.h:49
const Vector< T > const Vector< T > const Vector< T > int T T & err
Definition: LM_fit.h:102
int i
Definition: LM_fit.h:71
#define STD__
Definition: basics.h:338
SysMatrix
Definition: bicgstab.h:90
virtual TVector< T > solve(const Vector< T > &) const =0
#define NAMESPACE_END
Definition: basics.h:323
Definition: bvector.h:54
const Vector< T > Vector< T > Vector< T > Vector< T > & y
Definition: LM_fit.h:172
double fabssqr(const double a)
Definition: basics.h:1157
#define T
Definition: bdmatlib.cc:20
const Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > long int int char v
&lt; find minimun of func on grid with resolution res
Definition: LM_fit.h:205
#define MATH__
Definition: basics.h:339