Complex Numbers
This chapter describes the complex numbers as supported by MAD-NG. The module for Complex numbers is not exposed, only the contructors are visible from the MAD
environment and thus, complex numbers are handled directly by their methods or by the generic functions of the same name from the module MAD.gmath
. Note that complex have value semantic like a pair of number equivalent to a C structure or an array const num_t[2]
for direct compliance with the C API.
Types promotion
The operations on complex numbers may involve other data types like real numbers leading to few combinations of types. In order to simplify the descriptions, the generic names num
and cpx
are used for real and complex numbers respectively. The following table summarizes all valid combinations of types for binary operations involving at least one complex type:
Left Operand Type |
Right Operand Type |
Result Type |
---|---|---|
number |
complex |
complex |
complex |
number |
complex |
complex |
complex |
complex |
Constructors
The constructors for complex numbers are directly available from the MAD
environment, except for the special case of the imaginary postfix, which is part of the language definition.
- i
The imaginary postfix that qualifies literal numbers as imaginary numbers, i.e.
1i
is the imaginary unit, and1+2i
is the complex number \(1+2i\).
- complex(re_, im_)
Return the complex number equivalent to
re + im * 1i
. Default:re_ = 0
,im_ = 0
.
- tocomplex(str)
Return the complex number decoded from the string
str
containing the literal complex number"a+bi"
(with no spaces) wherea
andb
are literal numbers, i.e. the strings"1"
,"2i"
and"1+2i"
will give respectively the complex numbers \(1+0i\), \(0+2i\) and \(1+2i\).
Attributes
- cpx.re
The real part of the complex number
cpx
.
- cpx.im
The imaginary part of the complex number
cpx
.
Functions
- is_complex(a)
Return
true
ifa
is a complex number,false
otherwise. This function is only available from the moduleMAD.typeid
.
- is_scalar(a)
Return
true
ifa
is a number or a complex number,false
otherwise. This function is only available from the moduleMAD.typeid
.
Methods
Operator-like Methods
Functions |
Return values |
Metamethods |
C functions |
---|---|---|---|
|
\(-z\) |
|
|
|
\(z + z_2\) |
|
|
|
\(z - z_2\) |
|
|
|
\(z \cdot z_2\) |
|
|
|
\(z / z_2\) |
|
|
|
\(z \mod z_2\) |
|
|
|
\(z ^ {z_2}\) |
|
|
|
\(z = z_2\) |
|
Real-like Methods
Functions |
Return values |
C functions |
---|---|---|
|
\(|z|\) |
|
|
\(\cos^{-1} z\) |
|
|
\(\cosh^{-1} z\) |
|
|
\(\cot^{-1} z\) |
|
|
\(\coth^{-1} z\) |
|
|
\(\sin^{-1} z\) |
|
|
\(\frac{\sin^{-1} z}{z}\) |
|
|
\(\sinh^{-1} x\) |
|
|
\(\frac{\sinh^{-1} z}{z}\) |
|
|
\(\tan^{-1} z\) |
|
|
\(\tanh^{-1} z\) |
|
|
\(\lceil\Re(z)\rceil+i\,\lceil\Im(z)\rceil\) |
|
|
\(\cos z\) |
|
|
\(\cosh z\) |
|
|
\(\cot z\) |
|
|
\(\coth z\) |
|
|
\(\exp z\) |
|
|
\(\lfloor\Re(z)\rfloor+i\,\lfloor\Im(z)\rfloor\) |
|
|
\(z - \operatorname{trunc}(z)\) |
|
|
\(\sqrt{z^2+z_2^2}\) |
|
|
\(\sqrt{z^2+z_2^2+z_3^2}\) |
|
|
\(\frac{v}{z}\) |
|
|
\(\frac{v}{\sqrt z}\) |
|
|
\(\log z\) |
|
|
\(\log_{10} z\) |
|
|
\(z^n\) |
|
|
\(\lfloor\Re(z)\rceil+i\,\lfloor\Im(z)\rceil\) |
|
|
\(\sin z\) |
|
|
\(\frac{\sin z}{z}\) |
|
|
\(\sinh z\) |
|
|
\(\frac{\sinh z}{z}\) |
|
|
\(z \cdot z\) |
|
|
\(\sqrt{z}\) |
|
|
\(\tan z\) |
|
|
\(\tanh z\) |
|
|
\(\operatorname{trunc} \Re(z)+i\,\operatorname{trunc} \Im(z)\) |
|
|
\(\frac{z}{|z|}\) |
In methods inv()
and invsqrt()
, default is v_ = 1
.
Complex-like Methods
Functions |
Return values |
C functions |
---|---|---|
|
\(|z|\) |
|
|
\(\arg z\) |
|
|
\(z^*\) |
|
|
\(|\Re(z)|+i\,|\Im(z)|\) |
|
|
\(\Im(z)\) |
|
|
\(|z|\,e^{i \arg z}\) |
|
|
\(\operatorname{proj}(z)\) |
|
|
\(\Re(z)\) |
|
|
\(\Re(z)\cos \Im(z)+i\,\Re(z)\sin \Im(z)\) |
|
|
\(\Re(z), \Im(z)\) |
Error-like Methods
Error-like methods call C wrappers to the corresponding functions from the Faddeeva library from the MIT, considered as one of the most accurate and fast implementation over the complex plane [FADDEEVA] (see mad_num.c
).
Functions |
Return values |
C functions |
---|---|---|
|
\(\frac{2}{\sqrt\pi}\int_0^z e^{-t^2} dt\) |
|
|
\(1-\operatorname{erf}(z)\) |
|
|
\(-i\operatorname{erf}(i z)\) |
|
|
\(e^{z^2}\operatorname{erfc}(z)\) |
|
|
\(e^{-z^2}\operatorname{erfc}(-i z)\) |
|
|
\(\frac{-i\sqrt\pi}{2}e^{-z^2}\operatorname{erf}(iz)\) |
Operators
The operators on complex follow the conventional mathematical operations of Complex numbers.
- -cpx
Return a complex resulting from the negation of the operand as computed by
cpx:unm()
.
- num + cpx
- cpx + num
- cpx + cpx
Return a complex resulting from the sum of the left and right operands as computed by
cpx:add()
.
- num - cpx
- cpx - num
- cpx - cpx
Return a complex resulting from the difference of the left and right operands as computed by
cpx:sub()
.
- num * cpx
- cpx * num
- cpx * cpx
Return a complex resulting from the product of the left and right operands as computed by
cpx:mul()
.
- num / cpx
- cpx / num
- cpx / cpx
Return a complex resulting from the division of the left and right operands as computed by
cpx:div()
. If the right operand is a complex number, the division uses a robut and fast algorithm implemented inmad_cpx_div_r()
[1].
- num % cpx
- cpx % num
- cpx % cpx
Return a complex resulting from the rest of the division of the left and right operands, i.e. \(x - y \lfloor \frac{x}{y} \rfloor\), as computed by
cpx:mod()
. If the right operand is a complex number, the division uses a robut and fast algorithm implemented inmad_cpx_div_r()
[1].
- num ^ cpx
- cpx ^ num
- cpx ^ cpx
Return a complex resulting from the left operand raised to the power of the right operand as computed by
cpx:pow()
.
- num == cpx
- cpx == num
- cpx == cpx
Return
false
if the real or the imaginary part differ between the left and right operands,true
otherwise. A numbera
will be interpreted as \(a+i0\) for the comparison.
C API
These functions are provided for performance reason and compliance (i.e. branch cut) with the C API of other modules dealing with complex numbers like the linear and the differential algebra. For the same reason, some functions hereafter refer to the section 7.3 of the C Programming Language Standard [ISOC99CPX].
-
num_t mad_cpx_abs_r(num_t x_re, num_t x_im)
Return the modulus of the complex
x
as computed bycabs()
.
-
num_t mad_cpx_arg_r(num_t x_re, num_t x_im)
Return the argument in \([-\pi, +\pi]\) of the complex
x
as computed bycarg()
.
-
void mad_cpx_unit_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the complexx
divided by its modulus as computed bycabs()
.
-
void mad_cpx_proj_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the projection of the complexx
on the Riemann sphere as computed bycproj()
.
-
void mad_cpx_rect_r(num_t rho, num_t ang, cpx_t *r)
Put in
r
the rectangular form of the complexrho * exp(i*ang)
.
-
void mad_cpx_inv_r(num_t x_re, num_t x_im, cpx_t *r)
-
cpx_t mad_cpx_inv(cpx_t x)
Put in
r
or return the inverse of the complexx
.
-
void mad_cpx_invsqrt_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the square root of the inverse of the complexx
.
-
void mad_cpx_div_r(num_t x_re, num_t x_im, num_t y_re, num_t y_im, cpx_t *r)
-
cpx_t mad_cpx_div(cpx_t x, cpx_t y)
Put in
r
or return the complexx
divided by the complexy
.
-
void mad_cpx_mod_r(num_t x_re, num_t x_im, num_t y_re, num_t y_im, cpx_t *r)
Put in
r
the remainder of the division of the complexx
by the complexy
.
-
void mad_cpx_pow_r(num_t x_re, num_t x_im, num_t y_re, num_t y_im, cpx_t *r)
Put in
r
the complexx
raised to the power of complexy
usingcpow()
.
-
void mad_cpx_powi_r(num_t x_re, num_t x_im, int n, cpx_t *r)
-
cpx_t mad_cpx_powi(cpx_t x, int n)
Put in
r
or return the complexx
raised to the power of the integern
using a fast algorithm.
-
void mad_cpx_sqrt_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the square root of the complexx
as computed bycsqrt()
.
-
void mad_cpx_exp_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the exponential of the complexx
as computed bycexp()
.
-
void mad_cpx_log_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the natural logarithm of the complexx
as computed byclog()
.
-
void mad_cpx_sin_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the sine of the complexx
as computed bycsin()
.
-
void mad_cpx_cos_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the cosine of the complexx
as computed byccos()
.
-
void mad_cpx_tan_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the tangent of the complexx
as computed byctan()
.
-
void mad_cpx_sinh_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the hyperbolic sine of the complexx
as computed bycsinh()
.
-
void mad_cpx_cosh_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the hyperbolic cosine of the complexx
as computed byccosh()
.
-
void mad_cpx_tanh_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the hyperbolic tangent of the complexx
as computed byctanh()
.
-
void mad_cpx_asin_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the arc sine of the complexx
as computed bycasin()
.
-
void mad_cpx_acos_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the arc cosine of the complexx
as computed bycacos()
.
-
void mad_cpx_atan_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the arc tangent of the complexx
as computed bycatan()
.
-
void mad_cpx_asinh_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the hyperbolic arc sine of the complexx
as computed bycasinh()
.
-
void mad_cpx_acosh_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the hyperbolic arc cosine of the complexx
as computed bycacosh()
.
-
void mad_cpx_atanh_r(num_t x_re, num_t x_im, cpx_t *r)
Put in
r
the hyperbolic arc tangent of the complexx
as computed bycatanh()
.
-
void mad_cpx_sinc_r(num_t x_re, num_t x_im, cpx_t *r)
-
cpx_t mad_cpx_sinc(cpx_t x)
Put in
r
or return the sine cardinal of the complexx
.
-
void mad_cpx_sinhc_r(num_t x_re, num_t x_im, cpx_t *r)
-
cpx_t mad_cpx_sinhc(cpx_t x)
Put in
r
or return the hyperbolic sine cardinal of the complexx
.
-
void mad_cpx_asinc_r(num_t x_re, num_t x_im, cpx_t *r)
-
cpx_t mad_cpx_asinc(cpx_t x)
Put in
r
or return the arc sine cardinal of the complexx
.
-
void mad_cpx_asinhc_r(num_t x_re, num_t x_im, cpx_t *r)
-
cpx_t mad_cpx_asinhc(cpx_t x)
Put in
r
or return the hyperbolic arc sine cardinal of the complexx
.
-
void mad_cpx_wf_r(num_t x_re, num_t x_im, num_t relerr, cpx_t *r)
-
cpx_t mad_cpx_wf(cpx_t x, num_t relerr)
Put in
r
or return the Faddeeva function of the complexx
.
-
void mad_cpx_erf_r(num_t x_re, num_t x_im, num_t relerr, cpx_t *r)
-
cpx_t mad_cpx_erf(cpx_t x, num_t relerr)
Put in
r
or return the error function of the complexx
.
-
void mad_cpx_erfc_r(num_t x_re, num_t x_im, num_t relerr, cpx_t *r)
-
cpx_t mad_cpx_erfc(cpx_t x, num_t relerr)
Put in
r
or return the complementary error function of the complexx
.
-
void mad_cpx_erfcx_r(num_t x_re, num_t x_im, num_t relerr, cpx_t *r)
-
cpx_t mad_cpx_erfcx(cpx_t x, num_t relerr)
Put in
r
or return the scaled complementary error function of the complexx
.
References
Smith, “Algorithm 116: Complex division”, Commun. ACM, 5(8):435, 1962.
Baudin and R. L. Smith, “A robust complex division in Scilab”, October 2012. http://arxiv.org/abs/1210.4539.
Oeftiger, R. De Maria, L. Deniau et al, “Review of CPU and GPU Faddeeva Implementations”, IPAC2016. https://cds.cern.ch/record/2207430/files/wepoy044.pdf.
ISO/IEC 9899:1999 Programming Languages - C. https://www.iso.org/standard/29237.html.
Footnotes