Theoretica
Mathematical Library
Loading...
Searching...
No Matches
complex_analysis.h
Go to the documentation of this file.
1
5
6#ifndef THEORETICA_COMPLEX_FUNCTIONS
7#define THEORETICA_COMPLEX_FUNCTIONS
8
9#include "./complex.h"
10#include "../core/real_analysis.h"
11
12
13namespace theoretica {
14
15
18 template<typename T>
19 inline complex<T> identity(complex<T> z) {
20 return z;
21 }
22
23
26 template<typename T>
27 inline complex<T> conjugate(complex<T> z) {
28 return complex<T>(z.a, -z.b);
29 }
30
31
34 template<typename T>
35 inline complex<T> inverse(complex<T> z) {
36 return conjugate(z) / z.sqr_norm();
37 }
38
39
42 template<typename T>
43 inline complex<T> square(complex<T> z) {
44 return complex<T>(
45 z.Re() * z.Re() - z.Im() * z.Im(),
46 2 * z.Re() * z.Im()
47 );
48 }
49
50
53 template<typename T>
54 inline complex<T> cube(complex<T> z) {
55
56 // Use the algebraic identity minimizing multiplications
57 // (a + bi)^3 = (a^3 - 3ab^2) + (3a^2b - b^3)i
58 const T a2 = z.Re() * z.Re();
59 const T b2 = z.Im() * z.Im();
60
61 const T real_factor = a2 - T(3) * b2;
62 const T imag_factor = T(3) * a2 - b2;
63
64 return complex<T>(z.Re() * real_factor, z.Im() * imag_factor);
65 }
66
67
73 template<typename T>
74 inline complex<T> powf(complex<T> z, real p) {
75
76 if(abs(z.Re()) < MACH_EPSILON && abs(z.Im()) < MACH_EPSILON) {
77
78 if(abs(p) < MACH_EPSILON) {
79 TH_MATH_ERROR("powf(complex, real)", 0, MathError::ImpossibleOperation);
80 return complex<T>(nan(), nan());
81 }
82
83 return complex<T>(0, 0);
84 }
85
86 const real rho = powf(z.norm(), p);
87 const real theta = p * z.arg();
88
89 return complex<T>(rho * th::cos(theta), rho * th::sin(theta));
90 }
91
92
95 template<typename T>
96 inline complex<T> exp(complex<T> z) {
97 return complex<T>(cos(z.Im()), sin(z.Im())) * exp(z.Re());
98 }
99
100
103 template<typename T>
104 inline real abs(complex<T> z) {
105 return z.norm();
106 }
107
108
111 template<typename T>
112 inline complex<T> sin(complex<T> z) {
113
114 const complex<T> t = z * complex<>::i();
115 return (exp(t) - exp(-t)) * complex<T>(0, -0.5);
116 }
117
118
121 template<typename T>
122 inline complex<T> cos(complex<T> z) {
123
124 const complex<T> t = z * complex<>::i();
125 return (exp(t) + exp(-t)) / 2.0;
126 }
127
128
131 template<typename T>
132 inline complex<T> tan(complex<T> z) {
133
134 const complex<T> t = exp(z * complex<T>(0, 2));
135 return (t - complex<T>(1, 0)) / (t + complex<T>(1, 0)) * complex<T>(0, -1);
136 }
137
138
141 template<typename T>
142 inline complex<T> sqrt(complex<T> z) {
143
144 if(abs(z.a) < MACH_EPSILON && abs(z.b) < MACH_EPSILON)
145 return complex<T>(0);
146
147 return complex<T>(
148 INVSQR2 * sqrt((z.norm() + z.Re())),
149 INVSQR2 * sqrt((z.norm() - z.Re())) * sgn(z.b));
150 }
151
152
155 template<typename T>
156 inline complex<T> ln(complex<T> z) {
157 return complex<T>(ln(z.norm()), z.arg());
158 }
159
160
163 template<typename T>
164 inline complex<T> asin(complex<T> z) {
165
166 // For real z in [-1, 1], use real asin
167 if(abs(z.Im()) < MACH_EPSILON && abs(z.Re()) <= 1.0 + MACH_EPSILON) {
168 T real_part = (z.Re() > 1.0) ? 1.0 : ((z.Re() < -1.0) ? -1.0 : z.Re());
169 return complex<T>(asin(real_part), 0);
170 }
171
172 // General formula with better stability
173 return ln(complex<>::i() * z + sqrt(complex<T>(1, 0) - square(z))) * complex<T>(0, -1);
174 }
175
176
179 template<typename T>
180 inline complex<T> acos(complex<T> z) {
181
182 // For real z in [-1, 1], use real acos
183 if(abs(z.Im()) < MACH_EPSILON && abs(z.Re()) <= 1.0 + MACH_EPSILON) {
184 const T real_part = (z.Re() > 1.0) ? 1.0 : ((z. Re() < -1.0) ? -1.0 : z.Re());
185 return complex<T>(acos(real_part), 0);
186 }
187
188 // General formula
189 return ln(z + sqrt(square(z) - complex<T>(1, 0))) * complex<T>(0, -1);
190 }
191
192
195 template<typename T>
196 inline complex<T> atan(complex<T> z) {
197
198 return ln((complex<>::i() - z) / (complex<>::i() + z)) * complex<T>(0, -0.5);
199 }
200
201}
202
203#endif
Complex number in algebraic form .
Definition complex.h:26
static constexpr complex i()
Imaginary unit.
Definition complex.h:336
real Re() const
Return real part.
Definition dual2.h:85
Complex number class.
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compilation op...
Definition error.h:238
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:207
dual2 sqrt(dual2 x)
Compute the square root of a second order dual number.
Definition dual2_functions.h:54
dual2 ln(dual2 x)
Compute the natural logarithm of a second order dual number.
Definition dual2_functions.h:151
dual2 abs(dual2 x)
Compute the absolute value of a second order dual number.
Definition dual2_functions.h:198
dual2 asin(dual2 x)
Compute the arcsine of a second order dual number.
Definition dual2_functions.h:204
complex< T > identity(complex< T > z)
Complex identity.
Definition complex_analysis.h:19
dual2 exp(dual2 x)
Compute the exponential of a second order dual number.
Definition dual2_functions.h:138
complex< T > inverse(complex< T > z)
Compute the conjugate of a complex number.
Definition complex_analysis.h:35
constexpr real INVSQR2
The inverse of the square root of 2.
Definition constants.h:273
dual2 conjugate(dual2 x)
Return the conjugate of a second order dual number.
Definition dual2_functions.h:35
TH_CONSTEXPR real nan()
Return a quiet NaN number in floating point representation.
Definition error.h:78
dual2 cos(dual2 x)
Compute the cosine of a second order dual number.
Definition dual2_functions.h:86
@ ImpossibleOperation
Mathematically impossible operation.
constexpr real MACH_EPSILON
Machine epsilon for the real type.
Definition constants.h:216
dual2 tan(dual2 x)
Compute the tangent of a second order dual number.
Definition dual2_functions.h:100
dual2 acos(dual2 x)
Compute the arcosine of a second order dual number.
Definition dual2_functions.h:223
int sgn(real x)
Return the sign of x (1 if positive, -1 if negative, 0 if null)
Definition real_analysis.h:259
complex< T > powf(complex< T > z, real p)
Compute a complex number raised to a real power.
Definition complex_analysis.h:74
dual2 sin(dual2 x)
Compute the sine of a second order dual number.
Definition dual2_functions.h:72
dual2 square(dual2 x)
Return the square of a second order dual number.
Definition dual2_functions.h:23
dual2 atan(dual2 x)
Compute the arctangent of a second order dual number.
Definition dual2_functions.h:242
dual2 cube(dual2 x)
Return the cube of a second order dual number.
Definition dual2_functions.h:29