// -*- C++ -*- /*************************************************************************** * * The IPPL Framework * * * Visit http://people.web.psi.ch/adelmann/ for more details * ***************************************************************************/ /////////////////////////////////////////////////////////////////////////// // // FILE NAME // IpplTypeComputations.h // // CREATED // July 11, 1997 // // DESCRIPTION // PETE: Portable Expression Template Engine. // // This header file contains IPPL-specific type computations. // /////////////////////////////////////////////////////////////////////////// #ifndef IPPL_TYPE_COMPUTATIONS_H #define IPPL_TYPE_COMPUTATIONS_H // include files #include "PETE/TypeComputations.h" #include // forward declarations template class Vektor; template class Tenzor; template class AntiSymTenzor; template class SymTenzor; class RNGBitReverse; template class RNGLattice; class RNGSimple; class RNGRand; class RNGXDiv; class RNGXCI; // definition of global sign function template inline int sign(T a) { return ((a > 0) ? 1 : (a == 0 ? 0 : -1)); } /////////////////////////////////////////////////////////////////////////// // // PETE_Type2Index FOR USER TYPES // /////////////////////////////////////////////////////////////////////////// // Complex numbers. template<> struct PETE_Type2Index> { enum { val = 8 }; }; // Return types for scalar ops with RNGs. #define _SCALAR_RNG_OP_RETURNS_(GEN,SCA,OP) \ template <> \ struct PETEBinaryReturn { \ typedef PETEBinaryReturn::type type; \ }; \ template <> \ struct PETEBinaryReturn { \ typedef PETEBinaryReturn::type type; \ }; #define _SCALAR_RNG_RETURNS_(GEN,SCA) \ _SCALAR_RNG_OP_RETURNS_(GEN,SCA,OpAdd) \ _SCALAR_RNG_OP_RETURNS_(GEN,SCA,OpSubtract) \ _SCALAR_RNG_OP_RETURNS_(GEN,SCA,OpMultipply) \ _SCALAR_RNG_OP_RETURNS_(GEN,SCA,OpDivide) #define _PETE_RNG_RETURNS_(GEN) \ \ template <> struct PETE_Type2Index< GEN > { \ enum { val = PETE_Type2Index::val }; \ }; \ \ _SCALAR_RNG_RETURNS_(GEN,short) \ _SCALAR_RNG_RETURNS_(GEN,int) \ _SCALAR_RNG_RETURNS_(GEN,long) \ _SCALAR_RNG_RETURNS_(GEN,float) \ _SCALAR_RNG_RETURNS_(GEN,double) \ _SCALAR_RNG_RETURNS_(GEN,std::complex) _PETE_RNG_RETURNS_(RNGBitReverse) _PETE_RNG_RETURNS_(RNGLattice) _PETE_RNG_RETURNS_(RNGLattice) _PETE_RNG_RETURNS_(RNGSimple) _PETE_RNG_RETURNS_(RNGRand) _PETE_RNG_RETURNS_(RNGXDiv) _PETE_RNG_RETURNS_(RNGXCI) // Life is way easier with this feature. template struct PETE_Type2Index< Vektor > { enum { val = 20 + 10 * Dim + PETE_Type2Index::val }; }; template struct PETE_Type2Index< SymTenzor > { enum { val = 120 + 10 * Dim + PETE_Type2Index::val }; }; template struct PETE_Type2Index< Tenzor > { enum { val = 220 + 10 * Dim + PETE_Type2Index::val }; }; template struct PETE_Type2Index< AntiSymTenzor > { enum { val = 320 + 10 * Dim + PETE_Type2Index::val }; }; /////////////////////////////////////////////////////////////////////////// // // SPECIAL CASES FOR UNARY FUNCTIONS // /////////////////////////////////////////////////////////////////////////// // Abs function: special return for complex numbers. struct FnAbs { enum { tag = PETE_UnaryPassThruTag }; }; template<> struct PETEUnaryReturn, FnAbs> { typedef double type; }; // The conj, norm, arg, real, and imag functions for complex numbers. struct FnConj { enum { tag = PETE_UnaryPassThruTag }; }; struct FnNorm { typedef double type; enum { tag = PETE_Type2Index::val }; }; template<> struct PETEUnaryReturn, FnNorm> { typedef double type; }; struct FnArg { typedef double type; enum { tag = PETE_Type2Index::val }; }; template<> struct PETEUnaryReturn, FnArg> { typedef double type; }; struct FnReal { typedef double type; enum { tag = PETE_Type2Index::val }; }; template<> struct PETEUnaryReturn, FnReal> { typedef double type; }; struct FnImag { typedef double type; enum { tag = PETE_Type2Index::val }; }; template<> struct PETEUnaryReturn, FnImag> { typedef double type; }; // The sign function. struct FnSign { typedef int type; enum { tag = PETE_Type2Index::val }; }; template struct OpParens { enum { tag = PETE_UnaryPassThruTag }; TP Arg; OpParens() { Arg = TP(); } OpParens(const TP& a) : Arg(a) {} }; // Tensor functions: trace, det (determinant), and transpose struct FnTrace { enum { tag = PETE_UnaryPassThruTag }; }; struct FnDet { enum { tag = PETE_UnaryPassThruTag }; }; struct FnTranspose { enum { tag = PETE_UnaryPassThruTag }; }; struct FnCofactors { enum { tag = PETE_UnaryPassThruTag }; }; // Life is pretty simple if we have partial specialization. template struct PETEUnaryReturn, FnTrace> { typedef T type; }; template struct PETEUnaryReturn, FnTrace> { typedef T type; }; template struct PETEUnaryReturn, FnTrace> { typedef T type; }; template struct PETEUnaryReturn, FnDet> { typedef T type; }; template struct PETEUnaryReturn, FnDet> { typedef T type; }; template struct PETEUnaryReturn, FnDet> { typedef T type; }; template struct PETEUnaryReturn, FnTranspose> { typedef Tenzor type; }; template struct PETEUnaryReturn, FnTranspose> { typedef SymTenzor type; }; template struct PETEUnaryReturn, FnTranspose> { typedef AntiSymTenzor type; }; template struct PETEUnaryReturn, FnCofactors> { typedef Tenzor type; }; template struct PETEUnaryReturn, FnCofactors> { typedef SymTenzor type; }; template struct PETEUnaryReturn, FnCofactors> { typedef AntiSymTenzor type; }; /////////////////////////////////////////////////////////////////////////// // // SPECIAL CASES FOR BINARY FUNCTIONS // /////////////////////////////////////////////////////////////////////////// // Min and Max functions. struct FnMin { enum { tag = PETE_BinaryPromoteTag }; }; struct FnMax { enum { tag = PETE_BinaryPromoteTag }; }; // Dot, dot-dot, and outerProduct functions. struct FnDot { enum { tag = PETE_BinaryPromoteTag }; }; struct FnDotDot { enum { tag = PETE_BinaryPromoteTag }; }; struct FnOuterProduct { enum { tag = PETE_BinaryPromoteTag }; }; // Cross-product: struct FnCross { enum { tag = PETE_BinaryPromoteTag }; }; // Involving Vektors: template struct PETEBinaryReturn,Vektor, FnCross> { typedef Vektor::type,Dim> type; }; template struct PETEBinaryReturn,Vektor, FnOuterProduct> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,Vektor, FnDot> { typedef typename PETEBinaryReturn::type type; }; // Involving Tenzors, but no combination with SymTenzors or AntiSymTenzors: template struct PETEBinaryReturn,Tenzor,FnDot> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,Tenzor, FnDot> { typedef Vektor::type,Dim> type; }; template struct PETEBinaryReturn,Vektor, FnDot> { typedef Vektor::type,Dim> type; }; template struct PETEBinaryReturn,Tenzor,FnDotDot> { typedef typename PETEBinaryReturn::type type; }; // Involving SymTenzors, possibly combined with Tenzors: template struct PETEBinaryReturn,SymTenzor, FnDot> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,SymTenzor, FnDotDot> { typedef typename PETEBinaryReturn::type type; }; template struct PETEBinaryReturn,SymTenzor, FnDot> { typedef Vektor::type,Dim> type; }; template struct PETEBinaryReturn,Vektor, FnDot> { typedef Vektor::type,Dim> type; }; template struct PETEBinaryReturn,SymTenzor,OpAdd> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,SymTenzor,OpSubtract> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,SymTenzor,OpMultipply> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,SymTenzor, FnDot> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,SymTenzor, FnDotDot> { typedef typename PETEBinaryReturn::type type; }; template struct PETEBinaryReturn,Tenzor,OpAdd> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,Tenzor,OpSubtract> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,Tenzor,FnDot> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,Tenzor,FnDotDot> { typedef typename PETEBinaryReturn::type type; }; // Involving AntiSymTenzors, possibly combined with Tenzors or SymTenzors: template struct PETEBinaryReturn,AntiSymTenzor, FnDot> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,AntiSymTenzor, FnDotDot> { typedef typename PETEBinaryReturn::type type; }; template struct PETEBinaryReturn,AntiSymTenzor, FnDot> { typedef Vektor::type,Dim> type; }; template struct PETEBinaryReturn,Vektor, FnDot> { typedef Vektor::type,Dim> type; }; template struct PETEBinaryReturn,AntiSymTenzor,OpAdd> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,AntiSymTenzor,OpSubtract> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,AntiSymTenzor,OpMultipply> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,AntiSymTenzor, FnDot> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,AntiSymTenzor, FnDotDot> { typedef typename PETEBinaryReturn::type type; }; template struct PETEBinaryReturn,Tenzor,OpAdd> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,Tenzor,OpSubtract> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,Tenzor,FnDot> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,Tenzor,FnDotDot> { typedef typename PETEBinaryReturn::type type; }; template struct PETEBinaryReturn,AntiSymTenzor,OpAdd> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,AntiSymTenzor,OpSubtract> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,AntiSymTenzor,OpMultipply> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,AntiSymTenzor, FnDot> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,AntiSymTenzor, FnDotDot> { typedef typename PETEBinaryReturn::type type; }; template struct PETEBinaryReturn,SymTenzor,OpAdd> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,SymTenzor,OpSubtract> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,SymTenzor,FnDot> { typedef Tenzor::type,Dim> type; }; template struct PETEBinaryReturn,SymTenzor,FnDotDot> { typedef typename PETEBinaryReturn::type type; }; // Need to specify scalar operations directly. #define _SCALAR_VST_RETURNS_(Sca) \ template \ struct PETEBinaryReturn,Sca,OpMultipply> { \ typedef Vektor::type,Dim> \ type; \ }; \ template \ struct PETEBinaryReturn,OpMultipply> { \ typedef Vektor::type,Dim> \ type; \ }; \ template \ struct PETEBinaryReturn,Sca,OpDivide> { \ typedef Vektor::type,Dim> \ type; \ }; \ template \ struct PETEBinaryReturn,Sca,OpMultipply> { \ typedef Tenzor::type,Dim> \ type; \ }; \ template \ struct PETEBinaryReturn,OpMultipply> { \ typedef Tenzor::type,Dim> \ type; \ }; \ template \ struct PETEBinaryReturn,Sca,OpDivide> { \ typedef Tenzor::type,Dim> \ type; \ }; \ template \ struct PETEBinaryReturn,Sca,OpMultipply> { \ typedef SymTenzor::type,Dim> \ type; \ }; \ template \ struct PETEBinaryReturn,OpMultipply> { \ typedef SymTenzor::type,Dim> \ type; \ }; \ template \ struct PETEBinaryReturn,Sca,OpDivide> { \ typedef SymTenzor::type,Dim> \ type; \ }; \ template \ struct PETEBinaryReturn,Sca,OpMultipply> { \ typedef \ AntiSymTenzor::type,Dim> \ type; \ }; \ template \ struct PETEBinaryReturn,OpMultipply> { \ typedef \ AntiSymTenzor::type,Dim> \ type; \ }; \ template \ struct PETEBinaryReturn,Sca,OpDivide> { \ typedef \ AntiSymTenzor::type,Dim> \ type; \ }; _SCALAR_VST_RETURNS_(short) _SCALAR_VST_RETURNS_(int) _SCALAR_VST_RETURNS_(long) _SCALAR_VST_RETURNS_(float) _SCALAR_VST_RETURNS_(double) _SCALAR_VST_RETURNS_(std::complex) #undef _SCALAR_VST_RETURNS_ /////////////////////////////////////////////////////////////////////////// // // ASSIGNMENT OPERATORS: min=, max=, &&=, ||= // /////////////////////////////////////////////////////////////////////////// struct OpMinAssign { enum { tag = PETE_BinaryUseLeftTag }; }; struct OpMaxAssign { enum { tag = PETE_BinaryUseLeftTag }; }; struct OpAndAssign { enum { tag = PETE_BinaryUseLeftTag }; }; struct OpOrAssign { enum { tag = PETE_BinaryUseLeftTag }; }; /////////////////////////////////////////////////////////////////////////// // // OPERATOR() // /////////////////////////////////////////////////////////////////////////// template struct PETEUnaryReturn< Vektor, OpParens > { typedef T type; }; template struct PETEUnaryReturn< AntiSymTenzor, OpParens > { typedef T type; }; template struct PETEUnaryReturn< SymTenzor, OpParens > { typedef T type; }; template struct PETEUnaryReturn< Tenzor, OpParens > { typedef T type; }; #endif // IPPL_TYPE_COMPUTATIONS_H