PeriDyno 1.0.0
Loading...
Searching...
No Matches
Complex.inl
Go to the documentation of this file.
1#include "Math/SimpleMath.h"
2#include <glm/glm.hpp>
4
5namespace dyno
6{
7 template <typename Real>
9 m_real(0.0), m_imag(0.0)
10 {
11 }
12
13 template <typename Real>
14 DYN_FUNC Complex<Real>::Complex(Real real, Real imag) :
15 m_real(real), m_imag(imag)
16 {
17 }
18
19 template <typename Real>
20 DYN_FUNC const Complex<Real> Complex<Real>::operator+ (const Complex<Real> &other) const {
21 Complex<Real> sum;
22 sum.m_real = m_real + other.m_real;
23 sum.m_imag = m_imag + other.m_imag;
24 return sum;
25 }
26
27 template <typename Real>
28 DYN_FUNC const Complex<Real> Complex<Real>::operator- (const Complex<Real> &other) const {
29 Complex dif;
30 dif.m_real = m_real - other.m_real;
31 dif.m_imag = m_imag - other.m_imag;
32 return dif;
33 }
34
35 template <typename Real>
36 DYN_FUNC const Complex<Real> Complex<Real>::operator* (const Complex<Real> &other) const
37 {
38 Complex mul;
39 mul.m_real = (m_real * other.m_real - m_imag * other.m_imag);
40 mul.m_imag = (m_real * other.m_imag + m_imag * other.m_real);
41 return mul;
42 }
43
44 template <typename Real>
45 DYN_FUNC const Complex<Real> Complex<Real>::operator/(const Complex<Real> &other) const
46 {
47 Complex div;
48 double l = (other.m_real*other.m_real + other.m_imag*other.m_imag);
49
50
51
52 double c = (m_real*other.m_real + m_imag * other.m_imag) / l;
53 double d = (m_imag*other.m_real - m_real * other.m_imag) / l;
54 div.m_real = c;
55 div.m_imag = d;
56 return div;
57 }
58
59 template <typename Real>
61 {
62 m_real += other.realPart();
63 m_imag += other.imagPart();
64 return *this;
65 }
66
67 template <typename Real>
69 {
70 m_real -= other.realPart();
71 m_imag -= other.imagPart();
72 return *this;
73 }
74
75 template <typename Real>
76 DYN_FUNC Complex<Real> &Complex<Real>::operator*=(const Complex &other)
77 {
78 double j = m_real * other.m_real + m_imag * other.m_imag;
79 double k = m_real * other.m_imag + m_imag * other.m_real;
80 m_real = j;
81 m_imag = k;
82 return *this;
83 }
84
85 template <typename Real>
87 {
88 double a = (m_real*other.m_real + m_imag * other.m_imag) /
89 (other.m_real*other.m_real + other.m_imag*other.m_imag);
90 double b = (m_imag*other.m_real - m_real * other.m_imag) / (other.m_real*other.m_real + other.m_imag*other.m_imag);
91 m_real = a;
92 m_imag = b;
93 return *this;
94 }
95
96
97 template <typename Real>
99 {
100 m_real = other.m_real;
101 m_imag = other.m_imag;
102
103 return *this;
104 }
105
106
107 template <typename Real>
108 DYN_FUNC bool Complex<Real>::operator==(const Complex<Real> &other) const
109 {
110 if (glm::abs(m_real - other.m_real) < dyno::REAL_EPSILON && glm::abs(m_imag - other.m_imag) < dyno::REAL_EPSILON) {
111 return true;
112 }
113 else {
114 return false;
115 }
116 return false;
117 }
118
119 template <typename Real>
120 DYN_FUNC bool Complex<Real>::operator!=(const Complex<Real> &other) const
121 {
122 return !(*this == other);
123 }
124
125
126 template <typename Real>
127 DYN_FUNC const Complex<Real> Complex<Real>::operator+(const Real& real) const
128 {
129 Complex<Real> addition;
130 addition.m_real = m_real + real;
131 addition.m_imag = m_imag;
132 return addition;
133 }
134
135 template <typename Real>
136 DYN_FUNC const Complex<Real> Complex<Real>::operator-(const Real& real) const
137 {
138 Complex<Real> sub;
139 sub.m_real = m_real - real;
140 sub.m_imag = m_imag;
141 return sub;
142 }
143
144 template <typename Real>
145 DYN_FUNC const Complex<Real> Complex<Real>::operator*(const Real& real) const
146 {
147 Complex<Real> mul;
148 mul.m_real = m_real * real;
149 mul.m_imag = m_imag * real;
150 return mul;
151 }
152
153
154 template <typename Real>
155 DYN_FUNC const Complex<Real> Complex<Real>::operator/(const Real& real) const
156 {
157 Complex<Real> div;
158 div.m_real = m_real / real;
159 div.m_imag = m_imag / real;
160 return div;
161 }
162
163 template <typename Real>
165 {
166 m_real += real;
167 return *this;
168 }
169
170
171 template <typename Real>
173 {
174 m_real -= real;
175 return *this;
176 }
177
178 template <typename Real>
180 {
181 m_real *= real;
182 m_imag *= real;
183 return *this;
184 }
185
186
187 template <typename Real>
189 {
190 m_real /= real;
191 m_imag /= real;
192 return *this;
193 }
194
195
196 template <typename Real>
197 DYN_FUNC const Complex<Real> Complex<Real>::operator-(void) const
198 {
199 Complex<Real> neg;
200 neg.m_real = -m_real;
201 neg.m_imag = -m_imag;
202 return neg;
203 }
204
205
206 template <typename Real>
208 {
210 return res;
211 }
212
213
214 template <typename Real>
215 DYN_FUNC Real Complex<Real>::norm() const
216 {
217 return glm::sqrt(m_real*m_real + m_imag * m_imag);
218 }
219
220
221 template <typename Real>
223 {
224 return m_real * m_real + m_imag * m_imag;
225 }
226
227 //Relax the threshold by 10 times
228 template <typename Real>
229 DYN_FUNC bool Complex<Real>::isReal() const
230 {
231 return glm::abs(m_imag) < Real(10)*REAL_EPSILON;
232 }
233
234 template <typename S, typename T>
235 DYN_FUNC const Complex<T> operator +(S scale, const Complex<T> &complex)
236 {
237 return complex + (T)scale;
238 }
239
240 template <typename S, typename T>
241 DYN_FUNC const Complex<T> operator -(S scale, const Complex<T> &complex)
242 {
243 return Complex<T>((T)scale, T(0)) - complex;
244 }
245
246 template <typename S, typename T>
247 DYN_FUNC const Complex<T> operator *(S scale, const Complex<T> &complex)
248 {
249 return complex * (T)scale;
250 }
251
252 template <typename S, typename T>
253 DYN_FUNC const Complex<T> operator /(S scale, const Complex<T> &complex)
254 {
255 return Complex<T>((T)scale, T(0)) / complex;
256 }
257
258
259 template<class Real>
260 DYN_FUNC Complex<Real> sinh(const Complex<Real>& __x)
261 {
262 if (isinf(__x.realPart()) && !isfinite(__x.imagPart()))
263 return Complex<Real>(__x.realPart(), Real(NAN));
264 if (__x.realPart() == 0 && !isfinite(__x.imagPart()))
265 return Complex<Real>(__x.realPart(), Real(NAN));
266 if (__x.imagPart() == 0 && !isfinite(__x.realPart()))
267 return __x;
268 return Complex<Real>(sinh(__x.realPart()) * cos(__x.imagPart()), cosh(__x.realPart()) * sin(__x.imagPart()));
269 }
270
271
272 template<typename Real>
273 inline DYN_FUNC Real arg(const Complex<Real>& __c)
274 {
275 return atan2(__c.imagPart(), __c.realPart());
276 }
277
278 template<typename Real>
279 inline DYN_FUNC Complex<Real> polar(const Real& __rho, const Real& __theta)
280 {
281 if (isnan(__rho) || signbit(__rho))
282 return Complex<Real>(Real(NAN), Real(NAN));
283 if (isnan(__theta))
284 {
285 if (isinf(__rho))
286 return Complex<Real>(__rho, __theta);
287 return Complex<Real>(__theta, __theta);
288 }
289 if (isinf(__theta))
290 {
291 if (isinf(__rho))
292 return Complex<Real>(__rho, Real(NAN));
293 return Complex<Real>(Real(NAN), Real(NAN));
294 }
295 Real __x = __rho * glm::cos(__theta);
296 if (isnan(__x))
297 __x = 0;
298 Real __y = __rho * glm::sin(__theta);
299 if (isnan(__y))
300 __y = 0;
301 return Complex<Real>(__x, __y);
302 }
303
304 template<typename Real>
305 inline DYN_FUNC Complex<Real> log(const Complex<Real>& __x)
306 {
307 return Complex<Real>(glm::log(__x.norm()), arg(__x));
308 }
309
310 // log10
311
312 template<typename Real>
313 inline DYN_FUNC Complex<Real> log10(const Complex<Real>& __x)
314 {
315 return log(__x) / log(Real(10));
316 }
317
318 // sqrt
319
320 template<typename Real>
321 inline DYN_FUNC Complex<Real> sqrt(const Complex<Real>& __x)
322 {
323 if (isinf(__x.imagPart()))
324 return Complex<Real>(Real(INFINITY), __x.imagPart());
325 if (isinf(__x.realPart()))
326 {
327 if (__x.realPart() > Real(0))
328 return Complex<Real>(__x.realPart(), isnan(__x.imagPart()) ? __x.imagPart() : copysign(Real(0), __x.imagPart()));
329 return Complex<Real>(isnan(__x.imagPart()) ? __x.imagPart() : Real(0), copysign(__x.realPart(), __x.imagPart()));
330 }
331
332 return polar(glm::sqrt(__x.norm()), arg(__x) / Real(2));
333 }
334
335 // exp
336
337 template<class Real>
338 DYN_FUNC Complex<Real> exp(const Complex<Real>& __x)
339 {
340 Real __i = __x.imagPart();
341 if (isinf(__x.realPart()))
342 {
343 if (__x.realPart() < Real(0))
344 {
345 if (!isfinite(__i))
346 __i = Real(1);
347 }
348 else if (__i == 0 || !isfinite(__i))
349 {
350 if (isinf(__i))
351 __i = Real(NAN);
352 return Complex<Real>(__x.realPart(), __i);
353 }
354 }
355 else if (isnan(__x.realPart()) && __x.imagPart() == 0)
356 return __x;
357 Real __e = glm::exp(__x.realPart());
358 return Complex<Real>(__e * glm::cos(__i), __e * glm::sin(__i));
359 }
360
361 // pow
362
363 template<class Real>
364 inline DYN_FUNC Complex<Real> pow(const Complex<Real>& __x, const Complex<Real>& __y)
365 {
366 return exp(__y * log(__x));
367 }
368
369 template<class Real>
370 inline DYN_FUNC Complex<Real> pow(const Complex<Real>& __x, const Real& __y)
371 {
372 return pow(__x, Complex<Real>(__y));
373 }
374
375 template<class Real>
376 inline DYN_FUNC Complex<Real> pow(const Real& __x, const Complex<Real>& __y)
377 {
378 return pow(Complex<Real>(__x), __y);
379 }
380
381 // asinh
382
383 template<class Real>
384 DYN_FUNC Complex<Real> asinh(const Complex<Real>& __x)
385 {
386 const Real __pi(atan2(+0., -0.));
387 if (isinf(__x.realPart()))
388 {
389 if (isnan(__x.imagPart()))
390 return __x;
391 if (isinf(__x.imagPart()))
392 return Complex<Real>(__x.realPart(), copysign(__pi * Real(0.25), __x.imagPart()));
393 return Complex<Real>(__x.realPart(), copysign(Real(0), __x.imagPart()));
394 }
395 if (isnan(__x.realPart()))
396 {
397 if (isinf(__x.imagPart()))
398 return Complex<Real>(__x.imagPart(), __x.realPart());
399 if (__x.imagPart() == 0)
400 return __x;
401 return Complex<Real>(__x.realPart(), __x.realPart());
402 }
403 if (isinf(__x.imagPart()))
404 return Complex<Real>(copysign(__x.imagPart(), __x.realPart()), copysign(__pi / Real(2), __x.imagPart()));
405 Complex<Real> __z = log(__x + sqrt(pow(__x, Real(2)) + Real(1)));
406 return Complex<Real>(copysign(__z.realPart(), __x.realPart()), copysign(__z.imagPart(), __x.imagPart()));
407 }
408
409 template<class Real>
410 DYN_FUNC Complex<Real> cosh(const Complex<Real>& __x)
411 {
412 if (isinf(__x.realPart()) && !isfinite(__x.imagPart()))
413 return Complex<Real>(glm::abs(__x.realPart()), Real(NAN));
414 if (__x.realPart() == 0 && !isfinite(__x.imagPart()))
415 return Complex<Real>(Real(NAN), __x.realPart());
416 if (__x.realPart() == 0 && __x.imagPart() == 0)
417 return Complex<Real>(Real(1), __x.imagPart());
418 if (__x.imagPart() == 0 && !isfinite(__x.realPart()))
419 return Complex<Real>(glm::abs(__x.realPart()), __x.imagPart());
420 return Complex<Real>(glm::cosh(__x.realPart()) * glm::cos(__x.imagPart()), glm::sinh(__x.realPart()) * glm::sin(__x.imagPart()));
421 }
422
423
424 // acosh
425
426 template<class Real>
427 DYN_FUNC Complex<Real> acosh(const Complex<Real>& __x)
428 {
429 const Real __pi(atan2(+0., -0.));
430 if (isinf(__x.realPart()))
431 {
432 if (isnan(__x.imagPart()))
433 return Complex<Real>(fabs(__x.realPart()), __x.imagPart());
434 if (isinf(__x.imagPart()))
435 if (__x.realPart() > 0)
436 return Complex<Real>(__x.realPart(), copysign(__pi * Real(0.25), __x.imagPart()));
437 else
438 return Complex<Real>(-__x.realPart(), copysign(__pi * Real(0.75), __x.imagPart()));
439 if (__x.realPart() < 0)
440 return Complex<Real>(-__x.realPart(), copysign(__pi, __x.imagPart()));
441 return Complex<Real>(__x.realPart(), copysign(Real(0), __x.imagPart()));
442 }
443 if (isnan(__x.realPart()))
444 {
445 if (isinf(__x.imagPart()))
446 return Complex<Real>(fabs(__x.imagPart()), __x.realPart());
447 return Complex<Real>(__x.realPart(), __x.realPart());
448 }
449 if (isinf(__x.imagPart()))
450 return Complex<Real>(fabs(__x.imagPart()), copysign(__pi / Real(2), __x.imagPart()));
451 Complex<Real> __z = log(__x + sqrt(pow(__x, Real(2)) - Real(1)));
452 return Complex<Real>(copysign(__z.realPart(), Real(0)), copysign(__z.imagPart(), __x.imagPart()));
453 }
454
455 // atanh
456
457 template<class Real>
458 DYN_FUNC Complex<Real> atanh(const Complex<Real>& __x)
459 {
460 const Real __pi(atan2(+0., -0.));
461 if (isinf(__x.imagPart()))
462 {
463 return Complex<Real>(copysign(Real(0), __x.realPart()), copysign(__pi / Real(2), __x.imagPart()));
464 }
465 if (isnan(__x.imagPart()))
466 {
467 if (isinf(__x.realPart()) || __x.realPart() == 0)
468 return Complex<Real>(copysign(Real(0), __x.realPart()), __x.imagPart());
469 return Complex<Real>(__x.imagPart(), __x.imagPart());
470 }
471 if (isnan(__x.realPart()))
472 {
473 return Complex<Real>(__x.realPart(), __x.realPart());
474 }
475 if (isinf(__x.realPart()))
476 {
477 return Complex<Real>(copysign(Real(0), __x.realPart()), copysign(__pi / Real(2), __x.imagPart()));
478 }
479 if (fabs(__x.realPart()) == Real(1) && __x.imagPart() == Real(0))
480 {
481 return Complex<Real>(copysign(Real(INFINITY), __x.realPart()), copysign(Real(0), __x.imagPart()));
482 }
483 Complex<Real> __z = log((Real(1) + __x) / (Real(1) - __x)) / Real(2);
484 return Complex<Real>(copysign(__z.realPart(), __x.realPart()), copysign(__z.imagPart(), __x.imagPart()));
485 }
486
487
488 // tanh
489
490 template<class Real>
491 DYN_FUNC Complex<Real> tanh(const Complex<Real>& __x)
492 {
493 if (isinf(__x.realPart()))
494 {
495 if (!isfinite(__x.imagPart()))
496 return Complex<Real>(Real(1), Real(0));
497 return Complex<Real>(Real(1), copysign(Real(0), sin(Real(2) * __x.imagPart())));
498 }
499 if (isnan(__x.realPart()) && __x.imagPart() == 0)
500 return __x;
501 Real __2r(Real(2) * __x.realPart());
502 Real __2i(Real(2) * __x.imagPart());
503 Real __d(cosh(__2r) + cos(__2i));
504 return Complex<Real>(sinh(__2r) / __d, sin(__2i) / __d);
505 }
506
507 // asin
508
509 template<class Real>
510 DYN_FUNC Complex<Real> asin(const Complex<Real>& __x)
511 {
512 Complex<Real> __z = asinh(Complex<Real>(-__x.imagPart(), __x.realPart()));
513 return Complex<Real>(__z.imagPart(), -__z.realPart());
514 }
515
516 // acos
517
518 template<class Real>
519 DYN_FUNC Complex<Real> acos(const Complex<Real>& __x)
520 {
521 const Real __pi(atan2(+0., -0.));
522 if (isinf(__x.realPart()))
523 {
524 if (isnan(__x.imagPart()))
525 return Complex<Real>(__x.imagPart(), __x.realPart());
526 if (isinf(__x.imagPart()))
527 {
528 if (__x.realPart() < Real(0))
529 return Complex<Real>(Real(0.75) * __pi, -__x.imagPart());
530 return Complex<Real>(Real(0.25) * __pi, -__x.imagPart());
531 }
532 if (__x.realPart() < Real(0))
533 return Complex<Real>(__pi, signbit(__x.imagPart()) ? -__x.realPart() : __x.realPart());
534 return Complex<Real>(Real(0), signbit(__x.imagPart()) ? __x.realPart() : -__x.realPart());
535 }
536 if (isnan(__x.realPart()))
537 {
538 if (isinf(__x.imagPart()))
539 return Complex<Real>(__x.realPart(), -__x.imagPart());
540 return Complex<Real>(__x.realPart(), __x.realPart());
541 }
542 if (isinf(__x.imagPart()))
543 return Complex<Real>(__pi / Real(2), -__x.imagPart());
544 if (__x.realPart() == 0)
545 return Complex<Real>(__pi / Real(2), -__x.imagPart());
546 Complex<Real> __z = log(__x + sqrt(pow(__x, Real(2)) - Real(1)));
547 if (signbit(__x.imagPart()))
548 return Complex<Real>(fabs(__z.imagPart()), fabs(__z.realPart()));
549 return Complex<Real>(fabs(__z.imagPart()), -fabs(__z.realPart()));
550 }
551
552 // atan
553
554 template<class Real>
555 DYN_FUNC Complex<Real> atan(const Complex<Real>& __x)
556 {
557 Complex<Real> __z = atanh(Complex<Real>(-__x.imagPart(), __x.realPart()));
558 return Complex<Real>(__z.imagPart(), -__z.realPart());
559 }
560
561 // sin
562
563 template<class Real>
564 DYN_FUNC Complex<Real> sin(const Complex<Real>& __x)
565 {
566 Complex<Real> __z = sinh(Complex<Real>(-__x.imagPart(), __x.realPart()));
567 return Complex<Real>(__z.imagPart(), -__z.realPart());
568 }
569
570 // cos
571
572 template<class Real>
573 inline DYN_FUNC Complex<Real> cos(const Complex<Real>& __x)
574 {
575 return cosh(Complex<Real>(-__x.imagPart(), __x.realPart()));
576 }
577
578 // tan
579
580 template<class Real>
581 DYN_FUNC Complex<Real> tan(const Complex<Real>& __x)
582 {
583 Complex<Real> __z = tanh(Complex<Real>(-__x.imagPart(), __x.realPart()));
584 return Complex<Real>(__z.imagPart(), -__z.realPart());
585 }
586
587
588}
589
double Real
Definition Typedef.inl:23
Real m_real
Definition Complex.h:68
DYN_FUNC const Complex< Real > operator+(const Complex< Real > &other) const
Definition Complex.inl:20
DYN_FUNC bool operator==(const Complex< Real > &other) const
Definition Complex.inl:108
DYN_FUNC Real realPart() const
Definition Complex.h:27
DYN_FUNC Real normSquared() const
Definition Complex.inl:222
DYN_FUNC const Complex< Real > operator*(const Complex< Real > &other) const
Definition Complex.inl:36
DYN_FUNC Complex()
Definition Complex.inl:8
DYN_FUNC Real norm() const
Definition Complex.inl:215
DYN_FUNC Complex< Real > & operator/=(const Complex< Real > &other)
Definition Complex.inl:86
DYN_FUNC Complex< Real > & operator-=(const Complex< Real > &other)
Definition Complex.inl:68
DYN_FUNC const Complex< Real > operator-(void) const
Definition Complex.inl:197
DYN_FUNC const Complex< Real > operator/(const Complex< Real > &other) const
Definition Complex.inl:45
DYN_FUNC bool operator!=(const Complex< Real > &other) const
Definition Complex.inl:120
DYN_FUNC Real imagPart() const
Definition Complex.h:28
DYN_FUNC Complex< Real > & operator*=(const Complex< Real > &other)
DYN_FUNC Complex< Real > conjugate() const
Definition Complex.inl:207
DYN_FUNC bool isReal() const
Definition Complex.inl:229
DYN_FUNC Complex< Real > & operator=(const Complex< Real > &other)
Definition Complex.inl:98
DYN_FUNC Complex< Real > & operator+=(const Complex< Real > &other)
Definition Complex.inl:60
Real m_imag
Definition Complex.h:69
#define T(t)
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
DYN_FUNC Complex< Real > cosh(const Complex< Real > &)
Definition Complex.inl:410
DYN_FUNC Real arg(const Complex< Real > &)
Definition Complex.inl:273
DYN_FUNC Complex< Real > atanh(const Complex< Real > &)
Definition Complex.inl:458
DYN_FUNC Complex< Real > tanh(const Complex< Real > &)
Definition Complex.inl:491
DYN_FUNC Complex< Real > log(const Complex< Real > &)
Definition Complex.inl:305
DYN_FUNC Complex< Real > sin(const Complex< Real > &)
Definition Complex.inl:564
DYN_FUNC Complex< Real > pow(const Complex< Real > &, const Real &)
Definition Complex.inl:370
DYN_FUNC Complex< Real > tan(const Complex< Real > &)
Definition Complex.inl:581
DYN_FUNC Complex< Real > cos(const Complex< Real > &)
Definition Complex.inl:573
DYN_FUNC const Complex< T > operator/(S scale, const Complex< T > &complex)
Definition Complex.inl:253
DYN_FUNC const Complex< T > operator*(S scale, const Complex< T > &complex)
Definition Complex.inl:247
constexpr Real REAL_EPSILON
Definition Typedef.inl:43
DYN_FUNC Complex< Real > acos(const Complex< Real > &)
Definition Complex.inl:519
DYN_FUNC Complex< Real > acosh(const Complex< Real > &)
Definition Complex.inl:427
DYN_FUNC Complex< Real > asinh(const Complex< Real > &)
Definition Complex.inl:384
DYN_FUNC Complex< Real > exp(const Complex< Real > &)
Definition Complex.inl:338
DYN_FUNC Complex< Real > sqrt(const Complex< Real > &)
Definition Complex.inl:321
DYN_FUNC Complex< Real > polar(const Real &__rho, const Real &__theta=Real(0))
Definition Complex.inl:279
DYN_FUNC Complex< Real > log10(const Complex< Real > &)
Definition Complex.inl:313
DYN_FUNC Complex< Real > sinh(const Complex< Real > &)
Definition Complex.inl:260
DYN_FUNC const Complex< T > operator-(S scale, const Complex< T > &complex)
Definition Complex.inl:241
DYN_FUNC const Complex< T > operator+(S scale, const Complex< T > &complex)
Definition Complex.inl:235
DYN_FUNC Complex< Real > asin(const Complex< Real > &)
Definition Complex.inl:510
DYN_FUNC Complex< Real > atan(const Complex< Real > &)
Definition Complex.inl:555