00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef SELDON_FILE_ITERATIVE_BICGSTABL_CXX
00022
00023 namespace Seldon
00024 {
00025
00027
00043 template <class Titer, class Matrix1, class Vector1, class Preconditioner>
00044 int BiCgStabl(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 int m = iter.GetRestart();
00053 int l = m;
00054 Complexe rho_0, rho_1, alpha, beta, omega, sigma, zero, unity;
00055 zero = 0.0; unity = 1.0;
00056
00057
00058 Vector1 q(b), r0(b);
00059 Vector<Complexe> gamma(l+1), gamma_prime(l+1), gamma_twice(l+1);
00060 Matrix<Complexe, General, RowMajor> tau(l+1,l+1);
00061
00062 std::vector<Vector1> r(l+1, b), u(l+1, b);
00063 for (int i = 0; i <= l; i++)
00064 {
00065 r[i].Zero();
00066 u[i].Zero();
00067 }
00068 tau.Zero(); gamma.Zero(); gamma_prime.Zero(); gamma_twice.Zero();
00069
00070
00071 Copy(b, r[0]);
00072 if (!iter.IsInitGuess_Null())
00073 MltAdd(Complexe(-1), A, x, Complexe(1), r[0]);
00074 else
00075 x.Zero();
00076
00077
00078 int success_init = iter.Init(b);
00079 if (success_init !=0 )
00080 return iter.ErrorCode();
00081
00082 Copy(r[0], r0);
00083
00084
00085 rho_0 = unity; alpha = zero; omega = unity; tau.Zero();
00086
00087 iter.SetNumberIteration(0);
00088
00089 while (! iter.Finished(r[0]))
00090 {
00091 rho_0 *= -omega;
00092
00093
00094 for (int j = 0; j < l; j++)
00095 {
00096 rho_1 = DotProd(r[j], r0);
00097 if (rho_0 == zero)
00098 {
00099 iter.Fail(1, "Bicgstabl breakdown #1");
00100 break;
00101 }
00102 beta = alpha*(rho_1/rho_0);
00103 rho_0 = rho_1;
00104 for (int i = 0; i <= j; i++)
00105 {
00106 Mlt(-beta, u[i]); Add(unity, r[i], u[i]);
00107 }
00108 M.Solve(A, u[j], q);
00109 Mlt(A, q, u[j+1]);
00110
00111 ++iter;
00112 sigma = DotProd(u[j+1], r0);
00113 if (sigma == zero)
00114 {
00115 iter.Fail(2, "Bicgstabl Breakdown #2");
00116 break;
00117 }
00118 alpha = rho_1/sigma;
00119 Add(alpha, u[0], x);
00120 for (int i = 0; i <= j; i++)
00121 Add(-alpha, u[i+1], r[i]);
00122
00123 M.Solve(A, r[j], q);
00124 Mlt(A, q, r[j+1]);
00125
00126 ++iter;
00127 }
00128
00129
00130 for (int j = 1; j <= l; j++)
00131 {
00132 for (int i = 1; i < j; i++)
00133 {
00134 if (gamma(i) != zero)
00135 {
00136 tau(i,j) = DotProd(r[j], r[i])/gamma(i);
00137 Add(-tau(i,j), r[i], r[j]);
00138 }
00139 }
00140 gamma(j) = DotProd(r[j], r[j]);
00141 if (gamma(j) != zero)
00142 gamma_prime(j) = DotProd(r[0], r[j])/gamma(j);
00143 }
00144
00145
00146 gamma(l) = gamma_prime(l); omega = gamma(l);
00147 for (int j = l-1; j >= 1; j--)
00148 {
00149 sigma = zero;
00150 for (int i = j+1; i <= l; i++)
00151 sigma += tau(j,i)*gamma(i);
00152
00153 gamma(j) = gamma_prime(j)-sigma;
00154 }
00155
00156
00157 for (int j = 1; j <= l-1; j++)
00158 {
00159 sigma = zero;
00160 for (int i = j+1; i <= l-1; i++)
00161 sigma += tau(j,i)*gamma(i+1);
00162
00163 gamma_twice(j) = gamma(j+1)+sigma;
00164 }
00165
00166
00167 Add(gamma(1), r[0], x);
00168 Add(-gamma_prime(l), r[l], r[0]);
00169 Add(-gamma(l), u[l], u[0]);
00170 for (int j = 1;j <= l-1; j++)
00171 {
00172 Add(-gamma(j), u[j], u[0]);
00173 Add(gamma_twice(j), r[j], x);
00174 Add(-gamma_prime(j), r[j], r[0]);
00175 }
00176 }
00177
00178 Copy(x,q); M.Solve(A, q, x);
00179 return iter.ErrorCode();
00180 }
00181
00182 }
00183
00184 #define SELDON_FILE_ITERATIVE_BICGSTABL_CXX
00185 #endif