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.0iComplex 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.3icomplex 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 == z2is 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*}\]