TBCI Numerical high perf. C++ Library  2.8.0
gmres.h
Go to the documentation of this file.
1 
5 /* $Id: gmres.h,v 1.10.2.23 2022/11/03 17:28:12 garloff Exp $ */
6 
7 #ifndef TBCI_SOLVER_GMRES_H
8 #define TBCI_SOLVER_GMRES_H
9 
10 #include "tbci/basics.h"
11 
13 
14 INST2(template <Matrix<T>, Vector<T> > class NN friend \
15 void Update (Vector<T>&, int, Matrix<T>&, Vector<T>&, Vector<T>*);)
16 INST2(template <BdMatrix<T>, Vector<T> > class NN friend \
17 void Update (Vector<T>&, int, BdMatrix<T>&, Vector<T>&, Vector<T>*);)
18 
19 
20 //Aenderung Marco:
21 template < typename SysMatrix, typename SysVector >
22 void Update(SysVector& x, int k, SysMatrix& h, SysVector& s, SysVector *V)
23 {
24  SysVector y(s);
25 
26  // Backsolve:
27  for (int i = k; i >= 0; --i) {
28  y(i) /= h(i,i);
29  for (int j = i - 1; j >= 0; --j)
30  y(j) -= h(j,i) * y(i);
31  }
32 
33  for (int j = 0; j <= k; ++j)
34  //Aenderung Marco:
35  //x += V[j] * y(j);
36  x += /*CPLX__ conj*/ (y(j)) * V[j];
37  /*statt:
38  x += v[j] * y(j);
39  */
40 }
41 
49 INST(template <typename T> class NN friend \
50  void GeneratePlaneRotation(const T &, const double &, double &, T &);)
51 
52 template<typename T>
53 inline void GeneratePlaneRotation(const T &dx, const double &dy, double &cs, T &sn)
54 {
55  if (UNLIKELY(dy == 0.0)) {
56  cs = 1.0;
57  sn = (T)0.0;
58  } else if (UNLIKELY (dx == (T)0.0)) {
59  cs = 0.0;
60  sn = (T)1.0;
61  }
62 #if 1
63  else { /* dy is always larger or equal than dx */
64  const double rel = fabssqr(dx/dy);
65  const double ynorm = 1.0 / MATH__ sqrt (1.0 + rel);
66  cs = MATH__ sqrt(rel) * ynorm;
67  sn = cs * dy / dx;
68  }
69 #else
70  else {
71  const double rnorm = 1.0/MATH__ sqrt (fabssqr(dx) + fabssqr(dy));
72  cs = MATH__ fabs(dx) * rnorm /* * sign(dx)*/;
73  sn = cs * dy / dx;
74  }
75 #endif
76 }
77 
78 
79 INST(template <typename T> class NN friend \
80  void ApplyPlaneRotation(T &, T &, const double &, const T &);)
81 
82 template<typename T>
83 inline void ApplyPlaneRotation(T &dx, T &dy, const double &cs, const T &sn)
84 {
85  REGISTER T temp = /*CPLX__ conj*/(cs) * dx + CPLX__ conj (sn) * dy;
86  dy = cs * dy - sn * dx;
87  dx = temp;
88 }
89 
90 
131 INST3(template <typename T, Matrix<T>, Vector<T> > class NN friend \
132 int GMRES (const Matrix<T>&, Vector<T>&, const Vector<T>&,\
133  const Preconditioner_Sig<T, Matrix<T> >&, int&, unsigned int&, double&);)
134 INST3(template <typename T, BdMatrix<T>, Vector<T> > class NN friend \
135 int GMRES (const BdMatrix<T>&, Vector<T>&, const Vector<T>&,\
136  const Preconditioner_Sig<T, BdMatrix<T> >&, int&, unsigned int&, double&);)
137 
138 
139 template < typename T, typename SysMatrix, typename SysVector >
140 int GMRES (const SysMatrix &A, SysVector &x, const SysVector &b,
141  const Preconditioner_Sig<T, SysMatrix> &M, int &m,
142  unsigned int &max_iter, double &tol)
143 {
144  const unsigned int dim = A.rows();
145  if (m == 0)
146  m = dim/8+max_iter/4;
147  if ((unsigned)m > max_iter)
148  m = max_iter;
149  SysVector s(m+1), sn(m+1), w(dim), r(dim);
150  Vector<double> cs(m+1);
151  Matrix<T> H(m+1, m+1);
152  int restart = 0;
153 
154  double normb = MATH__ sqrt(fabssqr(M.solve(b)));
155  if (UNLIKELY(normb < 1e-16))
156  normb = 1e-16;
157 
158  r = M.solve(b - A * x);
159 
160  const double rel_tol = tol*normb;
161 
162  double beta = r.fabs();
163 
164  if (beta <= rel_tol) {
165  tol = beta / normb;
166  max_iter = 0;
167  //m = 0;
168  return 0;
169  }
170 
171  unsigned int j;
172  int err = 0;
173 
174  //SysVector *V = new SysVector[m+1](dim);
175  SysVector *V = new SysVector[m+1];
176  for (j = 0; j <= (unsigned)m; ++j)
177  V[j].resize(dim);
178 
179  j = 1;
180  while (j <= max_iter) {
181 
182  V[0] = r /(T)beta;
183  s.fill ((T)0.0); s(0) = (T) beta;
184  //cs.fill (0.0); sn.fill((T)0.0);
185 
186  for (int i = 0; (i < m) && (j <= max_iter); ++i, ++j) {
187  int k;
188 
189  w = M.solve (A * V[i]);
190 
191  for (k = 0; k <= i; k++) {
192  H(k, i) = dot (V[k], w);
193  //H(k, i) = dot (w, V[k]);
194  //H(k, i) = w * V[k];
195  //H (k,i) = CPLX__ conj (w * V[k]);
196  w -= H(k, i) * V[k];
197  //w -= CPLX__ conj(H(k, i)) * V[k];
198  }
199  const REGISTER double normw = w.fabs();
200  H(i+1, i) = normw;
201  // This breakdown is a good one ...
202  //if (normw == 0.0)
203  // goto GMR_out;
204  if (UNLIKELY(normw == 0))
205  V[i+1] = w;
206  else
207  V[i+1] = w / normw;
208  //for (k = 0; k < dim; ++k)
209  // V[i+1](k) = CPLX__ conj(w(k) /normw);
210  //V[i+1] = CPLX__ conj(w) / H(i+1, i);
211 
212  for (k = 0; k < i; k++)
213  ApplyPlaneRotation(H(k,i), H(k+1,i), cs(k), sn(k));
214 
215  GeneratePlaneRotation(H(i,i), normw, cs(i), sn(i));
216  ApplyPlaneRotation(H(i,i), H(i+1,i), cs(i), sn(i));
217  ApplyPlaneRotation(s(i), s(i+1), cs(i), sn(i));
218 
219 #ifdef _MSC_VER
220  using ::fabs;
222  beta = fabs(s(i+1));
223 #else
224  beta = MATH__ fabs(s(i+1));
225 #endif
226 
227  if (beta <= rel_tol) {
228  Update(x, i, H, s, V);
229  goto GMR_out;
230  }
231  }
232  Update(x, m - 1, H, s, V);
233  r = M.solve(b - A * x);
234  beta = r.fabs();
235  if (beta < rel_tol)
236  goto GMR_out;
237  ++restart;
238  }
239 
240  err = 1;
241 
242  GMR_out:
243  tol = beta / normb;
244  max_iter = j;
245  //m = restart;
246  delete[] V;
247  return err;
248 }
249 
251 
252 #endif /* TBCI_SOLVER_GMRES_H */
const Vector< T > const Vector< T > & x
Definition: LM_fit.h:97
Abstract base class for all Preconditioners.
Definition: precond.h:40
const double & dy
Definition: gmres.h:53
const Vector< T > const Vector< T > const Vector< T > int T h
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
#define REGISTER
Definition: basics.h:108
double fabs(const int a)
Definition: basics.h:1215
#define NAMESPACE_TBCI
Definition: basics.h:317
const double double & cs
Definition: gmres.h:53
#define UNLIKELY(expr)
Definition: basics.h:101
double sqrt(const int a)
Definition: basics.h:1216
F_TMatrix< T > b
Definition: f_matrix.h:736
#define INST2(x, y)
Definition: basics.h:239
int conj(const int arg)
conj for elementary types
Definition: basics.h:1055
#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
#define CPLX__
Definition: basics.h:341
#define INST(x)
Definition: basics.h:238
T dot(const T &a1, const T &a2)
Definition: basics.h:1183
int i
Definition: LM_fit.h:71
NAMESPACE_TBCI Vector< T > class NN friend void Update(Vector< T > &, int, BdMatrix< T > &, Vector< T > &, Vector< T > *)
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
#define MATH__
Definition: basics.h:339