rv

Random variables (RV) for rust. rv offers basic functionality for many probability distributions.

For example, if we wanted to perform a conjugate analysis of Bernoulli trials:

```rust use rv::prelude::*;

// Prior over the unknown coin weight. Assume all weights are equally // likely. let prior = Beta::uniform();

// observations generated by a fair coin let obs_fair: Vec = vec![0, 1, 0, 1, 1, 0, 1];

// observations generated by a coin rigged to always show heads. Note that // we're using bools here. Bernoulli supports mutliple types. let obs_fixed: Vec = vec![true; 6];

let datafair: BernoulliData<_> = DataOrSuffStat::Data(&obsfair); let datafixed: BernoulliData<_> = DataOrSuffStat::Data(&obsfixed);

// Let's compute the posterior predictive probability (pp) of a heads given // the observations from each coin. let postpredfair = prior.pp(&1u8, &datafair); let postpredfixed = prior.pp(&true, &datafixed);

// The probability of heads should be greater under the all heads data assert!(postpredfixed > postpredfair);

// We can also get the posteriors let postfair: Beta = prior.posterior(&datafair); let postfixed: Beta = prior.posterior(&datafixed);

// And compare their means let postmeanfair: f64 = postfair.mean().unwrap(); let postmeanfixed: f64 = postfixed.mean().unwrap();

assert!(postmeanfixed > postmeanfair); ```

Design

Random variables are designed to be flexible. For example, we don't just want a Beta distribution that works with f64; we want it to work with a bunch of things like

```rust use rv::prelude::*;

// Beta(0.5, 0.5) let beta = Beta::jeffreys();

let mut rng = rand::thread_rng();

// 100 f64 weights in (0, 1) let f64s: Vec = beta.sample(100, &mut rng); let pdfx = beta.lnpdf(&f64s[42]);

// 100 f32 weights in (0, 1) let f32s: Vec = beta.sample(100, &mut rng); let pdfy = beta.lnpdf(&f32s[42]);

// 100 Bernoulli distributions -- Beta is a prior on the weight let berns: Vec = beta.sample(100, &mut rng); let pdfbern = beta.lnpdf(&berns[42]); ```

For more interesting examples, including use in machine learning, see examples/.

Contributing

  1. Please create an issue before starting any work. We're far from stable, so we might actually be working on what you want, or we might be working on something that will change the way you might implement it.
  2. If you plan on implementing a new distribution, implement at least Rv, Support, and either ContinuousDistr or DiscreteDistr. Of course, more is better!
  3. Implement new distributions for the appropriate types. For example, don't just implement Rv<f64>, also implement Rv<f32>. Check out other distributions to see how it can be done easily with macros.
  4. Write tests, docs, and doc tests.
  5. Use rustfmt. We've included a .rustfmt.toml in the project directory.