00001
00005
00006
00007 #ifndef TBCI_SOLVER_CHEBY_H
00008 #define TBCI_SOLVER_CHEBY_H
00009
00010 #include "../basics.h"
00011 #include "precond.h"
00012
00013 NAMESPACE_TBCI
00014
00015 INST3(template <typename T, Matrix<T>, Vector<T> > class NN friend \
00016 int CHEBY (const Matrix<T>&, Vector<T>&, const Vector<T>&,\
00017 const Preconditioner_Sig<T, Matrix<T> >&, unsigned int&, double&, T, T);)
00018 INST3(template <typename T, BdMatrix<T>, Vector<T> > class NN friend \
00019 int CHEBY (const BdMatrix<T>&, Vector<T>&, const Vector<T>&,\
00020 const Preconditioner_Sig<T, BdMatrix<T> >&, unsigned int&, double&, T, T);)
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef HAVE_BCXX_TYPENAME_BUG
00032 # define VALUE_TYPE typename SysVector::value_type
00033 #else
00034 # define VALUE_TYPE SysVector::value_type
00035 #endif
00036
00037
00059 template < typename T, typename SysMatrix, typename SysVector >
00060 int CHEBY(const SysMatrix &A, SysVector &x, const SysVector &b,
00061 const Preconditioner_Sig<T, SysMatrix> &M, unsigned int &max_iter, double &tol,
00062 T eigmin, T eigmax)
00063 {
00064 double resid;
00065 unsigned int dim = A.rows();
00066 T alpha(0), beta, c, d;
00067 SysVector p(dim), q(dim), z(dim);
00068
00069 double normb = b.fabs();
00070 SysVector r(b - A * x);
00071
00072 if (normb == 0.0)
00073 normb = 1;
00074
00075 if ((resid = r.fabs() / normb) <= tol)
00076 {
00077 tol = resid;
00078 max_iter = 0;
00079 return 0;
00080 }
00081
00082 c = (eigmax - eigmin) / 2.0;
00083 d = (eigmax + eigmin) / 2.0;
00084
00085 for (unsigned int i = 1; i <= max_iter; i++)
00086 {
00087 z = M.solve(r);
00088
00089 if (i == 1)
00090 {
00091 p = z;
00092 alpha = 2.0 / d;
00093 } else
00094 {
00095 beta = c * alpha / 2.0;
00096 beta = beta * beta;
00097 alpha = 1.0 / (d - beta);
00098 p = z + (VALUE_TYPE)beta * p;
00099 }
00100
00101 q = A * p;
00102 x += VALUE_TYPE (alpha) * p;
00103 r -= VALUE_TYPE (alpha) * q;
00104
00105 if ((resid = r.fabs() / normb) <= tol)
00106 {
00107 tol = resid;
00108 max_iter = i;
00109 return 0;
00110 }
00111 }
00112
00113 tol = resid;
00114 return 1;
00115 }
00116
00117 NAMESPACE_END
00118
00119 #endif