In Stan, “~” should be called a “distribution statement,” not a “sampling statement.”

Aki writes:

The sampling statement name for tilde (~) statements in Stan documentation has been replaced with distribution statement. The background is

  • the tilde (~) statement does not do any sampling (but due to the sampling statement name, some people had wrongly assumed so, which caused confusion)
  • in the literature, tilde (~) is usually read “is distributed as”
  • right side of the tilde (~) statement can only be a built-in or user defined distribution
  • distribution statement makes it more natural to discuss the difference in defining the model with collection of distributions or with log density increments

The change affects only the documentation. The documentation has been revised to be more clear on differences in describing models with distribution statements and increment log density (target +=) statements.

As this blog lacks equations support, it’s best to go to read the updated documentation on distribution statement.

In addition, Stan User’s Guide sections on censored data models and zero-inflated count models are good examples illustrating the difference between describing a data model with distribution statement or writing the likelihood directly with increment log density statement.

This doesn’t change Stan’s capabilities or performance in any way, but I think it’s still important!  I’ve often heard people say that the ~ in a Stan model corresponds to sampling, and it doesn’t!

Also don’t forget this example:

theta ~ normal(0, 1);
theta ~ normal(0, 1);

If you include the above two lines of code in your Stan model, the result is not a redundant specification that theta is distributed as normal(0, 1). Rather, the above two lines add two terms to the target function. They are equivalent to:

target += normal_lpdf(theta | 0, 1);
target += normal_lpdf(theta | 0, 1);

and equivalent to the explicit and less computationally-efficient expression:

target += -0.5 * log(2*pi()) - 0.5 * square(theta);
target += -0.5 * log(2*pi()) - 0.5 * square(theta);

and, because of the convolution properties of the normal distribution, equivalent to the single line of code:

theta ~ normal(0, 1/sqrt(2));

or

target += normal_lpdf(theta | 0, 1/sqrt(2));

Anyway, it’s not a “sampling statement.” This misinterpretation was bugging us for awhile and then we just recently noticed the faulty terminology in the manual (which could well be something that I used to write or say myself!), so we fixed it!

Stan does have a sampling statement; it’s called “random number generation”

The funny thing is that you can do sampling in Stan! It has to be done in the generated quantities block; for example:

phi = normal_rng(0, 1);

What happens if you include the following two lines in your generated quantities block?

phi = normal_rng(0, 1);
phi = normal_rng(0, 1);

Stan code is executed sequentially, and the above code will first sample phi from a unit normal, then sample phi again from a unit normal. So the first line above is completely overwritten, in the same way that if you write, a=2; a=3; in Stan (or just about any other language), it will give the same result as a simple a=3;.

Stan of course also does sampling in its posterior inference. That’s something different. Here we’re talking about random sampling within Stan.

[Edit: Fixed RNG notation.]

2 thoughts on “In Stan, “~” should be called a “distribution statement,” not a “sampling statement.”

  1. Sorry, my bad—I introduced the misleading terminology.

    I also edited the post to fix the RNG notation. It has to use an assignment (=), not a twiddle (~) for RNGs.

    I’m a bit distressed that everyone’s being encouraged to forego the distribution statement for target += because everyone’s using the normal_lpdf form, which keeps normalizing constants. That’s not so bad for normals, but it can be really expensive in some other distributions, like say the beta distribution, where the normalizing constants involve gamma functions. In these cases, unless you need the joint density, it’s more efficient to use normal_lupdf, where the extra ‘u’ denotes “unconstrained”.

    P.S. Had to edit this post because Andrew has it configured so that the tt tag (for typewriter text) uses the same font as the main body text. I had not use a code tag.

  2. Personally, I have never really liked the “syntactical sugar” of the distribution statement as it seems a bit misleading. It seems better just to be explicit and write out what is actually happening, incrementing the log probability, using _lpdf, _lpmf, _lupdf, or _lupmf.

Leave a Reply

Your email address will not be published. Required fields are marked *