TBCI Numerical high perf. C++ Library 2.8.0
bicgstab.h
Go to the documentation of this file.
1
4/* $Id: bicgstab.h,v 1.16.2.21 2019/05/28 11:13:02 garloff Exp $ */
5
6#ifndef TBCI_SOLVER_BICGSTAB_H
7#define TBCI_SOLVER_BICGSTAB_H
8
9#include "tbci/vector.h"
10#include "tbci/solver/precond.h"
11
12#ifdef SOLVER_LOG
13# include <fstream>
14# include <iomanip>
15#endif
16
17#ifndef NO_BICGSTAB_RESTART
18# define BICGSTAB_RESTART
19#endif
20
21/* There was some rather obscure magic to improve convergence, which is
22 * removed now. (KG, 99/06/15)
23 * Unlike the CGS solver, which does weird changes to the vector before
24 * finding a point from which to converge rapidly, the BiCGstab is unlikely
25 * to ever deteriorate the Vector. Drawback is that the approach rate is
26 * getting lower and lower, when the number of iterations increase.
27 * Now the magic comes to play. Whenever we are in such a situation, i.e.
28 * the result isn't improving any longer, we try to detect this ,,stall``
29 * and recalculate some values resulting in a kick to the solver. This
30 * often results in better results.
31 * KG, 99/05/26: I've been talking to experts. The loss in the convergence
32 * rate is likely to be caused by the loss of the orthogonality of the two
33 * base vectors. This should be detectable and solvable.
34 * The magic mentioned above should be removed and replaced by some proper
35 * mechanism.
36 */
37
39
40/* NOTE: Template parameter T and T_tol should really be double (or
41 * similar: float, long double are OK), as fabs() is used, which
42 * returns double. This could be changed to abs(), but will then
43 * cause some trouble for complex numbers.
44 */
45
46INST3(template <typename T, Matrix<T>, double> class NN friend \
47int BiCGSTAB (const Matrix<T> &, Vector<T> &, const Vector<T> &, \
48 const Preconditioner_Sig<T, Matrix<T> > &, unsigned int&, double&, const unsigned);)
49INST3(template <typename T, BdMatrix<T>, double> class NN friend \
50int BiCGSTAB (const BdMatrix<T> &, Vector<T> &, const Vector<T> &, \
51 const Preconditioner_Sig<T, BdMatrix<T> > &, unsigned int&, double&, const unsigned);)
52INST3(template <typename T, Symm_BdMatrix<T>, double> class NN friend \
53int BiCGSTAB (const Symm_BdMatrix<T> &, Vector<T> &, const Vector<T> &, \
54 const Preconditioner_Sig<T, Symm_BdMatrix<T> > &, unsigned int&, double&, const unsigned);)
55
56
89
90template < typename T, typename SysMatrix, typename T_tol /*= double*/>
91int BiCGSTAB (const SysMatrix &A, Vector<T> &x, const Vector<T> &b,
92 const Preconditioner_Sig<T, SysMatrix> &M, unsigned int& max_iter,
93 T_tol& tol, const unsigned off = 0)
94{
95 const unsigned int dim = A.rows();
96 typename SysMatrix::value_type rho_1, rho_2((typename SysMatrix::value_type)1),
97 alpha((typename SysMatrix::value_type)0), beta,
98 omega((typename SysMatrix::value_type)0);
99 //T rho_1, rho_2, alpha, beta, omega;
100 Vector<T> p(dim), phat(dim), s(dim), shat(dim), t(dim), v(dim);
101
102 const T_tol tolsqr = TBCI__ sqr(tol);
103 T_tol normbsqr = b.fabssqr();
104 T_tol residsqr;
105
106 if (normbsqr <= (T_tol)1e-32)
107 normbsqr = T_tol(1e32);
108 else
109 normbsqr = T_tol(1) / normbsqr;
110
111 Vector<T> r (b - A * x);
112 Vector<T> rtilde (r);
113 //M.update (A);
114
115 if (LIKELY((residsqr = r.fabssqr() * normbsqr) <= tolsqr)) {
116 tol = MATH__ sqrt(residsqr);
117 max_iter = 0;
118 return 0;
119 }
120 alpha = beta = omega = rho_1 = (typename SysMatrix::value_type)0;
121#ifdef SOLVER_LOG
122 STD__ ofstream cnvg;
123 if (off) cnvg.open ("bicgstab_cnvg.gnu", STD__ ios::app);
124 else cnvg.open ("bicgstab_cnvg.gnu");
125 cnvg << "# Iter res alpha beta omega rho_1 rho_2 rho_1 / sqr(normb)" << STD__ endl;
126#endif
127
128 for (unsigned int i = 1; i <= max_iter; ++i) {
129#ifdef SOLVER_LOG
130 cnvg << i+off << "\t" << MATH__ sqrt(residsqr) << "\t" << MATH__ fabs(alpha) << "\t" << MATH__ fabs(beta) << "\t"
131 << MATH__ fabs (omega) << "\t" << MATH__ fabs(rho_1) << "\t" << MATH__ fabs(rho_2) << "\t" << MATH__ fabs(rho_1)*normbsqr << "\n";
132#endif
133 rho_1 = dot (rtilde, r);
134 if (UNLIKELY(rho_1 == (typename SysMatrix::value_type)0)) {
135#ifdef BICGSTAB_RESTART
136# ifdef BICGSTAB_REPORT_RESTART
137 STD__ cerr << "BiCGstab failure 2 (iter " << i
138 << ") rho1 == " << rho_1 << ". Restart.\n";
139# endif
140 // RESTART
141 rtilde = b - A*x; r = rtilde;
142 alpha = 0;
143 continue;
144#else
145
146 tol = MATH__ sqrt (residsqr);
147 return 2;
148#endif
149 }
150 if (UNLIKELY(i == 1))
151 p = r;
152 else {
153 beta = (rho_1 * alpha) / (rho_2 * omega);
154 p = r + beta * (p - omega * v);
155 }
156 phat = M.solve(p);
157 v = A * phat;
158 alpha = rho_1 / dot (rtilde, v);
159 s = r - alpha * v;
160 if ((residsqr = s.fabssqr() * normbsqr) < tolsqr) {
161 x += alpha * phat;
162 max_iter = i; tol = MATH__ sqrt(residsqr);
163 return 0;
164 }
165 shat = M.solve(s);
166 t = A * shat;
167 omega = dot(t,s) / fabssqr(t); //dot(t,t);
168
169 x += alpha * phat + omega * shat;
170 r = s - omega * t;
171
172 rho_2 = rho_1;
173
174 if ((residsqr = r.fabssqr() * normbsqr) < tolsqr) {
175 tol = MATH__ sqrt(residsqr); max_iter = i;
176#ifdef SOLVER_LOG
177 cnvg << i+off << "\t" << MATH__ sqrt(residsqr) << "\t" << MATH__ fabs(alpha) << "\t" << MATH__ fabs(beta) << "\t"
178 << MATH__ fabs (omega) << "\t" << MATH__ fabs(rho_1) << "\t" << MATH__ fabs(rho_2) << "\t" << MATH__ fabs(rho_1)*normbsqr << STD__ endl;
179#endif
180 return 0;
181 }
182 if (UNLIKELY(omega == (typename SysMatrix::value_type)0)) {
183 tol = MATH__ sqrt(residsqr);
184 STD__ cerr << "BiCGstab failure 3: omega == 0\n";
185 max_iter = i;
186 return 3;
187 }
188 }
189
190 tol = MATH__ sqrt (residsqr);
191 return 1;
192}
193
195
196#endif /* TBCI_SOLVER_BICGSTAB_H */
const Vector< T > const Vector< T > const Vector< T > & p
Definition LM_fit.h:98
const Vector< T > const Vector< T > & x
Definition LM_fit.h:97
int i
Definition LM_fit.h:71
#define STD__
Definition basics.h:338
#define LIKELY(expr)
branch prediction note that we sometimes on purpose mark the unlikely possibility likely and vice ver...
Definition basics.h:100
#define INST3(x, y, z)
Definition basics.h:240
#define NAMESPACE_END
Definition basics.h:323
#define NAMESPACE_TBCI
Definition basics.h:317
#define TBCI__
Definition basics.h:332
#define UNLIKELY(expr)
Definition basics.h:101
#define MATH__
Definition basics.h:339
#define T
Definition bdmatlib.cc:20
SysMatrix
Definition bicgstab.h:90
NAMESPACE_TBCI double class NN friend int BiCGSTAB(const BdMatrix< T > &, Vector< T > &, const Vector< T > &, const Preconditioner_Sig< T, BdMatrix< T > > &, unsigned int &, double &, const unsigned)
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
Matrix class with optimized Matrix-Vector multiplication for symmetrical Matrices.
double fabssqr() const HOT
Definition vector.h:2399
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
cplx< T > sqr(const cplx< T > &c)
Definition cplx.h:449
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