BiCgStab.cxx
1 // Copyright (C) 2003-2009 Marc DuruflĂ©
2 // Copyright (C) 2001-2009 Vivien Mallet
3 //
4 // This file is part of the linear-algebra library Seldon,
5 // http://seldon.sourceforge.net/.
6 //
7 // Seldon is free software; you can redistribute it and/or modify it under the
8 // terms of the GNU Lesser General Public License as published by the Free
9 // Software Foundation; either version 2.1 of the License, or (at your option)
10 // any later version.
11 //
12 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15 // more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with Seldon. If not, see http://www.gnu.org/licenses/.
19 
20 
21 #ifndef SELDON_FILE_ITERATIVE_BICGSTAB_CXX
22 
23 namespace Seldon
24 {
25 
27 
43 #ifdef SELDON_WITH_VIRTUAL
44  template<class T, class Vector1>
45  int BiCgStab(const VirtualMatrix<T>& A, Vector1& x, const Vector1& b,
46  Preconditioner_Base<T>& M,
47  Iteration<typename ClassComplexType<T>::Treal>& iter)
48 #else
49  template <class Titer, class Matrix1, class Vector1, class Preconditioner>
50  int BiCgStab(const Matrix1& A, Vector1& x, const Vector1& b,
51  Preconditioner& M, Iteration<Titer> & iter)
52 #endif
53  {
54  const int N = A.GetM();
55  if (N <= 0)
56  return 0;
57 
58  typedef typename Vector1::value_type Complexe;
59  Complexe rho_1, rho_2, alpha, beta, omega, sigma;
60  Vector1 p(b), phat(b), s(b), shat(b), t(b), v(b), r(b), rtilde(b);
61  Complexe zero, one;
62  SetComplexZero(zero);
63  SetComplexOne(one);
64  omega = zero; alpha = zero; rho_2 = zero;
65 
66  // we initialize iter
67  int success_init = iter.Init(b);
68  if (success_init != 0)
69  return iter.ErrorCode();
70 
71  // we compute the residual r = b - Ax
72  Copy(b, r);
73  if (!iter.IsInitGuess_Null())
74  iter.MltAdd(-one, A, x, one, r);
75  else
76  x.Fill(zero);
77 
78  Copy(r, rtilde);
79 
80  iter.SetNumberIteration(0);
81  // Loop until the stopping criteria are satisfied
82  while (! iter.Finished(r))
83  {
84 
85  rho_1 = DotProdConj(rtilde, r);
86  if (rho_1 == zero)
87  {
88  iter.Fail(1, "Bicgstab breakdown #1");
89  break;
90  }
91 
92  if (iter.First())
93  Copy(r, p);
94  else
95  {
96  if (omega == zero)
97  {
98  iter.Fail(2, "Bicgstab breakdown #2");
99  break;
100  }
101  // p= r + beta*(p-omega*v)
102  // beta = rho_i/rho_{i-1} * alpha/omega
103  beta = (rho_1 / rho_2) * (alpha / omega);
104  Add(-omega, v, p);
105  Mlt(beta, p);
106  Add(one, r, p);
107  }
108  // preconditioning phat = M^{-1} p
109  M.Solve(A, p, phat);
110 
111  // product matrix vector v = A*phat
112  iter.Mlt(A, phat, v);
113 
114  // s=r-alpha*v where alpha = rho_i / (v,rtilde)
115  sigma = DotProdConj(rtilde, v);
116  if (sigma == zero)
117  {
118  iter.Fail(3, "Bicgstab breakdown #3");
119  break;
120  }
121  alpha = rho_1 / sigma;
122  Copy(r, s);
123  Add(-alpha, v, s);
124 
125  // we increment iter, bicgstab has two products matrix vector
126  ++iter;
127  if (iter.Finished(s))
128  {
129  // x=x+alpha*phat
130  Add(alpha, phat, x);
131  break;
132  }
133 
134  // preconditioning shat = M^{-1} s
135  M.Solve(A, s, shat);
136 
137  // product matrix vector t = A*shat
138  iter.Mlt(A, shat, t);
139 
140  omega = DotProdConj(t, s) / DotProdConj(t, t);
141 
142  // new iterate x=x+alpha*phat+omega*shat
143  Add(alpha, phat, x);
144  Add(omega, shat, x);
145 
146  // new residual r=s-omega*t
147  Copy(s, r);
148  Add(-omega, t, r);
149 
150  rho_2 = rho_1;
151 
152  ++iter;
153  }
154 
155  return iter.ErrorCode();
156  }
157 
158 } // end namespace
159 
160 #define SELDON_FILE_ITERATIVE_BICGSTAB_CXX
161 #endif
Seldon::Iteration::First
bool First() const
Returns true if it is the first iteration.
Definition: Iterative.cxx:236
Seldon::Iteration::Init
int Init(const Vector1 &r)
Initialization with the right hand side.
Definition: Iterative.cxx:218
Seldon::Iteration::Mlt
void Mlt(const Matrix1 &A, const Vector1 &x, Vector1 &y)
Computes y = A x.
Definition: IterativeInline.cxx:123
Seldon::Iteration::ErrorCode
int ErrorCode()
Returns the error code (if an error occured)
Definition: Iterative.cxx:351
Seldon::Iteration::Fail
void Fail(int i, const string &s)
Informs of a failure in the iterative solver.
Definition: Iterative.cxx:330
Seldon::Iteration::MltAdd
void MltAdd(const T1 &alpha, const Matrix1 &A, const Vector1 &x, const T1 &beta, Vector1 &y)
Computes y = beta y + alpha A x.
Definition: IterativeInline.cxx:109
Seldon::Iteration::SetNumberIteration
void SetNumberIteration(int nb)
Changes the number of iterations.
Definition: Iterative.cxx:177
Seldon
Seldon namespace.
Definition: Array.cxx:24
Seldon::Iteration
Class containing parameters for an iterative resolution.
Definition: Iterative.hxx:59
Seldon::Iteration::IsInitGuess_Null
bool IsInitGuess_Null() const
Returns true if the initial guess is null.
Definition: Iterative.cxx:247
Seldon::Iteration::Finished
bool Finished(const Vector1 &r) const
Returns true if the iterative solver has reached its end.
Definition: Iterative.cxx:264
Seldon::BiCgStab
int BiCgStab(const Matrix1 &A, Vector1 &x, const Vector1 &b, Preconditioner &M, Iteration< Titer > &iter)
Implements BiConjugate Gradient Stabilized (BICG-STAB)
Definition: BiCgStab.cxx:50