Theoretica
A C++ numerical and automatic mathematical library
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 
20 namespace theoretica {
21 
22 
25  template<typename Type = real>
26  class complex {
27  public:
28 
30  Type a;
31 
33  Type b;
34 
35 
38  complex() : a(0), b(0) {}
39 
40 
43  complex(Type real_part, Type imag_part)
44  : a(real_part), b(imag_part) {}
45 
46 
49  complex(Type real_part) : a(real_part), b(0) {}
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 
287  inline complex& operator+=(Type k) {
288  return (*this = complex(a + k, b));
289  }
290 
291 
293  inline complex& operator-=(Type k) {
294  return (*this = complex(a - k, b));
295  }
296 
297 
299  inline complex& operator*=(Type k) {
300  return (*this = complex(a * k, b * k));
301  }
302 
303 
305  inline complex& operator/=(Type k) {
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
complex & operator+=(const complex &z)
Add a complex number to this one.
Definition: complex.h:230
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
complex & operator=(const complex &z)
Assignment operator.
Definition: complex.h:57
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
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
friend Type & Im(complex &z)
Extract the imaginary part of the complex number.
Definition: complex.h:116
complex operator-() const
Get the opposite of the complex number.
Definition: complex.h:203
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
complex & operator/=(Type k)
Divide the complex number by a real number.
Definition: complex.h:305
complex & operator/=(const complex &z)
Divide the complex number by another.
Definition: complex.h:251
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()
Default constructor, initializes the number to zero.
Definition: complex.h:38
complex & operator-=(const complex &z)
Subtract a complex number from this one.
Definition: complex.h:236
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 operator+() const
Identity (for consistency)
Definition: complex.h:191
complex & operator*=(const complex &z)
Multiply the complex number by another.
Definition: complex.h:242
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
friend Type & Re(complex &z)
Extract the real part of the complex number.
Definition: complex.h:92
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
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
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
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) const
Subtract two complex numbers.
Definition: complex.h:209
complex & operator-=(Type k)
Subtract a real number from the complex number.
Definition: complex.h:293
complex operator+(Type k) const
Add a real number to the complex number.
Definition: complex.h:257
complex & invert()
Invert the complex number.
Definition: complex.h:154
Type & Im()
Get the imaginary part of the complex number.
Definition: complex.h:104
Type Im() const
Get the imaginary part of the complex number.
Definition: complex.h:98
complex & operator*=(Type k)
Multiply the complex number by a real number.
Definition: complex.h:299
complex & operator=(const std::array< T, 2 > &v)
Assignment operator from a 2D array.
Definition: complex.h:66
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
std::string string(size_t length)
Generate a random string made of human-readable ASCII characters.
Definition: random.h:102
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:188
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:183
real atan2(real y, real x)
Compute the 2 argument arctangent.
Definition: real_analysis.h:1099
dual2 cos(dual2 x)
Compute the cosine of a second order dual number.
Definition: dual2_functions.h:82
constexpr real MACH_EPSILON
Machine epsilon for the real type.
Definition: constants.h:197
dual2 sin(dual2 x)
Compute the sine of a second order dual number.
Definition: dual2_functions.h:70
constexpr real PI
The Pi mathematical constant.
Definition: constants.h:206
real nan()
Return a quiet NaN number in floating point representation.
Definition: error.h:54