TBCI Numerical high perf. C++ Library 2.8.0
gmres.h
Go to the documentation of this file.
1
4
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
14INST2(template <Matrix<T>, Vector<T> > class NN friend \
15void Update (Vector<T>&, int, Matrix<T>&, Vector<T>&, Vector<T>*);)
16INST2(template <BdMatrix<T>, Vector<T> > class NN friend \
18
19
20//Aenderung Marco:
21template < typename SysMatrix, typename SysVector >
22void 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
49INST(template <typename T> class NN friend \
50 void GeneratePlaneRotation(const T &, const double &, double &, T &);)
51
52template<typename T>
53inline 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
79INST(template <typename T> class NN friend \
80 void ApplyPlaneRotation(T &, T &, const double &, const T &);)
81
82template<typename T>
83inline 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
130
131INST3(template <typename T, Matrix<T>, Vector<T> > class NN friend \
132int GMRES (const Matrix<T>&, Vector<T>&, const Vector<T>&,\
133 const Preconditioner_Sig<T, Matrix<T> >&, int&, unsigned int&, double&);)
134INST3(template <typename T, BdMatrix<T>, Vector<T> > class NN friend \
135int GMRES (const BdMatrix<T>&, Vector<T>&, const Vector<T>&,\
136 const Preconditioner_Sig<T, BdMatrix<T> >&, int&, unsigned int&, double&);)
137
138
139template < typename T, typename SysMatrix, typename SysVector >
140int 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;
221 using ::std::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
const Vector< T > const Vector< T > const Vector< T > int T h
Definition LM_fit.h:99
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
doublereal y
Definition TOMS_707.C:27
#define INST3(x, y, z)
Definition basics.h:240
#define NAMESPACE_END
Definition basics.h:323
#define INST(x)
Definition basics.h:238
#define NAMESPACE_TBCI
Definition basics.h:317
#define UNLIKELY(expr)
Definition basics.h:101
#define REGISTER
Definition basics.h:108
#define MATH__
Definition basics.h:339
#define INST2(x, y)
Definition basics.h:239
#define T
Definition bdmatlib.cc:20
SysMatrix
Definition bicgstab.h:90
The class BdMatrix is an implementation to store and do operations on sparse Matrices with a band str...
Abstract base class for all Preconditioners.
Definition precond.h:41
virtual TVector< T > solve(const Vector< T > &) const =0
double fabs(const TBCI__ cplx< T > &c)
Definition cplx.h:746
cplx< T > dot(const cplx< T > &a, const cplx< T > &b)
Definition cplx.h:300
double fabssqr(const cplx< T > &c)
Definition cplx.h:390
NAMESPACE_END NAMESPACE_CPLX TBCI__ cplx< T > conj(const TBCI__ cplx< T > &c)
Definition cplx.h:663
NAMESPACE_END NAMESPACE_CSTD TBCI__ cplx< T > sqrt(const TBCI__ cplx< T > &z)
Definition cplx.h:751
F_TMatrix< T > b
Definition f_matrix.h:736
NAMESPACE_TBCI Vector< T > class NN friend void Update(Vector< T > &, int, BdMatrix< T > &, Vector< T > &, Vector< T > *)
const double & dy
Definition gmres.h:53
const double double & cs
Definition gmres.h:53
double fabs(const int a)
Definition basics.h:1217