/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/lattice/Lattice_comparison_utils.h Copyright (C) 2015 Author: Azusa Yamaguchi Author: Peter Boyle This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. See the full license in the file "LICENSE" in the top level distribution directory *************************************************************************************/ /* END LEGAL */ #ifndef GRID_COMPARISON_H #define GRID_COMPARISON_H namespace Grid { ///////////////////////////////////////// // This implementation is a bit poor. // // Only support relational logical operations (<, > etc) // on scalar objects. Therefore can strip any tensor structures. // // Should guard this with isGridTensor<> enable if? ///////////////////////////////////////// // // Generic list of functors // template class veq { public: vInteger operator()(const lobj &lhs, const robj &rhs) { return (lhs) == (rhs); } }; template class vne { public: vInteger operator()(const lobj &lhs, const robj &rhs) { return (lhs) != (rhs); } }; template class vlt { public: vInteger operator()(const lobj &lhs, const robj &rhs) { return (lhs) < (rhs); } }; template class vle { public: vInteger operator()(const lobj &lhs, const robj &rhs) { return (lhs) <= (rhs); } }; template class vgt { public: vInteger operator()(const lobj &lhs, const robj &rhs) { return (lhs) > (rhs); } }; template class vge { public: vInteger operator()(const lobj &lhs, const robj &rhs) { return (lhs) >= (rhs); } }; // Generic list of functors template class seq { public: Integer operator()(const lobj &lhs, const robj &rhs) { return (lhs) == (rhs); } }; template class sne { public: Integer operator()(const lobj &lhs, const robj &rhs) { return (lhs) != (rhs); } }; template class slt { public: Integer operator()(const lobj &lhs, const robj &rhs) { return (lhs) < (rhs); } }; template class sle { public: Integer operator()(const lobj &lhs, const robj &rhs) { return (lhs) <= (rhs); } }; template class sgt { public: Integer operator()(const lobj &lhs, const robj &rhs) { return (lhs) > (rhs); } }; template class sge { public: Integer operator()(const lobj &lhs, const robj &rhs) { return (lhs) >= (rhs); } }; ////////////////////////////////////////////////////////////////////////////////////////////////////// // Integer and real get extra relational functions. ////////////////////////////////////////////////////////////////////////////////////////////////////// template = 0> inline vInteger Comparison(sfunctor sop,const vsimd & lhs, const vsimd & rhs) { typedef typename vsimd::scalar_type scalar; std::vector vlhs(vsimd::Nsimd()); // Use functors to reduce this to single implementation std::vector vrhs(vsimd::Nsimd()); std::vector vpred(vsimd::Nsimd()); vInteger ret; extract(lhs,vlhs); extract(rhs,vrhs); for(int s=0;s(ret,vpred); return ret; } template = 0> inline vInteger Comparison(sfunctor sop,const vsimd & lhs, const typename vsimd::scalar_type & rhs) { typedef typename vsimd::scalar_type scalar; std::vector vlhs(vsimd::Nsimd()); // Use functors to reduce this to single implementation std::vector vpred(vsimd::Nsimd()); vInteger ret; extract(lhs,vlhs); for(int s=0;s(ret,vpred); return ret; } template = 0> inline vInteger Comparison(sfunctor sop,const typename vsimd::scalar_type & lhs, const vsimd & rhs) { typedef typename vsimd::scalar_type scalar; std::vector vrhs(vsimd::Nsimd()); // Use functors to reduce this to single implementation std::vector vpred(vsimd::Nsimd()); vInteger ret; extract(rhs,vrhs); for(int s=0;s(ret,vpred); return ret; } #define DECLARE_RELATIONAL(op,functor) \ template = 0>\ inline vInteger operator op (const vsimd & lhs, const vsimd & rhs)\ {\ typedef typename vsimd::scalar_type scalar;\ return Comparison(functor(),lhs,rhs);\ }\ template = 0>\ inline vInteger operator op (const vsimd & lhs, const typename vsimd::scalar_type & rhs) \ {\ typedef typename vsimd::scalar_type scalar;\ return Comparison(functor(),lhs,rhs);\ }\ template = 0>\ inline vInteger operator op (const typename vsimd::scalar_type & lhs, const vsimd & rhs) \ {\ typedef typename vsimd::scalar_type scalar;\ return Comparison(functor(),lhs,rhs);\ }\ template\ inline vInteger operator op(const iScalar &lhs,const iScalar &rhs)\ { \ return lhs._internal op rhs._internal; \ } \ template\ inline vInteger operator op(const iScalar &lhs,const typename vsimd::scalar_type &rhs) \ { \ return lhs._internal op rhs; \ } \ template\ inline vInteger operator op(const typename vsimd::scalar_type &lhs,const iScalar &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 } #endif