7.11 Print statements
Stan provides print statements that can print literal strings and the values of expressions. Print statements accept any number of arguments. Consider the following for-each statement with a print statement in its body.
for (n in 1:N) { print("loop iteration: ", n); ... }
The print statement will execute every time the body of the loop does.
Each time the loop body is executed, it will print the string “loop
iteration:” (with the trailing space), followed by the value of the
expression n
, followed by a new line.
Print content
The text printed by a print statement varies based on its content. A literal (i.e., quoted) string in a print statement always prints exactly that string (without the quotes). Expressions in print statements result in the value of the expression being printed. But how the value of the expression is formatted will depend on its type.
Printing a simple real
or int
typed variable always
prints the variable’s value.10
For array, vector, and matrix variables, the print format uses brackets. For example, a 3-vector will print as
1, 2, 3] [
and a \(2 \times 3\)-matrix as
1, 2, 3], [4, 5, 6]] [[
Complex numbers print as pairs. For example, the pair of statements
complex z = to_complex(1.2, -3.5);
print(z)
will print as (1.2,-3.5)
, with no space after the comma or within
the parentheses.
Printing a more readable version of arrays or matrices can be done with loops. An example is the print statement in the following transformed data block.
transformed data {
matrix[2, 2] u;
1, 1] = 1.0; u[1, 2] = 4.0;
u[2, 1] = 9.0; u[2, 2] = 16.0;
u[for (n in 1:2) {
print("u[", n, "] = ", u[n]);
} }
This print statement executes twice, printing the following two lines of output.
1] = [1, 4]
u[2] = [9, 16] u[
Non-void input
The input type to a print function cannot be void. In particular, it can’t be the result of a user-defined void function. All other types are allowed as arguments to the print function.
Print frequency
Printing for a print statement happens every time it is executed. The
transformed data
block is executed once per chain, the
transformed parameter
and model
blocks once per leapfrog
step, and the generated quantities
block once per iteration.
String literals
String literals begin and end with a double quote character
("
). The characters between the double quote characters may be
any byte sequence, with the exception of the double quote character.
The Stan interfaces preserve the byte sequences which they receive. The encoding of these byte sequences as characters and their rendering as glyphs will be handled by whatever display mechanism is being used to monitor Stan’s output (e.g., a terminal, a Jupyter notebook, RStudio, etc.). Stan does not enforce a character encoding for strings, and no attempt is made to validate the bytes as legal ASCII, UTF-8, etc.
Debug by print
Because Stan is an imperative language, print statements can be very useful for debugging. They can be used to display the values of variables or expressions at various points in the execution of a program. They are particularly useful for spotting problematic not-a-number of infinite values, both of which will be printed.
It is particularly useful to print the value of the target log
density accumulator (through the target()
function), as in the following example.
vector[2] y;
1] = 1;
y[print("log density before =", target());
0,1); // bug! y[2] not defined
y ~ normal(print("log density after =", target());
The example has a bug in that y[2]
is not defined before the
vector y
is used in the sampling statement. By printing the
value of the log probability accumulator before and after each
sampling statement, it’s possible to isolate where the log probability
becomes ill-defined (i.e., becomes not-a-number).
The adjoint component is always zero during execution for the algorithmic differentiation variables used to implement parameters, transformed parameters, and local variables in the model.↩︎