00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 template < class Matrix, class Vector, class Preconditioner, class Real >
00023 int
00024 CG(const Matrix &A, Vector &x, const Vector &b,
00025 const Preconditioner &M, int &max_iter, Real &tol)
00026 {
00027 Real resid;
00028 Vector p, z, q;
00029 Vector alpha(1), beta(1), rho(1), rho_1(1);
00030
00031 Real normb = norm(b);
00032 Vector r = b - A*x;
00033
00034 if (normb == 0.0)
00035 normb = 1;
00036
00037 if ((resid = norm(r) / normb) <= tol) {
00038 tol = resid;
00039 max_iter = 0;
00040 return 0;
00041 }
00042
00043 for (int i = 1; i <= max_iter; i++) {
00044 z = M.solve(r);
00045 rho(0) = dot(r, z);
00046
00047 if (i == 1)
00048 p = z;
00049 else {
00050 beta(0) = rho(0) / rho_1(0);
00051 p = z + beta(0) * p;
00052 }
00053
00054 q = A*p;
00055 alpha(0) = rho(0) / dot(p, q);
00056
00057 x += alpha(0) * p;
00058 r -= alpha(0) * q;
00059
00060 if ((resid = norm(r) / normb) <= tol) {
00061 tol = resid;
00062 max_iter = i;
00063 return 0;
00064 }
00065
00066 rho_1(0) = rho(0);
00067 }
00068
00069 tol = resid;
00070 return 1;
00071 }
00072