00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef __CG_H
00035 #define __CG_H
00036
00037 #include <iostream>
00038 using std::ostream;
00039 using std::endl;
00040
00041 #include <iomanip>
00042 using std::setw;
00043 using std::ios;
00044 using std::setprecision;
00045
00046
00047 #include "OFELI_Config.h"
00048 #include "Vect.h"
00049 #include "Precond.h"
00050 #include "util.h"
00051 #include "output.h"
00052
00053 namespace OFELI {
00054
00088 template<class T_, class M_, class P_ >
00089 int CG(const M_ &A, const P_ &P, const Vect<T_> &b, Vect<T_> &x, int max_it,
00090 double &toler, int verbose)
00091 {
00092 int it;
00093 size_t size = x.getSize();
00094 double res, nrm=b.getNorm2();
00095 T_ rho=0, rho_1=T_(1), beta=0;
00096
00097 if (nrm == 0)
00098 nrm = 1;
00099 Vect<T_> r(size), p(size), q(size), z(size);
00100 A.Mult(x,r);
00101 r = b - r;
00102 if ((res = r.getNorm2()/nrm) <= toler) {
00103 if (verbose > 1)
00104 cout << "Convergence after 0 iterations." << endl;
00105 return 0;
00106 }
00107
00108 for (it=1; it<=max_it; it++) {
00109 P.Solve(r,z);
00110 rho = Dot(r,z);
00111 if (it==1)
00112 p = z;
00113 else {
00114 beta = rho/rho_1;
00115 p = z + beta * p;
00116 }
00117 A.Mult(p,q);
00118 T_ alpha = rho/Dot(p,q);
00119 x += alpha * p;
00120 r -= alpha * q;
00121 res = r.getNorm2()/nrm;
00122
00123 if (verbose > 1) {
00124 cout << "Iteration: " << setw(4) << it;
00125 cout << " ... Residual: " << res << endl;
00126 }
00127 if (verbose > 2)
00128 cout << x;
00129 if (res <= toler) {
00130 toler = res;
00131 if (verbose)
00132 cout << "Convergence after " << it << " iterations." << endl;
00133 return it;
00134 }
00135 rho_1 = rho;
00136 }
00137 if (verbose)
00138 cout << "No Convergence after " << it << " iterations." << endl;
00139 return -it;
00140 }
00141
00142
00143 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00144 template<class T_>
00145 int _CG(Matrix<T_> *A, Prec<T_> *P, const Vect<T_> &b,
00146 Vect<T_> &x, int max_it, double toler, int verbose)
00147 {
00148 int it=0;
00149 size_t size = x.getSize();
00150 double nrm=b.getNorm2(), rho=0, res=0, beta=0, rho_1=0;
00151
00152 if (nrm == 0)
00153 nrm = 1;
00154 Vect<T_> r(size), z(size), p(size), q(size);
00155 A->Mult(x,r);
00156 r = b - r;
00157 if ((res = r.getNorm2()/nrm) <= toler) {
00158 if (verbose > 1)
00159 cout << "Convergence after " << it << " iterations." << endl;
00160 return it;
00161 }
00162
00163 for (it=1; it<=max_it; it++) {
00164 P->Solve(r,z);
00165 rho = Dot(r,z);
00166 if (it==1)
00167 p = z;
00168 else {
00169 beta = rho/rho_1;
00170 p = z + beta * p;
00171 }
00172 A->Mult(p,q);
00173 double alpha = rho/Dot(p,q);
00174 x += alpha * p;
00175 r -= alpha * q;
00176 res = r.getNorm2()/nrm;
00177
00178 if (verbose > 1) {
00179 cout << "Iteration : " << setw(4) << it;
00180 cout << " ... Residual : " << res << endl;
00181 }
00182 if (verbose > 2)
00183 cout << x;
00184 if (res <= toler) {
00185 if (verbose)
00186 cout << "Convergence after " << it << " iterations." << endl;
00187 return it;
00188 }
00189 rho_1 = rho;
00190 }
00191 if (verbose)
00192 cout << "No Convergence after " << it << " iterations." << endl;
00193 return -it;
00194 }
00195
00196
00197 template<class T_, class M_, class P_>
00198 int CG(const P_ &P, const Vect<T_> &b, Vect<T_> &x, int max_it, double toler,
00199 int verbose)
00200 {
00201 int it=0;
00202 size_t size = x.Dim();
00203 double nrm=b.getNorm2(), rho=0, res=0, beta=0, rho_1=0;
00204 if (nrm == 0)
00205 nrm = 1;
00206 Vect<T_> r(size), z(size), p(size), q(size);
00207 r = b;
00208 r.MultAdd(Mxv(x),-1);
00209
00210 if ((res = r.getNorm2() / nrm) <= toler) {
00211 if (verbose)
00212 cout << "Convergence after " << it << " iterations." << endl;
00213 return it;
00214 }
00215
00216 for (it=1; it<=max_it; it++) {
00217 P.Solve(r,z);
00218 rho = Dot(r,z);
00219 if (it==1)
00220 p = z;
00221 else {
00222 beta = rho/rho_1;
00223 p *= beta;
00224 p.MultAdd(z);
00225 }
00226
00227 q = Mxv(p);
00228 double alpha = rho/Dot(p,q);
00229 x.MultAdd(p, alpha);
00230 r.MultAdd(q,-alpha);
00231 res = r.Norm2()/nrm;
00232
00233 if (verbose > 1)
00234 cout << "\nIteration : " << it << " ..." << endl;
00235 if (verbose > 2)
00236 cout << x;
00237 if (res <= toler) {
00238 if (verbose)
00239 cout << "Convergence after " << it << " iterations." << endl;
00240 return it;
00241 }
00242 rho_1 = rho;
00243 }
00244 if (verbose)
00245 cout << "No Convergence after " << it << " iterations." << endl;
00246 return -it;
00247 }
00248
00249
00250 template<class T_>
00251 int _CG(const Prec<T_> *P, const Vect<T_> &b, Vect<T_> &x, int max_it,
00252 double toler, int verbose)
00253 {
00254 int it=0;
00255 size_t size = x.Dim();
00256 double nrm=b.Norm2(), rho=0, res=0, beta=0, rho_1=0;
00257 if (nrm == 0)
00258 nrm = 1;
00259 Vect<T_> r(size), z(size), p(size), q(size);
00260 r = b;
00261 r.MultAdd(Mxv(x),-1);
00262
00263 if ((res = r.Norm2() / nrm) <= toler) {
00264 if (verbose)
00265 cout << "Convergence after " << it << " iterations." << endl;
00266 return it;
00267 }
00268
00269 for (it=1; it<=max_it; it++) {
00270 P->Solve(r,z);
00271 rho = Dot(r,z);
00272 if (it==1)
00273 p = z;
00274 else {
00275 beta = rho/rho_1;
00276 p *= beta;
00277 p.MultAdd(z);
00278 }
00279
00280 q = Mxv(p);
00281 double alpha = rho/Dot(p,q);
00282 x.MultAdd(p, alpha);
00283 r.MultAdd(q,-alpha);
00284 res = r.Norm2()/nrm;
00285
00286 if (verbose > 1)
00287 cout << "\nIteration : " << it << " ..." << endl;
00288 if (verbose > 2)
00289 cout << x;
00290 if (res <= toler) {
00291 if (verbose)
00292 cout << "Convergence after " << it << " iterations." << endl;
00293 return it;
00294 }
00295 rho_1 = rho;
00296 }
00297 if (verbose)
00298 cout << "No Convergence after " << it << " iterations." << endl;
00299 return -it;
00300 }
00301 #endif
00302
00303 }
00304
00305 #endif