#ifdef USING__Calc_only #include "Term.H" #include "Tools.H" #include "Vector.H" #else #include "ATOOLS/Org/STL_Tools.H" #include "ATOOLS/Math/Term.H" #include "ATOOLS/Math/MathTools.H" #include "ATOOLS/Math/Vector.H" #include "ATOOLS/Org/MyStrStream.H" #include "ATOOLS/Org/Exception.H" #include "ATOOLS/Org/CXXFLAGS.H" #endif namespace ATOOLS { inline bool IsNum(const char c) { return c>=48 && c<=57; } bool IsAlpha(const std::string &expr) { bool ad(true), ae(true); for (size_t i=0;i class TermDelete_Vector: public std::vector<_Type*> { public: TermDelete_Vector() { } ~TermDelete_Vector() { while (!this->empty()) { delete this->back(); this->pop_back(); } } inline void MtxLock() { } inline void MtxUnLock() { } };// end of class TermDelete_Vector class DTerm: public Term { private: double m_this; friend class Term; static AutoDelete_Vector s_terms; inline DTerm(const double &val=0.0): Term('D'), m_this(val) {} public: static DTerm *New(const double &val=0.0) { #ifndef USING__Threading if (s_terms.empty()) #endif return new DTerm(val); DTerm *term(s_terms.back()); s_terms.pop_back(); term->m_this=val; return term; } void Delete() { #ifndef USING__Threading s_terms.push_back(this); #else delete this; #endif } };// end of class DTerm struct CTerm: public Term { private: Complex m_this; friend class Term; static AutoDelete_Vector s_terms; inline CTerm(const Complex &val=Complex(0.0,0.0)): Term('C'), m_this(val) {} public: static CTerm *New(const Complex &val=Complex(0.0,0.0)) { #ifndef USING__Threading if (s_terms.empty()) #endif return new CTerm(val); CTerm *term(s_terms.back()); s_terms.pop_back(); term->m_this=val; return term; } void Delete() { #ifndef USING__Threading s_terms.push_back(this); #else delete this; #endif } };// end of class CTerm struct DV4Term: public Term { private: Vec4D m_this; friend class Term; static AutoDelete_Vector s_terms; inline DV4Term(const Vec4D &val): Term('V'), m_this(val) {} public: static DV4Term *New(const Vec4D &val) { #ifndef USING__Threading if (s_terms.empty()) #endif return new DV4Term(val); DV4Term *term(s_terms.back()); s_terms.pop_back(); term->m_this=val; return term; } void Delete() { #ifndef USING__Threading s_terms.push_back(this); #else delete this; #endif } };// end of class DV4Term struct STerm: public Term { private: std::string m_this; friend class Term; static AutoDelete_Vector s_terms; inline STerm(const std::string &val): Term('S'), m_this(val) {} public: static STerm *New(const std::string &val) { #ifndef USING__Threading if (s_terms.empty()) #endif return new STerm(val); STerm *term(s_terms.back()); s_terms.pop_back(); term->m_this=val; return term; } void Delete() { #ifndef USING__Threading s_terms.push_back(this); #else delete this; #endif } };// end of class STerm AutoDelete_Vector DTerm::s_terms; AutoDelete_Vector CTerm::s_terms; AutoDelete_Vector DV4Term::s_terms; AutoDelete_Vector STerm::s_terms; template <> const double &Term::Get() const { return static_cast(this)->m_this; } template <> const Complex &Term::Get() const { return static_cast(this)->m_this; } template <> const Vec4D &Term::Get() const { return static_cast(this)->m_this; } template <> const std::string &Term::Get() const { return static_cast(this)->m_this; } Term::~Term() {} void Term::Print(std::ostream &ostr) const { if (m_type=='S') ostr<(); else if (m_type=='V') ostr<(); else if (m_type=='C') ostr<(); else ostr<(); } std::ostream &operator<<(std::ostream &ostr,const Term &t) { t.Print(ostr); return ostr; } template <> void Term::Set(const double &val) { static_cast(this)->m_this=val; } template <> void Term::Set(const Complex &val) { static_cast(this)->m_this=val; } template <> void Term::Set(const Vec4D &val) { static_cast(this)->m_this=val; } template <> void Term::Set(const std::string &val) { static_cast(this)->m_this=val; } void Term::SetTerm(const std::string &tag) { if (tag[0]!='(') { if (tag[0]=='"' && tag[tag.length()-1]=='"') static_cast(this)->m_this=tag.substr(1,tag.length()-2); else if (IsAlpha(tag)) static_cast(this)->m_this=(tag); else static_cast(this)->m_this=ToType(tag); } else { size_t pos(tag.find(',')); if (pos==std::string::npos) THROW(fatal_error,"Invalid syntax"); if ((pos=tag.find(',',pos+1))!=std::string::npos) static_cast(this)->m_this=ToType(tag); else static_cast(this)->m_this=ToType(tag); } } template <> Term *Term::New(const double &val) { return DTerm::New(val); } template <> Term *Term::New(const Complex &val) { return CTerm::New(val); } template <> Term *Term::New(const Vec4D &val) { return DV4Term::New(val); } template <> Term *Term::New(const std::string &val) { return STerm::New(val); } Term *Term::NewTerm(const std::string &tag) { if (tag[0]!='(') { if (tag[0]=='"' && tag[tag.length()-1]=='"') return STerm::New(tag.substr(1,tag.length()-2)); if (IsAlpha(tag)) return STerm::New(tag); return DTerm::New(ToType(tag)); } else { size_t pos(tag.find(',')); if (pos==std::string::npos) THROW(fatal_error,"Invalid syntax"); if ((pos=tag.find(',',pos+1))!=std::string::npos) return DV4Term::New(ToType(tag)); return CTerm::New(ToType(tag)); } } Term *Term::operator-() const { if (m_type=='S') THROW(fatal_error,"Invalid syntax"); if (m_type=='V') return DV4Term::New(-Get()); if (m_type=='C') return CTerm::New(-Get()); return DTerm::New(-Get()); } Term *Term::operator!() const { if (m_type=='C') return CTerm::New(!(int)(Get().real())); if (m_type=='D') return DTerm::New(!(int)(Get())); THROW(fatal_error,"Invalid syntax"); return NULL; } Term *TVec4D(const Term &t0,const Term &t1, const Term &t2,const Term &t3) { if (t0.Type()=='V' || t0.Type()=='C' || t0.Type()=='S' || t1.Type()=='V' || t1.Type()=='C' || t1.Type()=='S' || t2.Type()=='V' || t2.Type()=='C' || t2.Type()=='S' || t3.Type()=='V' || t3.Type()=='C' || t3.Type()=='S') THROW(fatal_error,"Invalid syntax"); return DV4Term::New(Vec4D(t0.Get(),t1.Get(), t2.Get(),t3.Get())); } #define DEFINE_BINARY_STERM_OPERATOR(OP)\ Term *Term::operator OP(const Term &ref) const\ {\ if (m_type=='S' || ref.m_type=='S')\ THROW(fatal_error,"Invalid syntax");\ if (m_type=='V') {\ if (ref.m_type=='V')\ return DV4Term::New(Get() OP ref.Get());\ THROW(fatal_error,"Invalid syntax");\ return NULL;\ }\ if (m_type=='C') {\ if (ref.m_type=='C')\ return CTerm::New(Get() OP ref.Get());\ if (ref.m_type=='D')\ return CTerm::New(Get() OP ref.Get());\ THROW(fatal_error,"Invalid syntax");\ return NULL;\ }\ if (ref.m_type=='C')\ return CTerm::New(Get() OP ref.Get());\ return DTerm::New(Get() OP ref.Get());\ } DEFINE_BINARY_STERM_OPERATOR(+) DEFINE_BINARY_STERM_OPERATOR(-) Term *Term::operator*(const Term &ref) const { if (m_type=='S' || ref.m_type=='S') THROW(fatal_error,"Invalid syntax"); if (m_type=='V') { if (ref.m_type=='V') return DTerm::New(Get()*ref.Get()); if (ref.m_type=='D') return DV4Term::New(ref.Get()*Get()); THROW(fatal_error,"Invalid syntax"); return NULL; } if (m_type=='C') { if (ref.m_type=='C') return CTerm::New(Get()*ref.Get()); if (ref.m_type=='D') return CTerm::New(Get()*ref.Get()); THROW(fatal_error,"Invalid syntax"); return NULL; } if (ref.m_type=='V') return DV4Term::New(Get()*ref.Get()); if (ref.m_type=='C') return CTerm::New(Get()*ref.Get()); return DTerm::New(Get()*ref.Get()); } Term *Term::operator/(const Term &ref) const { if (m_type=='S' || ref.m_type=='S') THROW(fatal_error,"Invalid syntax"); if (m_type=='V') { if (ref.m_type=='D') return DV4Term::New(1.0/ref.Get()*Get()); THROW(fatal_error,"Invalid syntax"); return NULL; } if (m_type=='C') { if (ref.m_type=='C') return CTerm::New(Get()/ref.Get()); if (ref.m_type=='D') return CTerm::New(Get()/ref.Get()); THROW(fatal_error,"Invalid syntax"); return NULL; } if (ref.m_type=='C') return CTerm::New(Get()/ref.Get()); return DTerm::New(Get()/ref.Get()); } #define DEFINE_BINARY_BTERM_OPERATOR(OP)\ Term *Term::operator OP(const Term &ref) const\ {\ if (m_type=='S' || ref.m_type=='S') {\ if (m_type!='S' || ref.m_type!='S')\ THROW(fatal_error,"Invalid syntax");\ return DTerm::New(Get() OP ref.Get());\ }\ if (m_type=='V' || ref.m_type=='V')\ THROW(fatal_error,"Invalid syntax");\ if (m_type=='C') {\ if (ref.m_type=='C')\ return DTerm::New(Get() OP ref.Get());\ return DTerm::New(Get() OP ref.Get());\ }\ if (ref.m_type=='C')\ return DTerm::New(Get() OP ref.Get());\ return DTerm::New(Get() OP ref.Get());\ } bool operator<(const Complex &a,const Complex &b) { return a.real()(const Complex &a,const Complex &b) { return a.real()>b.real() && a.imag()>b.imag(); } bool operator<=(const Complex &a,const Complex &b) { return !(a>b); } bool operator>=(const Complex &a,const Complex &b) { return !(a=) DEFINE_BINARY_BTERM_OPERATOR(<) DEFINE_BINARY_BTERM_OPERATOR(>) #define DEFINE_BINARY_ITERM_OPERATOR(OP)\ Term *Term::operator OP(const Term &ref) const\ {\ if (m_type=='S' || ref.m_type=='S' ||\ m_type=='V' || ref.m_type=='V')\ THROW(fatal_error,"Invalid syntax");\ if (m_type=='C') {\ if (ref.m_type=='C') \ return DTerm::New((long int)(Get().real()) OP\ (long int)(ref.Get().real()));\ return DTerm::New((long int)(Get().real()) OP\ (long int)(ref.Get()));\ }\ if (ref.m_type=='C')\ return DTerm::New((long int)(Get()) OP\ (long int)(ref.Get().real()));\ return DTerm::New((long int)(Get()) OP\ (long int)(ref.Get()));\ } DEFINE_BINARY_ITERM_OPERATOR(%) DEFINE_BINARY_ITERM_OPERATOR(<<) DEFINE_BINARY_ITERM_OPERATOR(>>) DEFINE_BINARY_ITERM_OPERATOR(&&) DEFINE_BINARY_ITERM_OPERATOR(||) DEFINE_BINARY_ITERM_OPERATOR(&) DEFINE_BINARY_ITERM_OPERATOR(^) DEFINE_BINARY_ITERM_OPERATOR(|) #define DEFINE_UNARY_DTERM_FUNCTION(NAME,FUNC)\ Term *NAME(const Term &t)\ {\ if (t.Type()=='S' || t.Type()=='V')\ THROW(fatal_error,"Invalid syntax");\ if (t.Type()=='C') return NULL;\ return DTerm::New(FUNC(t.Get()));\ } DEFINE_UNARY_DTERM_FUNCTION(TSgn,Sign) DEFINE_UNARY_DTERM_FUNCTION(TTheta,Theta) DEFINE_UNARY_DTERM_FUNCTION(TASin,asin) DEFINE_UNARY_DTERM_FUNCTION(TACos,acos) DEFINE_UNARY_DTERM_FUNCTION(TATan,atan) #define DEFINE_UNARY_TERM_FUNCTION(NAME,FUNC)\ Term *NAME(const Term &t)\ {\ if (t.Type()=='S' || t.Type()=='V')\ THROW(fatal_error,"Invalid syntax");\ if (t.Type()=='C')\ return CTerm::New(FUNC(t.Get()));\ return DTerm::New(FUNC(t.Get()));\ } DEFINE_UNARY_TERM_FUNCTION(TExp,exp) DEFINE_UNARY_TERM_FUNCTION(TLog,log) DEFINE_UNARY_TERM_FUNCTION(TLog10,log10) DEFINE_UNARY_TERM_FUNCTION(TAbs,std::abs) DEFINE_UNARY_TERM_FUNCTION(TSqr,sqr) DEFINE_UNARY_TERM_FUNCTION(TSqrt,sqrt) DEFINE_UNARY_TERM_FUNCTION(TSin,sin) DEFINE_UNARY_TERM_FUNCTION(TCos,cos) DEFINE_UNARY_TERM_FUNCTION(TTan,tan) DEFINE_UNARY_TERM_FUNCTION(TSinh,sinh) DEFINE_UNARY_TERM_FUNCTION(TCosh,cosh) DEFINE_UNARY_TERM_FUNCTION(TTanh,tanh) #define DEFINE_BINARY_DTERM_FUNCTION(NAME,FUNC)\ Term *NAME(const Term &t1,const Term &t2)\ {\ if (t1.Type()!='D' || t2.Type()!='D')\ THROW(fatal_error,"Invalid syntax");\ return DTerm::New(FUNC(t1.Get(),t2.Get()));\ } DEFINE_BINARY_DTERM_FUNCTION(TMin,Min) DEFINE_BINARY_DTERM_FUNCTION(TMax,Max) #define DEFINE_BINARY_TERM_FUNCTION(NAME,FUNC)\ Term *NAME(const Term &t1,const Term &t2)\ {\ if (t1.Type()=='S' || t2.Type()=='S' ||\ t1.Type()=='V' || t2.Type()=='V')\ THROW(fatal_error,"Invalid syntax");\ if (t1.Type()=='C') {\ if (t2.Type()=='C')\ return CTerm::New(FUNC(t1.Get(),t2.Get()));\ return CTerm::New(FUNC(t1.Get(),t2.Get()));\ }\ if (t2.Type()=='C')\ return CTerm::New(FUNC(t1.Get(),t2.Get()));\ return DTerm::New(FUNC(t1.Get(),t2.Get()));\ } DEFINE_BINARY_TERM_FUNCTION(TPow,pow) Term *Term::Real() const { if (m_type=='S' || m_type=='V' || m_type=='D') THROW(fatal_error,"Invalid syntax"); return DTerm::New(Get().real()); } Term *Term::Imag() const { if (m_type=='S' || m_type=='V' || m_type=='D') THROW(fatal_error,"Invalid syntax"); return DTerm::New(Get().imag()); } Term *Term::Conj() const { if (m_type=='S' || m_type=='V' || m_type=='D') THROW(fatal_error,"Invalid syntax"); return CTerm::New(std::conj(Get())); } Term *Term::Comp(const Term &i) const { if (m_type=='V' && i.m_type=='D') return DTerm::New(Get()[(int)(i.Get())]); THROW(fatal_error,"Invalid syntax"); return NULL; } #define DEFINE_UNARY_VVTERM_FUNCTION(FUNC)\ Term *Term::FUNC() const\ {\ if (m_type=='V') return DV4Term::New(Get().FUNC());\ THROW(fatal_error,"Invalid syntax");\ return NULL;\ } DEFINE_UNARY_VVTERM_FUNCTION(Perp) DEFINE_UNARY_VVTERM_FUNCTION(Plus) DEFINE_UNARY_VVTERM_FUNCTION(Minus) #define DEFINE_UNARY_VTERM_FUNCTION(FUNC)\ Term *Term::FUNC() const\ {\ if (m_type=='V') return DTerm::New(Get().FUNC());\ THROW(fatal_error,"Invalid syntax");\ return NULL;\ } DEFINE_UNARY_VTERM_FUNCTION(PPlus) DEFINE_UNARY_VTERM_FUNCTION(PMinus) DEFINE_UNARY_VTERM_FUNCTION(Abs2) DEFINE_UNARY_VTERM_FUNCTION(Mass) DEFINE_UNARY_VTERM_FUNCTION(PSpat) DEFINE_UNARY_VTERM_FUNCTION(PPerp) DEFINE_UNARY_VTERM_FUNCTION(PPerp2) DEFINE_UNARY_VTERM_FUNCTION(MPerp) DEFINE_UNARY_VTERM_FUNCTION(MPerp2) DEFINE_UNARY_VTERM_FUNCTION(Theta) DEFINE_UNARY_VTERM_FUNCTION(Eta) DEFINE_UNARY_VTERM_FUNCTION(Y) DEFINE_UNARY_VTERM_FUNCTION(Phi) #define DEFINE_BINARY_VTERM_FUNCTION(FUNC)\ Term *Term::FUNC(const Term &ref) const\ {\ if (m_type=='V' && ref.m_type=='V')\ return DTerm::New(Get().FUNC(ref.Get()));\ THROW(fatal_error,"Invalid syntax");\ return NULL;\ } DEFINE_BINARY_VTERM_FUNCTION(PPerp) DEFINE_BINARY_VTERM_FUNCTION(Theta) DEFINE_BINARY_VTERM_FUNCTION(DEta) DEFINE_BINARY_VTERM_FUNCTION(DY) DEFINE_BINARY_VTERM_FUNCTION(DPhi) DEFINE_BINARY_VTERM_FUNCTION(DR) }// end of namespace ATOOLS