C++ Mathematical Expression Toolkit (ExprTk) release
Loading...
Searching...
No Matches
complex_type.hpp
Go to the documentation of this file.
1/*
2 **************************************************************
3 * C++ Mathematical Expression Toolkit Library *
4 * *
5 * Simple Complex Type Example *
6 * Author: Arash Partow (1999-2024) *
7 * URL: https://www.partow.net/programming/exprtk/index.html *
8 * *
9 * Copyright notice: *
10 * Free use of the Mathematical Expression Toolkit Library is *
11 * permitted under the guidelines and in accordance with the *
12 * most current version of the MIT License. *
13 * https://www.opensource.org/licenses/MIT *
14 * SPDX-License-Identifier: MIT *
15 * *
16 **************************************************************
17*/
18
19
20#ifndef INCLUDE_COMPLEX_TYPE_HPP
21#define INCLUDE_COMPLEX_TYPE_HPP
22
23
24#include <cmath>
25#include <complex>
26#include <limits>
27
28
29namespace cmplx
30{
31 struct complex_t
32 {
33 typedef std::complex<double> value_type;
34
36 : c_(0.0)
37 {}
38
40 : c_(d.c_)
41 {}
42
43 complex_t(const double& real,const double& imag)
44 : c_(real,imag)
45 {}
46
48 : c_(v)
49 {}
50
51 complex_t& operator=(const double &d) { c_ = d; return *this; }
52
53 template <typename T>
54 complex_t& operator=(const T d) { c_ = (double)d; return *this; }
55
56 inline complex_t& operator =(const complex_t& r) { c_ = r.c_; return *this; }
57 inline complex_t& operator +=(const complex_t& r) { c_ += r.c_; return *this; }
58 inline complex_t& operator -=(const complex_t& r) { c_ -= r.c_; return *this; }
59 inline complex_t& operator *=(const complex_t& r) { c_ *= r.c_; return *this; }
60 inline complex_t& operator /=(const complex_t& r) { c_ /= r.c_; return *this; }
61
62 inline complex_t& operator =(const double r) { c_ = r; return *this; }
63 inline complex_t& operator +=(const double r) { c_ += r; return *this; }
64 inline complex_t& operator -=(const double r) { c_ -= r; return *this; }
65 inline complex_t& operator *=(const double r) { c_ *= r; return *this; }
66 inline complex_t& operator /=(const double r) { c_ /= r; return *this; }
67
68 inline complex_t& operator++() { c_ += 1.0; return *this; }
69 inline complex_t& operator--() { c_ -= 1.0; return *this; }
70
71 inline complex_t operator++(int) { complex_t tmp(c_); c_ += 1.0; return tmp; }
72 inline complex_t operator--(int) { complex_t tmp(c_); c_ -= 1.0; return tmp; }
73
74 inline complex_t operator-() const { complex_t d; d.c_ = -c_; return d; }
75
76 template <typename T>
77 inline operator T() const { return static_cast<T>(c_.real()); }
78 inline operator bool() const { return (c_ != 0.0); }
79
80 inline bool operator ==(const complex_t& r) const { return (c_ == r.c_); }
81 inline bool operator !=(const complex_t& r) const { return (c_ != r.c_); }
82
83 std::complex<double> c_;
84 };
85
86 inline complex_t operator+(const complex_t r0, const complex_t r1) { return complex_t(r0.c_ + r1.c_); }
87 inline complex_t operator-(const complex_t r0, const complex_t r1) { return complex_t(r0.c_ - r1.c_); }
88 inline complex_t operator*(const complex_t r0, const complex_t r1) { return complex_t(r0.c_ * r1.c_); }
89 inline complex_t operator/(const complex_t r0, const complex_t r1) { return complex_t(r0.c_ / r1.c_); }
90
91
92 inline bool operator< (const complex_t c0, const complex_t c1) { return std::arg(c0.c_) < std::arg(c1.c_); }
93 inline bool operator> (const complex_t c0, const complex_t c1) { return std::arg(c0.c_) > std::arg(c1.c_); }
94 inline bool operator<=(const complex_t c0, const complex_t c1) { return std::arg(c0.c_) <= std::arg(c1.c_); }
95 inline bool operator>=(const complex_t c0, const complex_t c1) { return std::arg(c0.c_) >= std::arg(c1.c_); }
96
97 #define complex_define_inequalities(Type) \
98 inline complex_t operator+ (const Type& r0, const complex_t& r1) { return complex_t(r0 + r1.c_); } \
99 inline complex_t operator- (const Type& r0, const complex_t& r1) { return complex_t(r0 - r1.c_); } \
100 inline complex_t operator* (const Type& r0, const complex_t& r1) { return complex_t(r0 * r1.c_); } \
101 inline complex_t operator/ (const Type& r0, const complex_t& r1) { return complex_t(r0 / r1.c_); } \
102 inline bool operator==(const Type& r0, const complex_t& r1) { return (r0 == r1.c_); } \
103 inline bool operator!=(const Type& r0, const complex_t& r1) { return (r0 != r1.c_); } \
104 inline complex_t operator+ (const complex_t& r0, const Type& r1) { return complex_t(r0.c_ + r1); } \
105 inline complex_t operator- (const complex_t& r0, const Type& r1) { return complex_t(r0.c_ - r1); } \
106 inline complex_t operator* (const complex_t& r0, const Type& r1) { return complex_t(r0.c_ * r1); } \
107 inline complex_t operator/ (const complex_t& r0, const Type& r1) { return complex_t(r0.c_ / r1); } \
108
110}
111
112namespace std
113{
115 template <>
116 class numeric_limits<complex_t>
117 {
119
120 public:
121
122 static const bool is_specialized = true;
123 static number_complex_t (min) () { return complex_t(std::numeric_limits<double>::min()); }
124 static number_complex_t (max) () { return complex_t(std::numeric_limits<double>::max()); }
125 static number_complex_t lowest() { return -(max)(); }
126 static number_complex_t epsilon() { return complex_t(std::numeric_limits<double>::epsilon ()); }
127 static number_complex_t round_error() { return complex_t(std::numeric_limits<double>::round_error ()); }
128 static number_complex_t infinity() { return complex_t(std::numeric_limits<double>::infinity ()); }
129 static number_complex_t quiet_NaN() { return complex_t(std::numeric_limits<double>::quiet_NaN ()); }
130 static number_complex_t signaling_NaN() { return complex_t(std::numeric_limits<double>::signaling_NaN()); }
131 static number_complex_t denorm_min() { return complex_t(std::numeric_limits<double>::denorm_min ()); }
132 static const int digits = std::numeric_limits<double>::digits;
133 static const int digits10 = std::numeric_limits<double>::digits10;
134 static const int radix = std::numeric_limits<double>::radix;
135 static const int min_exponent = std::numeric_limits<double>::min_exponent;
136 static const int min_exponent10 = std::numeric_limits<double>::min_exponent10;
137 static const int max_exponent = std::numeric_limits<double>::max_exponent;
138 static const int max_exponent10 = std::numeric_limits<double>::max_exponent10;
139 static const bool has_infinity = std::numeric_limits<double>::has_infinity;
140 static const bool has_quiet_NaN = std::numeric_limits<double>::has_quiet_NaN;
141 static const bool has_signaling_NaN = std::numeric_limits<double>::has_signaling_NaN;
142 static const bool has_denorm_loss = std::numeric_limits<double>::has_denorm_loss;
143 static const bool is_signed = std::numeric_limits<double>::is_signed;
144 static const bool is_integer = std::numeric_limits<double>::is_integer;
145 static const bool is_exact = std::numeric_limits<double>::is_exact;
146 static const bool is_iec559 = std::numeric_limits<double>::is_iec559;
147 static const bool is_bounded = std::numeric_limits<double>::is_bounded;
148 static const bool is_modulo = std::numeric_limits<double>::is_modulo;
149 static const bool traps = std::numeric_limits<double>::traps;
150 static const float_denorm_style has_denorm = std::numeric_limits<double>::has_denorm;
151 static const float_round_style round_style = std::numeric_limits<double>::round_style;
152 };
153}
154
155namespace cmplx
156{
157 namespace details
158 {
159
160 namespace constant
161 {
162 static const complex_t e = complex_t( 2.718281828459045235360);
163 static const complex_t pi = complex_t( 3.141592653589793238462);
164 static const complex_t pi_2 = complex_t( 1.570796326794896619231);
165 static const complex_t pi_4 = complex_t( 0.785398163397448309616);
166 static const complex_t pi_180 = complex_t( 0.017453292519943295769);
167 static const complex_t _1_pi = complex_t( 0.318309886183790671538);
168 static const complex_t _2_pi = complex_t( 0.636619772367581343076);
169 static const complex_t _180_pi = complex_t(57.295779513082320876798);
170 static const complex_t log2 = complex_t( 0.693147180559945309417);
171 static const complex_t sqrt2 = complex_t( 1.414213562373095048801);
172 }
173 }
174
175 inline complex_t abs(const complex_t v) { return complex_t(std::abs (v.c_)); }
176 inline complex_t acos(const complex_t v) { return complex_t(std::acos (v.c_)); }
177 inline complex_t asin(const complex_t v) { return complex_t(std::asin (v.c_)); }
178 inline complex_t atan(const complex_t v) { return complex_t(std::atan (v.c_)); }
179 inline complex_t ceil(const complex_t v) { return complex_t(std::ceil (v.c_.real()),std::ceil (v.c_.imag())); }
180 inline complex_t cos(const complex_t v) { return complex_t(std::cos (v.c_)); }
181 inline complex_t cosh(const complex_t v) { return complex_t(std::cosh (v.c_)); }
182 inline complex_t exp(const complex_t v) { return complex_t(std::exp (v.c_)); }
183 inline complex_t floor(const complex_t v) { return complex_t(std::floor(v.c_.real()),std::floor(v.c_.imag())); }
184 inline complex_t log(const complex_t v) { return complex_t(std::log (v.c_)); }
185 inline complex_t log10(const complex_t v) { return complex_t(std::log10(v.c_)); }
186 inline complex_t log2(const complex_t v) { return complex_t(std::log(v.c_) / details::constant::log2.c_); }
187 inline complex_t neg(const complex_t v) { return complex_t(-1.0 * v.c_); }
188 inline complex_t pos(const complex_t v) { return v; }
189 inline complex_t sin(const complex_t v) { return complex_t(std::sin (v.c_)); }
190 inline complex_t sinh(const complex_t v) { return complex_t(std::sinh (v.c_)); }
191 inline complex_t sqrt(const complex_t v) { return complex_t(std::sqrt (v.c_)); }
192 inline complex_t tan(const complex_t v) { return complex_t(std::tan (v.c_)); }
193 inline complex_t tanh(const complex_t v) { return complex_t(std::tanh (v.c_)); }
194 inline complex_t cot(const complex_t v) { return complex_t(1.0 / std::tan(v.c_)); }
195 inline complex_t sec(const complex_t v) { return complex_t(1.0 / std::cos(v.c_)); }
196 inline complex_t csc(const complex_t v) { return complex_t(1.0 / std::sin(v.c_)); }
199 inline complex_t d2g(const complex_t v) { return complex_t(v.c_ * (20.0/9.0)); }
200 inline complex_t g2d(const complex_t v) { return complex_t(v.c_ * (9.0/20.0)); }
201 inline complex_t notl(const complex_t v) { return complex_t(v != complex_t(0) ? complex_t(0) : complex_t(1)); }
202 inline complex_t frac(const complex_t v) { return complex_t(v.c_.real() - static_cast<long long>(v.c_.real())); }
203 inline complex_t trunc(const complex_t v) { return complex_t((double)static_cast<long long>(v.c_.real())); }
204
205 inline complex_t modulus(const complex_t v0, const complex_t v1) { return complex_t(fmod(v0.c_.real() , v1.c_.real()),fmod(v0.c_.imag() , v1.c_.imag())); }
206 inline complex_t pow(const complex_t v0, const complex_t v1) { return complex_t(std::pow(v0.c_,v1.c_) ); }
207 inline complex_t logn(const complex_t v0, const complex_t v1) { return complex_t(std::log(v0.c_) / std::log(v1.c_)); }
208 inline complex_t root(const complex_t v0, const complex_t v1) { return pow(v0,complex_t(1.0) / v1); }
209 inline complex_t atan2(const complex_t v0, const complex_t v1) { return complex_t(std::atan2(v0.c_.real(),v0.c_.imag()),std::atan2(v1.c_.real(),v1.c_.imag())); }
210 inline complex_t max(const complex_t v0, const complex_t v1) { return complex_t(v0 > v1 ? v0.c_ : v1.c_); }
211 inline complex_t min(const complex_t v0, const complex_t v1) { return complex_t(v0 < v1 ? v0.c_ : v1.c_); }
212
213 inline bool is_true (const complex_t v) { return (v != complex_t(0)); }
214 inline bool is_false (const complex_t v) { return (v == complex_t(0)); }
215
216 inline complex_t equal(const complex_t v0x, const complex_t v1x)
217 {
218 const complex_t v0 = v0x;
219 const complex_t v1 = v1x;
220 static const complex_t epsilon = complex_t(0.0000000001);
221 return (abs(v0 - v1) <= (max(complex_t(1),max(abs(v0),abs(v1))) * epsilon)) ? complex_t(1) : complex_t(0);
222 }
223
224 inline complex_t expm1(const complex_t vx)
225 {
226 const complex_t v = vx;
227 if (abs(v) < complex_t(0.00001))
228 return complex_t(v + (0.5 * v * v));
229 else
230 return complex_t(exp(v) - complex_t(1));
231 }
232
233 inline complex_t nequal(const complex_t v0, const complex_t v1)
234 {
235 static const complex_t epsilon = complex_t(0.0000000001);
236 return (abs(v0 - v1) > (max(complex_t(1),max(abs(v0),abs(v1))) * epsilon)) ? complex_t(1) : complex_t(0);
237 }
238
239 inline complex_t log1p(const complex_t v)
240 {
241 if (v > complex_t(-1))
242 {
243 if (abs(v) > complex_t(0.0001))
244 {
245 return log(complex_t(1) + v);
246 }
247 else
248 return (complex_t(-0.5) * v + complex_t(1)) * v;
249 }
250 else
251 return complex_t(std::numeric_limits<double>::quiet_NaN());
252 }
253
254 inline complex_t round(const complex_t v)
255 {
256 return ((v < complex_t(0)) ? ceil(v - complex_t(0.5)) : floor(v + complex_t(0.5)));
257 }
258
259 inline complex_t roundn(const complex_t v0, const complex_t v1)
260 {
261 const complex_t p10 = pow(complex_t(10),trunc(v1));
262 if (v0 < complex_t(0))
263 return complex_t(ceil ((v0 * p10) - complex_t(0.5)) / p10);
264 else
265 return complex_t(floor((v0 * p10) + complex_t(0.5)) / p10);
266 }
267
268 inline complex_t hypot(const complex_t v0, const complex_t v1)
269 {
270 return sqrt((v0 * v0) + (v1 * v1));
271 }
272
273 inline complex_t shr(const complex_t v0, const complex_t v1)
274 {
275 return v0 * (complex_t(1) / pow(complex_t(2),trunc(v1)));
276 }
277
278 inline complex_t shl(const complex_t v0, const complex_t v1)
279 {
280 return v0 * pow(complex_t(2),trunc(v1));
281 }
282
283 inline complex_t sgn(const complex_t v)
284 {
285 if (v > complex_t(0)) return complex_t(+1);
286 else if (v < complex_t(0)) return complex_t(-1);
287 else return complex_t( 0);
288 }
289
290 inline complex_t nand(const complex_t v0, const complex_t& v1)
291 {
292 return (is_false(v0) || is_false(v1)) ? complex_t(1) : complex_t(0);
293 }
294
295 inline complex_t nor(const complex_t v0, const complex_t& v1)
296 {
297 return (is_false(v0) && is_false(v1)) ? complex_t(1) : complex_t(0);
298 }
299
300 inline complex_t xnor(const complex_t v0, const complex_t& v1)
301 {
302 const bool v0_true = is_true(v0);
303 const bool v1_true = is_true(v1);
304 if ((v0_true && v1_true) || (!v0_true && !v1_true))
305 return complex_t(1);
306 else
307 return complex_t(0);
308 }
309
310 inline complex_t erf(complex_t /*v*/)
311 {
312 // Note: Implementation for erf of a complex number is required.
313 // http://ab-initio.mit.edu/Faddeeva.hh
314 return complex_t(0);
315 }
316
318 {
319 return complex_t(1) - erf(v);
320 }
321}
322
323#endif
static number_complex_t denorm_min()
static number_complex_t round_error()
static number_complex_t lowest()
static number_complex_t quiet_NaN()
static number_complex_t infinity()
static number_complex_t epsilon()
static number_complex_t signaling_NaN()
#define complex_define_inequalities(Type)
static const complex_t sqrt2
static const complex_t _180_pi
static const complex_t pi_2
static const complex_t pi_4
static const complex_t e
static const complex_t pi_180
static const complex_t _2_pi
static const complex_t log2
static const complex_t pi
static const complex_t _1_pi
complex_t log(const complex_t v)
complex_t cosh(const complex_t v)
complex_t expm1(const complex_t vx)
bool operator<=(const complex_t c0, const complex_t c1)
complex_t floor(const complex_t v)
complex_t shl(const complex_t v0, const complex_t v1)
complex_t modulus(const complex_t v0, const complex_t v1)
complex_t sinh(const complex_t v)
complex_t r2d(const complex_t v)
bool operator>=(const complex_t c0, const complex_t c1)
complex_t abs(const complex_t v)
complex_t asin(const complex_t v)
complex_t nequal(const complex_t v0, const complex_t v1)
complex_t tanh(const complex_t v)
complex_t root(const complex_t v0, const complex_t v1)
complex_t tan(const complex_t v)
complex_t operator+(const complex_t r0, const complex_t r1)
complex_t round(const complex_t v)
complex_t frac(const complex_t v)
complex_t min(const complex_t v0, const complex_t v1)
complex_t csc(const complex_t v)
complex_t operator-(const complex_t r0, const complex_t r1)
complex_t operator*(const complex_t r0, const complex_t r1)
complex_t d2g(const complex_t v)
complex_t erfc(complex_t v)
complex_t sgn(const complex_t v)
complex_t trunc(const complex_t v)
complex_t d2r(const complex_t v)
bool operator>(const complex_t c0, const complex_t c1)
complex_t atan2(const complex_t v0, const complex_t v1)
complex_t exp(const complex_t v)
complex_t log1p(const complex_t v)
complex_t sin(const complex_t v)
complex_t operator/(const complex_t r0, const complex_t r1)
complex_t nand(const complex_t v0, const complex_t &v1)
complex_t atan(const complex_t v)
complex_t max(const complex_t v0, const complex_t v1)
complex_t ceil(const complex_t v)
complex_t g2d(const complex_t v)
bool operator<(const complex_t c0, const complex_t c1)
complex_t pos(const complex_t v)
complex_t notl(const complex_t v)
complex_t erf(complex_t)
complex_t sqrt(const complex_t v)
complex_t roundn(const complex_t v0, const complex_t v1)
complex_t acos(const complex_t v)
complex_t logn(const complex_t v0, const complex_t v1)
complex_t neg(const complex_t v)
bool is_false(const complex_t v)
complex_t equal(const complex_t v0x, const complex_t v1x)
complex_t shr(const complex_t v0, const complex_t v1)
bool is_true(const complex_t v)
complex_t sec(const complex_t v)
complex_t log10(const complex_t v)
complex_t pow(const complex_t v0, const complex_t v1)
complex_t log2(const complex_t v)
complex_t xnor(const complex_t v0, const complex_t &v1)
complex_t cos(const complex_t v)
complex_t cot(const complex_t v)
complex_t nor(const complex_t v0, const complex_t &v1)
complex_t hypot(const complex_t v0, const complex_t v1)
bool operator==(const complex_t &r) const
complex_t(const complex_t &d)
complex_t(const double &real, const double &imag)
complex_t & operator=(const double &d)
std::complex< double > c_
complex_t & operator*=(const complex_t &r)
complex_t & operator++()
complex_t operator--(int)
bool operator!=(const complex_t &r) const
complex_t & operator-=(const complex_t &r)
complex_t operator++(int)
std::complex< double > value_type
complex_t operator-() const
complex_t & operator/=(const complex_t &r)
complex_t & operator+=(const complex_t &r)
complex_t & operator--()
complex_t & operator=(const T d)
complex_t(const value_type &v)