computation/solver/iterative/CoCg.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_COCG_CXX
00021 
00022 namespace Seldon
00023 {
00024 
00026 
00044   template <class Titer, class Matrix1, class Vector1, class Preconditioner>
00045   int CoCg(Matrix1& A, Vector1& x, const Vector1& b,
00046            Preconditioner& M, Iteration<Titer> & iter)
00047   {
00048     const int N = A.GetM();
00049     if (N <= 0)
00050       return 0;
00051 
00052     typedef typename Vector1::value_type Complexe;
00053     Complexe rho, rho_1(0), alpha, beta, delta, zero;
00054     zero = b(0)*Titer(0);
00055     rho = zero+Titer(1);
00056 
00057     Vector1 p(b), q(b), r(b), z(b);
00058     p.Fill(zero); q.Fill(zero); r.Fill(zero); z.Fill(zero);
00059 
00060     // for implementation see Cg
00061     // we initialize iter
00062     int success_init = iter.Init(b);
00063     if (success_init != 0)
00064       return iter.ErrorCode();
00065 
00066     Copy(b,r);
00067     if (!iter.IsInitGuess_Null())
00068       MltAdd(Complexe(-1), A, x, Complexe(1), r);
00069     else
00070       x.Fill(zero);
00071 
00072     iter.SetNumberIteration(0);
00073     // Loop until the stopping criteria are reached
00074     while (! iter.Finished(r))
00075       {
00076         // preconditioning
00077         M.Solve(A, r, z);
00078 
00079         // instead of (bar(r),z) in CG we compute (r,z)
00080         rho = DotProd(r, z);
00081 
00082         if (rho == zero)
00083           {
00084             iter.Fail(1, "Cocg breakdown #1");
00085             break;
00086           }
00087 
00088         if (iter.First())
00089           Copy(z, p);
00090         else
00091           {
00092             beta = rho / rho_1;
00093             Mlt(beta, p);
00094             Add(Complexe(1), z, p);
00095           }
00096         // product matrix vector
00097         Mlt(A, p, q);
00098 
00099         delta = DotProd(p, q);
00100         if (delta == zero)
00101           {
00102             iter.Fail(2, "Cocg breakdown #2");
00103             break;
00104           }
00105         alpha = rho / delta;
00106 
00107         Add(alpha, p, x);
00108         Add(-alpha, q, r);
00109 
00110         rho_1 = rho;
00111 
00112         ++iter;
00113       }
00114 
00115     return iter.ErrorCode();
00116   }
00117 
00118 
00119 } // end namespace
00120 
00121 #define ITERATIVE_COCG_CXX
00122 #endif