Grid 0.7.0
ConjugateResidual.h
Go to the documentation of this file.
1/*************************************************************************************
2
3 Grid physics library, www.github.com/paboyle/Grid
4
5 Source file: ./lib/algorithms/iterative/ConjugateResidual.h
6
7 Copyright (C) 2015
8
9Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
10Author: Peter Boyle <paboyle@ph.ed.ac.uk>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License along
23 with this program; if not, write to the Free Software Foundation, Inc.,
24 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25
26 See the full license in the file "LICENSE" in the top level distribution directory
27*************************************************************************************/
28/* END LEGAL */
29#ifndef GRID_CONJUGATE_RESIDUAL_H
30#define GRID_CONJUGATE_RESIDUAL_H
31
33
35// Base classes for iterative processes based on operators
36// single input vec, single output vec.
38
39template<class Field>
40class ConjugateResidual : public OperatorFunction<Field> {
41public:
42 using OperatorFunction<Field>::operator();
43
47
49 verbose=0;
50 };
51
52 void operator() (LinearOperatorBase<Field> &Linop,const Field &src, Field &psi){
53
54 RealD a, b; // c, d;
55 RealD cp, ssq,rsq;
56
57 RealD rAr, rAAr, rArp;
58 RealD pAp, pAAp;
59
60 GridBase *grid = src.Grid();
61 psi=Zero();
62 Field r(grid), p(grid), Ap(grid), Ar(grid);
63
64 r=src;
65 p=src;
66
67 Linop.HermOpAndNorm(p,Ap,pAp,pAAp);
68 Linop.HermOpAndNorm(r,Ar,rAr,rAAr);
69
70 cp =norm2(r);
71 ssq=norm2(src);
72 rsq=Tolerance*Tolerance*ssq;
73
74 if (verbose) std::cout<<GridLogMessage<<"ConjugateResidual: iteration " <<0<<" residual "<<cp<< " target"<< rsq<<std::endl;
75
76 for(int k=1;k<MaxIterations;k++){
77
78 a = rAr/pAAp;
79
80 axpy(psi,a,p,psi);
81
82 cp = axpy_norm(r,-a,Ap,r);
83
84 rArp=rAr;
85
86 Linop.HermOpAndNorm(r,Ar,rAr,rAAr);
87
88 b =rAr/rArp;
89
90 axpy(p,b,p,r);
91 pAAp=axpy_norm(Ap,b,Ap,Ar);
92
93 if(verbose) std::cout<<GridLogMessage<<"ConjugateResidual: iteration " <<k<<" residual "<<cp<< " target"<< rsq<<std::endl;
94
95 if(cp<rsq) {
96 Linop.HermOp(psi,Ap);
97 axpy(r,-1.0,src,Ap);
98 RealD true_resid = norm2(r)/ssq;
99 std::cout<<GridLogMessage<<"ConjugateResidual: Converged on iteration " <<k
100 << " computed residual "<<std::sqrt(cp/ssq)
101 << " true residual "<<std::sqrt(true_resid)
102 << " target " <<Tolerance <<std::endl;
103 return;
104 }
105
106 }
107
108 std::cout<<GridLogMessage<<"ConjugateResidual did NOT converge"<<std::endl;
109 assert(0);
110 }
111};
113#endif
RealD axpy_norm(Lattice< vobj > &ret, sobj a, const Lattice< vobj > &x, const Lattice< vobj > &y)
void axpy(Lattice< vobj > &ret, sobj a, const Lattice< vobj > &x, const Lattice< vobj > &y)
RealD norm2(const Lattice< vobj > &arg)
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
uint32_t Integer
Definition Simd.h:58
double RealD
Definition Simd.h:61
ConjugateResidual(RealD tol, Integer maxit)
void operator()(LinearOperatorBase< Field > &Linop, const Field &src, Field &psi)
virtual void HermOp(const Field &in, Field &out)=0
virtual void HermOpAndNorm(const Field &in, Field &out, RealD &n1, RealD &n2)=0
Definition Simd.h:194