Complex numbers
Enoki provides a vectorizable type for complex number arithmetic analogous to
std::complex<T>
. To use it, include the following header file:
#include <enoki/complex.h>
Usage
The following example shows how to define and perform basic arithmetic using
enoki::Complex
vectorized over 4-wide packets.
/* Declare underlying packet type, could just be 'float' for scalar arithmetic */
using FloatP = Packet<float, 4>;
/* Define complex number type */
using ComplexP = Complex<FloatP>;
const ComplexP I(0.f, 1.f);
const ComplexP z(0.2f, 0.3f);
/* Two different ways of computing the tangent function */
ComplexP t0 = (exp(I * z) - exp(-I * z)) / (I * (exp(I * z) + exp(-I * z)));
ComplexP t1 = tan(z);
std::cout << "t0 = " << t0 << std::endl << std::endl;
std::cout << "t1 = " << t1 << std::endl;
/* Prints
t0 = [0.184863 + 0.302229i,
0.184863 + 0.302229i,
0.184863 + 0.302229i,
0.184863 + 0.302229i]
t1 = [0.184863 + 0.302229i,
0.184863 + 0.302229i,
0.184863 + 0.302229i,
0.184863 + 0.302229i]
*/
Reference
-
template<typename
Type
>
class Complex
: StaticArrayImpl<Type, 2>
The class enoki::Complex
is a 2D Enoki array whose components
are of type Type
. Various arithmetic operators (e.g. multiplication)
and transcendental functions are overloaded so that they provide the
correct behavior for complex-valued inputs.
-
Complex
(Type real, Type imag)
Creates a enoki::Complex
instance from the given real and
imaginary inputs.
-
Complex
(Type f)
Creates a real-valued enoki::Complex
instance from f
.
This constructor effectively changes the broadcasting behavior of
non-complex inputs—for instance, the snippet
auto value_a = zero<Array<float, 2>>();
auto value_c = zero<Complex<float>>();
value_a += 1.f; value_c += 1.f;
std::cout << "value_a = "<< value_a << ", value_c = " << value_c << std::endl;
prints value_a = [1, 1], value_c = 1 + 0i
, which is the desired
behavior for complex numbers. For standard Enoki arrays, the number
1.f
is broadcast to both components.
Elementary operations
-
template<typename
T
>
T real
(Complex<T> z)
Extracts the real part of z
.
-
template<typename
T
>
T imag
(Complex<T> z)
Extracts the imaginary part of z
.
-
template<typename
T
>
Complex<T> arg
(Complex<T> z)
Evaluates the complex argument of z
.
-
template<typename
T
>
Complex<T> abs
(Complex<T> z)
Compute the absolute value of z
.
-
template<typename
T
>
Complex<T> sqrt
(Complex<T> z)
Compute the square root of z
.
-
template<typename
T
>
Complex<T> conj
(Complex<T> z)
Evaluates the complex conjugate of z
.
-
template<typename
T
>
Complex<T> rcp
(Complex<T> z)
Evaluates the complex reciprocal of z
.
Arithmetic operators
Only a few arithmetic operators need to be overridden to support complex
arithmetic. The rest are automatically provided by Enoki’s existing operators
and broadcasting rules.
-
template<typename
T
>
Complex<T> operator*
(Complex<T> z0, Complex<T> z1)
Evaluates the complex product of z1
and z2
.
-
template<typename
T
>
Complex<T> operator/
(Complex<T> z0, Complex<T> z1)
Evaluates the complex division of z1
and z2
.
Stream operators
-
std::ostream &
operator<<
(std::ostream &os, const Complex<T> &z)
Sends the complex number z
to the stream os
using the format
1 + 2i
.
Exponential, logarithm, and power function
-
template<typename
T
>
Complex<T> exp
(Complex<T> z)
Evaluates the complex exponential of z
.
-
template<typename
T
>
Complex<T> log
(Complex<T> z)
Evaluates the complex logarithm of z
.
-
template<typename
T
>
Complex<T> pow
(Complex<T> z0, Complex<T> z1)
Evaluates the complex power of z0
raised to the z1
.
Trigonometric functions
-
template<typename
T
>
Complex<T> sin
(Complex<T> z)
Evaluates the complex sine function for z
.
-
template<typename
T
>
Complex<T> cos
(Complex<T> z)
Evaluates the complex cosine function for z
.
-
template<typename
T
>
Complex<T> tan
(Complex<T> z)
Evaluates the complex tangent function for z
.
-
template<typename
T
>
std::pair<Complex<T>, Complex<T>> sincos
(Complex<T> z)
Jointly evaluates the complex sine and cosine function for z
.
-
template<typename
T
>
Complex<T> asin
(Complex<T> z)
Evaluates the complex arc sine function for z
.
-
template<typename
T
>
Complex<T> acos
(Complex<T> z)
Evaluates the complex arc cosine function for z
.
-
template<typename
T
>
Complex<T> atan
(Complex<T> z)
Evaluates the complex arc tangent function for z
.
Hyperbolic functions
-
template<typename
T
>
Complex<T> sinh
(Complex<T> z)
Evaluates the complex hyperbolic sine function for z
.
-
template<typename
T
>
Complex<T> cosh
(Complex<T> z)
Evaluates the complex hyperbolic cosine function for z
.
-
template<typename
T
>
Complex<T> tanh
(Complex<T> z)
Evaluates the complex hyperbolic tangent function for z
.
-
template<typename
T
>
std::pair<Complex<T>, Complex<T>> sincosh
(Complex<T> z)
Jointly evaluates the complex hyperbolic sine and cosine function for z
.
-
template<typename
T
>
Complex<T> asinh
(Complex<T> z)
Evaluates the complex hyperbolic arc sine function for z
.
-
template<typename
T
>
Complex<T> acosh
(Complex<T> z)
Evaluates the complex hyperbolic arc cosine function for z
.
-
template<typename
T
>
Complex<T> atanh
(Complex<T> z)
Evaluates the complex hyperbolic arc tangent function for z
.
Miscellaneous functions
-
std::pair<T, T>
sincos_arg_diff
(const Complex<T> &z1, const Complex<T> &z2)
Efficiently evaluates sin(arg(z1) - arg(z2))
and cos(arg(z1) - arg(z2))
.
-
template<typename
T
>
Complex<T> sqrtz
(T x)
Compute the complex square root of a real-valued argument x
(which may
be negative). This is considerably more efficient than the general complex
square root above.