diff --git a/conjgrad.h b/conjgrad.h index d16ca62..f181841 100644 --- a/conjgrad.h +++ b/conjgrad.h @@ -3,12 +3,69 @@ #include "mat.h" #include "sparsemat.h" #include "nonclass.h" +#include //conjugate gradient solution of a linear system //matrix can be any class which has nrows(), ncols(), diagonalof() and NRVec::gemv() available //does not even have to be explicitly stored +//Conjugate gradient algorithm, cf. Bulirsch-Stoer book template -extern void conjgrad(const Matrix &bigmat, const NRVec &b, NRVec &x, const bool doguess, const double tol, const int itmax, const bool verbose, bool issquare,const bool precondition); +extern void conjgrad(const Matrix &bigmat, const NRVec &b, NRVec &x, const bool doguess, const double tol, const int itmax, const bool verbose, bool issquare,const bool precondition) +{ +int m=bigmat.nrows(); +int n=bigmat.ncols(); + +if(x.size()!=n || b.size() != m) laerror("incompatible vectors and matrix sizes in conjgrad"); +if(m!=n) issquare=0; + +double t,tt,bscal,ascal; + +NRVec p,rr, *r; +NRVec q(m),s(m); +if(issquare) r=&s; else r = new NRVec(m); + +if(doguess) + { + x.gemv(0,bigmat,'t',-1.,b); + if(precondition) bigmat.diagonalof(x,true); + x.normalize(); + } + +s.gemv(0,bigmat,'n',-1.,x); +s+=b; +if(!issquare) (*r).gemv(0,bigmat,'t',1,s); +rr= *r; +if(precondition) bigmat.diagonalof(rr,true); +p=rr; + +for(int iter=0; iter<= itmax; iter++) + { + double err=p.norm(); + if(verbose) cout << "conjgrad: iter= "<