rv/lib.rs
1//! Provides random variables for probabilistic modeling.
2//!
3//! The [`dist`] module provides a number of probability distributions with
4//! various traits implemented in the [`traits`] module. You can do all the
5//! standard probability distribution stuff like evaluate the PDF/PMF and draw
6//! values of different types.
7//!
8//! The [`prelude`] module provides all the distributions, all the traits, and
9//! creates a few useful type aliases.
10//!
11//! # Features
12//!
13//! - `serde1`: enables serialization and de-serialization of structs via
14//! [serde](https://crates.io/crates/serde)
15//! - `process`: Gives you access to Gaussian processes.
16//! - `arraydist`: Enables distributions and statistical tests that require the
17//! [nalgebra](https://crates.io/crates/nalgebra) crate.
18//! - `experimental`: Enables experimental features.
19//!
20//! # Design
21//!
22//! Random variables are designed to be flexible. For example, we don't just
23//! want a `Beta` distribution that works with `f64`; we want it to work with a
24//! bunch of things
25//!
26//! ```
27//! use rv::prelude::*;
28//!
29//! // Beta(0.5, 0.5)
30//! let beta = Beta::jeffreys();
31//!
32//! let mut rng = rand::rng();
33//!
34//! // 100 f64 weights in (0, 1)
35//! let f64s: Vec<f64> = beta.sample(100, &mut rng);
36//! let pdf_x = beta.ln_pdf(&f64s[42]);
37//!
38//! // 100 f32 weights in (0, 1)
39//! let f32s: Vec<f32> = beta.sample(100, &mut rng);
40//! let pdf_y = beta.ln_pdf(&f32s[42]);
41//!
42//! // 100 Bernoulli distributions -- Beta is a prior on the weight
43//! let berns: Vec<Bernoulli> = beta.sample(100, &mut rng);
44//! let pdf_bern = beta.ln_pdf(&berns[42]);
45//! ```
46//!
47//! # Examples
48//!
49//! For more examples, check out the `examples` directory.
50//!
51//! ## Conjugate analysis of coin flips
52//!
53//! ```rust
54//! use rv::prelude::*;
55//!
56//! let mut rng = rand::rng();
57//!
58//! // A sequence of observations
59//! let flips = vec![true, false, true, true, true, false, true];
60//!
61//! // Construct the Jeffreys prior of Beta(0.5, 0.5)
62//! let prior = Beta::jeffreys();
63//!
64//! // Packages the data in a wrapper that marks it as having come from
65//! // Bernoulli trials.
66//! let obs: BernoulliData<bool> = DataOrSuffStat::Data(&flips);
67//!
68//! // Generate the posterior distribution P(θ|x); the distribution of
69//! // probable coin weights
70//! let posterior: Beta = prior.posterior(&obs);
71//!
72//! // What is the probability that the next flip would come up heads
73//! // (true) given the observed flips (posterior predictive)?
74//! let p_heads = prior.pp(&true, &obs);
75//! ```
76
77#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
78#![warn(
79 clippy::all,
80 clippy::imprecise_flops,
81 clippy::suboptimal_flops,
82 clippy::unseparated_literal_suffix,
83 clippy::unreadable_literal,
84 clippy::option_option,
85 clippy::implicit_clone
86)]
87#![deny(clippy::print_stdout)]
88#![cfg_attr(feature = "experimental", feature(f16))]
89
90#[cfg(feature = "serde1")]
91extern crate serde;
92
93// Test the README
94use doc_comment::doctest;
95doctest!("../README.md");
96
97pub mod consts;
98pub mod data;
99pub mod dist;
100#[cfg(feature = "experimental")]
101pub mod experimental;
102pub mod misc;
103mod model;
104pub mod prelude;
105#[cfg(feature = "process")]
106pub mod process;
107pub mod test;
108pub mod traits;
109
110pub use crate::model::ConjugateModel;
111
112// re-export
113#[cfg(feature = "arraydist")]
114pub use nalgebra;
115
116#[macro_export]
117macro_rules! impl_display {
118 ($kind: ty) => {
119 #[cfg_attr(coverage_nightly, coverage(off))]
120 impl ::std::fmt::Display for $kind {
121 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
122 write!(f, "{}", String::from(self))
123 }
124 }
125 };
126}
127
128#[macro_export]
129macro_rules! extract_stat {
130 ($fx: ty, $stat_type: ty) => {
131 fn extract_stat(x: &DataOrSuffStat<f64, $fx>) -> $stat_type {
132 match x {
133 DataOrSuffStat::SuffStat(ref s) => (*s).clone(),
134 DataOrSuffStat::Data(xs) => {
135 let mut stat = $stat_type::new();
136 xs.iter().for_each(|y| stat.observe(y));
137 stat
138 }
139 }
140 }
141 };
142}