Warning: this documentation for the development version is under construction.
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_GCR_CXX 00022 00023 namespace Seldon 00024 { 00025 00027 00045 template <class Titer, class Matrix1, class Vector1, class Preconditioner> 00046 int Gcr(Matrix1& A, Vector1& x, const Vector1& b, 00047 Preconditioner& M, Iteration<Titer> & outer) 00048 { 00049 const int N = A.GetM(); 00050 if (N <= 0) 00051 return 0; 00052 00053 typedef typename Vector1::value_type Complexe; 00054 int m = outer.GetRestart(); 00055 // we initialize outer 00056 int success_init = outer.Init(b); 00057 if (success_init != 0) 00058 return outer.ErrorCode(); 00059 00060 std::vector<Vector1> p(m+1, b), w(m+1, b); 00061 00062 Vector<Complexe> beta(m+1); 00063 00064 Vector1 r(b), q(b), u(b); 00065 00066 for (int i = 0; i < (m+1); i++) 00067 { 00068 p[i].Zero(); 00069 w[i].Zero(); 00070 } 00071 00072 // we compute initial residual 00073 Copy(b,u); 00074 if (!outer.IsInitGuess_Null()) 00075 MltAdd(Complexe(-1), A, x, Complexe(1), u); 00076 else 00077 x.Zero(); 00078 00079 M.Solve(A, u, r); 00080 00081 Complexe alpha,delta; 00082 00083 Titer normr = Norm2(r); 00084 outer.SetNumberIteration(0); 00085 // Loop until the stopping criteria are satisfied 00086 while (! outer.Finished(r)) 00087 { 00088 // m is the maximum number of inner iterations 00089 Iteration<Titer> inner(outer); 00090 inner.SetNumberIteration(outer.GetNumberIteration()); 00091 inner.SetMaxNumberIteration(outer.GetNumberIteration()+m); 00092 Copy(r, p[0]); 00093 Mlt(Titer(1)/normr, p[0]); 00094 00095 int j = 0; 00096 00097 while (! inner.Finished(r) ) 00098 { 00099 // product matrix vector u=A*p(j) 00100 Mlt(A, p[j], u); 00101 00102 // preconditioning 00103 M.Solve(A, u, w[j]); 00104 00105 beta(j) = DotProdConj(w[j], w[j]); 00106 if (beta(j) == Complexe(0)) 00107 { 00108 outer.Fail(1, "Gcr breakdown #1"); 00109 break; 00110 } 00111 00112 // new iterate x = x + alpha*p(j) new residual r = r - alpha*w(j) 00113 // where alpha = (conj(r_j),A*p_j)/(A*p_j,A*p_j) 00114 alpha = DotProdConj(w[j], r) / beta(j); 00115 Add(alpha, p[j], x); 00116 Add(-alpha, w[j], r); 00117 00118 ++inner; 00119 ++outer; 00120 // product Matrix vector u = A*r 00121 Mlt(A, r, u); 00122 M.Solve(A, u, q); 00123 00124 Copy(r, p[j+1]); 00125 // we compute direction p(j+1) = r(j+1) + 00126 // \sum_{i=0..j} ( -(A*r_j+1,A*p_i)/(A*p_i,A*p_i) p(i)) 00127 for (int i = 0; i <= j; i++) 00128 { 00129 delta = -DotProdConj(w[i], q)/beta(i); 00130 Add(delta, p[i], p[j+1]); 00131 } 00132 00133 ++inner; 00134 ++outer; 00135 ++j; 00136 } 00137 normr = Norm2(r); 00138 } 00139 00140 return outer.ErrorCode(); 00141 } 00142 00143 } // end namespace 00144 00145 #define SELDON_FILE_ITERATIVE_GCR_CXX 00146 #endif