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_BICG_CXX 00022 00023 namespace Seldon 00024 { 00025 00027 00046 template <class Titer, class Matrix1, class Vector1, class Preconditioner> 00047 int BiCg(Matrix1& A, Vector1& x, const Vector1& b, 00048 Preconditioner& M, Iteration<Titer> & iter) 00049 { 00050 int N = A.GetM(); 00051 if (N <= 0) 00052 return 0; 00053 00054 typedef typename Vector1::value_type Complexe; 00055 Complexe rho_1, rho_2(0), alpha, beta, delta; 00056 00057 Vector1 r(b), z(b), p(b), q(b); 00058 Vector1 r_tilde(b), z_tilde(b), p_tilde(b), q_tilde(b); 00059 00060 // we initialize iter 00061 int success_init = iter.Init(b); 00062 if (success_init != 0) 00063 return iter.ErrorCode(); 00064 00065 // we compute the residual r = b - Ax 00066 Copy(b, r); 00067 if (!iter.IsInitGuess_Null()) 00068 MltAdd(Complexe(-1), A, x, Complexe(1), r); 00069 else 00070 x.Zero(); 00071 00072 Copy(r, r_tilde); 00073 00074 iter.SetNumberIteration(0); 00075 // Loop until the stopping criteria are reached 00076 while (! iter.Finished(r)) 00077 { 00078 // preconditioning z = M^{-1} r and z_tilde = M^{-t} r_tilde 00079 M.Solve(A, r, z); 00080 M.TransSolve(A, r_tilde, z_tilde); 00081 // rho_1 = (z,r_tilde) 00082 rho_1 = DotProd(z, r_tilde); 00083 00084 if (rho_1 == Complexe(0)) 00085 { 00086 iter.Fail(1, "Bicg breakdown #1"); 00087 break; 00088 } 00089 00090 if (iter.First()) 00091 { 00092 Copy(z, p); 00093 Copy(z_tilde, p_tilde); 00094 } 00095 else 00096 { 00097 // p=beta*p+z where beta = rho_i/rho_{i-1} 00098 // p_tilde=beta*p_tilde+z_tilde 00099 beta = rho_1 / rho_2; 00100 Mlt(beta, p); 00101 Add(Complexe(1), z, p); 00102 Mlt(beta, p_tilde); 00103 Add(Complexe(1), z_tilde, p_tilde); 00104 } 00105 00106 // we do the product matrix vector and transpose matrix vector 00107 // q = A*p q_tilde = A^t p_tilde 00108 Mlt(A, p, q); 00109 ++iter; 00110 Mlt(SeldonTrans, A, p_tilde, q_tilde); 00111 00112 delta = DotProd(p_tilde, q); 00113 if (delta == Complexe(0)) 00114 { 00115 iter.Fail(2, "Bicg breakdown #2"); 00116 break; 00117 } 00118 00119 alpha = rho_1 / delta; 00120 00121 // the new iterate x=x+alpha*p and residual r=r-alpha*q 00122 // where alpha = rho_i/delta 00123 Add(alpha, p, x); 00124 Add(-alpha, q, r); 00125 Add(-alpha, q_tilde, r_tilde); 00126 00127 rho_2 = rho_1; 00128 00129 ++iter; 00130 } 00131 00132 return iter.ErrorCode(); 00133 } 00134 00135 } 00136 00137 #define SELDON_FILE_ITERATIVE_BICG_CXX 00138 #endif