From 3931ad65c8a0ad6f137d5b50fb274cf62e0ba4ca Mon Sep 17 00:00:00 2001 From: Peter Boyle Date: Sat, 18 Apr 2015 18:37:22 +0100 Subject: [PATCH] Reorg --- lib/Grid_math_types.h | 1662 ----------------------------------------- 1 file changed, 1662 deletions(-) delete mode 100644 lib/Grid_math_types.h diff --git a/lib/Grid_math_types.h b/lib/Grid_math_types.h deleted file mode 100644 index 1042a95b..00000000 --- a/lib/Grid_math_types.h +++ /dev/null @@ -1,1662 +0,0 @@ -#ifndef GRID_MATH_TYPES_H -#define GRID_MATH_TYPES_H - -#include - -#include - -// -// Indexing; want to be able to dereference and -// obtain either an lvalue or an rvalue. -// -namespace Grid { - - // First some of my own traits - template struct isGridTensor { - static const bool value = true; - static const bool notvalue = false; - }; - - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - template<> struct isGridTensor { - static const bool value = false; - static const bool notvalue = true; - }; - - // Match the index - template struct matchGridTensorIndex { - static const bool value = (Level==T::TensorLevel); - static const bool notvalue = (Level!=T::TensorLevel); - }; - // What is the vtype - template struct isComplex { - static const bool value = false; - }; - template<> struct isComplex { - static const bool value = true; - }; - template<> struct isComplex { - static const bool value = true; - }; - - -/////////////////////////////////////////////////// -// Scalar, Vector, Matrix objects. -// These can be composed to form tensor products of internal indices. -/////////////////////////////////////////////////// - - - -template class iScalar -{ -public: - vtype _internal; - - typedef typename GridTypeMapper::scalar_type scalar_type; - typedef typename GridTypeMapper::vector_type vector_type; - typedef typename GridTypeMapper::tensor_reduced tensor_reduced_v; - typedef iScalar tensor_reduced; - - enum { TensorLevel = GridTypeMapper::TensorLevel + 1}; - - // Scalar no action - // template using tensor_reduce_level = typename iScalar::tensor_reduce_level >; - - iScalar(){}; - - iScalar(scalar_type s) : _internal(s) {};// recurse down and hit the constructor for vector_type - - iScalar(Zero &z){ *this = zero; }; - - iScalar & operator= (const Zero &hero){ - zeroit(*this); - return *this; - } - friend void zeroit(iScalar &that){ - zeroit(that._internal); - } - friend void permute(iScalar &out,const iScalar &in,int permutetype){ - permute(out._internal,in._internal,permutetype); - } - friend void extract(const iScalar &in,std::vector &out){ - extract(in._internal,out); // extract advances the pointers in out - } - friend void merge(iScalar &in,std::vector &out){ - merge(in._internal,out); // extract advances the pointers in out - } - - // Unary negation - friend inline iScalar operator -(const iScalar &r) { - iScalar ret; - ret._internal= -r._internal; - return ret; - } - // *=,+=,-= operators inherit from corresponding "*,-,+" behaviour - inline iScalar &operator *=(const iScalar &r) { - *this = (*this)*r; - return *this; - } - inline iScalar &operator -=(const iScalar &r) { - *this = (*this)-r; - return *this; - } - inline iScalar &operator +=(const iScalar &r) { - *this = (*this)+r; - return *this; - } - - inline vtype & operator ()(void) { - return _internal; - } - - operator ComplexD () const { return(TensorRemove(_internal)); }; - operator RealD () const { return(real(TensorRemove(_internal))); } - -}; -/////////////////////////////////////////////////////////// -// Allows to turn scalar>>> back to double. -/////////////////////////////////////////////////////////// -template inline typename std::enable_if::notvalue, T>::type TensorRemove(T arg) { return arg;} -template inline auto TensorRemove(iScalar arg) -> decltype(TensorRemove(arg._internal)) -{ - return TensorRemove(arg._internal); -} - -template class iVector -{ -public: - vtype _internal[N]; - - typedef typename GridTypeMapper::scalar_type scalar_type; - typedef typename GridTypeMapper::vector_type vector_type; - typedef typename GridTypeMapper::tensor_reduced tensor_reduced_v; - - enum { TensorLevel = GridTypeMapper::TensorLevel + 1}; - typedef iScalar tensor_reduced; - - iVector(Zero &z){ *this = zero; }; - iVector() {};// Empty constructure - - iVector & operator= (Zero &hero){ - zeroit(*this); - return *this; - } - friend void zeroit(iVector &that){ - for(int i=0;i &out,const iVector &in,int permutetype){ - for(int i=0;i &in,std::vector &out){ - for(int i=0;i &in,std::vector &out){ - for(int i=0;i operator -(const iVector &r) { - iVector ret; - for(int i=0;i &operator *=(const iScalar &r) { - *this = (*this)*r; - return *this; - } - inline iVector &operator -=(const iVector &r) { - *this = (*this)-r; - return *this; - } - inline iVector &operator +=(const iVector &r) { - *this = (*this)+r; - return *this; - } - inline vtype & operator ()(int i) { - return _internal[i]; - } -}; - -template class iMatrix -{ -public: - vtype _internal[N][N]; - - typedef typename GridTypeMapper::scalar_type scalar_type; - typedef typename GridTypeMapper::vector_type vector_type; - - typedef typename GridTypeMapper::tensor_reduced tensor_reduced_v; - - enum { TensorLevel = GridTypeMapper::TensorLevel + 1}; - typedef iScalar tensor_reduced; - - iMatrix(Zero &z){ *this = zero; }; - iMatrix() {}; - iMatrix & operator= (Zero &hero){ - zeroit(*this); - return *this; - } - friend void zeroit(iMatrix &that){ - for(int i=0;i &out,const iMatrix &in,int permutetype){ - for(int i=0;i &in,std::vector &out){ - for(int i=0;i &in,std::vector &out){ - for(int i=0;i operator -(const iMatrix &r) { - iMatrix ret; - for(int i=0;i - inline iMatrix &operator *=(const T &r) { - *this = (*this)*r; - return *this; - } - template - inline iMatrix &operator -=(const T &r) { - *this = (*this)-r; - return *this; - } - template - inline iMatrix &operator +=(const T &r) { - *this = (*this)+r; - return *this; - } - inline vtype & operator ()(int i,int j) { - return _internal[i][j]; - } - -}; - - - /////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////// ADD /////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////////////////////////// - - -// ADD is simple for now; cannot mix types and straightforward template -// Scalar +/- Scalar -// Vector +/- Vector -// Matrix +/- Matrix -template inline void add(iScalar * __restrict__ ret, - const iScalar * __restrict__ lhs, - const iScalar * __restrict__ rhs) -{ - add(&ret->_internal,&lhs->_internal,&rhs->_internal); -} -template inline void add(iVector * __restrict__ ret, - const iVector * __restrict__ lhs, - const iVector * __restrict__ rhs) -{ - for(int c=0;c_internal[c]=lhs->_internal[c]+rhs->_internal[c]; - } - return; -} -template inline void add(iMatrix * __restrict__ ret, - const iMatrix * __restrict__ lhs, - const iMatrix * __restrict__ rhs) -{ - for(int c2=0;c2_internal[c1][c2],&lhs->_internal[c1][c2],&rhs->_internal[c1][c2]); - }} - return; -} -template inline void add(iMatrix * __restrict__ ret, - const iScalar * __restrict__ lhs, - const iMatrix * __restrict__ rhs) -{ - for(int c2=0;c2_internal[c1][c2],&lhs->_internal,&rhs->_internal[c1][c2]); - }} - return; -} -template inline void add(iMatrix * __restrict__ ret, - const iMatrix * __restrict__ lhs, - const iScalar * __restrict__ rhs) -{ - for(int c2=0;c2_internal[c1][c2],&lhs->_internal[c1][c2],&rhs->_internal); - else - ret->_internal[c1][c2]=lhs->_internal[c1][c2]; - }} - return; -} -// Need to figure multi-precision. -template Mytype timesI(Mytype &r) -{ - iScalar i; - i._internal = Complex(0,1); - return r*i; -} - - // + operator for scalar, vector, matrix -template -//inline auto operator + (iScalar& lhs,iScalar&& rhs) -> iScalar -inline auto operator + (const iScalar& lhs,const iScalar& rhs) -> iScalar -{ - typedef iScalar ret_t; - ret_t ret; - add(&ret,&lhs,&rhs); - return ret; -} -template -inline auto operator + (const iVector& lhs,const iVector& rhs) ->iVector -{ - typedef iVector ret_t; - ret_t ret; - add(&ret,&lhs,&rhs); - return ret; -} -template -inline auto operator + (const iMatrix& lhs,const iMatrix& rhs) ->iMatrix -{ - typedef iMatrix ret_t; - ret_t ret; - add(&ret,&lhs,&rhs); - return ret; -} -template -inline auto operator + (const iScalar& lhs,const iMatrix& rhs)->iMatrix -{ - typedef iMatrix ret_t; - ret_t ret; - add(&ret,&lhs,&rhs); - return ret; -} -template -inline auto operator + (const iMatrix& lhs,const iScalar& rhs)->iMatrix -{ - typedef iMatrix ret_t; - ret_t ret; - add(&ret,&lhs,&rhs); - return ret; -} - - - /////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////// SUB /////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////////////////////////// - - -// SUB is simple for now; cannot mix types and straightforward template -// Scalar +/- Scalar -// Vector +/- Vector -// Matrix +/- Matrix -// Matrix /- scalar -template inline void sub(iScalar * __restrict__ ret, - const iScalar * __restrict__ lhs, - const iScalar * __restrict__ rhs) -{ - sub(&ret->_internal,&lhs->_internal,&rhs->_internal); -} - -template inline void sub(iVector * __restrict__ ret, - const iVector * __restrict__ lhs, - const iVector * __restrict__ rhs) -{ - for(int c=0;c_internal[c]=lhs->_internal[c]-rhs->_internal[c]; - } - return; -} -template inline void sub(iMatrix * __restrict__ ret, - const iMatrix * __restrict__ lhs, - const iMatrix * __restrict__ rhs){ - for(int c2=0;c2_internal[c1][c2],&lhs->_internal[c1][c2],&rhs->_internal[c1][c2]); - }} - return; -} -template inline void sub(iMatrix * __restrict__ ret, - const iScalar * __restrict__ lhs, - const iMatrix * __restrict__ rhs){ - for(int c2=0;c2_internal[c1][c2],&lhs->_internal,&rhs->_internal[c1][c2]); - } else { - // Fails -- need unary minus. Catalogue other unops? - ret->_internal[c1][c2]=zero; - ret->_internal[c1][c2]=ret->_internal[c1][c2]-rhs->_internal[c1][c2]; - - } - }} - return; -} -template inline void sub(iMatrix * __restrict__ ret, - const iMatrix * __restrict__ lhs, - const iScalar * __restrict__ rhs){ - for(int c2=0;c2_internal[c1][c2],&lhs->_internal[c1][c2],&rhs->_internal); - else - ret->_internal[c1][c2]=lhs->_internal[c1][c2]; - }} - return; -} - -template void vprefetch(const iScalar &vv) -{ - vprefetch(vv._internal); -} -template void vprefetch(const iVector &vv) -{ - for(int i=0;i void vprefetch(const iMatrix &vv) -{ - for(int i=0;i inline auto -operator - (const iScalar& lhs, const iScalar& rhs) -> iScalar -{ - typedef iScalar ret_t; - ret_t ret; - sub(&ret,&lhs,&rhs); - return ret; -} -template -inline auto operator - (const iVector& lhs,const iVector& rhs) ->iVector -{ - typedef iVector ret_t; - ret_t ret; - sub(&ret,&lhs,&rhs); - return ret; -} -template -inline auto operator - (const iMatrix& lhs,const iMatrix& rhs) ->iMatrix -{ - typedef iMatrix ret_t; - ret_t ret; - sub(&ret,&lhs,&rhs); - return ret; -} -template -inline auto operator - (const iScalar& lhs,const iMatrix& rhs)->iMatrix -{ - typedef iMatrix ret_t; - ret_t ret; - sub(&ret,&lhs,&rhs); - return ret; -} -template -inline auto operator - (const iMatrix& lhs,const iScalar& rhs)->iMatrix -{ - typedef iMatrix ret_t; - ret_t ret; - sub(&ret,&lhs,&rhs); - return ret; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////// MAC /////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////// - // Legal multiplication table - /////////////////////////// - // scal x scal = scal - // mat x mat = mat - // mat x scal = mat - // scal x mat = mat - // mat x vec = vec - // vec x scal = vec - // scal x vec = vec - /////////////////////////// -template -inline void mac(iScalar * __restrict__ ret,const iScalar * __restrict__ lhs,const iScalar * __restrict__ rhs) -{ - mac(&ret->_internal,&lhs->_internal,&rhs->_internal); -} -template -inline void mac(iMatrix * __restrict__ ret,const iMatrix * __restrict__ lhs,const iMatrix * __restrict__ rhs){ - for(int c2=0;c2_internal[c1][c2],&lhs->_internal[c1][c3],&rhs->_internal[c3][c2]); - }}} - return; -} -template -inline void mac(iMatrix * __restrict__ ret,const iMatrix * __restrict__ lhs,const iScalar * __restrict__ rhs){ - for(int c1=0;c1_internal[c1][c2],&lhs->_internal[c1][c2],&rhs->_internal); - }} - return; -} -template -inline void mac(iMatrix * __restrict__ ret,const iScalar * __restrict__ lhs,const iMatrix * __restrict__ rhs){ - for(int c1=0;c1_internal[c1][c2],&lhs->_internal,&rhs->_internal[c1][c2]); - }} - return; -} -template -inline void mac(iVector * __restrict__ ret,const iMatrix * __restrict__ lhs,const iVector * __restrict__ rhs) -{ - for(int c1=0;c1_internal[c1],&lhs->_internal[c1][c2],&rhs->_internal[c2]); - }} - return; -} -template -inline void mac(iVector * __restrict__ ret,const iScalar * __restrict__ lhs,const iVector * __restrict__ rhs) -{ - for(int c1=0;c1_internal[c1],&lhs->_internal,&rhs->_internal[c1]); - } - return; -} -template -inline void mac(iVector * __restrict__ ret,const iVector * __restrict__ lhs,const iScalar * __restrict__ rhs) -{ - for(int c1=0;c1_internal[c1],&lhs->_internal[c1],&rhs->_internal); - } - return; -} - - /////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////// MUL /////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////////////////////////// - - -template -inline void mult(iScalar * __restrict__ ret,const iScalar * __restrict__ lhs,const iScalar * __restrict__ rhs){ - mult(&ret->_internal,&lhs->_internal,&rhs->_internal); -} - -template -inline void mult(iMatrix * __restrict__ ret,const iMatrix * __restrict__ lhs,const iMatrix * __restrict__ rhs){ - for(int c2=0;c2_internal[c1][c2],&lhs->_internal[c1][0],&rhs->_internal[0][c2]); - for(int c3=1;c3_internal[c1][c2],&lhs->_internal[c1][c3],&rhs->_internal[c3][c2]); - } - }} - return; -} -template -inline void mult(iMatrix * __restrict__ ret,const iMatrix * __restrict__ lhs,const iScalar * __restrict__ rhs){ - for(int c2=0;c2_internal[c1][c2],&lhs->_internal[c1][c2],&rhs->_internal); - }} - return; -} - -template -inline void mult(iMatrix * __restrict__ ret,const iScalar * __restrict__ lhs,const iMatrix * __restrict__ rhs){ - for(int c2=0;c2_internal[c1][c2],&lhs->_internal,&rhs->_internal[c1][c2]); - }} - return; -} -// Matrix left multiplies vector -template -inline void mult(iVector * __restrict__ ret,const iMatrix * __restrict__ lhs,const iVector * __restrict__ rhs) -{ - for(int c1=0;c1_internal[c1],&lhs->_internal[c1][0],&rhs->_internal[0]); - for(int c2=1;c2_internal[c1],&lhs->_internal[c1][c2],&rhs->_internal[c2]); - } - } - return; -} -template -inline void mult(iVector * __restrict__ ret, - const iScalar * __restrict__ lhs, - const iVector * __restrict__ rhs){ - for(int c1=0;c1_internal[c1],&lhs->_internal,&rhs->_internal[c1]); - } -} -template -inline void mult(iVector * __restrict__ ret, - const iVector * __restrict__ rhs, - const iScalar * __restrict__ lhs){ - mult(ret,lhs,rhs); -} - - - -template inline -iVector operator * (const iMatrix& lhs,const iVector& rhs) -{ - iVector ret; - mult(&ret,&lhs,&rhs); - return ret; -} - -template inline -iVector operator * (const iScalar& lhs,const iVector& rhs) -{ - iVector ret; - mult(&ret,&lhs,&rhs); - return ret; -} - -template inline -iVector operator * (const iVector& lhs,const iScalar& rhs) -{ - iVector ret; - mult(&ret,&lhs,&rhs); - return ret; -} - - ////////////////////////////////////////////////////////////////// - // Glue operators to mult routines. Must resolve return type cleverly from typeof(internal) - // since nesting matrix x matrix-> matrix - // while matrix x matrix-> matrix - // so return type depends on argument types in nasty way. - ////////////////////////////////////////////////////////////////// - // scal x scal = scal - // mat x mat = mat - // mat x scal = mat - // scal x mat = mat - // mat x vec = vec - // vec x scal = vec - // scal x vec = vec - // - // We can special case scalar_type ?? -template -inline auto operator * (const iScalar& lhs,const iScalar& rhs) -> iScalar -{ - typedef iScalar ret_t; - ret_t ret; - mult(&ret,&lhs,&rhs); - return ret; -} -template inline -auto operator * (const iMatrix& lhs,const iMatrix& rhs) -> iMatrix -{ - typedef decltype(lhs._internal[0][0]*rhs._internal[0][0]) ret_t; - iMatrix ret; - mult(&ret,&lhs,&rhs); - return ret; -} -template inline -auto operator * (const iMatrix& lhs,const iScalar& rhs) -> iMatrix -{ - typedef decltype(lhs._internal[0][0]*rhs._internal) ret_t; - - iMatrix ret; - for(int c1=0;c1 inline -auto operator * (const iScalar& lhs,const iMatrix& rhs) -> iMatrix -{ - typedef decltype(lhs._internal*rhs._internal[0][0]) ret_t; - iMatrix ret; - for(int c1=0;c1 inline -auto operator * (const iMatrix& lhs,const iVector& rhs) -> iVector -{ - typedef decltype(lhs._internal[0][0]*rhs._internal[0]) ret_t; - iVector ret; - for(int c1=0;c1 inline -auto operator * (const iScalar& lhs,const iVector& rhs) -> iVector -{ - typedef decltype(lhs._internal*rhs._internal[0]) ret_t; - iVector ret; - for(int c1=0;c1 inline -auto operator * (const iVector& lhs,const iScalar& rhs) -> iVector -{ - typedef decltype(lhs._internal[0]*rhs._internal) ret_t; - iVector ret; - for(int c1=0;c1 inline iScalar operator * (const iScalar& lhs,const typename iScalar::scalar_type rhs) -{ - typename iScalar::tensor_reduced srhs(rhs); - return lhs*srhs; -} -template inline iScalar operator * (const typename iScalar::scalar_type lhs,const iScalar& rhs) { return rhs*lhs; } - -template inline iVector operator * (const iVector& lhs,const typename iScalar::scalar_type rhs) -{ - typename iVector::tensor_reduced srhs(rhs); - return lhs*srhs; -} -template inline iVector operator * (const typename iScalar::scalar_type lhs,const iVector& rhs) { return rhs*lhs; } - -template inline iMatrix operator * (const iMatrix& lhs,const typename iScalar::scalar_type &rhs) -{ - typename iMatrix::tensor_reduced srhs(rhs); - return lhs*srhs; -} -template inline iMatrix operator * (const typename iScalar::scalar_type & lhs,const iMatrix& rhs) { return rhs*lhs; } - -//////////////////////////////////////////////////////////////////// -// Double support; cast to "scalar_type" through constructor -//////////////////////////////////////////////////////////////////// -template inline iScalar operator * (const iScalar& lhs,double rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs*srhs; -} -template inline iScalar operator * (double lhs,const iScalar& rhs) { return rhs*lhs; } - -template inline iVector operator * (const iVector& lhs,double rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs*srhs; -} -template inline iVector operator * (double lhs,const iVector& rhs) { return rhs*lhs; } - -template inline iMatrix operator * (const iMatrix& lhs,double rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs*srhs; -} -template inline iMatrix operator * (double lhs,const iMatrix& rhs) { return rhs*lhs; } - -//////////////////////////////////////////////////////////////////// -// Complex support; cast to "scalar_type" through constructor -//////////////////////////////////////////////////////////////////// -template inline iScalar operator * (const iScalar& lhs,ComplexD rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs*srhs; -} -template inline iScalar operator * (ComplexD lhs,const iScalar& rhs) { return rhs*lhs; } - -template inline iVector operator * (const iVector& lhs,ComplexD rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs*srhs; -} -template inline iVector operator * (ComplexD lhs,const iVector& rhs) { return rhs*lhs; } - -template inline iMatrix operator * (const iMatrix& lhs,ComplexD rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs*srhs; -} -template inline iMatrix operator * (ComplexD lhs,const iMatrix& rhs) { return rhs*lhs; } - -//////////////////////////////////////////////////////////////////// -// Integer support; cast to "scalar_type" through constructor -//////////////////////////////////////////////////////////////////// -template inline iScalar operator * (const iScalar& lhs,Integer rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs*srhs; -} -template inline iScalar operator * (Integer lhs,const iScalar& rhs) { return rhs*lhs; } - -template inline iVector operator * (const iVector& lhs,Integer rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs*srhs; -} -template inline iVector operator * (Integer lhs,const iVector& rhs) { return rhs*lhs; } - -template inline iMatrix operator * (const iMatrix& lhs,Integer rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs*srhs; -} -template inline iMatrix operator * (Integer lhs,const iMatrix& rhs) { return rhs*lhs; } - - - -/////////////////////////////////////////////////////////////////////////////////////////////// -// addition by fundamental scalar type applies to matrix(down diag) and scalar -/////////////////////////////////////////////////////////////////////////////////////////////// -template inline iScalar operator + (const iScalar& lhs,const typename iScalar::scalar_type rhs) -{ - typename iScalar::tensor_reduced srhs(rhs); - return lhs+srhs; -} -template inline iScalar operator + (const typename iScalar::scalar_type lhs,const iScalar& rhs) { return rhs+lhs; } - -template inline iMatrix operator + (const iMatrix& lhs,const typename iScalar::scalar_type rhs) -{ - typename iMatrix::tensor_reduced srhs(rhs); - return lhs+srhs; -} -template inline iMatrix operator + (const typename iScalar::scalar_type lhs,const iMatrix& rhs) { return rhs+lhs; } - -//////////////////////////////////////////////////////////////////// -// Double support; cast to "scalar_type" through constructor -//////////////////////////////////////////////////////////////////// -template inline iScalar operator + (const iScalar& lhs,double rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs+srhs; -} -template inline iScalar operator + (double lhs,const iScalar& rhs) { return rhs+lhs; } - -template inline iMatrix operator + (const iMatrix& lhs,double rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs+srhs; -} -template inline iMatrix operator + (double lhs,const iMatrix& rhs) { return rhs+lhs; } - -//////////////////////////////////////////////////////////////////// -// Integer support; cast to "scalar_type" through constructor -//////////////////////////////////////////////////////////////////// -template inline iScalar operator + (const iScalar& lhs,Integer rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs+srhs; -} -template inline iScalar operator + (Integer lhs,const iScalar& rhs) { return rhs+lhs; } - -template inline iMatrix operator + (const iMatrix& lhs,Integer rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs+srhs; -} -template inline iMatrix operator + (Integer lhs,const iMatrix& rhs) { return rhs+lhs; } - - -/////////////////////////////////////////////////////////////////////////////////////////////// -// subtraction of fundamental scalar type applies to matrix(down diag) and scalar -/////////////////////////////////////////////////////////////////////////////////////////////// -template inline iScalar operator - (const iScalar& lhs,const typename iScalar::scalar_type rhs) -{ - typename iScalar::tensor_reduced srhs(rhs); - return lhs-srhs; -} -template inline iScalar operator - (const typename iScalar::scalar_type lhs,const iScalar& rhs) -{ - typename iScalar::tensor_reduced slhs(lhs); - return slhs-rhs; -} - -template inline iMatrix operator - (const iMatrix& lhs,const typename iScalar::scalar_type rhs) -{ - typename iScalar::tensor_reduced srhs(rhs); - return lhs-srhs; -} -template inline iMatrix operator - (const typename iScalar::scalar_type lhs,const iMatrix& rhs) -{ - typename iScalar::tensor_reduced slhs(lhs); - return slhs-rhs; -} - -//////////////////////////////////////////////////////////////////// -// Double support; cast to "scalar_type" through constructor -//////////////////////////////////////////////////////////////////// -template inline iScalar operator - (const iScalar& lhs,double rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs-srhs; -} -template inline iScalar operator - (double lhs,const iScalar& rhs) -{ - typename iScalar::scalar_type t(lhs); - typename iScalar::tensor_reduced slhs(t); - return slhs-rhs; -} - -template inline iMatrix operator - (const iMatrix& lhs,double rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs-srhs; -} -template inline iMatrix operator - (double lhs,const iMatrix& rhs) -{ - typename iScalar::scalar_type t(lhs); - typename iScalar::tensor_reduced slhs(t); - return slhs-rhs; -} - -//////////////////////////////////////////////////////////////////// -// Integer support; cast to "scalar_type" through constructor -//////////////////////////////////////////////////////////////////// -template inline iScalar operator - (const iScalar& lhs,Integer rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs-srhs; -} -template inline iScalar operator - (Integer lhs,const iScalar& rhs) -{ - typename iScalar::scalar_type t(lhs); - typename iScalar::tensor_reduced slhs(t); - return slhs-rhs; -} -template inline iMatrix operator - (const iMatrix& lhs,Integer rhs) -{ - typename iScalar::scalar_type t(rhs); - typename iScalar::tensor_reduced srhs(t); - return lhs-srhs; -} -template inline iMatrix operator - (Integer lhs,const iMatrix& rhs) -{ - typename iScalar::scalar_type t(lhs); - typename iScalar::tensor_reduced slhs(t); - return slhs-rhs; -} - - - - - /////////////////////////////////////////////////////////////////////////////////////// - // innerProduct Scalar x Scalar -> Scalar - // innerProduct Vector x Vector -> Scalar - // innerProduct Matrix x Matrix -> Scalar - /////////////////////////////////////////////////////////////////////////////////////// - template inline - auto innerProduct (const iVector& lhs,const iVector& rhs) -> iScalar - { - typedef decltype(innerProduct(lhs._internal[0],rhs._internal[0])) ret_t; - iScalar ret=zero; - for(int c1=0;c1 inline - auto innerProduct (const iMatrix& lhs,const iMatrix& rhs) -> iScalar - { - typedef decltype(innerProduct(lhs._internal[0][0],rhs._internal[0][0])) ret_t; - iScalar ret=zero; - iScalar tmp; - for(int c1=0;c1 inline - auto innerProduct (const iScalar& lhs,const iScalar& rhs) -> iScalar - { - typedef decltype(innerProduct(lhs._internal,rhs._internal)) ret_t; - iScalar ret; - ret._internal = innerProduct(lhs._internal,rhs._internal); - return ret; - } - - /////////////////////////////////////////////////////////////////////////////////////// - // outerProduct Scalar x Scalar -> Scalar - // Vector x Vector -> Matrix - /////////////////////////////////////////////////////////////////////////////////////// - -template inline -auto outerProduct (const iVector& lhs,const iVector& rhs) -> iMatrix -{ - typedef decltype(outerProduct(lhs._internal[0],rhs._internal[0])) ret_t; - iMatrix ret; - for(int c1=0;c1 inline -auto outerProduct (const iScalar& lhs,const iScalar& rhs) -> iScalar -{ - typedef decltype(outerProduct(lhs._internal,rhs._internal)) ret_t; - iScalar ret; - ret._internal = outerProduct(lhs._internal,rhs._internal); - return ret; -} - -inline ComplexF outerProduct(const ComplexF &l, const ComplexF& r) -{ - return l*r; -} -inline ComplexD outerProduct(const ComplexD &l, const ComplexD& r) -{ - return l*r; -} -inline RealF outerProduct(const RealF &l, const RealF& r) -{ - return l*r; -} -inline RealD outerProduct(const RealD &l, const RealD& r) -{ - return l*r; -} - /////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////// CONJ /////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////////////////////////// - -// Conj function for scalar, vector, matrix -template inline iScalar conj(const iScalar&r) -{ - iScalar ret; - ret._internal = conj(r._internal); - return ret; -} -template inline iVector conj(const iVector&r) -{ - iVector ret; - for(int i=0;i inline iMatrix conj(const iMatrix&r) -{ - iMatrix ret; - for(int i=0;i inline iScalar adj(const iScalar&r) -{ - iScalar ret; - ret._internal = adj(r._internal); - return ret; -} -template inline iVector adj(const iVector&r) -{ - iVector ret; - for(int i=0;i inline iMatrix adj(const iMatrix &arg) -{ - iMatrix ret; - for(int c1=0;c1 - inline typename std::enable_if::value, iMatrix >::type - transpose(iMatrix arg) - { - iMatrix ret; - for(int i=0;i - inline typename std::enable_if::notvalue, iMatrix >::type - transpose(iMatrix arg) - { - iMatrix ret; - for(int i=0;i - inline typename std::enable_if::value, iScalar >::type - transpose(iScalar arg) - { - iScalar ret; - ret._internal = transpose(arg._internal); // NB recurses - return ret; - } - -template - inline typename std::enable_if::notvalue, iScalar >::type - transpose(iScalar arg) - { - iScalar ret; - ret._internal = arg._internal; // NB recursion stops - return ret; - } - - -//////////////////////////////////////////////////////////////////////////////////////////// -// Transpose a specific index; instructive to compare this style of recursion termination -// to that of adj; which is easiers? -//////////////////////////////////////////////////////////////////////////////////////////// -template inline - typename std::enable_if,Level>::value, iMatrix >::type -transposeIndex (const iMatrix &arg) -{ - iMatrix ret; - for(int i=0;i inline -typename std::enable_if,Level>::notvalue, iMatrix >::type -transposeIndex (const iMatrix &arg) -{ - iMatrix ret; - for(int i=0;i(arg._internal[i][j]); - }} - return ret; -} -template inline -typename std::enable_if,Level>::notvalue, iScalar >::type -transposeIndex (const iScalar &arg) -{ - iScalar ret; - ret._internal=transposeIndex(arg._internal); - return ret; -} -template inline -typename std::enable_if,Level>::value, iScalar >::type -transposeIndex (const iScalar &arg) -{ - return arg; -} - -////////////////////////////////////////////////////////////////// -// Traces: both all indices and a specific index -///////////////////////////////////////////////////////////////// - -inline ComplexF trace( const ComplexF &arg){ return arg;} -inline ComplexD trace( const ComplexD &arg){ return arg;} -inline RealF trace( const RealF &arg){ return arg;} -inline RealD trace( const RealD &arg){ return arg;} - -template inline ComplexF traceIndex(const ComplexF arg) { return arg;} -template inline ComplexD traceIndex(const ComplexD arg) { return arg;} -template inline RealF traceIndex(const RealF arg) { return arg;} -template inline RealD traceIndex(const RealD arg) { return arg;} - -template -inline auto trace(const iMatrix &arg) -> iScalar -{ - iScalar ret; - zeroit(ret._internal); - for(int i=0;i -inline auto trace(const iScalar &arg) -> iScalar -{ - iScalar ret; - ret._internal=trace(arg._internal); - return ret; -} -//////////////////////////////////////////////////////////////////////////////////////////////////////// -// Trace Specific indices. -//////////////////////////////////////////////////////////////////////////////////////////////////////// -/* -template inline -auto traceIndex(const iScalar &arg) -> iScalar(arg._internal)) > -{ - iScalar(arg._internal))> ret; - ret._internal = traceIndex(arg._internal); - return ret; -} -*/ -template inline auto -traceIndex (const iScalar &arg) -> -typename -std::enable_if,Level>::notvalue, - iScalar(arg._internal))> >::type - -{ - iScalar(arg._internal))> ret; - ret._internal=traceIndex(arg._internal); - return ret; -} -template inline auto -traceIndex (const iScalar &arg) -> -typename std::enable_if,Level>::value, - iScalar >::type -{ - return arg; -} - -// If we hit the right index, return scalar and trace it with no further recursion -template inline -auto traceIndex(const iMatrix &arg) -> - typename std::enable_if,Level>::value, // Index matches - iScalar >::type // return scalar -{ - iScalar ret; - zeroit(ret._internal); - for(int i=0;i inline -auto traceIndex(const iMatrix &arg) -> - typename std::enable_if,Level>::notvalue,// No index match - iMatrix(arg._internal[0][0])),N> >::type // return matrix -{ - iMatrix(arg._internal[0][0])),N> ret; - for(int i=0;i(arg._internal[i][j]); - }} - return ret; -} - -////////////////////////////////////////////////////////////////////////////// -// Peek on a specific index; returns a scalar in that index, tensor inherits rest -////////////////////////////////////////////////////////////////////////////// -// If we hit the right index, return scalar with no further recursion - -//template inline ComplexF peekIndex(const ComplexF arg) { return arg;} -//template inline ComplexD peekIndex(const ComplexD arg) { return arg;} -//template inline RealF peekIndex(const RealF arg) { return arg;} -//template inline RealD peekIndex(const RealD arg) { return arg;} - -// Scalar peek, no indices -template inline - auto peekIndex(const iScalar &arg) -> - typename std::enable_if,Level>::value, // Index matches - iScalar >::type // return scalar -{ - return arg; -} -// Vector peek, one index -template inline - auto peekIndex(const iVector &arg,int i) -> - typename std::enable_if,Level>::value, // Index matches - iScalar >::type // return scalar -{ - iScalar ret; // return scalar - ret._internal = arg._internal[i]; - return ret; -} -// Matrix peek, two indices -template inline - auto peekIndex(const iMatrix &arg,int i,int j) -> - typename std::enable_if,Level>::value, // Index matches - iScalar >::type // return scalar -{ - iScalar ret; // return scalar - ret._internal = arg._internal[i][j]; - return ret; -} - -///////////// -// No match peek for scalar,vector,matrix must forward on either 0,1,2 args. Must have 9 routines with notvalue -///////////// -// scalar -template inline - auto peekIndex(const iScalar &arg) -> // Scalar 0 index - typename std::enable_if,Level>::notvalue, // Index does NOT match - iScalar(arg._internal))> >::type -{ - iScalar(arg._internal))> ret; - ret._internal= peekIndex(arg._internal); - return ret; -} -template inline - auto peekIndex(const iScalar &arg,int i) -> // Scalar 1 index - typename std::enable_if,Level>::notvalue, // Index does NOT match - iScalar(arg._internal,i))> >::type -{ - iScalar(arg._internal,i))> ret; - ret._internal=peekIndex(arg._internal,i); - return ret; -} -template inline - auto peekIndex(const iScalar &arg,int i,int j) -> // Scalar, 2 index - typename std::enable_if,Level>::notvalue, // Index does NOT match - iScalar(arg._internal,i,j))> >::type -{ - iScalar(arg._internal,i,j))> ret; - ret._internal=peekIndex(arg._internal,i,j); - return ret; -} -// vector -template inline -auto peekIndex(const iVector &arg) -> - typename std::enable_if,Level>::notvalue, // Index does not match - iVector(arg._internal[0])),N> >::type -{ - iVector(arg._internal[0])),N> ret; - for(int ii=0;ii(arg._internal[ii]); - } - return ret; -} -template inline - auto peekIndex(const iVector &arg,int i) -> - typename std::enable_if,Level>::notvalue, // Index does not match - iVector(arg._internal[0],i)),N> >::type -{ - iVector(arg._internal[0],i)),N> ret; - for(int ii=0;ii(arg._internal[ii],i); - } - return ret; -} -template inline - auto peekIndex(const iVector &arg,int i,int j) -> - typename std::enable_if,Level>::notvalue, // Index does not match - iVector(arg._internal[0],i,j)),N> >::type -{ - iVector(arg._internal[0],i,j)),N> ret; - for(int ii=0;ii(arg._internal[ii],i,j); - } - return ret; -} -// matrix -template inline -auto peekIndex(const iMatrix &arg) -> - typename std::enable_if,Level>::notvalue, // Index does not match - iMatrix(arg._internal[0][0])),N> >::type -{ - iMatrix(arg._internal[0][0])),N> ret; - for(int ii=0;ii(arg._internal[ii][jj]);// Could avoid this because peeking a scalar is dumb - }} - return ret; -} -template inline - auto peekIndex(const iMatrix &arg,int i) -> - typename std::enable_if,Level>::notvalue, // Index does not match - iMatrix(arg._internal[0],i)),N> >::type -{ - iMatrix(arg._internal[0],i)),N> ret; - for(int ii=0;ii(arg._internal[ii][jj],i); - }} - return ret; -} -template inline - auto peekIndex(const iMatrix &arg,int i,int j) -> - typename std::enable_if,Level>::notvalue, // Index does not match - iMatrix(arg._internal[0][0],i,j)),N> >::type -{ - iMatrix(arg._internal[0][0],i,j)),N> ret; - for(int ii=0;ii(arg._internal[ii][jj],i,j); - }} - return ret; -} - - -////////////////////////////////////////////////////////////////////////////// -// Poke a specific index; -////////////////////////////////////////////////////////////////////////////// - -// Scalar poke -template inline - void pokeIndex(iScalar &ret, - const typename std::enable_if,Level>::value,iScalar >::type &arg) -{ - ret._internal = arg._internal; -} -// Vector poke, one index -template inline - void pokeIndex(iVector &ret, - const typename std::enable_if,Level>::value,iScalar >::type &arg,int i) -{ - ret._internal[i] = arg._internal; -} -// Vector poke, two indices -template inline - void pokeIndex(iMatrix &ret, - const typename std::enable_if,Level>::value,iScalar >::type &arg,int i,int j) -{ - ret._internal[i][j] = arg._internal; -} - -///////////// -// No match poke for scalar,vector,matrix must forward on either 0,1,2 args. Must have 9 routines with notvalue -///////////// -// scalar -template inline - void pokeIndex(iScalar &ret, - const typename std::enable_if,Level>::notvalue,iScalar(ret._internal))> >::type &arg) - -{ - pokeIndex(ret._internal,arg._internal); -} -template inline - void pokeIndex(iScalar &ret, - const typename std::enable_if,Level>::notvalue,iScalar(ret._internal,0))> >::type &arg, - int i) - -{ - pokeIndex(ret._internal,arg._internal,i); -} -template inline - void pokeIndex(iScalar &ret, - const typename std::enable_if,Level>::notvalue,iScalar(ret._internal,0,0))> >::type &arg, - int i,int j) - -{ - pokeIndex(ret._internal,arg._internal,i,j); -} - -// Vector -template inline - void pokeIndex(iVector &ret, - const typename std::enable_if,Level>::notvalue,iVector(ret._internal)),N> >::type &arg) - -{ - for(int ii=0;ii(ret._internal[ii],arg._internal[ii]); - } -} -template inline - void pokeIndex(iVector &ret, - const typename std::enable_if,Level>::notvalue,iVector(ret._internal,0)),N> >::type &arg, - int i) - -{ - for(int ii=0;ii(ret._internal[ii],arg._internal[ii],i); - } -} -template inline - void pokeIndex(iVector &ret, - const typename std::enable_if,Level>::notvalue,iVector(ret._internal,0,0)),N> >::type &arg, - int i,int j) - -{ - for(int ii=0;ii(ret._internal[ii],arg._internal[ii],i,j); - } -} - -// Matrix -template inline - void pokeIndex(iMatrix &ret, - const typename std::enable_if,Level>::notvalue,iMatrix(ret._internal)),N> >::type &arg) - -{ - for(int ii=0;ii(ret._internal[ii][jj],arg._internal[ii][jj]); - }} -} -template inline - void pokeIndex(iMatrix &ret, - const typename std::enable_if,Level>::notvalue,iMatrix(ret._internal,0)),N> >::type &arg, - int i) - -{ - for(int ii=0;ii(ret._internal[ii][jj],arg._internal[ii][jj],i); - }} -} -template inline - void pokeIndex(iMatrix &ret, - const typename std::enable_if,Level>::notvalue,iMatrix(ret._internal,0,0)),N> >::type &arg, - int i,int j) - -{ - for(int ii=0;ii(ret._internal[ii][jj],arg._internal[ii][jj],i,j); - }} -} - -///////////////////////////////////////////////////////////////// -// Can only take the real/imag part of scalar objects, since -// lattice objects of different complex nature are non-conformable. -///////////////////////////////////////////////////////////////// -template inline auto real(const iScalar &z) -> iScalar -{ - iScalar ret; - ret._internal = real(z._internal); - return ret; -} -template inline auto real(const iMatrix &z) -> iMatrix -{ - iMatrix ret; - for(int c1=0;c1 inline auto real(const iVector &z) -> iVector -{ - iVector ret; - for(int c1=0;c1 inline auto imag(const iScalar &z) -> iScalar -{ - iScalar ret; - ret._internal = imag(z._internal); - return ret; -} -template inline auto imag(const iMatrix &z) -> iMatrix -{ - iMatrix ret; - for(int c1=0;c1 inline auto imag(const iVector &z) -> iVector -{ - iVector ret; - for(int c1=0;c1