mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-03 21:44:33 +00:00 
			
		
		
		
	Conjugate residual algorithm; some more unary functions
This commit is contained in:
		@@ -299,6 +299,7 @@ PARALLEL_FOR_LOOP
 | 
			
		||||
#include <lattice/Lattice_reality.h>
 | 
			
		||||
#include <lattice/Lattice_coordinate.h>
 | 
			
		||||
#include <lattice/Lattice_rng.h>
 | 
			
		||||
#include <lattice/Lattice_unary.h>
 | 
			
		||||
#include <lattice/Lattice_transfer.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -25,8 +25,7 @@ PARALLEL_FOR_LOOP
 | 
			
		||||
    
 | 
			
		||||
    // localInnerProduct
 | 
			
		||||
    template<class vobj>
 | 
			
		||||
    inline auto localInnerProduct (const Lattice<vobj> &lhs,const Lattice<vobj> &rhs)
 | 
			
		||||
      -> Lattice<typename vobj::tensor_reduced>
 | 
			
		||||
    inline auto localInnerProduct (const Lattice<vobj> &lhs,const Lattice<vobj> &rhs) -> Lattice<typename vobj::tensor_reduced>
 | 
			
		||||
    {
 | 
			
		||||
      Lattice<typename vobj::tensor_reduced> ret(rhs._grid);
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
 
 | 
			
		||||
@@ -27,9 +27,9 @@ PARALLEL_FOR_LOOP
 | 
			
		||||
        return ret;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<class vobj> inline auto real(const Lattice<vobj> &z) -> Lattice<decltype(real(z._odata[0]))>
 | 
			
		||||
    template<class vobj> inline auto real(const Lattice<vobj> &z) -> Lattice<vobj>
 | 
			
		||||
    {
 | 
			
		||||
      Lattice<decltype(real(z._odata[0]))> ret(z._grid);
 | 
			
		||||
      Lattice<vobj> ret(z._grid);
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
        for(int ss=0;ss<z._grid->oSites();ss++){
 | 
			
		||||
            ret._odata[ss] = real(z._odata[ss]);
 | 
			
		||||
@@ -37,9 +37,9 @@ PARALLEL_FOR_LOOP
 | 
			
		||||
      return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class vobj> inline auto imag(const Lattice<vobj> &z) -> Lattice<decltype(imag(z._odata[0]))>
 | 
			
		||||
    template<class vobj> inline auto imag(const Lattice<vobj> &z) -> Lattice<vobj>
 | 
			
		||||
    {
 | 
			
		||||
      Lattice<decltype(imag(z._odata[0]))> ret(z._grid);
 | 
			
		||||
      Lattice<vobj> ret(z._grid);
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
        for(int ss=0;ss<z._grid->oSites();ss++){
 | 
			
		||||
            ret._odata[ss] = imag(z._odata[ss]);
 | 
			
		||||
 
 | 
			
		||||
@@ -56,10 +56,10 @@ PARALLEL_FOR_LOOP
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
template<class vobj,int nbasis>
 | 
			
		||||
inline void projectBlockBasis(Lattice<iVector<vComplex,nbasis > > &coarseData,
 | 
			
		||||
			      const             Lattice<vobj>   &fineData,
 | 
			
		||||
			      const std::vector<Lattice<vobj> > &Basis)
 | 
			
		||||
template<class vobj,class CComplex,int nbasis>
 | 
			
		||||
inline void blockProject(Lattice<iVector<CComplex,nbasis > > &coarseData,
 | 
			
		||||
			 const             Lattice<vobj>   &fineData,
 | 
			
		||||
			 const std::vector<Lattice<vobj> > &Basis)
 | 
			
		||||
{
 | 
			
		||||
  GridBase * fine  = fineData._grid;
 | 
			
		||||
  GridBase * coarse= coarseData._grid;
 | 
			
		||||
@@ -69,13 +69,14 @@ inline void projectBlockBasis(Lattice<iVector<vComplex,nbasis > > &coarseData,
 | 
			
		||||
  assert( nbasis == Basis.size() );
 | 
			
		||||
  subdivides(coarse,fine); 
 | 
			
		||||
  for(int i=0;i<nbasis;i++){
 | 
			
		||||
    conformable(Basis,fineData);
 | 
			
		||||
    conformable(Basis[i],fineData);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::vector<int>  block_r      (_ndimension);
 | 
			
		||||
  
 | 
			
		||||
  for(int d=0 ; d<_ndimension;d++){
 | 
			
		||||
    block_r[d] = fine->_rdimensions[d] / coarse->_rdimensions[d];
 | 
			
		||||
    assert(block_r[d]*coarse->_rdimensions[d] == fine->_rdimensions[d]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  coarseData=zero;
 | 
			
		||||
@@ -92,20 +93,149 @@ inline void projectBlockBasis(Lattice<iVector<vComplex,nbasis > > &coarseData,
 | 
			
		||||
 | 
			
		||||
    for(int i=0;i<nbasis;i++) {
 | 
			
		||||
      
 | 
			
		||||
      coarseData._odata[sc][i]=coarseData._odata[sc][i]
 | 
			
		||||
	+ innerProduct(Basis[i]._odata[sf],fineData._odata[sf]);
 | 
			
		||||
      coarseData._odata[sc](i)=coarseData._odata[sc](i)
 | 
			
		||||
	+ TensorRemove( innerProduct(Basis[i]._odata[sf],fineData._odata[sf]));
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class vobj,class CComplex>
 | 
			
		||||
inline void blockZAXPY(Lattice<vobj> &fineZ,
 | 
			
		||||
		       const Lattice<CComplex> &coarseA,
 | 
			
		||||
		       const Lattice<vobj> &fineX,
 | 
			
		||||
		       const Lattice<vobj> &fineY)
 | 
			
		||||
{
 | 
			
		||||
  GridBase * fine  = fineZ._grid;
 | 
			
		||||
  GridBase * coarse= coarseA._grid;
 | 
			
		||||
 | 
			
		||||
  fineZ.checkerboard=fineX.checkerboard;
 | 
			
		||||
  subdivides(coarse,fine); // require they map
 | 
			
		||||
  conformable(fineX,fineY);
 | 
			
		||||
  conformable(fineX,fineZ);
 | 
			
		||||
 | 
			
		||||
  int _ndimension = coarse->_ndimension;
 | 
			
		||||
  
 | 
			
		||||
  std::vector<int>  block_r      (_ndimension);
 | 
			
		||||
 | 
			
		||||
  // FIXME merge with subdivide checking routine as this is redundant
 | 
			
		||||
  for(int d=0 ; d<_ndimension;d++){
 | 
			
		||||
    block_r[d] = fine->_rdimensions[d] / coarse->_rdimensions[d];
 | 
			
		||||
    assert(block_r[d]*coarse->_rdimensions[d]==fine->_rdimensions[d]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
  for(int sf=0;sf<fine->oSites();sf++){
 | 
			
		||||
    
 | 
			
		||||
    int sc;
 | 
			
		||||
    std::vector<int> coor_c(_ndimension);
 | 
			
		||||
    std::vector<int> coor_f(_ndimension);
 | 
			
		||||
 | 
			
		||||
    GridBase::CoorFromIndex(coor_f,sf,fine->_rdimensions);
 | 
			
		||||
    for(int d=0;d<_ndimension;d++) coor_c[d]=coor_f[d]/block_r[d];
 | 
			
		||||
    GridBase::IndexFromCoor(coor_c,sc,coarse->_rdimensions);
 | 
			
		||||
 | 
			
		||||
    // z = A x + y
 | 
			
		||||
    fineZ._odata[sf]=coarseA._odata[sc]*fineX._odata[sf]+fineY._odata[sf];
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
template<class vobj,class CComplex>
 | 
			
		||||
  inline void blockInnerProduct(Lattice<CComplex> &CoarseInner,
 | 
			
		||||
				const Lattice<vobj> &fineX,
 | 
			
		||||
				const Lattice<vobj> &fineY)
 | 
			
		||||
{
 | 
			
		||||
  typedef decltype(innerProduct(fineX._odata[0],fineY._odata[0])) dotp;
 | 
			
		||||
 | 
			
		||||
  GridBase *coarse(CoarseInner._grid);
 | 
			
		||||
  GridBase *fine  (fineX._grid);
 | 
			
		||||
 | 
			
		||||
  Lattice<dotp> fine_inner(fine);
 | 
			
		||||
  Lattice<dotp> coarse_inner(coarse);
 | 
			
		||||
 | 
			
		||||
  fine_inner = localInnerProduct(fineX,fineY);
 | 
			
		||||
  blockSum(coarse_inner,fine_inner);
 | 
			
		||||
  for(int ss=0;ss<coarse->oSites();ss++){
 | 
			
		||||
    CoarseInner._odata[ss] = coarse_inner._odata[ss];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
template<class vobj,class CComplex>
 | 
			
		||||
inline void blockNormalise(Lattice<CComplex> &ip,Lattice<vobj> &fineX)
 | 
			
		||||
{
 | 
			
		||||
  GridBase *coarse = ip._grid;
 | 
			
		||||
  blockInnerProduct(ip,fineX,fineX);
 | 
			
		||||
  ip = rsqrt(ip);
 | 
			
		||||
  blockZAXPY(fineX,ip,fineX,fineX);
 | 
			
		||||
}
 | 
			
		||||
// useful in multigrid project;
 | 
			
		||||
// Generic name : Coarsen?
 | 
			
		||||
template<class vobj>
 | 
			
		||||
inline void blockSum(Lattice<vobj> &coarseData,const Lattice<vobj> &fineData)
 | 
			
		||||
{
 | 
			
		||||
  GridBase * fine  = fineData._grid;
 | 
			
		||||
  GridBase * coarse= coarseData._grid;
 | 
			
		||||
 | 
			
		||||
  subdivides(coarse,fine); // require they map
 | 
			
		||||
 | 
			
		||||
  int _ndimension = coarse->_ndimension;
 | 
			
		||||
  
 | 
			
		||||
  std::vector<int>  block_r      (_ndimension);
 | 
			
		||||
  
 | 
			
		||||
  for(int d=0 ; d<_ndimension;d++){
 | 
			
		||||
    block_r[d] = fine->_rdimensions[d] / coarse->_rdimensions[d];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  coarseData=zero;
 | 
			
		||||
  for(int sf=0;sf<fine->oSites();sf++){
 | 
			
		||||
    
 | 
			
		||||
    int sc;
 | 
			
		||||
    std::vector<int> coor_c(_ndimension);
 | 
			
		||||
    std::vector<int> coor_f(_ndimension);
 | 
			
		||||
 | 
			
		||||
    GridBase::CoorFromIndex(coor_f,sf,fine->_rdimensions);
 | 
			
		||||
    for(int d=0;d<_ndimension;d++) coor_c[d]=coor_f[d]/block_r[d];
 | 
			
		||||
    GridBase::IndexFromCoor(coor_c,sc,coarse->_rdimensions);
 | 
			
		||||
 | 
			
		||||
    coarseData._odata[sc]=coarseData._odata[sc]+fineData._odata[sf];
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<class vobj,int nbasis>
 | 
			
		||||
inline void promoteBlockBasis(const Lattice<iVector<vComplex,nbasis > > &coarseData,
 | 
			
		||||
			                        Lattice<vobj>   &fineData,
 | 
			
		||||
			      const std::vector<Lattice<vobj> > &Basis)
 | 
			
		||||
template<class vobj,class CComplex>
 | 
			
		||||
inline void blockOrthogonalise(Lattice<CComplex> &ip,std::vector<Lattice<vobj> > &Basis)
 | 
			
		||||
{
 | 
			
		||||
  GridBase *coarse = ip._grid;
 | 
			
		||||
  GridBase *fine   = Basis[0]._grid;
 | 
			
		||||
 | 
			
		||||
  int       nbasis = Basis.size() ;
 | 
			
		||||
  int  _ndimension = coarse->_ndimension;
 | 
			
		||||
 | 
			
		||||
  // checks
 | 
			
		||||
  subdivides(coarse,fine); 
 | 
			
		||||
  for(int i=0;i<nbasis;i++){
 | 
			
		||||
    conformable(Basis[i]._grid,fine);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for(int v=0;v<nbasis;v++) {
 | 
			
		||||
    for(int u=0;u<v;u++) {
 | 
			
		||||
      //Inner product & remove component 
 | 
			
		||||
      blockInnerProduct(ip,Basis[u],Basis[v]);
 | 
			
		||||
      ip = -ip;
 | 
			
		||||
      blockZAXPY<vobj,CComplex> (Basis[v],ip,Basis[u],Basis[v]);
 | 
			
		||||
    }
 | 
			
		||||
    blockNormalise(ip,Basis[v]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class vobj,class CComplex,int nbasis>
 | 
			
		||||
inline void blockPromote(const Lattice<iVector<CComplex,nbasis > > &coarseData,
 | 
			
		||||
			 Lattice<vobj>   &fineData,
 | 
			
		||||
			 const std::vector<Lattice<vobj> > &Basis)
 | 
			
		||||
{
 | 
			
		||||
  GridBase * fine  = fineData._grid;
 | 
			
		||||
  GridBase * coarse= coarseData._grid;
 | 
			
		||||
@@ -146,40 +276,6 @@ inline void promoteBlockBasis(const Lattice<iVector<vComplex,nbasis > > &coarseD
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// useful in multigrid project;
 | 
			
		||||
// Generic name : Coarsen?
 | 
			
		||||
template<class vobj>
 | 
			
		||||
inline void sumBlocks(Lattice<vobj> &coarseData,const Lattice<vobj> &fineData)
 | 
			
		||||
{
 | 
			
		||||
  GridBase * fine  = fineData._grid;
 | 
			
		||||
  GridBase * coarse= coarseData._grid;
 | 
			
		||||
 | 
			
		||||
  subdivides(coarse,fine); // require they map
 | 
			
		||||
 | 
			
		||||
  int _ndimension = coarse->_ndimension;
 | 
			
		||||
  
 | 
			
		||||
  std::vector<int>  block_r      (_ndimension);
 | 
			
		||||
  
 | 
			
		||||
  for(int d=0 ; d<_ndimension;d++){
 | 
			
		||||
    block_r[d] = fine->_rdimensions[d] / coarse->_rdimensions[d];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  coarseData=zero;
 | 
			
		||||
  for(int sf=0;sf<fine->oSites();sf++){
 | 
			
		||||
    
 | 
			
		||||
    int sc;
 | 
			
		||||
    std::vector<int> coor_c(_ndimension);
 | 
			
		||||
    std::vector<int> coor_f(_ndimension);
 | 
			
		||||
 | 
			
		||||
    GridBase::CoorFromIndex(coor_f,sf,fine->_rdimensions);
 | 
			
		||||
    for(int d=0;d<_ndimension;d++) coor_c[d]=coor_f[d]/block_r[d];
 | 
			
		||||
    GridBase::IndexFromCoor(coor_c,sc,coarse->_rdimensions);
 | 
			
		||||
 | 
			
		||||
    coarseData._odata[sc]=coarseData._odata[sc]+fineData._odata[sf];
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								lib/lattice/Lattice_unary.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								lib/lattice/Lattice_unary.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
#ifndef GRID_LATTICE_UNARY_H
 | 
			
		||||
#define GRID_LATTICE_UNARY_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  //////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  //  avoid copy back routines for mult, mac, sub, add
 | 
			
		||||
  //////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  template<class obj> Lattice<obj> sqrt(const Lattice<obj> &rhs){
 | 
			
		||||
    Lattice<obj> ret(rhs._grid);
 | 
			
		||||
    ret.checkerboard = rhs.checkerboard;
 | 
			
		||||
    conformable(ret,rhs);
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
    for(int ss=0;ss<rhs._grid->oSites();ss++){
 | 
			
		||||
      ret._odata[ss]=sqrt(rhs._odata[ss]);
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
  template<class obj> Lattice<obj> rsqrt(const Lattice<obj> &rhs){
 | 
			
		||||
    Lattice<obj> ret(rhs._grid);
 | 
			
		||||
    ret.checkerboard = rhs.checkerboard;
 | 
			
		||||
    conformable(ret,rhs);
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
    for(int ss=0;ss<rhs._grid->oSites();ss++){
 | 
			
		||||
      ret._odata[ss]=rsqrt(rhs._odata[ss]);
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user