7.2 Assignment statements
An assignment statement consists of a variable (possibly multivariate with indexing information) and an expression. Executing an assignment statement evaluates the expression on the right-hand side and assigns it to the (indexed) variable on the left-hand side. An example of a simple assignment is as follows.4
Executing this statement assigns the value of the expression
which is the integer zero, to the variable
n. For an assignment
to be well formed, the type of the expression on the right-hand side
should be compatible with the type of the (indexed) variable on the
left-hand side. For the above example, because
0 is an
expression of type
int, the variable
n must be declared
as being of type
int or of type
real. If the variable
is of type
real, the integer zero is promoted to a
floating-point zero and assigned to the variable. After the
assignment statement executes, the variable
n will have the
value zero (either as an integer or a floating-point value, depending on
Syntactically, every assignment statement must be followed by a semicolon. Otherwise, whitespace between the tokens does not matter (the tokens here being the left-hand-side (indexed) variable, the assignment operator, the right-hand-side expression and the semicolon).
Because the right-hand side is evaluated first, it is possible to increment a variable in Stan just as in C++ and other programming languages by writing
1;n = n +
Such self assignments are not allowed in BUGS, because they induce a cycle into the directed graphical model.
The left-hand side of an assignment may contain indices for array,
matrix, or vector data structures. For instance, if
1, 1] = 1.0;Sigma[
sets the value in the first column of the first row of
Sigma to one.
Assignments to subcomponents of larger multi-variate data structures
are supported by Stan. For example,
a is an array of type
array[,] real and
b is an array of type
array real, then
the following two statements are both well-formed.
3] = b; a;b = a[
x is a variable declared to have type
Y is a variable declared as type
matrix, then the following sequence of statements to swap the
first two rows of
Y is well formed.
1]; x = Y = Y; Y = x;Y[
Stan allows assignment of lower types to higher types, but not
vice-versa. That is, we can assign an expression of type
int to an
lvalue of type
real, and we can assign an expression of type
to an lvalue of type
complex. Furthermore, promotion is transitive,
so that we can assign an expression of type
int to an lvalue of type
Promotion extends to containers, so that arrays of
int can be
promoted to arrays of
real during assignment, and arrays of
can be assigned to an lvalue of type array of
an expression of type
vector may be assigned to an lvalue of type
complex_vector, and similarly for row vectors and matrices.
The expressions that are legal left-hand sides of assignment statements are known as “lvalues.” In Stan, there are only two kinds of legal lvalues,
- a variable, or
- a variable with one or more indices.
To be used as an lvalue, an indexed variable must have at least as many dimensions as the number of indices provided. An array of real or integer types has as many dimensions as it is declared for. A matrix has two dimensions and a vector or row vector one dimension; this also holds for the constrained types, covariance and correlation matrices and their Cholesky factors and ordered, positive ordered, and simplex vectors. An array of matrices has two more dimensions than the array and an array of vectors or row vectors has one more dimension than the array. Note that the number of indices can be less than the number of dimensions of the variable, meaning that the right hand side must itself be multidimensional to match the remaining dimensions.
Multiple indexes, as described in the multi-indexing section, are also permitted on the left-hand side of assignments. Indexing on the left side works exactly as it does for expressions, with multiple indexes preserving index positions and single indexes reducing them. The type on the left side must still match the type on the right side.
All assignment is carried out as if the right-hand side is copied before the assignment. This resolves any potential aliasing issues arising from he right-hand side changing in the middle of an assignment statement’s execution.
Compound arithmetic and assignment statement
Stan’s arithmetic operators may be used in compound arithmetic and assignment operations. For example, consider the following example of compound addition and assignment.
real x = 5; 7; // value of x is now 12x +=
The compound arithmetic and assignment statement above is equivalent to the following long form.
7;x = x +
In general, the compound form
x op= y
will be equivalent to
x = x op y;
The compound statement will be legal whenever the long form is legal.
This requires that the operation
x op y must itself be well
formed and that the result of the operation be assignable to
For the expression
x to be assignable, it must be an indexed
variable where the variable is defined in the current block. For
example, the following compound addition and assignment statement will
increment a single element of a vector by two.
vector[N] x; 3] += 2;x[
As a further example, consider
matrix[M, M] x; vector[M] y; real z; // OK, (x * x) is a matrix x *= x; // OK, (x * z) is a matrix x *= z; // BAD, (x * y) is a vectorx *= y;
The supported compound arithmetic and assignment
operations are listed in the compound arithmetic/assignment table; they
are also listed in the index prefaced by
Compound Arithmetic/Assignment Table. Stan allows compound arithmetic and assignment statements of the forms listed in the table. The compound form is legal whenever the corresponding long form would be legal and it has the same effect.
In versions of Stan before 2.18.0, the operator
<-was used for assignment rather than using the equal sign
=. The old operator
<-is now deprecated and will print a warning. In the future, it will be removed.↩︎