TfQmr.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_TFQMR_CXX
22 
23 namespace Seldon
24 {
25 
27 
44 #ifdef SELDON_WITH_VIRTUAL
45  template<class T, class Vector1>
46  int TfQmr(const VirtualMatrix<T>& A, Vector1& x, const Vector1& b,
47  Preconditioner_Base<T>& M,
48  Iteration<typename ClassComplexType<T>::Treal>& iter)
49 #else
50  template <class Titer, class Matrix1, class Vector1, class Preconditioner>
51  int TfQmr(const Matrix1& A, Vector1& x, const Vector1& b,
52  Preconditioner& M, Iteration<Titer> & iter)
53 #endif
54  {
55  const int N = A.GetM();
56  if (N <= 0)
57  return 0;
58 
59  Vector1 tmp(b), r0(b), v(b), h(b), w(b),
60  y1(b), g(b), y0(b), rtilde(b), d(b);
61 
62  typedef typename Vector1::value_type Complexe;
63  Complexe sigma, alpha, beta, eta, rho, rho0;
64  typedef typename ClassComplexType<Complexe>::Treal Treal;
65  Treal c, kappa, tau, theta;
66  Complexe zero, one;
67  SetComplexZero(zero);
68  SetComplexOne(one);
69 
70  tmp.Fill(zero);
71  // x is initial value
72  // 1. r0 = M^{-1} (b - A x)
73  Copy(b, tmp);
74  if (!iter.IsInitGuess_Null())
75  iter.MltAdd(-one, A, x, one, tmp);
76  else
77  x.Fill(zero);
78 
79  M.Solve(A, tmp, r0);
80 
81  // we initialize iter
82  int success_init = iter.Init(r0);
83  if (success_init != 0)
84  return iter.ErrorCode();
85 
86  // 2. w=y=r
87  Copy(r0, w);
88  Copy(r0, y1);
89 
90  // 3. g=v=M^{-1}Ay
91  Copy(y1, v);
92  iter.Mlt(A, v, tmp);
93  M.Solve(A, tmp, v);
94  ++iter;
95 
96  Copy(v, g);
97 
98  // 4. d=0
99  d.Fill(zero);
100 
101  // 5. tau = ||r||
102  tau = Norm2(r0);
103 
104  // 6. theta = eta = 0
105  theta = Treal(0);
106  eta = zero;
107 
108  // 7. rtilde = r
109  Copy(r0, rtilde);
110 
111  // 8. rho=dot(rtilde, r)
112  rho = DotProd(rtilde, r0);
113  rho0 = rho;
114 
115  iter.SetNumberIteration(0);
116  // Loop until the stopping criteria are reached
117  for (;;)
118  {
119  // 9. 10. 11.
120  // sigma=dot(rtilde,v)
121  // alpha=rho/sigma
122  // y2k=y(2k-1)-alpha*v
123  sigma = DotProd(rtilde, v);
124 
125  if (sigma == zero)
126  {
127  iter.Fail(1, "Tfqmr breakdown: sigma=0");
128  break;
129  }
130  alpha = rho / sigma;
131 
132  //y0 = y1 - alpha * v;
133  Copy(y1, y0);
134  Add(-alpha, v, y0);
135 
136  // 12. h=M^{-1}*A*y
137  Copy(y0, h);
138  iter.Mlt(A, h, tmp);
139  M.Solve(A, tmp, h);
140  //split the loop of "for m = 2k-1, 2k"
141 
142  //The first one
143  // 13. w = w-alpha*M^{-1} A y0
144  //w = w - alpha * g;
145  Add(-alpha, g, w);
146  // 18. d=y0+((theta0^2)*eta0/alpha)*d //need check breakdown
147  if (alpha == zero)
148  {
149  iter.Fail(2, "Tfqmr breakdown: alpha=0");
150  break;
151  }
152  //d = y1 + ( theta * theta * eta / alpha ) * d;
153  Mlt(theta * theta * eta / alpha, d);
154  Add(one, y1, d);
155 
156  // 14. theta=||w||_2/tau0 //need check breakdown
157  if (tau == Treal(0))
158  {
159  iter.Fail(3, "Tfqmr breakdown: tau=0");
160  break;
161  }
162  theta = Norm2(w) / tau;
163 
164  // 15. c = 1/sqrt(1+theta^2)
165  c = Treal(1) / sqrt(Treal(1) + theta * theta);
166 
167  // 16. tau = tau0*theta*c
168  tau = tau * c * theta;
169 
170  // 17. eta = (c^2)*alpha
171  eta = c * c * alpha;
172 
173  // 19. x = x+eta*d
174  Add(eta, d, x);
175  // 20. kappa = tau*sqrt(m+1)
176  kappa = tau * sqrt( Treal(2)* (iter.GetNumberIteration()+1) );
177 
178  // 21. check stopping criterion
179  if ( iter.Finished(kappa) )
180  {
181  break;
182  }
183  ++iter;
184  // g = h;
185  Copy(h, g);
186  //The second one
187 
188  // 13. w = w-alpha*M^{-1} A y0
189  // w = w - alpha * g;
190  Add(-alpha, g, w);
191  // 18. d = y0+((theta0^2)*eta0/alpha)*d
192  Mlt(theta * theta * eta / alpha,d);
193  Add(one, y0, d);
194  // 14. theta=||w||_2/tau0
195  if (tau == Treal(0))
196  {
197  iter.Fail(4, "Tfqmr breakdown: tau=0");
198  break;
199  }
200  theta = Norm2(w) / tau;
201 
202  // 15. c = 1/sqrt(1+theta^2)
203  c = Treal(1) / sqrt(Treal(1) + theta * theta);
204 
205  // 16. tau = tau0*theta*c
206  tau = tau * c * theta;
207 
208  // 17. eta = (c^2)*alpha
209  eta = c * c * alpha;
210 
211  // 19. x = x+eta*d
212  Add(eta, d, x);
213 
214  // 20. kappa = tau*sqrt(m+1)
215  kappa = tau * sqrt(Treal(2)* (iter.GetNumberIteration()+1) + Treal(1));
216 
217  // 21. check stopping criterion
218  if ( iter.Finished(kappa) )
219  {
220  break;
221  }
222 
223  // 22. rho = dot(rtilde,w)
224  // 23. beta = rho/rho0 //need check breakdown
225 
226  rho0 = rho;
227  rho = DotProd(rtilde, w);
228  if (rho0 == zero)
229  {
230  iter.Fail(5, "tfqmr breakdown: beta=0");
231  break;
232  }
233  beta = rho/rho0;
234 
235  // 24. y = w+beta*y0
236  Copy(w, y1);
237  Add(beta, y0, y1);
238 
239  // 25. g=M^{-1} A y
240  Copy(y1, g);
241  iter.Mlt(A, g, tmp);
242  M.Solve(A, tmp, g);
243 
244  // 26. v = M^{-1}A y + beta*( M^{-1} A y0 + beta*v)
245 
246  Mlt(beta*beta, v);
247  Add(beta, h, v);
248  Add(one, g, v);
249 
250  ++iter;
251  }
252 
253  return iter.ErrorCode();
254  }
255 
256 } // end namespace
257 
258 #define SELDON_FILE_ITERATIVE_TFQMR_CXX
259 #endif
Seldon::Iteration::GetNumberIteration
int GetNumberIteration() const
Returns the number of iterations.
Definition: Iterative.cxx:134
Seldon::TfQmr
int TfQmr(const Matrix1 &A, Vector1 &x, const Vector1 &b, Preconditioner &M, Iteration< Titer > &iter)
Solves a linear system by using Transpose Free Quasi-Minimal Residual.
Definition: TfQmr.cxx:51
Seldon::Norm2
ClassComplexType< T >::Treal Norm2(const VectorExpression< T, E > &X)
returns 2-norm of an expression with vectors
Definition: Functions_BaseInline.cxx:153
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