diff --git a/lib/algorithms/approx/Chebyshev.h b/lib/algorithms/approx/Chebyshev.h index 37331816..f00170cf 100644 --- a/lib/algorithms/approx/Chebyshev.h +++ b/lib/algorithms/approx/Chebyshev.h @@ -9,23 +9,34 @@ namespace Grid { //////////////////////////////////////////////////////////////////////////////////////////// // Simple general polynomial with user supplied coefficients //////////////////////////////////////////////////////////////////////////////////////////// + template + class HermOpOperatorFunction : public OperatorFunction { + void operator() (LinearOperatorBase &Linop, const Field &in, Field &out) { + Linop.HermOp(in,out); + }; + }; + template class Polynomial : public OperatorFunction { private: - std::vector Coeffs; + std::vector Coeffs; public: - Polynomial(std::vector &_Coeffs) : Coeffs(_Coeffs) {}; + Polynomial(std::vector &_Coeffs) : Coeffs(_Coeffs) { }; // Implement the required interface void operator() (LinearOperatorBase &Linop, const Field &in, Field &out) { - Field AtoN = in; + Field AtoN(in._grid); + Field Mtmp(in._grid); + AtoN = in; out = AtoN*Coeffs[0]; - + // std::cout <<"Poly in " < class Chebyshev : public OperatorFunction { private: - std::vector Coeffs; + std::vector Coeffs; int order; - double hi; - double lo; + RealD hi; + RealD lo; public: void csv(std::ostream &out){ - for (double x=lo; x U(M); - std::vector a(M); - std::vector g(M); + RealD M=order; + RealD alpha = M_PI/(M+2); + RealD lmax = std::cos(alpha); + RealD sumUsq =0; + std::vector U(M); + std::vector a(M); + std::vector g(M); for(int n=0;n<=M;n++){ U[n] = std::sin((n+1)*std::acos(lmax))/std::sin(std::acos(lmax)); sumUsq += U[n]*U[n]; @@ -107,18 +124,18 @@ namespace Grid { Coeffs[m]*=g[m]; } } - double approx(double x) // Convenience for plotting the approximation + RealD approx(RealD x) // Convenience for plotting the approximation { - double Tn; - double Tnm; - double Tnp; + RealD Tn; + RealD Tnm; + RealD Tnp; - double y=( x-0.5*(hi+lo))/(0.5*(hi-lo)); + RealD y=( x-0.5*(hi+lo))/(0.5*(hi-lo)); - double T0=1; - double T1=y; + RealD T0=1; + RealD T1=y; - double sum; + RealD sum; sum = 0.5*Coeffs[0]*T0; sum+= Coeffs[1]*T1; @@ -151,8 +168,8 @@ namespace Grid { std::cout< + class ChebyshevLanczos : public Chebyshev { + private: + std::vector Coeffs; + int order; + RealD alpha; + RealD beta; + RealD mu; + + public: + ChebyshevLanczos(RealD _alpha,RealD _beta,RealD _mu,int _order) : + alpha(_alpha), + beta(_beta), + mu(_mu) + { + order=_order; + Coeffs.resize(order); + for(int i=0;i<_order;i++){ + Coeffs[i] = 0.0; + } + Coeffs[order-1]=1.0; + }; + + void csv(std::ostream &out){ + for (RealD x=-1.2*alpha; x<1.2*alpha; x+=(2.0*alpha)/10000) { + RealD f = approx(x); + out<< x<<" "< &Linop, const Field &in, Field &out) + { + GridBase *grid=in._grid; + Field tmp(grid); + + RealD aa= alpha*alpha; + RealD bb= beta * beta; + + Linop.HermOp(in,out); + out = out - mu*in; + + Linop.HermOp(out,tmp); + tmp = tmp - mu * out; + + out = (2.0/ (aa-bb) ) * tmp - ((aa+bb)/(aa-bb))*in; + }; + // Implement the required interface + void operator() (LinearOperatorBase &Linop, const Field &in, Field &out) { + + GridBase *grid=in._grid; + + int vol=grid->gSites(); + + Field T0(grid); T0 = in; + Field T1(grid); + Field T2(grid); + Field y(grid); + + Field *Tnm = &T0; + Field *Tn = &T1; + Field *Tnp = &T2; + + // Tn=T1 = (xscale M )*in + AminusMuSq(Linop,T0,T1); + + // sum = .5 c[0] T0 + c[1] T1 + out = (0.5*Coeffs[0])*T0 + Coeffs[1]*T1; + for(int n=2;n