00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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;
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;
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