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>
8 struct Complex {
11 using rt = real_t;
12 Complex() = default;
13 Complex( const real_t& re, const real_t& im) : re(re), im(im) {}
14 // Complex( const float& re, const float& im) : re(re), im(im) {}
15 Complex( const std::complex<double>& f ) : re( f.real() ), im( f.imag() ) {}
16 Complex( const std::complex<float>& f ) : re( f.real() ), im( f.imag() ) {}
17 explicit Complex( const real_t& arg ) : re(arg) {};
18 Complex(const real_t& re, const double& im ) : re(re), im(im) {}
19 // explicit Complex( const double& arg ) : re(arg) {};
20 inline Complex operator+=(const Complex& rhs );
21 inline Complex operator-=(const Complex& rhs );
22 inline Complex operator*=(const Complex& rhs );
23 inline Complex operator/=(const Complex& rhs );
24 real_t real() const { return re; }
25 real_t imag() const { return im; }
26 real_t norm() const { return re*re + im *im ; }
27 };
28 namespace detail {
29
30 template <typename complex_t, typename real_t> complex_t make_complex( const real_t& re, const real_t& im ){
31 return complex_t(re, im );
32 }
33 template <typename complex_t> complex_t make_complex( const typename complex_t::rt& re){
34 using real_t = typename complex_t::rt;
35 return complex_t(re, real_t(0.) );
36 }
37 template <typename complex_t> complex_t make_complex( const complex_t& cmplx ){
38 return cmplx;
39 }
40 }
41
42 template<typename real_t> inline real_t real(const Complex<real_t>& arg ){ return arg.re ; }
43 template<typename real_t> inline real_t real(const real_t& arg ){ return arg; }
44 template<typename real_t> inline real_t imag(const Complex<real_t>& arg ){ return arg.im ; }
45 template<typename real_t> inline real_t abs(const Complex<real_t>& v ) { return sqrt( v.re * v.re + v.im * v.im ) ; }
46 template<typename real_t> inline real_t norm(const Complex<real_t>& v ) { return ( v.re * v.re + v.im * v.im ) ; }
47 template<typename real_t> inline Complex<real_t> conj(const Complex<real_t>& arg ){ return Complex<real_t>(arg.re, -arg.im) ; }
48
49
50 template<typename real_t, typename R2_t> inline Complex<real_t> operator+( const Complex<real_t>& lhs, const R2_t& rhs ) { return Complex<real_t>(lhs.re + real_t(rhs), lhs.im); }
51 template<typename real_t, typename R2_t> inline Complex<real_t> operator-( const Complex<real_t>& lhs, const R2_t& rhs ) { return Complex<real_t>(lhs.re - real_t(rhs), lhs.im); }
52 template<typename real_t, typename R2_t> inline Complex<real_t> operator*( const Complex<real_t>& lhs, const R2_t& rhs ) { return Complex<real_t>(lhs.re*real_t(rhs), lhs.im*real_t(rhs)); }
53 template<typename real_t, typename R2_t> inline Complex<real_t> operator/( const Complex<real_t>& lhs, const R2_t& rhs ) { return Complex<real_t>(lhs.re/real_t(rhs), lhs.im/real_t(rhs)); }
54 template<typename real_t, typename R2_t> inline Complex<real_t> operator+( const R2_t& lhs, const Complex<real_t>& rhs ) { return Complex<real_t>(real_t(lhs) + rhs.re, rhs.im); }
55 template<typename real_t, typename R2_t> inline Complex<real_t> operator-( const R2_t& lhs, const Complex<real_t>& rhs ) { return Complex<real_t>(real_t(lhs) - rhs.re, - rhs.im); }
56 template<typename real_t, typename R2_t> inline Complex<real_t> operator*( const R2_t& lhs, const Complex<real_t>& rhs ) { return Complex<real_t>(real_t(lhs)*rhs.re, lhs*rhs.im); }
57 template<typename real_t, typename R2_t> inline Complex<real_t> operator/( const R2_t& lhs, const Complex<real_t>& rhs ) { return Complex<real_t>( real_t(lhs) * rhs.re , -real_t(lhs) *rhs.im) / (rhs.re * rhs.re + rhs.im * rhs.im ); }
58 template<typename real_t> inline Complex<real_t> operator+( const Complex<real_t>& lhs, const Complex<real_t>& rhs ) { return Complex<real_t>(lhs.re + rhs.re, lhs.im + rhs.im); }
59 template<typename real_t> inline Complex<real_t> operator-( const Complex<real_t>& lhs, const Complex<real_t>& rhs ) { return Complex<real_t>(lhs.re - rhs.re, lhs.im - rhs.im); }
60 template<typename real_t> inline Complex<real_t> operator*( const Complex<real_t>& lhs, const Complex<real_t>& rhs ) { return Complex<real_t>(lhs.re*rhs.re - lhs.im*rhs.im, lhs.re*rhs.im + lhs.im*rhs.re); }
61 template<typename real_t> inline Complex<real_t> operator/( const Complex<real_t>& lhs, const Complex<real_t>& rhs ) { 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 ); }
62 template<typename real_t> inline Complex<real_t> operator-( const Complex<real_t>& x ) { return -1.f * x; }
63 template<typename real_t> inline Complex<real_t> Complex<real_t>::operator+=(const Complex<real_t>& rhs ){ *this = *this + rhs; return *this; }
64 template<typename real_t> inline Complex<real_t> Complex<real_t>::operator-=(const Complex<real_t>& rhs ){ *this = *this - rhs; return *this; }
65 template<typename real_t> inline Complex<real_t> Complex<real_t>::operator*=(const Complex<real_t>& rhs ){ *this = *this * rhs; return *this; }
66 template<typename real_t> inline Complex<real_t> Complex<real_t>::operator/=(const Complex<real_t>& rhs ){ *this = *this / rhs; return *this; }
67 template<typename real_t> inline Complex<real_t> exp( const Complex<real_t>& v ){
68 auto [s,c] = sincos(v.im);
69 return exp(v.re) * Complex<real_t>(c, s);
70 }
71 template <typename real_t>
73 {
74 auto r = abs(v);
75 return Complex ( sqrt( 0.5 * (r + v.re) ), sign(v.im) * sqrt( 0.5*( r - v.re ) ) );
76 }
77 template <typename real_t>
79 {
80 return Complex<real_t>( 0.5 * log( v.norm() ) , atan2(v.im, v.re) );
81 }
82 template <typename real_t>
83 inline std::ostream& operator<<( std::ostream& os, const Complex<real_t>& obj ) { return os << "( "<< obj.re << ") (" << obj.im << ")"; }
84}
85
86#endif
complex_t make_complex(const real_t &re, const real_t &im)
Definition Complex.h:30
double real_t
Definition Types.h:6
Complex< real_t > operator/(const Complex< real_t > &lhs, const R2_t &rhs)
Definition Complex.h:53
Complex< real_t > operator*(const Complex< real_t > &lhs, const R2_t &rhs)
Definition Complex.h:52
std::complex< real_t > complex_t
Definition Types.h:7
Complex< real_t > log(const Complex< real_t > &v)
Definition Complex.h:78
Complex< real_t > conj(const Complex< real_t > &arg)
Definition Complex.h:47
Complex< real_t > sqrt(const Complex< real_t > &v)
Definition Complex.h:72
std::ostream & operator<<(std::ostream &os, const CompiledExpressionBase &expression)
real_t abs(const Complex< real_t > &v)
Definition Complex.h:45
real_t norm(const Complex< real_t > &v)
Definition Complex.h:46
Complex< real_t > operator+(const Complex< real_t > &lhs, const R2_t &rhs)
Definition Complex.h:50
real_t real(const Complex< real_t > &arg)
Definition Complex.h:42
Complex< real_t > exp(const Complex< real_t > &v)
Definition Complex.h:67
Complex< real_t > operator-(const Complex< real_t > &lhs, const R2_t &rhs)
Definition Complex.h:51
real_t imag(const Complex< real_t > &arg)
Definition Complex.h:44
Complex(const real_t &arg)
Definition Complex.h:17
real_v real() const
Definition Complex.h:24
Complex()=default
Complex(const real_t &re, const double &im)
Definition Complex.h:18
Complex operator+=(const Complex &rhs)
Definition Complex.h:63
real_t norm() const
Definition Complex.h:26
real_v imag() const
Definition Complex.h:25
Complex(const std::complex< double > &f)
Definition Complex.h:15
Complex operator*=(const Complex &rhs)
Definition Complex.h:65
Complex operator-=(const Complex &rhs)
Definition Complex.h:64
Complex(const real_t &re, const real_t &im)
Definition Complex.h:13
Complex(const std::complex< float > &f)
Definition Complex.h:16
Complex operator/=(const Complex &rhs)
Definition Complex.h:66