mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-03 21:44:33 +00:00 
			
		
		
		
	Allow real comparisons and expressions in comparisons
This commit is contained in:
		@@ -5,140 +5,197 @@ namespace Grid {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /////////////////////////////////////////
 | 
					  /////////////////////////////////////////
 | 
				
			||||||
  // This implementation is a bit poor.
 | 
					  // This implementation is a bit poor.
 | 
				
			||||||
  // Only support logical operations (== etc)
 | 
					  //
 | 
				
			||||||
  // on scalar objects. Strip any tensor structures.
 | 
					  // Only support relational logical operations (<, >  etc)
 | 
				
			||||||
 | 
					  // on scalar objects. Therefore can strip any tensor structures.
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
  // Should guard this with isGridTensor<> enable if?
 | 
					  // Should guard this with isGridTensor<> enable if?
 | 
				
			||||||
  /////////////////////////////////////////
 | 
					  /////////////////////////////////////////
 | 
				
			||||||
    // Generic list of functors
 | 
					  //
 | 
				
			||||||
    template<class lobj,class robj> class veq {
 | 
					  // Generic list of functors
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  template<class lobj,class robj> class veq {
 | 
				
			||||||
 | 
					  public:
 | 
				
			||||||
 | 
					    vInteger operator()(const lobj &lhs, const robj &rhs)
 | 
				
			||||||
 | 
					    { 
 | 
				
			||||||
 | 
					      return (lhs) == (rhs);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  template<class lobj,class robj> class vne {
 | 
				
			||||||
 | 
					  public:
 | 
				
			||||||
 | 
					    vInteger operator()(const lobj &lhs, const robj &rhs)
 | 
				
			||||||
 | 
					    { 
 | 
				
			||||||
 | 
					      return (lhs) != (rhs);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  template<class lobj,class robj> class vlt {
 | 
				
			||||||
 | 
					  public:
 | 
				
			||||||
 | 
					    vInteger operator()(const lobj &lhs, const robj &rhs)
 | 
				
			||||||
 | 
					    { 
 | 
				
			||||||
 | 
					      return (lhs) < (rhs);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  template<class lobj,class robj> class vle {
 | 
				
			||||||
 | 
					  public:
 | 
				
			||||||
 | 
					    vInteger operator()(const lobj &lhs, const robj &rhs)
 | 
				
			||||||
 | 
					    { 
 | 
				
			||||||
 | 
					      return (lhs) <= (rhs);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  template<class lobj,class robj> class vgt {
 | 
				
			||||||
 | 
					  public:
 | 
				
			||||||
 | 
					    vInteger operator()(const lobj &lhs, const robj &rhs)
 | 
				
			||||||
 | 
					    { 
 | 
				
			||||||
 | 
					      return (lhs) > (rhs);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  template<class lobj,class robj> class vge {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
      vInteger operator()(const lobj &lhs, const robj &rhs)
 | 
					    vInteger operator()(const lobj &lhs, const robj &rhs)
 | 
				
			||||||
	{ 
 | 
					    { 
 | 
				
			||||||
	  return TensorRemove(lhs) == TensorRemove(rhs);
 | 
					      return (lhs) >= (rhs);
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
    };
 | 
					  };
 | 
				
			||||||
    template<class lobj,class robj> class vne {
 | 
					  
 | 
				
			||||||
    public:
 | 
					  // Generic list of functors
 | 
				
			||||||
      vInteger operator()(const lobj &lhs, const robj &rhs)
 | 
					  template<class lobj,class robj> class seq {
 | 
				
			||||||
	{ 
 | 
					  public:
 | 
				
			||||||
	  return TensorRemove(lhs) != TensorRemove(rhs);
 | 
					    Integer operator()(const lobj &lhs, const robj &rhs)
 | 
				
			||||||
	}
 | 
					    { 
 | 
				
			||||||
    };
 | 
					      return (lhs) == (rhs);
 | 
				
			||||||
    template<class lobj,class robj> class vlt {
 | 
					    }
 | 
				
			||||||
    public:
 | 
					  };
 | 
				
			||||||
      vInteger operator()(const lobj &lhs, const robj &rhs)
 | 
					  template<class lobj,class robj> class sne {
 | 
				
			||||||
	{ 
 | 
					  public:
 | 
				
			||||||
	  return TensorRemove(lhs) < TensorRemove(rhs);
 | 
					    Integer operator()(const lobj &lhs, const robj &rhs)
 | 
				
			||||||
	}
 | 
					    { 
 | 
				
			||||||
    };
 | 
					      return (lhs) != (rhs);
 | 
				
			||||||
    template<class lobj,class robj> class vle {
 | 
					    }
 | 
				
			||||||
    public:
 | 
					  };
 | 
				
			||||||
      vInteger operator()(const lobj &lhs, const robj &rhs)
 | 
					  template<class lobj,class robj> class slt {
 | 
				
			||||||
	{ 
 | 
					  public:
 | 
				
			||||||
	  return TensorRemove(lhs) <= TensorRemove(rhs);
 | 
					    Integer operator()(const lobj &lhs, const robj &rhs)
 | 
				
			||||||
	}
 | 
					    { 
 | 
				
			||||||
    };
 | 
					      return (lhs) < (rhs);
 | 
				
			||||||
    template<class lobj,class robj> class vgt {
 | 
					    }
 | 
				
			||||||
    public:
 | 
					  };
 | 
				
			||||||
      vInteger operator()(const lobj &lhs, const robj &rhs)
 | 
					  template<class lobj,class robj> class sle {
 | 
				
			||||||
	{ 
 | 
					  public:
 | 
				
			||||||
	  return TensorRemove(lhs) > TensorRemove(rhs);
 | 
					    Integer operator()(const lobj &lhs, const robj &rhs)
 | 
				
			||||||
	}
 | 
					    { 
 | 
				
			||||||
    };
 | 
					      return (lhs) <= (rhs);
 | 
				
			||||||
    template<class lobj,class robj> class vge {
 | 
					    }
 | 
				
			||||||
    public:
 | 
					  };
 | 
				
			||||||
      vInteger operator()(const lobj &lhs, const robj &rhs)
 | 
					  template<class lobj,class robj> class sgt {
 | 
				
			||||||
	{ 
 | 
					  public:
 | 
				
			||||||
	  return TensorRemove(lhs) >= TensorRemove(rhs);
 | 
					    Integer operator()(const lobj &lhs, const robj &rhs)
 | 
				
			||||||
	}
 | 
					    { 
 | 
				
			||||||
    };
 | 
					      return (lhs) > (rhs);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  template<class lobj,class robj> class sge {
 | 
				
			||||||
 | 
					  public:
 | 
				
			||||||
 | 
					    Integer operator()(const lobj &lhs, const robj &rhs)
 | 
				
			||||||
 | 
					    { 
 | 
				
			||||||
 | 
					      return (lhs) >= (rhs);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Generic list of functors
 | 
					  //////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
    template<class lobj,class robj> class seq {
 | 
					  // Integer and real get extra relational functions.
 | 
				
			||||||
    public:
 | 
					  //////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
      Integer operator()(const lobj &lhs, const robj &rhs)
 | 
					  template<class sfunctor, class vsimd,IfNotComplex<vsimd> = 0> 
 | 
				
			||||||
	{ 
 | 
					    inline vInteger Comparison(sfunctor sop,const vsimd & lhs, const vsimd & rhs)
 | 
				
			||||||
	  return TensorRemove(lhs) == TensorRemove(rhs);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    template<class lobj,class robj> class sne {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
      Integer operator()(const lobj &lhs, const robj &rhs)
 | 
					 | 
				
			||||||
	{ 
 | 
					 | 
				
			||||||
	  return TensorRemove(lhs) != TensorRemove(rhs);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    template<class lobj,class robj> class slt {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
      Integer operator()(const lobj &lhs, const robj &rhs)
 | 
					 | 
				
			||||||
	{ 
 | 
					 | 
				
			||||||
	  return TensorRemove(lhs) < TensorRemove(rhs);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    template<class lobj,class robj> class sle {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
      Integer operator()(const lobj &lhs, const robj &rhs)
 | 
					 | 
				
			||||||
	{ 
 | 
					 | 
				
			||||||
	  return TensorRemove(lhs) <= TensorRemove(rhs);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    template<class lobj,class robj> class sgt {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
      Integer operator()(const lobj &lhs, const robj &rhs)
 | 
					 | 
				
			||||||
	{ 
 | 
					 | 
				
			||||||
	  return TensorRemove(lhs) > TensorRemove(rhs);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    template<class lobj,class robj> class sge {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
      Integer operator()(const lobj &lhs, const robj &rhs)
 | 
					 | 
				
			||||||
	{ 
 | 
					 | 
				
			||||||
	  return TensorRemove(lhs) >= TensorRemove(rhs);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
    // Integer gets extra relational functions. Could also implement these for RealF, RealD etc..
 | 
					 | 
				
			||||||
    //////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
    template<class sfunctor> 
 | 
					 | 
				
			||||||
    inline vInteger Comparison(sfunctor sop,const vInteger & lhs, const vInteger & rhs)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      std::vector<Integer> vlhs(vInteger::Nsimd());   // Use functors to reduce this to single implementation
 | 
					      typedef typename vsimd::scalar_type scalar;
 | 
				
			||||||
      std::vector<Integer> vrhs(vInteger::Nsimd());
 | 
					      std::vector<scalar> vlhs(vsimd::Nsimd());   // Use functors to reduce this to single implementation
 | 
				
			||||||
 | 
					      std::vector<scalar> vrhs(vsimd::Nsimd());
 | 
				
			||||||
 | 
					      std::vector<Integer> vpred(vsimd::Nsimd());
 | 
				
			||||||
      vInteger ret;
 | 
					      vInteger ret;
 | 
				
			||||||
      extract<vInteger,Integer>(lhs,vlhs);
 | 
					      extract<vsimd,scalar>(lhs,vlhs);
 | 
				
			||||||
      extract<vInteger,Integer>(rhs,vrhs);
 | 
					      extract<vsimd,scalar>(rhs,vrhs);
 | 
				
			||||||
      for(int s=0;s<vInteger::Nsimd();s++){
 | 
					      for(int s=0;s<vsimd::Nsimd();s++){
 | 
				
			||||||
	vlhs[s] = sop(vlhs[s],vrhs[s]);
 | 
						vpred[s] = sop(vlhs[s],vrhs[s]);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      merge<vInteger,Integer>(ret,vlhs);
 | 
					      merge<vInteger,Integer>(ret,vpred);
 | 
				
			||||||
      return ret;
 | 
					      return ret;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    inline vInteger operator < (const vInteger & lhs, const vInteger & rhs)
 | 
					
 | 
				
			||||||
 | 
					  template<class sfunctor, class vsimd,IfNotComplex<vsimd> = 0> 
 | 
				
			||||||
 | 
					    inline vInteger Comparison(sfunctor sop,const vsimd & lhs, const typename vsimd::scalar_type & rhs)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      return Comparison(slt<Integer,Integer>(),lhs,rhs);
 | 
					      typedef typename vsimd::scalar_type scalar;
 | 
				
			||||||
 | 
					      std::vector<scalar> vlhs(vsimd::Nsimd());   // Use functors to reduce this to single implementation
 | 
				
			||||||
 | 
					      std::vector<Integer> vpred(vsimd::Nsimd());
 | 
				
			||||||
 | 
					      vInteger ret;
 | 
				
			||||||
 | 
					      extract<vsimd,scalar>(lhs,vlhs);
 | 
				
			||||||
 | 
					      for(int s=0;s<vsimd::Nsimd();s++){
 | 
				
			||||||
 | 
						vpred[s] = sop(vlhs[s],rhs);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      merge<vInteger,Integer>(ret,vpred);
 | 
				
			||||||
 | 
					      return ret;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    inline vInteger operator <= (const vInteger & lhs, const vInteger & rhs)
 | 
					
 | 
				
			||||||
 | 
					  template<class sfunctor, class vsimd,IfNotComplex<vsimd> = 0> 
 | 
				
			||||||
 | 
					    inline vInteger Comparison(sfunctor sop,const typename vsimd::scalar_type & lhs, const vsimd & rhs)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      return Comparison(sle<Integer,Integer>(),lhs,rhs);
 | 
					      typedef typename vsimd::scalar_type scalar;
 | 
				
			||||||
    }
 | 
					      std::vector<scalar> vrhs(vsimd::Nsimd());   // Use functors to reduce this to single implementation
 | 
				
			||||||
    inline vInteger operator > (const vInteger & lhs, const vInteger & rhs)
 | 
					      std::vector<Integer> vpred(vsimd::Nsimd());
 | 
				
			||||||
    {
 | 
					      vInteger ret;
 | 
				
			||||||
      return Comparison(sgt<Integer,Integer>(),lhs,rhs);
 | 
					      extract<vsimd,scalar>(rhs,vrhs);
 | 
				
			||||||
    }
 | 
					      for(int s=0;s<vsimd::Nsimd();s++){
 | 
				
			||||||
    inline vInteger operator >= (const vInteger & lhs, const vInteger & rhs)
 | 
						vpred[s] = sop(lhs,vrhs[s]);
 | 
				
			||||||
    {
 | 
					      }
 | 
				
			||||||
      return Comparison(sge<Integer,Integer>(),lhs,rhs);
 | 
					      merge<vInteger,Integer>(ret,vpred);
 | 
				
			||||||
    }
 | 
					      return ret;
 | 
				
			||||||
    inline vInteger operator == (const vInteger & lhs, const vInteger & rhs)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      return Comparison(seq<Integer,Integer>(),lhs,rhs);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    inline vInteger operator != (const vInteger & lhs, const vInteger & rhs)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      return Comparison(sne<Integer,Integer>(),lhs,rhs);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DECLARE_RELATIONAL(op,functor) \
 | 
				
			||||||
 | 
					  template<class vsimd,IfSimd<vsimd> = 0>\
 | 
				
			||||||
 | 
					    inline vInteger operator op (const vsimd & lhs, const vsimd & rhs)\
 | 
				
			||||||
 | 
					    {\
 | 
				
			||||||
 | 
					      typedef typename vsimd::scalar_type scalar;\
 | 
				
			||||||
 | 
					      return Comparison(functor<scalar,scalar>(),lhs,rhs);\
 | 
				
			||||||
 | 
					    }\
 | 
				
			||||||
 | 
					  template<class vsimd,IfSimd<vsimd> = 0>\
 | 
				
			||||||
 | 
					    inline vInteger operator op (const vsimd & lhs, const typename vsimd::scalar_type & rhs) \
 | 
				
			||||||
 | 
					    {\
 | 
				
			||||||
 | 
					      typedef typename vsimd::scalar_type scalar;\
 | 
				
			||||||
 | 
					      return Comparison(functor<scalar,scalar>(),lhs,rhs);\
 | 
				
			||||||
 | 
					    }\
 | 
				
			||||||
 | 
					  template<class vsimd,IfSimd<vsimd> = 0>\
 | 
				
			||||||
 | 
					    inline vInteger operator op (const typename vsimd::scalar_type & lhs, const vsimd & rhs) \
 | 
				
			||||||
 | 
					    {\
 | 
				
			||||||
 | 
					      typedef typename vsimd::scalar_type scalar;\
 | 
				
			||||||
 | 
					      return Comparison(functor<scalar,scalar>(),lhs,rhs);\
 | 
				
			||||||
 | 
					    }\
 | 
				
			||||||
 | 
					  template<class vsimd>\
 | 
				
			||||||
 | 
					    inline vInteger operator op(const iScalar<vsimd> &lhs,const iScalar<vsimd> &rhs)\
 | 
				
			||||||
 | 
					    {									\
 | 
				
			||||||
 | 
					      return lhs._internal op rhs._internal;				\
 | 
				
			||||||
 | 
					    }									\
 | 
				
			||||||
 | 
					  template<class vsimd>\
 | 
				
			||||||
 | 
					    inline vInteger operator op(const iScalar<vsimd> &lhs,const typename vsimd::scalar_type &rhs) \
 | 
				
			||||||
 | 
					    {									\
 | 
				
			||||||
 | 
					      return lhs._internal op rhs;					\
 | 
				
			||||||
 | 
					    }									\
 | 
				
			||||||
 | 
					  template<class vsimd>\
 | 
				
			||||||
 | 
					    inline vInteger operator op(const typename vsimd::scalar_type &lhs,const iScalar<vsimd> &rhs) \
 | 
				
			||||||
 | 
					    {									\
 | 
				
			||||||
 | 
					      return lhs op rhs._internal;					\
 | 
				
			||||||
 | 
					    }									
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DECLARE_RELATIONAL(<,slt);
 | 
				
			||||||
 | 
					DECLARE_RELATIONAL(<=,sle);
 | 
				
			||||||
 | 
					DECLARE_RELATIONAL(>,sgt);
 | 
				
			||||||
 | 
					DECLARE_RELATIONAL(>=,sge);
 | 
				
			||||||
 | 
					DECLARE_RELATIONAL(==,seq);
 | 
				
			||||||
 | 
					DECLARE_RELATIONAL(!=,sne);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef DECLARE_RELATIONAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user