# r-gen
A probabilistic programming framework for the rust programming language. This is heavily based on the Gen library for the Julia programming language.
Example using importance sampling to estimate latent variables.
```rust
...
fn main() {
//Define our generative model.
#[r_gen]
fn my_model(():()){
let p = sample!(format!("p"), Distribution::Beta(1.0, 1.0));
sample!(format!("num_heads"), Distribution::Binomial(100, p.into()));
}
//Run the model once in the forward direction and record the observations.
let (t, _) : (Trace, _)= simulate(&mut my_model, ());
let choices = Choicemap::from(vec![("num_heads", t.choices["num_heads"])]);
//Perform importance resampling to get an estimate for the value of p.
let mut traces = Vec::new();
for _ in 0..1000 {
let (gt, _) : (Trace, _)= generate(&mut my_model, (), &choices);
traces.push(gt);
}
println!("Actual value for p:\t {}", t.choices["p"]);
println!("Generated value for p:\t {}", Trace::sample_weighted_traces(&traces).unwrap().choices["p"]);
}
```
Outputs:
```
Actual value for p: 0.8011431168181488
Generated value for p: 0.7879998086169554
```
Note the `#[r_gen]` tag on the generative function. This must be on any of your generative functions in order to use `simulate` and `generate` on them. One other stipulation of a generative function is that it must have a single argument. This can be a tuple or `()` if you dont need to pass any arguments. In order to make a random choice (sample from a distribution) you must use the `sample!()` macro. The syntax for this is
```rust
sample!(identifier, Distribution);
```
This samples the `Distribution` given and stores the result in `identifier`. `Distribution` is defined as
```rust
pub enum Distribution {
Bernoulli(f64), //p
Binomial(i64, f64), //n, p
Normal(f64, f64), //mu, sigma
Gamma(f64, f64), //alpha, beta
Beta(f64, f64), //alpha, beta
LogNormal(f64, f64), //mu, sigma
Categorical(Vec<f64>), //p
Dirichlet(Vec<f64>), //alpha
}
```
`Value` is defined as
```rust
pub enum Value {
Boolean(bool),
Integer(i64),
Real(f64),
Vector(Vec<Value>)
}
```
The variant of the enum that is returned from sampling depends on the distribution being sampled.
---
This framework is in EARLY stages of development. Everything is subject to change.