Array Operations

Reductions

The following operations take arrays as input and produce single output values. The boundary values for size 0 arrays are the unit with respect to the combination operation (min, max, sum, or product).

Minimum and maximum

real min(array[] real x)
The minimum value in x, or \(+\infty\) if x is size 0.

Available since 2.0

int min(array[] int x)
The minimum value in x, or error if x is size 0.

Available since 2.0

real max(array[] real x)
The maximum value in x, or \(-\infty\) if x is size 0.

Available since 2.0

int max(array[] int x)
The maximum value in x, or error if x is size 0.

Available since 2.0

Sum, product, and log sum of exp

int sum(array[] int x)
The sum of the elements in x, or 0 if the array is empty.

Available since 2.1

real sum(array[] real x)
The sum of the elements in x; see definition above.

Available since 2.0

complex sum(array[] complex x)
The sum of the elements in x; see definition above.

Available since 2.30

real prod(array[] real x)
The product of the elements in x, or 1 if x is size 0.

Available since 2.0

real prod(array[] int x)
The product of the elements in x, \[\begin{equation*} \text{product}(x) = \begin{cases} \prod_{n=1}^N x_n & \text{if} N > 0 \\[4pt] 1 & \text{if} N = 0 \end{cases} \end{equation*}\]

Available since 2.0

real log_sum_exp(array[] real x)
The natural logarithm of the sum of the exponentials of the elements in x, or \(-\infty\) if the array is empty.

Available since 2.0

Sample mean, variance, and standard deviation

The sample mean, variance, and standard deviation are calculated in the usual way. For i.i.d. draws from a distribution of finite mean, the sample mean is an unbiased estimate of the mean of the distribution. Similarly, for i.i.d. draws from a distribution of finite variance, the sample variance is an unbiased estimate of the variance.1 The sample deviation is defined as the square root of the sample deviation, but is not unbiased.

real mean(array[] real x)
The sample mean of the elements in x. For an array \(x\) of size \(N > 0\), \[\begin{equation*} \text{mean}(x) \ = \ \bar{x} \ = \ \frac{1}{N} \sum_{n=1}^N x_n. \end{equation*}\] It is an error to the call the mean function with an array of size \(0\).

Available since 2.0

real variance(array[] real x)
The sample variance of the elements in x. For \(N > 0\), \[\begin{equation*} \text{variance}(x) \ = \ \begin{cases} \frac{1}{N-1} \sum_{n=1}^N (x_n - \bar{x})^2 & \text{if } N > 1 \\[4pt] 0 & \text{if } N = 1 \end{cases} \end{equation*}\] It is an error to call the variance function with an array of size 0.

Available since 2.0

real sd(array[] real x)
The sample standard deviation of elements in x. \[\begin{equation*} \text{sd}(x) = \begin{cases} \sqrt{\, \text{variance}(x)} & \text{if } N > 1 \\[4pt] 0 & \text{if } N = 0 \end{cases} \end{equation*}\] It is an error to call the sd function with an array of size 0.

Available since 2.0

Norms

real norm1(vector x)
The L1 norm of x, defined by \[\begin{equation*} \text{norm1}(x) \ = \ \textstyle \sum_{n=1}^N (|x_n|) \end{equation*}\] where N is the size of x.

Available since 2.30

real norm1(row_vector x)
The L1 norm of x

Available since 2.30

real norm1(array[] real x)
The L1 norm of x

Available since 2.30

real norm2(vector x)
The L2 norm of x, defined by \[\begin{equation*} \text{norm2}(x) \ = \ \sqrt{\textstyle \sum_{n=1}^N (x_n)^2} \end{equation*}\] where N is the size of x

Available since 2.30

real norm2(row_vector x)
The L2 norm of x

Available since 2.30

real norm2(array[] real x)
The L2 norm of x

Available since 2.30

Euclidean distance and squared distance

real distance(vector x, vector y)
The Euclidean distance between x and y, defined by \[\begin{equation*} \text{distance}(x,y) \ = \ \sqrt{\textstyle \sum_{n=1}^N (x_n - y_n)^2} \end{equation*}\] where N is the size of x and y. It is an error to call distance with arguments of unequal size.

Available since 2.2

real distance(vector x, row_vector y)
The Euclidean distance between x and y

Available since 2.2

real distance(row_vector x, vector y)
The Euclidean distance between x and y

Available since 2.2

real distance(row_vector x, row_vector y)
The Euclidean distance between x and y

Available since 2.2

real squared_distance(vector x, vector y)
The squared Euclidean distance between x and y, defined by \[\begin{equation*} \mathrm{squared\_distance}(x,y) \ = \ \text{distance}(x,y)^2 \ = \ \textstyle \sum_{n=1}^N (x_n - y_n)^2, \end{equation*}\] where N is the size of x and y. It is an error to call squared_distance with arguments of unequal size.

Available since 2.7

real squared_distance(vector x, row_vector y)
The squared Euclidean distance between x and y

Available since 2.26

real squared_distance(row_vector x, vector y)
The squared Euclidean distance between x and y

Available since 2.26

real squared_distance(row_vector x, row_vector y)
The Euclidean distance between x and y

Available since 2.26

Quantile

Produces sample quantiles corresponding to the given probabilities. The smallest observation corresponds to a probability of 0 and the largest to a probability of 1.

Implements algorithm 7 from Hyndman, R. J. and Fan, Y., Sample quantiles in Statistical Packages (R’s default quantile function).

real quantile(data array[] real x, data real p)
The p-th quantile of x

Available since 2.27

array[] real quantile(data array[] real x, data array[] real p)
An array containing the quantiles of x given by the array of probabilities p

Available since 2.27

Array size and dimension function

The size of an array or matrix can be obtained using the dims() function. The dims() function is defined to take an argument consisting of any variable with up to 8 array dimensions (and up to 2 additional matrix dimensions) and returns an array of integers with the dimensions. For example, if two variables are declared as follows,

 array[7, 8, 9] real x;
 array[7] matrix[8, 9] y;

then calling dims(x) or dims(y) returns an integer array of size 3 containing the elements 7, 8, and 9 in that order.

The size() function extracts the number of elements in an array. This is just the top-level elements, so if the array is declared as

 array[M, N] real a;

the size of a is M.

The function num_elements, on the other hand, measures all of the elements, so that the array a above has \(M \times N\) elements.

The specialized functions rows() and cols() should be used to extract the dimensions of vectors and matrices.

array[] int dims(T x)
Return an integer array containing the dimensions of x; the type of the argument T can be any Stan type with up to 8 array dimensions.

Available since 2.0

int num_elements(array[] T x)
Return the total number of elements in the array x including all elements in contained arrays, vectors, and matrices. T can be any array type. For example, if x is of type array[4, 3] real then num_elements(x) is 12, and if y is declared as array[5] matrix[3, 4] y, then size(y) evaluates to 60.

Available since 2.5

int size(array[] T x)
Return the number of elements in the array x; the type of the array T can be any type, but the size is just the size of the top level array, not the total number of elements contained. For example, if x is of type array[4, 3] real then size(x) is 4.

Available since 2.0

Array broadcasting

The following operations create arrays by repeating elements to fill an array of a specified size. These operations work for all input types T, including reals, integers, vectors, row vectors, matrices, or arrays.

array[] T rep_array(T x, int n)
Return the n array with every entry assigned to x.

Available since 2.0

array [,] T rep_array(T x, int m, int n)
Return the m by n array with every entry assigned to x.

Available since 2.0

array[,,] T rep_array(T x, int k, int m, int n)
Return the k by m by n array with every entry assigned to x.

Available since 2.0

For example, rep_array(1.0,5) produces a real array (type array[] real) of size 5 with all values set to 1.0. On the other hand, rep_array(1,5) produces an integer array (type array[] int) of size 5 with all values set to 1. This distinction is important because it is not possible to assign an integer array to a real array. For example, the following example contrasts legal with illegal array creation and assignment

 array[5] real y;
 array[5] int x;

 x = rep_array(1, 5);     // ok
 y = rep_array(1.0, 5);   // ok

 x = rep_array(1.0, 5);   // illegal
 y = rep_array(1, 5);     // illegal

 x = y;                  // illegal
 y = x;                  // illegal

If the value being repeated v is a vector (i.e., T is vector), then rep_array(v, 27) is a size 27 array consisting of 27 copies of the vector v.

 vector[5] v;
 array[3] vector[5] a;

 a = rep_array(v, 3);  // fill a with copies of v
 a[2, 4] = 9.0;        // v[4], a[1, 4], a[3, 4] unchanged

If the type T of x is itself an array type, then the result will be an array with one, two, or three added dimensions, depending on which of the rep_array functions is called. For instance, consider the following legal code snippet.

 array[5, 6] real a;
 array[3, 4, 5, 6] real b;

 b = rep_array(a, 3, 4); //  make (3 x 4) copies of a
 b[1, 1, 1, 1] = 27.9;    //  a[1, 1] unchanged

After the assignment to b, the value for b[j, k, m, n] is equal to a[m, n] where it is defined, for j in 1:3, k in 1:4, m in 1:5, and n in 1:6.

Array concatenation

T append_array(T x, T y)
Return the concatenation of two arrays in the order of the arguments. T must be an N-dimensional array of any Stan type (with a maximum N of 7). All dimensions but the first must match.

Available since 2.18

For example, the following code appends two three dimensional arrays of matrices together. Note that all dimensions except the first match. Any mismatches will cause an error to be thrown.

 array[2, 1, 7] matrix[4, 6] x1;
 array[3, 1, 7] matrix[4, 6] x2;
 array[5, 1, 7] matrix[4, 6] x3;

 x3 = append_array(x1, x2);

Sorting functions

Sorting can be used to sort values or the indices of those values in either ascending or descending order. For example, if v is declared as a real array of size 3, with values \[\begin{equation*} \text{v} = (1, -10.3, 20.987), \end{equation*}\] then the various sort routines produce \[\begin{eqnarray*} \mathrm{sort\_asc(v)} & = & (-10.3,1,20.987) \\[4pt] \mathrm{sort\_desc(v)} & = & (20.987,1,-10.3) \\[4pt] \mathrm{sort\_indices\_asc(v)} & = & (2,1,3) \\[4pt] \mathrm{sort\_indices\_desc(v)} & = & (3,1,2) \end{eqnarray*}\]

array[] real sort_asc(array[] real v)
Sort the elements of v in ascending order

Available since 2.0

array[] int sort_asc(array[] int v)
Sort the elements of v in ascending order

Available since 2.0

array[] real sort_desc(array[] real v)
Sort the elements of v in descending order

Available since 2.0

array[] int sort_desc(array[] int v)
Sort the elements of v in descending order

Available since 2.0

array[] int sort_indices_asc(array[] real v)
Return an array of indices between 1 and the size of v, sorted to index v in ascending order.

Available since 2.3

array[] int sort_indices_asc(array[] int v)
Return an array of indices between 1 and the size of v, sorted to index v in ascending order.

Available since 2.3

array[] int sort_indices_desc(array[] real v)
Return an array of indices between 1 and the size of v, sorted to index v in descending order.

Available since 2.3

array[] int sort_indices_desc(array[] int v)
Return an array of indices between 1 and the size of v, sorted to index v in descending order.

Available since 2.3

int rank(array[] real v, int s)
Number of components of v less than v[s]

Available since 2.0

int rank(array[] int v, int s)
Number of components of v less than v[s]

Available since 2.0

Reversing functions

Stan provides functions to create a new array by reversing the order of elements in an existing array. For example, if v is declared as a real array of size 3, with values \[\begin{equation*} \text{v} = (1,\, -10.3,\, 20.987), \end{equation*}\] then \[\begin{equation*} \mathrm{reverse(v)} = (20.987,\, -10.3,\, 1). \end{equation*}\]

array[] T reverse(array[] T v)
Return a new array containing the elements of the argument in reverse order.

Available since 2.23
Back to top

Footnotes

  1. Dividing by \(N\) rather than \((N-1)\) produces a maximum likelihood estimate of variance, which is biased to underestimate variance.↩︎