00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef ITL_BICGSTAB_2_INCLUDE
00013 #define ITL_BICGSTAB_2_INCLUDE
00014
00015 #include <boost/numeric/mtl/concept/collection.hpp>
00016 #include <boost/numeric/mtl/utility/exception.hpp>
00017 #include <boost/numeric/linear_algebra/identity.hpp>
00018
00019 namespace itl {
00020
00021
00022 template < typename LinearOperator, typename Vector,
00023 typename Preconditioner, typename Iteration >
00024 int bicgstab_2(const LinearOperator &A, Vector &x, const Vector &b,
00025 const Preconditioner &M, Iteration& iter)
00026 {
00027 using math::zero; using math::one;
00028 typedef typename mtl::Collection<Vector>::value_type Scalar;
00029 Scalar rho_0(0), rho_1(0), alpha(0), beta(0), gamma(0),
00030 mu(0), nu(0), tau(0), omega_1(0), omega_2(0);
00031 Vector r(b - A * x), r_0(r), r_i(r), x_i(x),
00032 s(size(x)), t(size(x)), u(size(x)), v(size(x)), w(size(x));
00033
00034 if (size(b) == 0) throw mtl::logic_error("empty rhs vector");
00035
00036 alpha= zero(b[0]); u= alpha; rho_0= omega_2= one(b[0]);
00037 while (! iter.finished(r)) {
00038 rho_0= -omega_2 * rho_0;
00039
00040
00041 rho_1= dot(r_0, r_i);
00042 beta= alpha * rho_1 / rho_0; rho_0= rho_1;
00043 u= r_i - beta * u;
00044 v= A * u;
00045 gamma= dot(v, r_0); alpha= rho_0 / gamma;
00046 r= r_i - alpha * v;
00047 s= A * r;
00048 x= x_i + alpha * u;
00049
00050 rho_1= dot(r_0, s); beta= alpha * rho_1 / rho_0; rho_0= rho_1;
00051 v= s - beta * v;
00052 w= A * v;
00053 gamma= dot(w, r_0); alpha= rho_0 / gamma;
00054 u= r - beta * u;
00055 r-= alpha * v;
00056 s-= alpha * w;
00057 t= A * s;
00058
00059 omega_1= dot(r, s); mu= dot(s, s); nu= dot(s, t); tau= dot(t, t);
00060 omega_2= dot(r, t); tau-= nu * nu / mu; omega_2= (omega_2 - nu * omega_1 / mu) / tau;
00061 omega_1= (omega_1 - nu * omega_2) / mu;
00062 x_i= x + omega_1 * r + omega_2 * s + alpha * u;
00063 r_i= r - omega_1 * s - omega_2 * t;
00064 u-= omega_1 * v + omega_2 * w;
00065
00066 ++iter;
00067 }
00068 return iter.error_code();
00069 }
00070
00071 }
00072
00073 #endif // ITL_BICGSTAB_2_INCLUDE
00074
00075
00076
00077
00078
00079