Warning: this documentation for the development version is under construction.
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