cg.h
Go to the documentation of this file.
00001 //*****************************************************************
00002 // Iterative template routine -- CG
00003 //
00004 // CG solves the symmetric positive definite linear
00005 // system Ax=b using the Conjugate Gradient method.
00006 //
00007 // CG follows the algorithm described on p. 15 in the 
00008 // SIAM Templates book.
00009 //
00010 // The return value indicates convergence within max_iter (input)
00011 // iterations (0), or no convergence within max_iter iterations (1).
00012 //
00013 // Upon successful return, output arguments have the following values:
00014 //  
00015 //        x  --  approximate solution to Ax = b
00016 // max_iter  --  the number of iterations performed before the
00017 //               tolerance was reached
00018 //      tol  --  the residual after the final iteration
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 


sparselib
Author(s): Roldan Pozo, Karin A. Remington, Andrew Lumsdaine
autogenerated on Thu Jan 2 2014 12:12:22