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_BICGSTAB_CXX 00022 00023 namespace Seldon 00024 { 00025 00027 00043 template <class Titer, class Matrix1, class Vector1, class Preconditioner> 00044 int BiCgStab(Matrix1& A, Vector1& x, const Vector1& b, 00045 Preconditioner& M, Iteration<Titer> & iter) 00046 { 00047 const int N = A.GetM(); 00048 if (N <= 0) 00049 return 0; 00050 00051 typedef typename Vector1::value_type Complexe; 00052 Complexe rho_1, rho_2(0), alpha(0), beta, omega(0), sigma; 00053 Vector1 p(b), phat(b), s(b), shat(b), t(b), v(b), r(b), rtilde(b); 00054 00055 // we initialize iter 00056 int success_init = iter.Init(b); 00057 if (success_init != 0) 00058 return iter.ErrorCode(); 00059 00060 // we compute the residual r = b - Ax 00061 Copy(b, r); 00062 if (!iter.IsInitGuess_Null()) 00063 MltAdd(Complexe(-1), A, x, Complexe(1), r); 00064 else 00065 x.Zero(); 00066 00067 Copy(r, rtilde); 00068 00069 iter.SetNumberIteration(0); 00070 // Loop until the stopping criteria are satisfied 00071 while (! iter.Finished(r)) 00072 { 00073 00074 rho_1 = DotProdConj(rtilde, r); 00075 if (rho_1 == Complexe(0)) 00076 { 00077 iter.Fail(1, "Bicgstab breakdown #1"); 00078 break; 00079 } 00080 00081 if (iter.First()) 00082 Copy(r, p); 00083 else 00084 { 00085 if (omega == Complexe(0)) 00086 { 00087 iter.Fail(2, "Bicgstab breakdown #2"); 00088 break; 00089 } 00090 // p= r + beta*(p-omega*v) 00091 // beta = rho_i/rho_{i-1} * alpha/omega 00092 beta = (rho_1 / rho_2) * (alpha / omega); 00093 Add(-omega, v, p); 00094 Mlt(beta, p); 00095 Add(Complexe(1), r, p); 00096 } 00097 // preconditioning phat = M^{-1} p 00098 M.Solve(A, p, phat); 00099 00100 // product matrix vector v = A*phat 00101 Mlt(A, phat, v); 00102 00103 // s=r-alpha*v where alpha = rho_i / (v,rtilde) 00104 sigma = DotProdConj(rtilde, v); 00105 if (sigma == Complexe(0)) 00106 { 00107 iter.Fail(3, "Bicgstab breakdown #3"); 00108 break; 00109 } 00110 alpha = rho_1 / sigma; 00111 Copy(r, s); 00112 Add(-alpha, v, s); 00113 00114 // we increment iter, bicgstab has two products matrix vector 00115 ++iter; 00116 if (iter.Finished(s)) 00117 { 00118 // x=x+alpha*phat 00119 Add(alpha, phat, x); 00120 break; 00121 } 00122 00123 // preconditioning shat = M^{-1} s 00124 M.Solve(A, s, shat); 00125 00126 // product matrix vector t = A*shat 00127 Mlt(A, shat, t); 00128 00129 omega = DotProdConj(t, s) / DotProdConj(t, t); 00130 00131 // new iterate x=x+alpha*phat+omega*shat 00132 Add(alpha, phat, x); 00133 Add(omega, shat, x); 00134 00135 // new residual r=s-omega*t 00136 Copy(s, r); 00137 Add(-omega, t, r); 00138 00139 rho_2 = rho_1; 00140 00141 ++iter; 00142 } 00143 00144 return iter.ErrorCode(); 00145 } 00146 00147 } // end namespace 00148 00149 #define SELDON_FILE_ITERATIVE_BICGSTAB_CXX 00150 #endif