AmpGen 2.1
Loading...
Searching...
No Matches
Complex.h
Go to the documentation of this file.
1#ifndef AMPGEN_COMPLEX_H
2#define AMPGEN_COMPLEX_H 1
3
4#include <complex>
5
6namespace AmpGen {
7 template <typename real_t> struct Complex {
10 using rt = real_t;
11 Complex() = default;
12 Complex(const real_t &re, const real_t &im) : re(re), im(im) {}
13 // Complex( const float& re, const float& im) : re(re), im(im) {}
14 Complex(const std::complex<double> &f) : re(f.real()), im(f.imag()) {}
15 Complex(const std::complex<float> &f) : re(f.real()), im(f.imag()) {}
16 explicit Complex(const real_t &arg) : re(arg) {};
17 Complex(const real_t &re, const double &im) : re(re), im(im) {}
18 // explicit Complex( const double& arg ) : re(arg) {};
19 inline Complex operator+=(const Complex &rhs);
20 inline Complex operator-=(const Complex &rhs);
21 inline Complex operator*=(const Complex &rhs);
22 inline Complex operator/=(const Complex &rhs);
23 real_t real() const { return re; }
24 real_t imag() const { return im; }
25 real_t norm() const { return re * re + im * im; }
26 };
27 namespace detail {
28 template <typename complex_t, typename real_t> complex_t make_complex(const real_t &re, const real_t &im) { return complex_t(re, im); }
29 template <typename complex_t> complex_t make_complex(const typename complex_t::rt &re) {
30 using real_t = typename complex_t::rt;
31 return complex_t(re, real_t(0.));
32 }
33 template <typename complex_t> complex_t make_complex(const complex_t &cmplx) { return cmplx; }
34 }
35
36 template <typename real_t> inline real_t real(const Complex<real_t> &arg) { return arg.re; }
37 template <typename real_t> inline real_t real(const real_t &arg) { return arg; }
38 template <typename real_t> inline real_t imag(const Complex<real_t> &arg) { return arg.im; }
39 template <typename real_t> inline real_t abs(const Complex<real_t> &v) { return sqrt(v.re * v.re + v.im * v.im); }
40 template <typename real_t> inline real_t norm(const Complex<real_t> &v) { return (v.re * v.re + v.im * v.im); }
41 template <typename real_t> inline Complex<real_t> conj(const Complex<real_t> &arg) { return Complex<real_t>(arg.re, -arg.im); }
42
43 template <typename real_t, typename R2_t> inline Complex<real_t> operator+(const Complex<real_t> &lhs, const R2_t &rhs) {
44 return Complex<real_t>(lhs.re + real_t(rhs), lhs.im);
45 }
46 template <typename real_t, typename R2_t> inline Complex<real_t> operator-(const Complex<real_t> &lhs, const R2_t &rhs) {
47 return Complex<real_t>(lhs.re - real_t(rhs), lhs.im);
48 }
49 template <typename real_t, typename R2_t> inline Complex<real_t> operator*(const Complex<real_t> &lhs, const R2_t &rhs) {
50 return Complex<real_t>(lhs.re * real_t(rhs), lhs.im * real_t(rhs));
51 }
52 template <typename real_t, typename R2_t> inline Complex<real_t> operator/(const Complex<real_t> &lhs, const R2_t &rhs) {
53 return Complex<real_t>(lhs.re / real_t(rhs), lhs.im / real_t(rhs));
54 }
55 template <typename real_t, typename R2_t> inline Complex<real_t> operator+(const R2_t &lhs, const Complex<real_t> &rhs) {
56 return Complex<real_t>(real_t(lhs) + rhs.re, rhs.im);
57 }
58 template <typename real_t, typename R2_t> inline Complex<real_t> operator-(const R2_t &lhs, const Complex<real_t> &rhs) {
59 return Complex<real_t>(real_t(lhs) - rhs.re, -rhs.im);
60 }
61 template <typename real_t, typename R2_t> inline Complex<real_t> operator*(const R2_t &lhs, const Complex<real_t> &rhs) {
62 return Complex<real_t>(real_t(lhs) * rhs.re, lhs * rhs.im);
63 }
64 template <typename real_t, typename R2_t> inline Complex<real_t> operator/(const R2_t &lhs, const Complex<real_t> &rhs) {
65 return Complex<real_t>(real_t(lhs) * rhs.re, -real_t(lhs) * rhs.im) / (rhs.re * rhs.re + rhs.im * rhs.im);
66 }
67 template <typename real_t> inline Complex<real_t> operator+(const Complex<real_t> &lhs, const Complex<real_t> &rhs) {
68 return Complex<real_t>(lhs.re + rhs.re, lhs.im + rhs.im);
69 }
70 template <typename real_t> inline Complex<real_t> operator-(const Complex<real_t> &lhs, const Complex<real_t> &rhs) {
71 return Complex<real_t>(lhs.re - rhs.re, lhs.im - rhs.im);
72 }
73 template <typename real_t> inline Complex<real_t> operator*(const Complex<real_t> &lhs, const Complex<real_t> &rhs) {
74 return Complex<real_t>(lhs.re * rhs.re - lhs.im * rhs.im, lhs.re * rhs.im + lhs.im * rhs.re);
75 }
76 template <typename real_t> inline Complex<real_t> operator/(const Complex<real_t> &lhs, const Complex<real_t> &rhs) {
77 return Complex<real_t>(lhs.re * rhs.re + lhs.im * rhs.im, -lhs.re * rhs.im + lhs.im * rhs.re) / (rhs.re * rhs.re + rhs.im * rhs.im);
78 }
79 template <typename real_t> inline Complex<real_t> operator-(const Complex<real_t> &x) { return -1.f * x; }
80 template <typename real_t> inline Complex<real_t> Complex<real_t>::operator+=(const Complex<real_t> &rhs) {
81 *this = *this + rhs;
82 return *this;
83 }
84 template <typename real_t> inline Complex<real_t> Complex<real_t>::operator-=(const Complex<real_t> &rhs) {
85 *this = *this - rhs;
86 return *this;
87 }
88 template <typename real_t> inline Complex<real_t> Complex<real_t>::operator*=(const Complex<real_t> &rhs) {
89 *this = *this * rhs;
90 return *this;
91 }
92 template <typename real_t> inline Complex<real_t> Complex<real_t>::operator/=(const Complex<real_t> &rhs) {
93 *this = *this / rhs;
94 return *this;
95 }
96 template <typename real_t> inline Complex<real_t> exp(const Complex<real_t> &v) {
97 auto [s, c] = sincos(v.im);
98 return exp(v.re) * Complex<real_t>(c, s);
99 }
100 template <typename real_t> inline Complex<real_t> sqrt(const Complex<real_t> &v) {
101 auto r = abs(v);
102 return Complex(sqrt(0.5 * (r + v.re)), sign(v.im) * sqrt(0.5 * (r - v.re)));
103 }
104 template <typename real_t> inline Complex<real_t> log(const Complex<real_t> &v) { return Complex<real_t>(0.5 * log(v.norm()), atan2(v.im, v.re)); }
105 template <typename real_t> inline std::ostream &operator<<(std::ostream &os, const Complex<real_t> &obj) {
106 return os << "( " << obj.re << ") (" << obj.im << ")";
107 }
108}
109
110#endif
complex_t make_complex(const real_t &re, const real_t &im)
Definition Complex.h:28
double real_t
Definition Types.h:6
Complex< real_t > operator/(const Complex< real_t > &lhs, const R2_t &rhs)
Definition Complex.h:52
Complex< real_t > operator*(const Complex< real_t > &lhs, const R2_t &rhs)
Definition Complex.h:49
std::complex< real_t > complex_t
Definition Types.h:7
Complex< real_t > log(const Complex< real_t > &v)
Definition Complex.h:104
Complex< real_t > conj(const Complex< real_t > &arg)
Definition Complex.h:41
Complex< real_t > sqrt(const Complex< real_t > &v)
Definition Complex.h:100
std::ostream & operator<<(std::ostream &os, const CompiledExpressionBase &expression)
real_t abs(const Complex< real_t > &v)
Definition Complex.h:39
real_t norm(const Complex< real_t > &v)
Definition Complex.h:40
Complex< real_t > operator+(const Complex< real_t > &lhs, const R2_t &rhs)
Definition Complex.h:43
real_t real(const Complex< real_t > &arg)
Definition Complex.h:36
Complex< real_t > exp(const Complex< real_t > &v)
Definition Complex.h:96
Complex< real_t > operator-(const Complex< real_t > &lhs, const R2_t &rhs)
Definition Complex.h:46
real_t imag(const Complex< real_t > &arg)
Definition Complex.h:38
Complex(const real_t &arg)
Definition Complex.h:16
real_v real() const
Definition Complex.h:23
Complex()=default
Complex(const real_t &re, const double &im)
Definition Complex.h:17
Complex operator+=(const Complex &rhs)
Definition Complex.h:80
real_t norm() const
Definition Complex.h:25
real_v imag() const
Definition Complex.h:24
Complex(const std::complex< double > &f)
Definition Complex.h:14
Complex operator*=(const Complex &rhs)
Definition Complex.h:88
Complex operator-=(const Complex &rhs)
Definition Complex.h:84
Complex(const real_t &re, const real_t &im)
Definition Complex.h:12
Complex(const std::complex< float > &f)
Definition Complex.h:15
Complex operator/=(const Complex &rhs)
Definition Complex.h:92