computation/solver/iterative/BiCgcr.cxx

00001 // Copyright (C) 2003-2009 Marc Duruflé
00002 // Copyright (C) 2001-2009 Vivien Mallet
00003 //
00004 // This file is part of the linear-algebra library Seldon,
00005 // http://seldon.sourceforge.net/.
00006 //
00007 // Seldon is free software; you can redistribute it and/or modify it under the
00008 // terms of the GNU Lesser General Public License as published by the Free
00009 // Software Foundation; either version 2.1 of the License, or (at your option)
00010 // any later version.
00011 //
00012 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
00013 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
00015 // more details.
00016 //
00017 // You should have received a copy of the GNU Lesser General Public License
00018 // along with Seldon. If not, see http://www.gnu.org/licenses/.
00019 
00020 
00021 #ifndef SELDON_FILE_ITERATIVE_BICGCR_CXX
00022 
00023 namespace Seldon
00024 {
00025 
00027 
00044   template <class Titer, class Matrix1, class Vector1, class Preconditioner>
00045   int BiCgcr(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, mu, alpha, beta, tau;
00054     Vector1 v(b), w(b), s(b), z(b), p(b), a(b);
00055     v.Zero(); w.Zero(); s.Zero(); z.Zero();  p.Zero(); a.Zero();
00056 
00057     // we initialize iter
00058     int success_init = iter.Init(b);
00059     if (success_init != 0)
00060       return iter.ErrorCode();
00061 
00062     // we compute the residual v = b - Ax
00063     Copy(b, v);
00064     if (!iter.IsInitGuess_Null())
00065       MltAdd(Complexe(-1), A, x, Complexe(1), v);
00066     else
00067       x.Zero();
00068 
00069     iter.SetNumberIteration(0);
00070     // s = M*v   p = s
00071     M.Solve(A, v, s); Copy(s, p);
00072     // a = A*p   w = M*a
00073     Mlt(A, p, a); M.Solve(A, a, w);
00074     // we made one product matrix vector
00075     ++iter;
00076 
00077     while (! iter.Finished(v))
00078       {
00079         rho = DotProd(w, v);
00080         mu = DotProd(w, a);
00081 
00082         // new iterate x = x + alpha*p0  where alpha = (r1,r0)/(p1,p1)
00083         if (mu == Complexe(0))
00084           {
00085             iter.Fail(1, "Bicgcr breakdown #1");
00086             break;
00087           }
00088         alpha = rho/mu;
00089         Add(alpha, p, x);
00090 
00091         // new residual r0 = r0 - alpha * p1
00092         // r1 = r1 - alpha*p2
00093         Add(-alpha, a, v);
00094         Add(-alpha, w, s);
00095 
00096         Mlt(A, s, z);
00097         tau = DotProd(w, z);
00098 
00099         if (tau == Complexe(0))
00100           {
00101             iter.Fail(2, "Bicgcr breakdown #2");
00102             break;
00103           }
00104 
00105         beta = tau/mu;
00106 
00107         Mlt(Complexe(-beta), p);
00108         Add(Complexe(1), s, p);
00109         Mlt(Complexe(-beta), a);
00110         Add(Complexe(1), z, a);
00111 
00112         M.Solve(A, a, w);
00113 
00114         ++iter;
00115       }
00116 
00117     return iter.ErrorCode();
00118   }
00119 
00120 } // end namespace
00121 
00122 #define SELDON_FILE_ITERATIVE_BICGCR_CXX
00123 #endif