REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestComplex.h
1 /*************************************************************************
2  * This file is part of the REST software framework. *
3  * *
4  * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5  * For more information see http://gifna.unizar.es/trex *
6  * *
7  * REST is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * REST is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have a copy of the GNU General Public License along with *
18  * REST in $REST_PATH/LICENSE. *
19  * If not, see http://www.gnu.org/licenses/. *
20  * For the list of contributors see $REST_PATH/CREDITS. *
21  *************************************************************************/
22 
23 #ifndef RestCore_TRestComplex
24 #define RestCore_TRestComplex
25 
26 #include <string>
27 
28 #include "Rtypes.h"
29 #include "TObject.h"
30 #include "mpreal.h"
31 
33 class TRestComplex {
34  protected:
36  mpfr::mpreal fRe = 1;
38  mpfr::mpreal fIm = 0;
39 
40  public:
41  // ctors and dtors
42  TRestComplex() {}
43  TRestComplex(mpfr::mpreal re, mpfr::mpreal im = 0, Bool_t polar = kFALSE);
44  virtual ~TRestComplex() {}
45 
46  static void SetPrecision(Int_t precision) {
47  mpfr::mpreal::set_default_prec(mpfr::digits2bits(precision));
48  }
49 
50  static int GetPrecision() { return mpfr::bits2digits(mpfr::mpreal::get_default_prec()); }
51 
52  // constants
53  static TRestComplex I() { return TRestComplex(0, 1); }
54  static TRestComplex One() { return TRestComplex(1, 0); }
55 
56  // getters and setters
57  mpfr::mpreal Re() const { return fRe; }
58  mpfr::mpreal Im() const { return fIm; }
59  mpfr::mpreal Rho() const { return mpfr::sqrt(fRe * fRe + fIm * fIm); }
60  mpfr::mpreal Rho2() const { return fRe * fRe + fIm * fIm; }
61  mpfr::mpreal Theta() const { return (fIm || fRe) ? mpfr::atan2(fIm, fRe) : 0; }
62  TRestComplex operator()(mpfr::mpreal x, mpfr::mpreal y, Bool_t polar = kFALSE) {
63  if (polar) {
64  fRe = x * mpfr::cos(y);
65  fIm = x * mpfr::sin(y);
66  } else {
67  fRe = x;
68  fIm = y;
69  }
70  return *this;
71  }
72 
73  // Simple operators complex - complex
74  TRestComplex operator*(const TRestComplex& c) const {
75  return TRestComplex(fRe * c.fRe - fIm * c.fIm, fRe * c.fIm + fIm * c.fRe);
76  }
77  TRestComplex operator+(const TRestComplex& c) const { return TRestComplex(fRe + c.fRe, fIm + c.fIm); }
78  TRestComplex operator/(const TRestComplex& c) const {
79  return TRestComplex(fRe * c.fRe + fIm * c.fIm, -fRe * c.fIm + fIm * c.fRe) / c.Rho2();
80  }
81  TRestComplex operator-(const TRestComplex& c) const { return TRestComplex(fRe - c.fRe, fIm - c.fIm); }
82 
83  TRestComplex operator*=(const TRestComplex& c) { return ((*this) = (*this) * c); }
84  TRestComplex operator+=(const TRestComplex& c) { return ((*this) = (*this) + c); }
85  TRestComplex operator/=(const TRestComplex& c) { return ((*this) = (*this) / c); }
86  TRestComplex operator-=(const TRestComplex& c) { return ((*this) = (*this) - c); }
87 
88  TRestComplex operator-() { return TRestComplex(-fRe, -fIm); }
89  TRestComplex operator+() { return *this; }
90 
91  // Simple operators complex - double
92  TRestComplex operator*(mpfr::mpreal c) const { return TRestComplex(fRe * c, fIm * c); }
93  TRestComplex operator+(mpfr::mpreal c) const { return TRestComplex(fRe + c, fIm); }
94  TRestComplex operator/(mpfr::mpreal c) const { return TRestComplex(fRe / c, fIm / c); }
95  TRestComplex operator-(mpfr::mpreal c) const { return TRestComplex(fRe - c, fIm); }
96 
97  // Simple operators double - complex
98  friend TRestComplex operator*(Double_t d, const TRestComplex& c) {
99  return TRestComplex(d * c.fRe, d * c.fIm);
100  }
101  friend TRestComplex operator+(Double_t d, const TRestComplex& c) {
102  return TRestComplex(d + c.fRe, c.fIm);
103  }
104  friend TRestComplex operator/(Double_t d, const TRestComplex& c) {
105  return TRestComplex(d * c.fRe, -d * c.fIm) / c.Rho2();
106  }
107  friend TRestComplex operator-(Double_t d, const TRestComplex& c) {
108  return TRestComplex(d - c.fRe, -c.fIm);
109  }
110 
111  // Convertors
112  operator Double_t() const { return static_cast<Double_t>(fRe); }
113  operator Float_t() const { return static_cast<Float_t>(fRe); }
114  operator Int_t() const { return static_cast<Int_t>(fRe); }
115 
116  // TMath:: extensions
117  static TRestComplex Sqrt(const TRestComplex& c) {
118  return TRestComplex(mpfr::sqrt(c.Rho()), 0.5 * c.Theta(), kTRUE);
119  }
120 
121  static TRestComplex Exp(const TRestComplex& c) { return TRestComplex(mpfr::exp(c.fRe), c.fIm, kTRUE); }
122  static TRestComplex Log(const TRestComplex& c) {
123  return TRestComplex(0.5 * mpfr::log(c.Rho2()), c.Theta());
124  }
125  static TRestComplex Log2(const TRestComplex& c) { return Log(c) / mpfr::log(2); }
126  static TRestComplex Log10(const TRestComplex& c) { return Log(c) / mpfr::log(10); }
127 
128  static TRestComplex Sin(const TRestComplex& c) {
129  return TRestComplex(mpfr::sin(c.fRe) * mpfr::cosh(c.fIm), mpfr::cos(c.fRe) * mpfr::sinh(c.fIm));
130  }
131  static TRestComplex Cos(const TRestComplex& c) {
132  return TRestComplex(mpfr::cos(c.fRe) * mpfr::cosh(c.fIm), -mpfr::sin(c.fRe) * mpfr::sinh(c.fIm));
133  }
134  static TRestComplex Tan(const TRestComplex& c) {
135  TRestComplex cc = Cos(c);
136  return Sin(c) * Conjugate(cc) / cc.Rho2();
137  }
138 
139  inline int Sign(const mpfr::mpreal& re, const mpfr::mpreal& im) {
141  return 0;
142  }
143 
144  static TRestComplex ASin(const TRestComplex& c) {
146  return I();
147  // return -I() * Log(I() * c + TMath::Sign(1., c.Im()) * Sqrt(1. - c * c));
148  }
149  static TRestComplex ACos(const TRestComplex& c) {
151  return I();
152  // return -I() * Log(c + TMath::Sign(1., c.Im()) * Sqrt(c * c - 1.));
153  }
154  static TRestComplex ATan(const TRestComplex& c) {
155  return -0.5 * I() * Log((1. + I() * c) / (1. - I() * c));
156  }
157 
158  static TRestComplex SinH(const TRestComplex& c) {
159  return TRestComplex(mpfr::sinh(c.fRe) * mpfr::cos(c.fIm), mpfr::cosh(c.fRe) * mpfr::sin(c.fIm));
160  }
161  static TRestComplex CosH(const TRestComplex& c) {
162  return TRestComplex(mpfr::cosh(c.fRe) * mpfr::cos(c.fIm), mpfr::sinh(c.fRe) * mpfr::sin(c.fIm));
163  }
164  static TRestComplex TanH(const TRestComplex& c) {
165  TRestComplex cc = CosH(c);
166  return SinH(c) * Conjugate(cc) / cc.Rho2();
167  }
168 
169  static TRestComplex ASinH(const TRestComplex& c) {
171  return I();
172  // return Log(c + TMath::Sign(1., c.Im()) * Sqrt(c * c + 1.));
173  }
174  static TRestComplex ACosH(const TRestComplex& c) {
176  return I();
177  // return Log(c + TMath::Sign(1., c.Im()) * Sqrt(c * c - 1.));
178  }
179  static TRestComplex ATanH(const TRestComplex& c) { return 0.5 * Log((1. + c) / (1. - c)); }
180 
181  static mpfr::mpreal Abs(const TRestComplex& c) { return c.Rho(); }
182 
183  static TRestComplex Power(const TRestComplex& x, const TRestComplex& y) {
184  mpfr::mpreal lrho = mpfr::log(x.Rho());
185  mpfr::mpreal theta = x.Theta();
186  return TRestComplex(mpfr::exp(lrho * y.Re() - theta * y.Im()), lrho * y.Im() + theta * y.Re(), kTRUE);
187  }
188  static TRestComplex Power(const TRestComplex& x, mpfr::mpreal y) {
189  return TRestComplex(mpfr::pow(x.Rho(), y), x.Theta() * y, kTRUE);
190  }
191  static TRestComplex Power(mpfr::mpreal x, const TRestComplex& y) {
192  mpfr::mpreal lrho = mpfr::log(mpfr::abs(x));
193  mpfr::mpreal theta = (x > 0) ? 0 : mpfr::const_pi();
194  return TRestComplex(mpfr::exp(lrho * y.Re() - theta * y.Im()), lrho * y.Im() + theta * y.Re(), kTRUE);
195  }
196  static TRestComplex Power(const TRestComplex& x, Int_t y) {
197  return TRestComplex(mpfr::pow(x.Rho(), y), x.Theta() * y, kTRUE);
198  }
199 
200  static Int_t IsNaN(const TRestComplex& c) { return mpfr::isnan(c.Re()) || mpfr::isnan(c.Im()); }
201 
202  static TRestComplex Min(const TRestComplex& a, const TRestComplex& b) {
203  return a.Rho() <= b.Rho() ? a : b;
204  }
205  static TRestComplex Max(const TRestComplex& a, const TRestComplex& b) {
206  return a.Rho() >= b.Rho() ? a : b;
207  }
208  static TRestComplex Normalize(const TRestComplex& c) { return TRestComplex(1., c.Theta(), kTRUE); }
209  static TRestComplex Conjugate(const TRestComplex& c) { return TRestComplex(c.Re(), -c.Im()); }
210  static TRestComplex Range(const TRestComplex& lb, const TRestComplex& ub, const TRestComplex& c) {
211  return Max(lb, Min(c, ub));
212  }
213 
214  // I/O
215  friend std::ostream& operator<<(std::ostream& out, const TRestComplex& c);
216  friend std::istream& operator>>(std::istream& in, TRestComplex& c);
217 
218  ClassDef(TRestComplex, 1) // Complex Class
219 };
220 
221 namespace cling {
222 std::string printValue(TRestComplex* c);
223 }
224 
225 #endif
A generic class to handle complex numbers with real precision.
Definition: TRestComplex.h:33
static TRestComplex ASinH(const TRestComplex &c)
Definition: TRestComplex.h:169
int Sign(const mpfr::mpreal &re, const mpfr::mpreal &im)
Definition: TRestComplex.h:139
mpfr::mpreal fIm
The imaginary part of the complex number using MPFR precision.
Definition: TRestComplex.h:38
static TRestComplex ASin(const TRestComplex &c)
Definition: TRestComplex.h:144
static TRestComplex ACos(const TRestComplex &c)
Definition: TRestComplex.h:149
static TRestComplex ACosH(const TRestComplex &c)
Definition: TRestComplex.h:174
mpfr::mpreal fRe
The real part of the complex number using MPFR precision.
Definition: TRestComplex.h:36