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 __CGS_H
00035 #define __CGS_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
00087 template< class T_, class M_, class P_ >
00088 int CGS(const M_ &A, const P_ &P, const Vect<T_> &b, Vect<T_> &x, int max_it,
00089 double &toler, int verbose)
00090 {
00091 int it;
00092 size_t size=x.getSize();
00093 T_ rho_1=0, rho_2=0, alpha=0, beta=0;
00094 double res;
00095 Vect<T_> r(size), p(size), y(size), q(size), z(size), v(size), u(size), w(size);
00096
00097 double nrm = b.getNorm2();
00098 A.Mult(x,r);
00099 Vect<T_> s = b - r;
00100 r = s;
00101
00102 if (nrm == 0)
00103 nrm = 1;
00104 if ((res = r.getNorm2() / nrm) <= toler) {
00105 toler = res;
00106 if (verbose)
00107 cout << "Convergence after 0 iterations." << endl;
00108 return 0;
00109 }
00110
00111 for (it=1; it<=max_it; it++) {
00112 rho_1 = Dot(s,r);
00113 if (rho_1 == T_(0)) {
00114 toler = r.getNorm2() / nrm;
00115 if (verbose)
00116 cout << "Convergence after 2 iterations." << endl;
00117 return 2;
00118 }
00119 if (it == 1) {
00120 u = r;
00121 p = u;
00122 } else {
00123 beta = rho_1 / rho_2;
00124 u = r + beta * q;
00125 p = u + beta * (q + beta * p);
00126 }
00127 y = p;
00128 P.Solve(y);
00129 A.Mult(y,v);
00130 alpha = rho_1 / Dot(s,v);
00131 w = u - alpha*v;
00132 w += u;
00133 P.Solve(w);
00134 Axpy(alpha,w,x);
00135 A.Mult(w,z);
00136 Axpy(-alpha,z,r);
00137 rho_2 = rho_1;
00138 res = r.getNorm2()/nrm;
00139 if (verbose > 1) {
00140 cout << "Iteration : " << setw(4) << it;
00141 cout << " ... Residual : " << res << endl;
00142 }
00143 if (verbose > 2)
00144 cout << x;
00145 if (res < toler) {
00146 toler = res;
00147 if (verbose)
00148 cout << "Convergence after " << it << " iterations." << endl;
00149 return it;
00150 }
00151 }
00152 toler = res;
00153 if (verbose)
00154 cout << "No Convergence after " << it << " iterations." << endl;
00155 return -max_it;
00156 }
00157
00158 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00159 template<class T_>
00160 int _CGS(Matrix<T_> *A, Prec<T_> *P, const Vect<T_> &b, Vect<T_> &x, int max_it,
00161 double &toler, int verbose)
00162 {
00163 int it;
00164 size_t size=x.getSize();
00165 T_ rho_1=0, rho_2=0, alpha=0, beta=0;
00166 double res;
00167 Vect<T_> r(size), p(size), y(size), q(size), z(size), v(size), u(size), w(size);
00168
00169 double nrm = b.getNorm2();
00170 A->Mult(x,r);
00171 Vect<T_> s = b - r;
00172 r = s;
00173
00174 if (nrm == 0)
00175 nrm = 1;
00176 if ((res = r.getNorm2() / nrm) <= toler) {
00177 toler = res;
00178 if (verbose)
00179 cout << "Convergence after 0 iterations." << endl;
00180 return 0;
00181 }
00182
00183 for (it=1; it<=max_it; it++) {
00184 rho_1 = Dot(s,r);
00185 if (rho_1 == T_(0)) {
00186 toler = r.getNorm2() / nrm;
00187 if (verbose)
00188 cout << "Convergence after 2 iterations." << endl;
00189 return 2;
00190 }
00191 if (it == 1) {
00192 u = r;
00193 p = u;
00194 } else {
00195 beta = rho_1 / rho_2;
00196 u = r + beta * q;
00197 p = u + beta * (q + beta * p);
00198 }
00199 y = p;
00200 P->Solve(y);
00201 A->Mult(y,v);
00202 alpha = rho_1 / Dot(s,v);
00203 w = u - alpha*v;
00204 w += u;
00205 P->Solve(w);
00206 Axpy(alpha,w,x);
00207 A->Mult(w,z);
00208 Axpy(-alpha,z,r);
00209 rho_2 = rho_1;
00210 res = r.getNorm2()/nrm;
00211 if (verbose > 1)
00212 cout << "Iteration: " << setw(4) << it << " ... Residual: " << res << endl;
00213 if (verbose > 2)
00214 cout << x;
00215 if (res < toler) {
00216 toler = res;
00217 if (verbose)
00218 cout << "Convergence after " << it << " iterations." << endl;
00219 return it;
00220 }
00221 }
00222 toler = res;
00223 if (verbose)
00224 cout << "No Convergence after " << it << " iterations." << endl;
00225 return -max_it;
00226 }
00227 #endif
00228
00229 }
00230
00231 #endif