Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/root/TComplex.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // @(#)root/mathcore:$Id$
0002 // Author: Federico Carminati   22/04/2004
0003 
0004 /*************************************************************************
0005  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
0006  * All rights reserved.                                                  *
0007  *                                                                       *
0008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010  *************************************************************************/
0011 
0012 #ifndef ROOT_TComplex
0013 #define ROOT_TComplex
0014 
0015 //////////////////////////////////////////////////////////////////////////
0016 //                                                                      //
0017 // TComplex                                                             //
0018 //                                                                      //
0019 //////////////////////////////////////////////////////////////////////////
0020 
0021 #include "TMath.h"
0022 
0023 #include "Rtypes.h"
0024 
0025 #include <string>
0026 #include <type_traits>
0027 
0028 
0029 class TComplex {
0030 
0031 protected:
0032    Double_t fRe;    // real part
0033    Double_t fIm;    // imaginary part
0034 
0035 public:
0036    // ctors and dtors
0037    TComplex(): fRe(0), fIm(0) {}
0038    TComplex(Double_t re, Double_t im=0, Bool_t polar=kFALSE);
0039    virtual ~TComplex() {}
0040 
0041    // constants
0042    static TComplex I() {return TComplex(0,1);}
0043    static TComplex One() {return TComplex(1,0);}
0044 
0045    // getters and setters
0046    Double_t Re() const {return fRe;}
0047    Double_t Im() const {return fIm;}
0048    Double_t Rho() const {return TMath::Sqrt(fRe*fRe+fIm*fIm);}
0049    Double_t Rho2() const {return fRe*fRe+fIm*fIm;}
0050    Double_t Theta() const {return (fIm||fRe)?TMath::ATan2(fIm,fRe):0;}
0051    TComplex operator()(Double_t x, Double_t y, Bool_t polar=kFALSE)
0052       { if (polar) { fRe = x*TMath::Cos(y); fIm = x*TMath::Sin(y); }
0053         else { fRe = x; fIm = y; } return *this; }
0054 
0055    // Simple operators complex - complex
0056    TComplex operator *(const TComplex & c) const
0057       {return TComplex(fRe*c.fRe-fIm*c.fIm,fRe*c.fIm+fIm*c.fRe);}
0058    TComplex operator +(const TComplex & c) const
0059       {return TComplex(fRe+c.fRe, fIm+c.fIm);}
0060    TComplex operator /(const TComplex & c) const
0061       {return TComplex(fRe*c.fRe+fIm*c.fIm,-fRe*c.fIm+fIm*c.fRe)/c.Rho2();}
0062    TComplex operator -(const TComplex & c) const
0063       {return TComplex(fRe-c.fRe, fIm-c.fIm);}
0064 
0065    TComplex operator *=(const TComplex & c)
0066       {return ((*this) = (*this) * c);}
0067    TComplex operator +=(const TComplex & c)
0068       {return ((*this) = (*this) + c);}
0069    TComplex operator /=(const TComplex & c)
0070       {return ((*this) = (*this) / c);}
0071    TComplex operator -=(const TComplex & c)
0072       {return ((*this) = (*this) - c);}
0073 
0074    TComplex operator -()
0075       {return TComplex(-fRe,-fIm);}
0076    TComplex operator +()
0077       {return *this;}
0078 
0079    // Metafunction to figure out whether a type is arithmetic. This is used for
0080    // the arithmetic operator implementation, so we can be sure that nothing
0081    // unexpected will happen for non-arithmetic types that implement these
0082    // operators with `double` themselves.
0083    template<class T>
0084    using enable_if_arithmetic = typename std::enable_if<std::is_arithmetic<T>::value, bool>::type;
0085 
0086    // Simple operators complex - arithmetic
0087    template <class T, enable_if_arithmetic<T> = true>
0088    TComplex operator *(T c) const { return {fRe*c,fIm*c}; }
0089    template <class T, enable_if_arithmetic<T> = true>
0090    TComplex operator +(T c) const { return {fRe+c, fIm}; }
0091    template <class T, enable_if_arithmetic<T> = true>
0092    TComplex operator /(T c) const { return {fRe/c,fIm/c}; }
0093    template <class T, enable_if_arithmetic<T> = true>
0094    TComplex operator -(T c) const { return {fRe-c, fIm}; }
0095 
0096    // Simple operators arithmetic - complex
0097    template <class T, enable_if_arithmetic<T> = true>
0098    friend TComplex operator *(T d, const TComplex & c) { return {d*c.fRe,d*c.fIm}; }
0099    template <class T, enable_if_arithmetic<T> = true>
0100    friend TComplex operator +(T d, const TComplex & c) { return {d+c.fRe, c.fIm}; }
0101    template <class T, enable_if_arithmetic<T> = true>
0102    friend TComplex operator /(T d, const TComplex & c) { return TComplex{d*c.fRe,-d*c.fIm} / c.Rho2(); }
0103    template <class T, enable_if_arithmetic<T> = true>
0104    friend TComplex operator -(T d, const TComplex & c) { return {d-c.fRe, -c.fIm}; }
0105 
0106    // Convertors
0107    operator Double_t () const {return fRe;}
0108    operator Float_t  () const {return static_cast<Float_t>(fRe);}
0109    operator Int_t    () const {return static_cast<Int_t>(fRe);}
0110 
0111    // TMath:: extensions
0112    static TComplex Sqrt(const TComplex &c)
0113       {return TComplex(TMath::Sqrt(c.Rho()),0.5*c.Theta(),kTRUE);}
0114 
0115    static TComplex Exp(const TComplex &c)
0116       {return TComplex(TMath::Exp(c.fRe),c.fIm,kTRUE);}
0117    static TComplex Log(const TComplex &c)
0118       {return TComplex(0.5*TMath::Log(c.Rho2()),c.Theta());}
0119    static TComplex Log2(const TComplex &c)
0120       {return Log(c)/TMath::Log(2);}
0121    static TComplex Log10(const TComplex &c)
0122       {return Log(c)/TMath::Log(10);}
0123 
0124    static TComplex Sin(const TComplex &c)
0125       {return TComplex(TMath::Sin(c.fRe)*TMath::CosH(c.fIm),
0126                        TMath::Cos(c.fRe)*TMath::SinH(c.fIm));}
0127    static TComplex Cos(const TComplex &c)
0128       {return TComplex(TMath::Cos(c.fRe)*TMath::CosH(c.fIm),
0129                        -TMath::Sin(c.fRe)*TMath::SinH(c.fIm));}
0130    static TComplex Tan(const TComplex &c)
0131       {TComplex cc=Cos(c); return Sin(c)*Conjugate(cc)/cc.Rho2();}
0132 
0133    static TComplex ASin(const TComplex &c)
0134       {return -I()*Log(I()*c+TMath::Sign(1.,c.Im())*Sqrt(1.-c*c));}
0135    static TComplex ACos(const TComplex &c)
0136       {return -I()*Log(c+TMath::Sign(1.,c.Im())*Sqrt(c*c-1.));}
0137    static TComplex ATan(const TComplex &c)
0138       {return -0.5*I()*Log((1.+I()*c)/(1.-I()*c));}
0139 
0140    static TComplex SinH(const TComplex &c)
0141       {return TComplex(TMath::SinH(c.fRe)*TMath::Cos(c.fIm),
0142                        TMath::CosH(c.fRe)*TMath::Sin(c.fIm));}
0143    static TComplex CosH(const TComplex &c)
0144       {return TComplex(TMath::CosH(c.fRe)*TMath::Cos(c.fIm),
0145                        TMath::SinH(c.fRe)*TMath::Sin(c.fIm));}
0146    static TComplex TanH(const TComplex &c)
0147       {TComplex cc=CosH(c); return SinH(c)*Conjugate(cc)/cc.Rho2();}
0148 
0149    static TComplex ASinH(const TComplex &c)
0150       {return Log(c+TMath::Sign(1.,c.Im())*Sqrt(c*c+1.));}
0151    static TComplex ACosH(const TComplex &c)
0152       {return Log(c+TMath::Sign(1.,c.Im())*Sqrt(c*c-1.));}
0153    static TComplex ATanH(const TComplex &c)
0154       {return 0.5*Log((1.+c)/(1.-c));}
0155 
0156    static Double_t Abs(const TComplex &c)
0157       {return c.Rho();}
0158 
0159    static TComplex Power(const TComplex& x, const TComplex& y)
0160       {Double_t lrho=TMath::Log(x.Rho());
0161        Double_t theta=x.Theta();
0162        return TComplex(TMath::Exp(lrho*y.Re()-theta*y.Im()),
0163                        lrho*y.Im()+theta*y.Re(),kTRUE);}
0164    static TComplex Power(const TComplex& x, Double_t y)
0165       {return TComplex(TMath::Power(x.Rho(),y),x.Theta()*y,kTRUE);}
0166    static TComplex Power(Double_t x, const TComplex& y)
0167       {Double_t lrho=TMath::Log(TMath::Abs(x));
0168        Double_t theta=(x>0)?0:TMath::Pi();
0169        return TComplex(TMath::Exp(lrho*y.Re()-theta*y.Im()),
0170                        lrho*y.Im()+theta*y.Re(),kTRUE);}
0171    static TComplex Power(const TComplex& x, Int_t y)
0172       {return TComplex(TMath::Power(x.Rho(),y),x.Theta()*y,kTRUE);}
0173 
0174    static Int_t Finite(const TComplex& c)
0175       {return TMath::Min(TMath::Finite(c.Re()),TMath::Finite(c.Im()));}
0176    static Int_t IsNaN(const TComplex& c)
0177       {return TMath::IsNaN(c.Re()) || TMath::IsNaN(c.Im());}
0178 
0179    static TComplex Min(const TComplex &a, const TComplex &b)
0180       {return a.Rho()<=b.Rho()?a:b;}
0181    static TComplex Max(const TComplex &a, const TComplex &b)
0182       {return a.Rho()>=b.Rho()?a:b;}
0183    static TComplex Normalize(const TComplex &c)
0184       {return TComplex(1.,c.Theta(),kTRUE);}
0185    static TComplex Conjugate(const TComplex &c)
0186       {return TComplex(c.Re(),-c.Im());}
0187    static TComplex Range(const TComplex &lb, const TComplex &ub, const TComplex &c)
0188      {return Max(lb,Min(c,ub));}
0189 
0190    // I/O
0191    friend std::ostream& operator<<(std::ostream& out, const TComplex& c);
0192    friend std::istream& operator>>(std::istream& in, TComplex& c);
0193 
0194    ClassDef(TComplex,1)  //Complex Class
0195 };
0196 
0197 namespace cling {
0198 std::string printValue(TComplex *c);
0199 }
0200 
0201 #endif