computation/solver/iterative/Iterative.cxx

00001 // Copyright (C) 2003-2009 Marc Duruflé
00002 //
00003 // This file is part of the linear-algebra library Seldon,
00004 // http://seldon.sourceforge.net/.
00005 //
00006 // Seldon is free software; you can redistribute it and/or modify it under the
00007 // terms of the GNU Lesser General Public License as published by the Free
00008 // Software Foundation; either version 2.1 of the License, or (at your option)
00009 // any later version.
00010 //
00011 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
00012 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00013 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
00014 // more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public License
00017 // along with Seldon. If not, see http://www.gnu.org/licenses/.
00018 
00019 
00020 #ifndef SELDON_FILE_ITERATIVE_CXX
00021 
00022 #include <vector>
00023 
00024 // headers of class Iteration and Preconditioner_Base
00025 #include "Iterative.hxx"
00026 
00027 // and all iterative solvers
00028 #include "Cg.cxx"
00029 #include "Cgne.cxx"
00030 #include "Lsqr.cxx"
00031 #include "Cgs.cxx"
00032 #include "BiCg.cxx"
00033 #include "BiCgStab.cxx"
00034 #include "BiCgStabl.cxx"
00035 #include "BiCgcr.cxx"
00036 #include "Gcr.cxx"
00037 #include "CoCg.cxx"
00038 #include "Gmres.cxx"
00039 #include "MinRes.cxx"
00040 #include "Qmr.cxx"
00041 #include "QmrSym.cxx"
00042 #include "QCgs.cxx"
00043 #include "TfQmr.cxx"
00044 #include "Symmlq.cxx"
00045 
00046 
00047 namespace Seldon
00048 {
00049 
00051   Preconditioner_Base::Preconditioner_Base()
00052   {
00053   }
00054 
00055 
00057 
00060   template<class Matrix1, class Vector1>
00061   void Preconditioner_Base::Solve(const Matrix1& A, const Vector1& r,
00062                                   Vector1& z)
00063   {
00064     Copy(r,z);
00065   }
00066 
00067 
00069 
00072   template<class Matrix1, class Vector1>
00073   void Preconditioner_Base::
00074   TransSolve(const Matrix1& A, const Vector1 & r, Vector1 & z)
00075   {
00076     Solve(A, r, z);
00077   }
00078 
00079 
00081   template<class Titer>
00082   Iteration<Titer>::Iteration()
00083   {
00084     tolerance = 1e-6;
00085     max_iter = 100;
00086     nb_iter = 0;
00087     error_code = 0;
00088     fail_convergence = false;
00089     print_level = 1;
00090     init_guess_null = true;
00091     type_solver = 0; parameter_restart = 10;
00092     type_preconditioning = 0;
00093   }
00094 
00095 
00097   template<class Titer>
00098   Iteration<Titer>::Iteration(int max_iteration, const Titer& tol)
00099   {
00100     max_iter = max_iteration;
00101     tolerance = tol;
00102     nb_iter = 0;
00103     error_code = 0;
00104     fail_convergence = false;
00105     print_level = 1;
00106     init_guess_null = true;
00107     type_solver = 0; parameter_restart = 10;
00108     type_preconditioning = 0;
00109   }
00110 
00111 
00113   template<class Titer>
00114   Iteration<Titer>::Iteration(const Iteration<Titer>& outer)
00115   {
00116     tolerance = outer.tolerance; facteur_reste = outer.facteur_reste;
00117     max_iter = outer.max_iter;
00118     nb_iter = 0;
00119     print_level = outer.print_level; error_code = outer.error_code;
00120     init_guess_null = true;
00121     type_solver = outer.type_solver;
00122     parameter_restart = outer.parameter_restart;
00123     type_preconditioning = outer.type_preconditioning;
00124   }
00125 
00126 
00128   template<class Titer>
00129   int Iteration<Titer>::GetTypeSolver() const
00130   {
00131     return type_solver;
00132   }
00133 
00134 
00136   template<class Titer>
00137   int Iteration<Titer>::GetRestart() const
00138   {
00139     return parameter_restart;
00140   }
00141 
00142 
00144   template<class Titer>
00145   Titer Iteration<Titer>::GetFactor() const
00146   {
00147     return facteur_reste;
00148   }
00149 
00150 
00152   template<class Titer>
00153   Titer Iteration<Titer>::GetTolerance() const
00154   {
00155     return tolerance;
00156   }
00157 
00158 
00160   template<class Titer>
00161   int Iteration<Titer>::GetNumberIteration() const
00162   {
00163     return nb_iter;
00164   }
00165 
00166 
00168   template<class Titer>
00169   void Iteration<Titer>::SetSolver(int type_resolution,
00170                                    int param_restart, int type_prec)
00171   {
00172     type_solver = type_resolution;
00173     parameter_restart = param_restart;
00174     type_preconditioning = type_prec;
00175   }
00176 
00177 
00179   template<class Titer>
00180   void Iteration<Titer>::SetRestart(int m)
00181   {
00182     parameter_restart = m;
00183   }
00184 
00185 
00187   template<class Titer>
00188   void Iteration<Titer>::SetTolerance(Titer stopping_criterion)
00189   {
00190     tolerance = stopping_criterion;
00191   }
00192 
00193 
00195   template<class Titer>
00196   void Iteration<Titer>::SetMaxNumberIteration(int max_iteration)
00197   {
00198     max_iter=max_iteration;
00199   }
00200 
00201 
00203   template<class Titer>
00204   void Iteration<Titer>::SetNumberIteration(int nb)
00205   {
00206     nb_iter = nb;
00207   }
00208 
00209 
00211   template<class Titer>
00212   void Iteration<Titer>::ShowMessages()
00213   {
00214     print_level = 1;
00215   }
00216 
00217 
00219   template<class Titer>
00220   void Iteration<Titer>::ShowFullHistory()
00221   {
00222     print_level = 6;
00223   }
00224 
00225 
00227   template<class Titer>
00228   void Iteration<Titer>::HideMessages()
00229   {
00230     print_level = 0;
00231   }
00232 
00233 
00235   template<class Titer> template<class Vector1>
00236   int Iteration<Titer>::Init(const Vector1& r)
00237   {
00238     Titer norme_rhs = Titer(Norm2(r));
00239     // test of a null right hand side
00240     if (norme_rhs == Titer(0))
00241       return -1;
00242 
00243     // coefficient used later to compute relative residual
00244     facteur_reste = Titer(1)/norme_rhs;
00245 
00246     // initialization of iterations
00247     nb_iter = 0;
00248     return 0; // successful initialization
00249   }
00250 
00251 
00253   template<class Titer>
00254   inline bool Iteration<Titer>::First() const
00255   {
00256     if (nb_iter == 0)
00257       return true;
00258 
00259     return false;
00260   }
00261 
00262 
00264   template<class Titer>
00265   inline bool Iteration<Titer>::IsInitGuess_Null() const
00266   {
00267     return init_guess_null;
00268   }
00269 
00270 
00272   template<class Titer> template<class Vector1>
00273   inline bool Iteration<Titer>::
00274   Finished(const Vector1& r) const
00275   {
00276     // absolute residual
00277     Titer reste = Norm2(r);
00278     // computation of relative residual
00279     reste = facteur_reste*reste;
00280 
00281     // displaying residual if required
00282     if ((print_level >= 1)&&(nb_iter%100 == 0))
00283       cout<<"Residu at iteration number "<<
00284         GetNumberIteration()<<"  "<<reste<<endl;
00285     else if (print_level >= 6)
00286       cout<<"Residu at iteration number "<<
00287         GetNumberIteration()<<"  "<<reste<<endl;
00288 
00289     // end of iterative solver when residual is small enough
00290     // or when the number of iterations is too high
00291     if ((reste < tolerance)||(nb_iter >= max_iter))
00292       return true;
00293 
00294     return false;
00295   }
00296 
00297 
00299   template<class Titer>
00300   inline bool Iteration<Titer>::Finished(const Titer& r) const
00301   {
00302     // relative residual
00303     Titer reste = facteur_reste*r;
00304 
00305     // displaying residual if required
00306     if ((print_level >= 1)&&(nb_iter%100 == 0))
00307       cout<<"Residu at iteration number "<<
00308         GetNumberIteration()<<"  "<<reste<<endl;
00309     else if (print_level >= 6)
00310       cout<<"Residu at iteration number "<<
00311         GetNumberIteration()<<"  "<<reste<<endl;
00312 
00313     // end of iterative solver when residual is small enough
00314     // or when the number of iterations is too high
00315     if ((reste < tolerance)||(nb_iter >= max_iter))
00316       return true;
00317 
00318     return false;
00319   }
00320 
00321 
00323   template<class Titer>
00324   void Iteration<Titer>::Fail(int i, const string& s)
00325   {
00326     fail_convergence = true;
00327     error_code = i;
00328     // displays information if required
00329     if ((print_level >= 1)&&(nb_iter%100==0))
00330       cout<<"Error during resolution : "<<s<<endl;
00331   }
00332 
00333 
00335   template<class Titer>
00336   inline Iteration<Titer>& Iteration<Titer>::operator ++ (void)
00337   {
00338     ++nb_iter;
00339     return *this;
00340   }
00341 
00342 
00344   template<class Titer>
00345   int Iteration<Titer>::ErrorCode() const
00346   {
00347     if (nb_iter >= max_iter)
00348       return -2;
00349 
00350     if (fail_convergence)
00351       return error_code;
00352 
00353     return 0;
00354   }
00355 
00356 } // end namespace
00357 
00358 #define SELDON_FILE_ITERATIVE_CXX
00359 #endif
00360