Main Page | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

cg_sngl.h

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 #ifndef CG_SNGL_H
00022 #define CG_SNGL_H
00023 
00024 
00025 template < class GMatrix, class GVector, class Preconditioner, class Real >
00026 int 
00027 CG_solv1(const GMatrix &A, GVector &x,  GVector &b,
00028    const Preconditioner &M, int &max_iter, Real &tol)
00029 // Solution for one vector 
00030 {
00031   Real resid;
00032   GVector p, z, q;
00033   Real alpha, beta, rho, rho_1;
00034 
00035   Real normb = norm(b);
00036   GVector r = b - A*x;
00037 
00038   if (normb == 0.0) 
00039     normb = 1;
00040   
00041   if ((resid = norm(r) / normb) <= tol) {
00042     tol = resid;
00043     max_iter = 0;
00044     return FALSE;
00045   }
00046 
00047   for (int i = 1; i <= max_iter; i++) {
00048     z = M.solve(r);
00049     rho = dot(r, z);
00050     
00051     if (i == 1)
00052       p = z;
00053     else {
00054       beta = rho / rho_1;
00055       p = z + beta * p;
00056     }
00057     
00058     q = A*p;
00059     alpha = rho / dot(p, q);
00060     
00061     x += alpha * p;
00062     r -= alpha * q;
00063     
00064     if ((resid = norm(r) / normb) <= tol) {
00065       tol = resid;
00066       max_iter = i;
00067       return 0;     
00068     }
00069 
00070     char buf[132]; 
00071         sprintf(buf,"resid=norm(r)/ normb at iteration %d  is %16.9f \n",i,resid );
00072         PrintLog("%s",buf);
00073 
00074     rho_1 = rho;
00075   }
00076   
00077   tol = resid;
00078   return 1;
00079 }
00080 
00081 
00082 template < class GMatrix, class GVector, class Preconditioner, class Real >
00083 int 
00084 CG_sngl(const GMatrix &A, GVector &x,  GVector &b,
00085    const Preconditioner &M, int &max_iter, Real &tol)
00086 // Solution for one vector 
00087 {
00088   Real resid;
00089   GVector p, z, q;
00090   Real alpha, beta, rho, rho_1;
00091 
00092   Real normb = norm(b);
00093   GVector r = b - A*x;
00094 
00095   if (normb == 0.0) 
00096     normb = 1;
00097   
00098   if ((resid = norm(r) / normb) <= tol) {
00099     tol = resid;
00100     max_iter = 0;
00101     return FALSE;
00102   }
00103 
00104   for (int i = 1; i <= max_iter; i++) {
00105     z = M.solve(r);
00106     rho = dot(r, z);
00107     
00108     if (i == 1)
00109       p = z;
00110     else {
00111       beta = rho / rho_1;
00112       p = z + beta * p;
00113     }
00114     
00115     q = A*p;
00116     alpha = rho / dot(p, q);
00117     
00118     x += alpha * p;
00119     r -= alpha * q;
00120     
00121     if ((resid = norm(r) / normb) <= tol) {
00122       tol = resid;
00123       max_iter = i;
00124       return 0;     
00125     }
00126 
00127     char buf[132]; 
00128         sprintf(buf,"resid=norm(r)/ normb at iteration %d  is %16.9f \n",i,resid );
00129         PrintLog("%s",buf);
00130 
00131     rho_1 = rho;
00132   }
00133   
00134   tol = resid;
00135   return 1;
00136 }
00137 
00138 template < class GMatrix, class GVector, class Preconditioner, class Real >
00139 int 
00140 CG_mult(GMatrix &A, GVector &x,  GVector &b,
00141    const Preconditioner &M, int &max_iter, Real &tol)
00142 // Solution for one vector 
00143 {
00144   Real resid;
00145   GVector p, z, q;
00146   Real alpha, beta, rho, rho_1;
00147 
00148   Real normb = norm2(b); 
00149   GVector tmp = A*x; 
00150   GVector r = b - tmp;  // r = b - Ax 
00151 
00152   if (normb == 0.0) 
00153     normb = 1;
00154   
00155   if ((resid = norm2(r) / normb) < tol) {
00156     tol = resid;
00157     max_iter = 0;
00158     return 0;
00159   }
00160 
00161   for (int i = 1; i <= max_iter; i++) {
00162     z = M.solve(r);
00163     rho = dot2(r, z);
00164     
00165     if (i == 1)
00166       p = z;
00167     else 
00168     {
00169       beta = rho / rho_1;
00170       tmp = beta*p;
00171       p = z + tmp;        // p = z + (rho / rho_1)* p
00172     }
00173     
00174     q = A*p;
00175     alpha = rho / dot2(p, q);
00176     
00177     tmp = alpha * p; 
00178     x += tmp;  
00179     tmp = alpha * q;
00180     r -= tmp;
00181     
00182     if ((resid = norm2(r) / normb) < tol) {
00183       tol = resid;
00184       max_iter = i;
00185       return 0;     
00186     }
00187 
00188     PrintLog("resid=norm(r)/ normb at iteration %d \n is %12.6e \n",i,resid);
00189 
00190     rho_1 = rho;
00191   }
00192   
00193   tol = resid;
00194   return 1;
00195 }
00196 
00197 
00198 #endif /* !CG_SNGL_H */

Generated on Tue Feb 17 02:03:02 2004 for harlem by doxygen 1.3.6