mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-03 21:44:33 +00:00 
			
		
		
		
	Added a test evolution for the above, Test_rhmc_EOWilsonRatioPowQuarter, demonstrating conservation of Hamiltonian Fixed HMC ignoring the MetropolisTest parameter of HMCparameters
		
			
				
	
	
		
			104 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#pragma once
 | 
						|
 | 
						|
NAMESPACE_BEGIN(Grid);
 | 
						|
 | 
						|
    template<class Field>
 | 
						|
    void HighBoundCheck(LinearOperatorBase<Field> &HermOp, 
 | 
						|
			Field &Phi,
 | 
						|
			RealD hi)
 | 
						|
    {
 | 
						|
      // Eigenvalue bound check at high end
 | 
						|
      PowerMethod<Field> power_method;
 | 
						|
      auto lambda_max = power_method(HermOp,Phi);
 | 
						|
      std::cout << GridLogMessage << "Pseudofermion action lamda_max "<<lambda_max<<"( bound "<<hi<<")"<<std::endl;
 | 
						|
      assert( (lambda_max < hi) && " High Bounds Check on operator failed" );
 | 
						|
    }
 | 
						|
      
 | 
						|
    template<class Field> void InverseSqrtBoundsCheck(int MaxIter,double tol,
 | 
						|
						       LinearOperatorBase<Field> &HermOp,
 | 
						|
						       Field &GaussNoise,
 | 
						|
						       MultiShiftFunction &PowerNegHalf) 
 | 
						|
    {
 | 
						|
      GridBase *FermionGrid = GaussNoise.Grid();
 | 
						|
 | 
						|
      Field X(FermionGrid);
 | 
						|
      Field Y(FermionGrid);
 | 
						|
      Field Z(FermionGrid);
 | 
						|
 | 
						|
      X=GaussNoise;
 | 
						|
      RealD Nx = norm2(X);
 | 
						|
 | 
						|
      ConjugateGradientMultiShift<Field> msCG(MaxIter,PowerNegHalf);
 | 
						|
      msCG(HermOp,X,Y);
 | 
						|
      msCG(HermOp,Y,Z);
 | 
						|
 | 
						|
      RealD Nz = norm2(Z);
 | 
						|
 | 
						|
      HermOp.HermOp(Z,Y);
 | 
						|
      RealD Ny = norm2(Y);
 | 
						|
 | 
						|
      X=X-Y;
 | 
						|
      RealD Nd = norm2(X);
 | 
						|
      std::cout << "************************* "<<std::endl;
 | 
						|
      std::cout << " noise                         = "<<Nx<<std::endl;
 | 
						|
      std::cout << " (MdagM^-1/2)^2  noise         = "<<Nz<<std::endl;
 | 
						|
      std::cout << " MdagM (MdagM^-1/2)^2  noise   = "<<Ny<<std::endl;
 | 
						|
      std::cout << " noise - MdagM (MdagM^-1/2)^2  noise   = "<<Nd<<std::endl;
 | 
						|
      std::cout << "************************* "<<std::endl;
 | 
						|
      assert( (std::sqrt(Nd/Nx)<tol) && " InverseSqrtBoundsCheck ");
 | 
						|
    }
 | 
						|
 | 
						|
    /* For a HermOp = M^dag M, check the approximation of  HermOp^{-1/inv_pow}
 | 
						|
       by computing   |X -    HermOp * [ Hermop^{-1/inv_pow} ]^{inv_pow} X|  < tol  
 | 
						|
       for noise X (aka GaussNoise).
 | 
						|
       ApproxNegPow should be the rational approximation for   X^{-1/inv_pow}
 | 
						|
    */
 | 
						|
    template<class Field> void InversePowerBoundsCheck(int inv_pow,
 | 
						|
						       int MaxIter,double tol,
 | 
						|
						       LinearOperatorBase<Field> &HermOp,
 | 
						|
						       Field &GaussNoise,
 | 
						|
						       MultiShiftFunction &ApproxNegPow) 
 | 
						|
    {
 | 
						|
      GridBase *FermionGrid = GaussNoise.Grid();
 | 
						|
 | 
						|
      Field X(FermionGrid);
 | 
						|
      Field Y(FermionGrid);
 | 
						|
      Field Z(FermionGrid);
 | 
						|
 | 
						|
      Field tmp1(FermionGrid), tmp2(FermionGrid);
 | 
						|
 | 
						|
      X=GaussNoise;
 | 
						|
      RealD Nx = norm2(X);
 | 
						|
 | 
						|
      ConjugateGradientMultiShift<Field> msCG(MaxIter,ApproxNegPow);
 | 
						|
 | 
						|
      tmp1 = X;
 | 
						|
      
 | 
						|
      Field* in = &tmp1;
 | 
						|
      Field* out = &tmp2;
 | 
						|
      for(int i=0;i<inv_pow;i++){ //apply  [ Hermop^{-1/inv_pow}  ]^{inv_pow} X =   HermOp^{-1} X
 | 
						|
	msCG(HermOp, *in, *out); //backwards conventions!
 | 
						|
	if(i!=inv_pow-1) std::swap(in, out);
 | 
						|
      }
 | 
						|
      Z = *out;
 | 
						|
 | 
						|
      RealD Nz = norm2(Z);
 | 
						|
 | 
						|
      HermOp.HermOp(Z,Y);
 | 
						|
      RealD Ny = norm2(Y);
 | 
						|
 | 
						|
      X=X-Y;
 | 
						|
      RealD Nd = norm2(X);
 | 
						|
      std::cout << "************************* "<<std::endl;
 | 
						|
      std::cout << " noise                         = "<<Nx<<std::endl;
 | 
						|
      std::cout << " (MdagM^-1/" << inv_pow << ")^" << inv_pow << " noise         = "<<Nz<<std::endl;
 | 
						|
      std::cout << " MdagM (MdagM^-1/" << inv_pow << ")^" << inv_pow << " noise   = "<<Ny<<std::endl;
 | 
						|
      std::cout << " noise - MdagM (MdagM^-1/" << inv_pow << ")^" << inv_pow << " noise   = "<<Nd<<std::endl;
 | 
						|
      std::cout << "************************* "<<std::endl;
 | 
						|
      assert( (std::sqrt(Nd/Nx)<tol) && " InversePowerBoundsCheck ");
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
NAMESPACE_END(Grid);
 | 
						|
 |