Theoretica
A C++ numerical and automatic mathematical library
Loading...
Searching...
No Matches
complex.h
Go to the documentation of this file.
1
5
6#ifndef THEORETICA_COMPLEX_H
7#define THEORETICA_COMPLEX_H
8
9#ifndef THEORETICA_NO_PRINT
10#include <sstream>
11#include <ostream>
12#endif
13
14#include <array>
15
16#include "../core/error.h"
17#include "../core/real_analysis.h"
18
19
20namespace theoretica {
21
22
25 template<typename Type = real>
26 class complex {
27 public:
28
31
34
35
38 complex() : a(0), b(0) {}
39
40
45
46
50
51
53 complex(const complex& z) : a(z.a), b(z.b) {}
54
55
57 inline complex& operator=(const complex& z) {
58 a = z.a;
59 b = z.b;
60 return *this;
61 }
62
63
65 template<typename T = Type>
66 inline complex& operator=(const std::array<T, 2>& v) {
67 a = v[0];
68 b = v[1];
69 return *this;
70 }
71
72
74 inline Type Re() const {
75 return a;
76 }
77
78
80 inline Type& Re() {
81 return a;
82 }
83
84
86 inline friend Type Re(const complex& z) {
87 return z.a;
88 }
89
90
92 inline friend Type& Re(complex& z) {
93 return z.a;
94 }
95
96
98 inline Type Im() const {
99 return b;
100 }
101
102
104 inline Type& Im() {
105 return b;
106 }
107
108
110 inline friend Type Im(const complex& z) {
111 return z.b;
112 }
113
114
116 inline friend Type& Im(complex& z) {
117 return z.b;
118 }
119
120
122 inline complex conjugate() const {
123 return complex(a, -b);
124 }
125
126
128 inline Type sqr_norm() const {
129 return a * a + b * b;
130 }
131
132
134 inline Type norm() const {
135 return sqrt(sqr_norm());
136 }
137
138
140 inline complex inverse() const {
141
142 const Type n = sqr_norm();
143
144 if(n < MACH_EPSILON) {
145 TH_MATH_ERROR("complex::inverse", n, DIV_BY_ZERO);
146 return complex(nan(), nan());
147 }
148
149 return conjugate() / n;
150 }
151
152
154 inline complex& invert() {
155
156 const Type n = sqr_norm();
157
158 if(n < MACH_EPSILON) {
159 TH_MATH_ERROR("complex::invert", n, DIV_BY_ZERO);
160 a = (Type) nan();
161 b = (Type) nan();
162 return *this;
163 }
164
165 a = a / n;
166 b = -b / n;
167
168 return *this;
169 }
170
171
173 inline Type arg() const {
174
175 // Real number case
176 if(abs(b) < MACH_EPSILON) {
177 return (a >= 0) ? ((Type) 0) : ((Type) PI);
178 }
179
180 // Pure imaginary number case
181 if(abs(a) < MACH_EPSILON) {
182 return (b >= 0) ? ((Type) PI / 2.0) : ((Type) -PI / 2.0);
183 }
184
185 // Use the 2-parameter arctangent in the general case
186 return atan2(b, a);
187 }
188
189
191 inline complex operator+() const {
192 return complex(a, b);
193 }
194
195
197 inline complex operator+(const complex& z) const {
198 return complex(a + z.a, b + z.b);
199 }
200
201
203 inline complex operator-() const {
204 return complex(-a, -b);
205 }
206
207
209 inline complex operator-(const complex& z) const {
210 return complex(a - z.a, b - z.b);
211 }
212
213
215 inline complex operator*(const complex& z) const {
216 return complex(
217 a * z.a - b * z.b,
218 a * z.b + b * z.a
219 );
220 }
221
222
224 inline complex operator/(const complex& z) const {
225 return operator*(z.inverse());
226 }
227
228
230 inline complex& operator+=(const complex& z) {
231 return (*this = complex(a + z.a, b + z.b));
232 }
233
234
236 inline complex& operator-=(const complex& z) {
237 return (*this = complex(a - z.a, b - z.b));
238 }
239
240
242 inline complex& operator*=(const complex& z) {
243 return (*this = complex(
244 a * z.a - b * z.b,
245 a * z.b + b * z.a
246 ));
247 }
248
249
251 inline complex& operator/=(const complex& z) {
252 return (*this = operator*(z.inverse()));
253 }
254
255
257 inline complex operator+(Type k) const {
258 return complex(a + k, b);
259 }
260
261
263 inline complex operator-(Type k) const {
264 return complex(a - k, b);
265 }
266
267
269 inline complex operator*(Type k) const {
270 return complex(a * k, b * k);
271 }
272
273
275 inline complex operator/(Type k) const {
276
277 if(abs(k) < MACH_EPSILON) {
278 TH_MATH_ERROR("complex::operator/", k, DIV_BY_ZERO);
279 return complex(nan(), nan());
280 }
281
282 return complex(a / k, b / k);
283 }
284
285
288 return (*this = complex(a + k, b));
289 }
290
291
294 return (*this = complex(a - k, b));
295 }
296
297
300 return (*this = complex(a * k, b * k));
301 }
302
303
306
307 if(abs(k) < MACH_EPSILON) {
308 TH_MATH_ERROR("complex::operator/=", k, DIV_BY_ZERO);
309 return complex(nan(), nan());
310 }
311
312 return (*this = complex(a / k, b / k));
313 }
314
315
317 inline bool operator==(const complex& z) const {
318 return (a == z.a) && (b == z.b);
319 }
320
321
323 inline bool operator!=(const complex& z) const {
324 return !(*this == z);
325 }
326
327
330 inline static complex rotor(Type rad) {
331 return complex(cos(rad), sin(rad));
332 }
333
334
336 inline static complex i() {
337 return complex(0, 1);
338 }
339
340
341 // Friend operators to enable equations of the form
342 // (real) op. (complex)
343
344 inline friend complex operator+(Type r, const complex& z) {
345 return z + r;
346 }
347
348 inline friend complex operator-(Type r, const complex& z) {
349 return -z + r;
350 }
351
352 inline friend complex operator*(Type r, const complex& z) {
353 return z * r;
354 }
355
356 inline friend complex operator/(Type r, const complex& z) {
357 return complex(r, 0) / z;
358 }
359
360
363 inline operator real () {
364
365 if (abs(b) >= MACH_EPSILON) {
366 return nan();
367 }
368
369 return a;
370 }
371
372
373#ifndef THEORETICA_NO_PRINT
374
376 inline std::string to_string() const {
377
378 std::stringstream res;
379
380 // TO-DO Check whether Type has comparison
381 // operators (bicomplex with Type=complex !)
382
383 res << a;
384 res << (b >= 0 ? " + " : " - ");
385
386 if(abs(b) != 1)
387 res << abs(b);
388
389 res << "i";
390
391 return res.str();
392 }
393
394
396 inline operator std::string() {
397 return to_string();
398 }
399
400
403 inline friend std::ostream& operator<<(std::ostream& out, const complex& obj) {
404 return out << obj.to_string();
405 }
406
407#endif
408
409 };
410
411}
412
413#endif
Complex number in algebraic form .
Definition complex.h:26
complex operator*(const complex &z) const
Multiply two complex numbers.
Definition complex.h:215
bool operator!=(const complex &z) const
Check whether two complex numbers are not the same.
Definition complex.h:323
static complex rotor(Type rad)
Construct a complex number representing a rotation of <rad> radians in 2 dimensions.
Definition complex.h:330
friend Type Re(const complex &z)
Extract the real part of the complex number.
Definition complex.h:86
std::string to_string() const
Convert the complex number to string representation.
Definition complex.h:376
Type a
Real part.
Definition complex.h:30
Type & Im()
Get the imaginary part of the complex number.
Definition complex.h:104
friend std::ostream & operator<<(std::ostream &out, const complex &obj)
Stream the complex number in string representation to an output stream (std::ostream)
Definition complex.h:403
complex & operator+=(const complex &z)
Add a complex number to this one.
Definition complex.h:230
complex operator-() const
Get the opposite of the complex number.
Definition complex.h:203
complex & operator-=(const complex &z)
Subtract a complex number from this one.
Definition complex.h:236
complex(Type real_part, Type imag_part)
Construct a complex number from its real and complex parts.
Definition complex.h:43
complex operator+(const complex &z) const
Add two complex numbers.
Definition complex.h:197
friend Type & Im(complex &z)
Extract the imaginary part of the complex number.
Definition complex.h:116
bool operator==(const complex &z) const
Check whether two complex numbers are the same.
Definition complex.h:317
Type sqr_norm() const
Compute the square norm of the complex number.
Definition complex.h:128
complex & operator*=(Type k)
Multiply the complex number by a real number.
Definition complex.h:299
complex()
Default constructor, initializes the number to zero.
Definition complex.h:38
friend Type Im(const complex &z)
Extract the imaginary part of the complex number.
Definition complex.h:110
complex(const complex &z)
Copy constructor.
Definition complex.h:53
complex & invert()
Invert the complex number.
Definition complex.h:154
complex operator+() const
Identity (for consistency)
Definition complex.h:191
complex & operator=(const std::array< T, 2 > &v)
Assignment operator from a 2D array.
Definition complex.h:66
complex operator/(const complex &z) const
Divide two complex numbers.
Definition complex.h:224
complex inverse() const
Compute the inverse of the complex number.
Definition complex.h:140
Type Re() const
Get the real part of the complex number.
Definition complex.h:74
complex operator*(Type k) const
Multiply the complex number by a real number.
Definition complex.h:269
complex(Type real_part)
Construct a complex number from a real number, with zero imaginary part.
Definition complex.h:49
Type b
Imaginary part.
Definition complex.h:33
complex operator/(Type k) const
Divide the complex number by a real number.
Definition complex.h:275
complex & operator*=(const complex &z)
Multiply the complex number by another.
Definition complex.h:242
static complex i()
Imaginary unit.
Definition complex.h:336
complex operator-(Type k) const
Subtract a real number from the complex number.
Definition complex.h:263
complex & operator/=(Type k)
Divide the complex number by a real number.
Definition complex.h:305
Type arg() const
Get the argument of the complex number.
Definition complex.h:173
Type norm() const
Compute the norm of the complex number.
Definition complex.h:134
complex operator-(const complex &z) const
Subtract two complex numbers.
Definition complex.h:209
Type & Re()
Get the real part of the complex number.
Definition complex.h:80
complex & operator+=(Type k)
Add a real number to the complex number.
Definition complex.h:287
complex & operator=(const complex &z)
Assignment operator.
Definition complex.h:57
complex operator+(Type k) const
Add a real number to the complex number.
Definition complex.h:257
friend Type & Re(complex &z)
Extract the real part of the complex number.
Definition complex.h:92
complex & operator-=(Type k)
Subtract a real number from the complex number.
Definition complex.h:293
Type Im() const
Get the imaginary part of the complex number.
Definition complex.h:98
complex & operator/=(const complex &z)
Divide the complex number by another.
Definition complex.h:251
complex conjugate() const
Compute the conjugate of the complex number.
Definition complex.h:122
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compiling opti...
Definition error.h:219
Main namespace of the library which contains all functions and objects.
Definition algebra.h:27
double real
A real number, defined as a floating point type.
Definition constants.h:198
dual2 sqrt(dual2 x)
Compute the square root of a second order dual number.
Definition dual2_functions.h:54
dual2 abs(dual2 x)
Compute the absolute value of a second order dual number.
Definition dual2_functions.h:198
std::remove_reference_t< decltype(std::declval< Structure >()[0])> vector_element_t
Extract the type of a vector (or any indexable container) from its operator[].
Definition core_traits.h:134
real atan2(real y, real x)
Compute the 2 argument arctangent.
Definition real_analysis.h:1098
dual2 cos(dual2 x)
Compute the cosine of a second order dual number.
Definition dual2_functions.h:86
constexpr real MACH_EPSILON
Machine epsilon for the real type.
Definition constants.h:207
dual2 sin(dual2 x)
Compute the sine of a second order dual number.
Definition dual2_functions.h:72
constexpr real PI
The Pi mathematical constant.
Definition constants.h:216
real nan()
Return a quiet NaN number in floating point representation.
Definition error.h:54