thepeg is hosted by Hepforge, IPPP Durham
ThePEG 2.3.0
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
19namespace 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
54 complex<ThePEG::QtyDouble> &
55 operator+=(const complex<ThePEG::QtyDouble> x) {
56 rawValue_ += x.rawValue();
57 return *this;
58 }
59
61 complex<ThePEG::QtyDouble> &
62 operator-=(const complex<ThePEG::QtyDouble> x) {
63 rawValue_ -= x.rawValue();
64 return *this;
65 }
66
67 private:
69 complex<double> rawValue_;
70 };
71}
72// =========================================
73
74namespace ThePEG {
75
77
78// complex qty = complex qty * complex qty
79template<typename L1, typename E1, typename Q1,
80 typename L2, typename E2, typename Q2>
81inline constexpr auto
82operator*(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
91template<typename L, typename E, typename Q>
92inline constexpr std::complex<typename Qty<L,E,Q>::Squared>
93operator*(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
101inline constexpr std::complex<double>
102operator-(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
107inline constexpr std::complex<double>
108operator+(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
113template<typename L, typename E, typename Q>
114inline constexpr std::complex<Qty<L,E,Q>>
115operator*(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
121template<typename L, typename E, typename Q>
122inline std::complex<typename Qty<L,E,Q>::Inverse>
123operator/(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
130template<typename L, typename E, typename Q>
131inline constexpr std::complex<typename Qty<L,E,Q>::Inverse>
132operator/(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
137template<typename L, typename E, typename Q>
138inline std::complex<Qty<L,E,Q>>
139operator/(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
146template<typename L, typename E, typename Q>
147inline std::complex<Qty<L,E,Q>>
148operator/(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
155template<typename L, typename E, typename Q>
156inline std::complex<double>
157operator/(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
165template<typename L, typename E, typename Q>
166inline std::complex<double>
167operator/(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
174template<typename L, typename E, typename Q>
175inline constexpr std::complex<double>
176operator/(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
181template<typename L1, typename E1, typename Q1,
182 typename L2, typename E2, typename Q2>
183inline auto
184operator/(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
194template<typename L1, typename E1, typename Q1,
195 typename L2, typename E2, typename Q2>
196inline auto
197operator/(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
207template<typename L1, typename E1, typename Q1,
208 typename L2, typename E2, typename Q2>
209inline constexpr auto
210operator/(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
218template<typename L, typename E, typename Q>
219inline constexpr std::complex<Qty<L,E,Q>>
220operator*(std::complex<Qty<L,E,Q>> q1, std::complex<double> q2) {
221 return q2 * q1;
222}
223
224
225// complex qty = qty * complex qty
226template<typename L1, typename E1, typename Q1,
227 typename L2, typename E2, typename Q2>
228inline constexpr auto
229operator*(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
236template<typename L, typename E, typename Q>
237inline constexpr std::complex<typename Qty<L,E,Q>::Squared>
238operator*(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
243template<typename L, typename E, typename Q>
244inline constexpr std::complex<Qty<L,E,Q>>
245operator*(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
250template<typename L, typename E, typename Q>
251inline constexpr std::complex<Qty<L,E,Q>>
252operator*(std::complex<double> q1, Qty<L,E,Q> q2) {
253 return q2 * q1;
254}
255
256
257// complex qty = complex qty * qty
258template<typename L1, typename E1, typename Q1,
259 typename L2, typename E2, typename Q2>
260inline constexpr auto
261operator*(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
268template<typename L, typename E, typename Q>
269inline constexpr std::complex<typename Qty<L,E,Q>::Squared>
270operator*(std::complex<Qty<L,E,Q>> q1, Qty<L,E,Q> q2) {
271 return q2 * q1;
272}
273
274// complex qty *= double
275template<typename L, typename E, typename Q>
276inline constexpr std::complex<Qty<L,E,Q>> &
277operator*=(std::complex<Qty<L,E,Q>> & q1, double q2) {
278 return (q1 = q1 * q2);
279}
280
281// complex qty /= double
282template<typename L, typename E, typename Q>
283inline constexpr std::complex<Qty<L,E,Q>> &
284operator/=(std::complex<Qty<L,E,Q>> & q1, double q2) {
285 return (q1 = q1 / q2);
286}
288}
289
290#endif
Overloads for mathematical operations on physical quantities.
The PhysicalQty class allows compile-time checking of dimensional correctness.
constexpr double real() const
Real part.
complex< ThePEG::QtyDouble > & operator+=(const complex< ThePEG::QtyDouble > x)
Addition-assignment.
constexpr complex(double r=0.0, double i=0.0)
Default constructor.
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.
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
STL namespace.