7.1 Complex promotion

This chapter provides the details of functions that operate over complex matrices, vectors, and row vectors. These mirror the operations over real complex_matrix types and are defined in the usual way for complex numbers.

Promotion of complex arguments

If an expression e can be assigned to a variable of type T, then it can be used as an argument to a function that is specified to take arguments of type T. For instance, sqrt(real) is specified to take a real argument, but an integer expression such as 2 + 2 of type int can be passed to sqrt, so that sqrt(2 + 2) is well defined. This works by promoting the integer expression 2 + 2 to be of real type.

The rules for promotion in Stan are simple:

  • int may be promoted to real,
  • real may be promoted to complex,
  • vector can be promoted to complex_vector,
  • row_vector can be promoted to complex_row_vector,
  • matrix can be promoted to complex_matrix,
  • if T can be promoted to U and U can be promoted to V, then T can be promoted to V (transitive), and
  • if T can be promoted to U, then T[] can be promoted to U[] (covariant).

7.1.1 Signature selection

When a function is called, the definition requiring the fewest number of promotions is used. For example, when calling vector + vector, the real-valued signature is used. When calling any of complex_vector + vector, vector + complex_vector, or complex_vector + complex_vector, the complex signature is used. If more than one signature matches with a the minimal number of promotions, the call is ambiguous, and an error will be raised by the compiler. Promotion ambiguity leading to ill-defined calls should never happen with Stan built-in functions.

Signatures for complex functions

Complex function signatures will only list the fully complex type. For example, with complex vector addition, we will list a single signature, complex operator+(complex_vector, complex_vector). Through promotion, operator+ may be called with one complex vector and one real vector as well, but the documentation elides the implied signatures operator+(complex_vector, vector) and operator+(vector, complex_vector).

Generic functions work for complex containers

Generic functions work for arrays containing complex, complex matrix, complex vector, or complex row vector types. This includes the functions append_array, dims, head, num_elements, rep_array, reverse, segment, size, and tail.