#ifndef GRID_IRL_H #define GRID_IRL_H namespace Grid { ///////////////////////////////////////////////////////////// // Base classes for iterative processes based on operators // single input vec, single output vec. ///////////////////////////////////////////////////////////// template class ImplicitlyRestartedLanczos { public: int Niter; int Nk; int Np; RealD enorm; RealD vthr; LinearOperatorBase &_Linop; OperatorFunction &_poly; ImplicitlyRestartedLanczos( LinearOperatorBase &Linop, OperatorFunction & poly, int _Nk, int _Np, RealD _enorm, RealD _vthrs, int _Niter) : _Linop(Linop), _poly(poly), Nk(_Nk), Np(_Np), enorm(_enorm), vthr(_vthrs) { vthr=_vthrs; Niter=_Niter; }; void step(Vector& lmda, Vector& lmdb, Vector& evec, Field& f,int Nm,int k) { assert( k< Nm ); w = opr_->mult(evec[k]); if(k==0){ // Initial step RealD wnorm= w*w; std::cout<<"wnorm="<& lmda, Vector& lmdb, int Nk, int Nm, Vector& Qt, RealD Dsft, int kmin, int kmax) { int k = kmin-1; RealD x; RealD Fden = 1.0/sqrt((lmd[k]-Dsh)*(lmd[k]-Dsh) +lme[k]*lme[k]); RealD c = ( lmd[k] -Dsh) *Fden; RealD s = -lme[k] *Fden; RealD tmpa1 = lmd[k]; RealD tmpa2 = lmd[k+1]; RealD tmpb = lme[k]; lmd[k] = c*c*tmpa1 +s*s*tmpa2 -2.0*c*s*tmpb; lmd[k+1] = s*s*tmpa1 +c*c*tmpa2 +2.0*c*s*tmpb; lme[k] = c*s*(tmpa1-tmpa2) +(c*c-s*s)*tmpb; x = -s*lme[k+1]; lme[k+1] = c*lme[k+1]; for(int i=0; i& lmda, Vector& lmdb, int Nm2, int Nm, Vector& Qt) { int Niter = 100*Nm; int kmin = 1; int kmax = Nk; // (this should be more sophisticated) for(int iter=0; iter= kmin; --j){ RealD dds = fabs(lmd[j-1])+fabs(lmd[j]); if(fabs(lme[j-1])+dds > dds){ kmax = j+1; goto continued; } } Niter = iter; return; continued: for(int j=0; j dds){ kmin = j+1; break; } } } std::cout << "[QL method] Error - Too many iteration: "<& evec, int k) { // Schmidt orthogonalization size_t size = w.size(); assert(size%2 ==0); std::slice re(0,size/2,2); std::slice im(1,size/2,2); for(int j=0; j evr(evec[j][re]); valarray evi(evec[j][im]); w.add(re, -prdr*evr +prdi*evi); w.add(im, -prdr*evi -prdi*evr); } } void calc(Vector& lmd, Vector& evec, const Field& b, int& Nsbt, int& Nconv) { const size_t fsize = evec[0].size(); Nconv = -1; Nsbt = 0; int Nm = Nk_+Np_; std::cout << " -- Nk = " << Nk_ << " Np = "<< Np_ << endl; std::cout << " -- Nm = " << Nm << endl; std::cout << " -- size of lmd = " << lmd.size() << endl; std::cout << " -- size of evec = " << evec.size() << endl; assert(Nm < evec.size() && Nm < lmd.size()); vector lme(Nm); vector lmd2(Nm); vector lme2(Nm); vector Qt(Nm*Nm); vector Iconv(Nm); vector B(Nm); for(int k=0; ksaturated(lmd2[i],vthr)) ++Kthrs; std::cout<<"Kthrs="< 0){ // (there is a converged eigenvalue larger than Vthrs.) Nconv = iter; goto converged; } } // end of iter loop std::cout<<"\n NOT converged.\n"; abort(); converged: // Sorting lmd.clear(); evec.clear(); for(int i=0; ipush(lmd,evec,Kdis); Nsbt = Kdis - Kthrs; std::cout << "\n Converged\n Summary :\n"; std::cout << " -- Iterations = "<< Nconv << "\n"; std::cout << " -- beta(k) = "<< beta_k << "\n"; std::cout << " -- Kdis = "<< Kdis << "\n"; std::cout << " -- Nsbt = "<< Nsbt << "\n"; } }; } #endif