mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-04 14:04:32 +00:00 
			
		
		
		
	Tested smeared RHMC Wilson1p1, accepting
This commit is contained in:
		@@ -1,48 +1,49 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
    Source file: ./lib/lattice/Lattice_ET.h
 | 
			
		||||
Source file: ./lib/lattice/Lattice_ET.h
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: neo <cossu@post.kek.jp>
 | 
			
		||||
 | 
			
		||||
    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 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.
 | 
			
		||||
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.
 | 
			
		||||
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 */
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef GRID_LATTICE_ET_H
 | 
			
		||||
#define GRID_LATTICE_ET_H
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <tuple>
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////////////////////
 | 
			
		||||
  // Predicated where support
 | 
			
		||||
  ////////////////////////////////////////////////////
 | 
			
		||||
  template<class iobj,class vobj,class robj>
 | 
			
		||||
    inline vobj predicatedWhere(const iobj &predicate,const vobj &iftrue,const robj &iffalse) {
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////
 | 
			
		||||
// Predicated where support
 | 
			
		||||
////////////////////////////////////////////////////
 | 
			
		||||
template <class iobj, class vobj, class robj>
 | 
			
		||||
inline vobj predicatedWhere(const iobj &predicate, const vobj &iftrue,
 | 
			
		||||
                            const robj &iffalse) {
 | 
			
		||||
  typename std::remove_const<vobj>::type ret;
 | 
			
		||||
 | 
			
		||||
  typedef typename vobj::scalar_object scalar_object;
 | 
			
		||||
@@ -50,23 +51,23 @@ namespace Grid {
 | 
			
		||||
  typedef typename vobj::vector_type vector_type;
 | 
			
		||||
 | 
			
		||||
  const int Nsimd = vobj::vector_type::Nsimd();
 | 
			
		||||
    const int words = sizeof(vobj)/sizeof(vector_type);
 | 
			
		||||
  const int words = sizeof(vobj) / sizeof(vector_type);
 | 
			
		||||
 | 
			
		||||
  std::vector<Integer> mask(Nsimd);
 | 
			
		||||
    std::vector<scalar_object> truevals (Nsimd);
 | 
			
		||||
  std::vector<scalar_object> truevals(Nsimd);
 | 
			
		||||
  std::vector<scalar_object> falsevals(Nsimd);
 | 
			
		||||
 | 
			
		||||
    extract(iftrue   ,truevals);
 | 
			
		||||
    extract(iffalse  ,falsevals);
 | 
			
		||||
    extract<vInteger,Integer>(TensorRemove(predicate),mask);
 | 
			
		||||
  extract(iftrue, truevals);
 | 
			
		||||
  extract(iffalse, falsevals);
 | 
			
		||||
  extract<vInteger, Integer>(TensorRemove(predicate), mask);
 | 
			
		||||
 | 
			
		||||
    for(int s=0;s<Nsimd;s++){
 | 
			
		||||
      if (mask[s]) falsevals[s]=truevals[s];
 | 
			
		||||
  for (int s = 0; s < Nsimd; s++) {
 | 
			
		||||
    if (mask[s]) falsevals[s] = truevals[s];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    merge(ret,falsevals);
 | 
			
		||||
  merge(ret, falsevals);
 | 
			
		||||
  return ret;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////
 | 
			
		||||
// recursive evaluation of expressions; Could
 | 
			
		||||
@@ -75,192 +76,205 @@ namespace Grid {
 | 
			
		||||
// from tuple is hideous; C++14 introduces std::make_index_sequence for this
 | 
			
		||||
////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
// leaf eval of lattice ; should enable if protect using traits
 | 
			
		||||
 | 
			
		||||
//leaf eval of lattice ; should enable if protect using traits
 | 
			
		||||
template <typename T>
 | 
			
		||||
using is_lattice = std::is_base_of<LatticeBase, T>;
 | 
			
		||||
 | 
			
		||||
template <typename T> using is_lattice      = std::is_base_of<LatticeBase,T >;
 | 
			
		||||
template <typename T>
 | 
			
		||||
using is_lattice_expr = std::is_base_of<LatticeExpressionBase, T>;
 | 
			
		||||
 | 
			
		||||
template <typename T> using is_lattice_expr = std::is_base_of<LatticeExpressionBase,T >;
 | 
			
		||||
 | 
			
		||||
template<class sobj>
 | 
			
		||||
inline sobj eval(const unsigned int ss, const sobj &arg)
 | 
			
		||||
{
 | 
			
		||||
template <class sobj>
 | 
			
		||||
inline sobj eval(const unsigned int ss, const sobj &arg) {
 | 
			
		||||
  return arg;
 | 
			
		||||
}
 | 
			
		||||
template<class lobj>
 | 
			
		||||
inline const lobj &eval(const unsigned int ss, const Lattice<lobj> &arg)
 | 
			
		||||
{
 | 
			
		||||
template <class lobj>
 | 
			
		||||
inline const lobj &eval(const unsigned int ss, const Lattice<lobj> &arg) {
 | 
			
		||||
  return arg._odata[ss];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// handle nodes in syntax tree
 | 
			
		||||
template <typename Op, typename T1>
 | 
			
		||||
auto inline eval(const unsigned int ss, const LatticeUnaryExpression<Op,T1 > &expr) // eval one operand
 | 
			
		||||
  -> decltype(expr.first.func(eval(ss,std::get<0>(expr.second))))
 | 
			
		||||
{
 | 
			
		||||
  return expr.first.func(eval(ss,std::get<0>(expr.second)));
 | 
			
		||||
auto inline eval(
 | 
			
		||||
    const unsigned int ss,
 | 
			
		||||
    const LatticeUnaryExpression<Op, T1> &expr)  // eval one operand
 | 
			
		||||
    -> decltype(expr.first.func(eval(ss, std::get<0>(expr.second)))) {
 | 
			
		||||
  return expr.first.func(eval(ss, std::get<0>(expr.second)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Op, typename T1, typename T2>
 | 
			
		||||
auto inline eval(const unsigned int ss, const LatticeBinaryExpression<Op,T1,T2> &expr) // eval two operands
 | 
			
		||||
  -> decltype(expr.first.func(eval(ss,std::get<0>(expr.second)),eval(ss,std::get<1>(expr.second))))
 | 
			
		||||
{
 | 
			
		||||
  return expr.first.func(eval(ss,std::get<0>(expr.second)),eval(ss,std::get<1>(expr.second)));
 | 
			
		||||
auto inline eval(
 | 
			
		||||
    const unsigned int ss,
 | 
			
		||||
    const LatticeBinaryExpression<Op, T1, T2> &expr)  // eval two operands
 | 
			
		||||
    -> decltype(expr.first.func(eval(ss, std::get<0>(expr.second)),
 | 
			
		||||
                                eval(ss, std::get<1>(expr.second)))) {
 | 
			
		||||
  return expr.first.func(eval(ss, std::get<0>(expr.second)),
 | 
			
		||||
                         eval(ss, std::get<1>(expr.second)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Op, typename T1, typename T2, typename T3>
 | 
			
		||||
auto inline eval(const unsigned int ss, const LatticeTrinaryExpression<Op,T1,T2,T3 > &expr) // eval three operands
 | 
			
		||||
  -> decltype(expr.first.func(eval(ss,std::get<0>(expr.second)),eval(ss,std::get<1>(expr.second)),eval(ss,std::get<2>(expr.second))))
 | 
			
		||||
{
 | 
			
		||||
  return expr.first.func(eval(ss,std::get<0>(expr.second)),eval(ss,std::get<1>(expr.second)),eval(ss,std::get<2>(expr.second)) );
 | 
			
		||||
auto inline eval(const unsigned int ss,
 | 
			
		||||
                 const LatticeTrinaryExpression<Op, T1, T2, T3>
 | 
			
		||||
                     &expr)  // eval three operands
 | 
			
		||||
    -> decltype(expr.first.func(eval(ss, std::get<0>(expr.second)),
 | 
			
		||||
                                eval(ss, std::get<1>(expr.second)),
 | 
			
		||||
                                eval(ss, std::get<2>(expr.second)))) {
 | 
			
		||||
  return expr.first.func(eval(ss, std::get<0>(expr.second)),
 | 
			
		||||
                         eval(ss, std::get<1>(expr.second)),
 | 
			
		||||
                         eval(ss, std::get<2>(expr.second)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Obtain the grid from an expression, ensuring conformable. This must follow a tree recursion
 | 
			
		||||
// Obtain the grid from an expression, ensuring conformable. This must follow a
 | 
			
		||||
// tree recursion
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
template<class T1, typename std::enable_if<is_lattice<T1>::value, T1>::type * =nullptr >
 | 
			
		||||
inline void GridFromExpression(GridBase * &grid,const T1& lat)   // Lattice leaf
 | 
			
		||||
template <class T1,
 | 
			
		||||
          typename std::enable_if<is_lattice<T1>::value, T1>::type * = nullptr>
 | 
			
		||||
inline void GridFromExpression(GridBase *&grid, const T1 &lat)  // Lattice leaf
 | 
			
		||||
{
 | 
			
		||||
  if ( grid ) {
 | 
			
		||||
    conformable(grid,lat._grid);
 | 
			
		||||
  if (grid) {
 | 
			
		||||
    conformable(grid, lat._grid);
 | 
			
		||||
  }
 | 
			
		||||
  grid=lat._grid;
 | 
			
		||||
}
 | 
			
		||||
template<class T1,typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr >
 | 
			
		||||
inline void GridFromExpression(GridBase * &grid,const T1& notlat)   // non-lattice leaf
 | 
			
		||||
{
 | 
			
		||||
  grid = lat._grid;
 | 
			
		||||
}
 | 
			
		||||
template <class T1,
 | 
			
		||||
          typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr>
 | 
			
		||||
inline void GridFromExpression(GridBase *&grid,
 | 
			
		||||
                               const T1 ¬lat)  // non-lattice leaf
 | 
			
		||||
{}
 | 
			
		||||
template <typename Op, typename T1>
 | 
			
		||||
inline void GridFromExpression(GridBase * &grid,const LatticeUnaryExpression<Op,T1 > &expr)
 | 
			
		||||
{
 | 
			
		||||
  GridFromExpression(grid,std::get<0>(expr.second));// recurse 
 | 
			
		||||
inline void GridFromExpression(GridBase *&grid,
 | 
			
		||||
                               const LatticeUnaryExpression<Op, T1> &expr) {
 | 
			
		||||
  GridFromExpression(grid, std::get<0>(expr.second));  // recurse
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Op, typename T1, typename T2>
 | 
			
		||||
inline void GridFromExpression(GridBase * &grid,const LatticeBinaryExpression<Op,T1,T2> &expr) 
 | 
			
		||||
{
 | 
			
		||||
  GridFromExpression(grid,std::get<0>(expr.second));// recurse
 | 
			
		||||
  GridFromExpression(grid,std::get<1>(expr.second));
 | 
			
		||||
inline void GridFromExpression(
 | 
			
		||||
    GridBase *&grid, const LatticeBinaryExpression<Op, T1, T2> &expr) {
 | 
			
		||||
  GridFromExpression(grid, std::get<0>(expr.second));  // recurse
 | 
			
		||||
  GridFromExpression(grid, std::get<1>(expr.second));
 | 
			
		||||
}
 | 
			
		||||
template <typename Op, typename T1, typename T2, typename T3>
 | 
			
		||||
inline void GridFromExpression( GridBase * &grid,const LatticeTrinaryExpression<Op,T1,T2,T3 > &expr) 
 | 
			
		||||
{
 | 
			
		||||
  GridFromExpression(grid,std::get<0>(expr.second));// recurse
 | 
			
		||||
  GridFromExpression(grid,std::get<1>(expr.second));
 | 
			
		||||
  GridFromExpression(grid,std::get<2>(expr.second));
 | 
			
		||||
inline void GridFromExpression(
 | 
			
		||||
    GridBase *&grid, const LatticeTrinaryExpression<Op, T1, T2, T3> &expr) {
 | 
			
		||||
  GridFromExpression(grid, std::get<0>(expr.second));  // recurse
 | 
			
		||||
  GridFromExpression(grid, std::get<1>(expr.second));
 | 
			
		||||
  GridFromExpression(grid, std::get<2>(expr.second));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Obtain the CB from an expression, ensuring conformable. This must follow a tree recursion
 | 
			
		||||
// Obtain the CB from an expression, ensuring conformable. This must follow a
 | 
			
		||||
// tree recursion
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
template<class T1, typename std::enable_if<is_lattice<T1>::value, T1>::type * =nullptr >
 | 
			
		||||
inline void CBFromExpression(int &cb,const T1& lat)   // Lattice leaf
 | 
			
		||||
template <class T1,
 | 
			
		||||
          typename std::enable_if<is_lattice<T1>::value, T1>::type * = nullptr>
 | 
			
		||||
inline void CBFromExpression(int &cb, const T1 &lat)  // Lattice leaf
 | 
			
		||||
{
 | 
			
		||||
  if ( (cb==Odd) || (cb==Even) ) {
 | 
			
		||||
    assert(cb==lat.checkerboard);
 | 
			
		||||
  if ((cb == Odd) || (cb == Even)) {
 | 
			
		||||
    assert(cb == lat.checkerboard);
 | 
			
		||||
  }
 | 
			
		||||
  cb=lat.checkerboard;
 | 
			
		||||
  cb = lat.checkerboard;
 | 
			
		||||
  //  std::cout<<GridLogMessage<<"Lattice leaf cb "<<cb<<std::endl;
 | 
			
		||||
}
 | 
			
		||||
template<class T1,typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr >
 | 
			
		||||
inline void CBFromExpression(int &cb,const T1& notlat)   // non-lattice leaf
 | 
			
		||||
template <class T1,
 | 
			
		||||
          typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr>
 | 
			
		||||
inline void CBFromExpression(int &cb, const T1 ¬lat)  // non-lattice leaf
 | 
			
		||||
{
 | 
			
		||||
  //  std::cout<<GridLogMessage<<"Non lattice leaf cb"<<cb<<std::endl;
 | 
			
		||||
}
 | 
			
		||||
template <typename Op, typename T1>
 | 
			
		||||
inline void CBFromExpression(int &cb,const LatticeUnaryExpression<Op,T1 > &expr)
 | 
			
		||||
{
 | 
			
		||||
  CBFromExpression(cb,std::get<0>(expr.second));// recurse 
 | 
			
		||||
inline void CBFromExpression(int &cb,
 | 
			
		||||
                             const LatticeUnaryExpression<Op, T1> &expr) {
 | 
			
		||||
  CBFromExpression(cb, std::get<0>(expr.second));  // recurse
 | 
			
		||||
  //  std::cout<<GridLogMessage<<"Unary node cb "<<cb<<std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Op, typename T1, typename T2>
 | 
			
		||||
inline void CBFromExpression(int &cb,const LatticeBinaryExpression<Op,T1,T2> &expr) 
 | 
			
		||||
{
 | 
			
		||||
  CBFromExpression(cb,std::get<0>(expr.second));// recurse
 | 
			
		||||
  CBFromExpression(cb,std::get<1>(expr.second));
 | 
			
		||||
inline void CBFromExpression(int &cb,
 | 
			
		||||
                             const LatticeBinaryExpression<Op, T1, T2> &expr) {
 | 
			
		||||
  CBFromExpression(cb, std::get<0>(expr.second));  // recurse
 | 
			
		||||
  CBFromExpression(cb, std::get<1>(expr.second));
 | 
			
		||||
  //  std::cout<<GridLogMessage<<"Binary node cb "<<cb<<std::endl;
 | 
			
		||||
}
 | 
			
		||||
template <typename Op, typename T1, typename T2, typename T3>
 | 
			
		||||
inline void CBFromExpression( int &cb,const LatticeTrinaryExpression<Op,T1,T2,T3 > &expr) 
 | 
			
		||||
{
 | 
			
		||||
  CBFromExpression(cb,std::get<0>(expr.second));// recurse
 | 
			
		||||
  CBFromExpression(cb,std::get<1>(expr.second));
 | 
			
		||||
  CBFromExpression(cb,std::get<2>(expr.second));
 | 
			
		||||
inline void CBFromExpression(
 | 
			
		||||
    int &cb, const LatticeTrinaryExpression<Op, T1, T2, T3> &expr) {
 | 
			
		||||
  CBFromExpression(cb, std::get<0>(expr.second));  // recurse
 | 
			
		||||
  CBFromExpression(cb, std::get<1>(expr.second));
 | 
			
		||||
  CBFromExpression(cb, std::get<2>(expr.second));
 | 
			
		||||
  //  std::cout<<GridLogMessage<<"Trinary node cb "<<cb<<std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////
 | 
			
		||||
// Unary operators and funcs
 | 
			
		||||
////////////////////////////////////////////
 | 
			
		||||
#define GridUnopClass(name,ret)\
 | 
			
		||||
  template <class arg> struct name		\
 | 
			
		||||
    {								       \
 | 
			
		||||
      static auto inline func(const arg a)-> decltype(ret) { return ret; } \
 | 
			
		||||
#define GridUnopClass(name, ret)                                          \
 | 
			
		||||
  template <class arg>                                                    \
 | 
			
		||||
  struct name {                                                           \
 | 
			
		||||
    static auto inline func(const arg a) -> decltype(ret) { return ret; } \
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 GridUnopClass(UnarySub,-a);
 | 
			
		||||
 GridUnopClass(UnaryNot,Not(a));
 | 
			
		||||
 GridUnopClass(UnaryAdj,adj(a));
 | 
			
		||||
 GridUnopClass(UnaryConj,conjugate(a));
 | 
			
		||||
 GridUnopClass(UnaryTrace,trace(a));
 | 
			
		||||
 GridUnopClass(UnaryTranspose,transpose(a));
 | 
			
		||||
 GridUnopClass(UnaryTa,Ta(a));
 | 
			
		||||
 GridUnopClass(UnaryProjectOnGroup,ProjectOnGroup(a));
 | 
			
		||||
 GridUnopClass(UnaryReal,real(a));
 | 
			
		||||
 GridUnopClass(UnaryImag,imag(a));
 | 
			
		||||
 GridUnopClass(UnaryToReal,toReal(a));
 | 
			
		||||
 GridUnopClass(UnaryToComplex,toComplex(a));
 | 
			
		||||
 GridUnopClass(UnaryTimesI,timesI(a));
 | 
			
		||||
 GridUnopClass(UnaryTimesMinusI,timesMinusI(a));
 | 
			
		||||
 GridUnopClass(UnaryAbs,abs(a));
 | 
			
		||||
 GridUnopClass(UnarySqrt,sqrt(a));
 | 
			
		||||
 GridUnopClass(UnaryRsqrt,rsqrt(a));
 | 
			
		||||
 GridUnopClass(UnarySin,sin(a));
 | 
			
		||||
 GridUnopClass(UnaryCos,cos(a));
 | 
			
		||||
 GridUnopClass(UnaryAsin,asin(a));
 | 
			
		||||
 GridUnopClass(UnaryAcos,acos(a));
 | 
			
		||||
 GridUnopClass(UnaryLog,log(a));
 | 
			
		||||
 GridUnopClass(UnaryExp,exp(a));
 | 
			
		||||
GridUnopClass(UnarySub, -a);
 | 
			
		||||
GridUnopClass(UnaryNot, Not(a));
 | 
			
		||||
GridUnopClass(UnaryAdj, adj(a));
 | 
			
		||||
GridUnopClass(UnaryConj, conjugate(a));
 | 
			
		||||
GridUnopClass(UnaryTrace, trace(a));
 | 
			
		||||
GridUnopClass(UnaryTranspose, transpose(a));
 | 
			
		||||
GridUnopClass(UnaryTa, Ta(a));
 | 
			
		||||
GridUnopClass(UnaryProjectOnGroup, ProjectOnGroup(a));
 | 
			
		||||
GridUnopClass(UnaryReal, real(a));
 | 
			
		||||
GridUnopClass(UnaryImag, imag(a));
 | 
			
		||||
GridUnopClass(UnaryToReal, toReal(a));
 | 
			
		||||
GridUnopClass(UnaryToComplex, toComplex(a));
 | 
			
		||||
GridUnopClass(UnaryTimesI, timesI(a));
 | 
			
		||||
GridUnopClass(UnaryTimesMinusI, timesMinusI(a));
 | 
			
		||||
GridUnopClass(UnaryAbs, abs(a));
 | 
			
		||||
GridUnopClass(UnarySqrt, sqrt(a));
 | 
			
		||||
GridUnopClass(UnaryRsqrt, rsqrt(a));
 | 
			
		||||
GridUnopClass(UnarySin, sin(a));
 | 
			
		||||
GridUnopClass(UnaryCos, cos(a));
 | 
			
		||||
GridUnopClass(UnaryAsin, asin(a));
 | 
			
		||||
GridUnopClass(UnaryAcos, acos(a));
 | 
			
		||||
GridUnopClass(UnaryLog, log(a));
 | 
			
		||||
GridUnopClass(UnaryExp, exp(a));
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////
 | 
			
		||||
// Binary operators
 | 
			
		||||
////////////////////////////////////////////
 | 
			
		||||
#define GridBinOpClass(name,combination)\
 | 
			
		||||
template <class left,class right>\
 | 
			
		||||
struct name\
 | 
			
		||||
{\
 | 
			
		||||
  static auto inline func(const left &lhs,const right &rhs)-> decltype(combination) const \
 | 
			
		||||
    {\
 | 
			
		||||
      return combination;\
 | 
			
		||||
    }\
 | 
			
		||||
}
 | 
			
		||||
GridBinOpClass(BinaryAdd,lhs+rhs);
 | 
			
		||||
GridBinOpClass(BinarySub,lhs-rhs);
 | 
			
		||||
GridBinOpClass(BinaryMul,lhs*rhs);
 | 
			
		||||
#define GridBinOpClass(name, combination)                      \
 | 
			
		||||
  template <class left, class right>                           \
 | 
			
		||||
  struct name {                                                \
 | 
			
		||||
    static auto inline func(const left &lhs, const right &rhs) \
 | 
			
		||||
        -> decltype(combination) const {                       \
 | 
			
		||||
      return combination;                                      \
 | 
			
		||||
    }                                                          \
 | 
			
		||||
  }
 | 
			
		||||
GridBinOpClass(BinaryAdd, lhs + rhs);
 | 
			
		||||
GridBinOpClass(BinarySub, lhs - rhs);
 | 
			
		||||
GridBinOpClass(BinaryMul, lhs *rhs);
 | 
			
		||||
 | 
			
		||||
GridBinOpClass(BinaryAnd   ,lhs&rhs);
 | 
			
		||||
GridBinOpClass(BinaryOr    ,lhs|rhs);
 | 
			
		||||
GridBinOpClass(BinaryAndAnd,lhs&&rhs);
 | 
			
		||||
GridBinOpClass(BinaryOrOr  ,lhs||rhs);
 | 
			
		||||
GridBinOpClass(BinaryAnd, lhs &rhs);
 | 
			
		||||
GridBinOpClass(BinaryOr, lhs | rhs);
 | 
			
		||||
GridBinOpClass(BinaryAndAnd, lhs &&rhs);
 | 
			
		||||
GridBinOpClass(BinaryOrOr, lhs || rhs);
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////
 | 
			
		||||
// Trinary conditional op
 | 
			
		||||
////////////////////////////////////////////////////
 | 
			
		||||
#define GridTrinOpClass(name,combination)\
 | 
			
		||||
template <class predicate,class left, class right>	\
 | 
			
		||||
struct name\
 | 
			
		||||
{\
 | 
			
		||||
  static auto inline func(const predicate &pred,const left &lhs,const right &rhs)-> decltype(combination) const \
 | 
			
		||||
    {\
 | 
			
		||||
      return combination;\
 | 
			
		||||
    }\
 | 
			
		||||
}
 | 
			
		||||
#define GridTrinOpClass(name, combination)                                     \
 | 
			
		||||
  template <class predicate, class left, class right>                          \
 | 
			
		||||
  struct name {                                                                \
 | 
			
		||||
    static auto inline func(const predicate &pred, const left &lhs,            \
 | 
			
		||||
                            const right &rhs) -> decltype(combination) const { \
 | 
			
		||||
      return combination;                                                      \
 | 
			
		||||
    }                                                                          \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
GridTrinOpClass(TrinaryWhere,(predicatedWhere<predicate, \
 | 
			
		||||
			       typename std::remove_reference<left>::type, \
 | 
			
		||||
			       typename std::remove_reference<right>::type> (pred,lhs,rhs)));
 | 
			
		||||
GridTrinOpClass(
 | 
			
		||||
    TrinaryWhere,
 | 
			
		||||
    (predicatedWhere<predicate, typename std::remove_reference<left>::type,
 | 
			
		||||
                     typename std::remove_reference<right>::type>(pred, lhs,
 | 
			
		||||
                                                                  rhs)));
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////
 | 
			
		||||
// Operator syntactical glue
 | 
			
		||||
@@ -268,118 +282,136 @@ GridTrinOpClass(TrinaryWhere,(predicatedWhere<predicate, \
 | 
			
		||||
 | 
			
		||||
#define GRID_UNOP(name) name<decltype(eval(0, arg))>
 | 
			
		||||
#define GRID_BINOP(name) name<decltype(eval(0, lhs)), decltype(eval(0, rhs))>
 | 
			
		||||
#define GRID_TRINOP(name) name<decltype(eval(0, pred)), decltype(eval(0, lhs)), decltype(eval(0, rhs))>
 | 
			
		||||
#define GRID_TRINOP(name) \
 | 
			
		||||
  name<decltype(eval(0, pred)), decltype(eval(0, lhs)), decltype(eval(0, rhs))>
 | 
			
		||||
 | 
			
		||||
#define GRID_DEF_UNOP(op, name)\
 | 
			
		||||
template <typename T1,\
 | 
			
		||||
  typename std::enable_if<is_lattice<T1>::value||is_lattice_expr<T1>::value, T1>::type* = nullptr> inline auto op(const T1 &arg) \
 | 
			
		||||
  -> decltype(LatticeUnaryExpression<GRID_UNOP(name),const T1&>(std::make_pair(GRID_UNOP(name)(),std::forward_as_tuple(arg)))) \
 | 
			
		||||
{ return LatticeUnaryExpression<GRID_UNOP(name), const T1 &>(std::make_pair(GRID_UNOP(name)(),std::forward_as_tuple(arg))); }
 | 
			
		||||
#define GRID_DEF_UNOP(op, name)                                             \
 | 
			
		||||
  template <typename T1,                                                    \
 | 
			
		||||
            typename std::enable_if<is_lattice<T1>::value ||                \
 | 
			
		||||
                                        is_lattice_expr<T1>::value,         \
 | 
			
		||||
                                    T1>::type * = nullptr>                  \
 | 
			
		||||
  inline auto op(const T1 &arg)                                             \
 | 
			
		||||
      ->decltype(LatticeUnaryExpression<GRID_UNOP(name), const T1 &>(       \
 | 
			
		||||
          std::make_pair(GRID_UNOP(name)(), std::forward_as_tuple(arg)))) { \
 | 
			
		||||
    return LatticeUnaryExpression<GRID_UNOP(name), const T1 &>(             \
 | 
			
		||||
        std::make_pair(GRID_UNOP(name)(), std::forward_as_tuple(arg)));     \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#define GRID_BINOP_LEFT(op, name)\
 | 
			
		||||
template <typename T1,typename T2,\
 | 
			
		||||
          typename std::enable_if<is_lattice<T1>::value||is_lattice_expr<T1>::value, T1>::type* = nullptr>\
 | 
			
		||||
inline auto op(const T1 &lhs,const T2&rhs) \
 | 
			
		||||
  -> decltype(LatticeBinaryExpression<GRID_BINOP(name),const T1&,const T2 &>(std::make_pair(GRID_BINOP(name)(),\
 | 
			
		||||
											    std::forward_as_tuple(lhs, rhs)))) \
 | 
			
		||||
{\
 | 
			
		||||
 return LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>(std::make_pair(GRID_BINOP(name)(),\
 | 
			
		||||
									  std::forward_as_tuple(lhs, rhs))); \
 | 
			
		||||
}
 | 
			
		||||
#define GRID_BINOP_LEFT(op, name)                                             \
 | 
			
		||||
  template <typename T1, typename T2,                                         \
 | 
			
		||||
            typename std::enable_if<is_lattice<T1>::value ||                  \
 | 
			
		||||
                                        is_lattice_expr<T1>::value,           \
 | 
			
		||||
                                    T1>::type * = nullptr>                    \
 | 
			
		||||
  inline auto op(const T1 &lhs, const T2 &rhs)                                \
 | 
			
		||||
      ->decltype(                                                             \
 | 
			
		||||
          LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>(  \
 | 
			
		||||
              std::make_pair(GRID_BINOP(name)(),                              \
 | 
			
		||||
                             std::forward_as_tuple(lhs, rhs)))) {             \
 | 
			
		||||
    return LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>( \
 | 
			
		||||
        std::make_pair(GRID_BINOP(name)(), std::forward_as_tuple(lhs, rhs))); \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#define GRID_BINOP_RIGHT(op, name)\
 | 
			
		||||
 template <typename T1,typename T2,\
 | 
			
		||||
           typename std::enable_if<!is_lattice<T1>::value && !is_lattice_expr<T1>::value, T1>::type* = nullptr,\
 | 
			
		||||
           typename std::enable_if< is_lattice<T2>::value ||  is_lattice_expr<T2>::value, T2>::type* = nullptr> \
 | 
			
		||||
inline auto op(const T1 &lhs,const T2&rhs)			\
 | 
			
		||||
  -> decltype(LatticeBinaryExpression<GRID_BINOP(name),const T1&,const T2 &>(std::make_pair(GRID_BINOP(name)(),\
 | 
			
		||||
											    std::forward_as_tuple(lhs, rhs)))) \
 | 
			
		||||
{\
 | 
			
		||||
 return LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>(std::make_pair(GRID_BINOP(name)(),\
 | 
			
		||||
								          std::forward_as_tuple(lhs, rhs))); \
 | 
			
		||||
}
 | 
			
		||||
#define GRID_BINOP_RIGHT(op, name)                                            \
 | 
			
		||||
  template <typename T1, typename T2,                                         \
 | 
			
		||||
            typename std::enable_if<!is_lattice<T1>::value &&                 \
 | 
			
		||||
                                        !is_lattice_expr<T1>::value,          \
 | 
			
		||||
                                    T1>::type * = nullptr,                    \
 | 
			
		||||
            typename std::enable_if<is_lattice<T2>::value ||                  \
 | 
			
		||||
                                        is_lattice_expr<T2>::value,           \
 | 
			
		||||
                                    T2>::type * = nullptr>                    \
 | 
			
		||||
  inline auto op(const T1 &lhs, const T2 &rhs)                                \
 | 
			
		||||
      ->decltype(                                                             \
 | 
			
		||||
          LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>(  \
 | 
			
		||||
              std::make_pair(GRID_BINOP(name)(),                              \
 | 
			
		||||
                             std::forward_as_tuple(lhs, rhs)))) {             \
 | 
			
		||||
    return LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>( \
 | 
			
		||||
        std::make_pair(GRID_BINOP(name)(), std::forward_as_tuple(lhs, rhs))); \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#define GRID_DEF_BINOP(op, name)\
 | 
			
		||||
 GRID_BINOP_LEFT(op,name);\
 | 
			
		||||
 GRID_BINOP_RIGHT(op,name);
 | 
			
		||||
#define GRID_DEF_BINOP(op, name) \
 | 
			
		||||
  GRID_BINOP_LEFT(op, name);     \
 | 
			
		||||
  GRID_BINOP_RIGHT(op, name);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define GRID_DEF_TRINOP(op, name)\
 | 
			
		||||
template <typename T1,typename T2,typename T3> inline auto op(const T1 &pred,const T2&lhs,const T3 &rhs) \
 | 
			
		||||
  -> decltype(LatticeTrinaryExpression<GRID_TRINOP(name),const T1&,const T2 &,const T3&>(std::make_pair(GRID_TRINOP(name)(),\
 | 
			
		||||
										   std::forward_as_tuple(pred,lhs,rhs)))) \
 | 
			
		||||
{\
 | 
			
		||||
  return LatticeTrinaryExpression<GRID_TRINOP(name), const T1 &, const T2 &,const T3&>(std::make_pair(GRID_TRINOP(name)(), \
 | 
			
		||||
										 std::forward_as_tuple(pred,lhs, rhs))); \
 | 
			
		||||
}
 | 
			
		||||
#define GRID_DEF_TRINOP(op, name)                                              \
 | 
			
		||||
  template <typename T1, typename T2, typename T3>                             \
 | 
			
		||||
  inline auto op(const T1 &pred, const T2 &lhs, const T3 &rhs)                 \
 | 
			
		||||
      ->decltype(                                                              \
 | 
			
		||||
          LatticeTrinaryExpression<GRID_TRINOP(name), const T1 &, const T2 &,  \
 | 
			
		||||
                                   const T3 &>(std::make_pair(                 \
 | 
			
		||||
              GRID_TRINOP(name)(), std::forward_as_tuple(pred, lhs, rhs)))) {  \
 | 
			
		||||
    return LatticeTrinaryExpression<GRID_TRINOP(name), const T1 &, const T2 &, \
 | 
			
		||||
                                    const T3 &>(std::make_pair(                \
 | 
			
		||||
        GRID_TRINOP(name)(), std::forward_as_tuple(pred, lhs, rhs)));          \
 | 
			
		||||
  }
 | 
			
		||||
////////////////////////
 | 
			
		||||
//Operator definitions
 | 
			
		||||
// Operator definitions
 | 
			
		||||
////////////////////////
 | 
			
		||||
 | 
			
		||||
GRID_DEF_UNOP(operator -,UnarySub);
 | 
			
		||||
GRID_DEF_UNOP(Not,UnaryNot);
 | 
			
		||||
GRID_DEF_UNOP(operator !,UnaryNot);
 | 
			
		||||
GRID_DEF_UNOP(adj,UnaryAdj);
 | 
			
		||||
GRID_DEF_UNOP(conjugate,UnaryConj);
 | 
			
		||||
GRID_DEF_UNOP(trace,UnaryTrace);
 | 
			
		||||
GRID_DEF_UNOP(transpose,UnaryTranspose);
 | 
			
		||||
GRID_DEF_UNOP(Ta,UnaryTa);
 | 
			
		||||
GRID_DEF_UNOP(ProjectOnGroup,UnaryProjectOnGroup);
 | 
			
		||||
GRID_DEF_UNOP(real,UnaryReal);
 | 
			
		||||
GRID_DEF_UNOP(imag,UnaryImag);
 | 
			
		||||
GRID_DEF_UNOP(toReal,UnaryToReal);
 | 
			
		||||
GRID_DEF_UNOP(toComplex,UnaryToComplex);
 | 
			
		||||
GRID_DEF_UNOP(timesI,UnaryTimesI);
 | 
			
		||||
GRID_DEF_UNOP(timesMinusI,UnaryTimesMinusI);
 | 
			
		||||
GRID_DEF_UNOP(abs  ,UnaryAbs); //abs overloaded in cmath C++98; DON'T do the abs-fabs-dabs-labs thing
 | 
			
		||||
GRID_DEF_UNOP(sqrt ,UnarySqrt);
 | 
			
		||||
GRID_DEF_UNOP(rsqrt,UnaryRsqrt);
 | 
			
		||||
GRID_DEF_UNOP(sin  ,UnarySin);
 | 
			
		||||
GRID_DEF_UNOP(cos  ,UnaryCos);
 | 
			
		||||
GRID_DEF_UNOP(asin  ,UnaryAsin);
 | 
			
		||||
GRID_DEF_UNOP(acos  ,UnaryAcos);
 | 
			
		||||
GRID_DEF_UNOP(log  ,UnaryLog);
 | 
			
		||||
GRID_DEF_UNOP(exp  ,UnaryExp);
 | 
			
		||||
GRID_DEF_UNOP(operator-, UnarySub);
 | 
			
		||||
GRID_DEF_UNOP(Not, UnaryNot);
 | 
			
		||||
GRID_DEF_UNOP(operator!, UnaryNot);
 | 
			
		||||
GRID_DEF_UNOP(adj, UnaryAdj);
 | 
			
		||||
GRID_DEF_UNOP(conjugate, UnaryConj);
 | 
			
		||||
GRID_DEF_UNOP(trace, UnaryTrace);
 | 
			
		||||
GRID_DEF_UNOP(transpose, UnaryTranspose);
 | 
			
		||||
GRID_DEF_UNOP(Ta, UnaryTa);
 | 
			
		||||
GRID_DEF_UNOP(ProjectOnGroup, UnaryProjectOnGroup);
 | 
			
		||||
GRID_DEF_UNOP(real, UnaryReal);
 | 
			
		||||
GRID_DEF_UNOP(imag, UnaryImag);
 | 
			
		||||
GRID_DEF_UNOP(toReal, UnaryToReal);
 | 
			
		||||
GRID_DEF_UNOP(toComplex, UnaryToComplex);
 | 
			
		||||
GRID_DEF_UNOP(timesI, UnaryTimesI);
 | 
			
		||||
GRID_DEF_UNOP(timesMinusI, UnaryTimesMinusI);
 | 
			
		||||
GRID_DEF_UNOP(abs, UnaryAbs);  // abs overloaded in cmath C++98; DON'T do the
 | 
			
		||||
                               // abs-fabs-dabs-labs thing
 | 
			
		||||
GRID_DEF_UNOP(sqrt, UnarySqrt);
 | 
			
		||||
GRID_DEF_UNOP(rsqrt, UnaryRsqrt);
 | 
			
		||||
GRID_DEF_UNOP(sin, UnarySin);
 | 
			
		||||
GRID_DEF_UNOP(cos, UnaryCos);
 | 
			
		||||
GRID_DEF_UNOP(asin, UnaryAsin);
 | 
			
		||||
GRID_DEF_UNOP(acos, UnaryAcos);
 | 
			
		||||
GRID_DEF_UNOP(log, UnaryLog);
 | 
			
		||||
GRID_DEF_UNOP(exp, UnaryExp);
 | 
			
		||||
 | 
			
		||||
GRID_DEF_BINOP(operator+,BinaryAdd);
 | 
			
		||||
GRID_DEF_BINOP(operator-,BinarySub);
 | 
			
		||||
GRID_DEF_BINOP(operator*,BinaryMul);
 | 
			
		||||
GRID_DEF_BINOP(operator+, BinaryAdd);
 | 
			
		||||
GRID_DEF_BINOP(operator-, BinarySub);
 | 
			
		||||
GRID_DEF_BINOP(operator*, BinaryMul);
 | 
			
		||||
 | 
			
		||||
GRID_DEF_BINOP(operator&,BinaryAnd);
 | 
			
		||||
GRID_DEF_BINOP(operator|,BinaryOr);
 | 
			
		||||
GRID_DEF_BINOP(operator&&,BinaryAndAnd);
 | 
			
		||||
GRID_DEF_BINOP(operator||,BinaryOrOr);
 | 
			
		||||
GRID_DEF_BINOP(operator&, BinaryAnd);
 | 
			
		||||
GRID_DEF_BINOP(operator|, BinaryOr);
 | 
			
		||||
GRID_DEF_BINOP(operator&&, BinaryAndAnd);
 | 
			
		||||
GRID_DEF_BINOP(operator||, BinaryOrOr);
 | 
			
		||||
 | 
			
		||||
GRID_DEF_TRINOP(where,TrinaryWhere);
 | 
			
		||||
GRID_DEF_TRINOP(where, TrinaryWhere);
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////
 | 
			
		||||
// Closure convenience to force expression to evaluate
 | 
			
		||||
/////////////////////////////////////////////////////////////
 | 
			
		||||
template<class Op,class T1>
 | 
			
		||||
  auto closure(const LatticeUnaryExpression<Op,T1> & expr)
 | 
			
		||||
  -> Lattice<decltype(expr.first.func(eval(0,std::get<0>(expr.second))))>
 | 
			
		||||
{
 | 
			
		||||
  Lattice<decltype(expr.first.func(eval(0,std::get<0>(expr.second))))> ret(expr);
 | 
			
		||||
template <class Op, class T1>
 | 
			
		||||
auto closure(const LatticeUnaryExpression<Op, T1> &expr)
 | 
			
		||||
    -> Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second))))> {
 | 
			
		||||
  Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second))))> ret(
 | 
			
		||||
      expr);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
template<class Op,class T1, class T2>
 | 
			
		||||
  auto closure(const LatticeBinaryExpression<Op,T1,T2> & expr)
 | 
			
		||||
  -> Lattice<decltype(expr.first.func(eval(0,std::get<0>(expr.second)),
 | 
			
		||||
				      eval(0,std::get<1>(expr.second))))>
 | 
			
		||||
{
 | 
			
		||||
  Lattice<decltype(expr.first.func(eval(0,std::get<0>(expr.second)),
 | 
			
		||||
				   eval(0,std::get<1>(expr.second))))> ret(expr);
 | 
			
		||||
template <class Op, class T1, class T2>
 | 
			
		||||
auto closure(const LatticeBinaryExpression<Op, T1, T2> &expr)
 | 
			
		||||
    -> Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
 | 
			
		||||
                                        eval(0, std::get<1>(expr.second))))> {
 | 
			
		||||
  Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
 | 
			
		||||
                                   eval(0, std::get<1>(expr.second))))>
 | 
			
		||||
      ret(expr);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
template<class Op,class T1, class T2, class T3>
 | 
			
		||||
  auto closure(const LatticeTrinaryExpression<Op,T1,T2,T3> & expr)
 | 
			
		||||
  -> Lattice<decltype(expr.first.func(eval(0,std::get<0>(expr.second)),
 | 
			
		||||
				      eval(0,std::get<1>(expr.second)),
 | 
			
		||||
				      eval(0,std::get<2>(expr.second))))>
 | 
			
		||||
{
 | 
			
		||||
  Lattice<decltype(expr.first.func(eval(0,std::get<0>(expr.second)),
 | 
			
		||||
				   eval(0,std::get<1>(expr.second)),
 | 
			
		||||
				   eval(0,std::get<2>(expr.second))))> ret(expr);
 | 
			
		||||
template <class Op, class T1, class T2, class T3>
 | 
			
		||||
auto closure(const LatticeTrinaryExpression<Op, T1, T2, T3> &expr)
 | 
			
		||||
    -> Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
 | 
			
		||||
                                        eval(0, std::get<1>(expr.second)),
 | 
			
		||||
                                        eval(0, std::get<2>(expr.second))))> {
 | 
			
		||||
  Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
 | 
			
		||||
                                   eval(0, std::get<1>(expr.second)),
 | 
			
		||||
                                   eval(0, std::get<2>(expr.second))))>
 | 
			
		||||
      ret(expr);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -390,7 +422,6 @@ template<class Op,class T1, class T2, class T3>
 | 
			
		||||
#undef GRID_DEF_UNOP
 | 
			
		||||
#undef GRID_DEF_BINOP
 | 
			
		||||
#undef GRID_DEF_TRINOP
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
 
 | 
			
		||||
@@ -1,95 +1,96 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
    Source file: ./lib/qcd/action/pseudofermion/OneFlavourEvenOddRational.h
 | 
			
		||||
Source file: ./lib/qcd/action/pseudofermion/OneFlavourEvenOddRational.h
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
    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 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.
 | 
			
		||||
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.
 | 
			
		||||
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 */
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef QCD_PSEUDOFERMION_ONE_FLAVOUR_EVEN_ODD_RATIONAL_H
 | 
			
		||||
#define QCD_PSEUDOFERMION_ONE_FLAVOUR_EVEN_ODD_RATIONAL_H
 | 
			
		||||
 | 
			
		||||
namespace Grid{
 | 
			
		||||
  namespace QCD{
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
    ///////////////////////////////////////
 | 
			
		||||
    // One flavour rational
 | 
			
		||||
    ///////////////////////////////////////
 | 
			
		||||
///////////////////////////////////////
 | 
			
		||||
// One flavour rational
 | 
			
		||||
///////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    // S_f = chi^dag *  N(Mpc^dag*Mpc)/D(Mpc^dag*Mpc) * chi
 | 
			
		||||
    //
 | 
			
		||||
    // Here, M is some operator 
 | 
			
		||||
    // N and D makeup the rat. poly 
 | 
			
		||||
    //
 | 
			
		||||
// S_f = chi^dag *  N(Mpc^dag*Mpc)/D(Mpc^dag*Mpc) * chi
 | 
			
		||||
//
 | 
			
		||||
// Here, M is some operator
 | 
			
		||||
// N and D makeup the rat. poly
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
    template<class Impl>
 | 
			
		||||
    class OneFlavourEvenOddRationalPseudoFermionAction : public Action<typename Impl::GaugeField> {
 | 
			
		||||
template <class Impl>
 | 
			
		||||
class OneFlavourEvenOddRationalPseudoFermionAction
 | 
			
		||||
    : public Action<typename Impl::GaugeField> {
 | 
			
		||||
 public:
 | 
			
		||||
  INHERIT_IMPL_TYPES(Impl);
 | 
			
		||||
 | 
			
		||||
  typedef OneFlavourRationalParams Params;
 | 
			
		||||
  Params param;
 | 
			
		||||
 | 
			
		||||
      MultiShiftFunction PowerHalf   ;
 | 
			
		||||
  MultiShiftFunction PowerHalf;
 | 
			
		||||
  MultiShiftFunction PowerNegHalf;
 | 
			
		||||
  MultiShiftFunction PowerQuarter;
 | 
			
		||||
  MultiShiftFunction PowerNegQuarter;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  FermionOperator<Impl> &FermOp;  // the basic operator
 | 
			
		||||
 | 
			
		||||
      FermionOperator<Impl> & FermOp;// the basic operator
 | 
			
		||||
 | 
			
		||||
      // NOT using "Nroots"; IroIro is -- perhaps later, but this wasn't good for us historically
 | 
			
		||||
  // NOT using "Nroots"; IroIro is -- perhaps later, but this wasn't good for us
 | 
			
		||||
  // historically
 | 
			
		||||
  // and hasenbusch works better
 | 
			
		||||
 | 
			
		||||
  FermionField PhiEven;  // the pseudo fermion field for this trajectory
 | 
			
		||||
  FermionField PhiOdd;   // the pseudo fermion field for this trajectory
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
 | 
			
		||||
  OneFlavourEvenOddRationalPseudoFermionAction(FermionOperator<Impl> &Op,
 | 
			
		||||
						   Params & p ) : FermOp(Op), 
 | 
			
		||||
                                               Params &p)
 | 
			
		||||
      : FermOp(Op),
 | 
			
		||||
        PhiEven(Op.FermionRedBlackGrid()),
 | 
			
		||||
	PhiOdd (Op.FermionRedBlackGrid()), 
 | 
			
		||||
	param(p) 
 | 
			
		||||
      {
 | 
			
		||||
	AlgRemez remez(param.lo,param.hi,param.precision);
 | 
			
		||||
        PhiOdd(Op.FermionRedBlackGrid()),
 | 
			
		||||
        param(p) {
 | 
			
		||||
    AlgRemez remez(param.lo, param.hi, param.precision);
 | 
			
		||||
 | 
			
		||||
    // MdagM^(+- 1/2)
 | 
			
		||||
	std::cout<<GridLogMessage << "Generating degree "<<param.degree<<" for x^(1/2)"<<std::endl;
 | 
			
		||||
	remez.generateApprox(param.degree,1,2);
 | 
			
		||||
	PowerHalf.Init(remez,param.tolerance,false);
 | 
			
		||||
	PowerNegHalf.Init(remez,param.tolerance,true);
 | 
			
		||||
    std::cout << GridLogMessage << "Generating degree " << param.degree
 | 
			
		||||
              << " for x^(1/2)" << std::endl;
 | 
			
		||||
    remez.generateApprox(param.degree, 1, 2);
 | 
			
		||||
    PowerHalf.Init(remez, param.tolerance, false);
 | 
			
		||||
    PowerNegHalf.Init(remez, param.tolerance, true);
 | 
			
		||||
 | 
			
		||||
    // MdagM^(+- 1/4)
 | 
			
		||||
	std::cout<<GridLogMessage << "Generating degree "<<param.degree<<" for x^(1/4)"<<std::endl;
 | 
			
		||||
	remez.generateApprox(param.degree,1,4);
 | 
			
		||||
   	PowerQuarter.Init(remez,param.tolerance,false);
 | 
			
		||||
	PowerNegQuarter.Init(remez,param.tolerance,true);
 | 
			
		||||
    std::cout << GridLogMessage << "Generating degree " << param.degree
 | 
			
		||||
              << " for x^(1/4)" << std::endl;
 | 
			
		||||
    remez.generateApprox(param.degree, 1, 4);
 | 
			
		||||
    PowerQuarter.Init(remez, param.tolerance, false);
 | 
			
		||||
    PowerNegQuarter.Init(remez, param.tolerance, true);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
      virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) {
 | 
			
		||||
 | 
			
		||||
  virtual void refresh(const GaugeField &U, GridParallelRNG &pRNG) {
 | 
			
		||||
    // P(phi) = e^{- phi^dag (MpcdagMpc)^-1/2 phi}
 | 
			
		||||
    //        = e^{- phi^dag (MpcdagMpc)^-1/4 (MpcdagMpc)^-1/4 phi}
 | 
			
		||||
    // Phi = MpcdagMpc^{1/4} eta
 | 
			
		||||
@@ -102,21 +103,22 @@ namespace Grid{
 | 
			
		||||
 | 
			
		||||
    RealD scale = std::sqrt(0.5);
 | 
			
		||||
 | 
			
		||||
	FermionField eta    (FermOp.FermionGrid());
 | 
			
		||||
	FermionField etaOdd (FermOp.FermionRedBlackGrid());
 | 
			
		||||
    FermionField eta(FermOp.FermionGrid());
 | 
			
		||||
    FermionField etaOdd(FermOp.FermionRedBlackGrid());
 | 
			
		||||
    FermionField etaEven(FermOp.FermionRedBlackGrid());
 | 
			
		||||
 | 
			
		||||
	gaussian(pRNG,eta);	eta=eta*scale;
 | 
			
		||||
    gaussian(pRNG, eta);
 | 
			
		||||
    eta = eta * scale;
 | 
			
		||||
 | 
			
		||||
	pickCheckerboard(Even,etaEven,eta);
 | 
			
		||||
	pickCheckerboard(Odd,etaOdd,eta);
 | 
			
		||||
    pickCheckerboard(Even, etaEven, eta);
 | 
			
		||||
    pickCheckerboard(Odd, etaOdd, eta);
 | 
			
		||||
 | 
			
		||||
    FermOp.ImportGauge(U);
 | 
			
		||||
 | 
			
		||||
    // mutishift CG
 | 
			
		||||
    SchurDifferentiableOperator<Impl> Mpc(FermOp);
 | 
			
		||||
	ConjugateGradientMultiShift<FermionField> msCG(param.MaxIter,PowerQuarter);
 | 
			
		||||
	msCG(Mpc,etaOdd,PhiOdd);
 | 
			
		||||
    ConjugateGradientMultiShift<FermionField> msCG(param.MaxIter, PowerQuarter);
 | 
			
		||||
    msCG(Mpc, etaOdd, PhiOdd);
 | 
			
		||||
 | 
			
		||||
    //////////////////////////////////////////////////////
 | 
			
		||||
    // FIXME : Clover term not yet..
 | 
			
		||||
@@ -124,26 +126,27 @@ namespace Grid{
 | 
			
		||||
 | 
			
		||||
    assert(FermOp.ConstEE() == 1);
 | 
			
		||||
    PhiEven = zero;
 | 
			
		||||
	
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  //////////////////////////////////////////////////////
 | 
			
		||||
  // S = phi^dag (Mdag M)^-1/2 phi
 | 
			
		||||
  //////////////////////////////////////////////////////
 | 
			
		||||
  virtual RealD S(const GaugeField &U) {
 | 
			
		||||
 | 
			
		||||
    FermOp.ImportGauge(U);
 | 
			
		||||
 | 
			
		||||
    FermionField Y(FermOp.FermionRedBlackGrid());
 | 
			
		||||
 | 
			
		||||
    SchurDifferentiableOperator<Impl> Mpc(FermOp);
 | 
			
		||||
 | 
			
		||||
	ConjugateGradientMultiShift<FermionField> msCG(param.MaxIter,PowerNegQuarter);
 | 
			
		||||
    ConjugateGradientMultiShift<FermionField> msCG(param.MaxIter,
 | 
			
		||||
                                                   PowerNegQuarter);
 | 
			
		||||
 | 
			
		||||
	msCG(Mpc,PhiOdd,Y);
 | 
			
		||||
    msCG(Mpc, PhiOdd, Y);
 | 
			
		||||
 | 
			
		||||
    RealD action = norm2(Y);
 | 
			
		||||
	std::cout << GridLogMessage << "Pseudofermion action FIXME -- is -1/4 solve or -1/2 solve faster??? "<<action<<std::endl;
 | 
			
		||||
    std::cout << GridLogMessage << "Pseudofermion action FIXME -- is -1/4 "
 | 
			
		||||
                                   "solve or -1/2 solve faster??? "
 | 
			
		||||
              << action << std::endl;
 | 
			
		||||
 | 
			
		||||
    return action;
 | 
			
		||||
  };
 | 
			
		||||
@@ -158,7 +161,8 @@ namespace Grid{
 | 
			
		||||
  //
 | 
			
		||||
  // d[N/D] is then
 | 
			
		||||
  //
 | 
			
		||||
      //          \sum_k -ak [M^dagM+bk]^{-1}  [ dM^dag M + M^dag dM ] [M^dag M + bk]^{-1}
 | 
			
		||||
  //          \sum_k -ak [M^dagM+bk]^{-1}  [ dM^dag M + M^dag dM ] [M^dag M +
 | 
			
		||||
  //          bk]^{-1}
 | 
			
		||||
  //
 | 
			
		||||
  // Need
 | 
			
		||||
  //       Mf Phi_k = [MdagM+bk]^{-1} Phi
 | 
			
		||||
@@ -166,14 +170,14 @@ namespace Grid{
 | 
			
		||||
  //
 | 
			
		||||
  // With these building blocks
 | 
			
		||||
  //
 | 
			
		||||
      //       dS/dU =  \sum_k -ak Mf Phi_k^dag      [ dM^dag M + M^dag dM ] Mf Phi_k
 | 
			
		||||
  //       dS/dU =  \sum_k -ak Mf Phi_k^dag      [ dM^dag M + M^dag dM ] Mf
 | 
			
		||||
  //       Phi_k
 | 
			
		||||
  //        S    = innerprodReal(Phi,Mf Phi);
 | 
			
		||||
  //////////////////////////////////////////////////////
 | 
			
		||||
      virtual void deriv(const GaugeField &U,GaugeField & dSdU) {
 | 
			
		||||
 | 
			
		||||
  virtual void deriv(const GaugeField &U, GaugeField &dSdU) {
 | 
			
		||||
    const int Npole = PowerNegHalf.poles.size();
 | 
			
		||||
 | 
			
		||||
	std::vector<FermionField> MPhi_k (Npole,FermOp.FermionRedBlackGrid());
 | 
			
		||||
    std::vector<FermionField> MPhi_k(Npole, FermOp.FermionRedBlackGrid());
 | 
			
		||||
 | 
			
		||||
    FermionField X(FermOp.FermionRedBlackGrid());
 | 
			
		||||
    FermionField Y(FermOp.FermionRedBlackGrid());
 | 
			
		||||
@@ -184,29 +188,27 @@ namespace Grid{
 | 
			
		||||
 | 
			
		||||
    SchurDifferentiableOperator<Impl> Mpc(FermOp);
 | 
			
		||||
 | 
			
		||||
	ConjugateGradientMultiShift<FermionField> msCG(param.MaxIter,PowerNegHalf);
 | 
			
		||||
    ConjugateGradientMultiShift<FermionField> msCG(param.MaxIter, PowerNegHalf);
 | 
			
		||||
 | 
			
		||||
	msCG(Mpc,PhiOdd,MPhi_k);
 | 
			
		||||
    msCG(Mpc, PhiOdd, MPhi_k);
 | 
			
		||||
 | 
			
		||||
    dSdU = zero;
 | 
			
		||||
	for(int k=0;k<Npole;k++){
 | 
			
		||||
 | 
			
		||||
    for (int k = 0; k < Npole; k++) {
 | 
			
		||||
      RealD ak = PowerNegHalf.residues[k];
 | 
			
		||||
 | 
			
		||||
      X = MPhi_k[k];
 | 
			
		||||
 | 
			
		||||
	  Mpc.Mpc(X,Y);
 | 
			
		||||
	  Mpc.MpcDeriv   (tmp , Y, X );  dSdU=dSdU+ak*tmp;
 | 
			
		||||
	  Mpc.MpcDagDeriv(tmp , X, Y );  dSdU=dSdU+ak*tmp;
 | 
			
		||||
 | 
			
		||||
      Mpc.Mpc(X, Y);
 | 
			
		||||
      Mpc.MpcDeriv(tmp, Y, X);
 | 
			
		||||
      dSdU = dSdU + ak * tmp;
 | 
			
		||||
      Mpc.MpcDagDeriv(tmp, X, Y);
 | 
			
		||||
      dSdU = dSdU + ak * tmp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	//dSdU = Ta(dSdU);
 | 
			
		||||
 | 
			
		||||
    // dSdU = Ta(dSdU);
 | 
			
		||||
  };
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +1,32 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
    Source file: ./lib/tensors/Tensor_class.h
 | 
			
		||||
Source file: ./lib/tensors/Tensor_class.h
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
    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 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.
 | 
			
		||||
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.
 | 
			
		||||
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 */
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef GRID_MATH_TENSORS_H
 | 
			
		||||
#define GRID_MATH_TENSORS_H
 | 
			
		||||
 | 
			
		||||
@@ -38,7 +39,8 @@ namespace Grid {
 | 
			
		||||
 | 
			
		||||
// It is useful to NOT have any constructors
 | 
			
		||||
// so that these classes assert "is_pod<class> == true"
 | 
			
		||||
// because then the standard C++ valarray container eliminates fill overhead on new allocation and 
 | 
			
		||||
// because then the standard C++ valarray container eliminates fill overhead on
 | 
			
		||||
// new allocation and
 | 
			
		||||
// non-move copying.
 | 
			
		||||
//
 | 
			
		||||
// However note that doing this eliminates some syntactical sugar such as
 | 
			
		||||
@@ -46,9 +48,9 @@ namespace Grid {
 | 
			
		||||
//
 | 
			
		||||
class GridTensorBase {};
 | 
			
		||||
 | 
			
		||||
template<class vtype> class iScalar 
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
template <class vtype>
 | 
			
		||||
class iScalar {
 | 
			
		||||
 public:
 | 
			
		||||
  vtype _internal;
 | 
			
		||||
 | 
			
		||||
  typedef vtype element;
 | 
			
		||||
@@ -60,13 +62,14 @@ public:
 | 
			
		||||
  typedef iScalar<recurse_scalar_object> scalar_object;
 | 
			
		||||
 | 
			
		||||
  // substitutes a real or complex version with same tensor structure
 | 
			
		||||
  typedef iScalar<typename GridTypeMapper<vtype>::Complexified > Complexified;
 | 
			
		||||
  typedef iScalar<typename GridTypeMapper<vtype>::Realified >    Realified;
 | 
			
		||||
  typedef iScalar<typename GridTypeMapper<vtype>::Complexified> Complexified;
 | 
			
		||||
  typedef iScalar<typename GridTypeMapper<vtype>::Realified> Realified;
 | 
			
		||||
 | 
			
		||||
  enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1};
 | 
			
		||||
  enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1 };
 | 
			
		||||
 | 
			
		||||
  // Scalar no action
 | 
			
		||||
  //  template<int Level> using tensor_reduce_level = typename iScalar<GridTypeMapper<vtype>::tensor_reduce_level<Level> >;
 | 
			
		||||
  //  template<int Level> using tensor_reduce_level = typename
 | 
			
		||||
  //  iScalar<GridTypeMapper<vtype>::tensor_reduce_level<Level> >;
 | 
			
		||||
  iScalar() = default;
 | 
			
		||||
  /*
 | 
			
		||||
  iScalar(const iScalar<vtype> ©me)=default;
 | 
			
		||||
@@ -74,83 +77,106 @@ public:
 | 
			
		||||
  iScalar<vtype> & operator= (const iScalar<vtype> ©me) = default;
 | 
			
		||||
  iScalar<vtype> & operator= (iScalar<vtype> &©me) = default;
 | 
			
		||||
  */
 | 
			
		||||
  iScalar(scalar_type s) : _internal(s) {};// recurse down and hit the constructor for vector_type
 | 
			
		||||
  iScalar(const Zero &z){ *this = zero; };
 | 
			
		||||
  iScalar(scalar_type s)
 | 
			
		||||
      : _internal(s){};  // recurse down and hit the constructor for vector_type
 | 
			
		||||
  iScalar(const Zero &z) { *this = zero; };
 | 
			
		||||
 | 
			
		||||
  iScalar<vtype> & operator= (const Zero &hero){
 | 
			
		||||
  iScalar<vtype> &operator=(const Zero &hero) {
 | 
			
		||||
    zeroit(*this);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void vstream(iScalar<vtype> &out,const iScalar<vtype> &in){
 | 
			
		||||
    vstream(out._internal,in._internal);
 | 
			
		||||
  friend strong_inline void vstream(iScalar<vtype> &out,
 | 
			
		||||
                                    const iScalar<vtype> &in) {
 | 
			
		||||
    vstream(out._internal, in._internal);
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void zeroit(iScalar<vtype> &that){
 | 
			
		||||
  friend strong_inline void zeroit(iScalar<vtype> &that) {
 | 
			
		||||
    zeroit(that._internal);
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void prefetch(iScalar<vtype> &that){
 | 
			
		||||
  friend strong_inline void prefetch(iScalar<vtype> &that) {
 | 
			
		||||
    prefetch(that._internal);
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void permute(iScalar<vtype> &out,const iScalar<vtype> &in,int permutetype){
 | 
			
		||||
    permute(out._internal,in._internal,permutetype);
 | 
			
		||||
  friend strong_inline void permute(iScalar<vtype> &out,
 | 
			
		||||
                                    const iScalar<vtype> &in, int permutetype) {
 | 
			
		||||
    permute(out._internal, in._internal, permutetype);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Unary negation
 | 
			
		||||
  friend strong_inline iScalar<vtype> operator -(const iScalar<vtype> &r) {
 | 
			
		||||
  friend strong_inline iScalar<vtype> operator-(const iScalar<vtype> &r) {
 | 
			
		||||
    iScalar<vtype> ret;
 | 
			
		||||
    ret._internal= -r._internal;
 | 
			
		||||
    ret._internal = -r._internal;
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
  // *=,+=,-= operators inherit from corresponding "*,-,+" behaviour
 | 
			
		||||
  strong_inline iScalar<vtype> &operator *=(const iScalar<vtype> &r) {
 | 
			
		||||
    *this = (*this)*r;
 | 
			
		||||
  strong_inline iScalar<vtype> &operator*=(const iScalar<vtype> &r) {
 | 
			
		||||
    *this = (*this) * r;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline iScalar<vtype> &operator -=(const iScalar<vtype> &r) {
 | 
			
		||||
    *this = (*this)-r;
 | 
			
		||||
  strong_inline iScalar<vtype> &operator-=(const iScalar<vtype> &r) {
 | 
			
		||||
    *this = (*this) - r;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline iScalar<vtype> &operator +=(const iScalar<vtype> &r) {
 | 
			
		||||
    *this = (*this)+r;
 | 
			
		||||
  strong_inline iScalar<vtype> &operator+=(const iScalar<vtype> &r) {
 | 
			
		||||
    *this = (*this) + r;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline vtype & operator ()(void) {
 | 
			
		||||
    return _internal;
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline const vtype & operator ()(void) const {
 | 
			
		||||
    return _internal;
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline vtype &operator()(void) { return _internal; }
 | 
			
		||||
  strong_inline const vtype &operator()(void) const { return _internal; }
 | 
			
		||||
 | 
			
		||||
  // Type casts meta programmed, must be pure scalar to match TensorRemove
 | 
			
		||||
  template<class U=vtype,class V=scalar_type,IfComplex<V> = 0,IfNotSimd<U> = 0> operator ComplexF () const { return(TensorRemove(_internal)); };
 | 
			
		||||
  template<class U=vtype,class V=scalar_type,IfComplex<V> = 0,IfNotSimd<U> = 0> operator ComplexD () const { return(TensorRemove(_internal)); };
 | 
			
		||||
  //  template<class U=vtype,class V=scalar_type,IfComplex<V> = 0,IfNotSimd<U> = 0> operator RealD    () const { return(real(TensorRemove(_internal))); }
 | 
			
		||||
  template<class U=vtype,class V=scalar_type,IfReal<V>    = 0,IfNotSimd<U> = 0> operator RealD    () const { return TensorRemove(_internal); }
 | 
			
		||||
  template<class U=vtype,class V=scalar_type,IfInteger<V> = 0,IfNotSimd<U> = 0> operator Integer  () const { return Integer(TensorRemove(_internal)); }
 | 
			
		||||
  template <class U = vtype, class V = scalar_type, IfComplex<V> = 0,
 | 
			
		||||
            IfNotSimd<U> = 0>
 | 
			
		||||
  operator ComplexF() const {
 | 
			
		||||
    return (TensorRemove(_internal));
 | 
			
		||||
  };
 | 
			
		||||
  template <class U = vtype, class V = scalar_type, IfComplex<V> = 0,
 | 
			
		||||
            IfNotSimd<U> = 0>
 | 
			
		||||
  operator ComplexD() const {
 | 
			
		||||
    return (TensorRemove(_internal));
 | 
			
		||||
  };
 | 
			
		||||
  //  template<class U=vtype,class V=scalar_type,IfComplex<V> = 0,IfNotSimd<U> =
 | 
			
		||||
  //  0> operator RealD    () const { return(real(TensorRemove(_internal))); }
 | 
			
		||||
  template <class U = vtype, class V = scalar_type, IfReal<V> = 0,
 | 
			
		||||
            IfNotSimd<U> = 0>
 | 
			
		||||
  operator RealD() const {
 | 
			
		||||
    return TensorRemove(_internal);
 | 
			
		||||
  }
 | 
			
		||||
  template <class U = vtype, class V = scalar_type, IfInteger<V> = 0,
 | 
			
		||||
            IfNotSimd<U> = 0>
 | 
			
		||||
  operator Integer() const {
 | 
			
		||||
    return Integer(TensorRemove(_internal));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // convert from a something to a scalar via constructor of something arg
 | 
			
		||||
  template<class T,typename std::enable_if<!isGridTensor<T>::value, T>::type* = nullptr > strong_inline iScalar<vtype> operator = (T arg)
 | 
			
		||||
    { 
 | 
			
		||||
  template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type
 | 
			
		||||
                         * = nullptr>
 | 
			
		||||
  strong_inline iScalar<vtype> operator=(T arg) {
 | 
			
		||||
    _internal = arg;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    friend std::ostream& operator<< (std::ostream& stream, const iScalar<vtype> &o){
 | 
			
		||||
      stream<< "S {"<<o._internal<<"}";
 | 
			
		||||
  friend std::ostream &operator<<(std::ostream &stream,
 | 
			
		||||
                                  const iScalar<vtype> &o) {
 | 
			
		||||
    stream << "S {" << o._internal << "}";
 | 
			
		||||
    return stream;
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
// Allows to turn scalar<scalar<scalar<double>>>> back to double.
 | 
			
		||||
///////////////////////////////////////////////////////////
 | 
			
		||||
template<class T>     strong_inline typename std::enable_if<!isGridTensor<T>::value, T>::type TensorRemove(T arg) { return arg;}
 | 
			
		||||
template<class vtype> strong_inline auto TensorRemove(iScalar<vtype> arg) -> decltype(TensorRemove(arg._internal))
 | 
			
		||||
{
 | 
			
		||||
template <class T>
 | 
			
		||||
strong_inline typename std::enable_if<!isGridTensor<T>::value, T>::type
 | 
			
		||||
TensorRemove(T arg) {
 | 
			
		||||
  return arg;
 | 
			
		||||
}
 | 
			
		||||
template <class vtype>
 | 
			
		||||
strong_inline auto TensorRemove(iScalar<vtype> arg)
 | 
			
		||||
    -> decltype(TensorRemove(arg._internal)) {
 | 
			
		||||
  return TensorRemove(arg._internal);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class vtype,int N> class iVector 
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
template <class vtype, int N>
 | 
			
		||||
class iVector {
 | 
			
		||||
 public:
 | 
			
		||||
  vtype _internal[N];
 | 
			
		||||
 | 
			
		||||
  typedef vtype element;
 | 
			
		||||
@@ -159,23 +185,23 @@ public:
 | 
			
		||||
  typedef typename GridTypeMapper<vtype>::tensor_reduced tensor_reduced_v;
 | 
			
		||||
  typedef typename GridTypeMapper<vtype>::scalar_object recurse_scalar_object;
 | 
			
		||||
  typedef iScalar<tensor_reduced_v> tensor_reduced;
 | 
			
		||||
  typedef iVector<recurse_scalar_object,N> scalar_object;
 | 
			
		||||
  typedef iVector<recurse_scalar_object, N> scalar_object;
 | 
			
		||||
 | 
			
		||||
  // substitutes a real or complex version with same tensor structure
 | 
			
		||||
  typedef iVector<typename GridTypeMapper<vtype>::Complexified,N > Complexified;
 | 
			
		||||
  typedef iVector<typename GridTypeMapper<vtype>::Realified,N >    Realified;
 | 
			
		||||
  typedef iVector<typename GridTypeMapper<vtype>::Complexified, N> Complexified;
 | 
			
		||||
  typedef iVector<typename GridTypeMapper<vtype>::Realified, N> Realified;
 | 
			
		||||
 | 
			
		||||
  template<class T,typename std::enable_if<!isGridTensor<T>::value, T>::type* = nullptr > strong_inline auto operator = (T arg) -> iVector<vtype,N>
 | 
			
		||||
    { 
 | 
			
		||||
  template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type
 | 
			
		||||
                         * = nullptr>
 | 
			
		||||
  strong_inline auto operator=(T arg) -> iVector<vtype, N> {
 | 
			
		||||
    zeroit(*this);
 | 
			
		||||
      for(int i=0;i<N;i++)
 | 
			
		||||
	_internal[i] = arg;
 | 
			
		||||
    for (int i = 0; i < N; i++) _internal[i] = arg;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1};
 | 
			
		||||
  iVector(const Zero &z){ *this = zero; };
 | 
			
		||||
  iVector() =default;
 | 
			
		||||
  enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1 };
 | 
			
		||||
  iVector(const Zero &z) { *this = zero; };
 | 
			
		||||
  iVector() = default;
 | 
			
		||||
  /*
 | 
			
		||||
  iVector(const iVector<vtype,N> ©me)=default;
 | 
			
		||||
  iVector(iVector<vtype,N> &©me)=default;
 | 
			
		||||
@@ -183,61 +209,61 @@ public:
 | 
			
		||||
  iVector<vtype,N> & operator= (iVector<vtype,N> &©me) = default;
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
  iVector<vtype,N> & operator= (const Zero &hero){
 | 
			
		||||
  iVector<vtype, N> &operator=(const Zero &hero) {
 | 
			
		||||
    zeroit(*this);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void zeroit(iVector<vtype,N> &that){
 | 
			
		||||
    for(int i=0;i<N;i++){
 | 
			
		||||
  friend strong_inline void zeroit(iVector<vtype, N> &that) {
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      zeroit(that._internal[i]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void prefetch(iVector<vtype,N> &that){
 | 
			
		||||
    for(int i=0;i<N;i++) prefetch(that._internal[i]);
 | 
			
		||||
  friend strong_inline void prefetch(iVector<vtype, N> &that) {
 | 
			
		||||
    for (int i = 0; i < N; i++) prefetch(that._internal[i]);
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void vstream(iVector<vtype,N> &out,const iVector<vtype,N> &in){
 | 
			
		||||
    for(int i=0;i<N;i++){
 | 
			
		||||
      vstream(out._internal[i],in._internal[i]);
 | 
			
		||||
  friend strong_inline void vstream(iVector<vtype, N> &out,
 | 
			
		||||
                                    const iVector<vtype, N> &in) {
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      vstream(out._internal[i], in._internal[i]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void permute(iVector<vtype,N> &out,const iVector<vtype,N> &in,int permutetype){
 | 
			
		||||
    for(int i=0;i<N;i++){
 | 
			
		||||
      permute(out._internal[i],in._internal[i],permutetype);
 | 
			
		||||
  friend strong_inline void permute(iVector<vtype, N> &out,
 | 
			
		||||
                                    const iVector<vtype, N> &in,
 | 
			
		||||
                                    int permutetype) {
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      permute(out._internal[i], in._internal[i], permutetype);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Unary negation
 | 
			
		||||
  friend strong_inline iVector<vtype,N> operator -(const iVector<vtype,N> &r) {
 | 
			
		||||
    iVector<vtype,N> ret;
 | 
			
		||||
    for(int i=0;i<N;i++) ret._internal[i]= -r._internal[i];
 | 
			
		||||
  friend strong_inline iVector<vtype, N> operator-(const iVector<vtype, N> &r) {
 | 
			
		||||
    iVector<vtype, N> ret;
 | 
			
		||||
    for (int i = 0; i < N; i++) ret._internal[i] = -r._internal[i];
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
  // *=,+=,-= operators inherit from corresponding "*,-,+" behaviour
 | 
			
		||||
  strong_inline iVector<vtype,N> &operator *=(const iScalar<vtype> &r) {
 | 
			
		||||
    *this = (*this)*r;
 | 
			
		||||
  strong_inline iVector<vtype, N> &operator*=(const iScalar<vtype> &r) {
 | 
			
		||||
    *this = (*this) * r;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline iVector<vtype,N> &operator -=(const iVector<vtype,N> &r) {
 | 
			
		||||
    *this = (*this)-r;
 | 
			
		||||
  strong_inline iVector<vtype, N> &operator-=(const iVector<vtype, N> &r) {
 | 
			
		||||
    *this = (*this) - r;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline iVector<vtype,N> &operator +=(const iVector<vtype,N> &r) {
 | 
			
		||||
    *this = (*this)+r;
 | 
			
		||||
  strong_inline iVector<vtype, N> &operator+=(const iVector<vtype, N> &r) {
 | 
			
		||||
    *this = (*this) + r;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline vtype & operator ()(int i) {
 | 
			
		||||
    return _internal[i];
 | 
			
		||||
  strong_inline vtype &operator()(int i) { return _internal[i]; }
 | 
			
		||||
  strong_inline const vtype &operator()(int i) const { return _internal[i]; }
 | 
			
		||||
  friend std::ostream &operator<<(std::ostream &stream,
 | 
			
		||||
                                  const iVector<vtype, N> &o) {
 | 
			
		||||
    stream << "V<" << N << ">{";
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      stream << o._internal[i];
 | 
			
		||||
      if (i < N - 1) stream << ",";
 | 
			
		||||
    }
 | 
			
		||||
  strong_inline const vtype & operator ()(int i) const {
 | 
			
		||||
    return _internal[i];
 | 
			
		||||
  }
 | 
			
		||||
  friend std::ostream& operator<< (std::ostream& stream, const iVector<vtype,N> &o){
 | 
			
		||||
    stream<< "V<"<<N<<">{";
 | 
			
		||||
    for(int i=0;i<N;i++) {
 | 
			
		||||
      stream<<o._internal[i];
 | 
			
		||||
      if (i<N-1)	stream<<",";
 | 
			
		||||
    }
 | 
			
		||||
    stream<<"}";
 | 
			
		||||
    stream << "}";
 | 
			
		||||
    return stream;
 | 
			
		||||
  };
 | 
			
		||||
  //    strong_inline vtype && operator ()(int i) {
 | 
			
		||||
@@ -245,9 +271,9 @@ public:
 | 
			
		||||
  //    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class vtype,int N> class iMatrix 
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
template <class vtype, int N>
 | 
			
		||||
class iMatrix {
 | 
			
		||||
 public:
 | 
			
		||||
  vtype _internal[N][N];
 | 
			
		||||
 | 
			
		||||
  typedef vtype element;
 | 
			
		||||
@@ -257,29 +283,27 @@ public:
 | 
			
		||||
  typedef typename GridTypeMapper<vtype>::scalar_object recurse_scalar_object;
 | 
			
		||||
 | 
			
		||||
  // substitutes a real or complex version with same tensor structure
 | 
			
		||||
  typedef iMatrix<typename GridTypeMapper<vtype>::Complexified,N > Complexified;
 | 
			
		||||
  typedef iMatrix<typename GridTypeMapper<vtype>::Realified,N >    Realified;
 | 
			
		||||
  typedef iMatrix<typename GridTypeMapper<vtype>::Complexified, N> Complexified;
 | 
			
		||||
  typedef iMatrix<typename GridTypeMapper<vtype>::Realified, N> Realified;
 | 
			
		||||
 | 
			
		||||
  // Tensure removal
 | 
			
		||||
  typedef iScalar<tensor_reduced_v> tensor_reduced;
 | 
			
		||||
  typedef iMatrix<recurse_scalar_object,N> scalar_object;
 | 
			
		||||
  typedef iMatrix<recurse_scalar_object, N> scalar_object;
 | 
			
		||||
 | 
			
		||||
  enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1};
 | 
			
		||||
  enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1 };
 | 
			
		||||
 | 
			
		||||
  iMatrix(const Zero &z) { *this = zero; };
 | 
			
		||||
  iMatrix() = default;
 | 
			
		||||
 | 
			
		||||
  iMatrix(const Zero &z){ *this = zero; };
 | 
			
		||||
  iMatrix() =default;
 | 
			
		||||
  
 | 
			
		||||
  iMatrix& operator=(const iMatrix& rhs){
 | 
			
		||||
    for(int i=0;i<N;i++)
 | 
			
		||||
      for(int j=0;j<N;j++)
 | 
			
		||||
	vstream(_internal[i][j],rhs._internal[i][j]);
 | 
			
		||||
  iMatrix &operator=(const iMatrix &rhs) {
 | 
			
		||||
    for (int i = 0; i < N; i++)
 | 
			
		||||
      for (int j = 0; j < N; j++) vstream(_internal[i][j], rhs._internal[i][j]);
 | 
			
		||||
    return *this;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
  iMatrix(scalar_type s)  { (*this) = s ;};// recurse down and hit the constructor for vector_type
 | 
			
		||||
  iMatrix(scalar_type s) {
 | 
			
		||||
    (*this) = s;
 | 
			
		||||
  };  // recurse down and hit the constructor for vector_type
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
  iMatrix(const iMatrix<vtype,N> ©me)=default;
 | 
			
		||||
@@ -288,118 +312,118 @@ public:
 | 
			
		||||
  iMatrix<vtype,N> & operator= (iMatrix<vtype,N> &©me) = default;
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  iMatrix<vtype,N> & operator= (const Zero &hero){
 | 
			
		||||
  iMatrix<vtype, N> &operator=(const Zero &hero) {
 | 
			
		||||
    zeroit(*this);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  template<class T,typename std::enable_if<!isGridTensor<T>::value, T>::type* = nullptr > strong_inline auto operator = (T arg) -> iMatrix<vtype,N>
 | 
			
		||||
    { 
 | 
			
		||||
  template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type
 | 
			
		||||
                         * = nullptr>
 | 
			
		||||
  strong_inline auto operator=(T arg) -> iMatrix<vtype, N> {
 | 
			
		||||
    zeroit(*this);
 | 
			
		||||
      for(int i=0;i<N;i++)
 | 
			
		||||
	_internal[i][i] = arg;
 | 
			
		||||
    for (int i = 0; i < N; i++) _internal[i][i] = arg;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  friend strong_inline void zeroit(iMatrix<vtype,N> &that){
 | 
			
		||||
    for(int i=0;i<N;i++){
 | 
			
		||||
      for(int j=0;j<N;j++){
 | 
			
		||||
  friend strong_inline void zeroit(iMatrix<vtype, N> &that) {
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      for (int j = 0; j < N; j++) {
 | 
			
		||||
        zeroit(that._internal[i][j]);
 | 
			
		||||
    }}
 | 
			
		||||
      }
 | 
			
		||||
  friend strong_inline void prefetch(iMatrix<vtype,N> &that){
 | 
			
		||||
    for(int i=0;i<N;i++) 
 | 
			
		||||
    for(int j=0;j<N;j++) 
 | 
			
		||||
      prefetch(that._internal[i][j]);
 | 
			
		||||
    }
 | 
			
		||||
  friend strong_inline void vstream(iMatrix<vtype,N> &out,const iMatrix<vtype,N> &in){
 | 
			
		||||
      for(int i=0;i<N;i++){
 | 
			
		||||
      for(int j=0;j<N;j++){
 | 
			
		||||
	vstream(out._internal[i][j],in._internal[i][j]);
 | 
			
		||||
      }}
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void prefetch(iMatrix<vtype, N> &that) {
 | 
			
		||||
    for (int i = 0; i < N; i++)
 | 
			
		||||
      for (int j = 0; j < N; j++) prefetch(that._internal[i][j]);
 | 
			
		||||
  }
 | 
			
		||||
  friend strong_inline void vstream(iMatrix<vtype, N> &out,
 | 
			
		||||
                                    const iMatrix<vtype, N> &in) {
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      for (int j = 0; j < N; j++) {
 | 
			
		||||
        vstream(out._internal[i][j], in._internal[i][j]);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  friend strong_inline void permute(iMatrix<vtype,N> &out,const iMatrix<vtype,N> &in,int permutetype){
 | 
			
		||||
    for(int i=0;i<N;i++){
 | 
			
		||||
      for(int j=0;j<N;j++){
 | 
			
		||||
	permute(out._internal[i][j],in._internal[i][j],permutetype);
 | 
			
		||||
    }}
 | 
			
		||||
  friend strong_inline void permute(iMatrix<vtype, N> &out,
 | 
			
		||||
                                    const iMatrix<vtype, N> &in,
 | 
			
		||||
                                    int permutetype) {
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      for (int j = 0; j < N; j++) {
 | 
			
		||||
        permute(out._internal[i][j], in._internal[i][j], permutetype);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // Unary negation
 | 
			
		||||
  friend strong_inline iMatrix<vtype,N> operator -(const iMatrix<vtype,N> &r) {
 | 
			
		||||
    iMatrix<vtype,N> ret;
 | 
			
		||||
    for(int i=0;i<N;i++){
 | 
			
		||||
      for(int j=0;j<N;j++){
 | 
			
		||||
	ret._internal[i][j]= -r._internal[i][j];
 | 
			
		||||
    }}
 | 
			
		||||
  friend strong_inline iMatrix<vtype, N> operator-(const iMatrix<vtype, N> &r) {
 | 
			
		||||
    iMatrix<vtype, N> ret;
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      for (int j = 0; j < N; j++) {
 | 
			
		||||
        ret._internal[i][j] = -r._internal[i][j];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
  // *=,+=,-= operators inherit from corresponding "*,-,+" behaviour
 | 
			
		||||
  template<class T>
 | 
			
		||||
  strong_inline iMatrix<vtype,N> &operator *=(const T &r) {
 | 
			
		||||
    *this = (*this)*r;
 | 
			
		||||
  template <class T>
 | 
			
		||||
  strong_inline iMatrix<vtype, N> &operator*=(const T &r) {
 | 
			
		||||
    *this = (*this) * r;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  template<class T>
 | 
			
		||||
  strong_inline iMatrix<vtype,N> &operator -=(const T &r) {
 | 
			
		||||
    *this = (*this)-r;
 | 
			
		||||
  template <class T>
 | 
			
		||||
  strong_inline iMatrix<vtype, N> &operator-=(const T &r) {
 | 
			
		||||
    *this = (*this) - r;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  template<class T>
 | 
			
		||||
  strong_inline iMatrix<vtype,N> &operator +=(const T &r) {
 | 
			
		||||
    *this = (*this)+r;
 | 
			
		||||
  template <class T>
 | 
			
		||||
  strong_inline iMatrix<vtype, N> &operator+=(const T &r) {
 | 
			
		||||
    *this = (*this) + r;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // returns an lvalue reference
 | 
			
		||||
  strong_inline vtype & operator ()(int i,int j) {
 | 
			
		||||
  strong_inline vtype &operator()(int i, int j) { return _internal[i][j]; }
 | 
			
		||||
  strong_inline const vtype &operator()(int i, int j) const {
 | 
			
		||||
    return _internal[i][j];
 | 
			
		||||
  }
 | 
			
		||||
  strong_inline const vtype & operator ()(int i,int j) const {
 | 
			
		||||
    return _internal[i][j];
 | 
			
		||||
  friend std::ostream &operator<<(std::ostream &stream,
 | 
			
		||||
                                  const iMatrix<vtype, N> &o) {
 | 
			
		||||
    stream << "M<" << N << ">{";
 | 
			
		||||
    for (int i = 0; i < N; i++) {
 | 
			
		||||
      stream << "{";
 | 
			
		||||
      for (int j = 0; j < N; j++) {
 | 
			
		||||
        stream << o._internal[i][j];
 | 
			
		||||
        if (i < N - 1) stream << ",";
 | 
			
		||||
      }
 | 
			
		||||
  friend std::ostream& operator<< (std::ostream& stream, const iMatrix<vtype,N> &o){
 | 
			
		||||
    stream<< "M<"<<N<<">{";
 | 
			
		||||
    for(int i=0;i<N;i++) {
 | 
			
		||||
      stream<< "{";
 | 
			
		||||
      for(int j=0;j<N;j++) {
 | 
			
		||||
	stream<<o._internal[i][j];
 | 
			
		||||
	if (i<N-1)	stream<<",";
 | 
			
		||||
      stream << "}";
 | 
			
		||||
      if (i != N - 1) stream << "\n\t\t";
 | 
			
		||||
    }
 | 
			
		||||
      stream<<"}";
 | 
			
		||||
      if(i!=N-1) stream<<"\n\t\t";
 | 
			
		||||
    }
 | 
			
		||||
    stream<<"}";
 | 
			
		||||
    stream << "}";
 | 
			
		||||
    return stream;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  //  strong_inline vtype && operator ()(int i,int j) {
 | 
			
		||||
  //    return _internal[i][j];
 | 
			
		||||
  //  }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class v> void vprefetch(const iScalar<v> &vv)
 | 
			
		||||
{
 | 
			
		||||
template <class v>
 | 
			
		||||
void vprefetch(const iScalar<v> &vv) {
 | 
			
		||||
  vprefetch(vv._internal);
 | 
			
		||||
}
 | 
			
		||||
template<class v,int N> void vprefetch(const iVector<v,N> &vv)
 | 
			
		||||
{
 | 
			
		||||
  for(int i=0;i<N;i++){
 | 
			
		||||
template <class v, int N>
 | 
			
		||||
void vprefetch(const iVector<v, N> &vv) {
 | 
			
		||||
  for (int i = 0; i < N; i++) {
 | 
			
		||||
    vprefetch(vv._internal[i]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
template<class v,int N> void vprefetch(const iMatrix<v,N> &vv)
 | 
			
		||||
{
 | 
			
		||||
  for(int i=0;i<N;i++){
 | 
			
		||||
  for(int j=0;j<N;j++){
 | 
			
		||||
template <class v, int N>
 | 
			
		||||
void vprefetch(const iMatrix<v, N> &vv) {
 | 
			
		||||
  for (int i = 0; i < N; i++) {
 | 
			
		||||
    for (int j = 0; j < N; j++) {
 | 
			
		||||
      vprefetch(vv._internal[i][j]);
 | 
			
		||||
  }}
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +1,32 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
    Source file: ./tests/Test_rhmc_EOWilson1p1.cc
 | 
			
		||||
Source file: ./tests/Test_rhmc_EOWilson1p1.cc
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
    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 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.
 | 
			
		||||
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.
 | 
			
		||||
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 */
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#include "Grid.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
@@ -33,20 +34,20 @@ using namespace Grid;
 | 
			
		||||
using namespace Grid::QCD;
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
  namespace QCD { 
 | 
			
		||||
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
class HmcRunner : public NerscHmcRunner {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  void BuildTheAction (int argc, char **argv)
 | 
			
		||||
 public:
 | 
			
		||||
  void BuildTheAction(int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    typedef WilsonImplR ImplPolicy;
 | 
			
		||||
    typedef WilsonFermionR FermionAction;
 | 
			
		||||
    typedef typename FermionAction::FermionField FermionField;
 | 
			
		||||
 | 
			
		||||
    UGrid   = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
 | 
			
		||||
    UGrid = SpaceTimeGrid::makeFourDimGrid(
 | 
			
		||||
        GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()),
 | 
			
		||||
        GridDefaultMpi());
 | 
			
		||||
    UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
			
		||||
 | 
			
		||||
    FGrid = UGrid;
 | 
			
		||||
@@ -58,15 +59,21 @@ public:
 | 
			
		||||
    // Gauge action
 | 
			
		||||
    WilsonGaugeActionR Waction(5.6);
 | 
			
		||||
 | 
			
		||||
    Real mass=-0.77;
 | 
			
		||||
    FermionAction FermOp(U,*FGrid,*FrbGrid,mass);
 | 
			
		||||
    Real mass = -0.77;
 | 
			
		||||
    FermionAction FermOp(U, *FGrid, *FrbGrid, mass);
 | 
			
		||||
 | 
			
		||||
    // 1+1 flavour
 | 
			
		||||
    OneFlavourRationalParams Params(1.0e-4,64.0,1000,1.0e-6);
 | 
			
		||||
    OneFlavourEvenOddRationalPseudoFermionAction<WilsonImplR> WilsonNf1a(FermOp,Params);
 | 
			
		||||
    OneFlavourEvenOddRationalPseudoFermionAction<WilsonImplR> WilsonNf1b(FermOp,Params);
 | 
			
		||||
    OneFlavourRationalParams Params(1.0e-4, 64.0, 2000, 1.0e-6);
 | 
			
		||||
    OneFlavourEvenOddRationalPseudoFermionAction<WilsonImplR> WilsonNf1a(
 | 
			
		||||
        FermOp, Params);
 | 
			
		||||
    OneFlavourEvenOddRationalPseudoFermionAction<WilsonImplR> WilsonNf1b(
 | 
			
		||||
        FermOp, Params);
 | 
			
		||||
 | 
			
		||||
    //Collect actions
 | 
			
		||||
    //Smearing on/off
 | 
			
		||||
    WilsonNf1a.is_smeared = true;
 | 
			
		||||
    WilsonNf1b.is_smeared = true;
 | 
			
		||||
 | 
			
		||||
    // Collect actions
 | 
			
		||||
    ActionLevel<LatticeGaugeField> Level1;
 | 
			
		||||
    Level1.push_back(&WilsonNf1a);
 | 
			
		||||
    Level1.push_back(&WilsonNf1b);
 | 
			
		||||
@@ -74,24 +81,20 @@ public:
 | 
			
		||||
 | 
			
		||||
    TheAction.push_back(Level1);
 | 
			
		||||
 | 
			
		||||
    Run(argc,argv);
 | 
			
		||||
    Run(argc, argv);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
int main (int argc, char ** argv)
 | 
			
		||||
{
 | 
			
		||||
  Grid_init(&argc,&argv);
 | 
			
		||||
int main(int argc, char **argv) {
 | 
			
		||||
  Grid_init(&argc, &argv);
 | 
			
		||||
 | 
			
		||||
  int threads = GridThread::GetThreads();
 | 
			
		||||
  std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
 | 
			
		||||
  std::cout << GridLogMessage << "Grid is setup to use " << threads
 | 
			
		||||
            << " threads" << std::endl;
 | 
			
		||||
 | 
			
		||||
  HmcRunner TheHMC;
 | 
			
		||||
 | 
			
		||||
  TheHMC.BuildTheAction(argc,argv);
 | 
			
		||||
 | 
			
		||||
  TheHMC.BuildTheAction(argc, argv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user