6.3 Vector, Matrix, and Array Expressions
Expressions for the Stan container objects arrays, vectors, and matrices can be constructed via a sequence of expressions enclosed in either curly braces for arrays, or square brackets for vectors and matrices.
Vector Expressions
Square brackets may be wrapped around a sequence of comma separated
primitive expressions to produce a row vector expression. For
example, the expression [ 1, 10, 100 ]
denotes a row vector of
three elements with real values 1.0, 10.0, and 100.0.
Applying the transpose operator to a row vector expression produces
a vector expression.
This syntax provides a way declare and define small vectors a single line, as follows.
row_vector[2] rv2= [ 1, 2 ];
vector[3] v3 = [ 3, 4, 5 ]';
The vector expression values may be compound expressions
or variable names, so it is legal to write
[ 2 * 3, 1 + 4]
or [ x, y ]
, providing that x
and y
are primitive variables.
Matrix Expressions
A matrix expression consists of square brackets wrapped around a sequence of comma separated row vector expressions. This syntax provides a way declare and define a matrix in a single line, as follows.
matrix[3,2] m1 = [ [ 1, 2 ], [ 3, 4 ], [5, 6 ] ];
Any expression denoting a row vector can be used in a matrix expression. For example, the following code is valid:
vector[2] vX = [ 1, 10 ]';
row_vector[2] vY = [ 100, 1000 ];
matrix[3,2] m2 = [ vX', vY, [ 1, 2 ] ];
No empty vector or matrix expressions
The empty expression [ ]
is ambiguous and therefore is not
allowed and similarly expressions such as [ [ ] ]
or
[ [ ], [ ] ]
are not allowed.
Array Expressions
Curly braces may be wrapped around a sequence of expressions to
produce an array expression. For example, the expression
{ 1, 10, 100 }
denotes an integer array of three elements with
values 1, 10, and 100. This syntax is particularly convenient to
define small arrays in a single line, as follows.
int a[3] = { 1, 10, 100 };
The values may be compound expressions, so it is legal to write
{ 2 * 3, 1 + 4 }
. It is also possible to write two dimensional
arrays directly, as in the following example.
int b[2, 3] = { { 1, 2, 3 }, { 4, 5, 6 } };
This way, b[1]
is { 1, 2, 3 }
and b[2]
is
{ 4, 5, 6 }
.
Whitespace is always interchangeable in Stan, so the above can be laid out as follows to more clearly indicate the row and column structure of the resulting two dimensional array.
int b[2, 3] = { { 1, 2, 3 },
{ 4, 5, 6 } };
Array Expression Types
Any type of expression may be used within braces to form an array expression. In the simplest case, all of the elements will be of the same type and the result will be an array of elements of that type. For example, the elements of the array can be vectors, in which case the result is an array of vectors.
vector[3] b;
vector[3] c;
...
vector[3] d[2] = { b, c };
The elements may also be a mixture of int
and real
typed
expressions, in which case the result is an array of real values.
real b[2] = { 1, 1.9 };
Restrictions on Values
There are some restrictions on how array expressions may be used that arise from their types being calculated bottom up and the basic data type and assignment rules of Stan.
Rectangular array expressions only
Although it is tempting to try to define a ragged array expression, all Stan data types are rectangular (or boxes or other higher-dimensional generalizations). Thus the following nested array expression will cause an error when it tries to create a non-rectangular array.
{ { 1, 2, 3 }, { 4, 5 } } // compile time error: size mismatch
This may appear to be OK, because it is creating a two-dimensional
integer array (int[ , ]
) out of two one-dimensional array
integer arrays (int[ ]
). But it is not allowed because the two
one-dimensional arrays are not the same size. If the elements are
array expressions, this can be diagnosed at compile time. If one or
both expressions is a variable, then that won’t be caught until
runtime.
{ { 1, 2, 3 }, m } // runtime error if m not size 3
No empty array expressions
Because there is no way to infer the type of the result, the empty
array expression ({ }
) is not allowed. This does not sacrifice
expressive power, because a declaration is sufficient to initialize a
zero-element array.
int a[0]; // a is fully defined as zero element array
Integer only array expressions
If an array expression contains only integer elements, such as
{ 1, 2, 3 }
, then the result type will be an integer array,
int[]
. This means that the following will not be
legal.
real a[2] = { -3, 12 }; // error: int[] can't be assigned to real[]
Integer arrays may not be assigned to real values. However, this problem is easily sidestepped by using real literal expressions.
real a[2] = { -3.0, 12.0 };
Now the types match and the assignment is allowed.