mirror of
https://github.com/paboyle/Grid.git
synced 2025-06-13 12:47:05 +01:00
Getting closer to having a wilson solver... introducing a first and untested
cut at Conjugate gradient. Also copied in Remez, Zolotarev, Chebyshev from Mike Clark, Tony Kennedy and my BFM package respectively since we know we will need these. I wanted the structure of algorithms/approx algorithms/iterative etc.. to start taking shape.
This commit is contained in:
@ -1,19 +1,25 @@
|
||||
#ifndef GRID_CONJUGATE_GRADIENT_H
|
||||
#define GRID_CONJUGATE_GRADIENT_H
|
||||
|
||||
#include<Grid.h>
|
||||
#include<algorithms/LinearOperator.h>
|
||||
|
||||
namespace Grid {
|
||||
|
||||
template<class Field> class ConjugateGradient : public IterativeProcess<Field> {
|
||||
public:
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Base classes for iterative processes based on operators
|
||||
// single input vec, single output vec.
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
ConjugateGradient(RealD tol,Integer maxit): IterativeProces(tol,maxit) {};
|
||||
template<class Field>
|
||||
class ConjugateGradient : public OperatorFunction<Field> {
|
||||
public:
|
||||
RealD Tolerance;
|
||||
Integer MaxIterations;
|
||||
|
||||
void operator() (HermitianOperatorBase<Field> *Linop,const Field &src, Field &psi){
|
||||
ConjugateGradient(RealD tol,Integer maxit) : Tolerance(tol), MaxIterations(maxit) {
|
||||
std::cout << Tolerance<<std::endl;
|
||||
};
|
||||
|
||||
void operator() (HermitianOperatorBase<Field> &Linop,const Field &src, Field &psi){
|
||||
|
||||
RealD residual = Tolerance;
|
||||
RealD cp,c,a,d,b,ssq,qq,b_pred;
|
||||
|
||||
Field p(src);
|
||||
@ -32,24 +38,24 @@ namespace Grid {
|
||||
cp =a;
|
||||
ssq=norm2(src);
|
||||
|
||||
std::cout <<setprecision(4)<< "ConjugateGradient: guess "<<guess<<std::endl;
|
||||
std::cout <<setprecision(4)<< "ConjugateGradient: src "<<ssq <<std::endl;
|
||||
std::cout <<setprecision(4)<< "ConjugateGradient: mp "<<d <<std::endl;
|
||||
std::cout <<setprecision(4)<< "ConjugateGradient: mmp "<<b <<std::endl;
|
||||
std::cout <<setprecision(4)<< "ConjugateGradient: r "<<cp <<std::endl;
|
||||
std::cout <<setprecision(4)<< "ConjugateGradient: p "<<a <<std::endl;
|
||||
std::cout <<std::setprecision(4)<< "ConjugateGradient: guess "<<guess<<std::endl;
|
||||
std::cout <<std::setprecision(4)<< "ConjugateGradient: src "<<ssq <<std::endl;
|
||||
std::cout <<std::setprecision(4)<< "ConjugateGradient: mp "<<d <<std::endl;
|
||||
std::cout <<std::setprecision(4)<< "ConjugateGradient: mmp "<<b <<std::endl;
|
||||
std::cout <<std::setprecision(4)<< "ConjugateGradient: r "<<cp <<std::endl;
|
||||
std::cout <<std::setprecision(4)<< "ConjugateGradient: p "<<a <<std::endl;
|
||||
|
||||
RealD rsq = residual* residual*ssq;
|
||||
RealD rsq = Tolerance* Tolerance*ssq;
|
||||
|
||||
//Check if guess is really REALLY good :)
|
||||
if ( cp <= rsq ) {
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << setprecision(4)<< "ConjugateGradient: k=0 residual "<<cp<<" rsq"<<rsq<<std::endl;
|
||||
std::cout << std::setprecision(4)<< "ConjugateGradient: k=0 residual "<<cp<<" rsq"<<rsq<<std::endl;
|
||||
|
||||
int k;
|
||||
for (k=1;k<=max_iter;k++){
|
||||
for (k=1;k<=MaxIterations;k++){
|
||||
|
||||
c=cp;
|
||||
|
||||
@ -62,10 +68,10 @@ namespace Grid {
|
||||
b = cp/c;
|
||||
|
||||
// Fuse these loops ; should be really easy
|
||||
// Update psi; New (conjugate/M-orthogonal) search direction
|
||||
psi= a*p+psi;
|
||||
p = p*b+r;
|
||||
|
||||
std::cout << "Iteration " <<k<<" residual "<<cp<< " target"<< rsq<<std::endl;
|
||||
// Stopping condition
|
||||
if ( cp <= rsq ) {
|
||||
|
||||
@ -78,10 +84,11 @@ namespace Grid {
|
||||
RealD resnorm = sqrt(norm2(p));
|
||||
RealD true_residual = resnorm/srcnorm;
|
||||
std::cout<<"ConjugateGradient: true residual is "<<true_residual<<" sol "<<psinorm<<" src "<<srcnorm<<std::endl;
|
||||
std::cout<<"ConjugateGradient: target residual was "<<residual<<std::endl;
|
||||
return k;
|
||||
std::cout<<"ConjugateGradient: target residual was "<<Tolerance<<std::endl;
|
||||
}
|
||||
}
|
||||
std::cout<<"ConjugateGradient did NOT converge"<<std::endl;
|
||||
assert(0);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user