StanBlocks.jl
Implements many - but currently not all - of the Bayesian models in posteriordb
by implementing Julia macros and functions which mimick Stan blocks and functions respectively, with relatively light dependencies. Using the macros and functions defined in this package, the “shortest” posteriordb
model (earn_height.stan
)
data {
int<lower=0> N;
vector[N] earn;
vector[N] height;
}parameters {
vector[2] beta;
real<lower=0> sigma;
}model {
1] + beta[2] * height, sigma);
earn ~ normal(beta[ }
becomes
julia_implementation(::Val{:earn_height}; N, earn, height, kwargs...) = begin
@stan begin
@parameters begin
::vector[2]
beta::real(lower=0.)
sigmaend
@model begin
~ normal(@broadcasted(beta[1] + beta[2] * height), sigma);
earn end
end
end
Instantiating the posterior (i.e. model + data) requires loading PosteriorDB.jl
, which provides access to the datasets, e.g. to load the earnings-earn_height
posterior (earn_height
model + earning
data):
import StanBlocks, PosteriorDB
= PosteriorDB.database()
pdb = PosteriorDB.posterior(pdb, "earnings-earn_height")
post
= StanBlocks.julia_implementation(post)
jlpdf jlpdf(randn(StanBlocks.dimension(jlpdf))) # Returns some number
Caveats
Differences in the returned log-density
Stan’s default “sampling statement” (e.g. y ~ normal(mu, sigma);
) automatically drops constant terms (unless configured differently), see https://mc-stan.org/docs/reference-manual/statements.html#log-probability-increment-vs.-distribution-statement. Constant terms are terms which do not depend on model parameters, and this package’s macros and functions currently do not try to figure out which terms do not depend on model parameters, and as such we never drop them. This may lead to (constant) differences in the computed log-densities from the Stan and Julia implementations.
Some models are not implemented yet, or may have smaller or bigger errors
I’ve implemented many of the models, but I haven’t implemented all of them, and I probably have made some mistakes in implementing some of them.
Some models may have been implemented suboptimally
Just that.
Using and testing the implementations
See https://nsiccha.github.io/StanBlocks.jl/#overview-of-posteriors for an overview of (hopefully) correctly implemented models.
See test/runtests.jl
for a way to run and check the models. After importing PosteriorDB
, StanLogDensityProblems
and LogDensityProblems
, you should have access to reference Stan implementations of the log density and of its gradient, see the documentation of StanLogDensityProblems.jl
. The Stan log density can then be compared to the Julia log density as is, and after loading Julia’s AD packages, you can also compare the Stan log density gradient to the Julia log density gradient.
Overview of implemented posteriors
Check out https://nsiccha.github.io/StanBlocks.jl/performance.html for an overview of implemented posteriors and their relative performances.