thepeg is hosted by Hepforge, IPPP Durham
ThePEG  2.2.1
PhysicalQtyComplex.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // PhysicalQtyComplex.h is a part of ThePEG - Toolkit for HEP Event Generation
4 // Copyright (C) 2006-2019 David Grellscheid, Leif Lonnblad
5 //
6 // ThePEG is licenced under version 3 of the GPL, see COPYING for details.
7 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
8 //
9 #ifndef Physical_Qty_Complex_H
10 #define Physical_Qty_Complex_H
11 #include "PhysicalQty.h"
12 #include "PhysicalQtyOps.h"
13 #include <complex>
14 
19 namespace std {
24  template<>
25  class complex<ThePEG::QtyDouble>
26  {
27  public:
29  constexpr complex(double r=0.0, double i=0.0)
30  : rawValue_(r,i) {}
31 
33  constexpr complex(complex<double> C)
34  : rawValue_(C) {}
35 
40  constexpr complex<double> rawValue() const { return rawValue_; }
41 
43  constexpr double real() const { return rawValue_.real(); }
44 
46  constexpr double imag() const { return rawValue_.imag(); }
47 
49  constexpr operator complex<double>() const {
50  return rawValue_;
51  }
52 
56  rawValue_ += x.rawValue();
57  return *this;
58  }
59 
63  rawValue_ -= x.rawValue();
64  return *this;
65  }
66 
67  private:
69  complex<double> rawValue_;
70  };
71 }
72 // =========================================
73 
74 namespace ThePEG {
75 
77 
78 // complex qty = complex qty * complex qty
79 template<typename L1, typename E1, typename Q1,
80  typename L2, typename E2, typename Q2>
81 inline constexpr auto
82 operator*(std::complex<Qty<L1,E1,Q1>> q1,
83  std::complex<Qty<L2,E2,Q2>> q2)
84 -> std::complex<decltype(q1.real()*q2.real())>
85 {
86  return {q1.real()*q2.real() - q1.imag()*q2.imag(),
87  q1.real()*q2.imag() + q1.imag()*q2.real()};
88 }
89 
90 // complex qty = complex qty * complex qty
91 template<typename L, typename E, typename Q>
92 inline constexpr std::complex<typename Qty<L,E,Q>::Squared>
93 operator*(std::complex<Qty<L,E,Q>> q1,
94  std::complex<Qty<L,E,Q>> q2)
95 {
96  return {q1.real()*q2.real() - q1.imag()*q2.imag(),
97  q1.real()*q2.imag() + q1.imag()*q2.real()};
98 }
99 
100 // complex qty = complex double - complex qty
101 inline constexpr std::complex<double>
102 operator-(std::complex<double> q1, std::complex<QtyDouble> q2) {
103  return {q1.real()-q2.real(), q1.imag()-q2.imag()};
104 }
105 
106 // complex qty = complex double + complex qty
107 inline constexpr std::complex<double>
108 operator+(std::complex<double> q1, std::complex<QtyDouble> q2) {
109  return {q1.real()+q2.real(), q1.imag()+q2.imag()};
110 }
111 
112 // complex qty = complex double * complex qty
113 template<typename L, typename E, typename Q>
114 inline constexpr std::complex<Qty<L,E,Q>>
115 operator*(std::complex<double> q1, std::complex<Qty<L,E,Q>> q2) {
116  return {q1.real()*q2.real() - q1.imag()*q2.imag(),
117  q1.real()*q2.imag() + q1.imag()*q2.real()};
118 }
119 
120 // complex qty = complex double / complex qty
121 template<typename L, typename E, typename Q>
122 inline std::complex<typename Qty<L,E,Q>::Inverse>
123 operator/(std::complex<double> q1, std::complex<Qty<L,E,Q>> q2) {
124  auto tmp = q1*conj(q2);
125  auto norm = (q2*conj(q2)).real();
126  return {tmp.real()/norm, tmp.imag()/norm};
127 }
128 
129 // complex qty = complex double / qty
130 template<typename L, typename E, typename Q>
131 inline constexpr std::complex<typename Qty<L,E,Q>::Inverse>
132 operator/(std::complex<double> q1, Qty<L,E,Q> q2) {
133  return {q1.real()/q2, q1.imag()/q2};
134 }
135 
136 // complex qty = complex qty / complex double
137 template<typename L, typename E, typename Q>
138 inline std::complex<Qty<L,E,Q>>
139 operator/(std::complex<Qty<L,E,Q>> q1, std::complex<double> q2) {
140  auto tmp = q1*conj(q2);
141  auto norm = (q2*conj(q2)).real();
142  return {tmp.real()/norm, tmp.imag()/norm};
143 }
144 
145 // complex qty = qty / complex double
146 template<typename L, typename E, typename Q>
147 inline std::complex<Qty<L,E,Q>>
148 operator/(Qty<L,E,Q> q1, std::complex<double> q2) {
149  auto tmp = q1*conj(q2);
150  auto norm = (q2*conj(q2)).real();
151  return {tmp.real()/norm, tmp.imag()/norm};
152 }
153 
154 // complex double = complex qty / complex qty
155 template<typename L, typename E, typename Q>
156 inline std::complex<double>
157 operator/(std::complex<Qty<L,E,Q>> q1,
158  std::complex<Qty<L,E,Q>> q2) {
159  auto tmp = q1*conj(q2);
160  auto norm = (q2*conj(q2)).real();
161  return {tmp.real()/norm, tmp.imag()/norm};
162 }
163 
164 // complex double = qty / complex qty
165 template<typename L, typename E, typename Q>
166 inline std::complex<double>
167 operator/(Qty<L,E,Q> q1, std::complex<Qty<L,E,Q>> q2) {
168  auto tmp = q1*conj(q2);
169  auto norm = (q2*conj(q2)).real();
170  return {tmp.real()/norm, tmp.imag()/norm};
171 }
172 
173 // complex double = complex qty / qty
174 template<typename L, typename E, typename Q>
175 inline constexpr std::complex<double>
176 operator/(std::complex<Qty<L,E,Q>> q1, Qty<L,E,Q> q2) {
177  return {q1.real()/q2, q1.imag()/q2};
178 }
179 
180 // complex qty = complex qty / complex qty
181 template<typename L1, typename E1, typename Q1,
182  typename L2, typename E2, typename Q2>
183 inline auto
184 operator/(std::complex<Qty<L1,E1,Q1>> q1,
185  std::complex<Qty<L2,E2,Q2>> q2)
186 -> std::complex<decltype(q1.real()/q2.real())>
187 {
188  auto tmp = q1*conj(q2);
189  auto norm = (q2*conj(q2)).real();
190  return {tmp.real()/norm, tmp.imag()/norm};
191 }
192 
193 // complex qty = qty / complex qty
194 template<typename L1, typename E1, typename Q1,
195  typename L2, typename E2, typename Q2>
196 inline auto
197 operator/(Qty<L1,E1,Q1> q1,
198  std::complex<Qty<L2,E2,Q2>> q2)
199 -> std::complex<decltype(q1/q2.real())>
200 {
201  auto tmp = q1*conj(q2);
202  auto norm = (q2*conj(q2)).real();
203  return {tmp.real()/norm, tmp.imag()/norm};
204 }
205 
206 // complex qty = complex qty / qty
207 template<typename L1, typename E1, typename Q1,
208  typename L2, typename E2, typename Q2>
209 inline constexpr auto
210 operator/(std::complex<Qty<L1,E1,Q1>> q1, Qty<L2,E2,Q2> q2)
211 -> std::complex<decltype(q1.real()/q2)>
212 {
213  return {q1.real()/q2, q1.imag()/q2};
214 }
215 
216 
217 // complex qty = complex qty * complex double
218 template<typename L, typename E, typename Q>
219 inline constexpr std::complex<Qty<L,E,Q>>
220 operator*(std::complex<Qty<L,E,Q>> q1, std::complex<double> q2) {
221  return q2 * q1;
222 }
223 
224 
225 // complex qty = qty * complex qty
226 template<typename L1, typename E1, typename Q1,
227  typename L2, typename E2, typename Q2>
228 inline constexpr auto
229 operator*(Qty<L1,E1,Q1> q1, std::complex<Qty<L2,E2,Q2>> q2)
230 -> std::complex<decltype(q1*q2.real())>
231 {
232  return {q1*q2.real(), q1*q2.imag()};
233 }
234 
235 // complex qty = qty * complex qty
236 template<typename L, typename E, typename Q>
237 inline constexpr std::complex<typename Qty<L,E,Q>::Squared>
238 operator*(Qty<L,E,Q> q1, std::complex<Qty<L,E,Q>> q2) {
239  return {q1*q2.real(), q1*q2.imag()};
240 }
241 
242 // complex qty = qty * complex double
243 template<typename L, typename E, typename Q>
244 inline constexpr std::complex<Qty<L,E,Q>>
245 operator*(Qty<L,E,Q> q1, std::complex<double> q2) {
246  return {q1*q2.real(), q1*q2.imag()};
247 }
248 
249 // complex qty = complex double * qty
250 template<typename L, typename E, typename Q>
251 inline constexpr std::complex<Qty<L,E,Q>>
252 operator*(std::complex<double> q1, Qty<L,E,Q> q2) {
253  return q2 * q1;
254 }
255 
256 
257 // complex qty = complex qty * qty
258 template<typename L1, typename E1, typename Q1,
259  typename L2, typename E2, typename Q2>
260 inline constexpr auto
261 operator*(std::complex<Qty<L1,E1,Q1>> q1, Qty<L2,E2,Q2> q2)
262 -> decltype(q2*q1)
263 {
264  return q2 * q1;
265 }
266 
267 // complex qty = complex qty * qty
268 template<typename L, typename E, typename Q>
269 inline constexpr std::complex<typename Qty<L,E,Q>::Squared>
270 operator*(std::complex<Qty<L,E,Q>> q1, Qty<L,E,Q> q2) {
271  return q2 * q1;
272 }
273 
274 // complex qty *= double
275 template<typename L, typename E, typename Q>
276 inline constexpr std::complex<Qty<L,E,Q>> &
277 operator*=(std::complex<Qty<L,E,Q>> & q1, double q2) {
278  return (q1 = q1 * q2);
279 }
280 
281 // complex qty /= double
282 template<typename L, typename E, typename Q>
283 inline constexpr std::complex<Qty<L,E,Q>> &
284 operator/=(std::complex<Qty<L,E,Q>> & q1, double q2) {
285  return (q1 = q1 / q2);
286 }
288 }
289 
290 #endif
The PhysicalQty class allows compile-time checking of dimensional correctness.
STL namespace.
complex< double > rawValue_
Internal value of the dimensioned quantity.
This is the main namespace within which all identifiers in ThePEG are declared.
Definition: FactoryBase.h:28
Overloads for mathematical operations on physical quantities.
complex< ThePEG::QtyDouble > & operator+=(const complex< ThePEG::QtyDouble > x)
Addition-assignment.
constexpr complex(double r=0.0, double i=0.0)
Default constructor.
constexpr double real() const
Real part.
constexpr complex< double > rawValue() const
The internal representation of the dimensionful quantity.
complex< ThePEG::QtyDouble > & operator-=(const complex< ThePEG::QtyDouble > x)
Subtraction-assignment.
constexpr complex(complex< double > C)
Constructor from complex<double>
constexpr double imag() const
Imaginary part.
Template specialization for std::complex<Qty<0,0,0> > with conversions to complex<double> ...