BridgeStan from Rust

View the BridgeStan documentation on Github Pages.

This is a Rust wrapper for BridgeStan. It allows users to evaluate the log likelihood and related functions for Stan models natively from Rust.

Internally, it relies on bindgen and libloading.

Compiling the model

The Rust wrapper does not currently have any functionality to compile Stan models. Compiled shared libraries need to be built manually using make or with the Julia or Python bindings.

For safety reasons all Stan models need to be installed with STAN_THREADS=true. When compiling a model using make, set the environment variable:

bash STAN_THREADS=true make some_model

When compiling a Stan model in python, this has to be specified in the make_args argument:

python path = bridgestan.compile_model("stan_model.stan", make_args=["STAN_THREADS=true"])

If STAN_THREADS was not specified while building the model, the Rust wrapper will throw an error when loading the model.

Usage:

Run this example with cargo run --example=example.

```rust use std::ffi::CString; use std::path::Path; use bridgestan::{BridgeStanError, Model, open_library};

// The path to the compiled model. // Get for instance from python bridgestan.compile_model let path = Path::new(env!["CARGOMANIFESTDIR"]) .parent() .unwrap() .join("testmodels/simple/simplemodel.so");

let lib = open_library(path).expect("Could not load compiled Stan model.");

// The dataset as json let data = r#"{"N": 7}"#; let data = CString::new(data.tostring().intobytes()).unwrap();

// The seed is used in case the model contains a transformed data section // that uses rng functions. let seed = 42;

let model = match Model::new(&lib, Some(data), seed) { Ok(model) => { model }, Err(BridgeStanError::ConstructFailed(msg)) => { panic!("Model initialization failed. Error message from Stan was {}", msg) }, _ => { panic!("Unexpected error") }, };

let ndim = model.paramuncnum(); asserteq!(ndim, 7); let point = vec![1f64; ndim]; let mut gradientout = vec![0f64; ndim]; let logp = model.logdensitygradient(&point[..], true, true, &mut gradientout[..]) .expect("Stan failed to evaluate the logp function."); // gradientout contains the gradient of the logp density ```