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
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
221namespace cling {
222std::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