Himalaya
complex.hpp
Go to the documentation of this file.
1 // ====================================================================
2 // This file is part of Himalaya.
3 //
4 // Himalaya is licenced under the GNU General Public License (GNU GPL)
5 // version 3.
6 // ====================================================================
7 
8 #pragma once
9 
10 #include <cmath>
11 #include <complex>
12 
13 namespace himalaya {
14 
15 template <typename T>
16 struct Complex {
17  constexpr Complex(T re_ = T{}, T im_ = T{}) : re(re_), im(im_) {}
18  operator std::complex<T>() const noexcept { return std::complex<T>(re, im); }
19  T re{};
20  T im{};
21 };
22 
23 /// converts -0.0 to 0.0
24 template <typename T>
25 Complex<T> pos(const Complex<T>& z) noexcept
26 {
27  const T rz = z.re == T(0) ? std::abs(z.re) : z.re;
28  const T iz = z.im == T(0) ? std::abs(z.im) : z.im;
29  return { rz, iz };
30 }
31 
32 template <typename T>
33 constexpr T arg(const Complex<T>& z) noexcept
34 {
35  return std::atan2(z.im, z.re);
36 }
37 
38 template <typename T>
39 constexpr Complex<T> conj(const Complex<T>& z) noexcept
40 {
41  return { z.re, -z.im };
42 }
43 
44 template <typename T>
45 Complex<T> log(const Complex<T>& z_) noexcept
46 {
47  const Complex<T> z = pos(z_);
48  return { 0.5*std::log(norm_sqr(z)), arg(z) };
49 }
50 
51 template <typename T>
52 constexpr T norm_sqr(const Complex<T>& z) noexcept
53 {
54  return z.re*z.re + z.im*z.im;
55 }
56 
57 template <typename T>
58 constexpr Complex<T> operator+(const Complex<T>& a, const Complex<T>& b) noexcept
59 {
60  return { a.re + b.re, a.im + b.im };
61 }
62 
63 template <typename T>
64 constexpr Complex<T> operator+(const Complex<T>& z, T x) noexcept
65 {
66  return { z.re + x, z.im };
67 }
68 
69 template <typename T>
70 constexpr Complex<T> operator+(T x, const Complex<T>& z) noexcept
71 {
72  return { x + z.re, z.im };
73 }
74 
75 template <typename T>
76 constexpr Complex<T> operator-(const Complex<T>& a, const Complex<T>& b) noexcept
77 {
78  return { a.re - b.re, a.im - b.im };
79 }
80 
81 template <typename T>
82 constexpr Complex<T> operator-(T x, const Complex<T>& z) noexcept
83 {
84  return { x - z.re, -z.im };
85 }
86 
87 template <typename T>
88 constexpr Complex<T> operator-(const Complex<T>& z, T x) noexcept
89 {
90  return { z.re - x, z.im };
91 }
92 
93 template <typename T>
94 constexpr Complex<T> operator-(const Complex<T>& z) noexcept
95 {
96  return { -z.re, -z.im };
97 }
98 
99 template <typename T>
100 constexpr Complex<T> operator*(const Complex<T>& a, const Complex<T>& b) noexcept
101 {
102  return { a.re*b.re - a.im*b.im, a.re*b.im + a.im*b.re };
103 }
104 
105 template <typename T>
106 constexpr Complex<T> operator*(T x, const Complex<T>& z) noexcept
107 {
108  return { x*z.re, x*z.im };
109 }
110 
111 template <typename T>
112 constexpr Complex<T> operator*(const Complex<T>& z, T x) noexcept
113 {
114  return x*z;
115 }
116 
117 template <typename T>
118 constexpr Complex<T> operator/(T x, const Complex<T>& z) noexcept
119 {
120  return x*conj(z)/norm_sqr(z);
121 }
122 
123 template <typename T>
124 constexpr Complex<T> operator/(const Complex<T>& z, T x) noexcept
125 {
126  return { z.re/x, z.im/x };
127 }
128 
129 } // namespace himalaya
constexpr Complex< T > operator*(const Complex< T > &a, const Complex< T > &b) noexcept
Definition: complex.hpp:100
Definition: H3.cpp:14
constexpr Complex(T re_=T{}, T im_=T{})
Definition: complex.hpp:17
constexpr Complex< T > operator-(const Complex< T > &a, const Complex< T > &b) noexcept
Definition: complex.hpp:76
constexpr Complex< T > operator+(const Complex< T > &a, const Complex< T > &b) noexcept
Definition: complex.hpp:58
constexpr T norm_sqr(const Complex< T > &z) noexcept
Definition: complex.hpp:52
Complex< T > log(const Complex< T > &z_) noexcept
Definition: complex.hpp:45
constexpr Complex< T > conj(const Complex< T > &z) noexcept
Definition: complex.hpp:39
constexpr Complex< T > operator/(T x, const Complex< T > &z) noexcept
Definition: complex.hpp:118
constexpr T arg(const Complex< T > &z) noexcept
Definition: complex.hpp:33
Complex< T > pos(const Complex< T > &z) noexcept
converts -0.0 to 0.0
Definition: complex.hpp:25