// @(#)root/mathcore:$Id$
// Author: Federico Carminati   22/04/2004

/*************************************************************************
 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TComplex
#define ROOT_TComplex

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TComplex                                                             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_Riosfwd
#include "Riosfwd.h"
#endif
#ifndef ROOT_TMath
#include "TMath.h"
#endif


class TComplex {

protected:
   Double_t fRe;    // real part
   Double_t fIm;    // imaginary part

public:
   // ctors and dtors
   TComplex(): fRe(0), fIm(0) {}
   TComplex(Double_t re, Double_t im=0, Bool_t polar=kFALSE);
   virtual ~TComplex() {}

   // constants
   static TComplex I() {return TComplex(0,1);}
   static TComplex One() {return TComplex(1,0);}

   // getters and setters
   Double_t Re() const {return fRe;}
   Double_t Im() const {return fIm;}
   Double_t Rho() const {return TMath::Sqrt(fRe*fRe+fIm*fIm);}
   Double_t Rho2() const {return fRe*fRe+fIm*fIm;}
   Double_t Theta() const {return (fIm||fRe)?TMath::ATan2(fIm,fRe):0;}
   TComplex operator()(Double_t x, Double_t y, Bool_t polar=kFALSE)
      { if (polar) { fRe = x*TMath::Cos(y); fIm = x*TMath::Sin(y); }
        else { fRe = x; fIm = y; } return *this; }

   // Simple operators complex - complex
   TComplex operator *(const TComplex & c) const
      {return TComplex(fRe*c.fRe-fIm*c.fIm,fRe*c.fIm+fIm*c.fRe);}
   TComplex operator +(const TComplex & c) const
      {return TComplex(fRe+c.fRe, fIm+c.fIm);}
   TComplex operator /(const TComplex & c) const
      {return TComplex(fRe*c.fRe+fIm*c.fIm,-fRe*c.fIm+fIm*c.fRe)/c.Rho2();}
   TComplex operator -(const TComplex & c) const
      {return TComplex(fRe-c.fRe, fIm-c.fIm);}

   TComplex operator *=(const TComplex & c)
      {return ((*this) = (*this) * c);}
   TComplex operator +=(const TComplex & c)
      {return ((*this) = (*this) + c);}
   TComplex operator /=(const TComplex & c)
      {return ((*this) = (*this) / c);}
   TComplex operator -=(const TComplex & c)
      {return ((*this) = (*this) - c);}

   TComplex operator -()
      {return TComplex(-fRe,-fIm);}
   TComplex operator +()
      {return *this;}

   // Simple operators complex - double
   TComplex operator *(Double_t c) const
      {return TComplex(fRe*c,fIm*c);}
   TComplex operator +(Double_t c) const
      {return TComplex(fRe+c, fIm);}
   TComplex operator /(Double_t c) const
      {return TComplex(fRe/c,fIm/c);}
   TComplex operator -(Double_t c) const
      {return TComplex(fRe-c, fIm);}

   // Simple operators double - complex
   friend TComplex operator *(Double_t d, const TComplex & c)
      {return TComplex(d*c.fRe,d*c.fIm);}
   friend TComplex operator +(Double_t d, const TComplex & c)
      {return TComplex(d+c.fRe, c.fIm);}
   friend TComplex operator /(Double_t d, const TComplex & c)
      {return TComplex(d*c.fRe,-d*c.fIm)/c.Rho2();}
   friend TComplex operator -(Double_t d, const TComplex & c)
      {return TComplex(d-c.fRe, -c.fIm);}

   // Convertors
   operator Double_t () const {return fRe;}
   operator Float_t  () const {return static_cast<Float_t>(fRe);}
   operator Int_t    () const {return static_cast<Int_t>(fRe);}

   // TMath:: extensions
   static TComplex Sqrt(const TComplex &c)
      {return TComplex(TMath::Sqrt(c.Rho()),0.5*c.Theta(),kTRUE);}

   static TComplex Exp(const TComplex &c)
      {return TComplex(TMath::Exp(c.fRe),c.fIm,kTRUE);}
   static TComplex Log(const TComplex &c)
      {return TComplex(0.5*TMath::Log(c.Rho2()),c.Theta());}
   static TComplex Log2(const TComplex &c)
      {return Log(c)/TMath::Log(2);}
   static TComplex Log10(const TComplex &c)
      {return Log(c)/TMath::Log(10);}

   static TComplex Sin(const TComplex &c)
      {return TComplex(TMath::Sin(c.fRe)*TMath::CosH(c.fIm),
                       TMath::Cos(c.fRe)*TMath::SinH(c.fIm));}
   static TComplex Cos(const TComplex &c)
      {return TComplex(TMath::Cos(c.fRe)*TMath::CosH(c.fIm),
                       -TMath::Sin(c.fRe)*TMath::SinH(c.fIm));}
   static TComplex Tan(const TComplex &c)
      {TComplex cc=Cos(c); return Sin(c)*Conjugate(cc)/cc.Rho2();}

   static TComplex ASin(const TComplex &c)
      {return -I()*Log(I()*c+TMath::Sign(1.,c.Im())*Sqrt(1.-c*c));}
   static TComplex ACos(const TComplex &c)
      {return -I()*Log(c+TMath::Sign(1.,c.Im())*Sqrt(c*c-1.));}
   static TComplex ATan(const TComplex &c)
      {return -0.5*I()*Log((1.+I()*c)/(1.-I()*c));}

   static TComplex SinH(const TComplex &c)
      {return TComplex(TMath::SinH(c.fRe)*TMath::Cos(c.fIm),
                       TMath::CosH(c.fRe)*TMath::Sin(c.fIm));}
   static TComplex CosH(const TComplex &c)
      {return TComplex(TMath::CosH(c.fRe)*TMath::Cos(c.fIm),
                       TMath::SinH(c.fRe)*TMath::Sin(c.fIm));}
   static TComplex TanH(const TComplex &c)
      {TComplex cc=CosH(c); return SinH(c)*Conjugate(cc)/cc.Rho2();}

   static TComplex ASinH(const TComplex &c)
      {return Log(c+TMath::Sign(1.,c.Im())*Sqrt(c*c+1.));}
   static TComplex ACosH(const TComplex &c)
      {return Log(c+TMath::Sign(1.,c.Im())*Sqrt(c*c-1.));}
   static TComplex ATanH(const TComplex &c)
      {return 0.5*Log((1.+c)/(1.-c));}

   static Double_t Abs(const TComplex &c)
      {return c.Rho();}

   static TComplex Power(const TComplex& x, const TComplex& y)
      {Double_t lrho=TMath::Log(x.Rho());
       Double_t theta=x.Theta();
       return TComplex(TMath::Exp(lrho*y.Re()-theta*y.Im()),
                       lrho*y.Im()+theta*y.Re(),kTRUE);}
   static TComplex Power(const TComplex& x, Double_t y)
      {return TComplex(TMath::Power(x.Rho(),y),x.Theta()*y,kTRUE);}
   static TComplex Power(Double_t x, const TComplex& y)
      {Double_t lrho=TMath::Log(TMath::Abs(x));
       Double_t theta=(x>0)?0:TMath::Pi();
       return TComplex(TMath::Exp(lrho*y.Re()-theta*y.Im()),
                       lrho*y.Im()+theta*y.Re(),kTRUE);}
   static TComplex Power(const TComplex& x, Int_t y)
      {return TComplex(TMath::Power(x.Rho(),y),x.Theta()*y,kTRUE);}

   static Int_t Finite(const TComplex& c)
      {return TMath::Min(TMath::Finite(c.Re()),TMath::Finite(c.Im()));}
   static Int_t IsNaN(const TComplex& c)
      {return TMath::Max(TMath::IsNaN(c.Re()),TMath::IsNaN(c.Im()));}

   static TComplex Min(const TComplex &a, const TComplex &b)
      {return a.Rho()<=b.Rho()?a:b;}
   static TComplex Max(const TComplex &a, const TComplex &b)
      {return a.Rho()>=b.Rho()?a:b;}
   static TComplex Normalize(const TComplex &c)
      {return TComplex(1.,c.Theta(),kTRUE);}
   static TComplex Conjugate(const TComplex &c)
      {return TComplex(c.Re(),-c.Im());}
   static TComplex Range(const TComplex &lb, const TComplex &ub, const TComplex &c)
     {return Max(lb,Min(c,ub));}

   // I/O
   friend std::ostream& operator<<(std::ostream& out, const TComplex& c);
   friend std::istream& operator>>(std::istream& in, TComplex& c);

   ClassDef(TComplex,1)  //Complex Class
};

#endif
 TComplex.h:1
 TComplex.h:2
 TComplex.h:3
 TComplex.h:4
 TComplex.h:5
 TComplex.h:6
 TComplex.h:7
 TComplex.h:8
 TComplex.h:9
 TComplex.h:10
 TComplex.h:11
 TComplex.h:12
 TComplex.h:13
 TComplex.h:14
 TComplex.h:15
 TComplex.h:16
 TComplex.h:17
 TComplex.h:18
 TComplex.h:19
 TComplex.h:20
 TComplex.h:21
 TComplex.h:22
 TComplex.h:23
 TComplex.h:24
 TComplex.h:25
 TComplex.h:26
 TComplex.h:27
 TComplex.h:28
 TComplex.h:29
 TComplex.h:30
 TComplex.h:31
 TComplex.h:32
 TComplex.h:33
 TComplex.h:34
 TComplex.h:35
 TComplex.h:36
 TComplex.h:37
 TComplex.h:38
 TComplex.h:39
 TComplex.h:40
 TComplex.h:41
 TComplex.h:42
 TComplex.h:43
 TComplex.h:44
 TComplex.h:45
 TComplex.h:46
 TComplex.h:47
 TComplex.h:48
 TComplex.h:49
 TComplex.h:50
 TComplex.h:51
 TComplex.h:52
 TComplex.h:53
 TComplex.h:54
 TComplex.h:55
 TComplex.h:56
 TComplex.h:57
 TComplex.h:58
 TComplex.h:59
 TComplex.h:60
 TComplex.h:61
 TComplex.h:62
 TComplex.h:63
 TComplex.h:64
 TComplex.h:65
 TComplex.h:66
 TComplex.h:67
 TComplex.h:68
 TComplex.h:69
 TComplex.h:70
 TComplex.h:71
 TComplex.h:72
 TComplex.h:73
 TComplex.h:74
 TComplex.h:75
 TComplex.h:76
 TComplex.h:77
 TComplex.h:78
 TComplex.h:79
 TComplex.h:80
 TComplex.h:81
 TComplex.h:82
 TComplex.h:83
 TComplex.h:84
 TComplex.h:85
 TComplex.h:86
 TComplex.h:87
 TComplex.h:88
 TComplex.h:89
 TComplex.h:90
 TComplex.h:91
 TComplex.h:92
 TComplex.h:93
 TComplex.h:94
 TComplex.h:95
 TComplex.h:96
 TComplex.h:97
 TComplex.h:98
 TComplex.h:99
 TComplex.h:100
 TComplex.h:101
 TComplex.h:102
 TComplex.h:103
 TComplex.h:104
 TComplex.h:105
 TComplex.h:106
 TComplex.h:107
 TComplex.h:108
 TComplex.h:109
 TComplex.h:110
 TComplex.h:111
 TComplex.h:112
 TComplex.h:113
 TComplex.h:114
 TComplex.h:115
 TComplex.h:116
 TComplex.h:117
 TComplex.h:118
 TComplex.h:119
 TComplex.h:120
 TComplex.h:121
 TComplex.h:122
 TComplex.h:123
 TComplex.h:124
 TComplex.h:125
 TComplex.h:126
 TComplex.h:127
 TComplex.h:128
 TComplex.h:129
 TComplex.h:130
 TComplex.h:131
 TComplex.h:132
 TComplex.h:133
 TComplex.h:134
 TComplex.h:135
 TComplex.h:136
 TComplex.h:137
 TComplex.h:138
 TComplex.h:139
 TComplex.h:140
 TComplex.h:141
 TComplex.h:142
 TComplex.h:143
 TComplex.h:144
 TComplex.h:145
 TComplex.h:146
 TComplex.h:147
 TComplex.h:148
 TComplex.h:149
 TComplex.h:150
 TComplex.h:151
 TComplex.h:152
 TComplex.h:153
 TComplex.h:154
 TComplex.h:155
 TComplex.h:156
 TComplex.h:157
 TComplex.h:158
 TComplex.h:159
 TComplex.h:160
 TComplex.h:161
 TComplex.h:162
 TComplex.h:163
 TComplex.h:164
 TComplex.h:165
 TComplex.h:166
 TComplex.h:167
 TComplex.h:168
 TComplex.h:169
 TComplex.h:170
 TComplex.h:171
 TComplex.h:172
 TComplex.h:173
 TComplex.h:174
 TComplex.h:175
 TComplex.h:176
 TComplex.h:177
 TComplex.h:178
 TComplex.h:179
 TComplex.h:180
 TComplex.h:181
 TComplex.h:182
 TComplex.h:183
 TComplex.h:184
 TComplex.h:185
 TComplex.h:186
 TComplex.h:187
 TComplex.h:188
 TComplex.h:189
 TComplex.h:190