It is traditional for programming languages to offer a ‘Hello World!’ example to help newcomers understand how to edit/run/view output for the language in the simplest way possible. ‘Hello World!’ programs verify that the install works, that the user can interact with the software and that the user knows the how to use the most fundemental debugging tool–the ‘print’ statement. For example in Python we have:
print("Hello World!");
Hello World!
R’s version has very similar syntax:
print("Hello World!")
[1] "Hello World!"
Stan however is not a programming language as much as a modeling environment which makes creating a ‘Hello World!’ a bit more complex because:
One might wonder why bother with ‘Hello World!’ at all given the above complexity–there are some reasons:
We will start with CmdStan since it forms the foundatation of all ways of running Stan programs. This assumes you know how to use the command line on your computer–if you are not comfortable with the command line there are instructions for RStudio below.
Below is an example Stan program:
functions {
void helloWorld() {
print("functions{} hello world! from any block that one can print from");
}
}
data {
}
transformed data {
print("transformed data{} hello world! once per program run");
helloWorld();
}
parameters {
real<lower=0,upper=1> estimate_me;
}
transformed parameters {
print("transformed parameters {} hello world! every leap frog step");
}
model {
print("model{} hello world! every leap frog step: estimate_me=",estimate_me);
1 ~ bernoulli(estimate_me);
}
generated quantities {
print("generated quantities{} per sample (not warmup) step, have to include 'estimate_me' to run: ",estimate_me);
}
Steps are:
tmp_stan
with the name hello_world.stan
. <path>
is where ever you put the directory in your file system.cmdstan-2.22.1
. It is required that Stan’s compiler be invoked from the install directory.
<path>/tmp_stan/hello_world.stan
.<path>\tmp_stan\hello_world.stan
.hello_world.stan
. Note that you need to drop the .stan
suffix because the make
command is being directed to create the executable hello_world
.
make <path>/tmp_stan/hello_world
make <path>\tmp_stan\hello_world.exe
tmp_stan
directory:
hello_world
or hello_word.exe
for Windows.hello_world.d
, hello_world.o
and hello_world.hpp
. If the compiled failed there may be other files instead.hello_world
is and type the executable as follows (the >
is the command prompt):
>./hello_world method=sample num_samples=1 num_warmup=1
>hello_world.exe method=sample num_samples=1 num_warmup=1
Below is the system out output, but lets go over how the program was configured. The method=sample
argument tells the executable to run the standard HMC inference algorithm, num_samples=1
tells inference to only sample one time and num_warmup=1
to only do one iteration of the warmup process. Default values are 1000 for both arguments but we don’t care since we only want to generate ‘hello world!’ statements.
The first section of console output is a bunch of configuration information about how the Stan program is setup. Note that the num_samples and num_warmup are reflected here.
method = sample (Default)
sample
num_samples = 1
num_warmup = 1
save_warmup = 0 (Default)
thin = 1 (Default)
adapt
engaged = 1 (Default)
gamma = 0.050000000000000003 (Default)
delta = 0.80000000000000004 (Default)
kappa = 0.75 (Default)
t0 = 10 (Default)
init_buffer = 75 (Default)
term_buffer = 50 (Default)
window = 25 (Default)
algorithm = hmc (Default)
hmc
engine = nuts (Default)
nuts
max_depth = 10 (Default)
metric = diag_e (Default)
metric_file = (Default)
stepsize = 1 (Default)
stepsize_jitter = 0 (Default)
id = 0 (Default)
data
file = (Default)
init = 2 (Default)
random
seed = -1 (Default)
output
file = output.csv (Default)
diagnostic_file = (Default)
refresh = 100 (Default)
Next in the console output we get to the print statements we added to hello_world.stan
.
transformed data{} hello world! once per program run
functions{} hello world! from any block that one can print from
For details on how Stan programs are executed please refer to Chapter 8 of the [Stan Manual])https://mc-stan.org/docs/). You will however get a good sense of what is happening by looking at the hello world output. Our first hello is from transformed data{}
and it is executed once.
Next we see the result of a function call from transformed data{}
to helloWorld()
which can be called from any Stan block that allows statements calls–only data{}
and parameters{}
don’t allow statements.
Next Stan starts to estimate parameters. See Chapter 12 of the Stan manual for more details, we see below the leapfrog steps applying.
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=0.855965
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=0.855965
Gradient evaluation took 2.8e-05 seconds
1000 transitions using 10 leapfrog steps per transition would take 0.28 seconds.
Adjust your expectations accordingly!
WARNING: No variance estimation is
performed for num_warmup < 20
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=0.855965
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=0.545875
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=0.855965
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=0.941017
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=0.855965
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=0.225719
Iteration: 1 / 2
The above leapfrog steps supported getting a warmup sample indicated by Iteration: 1 / 2
. Because we are still in warmup the value for estimate_me
is not saved for user examination nor is generated quantities{}
called.
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=0.855965
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=0.816833
Iteration: 2 / 2 [100%] (Sampling)
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=0.816833
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=8.76032e-16
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=1
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=1
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=1
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=1
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=2.56267e-94
transformed parameters {} hello world! every leap frog step
model{} hello world! every leap frog step: estimate_me=5.03416e-110
transformed parameters {} hello world! every leap frog step
generated quantities{} per sample (not warmup) step, have to include 'estimate_me' to run: 0.816833
Elapsed Time: 0.000121 seconds (Warm-up)
0.000238 seconds (Sampling)
0.000359 seconds (Total)
Above is the second sample being determined with leapfrog steps and since we forced Stan to sample after one warmup step we get a value for the parameter ‘estimate_me’ that we can print out in the generated quantities{}
block.
So that is it, refer to the Stan manual for more about what is going on behind the scenes but these ‘Hello World!’ convey the general execution order of a Stan program doing HMC inference.
Below we show how to run ‘hello_world.stan’ from CmdStanR, CmdStanPy and RStudio.
Most users will work with Stan from another language. The most popular ones are R with two:
and Python with a pair as well:
and there are others at our interfaces page. For ‘Hello World!’ we will focus on the light weight interfaces CmdStanR and CmdStanPy.