Complex-Valued Basic Functions
This chapter describes built-in functions that operate on complex numbers, either as an argument type or a return type. This includes the arithmetic operators generalized to complex numbers.
Complex assignment and promotion
Just as integers may be assigned to real variables, real variables may be assigned to complex numbers, with the result being a zero imaginary component.
int n = 5; // n = 5
real x = a; // x = 5.0
complex z1 = n; // z = 5.0 + 0.0i
complex z2 = x; // z = 5.0 + 0.0i
Complex function arguments
Function arguments of type int
or real
may be promoted to type complex
. The complex version of functions in this chapter are only used if one of the arguments is complex. For example, if z
is complex, then pow(z, 2)
will call the complex version of the power function and the integer 2 will be promoted to a complex number with a real component of 2 and an imaginary component of 0. The same goes for binary operators like addition and subtraction, where z + 2
will be legal and produce a complex result. Functions such as arg
and conj
that are only available for complex numbers can accept integer or real arguments, promoting them to complex
before applying the function.
Complex constructors and accessors
Complex constructors
Variables and constants of type complex
are constructed from zero, one, or two real numbers.
complex z1 = to_complex(); // z1 = 0.0 + 0.0i
real re = -2.9;
complex z2 = to_complex(re); // z2 = -2.9 + 0.0i
real im = 1.3;
complex z3 = to_complex(re, im); // z3 = -2.9 + 1.3i
complex
to_complex
()
Return complex number with real part 0.0 and imaginary part 0.0.
complex
to_complex
(real re)
Return complex number with real part re
and imaginary part 0.0.
complex
to_complex
(real re, real im)
Return complex number with real part re
and imaginary part im
.
Z
to_complex
(T1 re, T2 im)
Vectorized implementation of the to_complex
function.
T1
and T2
can either be real containers of the same size, or a real container and a real, in which case the real value is used for the corresponding component in all elements of the output.
Complex accessors
Given a complex number, its real and imaginary parts can be extracted with the following functions.
real
get_real
(complex z)
Return the real part of the complex number z
.
real
get_imag
(complex z)
Return the imaginary part of the complex number z
.
Complex arithmetic operators
The arithmetic operators have the same precedence for complex and real arguments. The complex form of an operator will be selected if at least one of its argument is of type complex
. If there are two arguments and only one is of type complex
, then the other will be promoted to type complex
before performing the operation.
Unary operators
complex
operator+
(complex z)
Return the complex argument z
, \[\begin{equation*} +z = z. \end{equation*}\]
complex
operator-
(complex z)
Return the negation of the complex argument z
, which for \(z = x + yi\) is \[\begin{equation*} -z = -x - yi. \end{equation*}\]
T
operator-
(T x)
Vectorized version of operator-
. If T x
is a (possibly nested) array of complex numbers, -x
is the same shape array where each individual value is negated.
Binary operators
complex
operator+
(complex x, complex y)
Return the sum of x and y, \[\begin{equation*} (x + y) = \text{operator+}(x, y) = x + y. \end{equation*}\]
complex
operator-
(complex x, complex y)
Return the difference between x and y, \[\begin{equation*} (x - y) =
\text{operator-}(x, y) = x - y. \end{equation*}\]
complex
operator*
(complex x, complex y)
Return the product of x and y, \[\begin{equation*} (x \, * \, y) = \text{operator*}(x, y) = x
\times y. \end{equation*}\]
complex
operator/
(complex x, complex y)
Return the quotient of x and y, \[\begin{equation*} (x / y) = \text{operator/}(x,y) =
\frac{x}{y} \end{equation*}\]
complex
operator^
(complex x, complex y)
Return x raised to the power of y, \[\begin{equation*}
(x^\mathrm{\wedge}y)= \text{operator}^\mathrm{\wedge}(x,y)
= \textrm{exp}(y \, \log(x)).
\end{equation*}\]
Complex comparison operators
Complex numbers are equal if and only if both their real and imaginary components are equal. That is, the conditional
z1 == z2
is equivalent to
get_real(z1) == get_real(z2) && get_imag(z1) == get_imag(z2)
As with other complex functions, if one of the arguments is of type real
or int
, it will be promoted to type complex
before comparison. For example, if z
is of type complex
, then z == 0
will be true if z
has real component equal to 0.0 and complex component equal to 0.0.
Warning: As with real values, it is usually a mistake to compare complex numbers for equality because their parts are implemented using floating-point arithmetic, which suffers from precision errors, rendering algebraically equivalent expressions not equal after evaluation.
int
operator==
(complex x, complex y)
Return 1 if x is equal to y and 0 otherwise, \[\begin{equation*}
(x \,\text{==}\, y)
\ = \ \text{operator==}(x,y)
\ = \ \begin{cases} 1 & \text{if $x = y$}, \ \text{and} \\ 0 & \text{otherwise.}
\end{cases}
\end{equation*}\]
int
operator!=
(complex x, complex y)
Return 1 if x is not equal to y and 0 otherwise, \[\begin{equation*}
(x \,\text{!=}\, y)
\ = \ \text{operator!=}(x,y)
\ = \ \begin{cases} 1 & \text{if $x \neq y$}, \ \text{and} \\ 0 &
\text{otherwise.} \end{cases}
\end{equation*}\]
Complex (compound) assignment operators
The assignment operator only serves as a component in the assignment statement and is thus not technically a function in the Stan language. With that caveat, it is documented here for completeness.
Assignment of complex numbers works elementwise. If an expression of type int
or real
is assigned to a complex number, it will be promoted before assignment as if calling to_complex()
, so that the imaginary component is 0.0.
void
operator=
(complex x, complex y)
y = x;
assigns a (copy of) the value of y
to x
.
void
operator+=
(complex x, complex y)
x += y;
is equivalent to x = x + y;
.
void
operator-=
(complex x, complex y)
x -= y;
is equivalent to x = x - y;
.
void
operator*=
(complex x, complex y)
x *= y;
is equivalent to x = x * y;
.
void
operator/=
(complex x, complex y)
x /= y;
is equivalent to x = x / y;
.
Complex special functions
The following functions are specific to complex numbers other than absolute value, which has a specific meaning for complex numbers.
real
abs
(complex z)
Return the absolute value of z, also known as the modulus or magnitude, which for \(z = x + yi\) is \[\begin{equation*}
\textrm{abs}(z) = \sqrt{x^2 + y^2}.
\end{equation*}\]
This function works elementwise over containers, returning the same shape and kind of the input container but holding reals. For example, a complex_vector[n]
input will return a vector[n]
output, with each element transformed by the above equation.
real
arg
(complex z)
Return the phase angle (in radians) of z, which for \(z = x + yi\) is \[\begin{equation*}
\textrm{arg}(z) = \textrm{atan2}(y, x) = \textrm{atan}(y / x).
\end{equation*}\]
real
norm
(complex z)
Return the Euclidean norm of z, which is its absolute value squared, and which for \(z = x + yi\) is \[\begin{equation*}
\textrm{norm}(z) = \textrm{abs}^2(z) = x^2 + y^2.
\end{equation*}\]
complex
conj
(complex z)
Return the complex conjugate of z, which negates the imaginary component, so that if \(z = x + yi\), \[\begin{equation*}
\textrm{conj}(z) = x - yi.
\end{equation*}\]
Z
conj
(Z z)
Vectorized version of conj
. This will apply the conj
function to each element of a complex array, vector, or matrix.
complex
proj
(complex z)
Return the projection of z
onto the Riemann sphere, which for \(z = x
+ yi\) is \[\begin{equation*}
\textrm{proj}(z)
= \begin{cases}
z & \textrm{if} \ z \ \textrm{is finite, and} \\
0 + \textrm{sign}(y)i & \textrm{otherwise,}
\end{cases}
\end{equation*}\] where \(\textrm{sign}(y)\) is -1 if \(y\) is negative and 1 otherwise.
complex
polar
(real r, real theta)
Return the complex number with magnitude (absolute value) r
and phase angle theta
.
Complex exponential and power functions
The exponential, log, and power functions may be supplied with complex arguments with specialized meanings that generalize their real counterparts. These versions are only called when the argument is complex.
complex
exp
(complex z)
Return the complex natural exponential of z
, which for \(z = x + yi\) is \[\begin{equation*}
\exp z = \exp(x) \textrm{cis}(y) = \exp(x) (\cos(y) + i \sin(y)).
\end{equation*}\]
complex
log
(complex z)
Return the complex natural logarithm of z
, which for \(z = \textrm{polar}(r,
\theta)\) is \[\begin{equation*}
\log z = \log r + \theta i.
\end{equation*}\]
complex
log10
(complex z)
Return the complex common logarithm of z
, \[\begin{equation*}
\log_{10} z = \frac{\log z}{\log 10}.
\end{equation*}\]
complex
pow
(complex x, complex y)
Return x raised to the power of y, \[\begin{equation*}
\text{pow}(x,y) = \textrm{exp}(y \, \log(x)).
\end{equation*}\]
Z
pow
(T1 x, T2 y)
Vectorized implementation of the pow
function
complex
sqrt
(complex x)
Return the complex square root of x with branch cut along the negative real axis. For finite inputs, the result will be in the right half-plane.
Complex trigonometric functions
The standard trigonometric functions are supported for complex numbers.
complex
cos
(complex z)
Return the complex cosine of z, which is \[\begin{equation*}
\cos(z)
= \textrm{cosh}(z \, i)
= \frac{\displaystyle \exp(z \, i) + \exp(-z \, i)}
{\displaystyle 2}.
\end{equation*}\]
complex
sin
(complex z)
Return the complex sine of z, \[\begin{equation*}
\sin(z)
= -\textrm{sinh}(z \, i) \, i
= \frac{\displaystyle \exp(z \, i) - \exp(-z \, i)}
{\displaystyle 2 \, i}.
\end{equation*}\]
complex
tan
(complex z)
Return the complex tangent of z, \[\begin{equation*}
\tan(z)
= -\textrm{tanh}(z \, i) \, i
= \frac{(\exp(-z \, i) - \exp(z \, i)) \, i}
{\exp(-z \, i) + \exp(z \, i)}.
\end{equation*}\]
complex
acos
(complex z)
Return the complex arc (inverse) cosine of z, \[\begin{equation*}
\textrm{acos}(z)
= \frac{1}{2} \pi + \log (z \, i + \sqrt{1 - z^2}) \, i.
\end{equation*}\]
complex
asin
(complex z)
Return the complex arc (inverse) sine of z, \[\begin{equation*}
\text{asin}(z)
= -\log(z \, i + \sqrt{1 - z^2}) \, i.
\end{equation*}\]
complex
atan
(complex z)
Return the complex arc (inverse) tangent of z, \[\begin{equation*}
\text{atan}(z)
= - \frac{1}{2} (\log(1 - z \, i) - \log(1 + z \, i)) \, i.
\end{equation*}\]
Complex hyperbolic trigonometric functions
The standard hyperbolic trigonometric functions are supported for complex numbers.
complex
cosh
(complex z)
Return the complex hyperbolic cosine of z, \[\begin{equation*}
\textrm{cosh}(z)
= \frac{\exp(z) + \exp(-z)}
{2}.
\end{equation*}\]
complex
sinh
(complex z)
Return the complex hyperbolic sine of z, \[\begin{equation*}
\textrm{sinh}(z)
= \frac{\displaystyle \exp(z) - \exp(-z)}
{\displaystyle 2}.
\end{equation*}\]
complex
tanh
(complex z)
Return the complex hyperbolic tangent of z, \[\begin{equation*}
\textrm{tanh}(z)
\ = \ \frac{\textrm{sinh}(z)}
{\textrm{cosh}(z)}
\ = \ \frac{\displaystyle \exp(z) - \exp(-z)}
{\displaystyle \exp(z) + \exp(-z)}.
\end{equation*}\]
complex
acosh
(complex z)
Return the complex hyperbolic arc (inverse) cosine of z, \[\begin{equation*}
\textrm{acosh}(z)
= \log(z + \sqrt{(z + 1)(z - 1)}).
\end{equation*}\]
complex
asinh
(complex z)
Return the complex hyperbolic arc (inverse) sine of z, \[\begin{equation*}
\textrm{asinh}(z)
= \log(z + \sqrt{1 + z^2}).
\end{equation*}\]
complex
atanh
(complex z)
Return the complex hyperbolic arc (inverse) tangent of z, \[\begin{equation*}
\textrm{atanh}(z)
= \frac{\log(1 + z) - \log(1 - z)}
{2}.
\end{equation*}\]