5 releases
0.1.4 | Mar 25, 2021 |
---|---|
0.1.3 | Mar 21, 2021 |
0.1.2 | Feb 28, 2021 |
0.1.1 | Feb 26, 2021 |
0.1.0 | Feb 21, 2021 |
#2121 in Algorithms
18KB
172 lines
porco
Composable probability distributions.
Examples
Create simple probability distributions.
enum Coin {
Heads,
Tails,
}
impl Coin {
fn flip() -> Distribution<Coin> {
Distribution::uniform([Coin::Heads, Coin::Tails])
}
}
let coin = Coin::flip();
assert_eq!(coin.pmf(&Coin::Heads), Probability(0.5));
Compose operations over distributions using combinators.
fn reflip_if_tails(coin: Coin) -> Distribution<Coin> {
match coin {
Coin::Heads => Distribution::always(Coin::Heads),
Coin::Tails => Coin::flip(),
}
}
let coin = Coin::flip().and_then(reflip_if_tails);
assert_eq!(coin.pmf(&Coin::Heads), Probability(0.75));
Compute summary statistics of random variables.
let die = Distribution::uniform([1, 2, 3, 4, 5, 6]);
let ev = die.given(|&v| v <= 4).expectation();
assert_eq!(ev, 2.5);
lib.rs
:
Porco is a library for working with and composing probability distributions.
The API is inspired by the contents of
Probabilistic Functional Programming in Haskell
but with naming conventions that match those of Option
and Result
(such as Option::and_then
).
enum Coin {
Heads,
Tails,
}
impl Coin {
fn flip() -> Distribution<Coin> {
Distribution::uniform(vec![Coin::Heads, Coin::Tails])
}
}
let coin = Coin::flip();
assert_eq!(coin.pmf(&Coin::Heads), Probability(0.5));
You can compose various operations over Distribution
s using combinators
like Distribution::map
, Distribution::and_then
, and
Distribution::given
.
fn reflip_if_tails(coin: Coin) -> Distribution<Coin> {
match coin {
Coin::Heads => Distribution::always(Coin::Heads),
Coin::Tails => Coin::flip(),
}
}
let coin = Coin::flip().and_then(reflip_if_tails);
assert_eq!(coin.pmf(&Coin::Heads), Probability(0.75));
You can also manipulate random variables and compute summary statistics.
let die = Distribution::uniform(vec![1, 2, 3, 4, 5, 6]);
let ev = die.given(|&v| v <= 4).expectation();
assert_eq!(ev, 2.5);
fn two_sided_die() -> Distribution<u8> {
Distribution::uniform(vec![1, 2])
}
let x = two_sided_die();
let y = two_sided_die();
let sum = x.convolve(y);
assert_eq!(sum.pmf(&2), Probability(0.25));
assert_eq!(sum.pmf(&3), Probability(0.5));
Dependencies
~450KB