diff --git a/lib/Grid_math_arith.h b/lib/Grid_math_arith.h index aebaaee0..e7b6b4ac 100644 --- a/lib/Grid_math_arith.h +++ b/lib/Grid_math_arith.h @@ -1,745 +1,11 @@ #ifndef GRID_MATH_ARITH_H #define GRID_MATH_ARITH_H -namespace Grid { +#include +#include +#include +#include +#include - - /////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////// 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; -} - -} #endif diff --git a/lib/Grid_math_arith_add.h b/lib/Grid_math_arith_add.h new file mode 100644 index 00000000..7e62e07b --- /dev/null +++ b/lib/Grid_math_arith_add.h @@ -0,0 +1,122 @@ +#ifndef GRID_MATH_ARITH_ADD_H +#define GRID_MATH_ARITH_ADD_H + +namespace Grid { + + + /////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////// 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; + } + + + +} + +#endif diff --git a/lib/Grid_math_arith_mac.h b/lib/Grid_math_arith_mac.h new file mode 100644 index 00000000..59cb9a5e --- /dev/null +++ b/lib/Grid_math_arith_mac.h @@ -0,0 +1,81 @@ +#ifndef GRID_MATH_ARITH_MAC_H +#define GRID_MATH_ARITH_MAC_H + +namespace Grid { + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////// 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; +} + + +} + +#endif diff --git a/lib/Grid_math_arith_mul.h b/lib/Grid_math_arith_mul.h new file mode 100644 index 00000000..c8bb0b2c --- /dev/null +++ b/lib/Grid_math_arith_mul.h @@ -0,0 +1,189 @@ +#ifndef GRID_MATH_ARITH_MUL_H +#define GRID_MATH_ARITH_MUL_H + +namespace Grid { + + + /////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////// 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; +} + + +} +#endif diff --git a/lib/Grid_math_arith_sub.h b/lib/Grid_math_arith_sub.h new file mode 100644 index 00000000..3a58bf4c --- /dev/null +++ b/lib/Grid_math_arith_sub.h @@ -0,0 +1,134 @@ +#ifndef GRID_MATH_ARITH_SUB_H +#define GRID_MATH_ARITH_SUB_H + +namespace Grid { + + + /////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////// 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; +} + + +} + +#endif