00001
00003
00004
00005
00006
00007
00009
00010 #ifndef LITR_TComplex
00011 #define LITR_TComplex
00012
00013
00014 #undef TCOMPLEX_USE_RTYPES_MACROS
00015 #define TCOMPLEX_USE_DOUBLE
00016
00017 #ifdef TCOMPLEX_USE_DOUBLE
00018 # define TComplexBase Double_t
00019 #else
00020 # define TComplexBase Real_t
00021 #endif
00022
00023 #include <Riostream.h>
00024 #include <TBuffer.h>
00025 #include <TMath.h>
00026
00027 class TCplxRhoPhi {
00028 protected:
00029
00030 Double_t fRho;
00031 Double_t fPhi;
00032 public:
00033 TCplxRhoPhi(Double_t x,Double_t y) { fRho = TMath::Sqrt(x*x+y*y);
00034 fPhi = atan2(y,x); }
00035 Double_t GetRho() { return fRho; }
00036 Double_t GetPhi() { return fPhi; }
00037 void Sqrt() { fRho = TMath::Sqrt(fRho); fPhi = fPhi/2.0; }
00038 };
00039
00040 class TComplex {
00041
00042 protected:
00043 friend TComplex operator + (const Double_t,const TComplex&);
00044 friend TComplex operator - (const Double_t,const TComplex&);
00045 friend TComplex operator * (const Int_t,const TComplex&);
00046 friend TComplex operator * (const Double_t,const TComplex&);
00047 friend TComplex operator * (const TComplex&,const TComplex&);
00048 friend TComplex operator * (TComplex&, TComplex&);
00049 friend TComplex operator % (const TComplex&,const TComplex&);
00050 friend TComplex operator / (const Double_t,const TComplex&);
00051 friend Bool_t operator == (const TComplex&, const TComplex&);
00052 friend Bool_t operator != (const TComplex&, const TComplex&);
00053 friend Bool_t operator == (const TComplex&, const Double_t&);
00054 friend Bool_t operator != (const TComplex&, const Double_t&);
00055 friend Double_t Abs(const TComplex&);
00056 friend Double_t Abs2(const TComplex&);
00057 friend TComplex Sqrt(const TComplex&);
00058 friend TComplex Sqrt3(const TComplex&, Int_t);
00059 friend TComplex Exp(const TComplex&);
00060 friend TComplex Log(const TComplex&);
00061 friend TComplex Log10(const TComplex&);
00062 friend TComplex Log2(const TComplex&);
00063 friend TComplex Sin(const TComplex&);
00064 friend TComplex Cos(const TComplex&);
00065 friend TComplex Power(const TComplex &z,Int_t n) { return Exp(n*Log(z)); }
00066 friend TComplex Power(const TComplex &z,Double_t x) { return Exp(x*Log(z)); }
00067 friend Double_t Phase(TComplex z) { return TMath::ATan2(z.fIm,z.fRe);};
00068 friend istream &operator>>(istream&,TComplex&);
00069 friend ostream &operator<<(ostream&,TComplex&);
00070
00071 public:
00072
00073 TComplexBase fRe;
00074 TComplexBase fIm;
00075 TComplex() { fRe=0.0; fIm =0.0; }
00076 TComplex(Double_t x,Double_t y=0) { fRe = x; fIm=y; }
00077 TComplex(const TComplex &z) { fRe = z.fRe; fIm = z.fIm; }
00078 Double_t Re() const { return fRe; }
00079 Double_t Im() const { return fIm; }
00080 Double_t Phase() { return TMath::ATan2(fIm,fRe);};
00081 void Set(Double_t x,Double_t y) { fRe = x; fIm = y; }
00082 void SetReal(Double_t x) { fRe = x; }
00083 void SetIm(Double_t y) { fIm = y; }
00084 void C() { fIm = - fIm; }
00085 void PureReal() { fIm = 0.0; }
00086 void PureIm() { fRe = 0.0; }
00087 void SetNeg() { fRe = -fRe; fIm = -fIm; }
00088 void Dump();
00089
00090 operator Bool_t() { return fRe||fIm; };
00091 operator Double_t() { return fRe;};
00092 operator Int_t() { return Int_t(fRe);};
00093
00094
00096
00097 Bool_t operator!() { return (!fRe)&&(!fIm);};
00098 Bool_t operator&&(TComplex &z) {
00099 return Bool_t()&&Bool_t(z);
00100 }
00101
00102 TComplex operator+(const TComplex& z) {
00103
00104 TComplex z4;
00105 z4.fRe = fRe + z.fRe;
00106 z4.fIm = fIm + z.fIm;
00107 return z4;
00108 }
00109
00110 TComplex operator+(const Double_t x) {
00111 TComplex z4;
00112 z4.fRe = fRe + x;
00113 z4.fIm = fIm;
00114 return z4;
00115 }
00116 TComplex operator+(const Int_t x) {
00117 TComplex z4;
00118 z4.fRe = fRe + x;
00119 z4.fIm = fIm;
00120 return z4;
00121 }
00123
00124 TComplex operator -() {
00125 TComplex z;
00126 z.fRe = -fRe;
00127 z.fIm = -fIm;
00128 return z;
00129 }
00130
00131 TComplex operator-(const TComplex& z) {
00132
00133 TComplex z4;
00134 z4.fRe = fRe - z.fRe;
00135 z4.fIm = fIm - z.fIm;
00136 return z4;
00137 }
00138
00139 TComplex operator-(const Double_t x) {
00140
00141 TComplex z4;
00142 z4.fRe = fRe - x;
00143 z4.fIm = fIm;
00144 return z4;
00145 }
00146 TComplex operator-(const Int_t x) {
00147
00148 TComplex z4;
00149 z4.fRe = fRe - x;
00150 z4.fIm = fIm;
00151 return z4;
00152 }
00153
00155
00156
00157
00159
00160 TComplex& operator=(const TComplex &z) {
00161
00162 if (this != &z) {
00163 fRe = z.fRe;
00164 fIm = z.fIm;
00165 }
00166 return *this;
00167 }
00168 TComplex& operator=(const Double_t x) {
00169
00170 fRe = x;
00171 fIm = 0.0;
00172 return *this;
00173 }
00174
00176
00177 TComplex& operator+=(const Double_t& x) {
00178 fRe += x;
00179 return *this;
00180 }
00181 TComplex& operator+=(const TComplex& z) {
00182
00183 fRe += z.fRe;
00184 fIm += z.fIm;
00185 return *this;
00186 }
00187
00188 TComplex& operator-=(const Double_t& x) {
00189 fRe -= x;
00190 return *this;
00191 }
00192 TComplex& operator-=(const TComplex& z) {
00193
00194 fRe -= z.fRe;
00195 fIm -= z.fIm;
00196 return *this;
00197 }
00198
00200
00201 TComplex& operator/=(const Double_t& x) {
00202 fRe /= x;
00203 fIm /= x;
00204 return *this;
00205 }
00206
00207 TComplex& operator/=(const TComplex& z) {
00208 Double_t tmp,d;
00209 d = z.fRe*z.fRe + z.fIm*z.fIm;
00210 tmp = (fRe*z.fRe + fIm*z.fIm)/d;
00211 fIm = (fIm*z.fRe - fRe*z.fIm)/d;
00212 fRe = tmp;
00213
00214 return *this;
00215 }
00216
00218
00219 TComplex& operator*=(const Double_t & x) {
00220
00221 fIm *=x;
00222 fRe *=x;
00223 return *this;
00224 }
00225
00226 TComplex& operator*=(const TComplex& z) {
00227
00228 register Double_t tmp = fRe*z.fRe - fIm*z.fIm;
00229 fIm = fRe*z.fIm + fIm*z.fRe;
00230 fRe = tmp;
00231 return *this;
00232 }
00233
00234
00236
00237
00238 void FromRhoPhi(TCplxRhoPhi &r) {
00239
00240 register Double_t rho;
00241 register Double_t phi;
00242 rho = r.GetRho();
00243 phi = r.GetPhi();
00244 fRe = rho*TMath::Cos(phi);
00245 fIm = rho*TMath::Sin(phi);
00246 }
00247 Bool_t IsComplex(Double_t limreal) {
00248
00249
00250 const Double_t zero = 0.0;
00251 Bool_t cplx = kTRUE;
00252 if (TMath::Abs(fIm)<TMath::Abs(limreal)) {
00253 fIm = zero;
00254 cplx = kFALSE;
00255 }
00256 return cplx;
00257 }
00258 void BetterConj(TComplex &z2) {
00259
00260 const Double_t deux = 2.0;
00261 Double_t a,b;
00262 a = (fRe + z2.fRe)/deux;
00263 b = (fIm - z2.fIm)/deux;
00264 z2.fRe = a;
00265 z2.fIm = -b;
00266 fRe = a;
00267 fIm = b;
00268 }
00269 void CosFromSin() {
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 const Double_t zero = 0.0;
00280 const Double_t un = 1.0;
00281 const Double_t vsmall = 1.0e-12;
00282 TComplex z;
00283 z = *this;z*=z;
00284 z = Sqrt(un - z);
00285 if (z.fIm>vsmall) z = zero - z;
00286 if (TMath::Abs(z.fIm)<=vsmall) z.fIm = zero;
00287 *this = z;
00288 }
00289 void RPhi(Double_t &r, Double_t &phi) {
00290
00291
00292
00293
00294
00295 const Double_t zero = 0.0;
00296 const Double_t wsmall = 1.0e-300;
00297 Double_t axr,axi;
00298 axr = TMath::Abs(fRe);
00299 axi = TMath::Abs(fIm);
00300 if ((axr<wsmall) && (axi<wsmall)) {
00301 r = zero;
00302 phi = zero;
00303 }
00304 else {
00305 r = TMath::Sqrt(fRe*fRe+fIm*fIm);
00306 if (fRe<zero) r = -r;
00307 if (axi<wsmall) {
00308 phi = zero;
00309 }
00310 else {
00311 phi = atan2(fIm,fRe);
00312 if (fRe<zero) {
00313 if (fIm>=zero) phi = phi - TMath::Pi();
00314 else phi = phi + TMath::Pi();
00315 }
00316 }
00317 }
00318 }
00319
00320 TComplex operator*(const Double_t x) {
00321 TComplex z4;
00322 z4.fRe = fRe*x;
00323 z4.fIm = fIm*x;
00324 return z4;
00325 }
00326 TComplex operator*(const Int_t x) {
00327 TComplex z4;
00328 Double_t xx = x;
00329 z4.fRe = fRe*xx;
00330 z4.fIm = fIm*xx;
00331 return z4;
00332 }
00333
00334 TComplex operator/(const TComplex &z) {
00335
00336 TComplex z4;
00337 Double_t d;
00338 d = z.fRe*z.fRe + z.fIm*z.fIm;
00339 z4.fRe = (fRe*z.fRe + fIm*z.fIm)/d;
00340 z4.fIm = (fIm*z.fRe - fRe*z.fIm)/d;
00341 return z4;
00342 }
00343 TComplex operator/(const Double_t x) {
00344
00345 TComplex z4;
00346 z4.fRe = fRe/x;
00347 z4.fIm = fIm/x;
00348 return z4;
00349 }
00350 TComplex operator/(const Int_t x) {
00351
00352 TComplex z4;
00353 Double_t xx = x;
00354 z4.fRe = fRe/xx;
00355 z4.fIm = fIm/xx;
00356 return z4;
00357 }
00358
00359
00360
00361 void Print();
00362 void Test(Double_t,const TComplex&);
00363
00364 #ifdef TCOMPLEX_USE_RTYPES_MACROS
00365
00366
00367
00368
00369
00370 ClassDef(TComplex,0)
00371
00372 #else
00373
00374
00375
00376
00377
00378
00379
00380 private:
00381 static TClass *fgIsA;
00382 public:
00383 static TClass *Class();
00384 static const char *Class_Name();
00385 static Version_t Class_Version() { return 0; }
00386 static void Dictionary();
00387 TClass *IsA() const { return TComplex::Class(); }
00388 void ShowMembers(TMemberInspector &insp, char *parent);
00389 void Streamer(TBuffer &b);
00390 void StreamerNVirtual(TBuffer &b) { TComplex::Streamer(b); }
00391 static const char *DeclFileName() { return __FILE__; }
00392 static int DeclFileLine() { return __LINE__; }
00393 static const char *ImplFileName();
00394
00395 # if !defined(R__ACCESS_IN_SYMBOL) || defined(__CINT__)
00396
00397 friend void ROOT__ShowMembersFunc(TComplex *obj, TMemberInspector &R__insp,
00398 char *R__parent);
00399
00400 # endif
00401 static int ImplFileLine();
00402
00403 #endif
00404
00405 };
00406
00407
00408
00409 inline Double_t Dist(TComplex& z1, TComplex& z2) {
00410 return Abs(z1-z2);
00411 }
00412
00413 inline TComplex operator + (const Double_t x, const TComplex &z) {
00414
00415 return TComplex(x + z.fRe,z.fIm);
00416 }
00417
00418 inline TComplex operator - (const Double_t x, const TComplex &z) {
00419
00420 return TComplex(x - z.fRe,-z.fIm);
00421 }
00422 inline TComplex operator * (const Int_t x, const TComplex &z) {
00423
00424 return TComplex(x*z.fRe,x*z.fIm);
00425 }
00426 inline TComplex operator * (const Double_t x, const TComplex &z) {
00427
00428 return TComplex(x*z.fRe,x*z.fIm);
00429 }
00430 inline TComplex operator * (const TComplex &x, const TComplex &y) {
00431
00432 return TComplex(x.fRe*y.fRe - x.fIm*y.fIm,x.fRe*y.fIm + x.fIm*y.fRe);
00433 }
00434 inline TComplex operator * (TComplex &x, TComplex &y) {
00435
00436 return TComplex(x.fRe*y.fRe - x.fIm*y.fIm,x.fRe*y.fIm + x.fIm*y.fRe);
00437 }
00438 inline TComplex operator % (const TComplex &x, const TComplex &y) {
00439
00440 return TComplex(x.fRe*y.fRe + x.fIm*y.fIm,x.fRe*y.fIm - x.fIm*y.fRe);
00441 }
00442 inline TComplex operator / (const Double_t x, const TComplex &z) {
00443
00444 TComplex z4;
00445 Double_t d;
00446 d = z.fRe*z.fRe + z.fIm*z.fIm;
00447 z4.fRe = (x*z.fRe)/d;
00448 z4.fIm = -(x*z.fIm)/d;
00449 return z4;
00450 }
00451
00452 inline Bool_t operator ==(const TComplex &z1, const TComplex &z2) {
00453 return ((z1.fRe==z2.fRe)&&(z1.fIm==z2.fIm));
00454 }
00455
00456 inline Bool_t operator !=(const TComplex &z1, const TComplex &z2) {
00457 return ((z1.fRe!=z2.fRe)||(z1.fIm!=z2.fIm));
00458 }
00459 inline Bool_t operator ==(const TComplex &z1, const Double_t &d) {
00460 return ((z1.fRe==d)&&(z1.fIm==0.0));
00461 }
00462
00463 inline Bool_t operator !=(const TComplex &z1, const Double_t &d) {
00464 return ((z1.fRe!=d)||(z1.fIm!=0.0));
00465 }
00466 inline Double_t Abs(const TComplex &z) {
00467
00468 return TMath::Sqrt(Abs2(z));
00469 }
00470 inline Double_t Abs2(const TComplex &z) {
00471
00472 return z.fRe*z.fRe + z.fIm*z.fIm;
00473 }
00474
00475 inline TComplex Sqrt(const TComplex &z) {
00476
00477 const Double_t zero = 0.0;
00478 TComplex zz;
00479 if (z.fRe >= zero) {
00480 TCplxRhoPhi r(z.fRe,z.fIm);
00481 r.Sqrt();
00482 zz.FromRhoPhi(r);
00483 }
00484 else {
00485 TCplxRhoPhi r(-z.fRe,-z.fIm);
00486 r.Sqrt();
00487 zz.FromRhoPhi(r);
00488 TComplex j(0,1);
00489
00490 zz*=j;
00491 }
00492 return zz;
00493 }
00494
00495 inline TComplex Sqrt3(const TComplex &z,Int_t k) {
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 const Double_t zero = 0.0;
00506 const Double_t deux = 2.0;
00507 const Double_t trois = 3.0;
00508 const Double_t small = 1.0e-7;
00509 const Double_t wsmall = 1.0e-300;
00510 Double_t rho,phi;
00511 Bool_t isreal,isneg;
00512 TComplex z1,zz;
00513 isreal = (TMath::Abs(z.fIm)<wsmall);
00514 isneg = (z.fRe<zero);
00515 if (isneg) z1 = zero - z;
00516 else z1 = z;
00517 k = k % 3;
00518 TCplxRhoPhi r(z1.fRe,z1.fIm);
00519 rho = r.GetRho();
00520 phi = r.GetPhi();
00521 rho = TMath::Exp(TMath::Log(rho)/trois);
00522 switch (k) {
00523 case 0:
00524 phi = phi/trois;
00525 break;
00526 case 1:
00527 phi = (phi + deux*TMath::Pi())/trois;
00528 break;
00529 case 2:
00530 phi = (phi - deux*TMath::Pi())/trois;
00531 break;
00532 }
00533 zz.fRe = rho*TMath::Cos(phi);
00534 zz.fIm = rho*TMath::Sin(phi);
00535 if (isreal && (TMath::Abs(zz.fIm)<small)) zz.fIm = zero;
00536 if (isneg) zz = zero - zz;
00537 return zz;
00538 }
00539
00540 inline TComplex Exp(const TComplex &z) {
00541
00542 register Double_t ex;
00543 TComplex zz;
00544 ex = TMath::Exp(z.fRe);
00545 zz.fRe = ex*TMath::Cos(z.fIm);
00546 zz.fIm = ex*TMath::Sin(z.fIm);
00547 return zz;
00548 }
00549
00550 inline TComplex Log(const TComplex &z) {
00551
00552 TComplex zz;
00553 TCplxRhoPhi r(z.fRe,z.fIm);
00554 zz.fRe = TMath::Log(r.GetRho());
00555 zz.fIm = r.GetPhi();
00556 return zz;
00557 }
00558 inline TComplex Log2(const TComplex &z) {
00559
00560 TComplex zz;
00561 TCplxRhoPhi r(z.fRe,z.fIm);
00562 zz.fRe = TMath::Log2(r.GetRho());
00563 zz.fIm = r.GetPhi();
00564 return zz;
00565 }
00566 inline TComplex Log10(const TComplex &z) {
00567
00568 TComplex zz;
00569 TCplxRhoPhi r(z.fRe,z.fIm);
00570 zz.fRe = TMath::Log10(r.GetRho());
00571 zz.fIm = r.GetPhi();
00572 return zz;
00573 }
00574
00575 inline TComplex Sin(const TComplex &z) {
00576
00577 const Double_t un = 1.0;
00578 const Double_t deux = 2.0;
00579 TComplex zz;
00580 Double_t a,b;
00581 a = TMath::Exp(z.fIm);
00582 b = un/a;
00583 zz.fRe = ((a+b)*TMath::Sin(z.fRe))/deux;
00584 zz.fIm = ((a-b)*TMath::Cos(z.fRe))/deux;
00585 return zz;
00586 }
00587
00588 inline TComplex Cos(const TComplex &z) {
00589
00590 const Double_t un = 1.0;
00591 const Double_t deux = 2.0;
00592 TComplex zz;
00593 Double_t a,b;
00594 a = TMath::Exp(z.fIm);
00595 b = un/a;
00596 zz.fRe = ((a+b)*TMath::Cos(z.fRe))/deux;
00597 zz.fIm = ((b-a)*TMath::Sin(z.fRe))/deux;
00598 return zz;
00599 }
00600
00601
00602 extern TComplex ComplexZero;
00603 extern TComplex ComplexOne;
00604 extern TComplex I;
00605 #endif