00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef ITL_IDR_S_INCLUDE
00016 #define ITL_IDR_S_INCLUDE
00017
00018 #include <boost/numeric/mtl/concept/collection.hpp>
00019 #include <boost/numeric/mtl/vector/dense_vector.hpp>
00020 #include <boost/numeric/mtl/operation/random.hpp>
00021 #include <boost/numeric/linear_algebra/identity.hpp>
00022
00023 namespace itl {
00024
00025
00026 template < typename LinearOperator, typename Vector,
00027 typename LeftPreconditioner, typename RightPreconditioner,
00028 typename Iteration >
00029 int idr_s(const LinearOperator &A, Vector &x, const Vector &b,
00030 const LeftPreconditioner &L, const RightPreconditioner &R,
00031 Iteration& iter, size_t s)
00032 {
00033 using mtl::irange; using mtl::imax; using mtl::iall; using mtl::matrix::strict_upper;
00034 typedef typename mtl::Collection<Vector>::value_type Scalar;
00035 typedef typename mtl::Collection<Vector>::size_type Size;
00036
00037 if (size(b) == 0) throw mtl::logic_error("empty rhs vector");
00038 if (s < 1) s= 1;
00039
00040 Size n= size(x);
00041 const Scalar zero= math::zero(b[0]);
00042 Scalar omega(zero);
00043 Vector x0(x), y(n), v(n), t(n), q(n);
00044 mtl::multi_vector<Vector> dR(s, Vector(n, zero)), dX(s, Vector(n, zero)), P(s, Vector(n, zero)), M(s, s);
00045 mtl::dense2D<Scalar> M2(s, s);
00046
00047 Vector r(b - A * x);
00048
00049 mtl::seed<Scalar> seed;
00050 random(P, seed);
00051 P.vector(0)= r;
00052 orth(P);
00053
00054 for (size_t k= 0; k < s; k++) {
00055 v= A * r;
00056 omega= dot(v, r) / dot(v, v);
00057 dX.vector(k)= omega * r;
00058 dR.vector(k)= -omega * v;
00059 x+= dX.vector(k);
00060 r+= dR.vector(k);
00061 if (iter.finished(r))
00062 return iter;
00063 M.vector(k)= trans(P) * dR.vector(k);
00064 }
00065
00066 Size oldest= 0;
00067 iter+= s;
00068 Vector m(trans(P) * r), c(s), dm(s);
00069
00070 while (! iter.finished(r)) {
00071
00072 for (size_t k= 0; k < s; k++) {
00073
00074 M2= M;
00075 c= lu_solve(M2, m);
00076 q= dR * -c;
00077 v= r + q;
00078 if (k == 0) {
00079 t= A * v;
00080 omega= dot(t, v) / dot(t, t);
00081 dR.vector(oldest)= q - omega * t;
00082 dX.vector(oldest)= omega * v - dX * c;
00083 } else {
00084 dX.vector(oldest)= omega * v - dX * c;
00085 dR.vector(oldest)= A * -dX.vector(oldest);
00086 }
00087 r+= dR.vector(oldest);
00088 x+= dX.vector(oldest);
00089
00090 ++iter;
00091 if (iter.finished(r))
00092 return iter;
00093
00094 dm= trans(P) * dR.vector(oldest);
00095 M.vector(oldest)= dm;
00096 m+= dm;
00097 oldest= (oldest + 1) % s;
00098 }
00099 }
00100 return iter;
00101 }
00102
00103
00104 }
00105
00106 #endif // ITL_IDR_S_INCLUDE