Add distribution plots to rand_distr documentation (#1434)

This commit is contained in:
Michael Dyer 2024-07-08 20:16:19 +02:00 committed by GitHub
parent ca9e119859
commit 17746a1ace
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 550 additions and 142 deletions

View File

@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Added
- Add plots for `rand_distr` distributions to documentation (#1434)
## [0.5.0-alpha.1] - 2024-03-18
- Target `rand` version `0.9.0-alpha.1`

View File

@ -14,7 +14,7 @@ keywords = ["random", "rng", "distribution", "probability"]
categories = ["algorithms", "no-std"]
edition = "2021"
rust-version = "1.61"
include = ["src/", "LICENSE-*", "README.md", "CHANGELOG.md", "COPYRIGHT"]
include = ["/src", "LICENSE-*", "README.md", "CHANGELOG.md", "COPYRIGHT"]
[package.metadata.docs.rs]
rustdoc-args = ["--cfg docsrs", "--generate-link-to-definition"]

View File

@ -7,7 +7,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The binomial distribution.
//! The binomial distribution `Binomial(n, p)`.
use crate::{Distribution, Uniform};
use core::cmp::Ordering;
@ -16,11 +16,24 @@ use core::fmt;
use num_traits::Float;
use rand::Rng;
/// The binomial distribution `Binomial(n, p)`.
/// The [binomial distribution](https://en.wikipedia.org/wiki/Binomial_distribution) `Binomial(n, p)`.
///
/// The binomial distribution is a discrete probability distribution
/// which describes the probability of seeing `k` successes in `n`
/// independent trials, each of which has success probability `p`.
///
/// # Density function
///
/// This distribution has density function:
/// `f(k) = n!/(k! (n-k)!) p^k (1-p)^(n-k)` for `k >= 0`.
///
/// # Plot
///
/// The following plot of the binomial distribution illustrates the
/// probability of `k` successes out of `n = 10` trials with `p = 0.2`
/// and `p = 0.6` for `0 <= k <= n`.
///
/// ![Binomial distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/binomial.svg)
///
/// # Example
///
/// ```

View File

@ -7,20 +7,37 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The Cauchy distribution.
//! The Cauchy distribution `Cauchy(x₀, γ)`.
use crate::{Distribution, Standard};
use core::fmt;
use num_traits::{Float, FloatConst};
use rand::Rng;
/// The Cauchy distribution `Cauchy(median, scale)`.
/// The [Cauchy distribution](https://en.wikipedia.org/wiki/Cauchy_distribution) `Cauchy(x₀, γ)`.
///
/// This distribution has a density function:
/// `f(x) = 1 / (pi * scale * (1 + ((x - median) / scale)^2))`
/// The Cauchy distribution is a continuous probability distribution with
/// parameters `x₀` (median) and `γ` (scale).
/// It describes the distribution of the ratio of two independent
/// normally distributed random variables with means `x₀` and scales `γ`.
/// In other words, if `X` and `Y` are independent normally distributed
/// random variables with means `x₀` and scales `γ`, respectively, then
/// `X / Y` is `Cauchy(x₀, γ)` distributed.
///
/// Note that at least for `f32`, results are not fully portable due to minor
/// differences in the target system's *tan* implementation, `tanf`.
/// # Density function
///
/// `f(x) = 1 / (π * γ * (1 + ((x - x₀) / γ)²))`
///
/// # Plot
///
/// The plot illustrates the Cauchy distribution with various values of `x₀` and `γ`.
/// Note how the median parameter `x₀` shifts the distribution along the x-axis,
/// and how the scale `γ` changes the density around the median.
///
/// The standard Cauchy distribution is the special case with `x₀ = 0` and `γ = 1`,
/// which corresponds to the ratio of two [`StandardNormal`](crate::StandardNormal) distributions.
///
/// ![Cauchy distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/cauchy.svg)
///
/// # Example
///
@ -31,6 +48,11 @@ use rand::Rng;
/// let v = cau.sample(&mut rand::thread_rng());
/// println!("{} is from a Cauchy(2, 5) distribution", v);
/// ```
///
/// # Notes
///
/// Note that at least for `f32`, results are not fully portable due to minor
/// differences in the target system's *tan* implementation, `tanf`.
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub struct Cauchy<F>

View File

@ -7,7 +7,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The dirichlet distribution.
//! The dirichlet distribution `Dirichlet(α₁, α₂, ..., αₙ)`.
#![cfg(feature = "alloc")]
use crate::{Beta, Distribution, Exp1, Gamma, Open01, StandardNormal};
use core::fmt;
@ -185,11 +186,23 @@ where
FromBeta(DirichletFromBeta<F, N>),
}
/// The Dirichlet distribution `Dirichlet(alpha)`.
/// The [Dirichlet distribution](https://en.wikipedia.org/wiki/Dirichlet_distribution) `Dirichlet(α₁, α₂, ..., αₖ)`.
///
/// The Dirichlet distribution is a family of continuous multivariate
/// probability distributions parameterized by a vector alpha of positive reals.
/// It is a multivariate generalization of the beta distribution.
/// probability distributions parameterized by a vector of positive
/// real numbers `α₁, α₂, ..., αₖ`, where `k` is the number of dimensions
/// of the distribution. The distribution is supported on the `k-1`-dimensional
/// simplex, which is the set of points `x = [x₁, x₂, ..., xₖ]` such that
/// `0 ≤ xᵢ ≤ 1` and `∑ xᵢ = 1`.
/// It is a multivariate generalization of the [`Beta`](crate::Beta) distribution.
/// The distribution is symmetric when all `αᵢ` are equal.
///
/// # Plot
///
/// The following plot illustrates the 2-dimensional simplices for various
/// 3-dimensional Dirichlet distributions.
///
/// ![Dirichlet distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/dirichlet.png)
///
/// # Example
///

View File

@ -7,7 +7,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The exponential distribution.
//! The exponential distribution `Exp(λ)`.
use crate::utils::ziggurat;
use crate::{ziggurat_tables, Distribution};
@ -15,11 +15,30 @@ use core::fmt;
use num_traits::Float;
use rand::Rng;
/// Samples floating-point numbers according to the exponential distribution,
/// with rate parameter `λ = 1`. This is equivalent to `Exp::new(1.0)` or
/// sampling with `-rng.gen::<f64>().ln()`, but faster.
/// The standard exponential distribution `Exp(1)`.
///
/// See `Exp` for the general exponential distribution.
/// This is equivalent to `Exp::new(1.0)` or sampling with
/// `-rng.gen::<f64>().ln()`, but faster.
///
/// See [`Exp`](crate::Exp) for the general exponential distribution.
///
/// # Plot
///
/// The following plot illustrates the exponential distribution with `λ = 1`.
///
/// ![Exponential distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/exponential_exp1.svg)
///
/// # Example
///
/// ```
/// use rand::prelude::*;
/// use rand_distr::Exp1;
///
/// let val: f64 = thread_rng().sample(Exp1);
/// println!("{}", val);
/// ```
///
/// # Notes
///
/// Implemented via the ZIGNOR variant[^1] of the Ziggurat method. The exact
/// description in the paper was adjusted to use tables for the exponential
@ -29,15 +48,6 @@ use rand::Rng;
/// Generate Normal Random Samples*](
/// https://www.doornik.com/research/ziggurat.pdf).
/// Nuffield College, Oxford
///
/// # Example
/// ```
/// use rand::prelude::*;
/// use rand_distr::Exp1;
///
/// let val: f64 = thread_rng().sample(Exp1);
/// println!("{}", val);
/// ```
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub struct Exp1;
@ -75,12 +85,30 @@ impl Distribution<f64> for Exp1 {
}
}
/// The exponential distribution `Exp(lambda)`.
/// The [exponential distribution](https://en.wikipedia.org/wiki/Exponential_distribution) `Exp(λ)`.
///
/// This distribution has density function: `f(x) = lambda * exp(-lambda * x)`
/// for `x > 0`, when `lambda > 0`. For `lambda = 0`, all samples yield infinity.
/// The exponential distribution is a continuous probability distribution
/// with rate parameter `λ` (`lambda`). It describes the time between events
/// in a [`Poisson`](crate::Poisson) process, i.e. a process in which
/// events occur continuously and independently at a constant average rate.
///
/// Note that [`Exp1`](crate::Exp1) is an optimised implementation for `lambda = 1`.
/// See [`Exp1`](crate::Exp1) for an optimised implementation for `λ = 1`.
///
/// # Density function
///
/// `f(x) = λ * exp(-λ * x)` for `x > 0`, when `λ > 0`.
///
/// For `λ = 0`, all samples yield infinity (because a Poisson process
/// with rate 0 has no events).
///
/// # Plot
///
/// The following plot illustrates the exponential distribution with
/// various values of `λ`.
/// The `λ` parameter controls the rate of decay as `x` approaches infinity,
/// and the mean of the distribution is `1/λ`.
///
/// ![Exponential distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/exponential.svg)
///
/// # Example
///

View File

@ -6,20 +6,36 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The Fréchet distribution.
//! The Fréchet distribution `Fréchet(μ, σ, α)`.
use crate::{Distribution, OpenClosed01};
use core::fmt;
use num_traits::Float;
use rand::Rng;
/// Samples floating-point numbers according to the Fréchet distribution
/// The [Fréchet distribution](https://en.wikipedia.org/wiki/Fr%C3%A9chet_distribution) `Fréchet(α, μ, σ)`.
///
/// This distribution has density function:
/// `f(x) = [(x - μ) / σ]^(-1 - α) exp[-(x - μ) / σ]^(-α) α / σ`,
/// where `μ` is the location parameter, `σ` the scale parameter, and `α` the shape parameter.
/// The Fréchet distribution is a continuous probability distribution
/// with location parameter `μ` (`mu`), scale parameter `σ` (`sigma`),
/// and shape parameter `α` (`alpha`). It describes the distribution
/// of the maximum (or minimum) of a number of random variables.
/// It is also known as the Type II extreme value distribution.
///
/// # Density function
///
/// `f(x) = [(x - μ) / σ]^(-1 - α) exp[-(x - μ) / σ]^(-α) α / σ`
///
/// # Plot
///
/// The plot shows the Fréchet distribution with various values of `μ`, `σ`, and `α`.
/// Note how the location parameter `μ` shifts the distribution along the x-axis,
/// the scale parameter `σ` stretches or compresses the distribution along the x-axis,
/// and the shape parameter `α` changes the tail behavior.
///
/// ![Fréchet distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/frechet.svg)
///
/// # Example
///
/// ```
/// use rand::prelude::*;
/// use rand_distr::Frechet;

View File

@ -24,21 +24,28 @@ use rand::Rng;
#[cfg(feature = "serde1")]
use serde::{Deserialize, Serialize};
/// The Gamma distribution `Gamma(shape, scale)` distribution.
/// The [Gamma distribution](https://en.wikipedia.org/wiki/Gamma_distribution) `Gamma(k, θ)`.
///
/// The density function of this distribution is
/// The Gamma distribution is a continuous probability distribution
/// with shape parameter `k > 0` (number of events) and
/// scale parameter `θ > 0` (mean waiting time between events).
/// It describes the time until `k` events occur in a Poisson
/// process with rate `1/θ`. It is the generalization of the
/// [`Exponential`](crate::Exp) distribution.
///
/// ```text
/// f(x) = x^(k - 1) * exp(-x / θ) / (Γ(k) * θ^k)
/// ```
/// # Density function
///
/// where `Γ` is the Gamma function, `k` is the shape and `θ` is the
/// scale and both `k` and `θ` are strictly positive.
/// `f(x) = x^(k - 1) * exp(-x / θ) / (Γ(k) * θ^k)` for `x > 0`,
/// where `Γ` is the [gamma function](https://en.wikipedia.org/wiki/Gamma_function).
///
/// The algorithm used is that described by Marsaglia & Tsang 2000[^1],
/// falling back to directly sampling from an Exponential for `shape
/// == 1`, and using the boosting technique described in that paper for
/// `shape < 1`.
/// # Plot
///
/// The following plot illustrates the Gamma distribution with
/// various values of `k` and `θ`.
/// Curves with `θ = 1` are more saturated, while corresponding
/// curves with `θ = 2` have a lighter color.
///
/// ![Gamma distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/gamma.svg)
///
/// # Example
///
@ -50,6 +57,13 @@ use serde::{Deserialize, Serialize};
/// println!("{} is from a Gamma(2, 5) distribution", v);
/// ```
///
/// # Notes
///
/// The algorithm used is that described by Marsaglia & Tsang 2000[^1],
/// falling back to directly sampling from an Exponential for `shape
/// == 1`, and using the boosting technique described in that paper for
/// `shape < 1`.
///
/// [^1]: George Marsaglia and Wai Wan Tsang. 2000. "A Simple Method for
/// Generating Gamma Variables" *ACM Trans. Math. Softw.* 26, 3
/// (September 2000), 363-372.
@ -262,14 +276,23 @@ where
}
}
/// The chi-squared distribution `χ²(k)`, where `k` is the degrees of
/// freedom.
/// The [chi-squared distribution](https://en.wikipedia.org/wiki/Chi-squared_distribution) `χ²(k)`.
///
/// The chi-squared distribution is a continuous probability
/// distribution with parameter `k > 0` degrees of freedom.
///
/// For `k > 0` integral, this distribution is the sum of the squares
/// of `k` independent standard normal random variables. For other
/// `k`, this uses the equivalent characterisation
/// `χ²(k) = Gamma(k/2, 2)`.
///
/// # Plot
///
/// The plot shows the chi-squared distribution with various degrees
/// of freedom.
///
/// ![Chi-squared distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/chi_squared.svg)
///
/// # Example
///
/// ```
@ -368,12 +391,18 @@ where
}
}
/// The Fisher F distribution `F(m, n)`.
/// The [Fisher F-distribution](https://en.wikipedia.org/wiki/F-distribution) `F(m, n)`.
///
/// This distribution is equivalent to the ratio of two normalised
/// chi-squared distributions, that is, `F(m,n) = (χ²(m)/m) /
/// (χ²(n)/n)`.
///
/// # Plot
///
/// The plot shows the F-distribution with various values of `m` and `n`.
///
/// ![F-distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/fisher_f.svg)
///
/// # Example
///
/// ```
@ -457,8 +486,25 @@ where
}
}
/// The Student t distribution, `t(nu)`, where `nu` is the degrees of
/// freedom.
/// The [Student t-distribution](https://en.wikipedia.org/wiki/Student%27s_t-distribution) `t(ν)`.
///
/// The t-distribution is a continuous probability distribution
/// parameterized by degrees of freedom `ν` (`nu`), which
/// arises when estimating the mean of a normally-distributed
/// population in situations where the sample size is small and
/// the population's standard deviation is unknown.
/// It is widely used in hypothesis testing.
///
/// For `ν = 1`, this is equivalent to the standard
/// [`Cauchy`](crate::Cauchy) distribution,
/// and as `ν` diverges to infinity, `t(ν)` converges to
/// [`StandardNormal`](crate::StandardNormal).
///
/// # Plot
///
/// The plot shows the t-distribution with various degrees of freedom.
///
/// ![T-distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/student_t.svg)
///
/// # Example
///
@ -489,12 +535,12 @@ where
Exp1: Distribution<F>,
Open01: Distribution<F>,
{
/// Create a new Student t distribution with `n` degrees of
/// freedom.
pub fn new(n: F) -> Result<StudentT<F>, ChiSquaredError> {
/// Create a new Student t-distribution with `ν` (nu)
/// degrees of freedom.
pub fn new(nu: F) -> Result<StudentT<F>, ChiSquaredError> {
Ok(StudentT {
chi: ChiSquared::new(n)?,
dof: n,
chi: ChiSquared::new(nu)?,
dof: nu,
})
}
}
@ -545,7 +591,22 @@ struct BC<N> {
kappa2: N,
}
/// The Beta distribution with shape parameters `alpha` and `beta`.
/// The [Beta distribution](https://en.wikipedia.org/wiki/Beta_distribution) `Beta(α, β)`.
///
/// The Beta distribution is a continuous probability distribution
/// defined on the interval `[0, 1]`. It is the conjugate prior for the
/// parameter `p` of the [`Binomial`][crate::Binomial] distribution.
///
/// It has two shape parameters `α` (alpha) and `β` (beta) which control
/// the shape of the distribution. Both `a` and `β` must be greater than zero.
/// The distribution is symmetric when `α = β`.
///
/// # Plot
///
/// The plot shows the Beta distribution with various combinations
/// of `α` and `β`.
///
/// ![Beta distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/beta.svg)
///
/// # Example
///

View File

@ -1,4 +1,4 @@
//! The geometric distribution.
//! The geometric distribution `Geometric(p)`.
use crate::Distribution;
use core::fmt;
@ -6,20 +6,31 @@ use core::fmt;
use num_traits::Float;
use rand::Rng;
/// The geometric distribution `Geometric(p)` bounded to `[0, u64::MAX]`.
/// The [geometric distribution](https://en.wikipedia.org/wiki/Geometric_distribution) `Geometric(p)`.
///
/// This is the probability distribution of the number of failures before the
/// first success in a series of Bernoulli trials. It has the density function
/// `f(k) = (1 - p)^k p` for `k >= 0`, where `p` is the probability of success
/// on each trial.
/// This is the probability distribution of the number of failures
/// (bounded to `[0, u64::MAX]`) before the first success in a
/// series of [`Bernoulli`](crate::Bernoulli) trials, where the
/// probability of success on each trial is `p`.
///
/// This is the discrete analogue of the [exponential distribution](crate::Exp).
///
/// Note that [`StandardGeometric`](crate::StandardGeometric) is an optimised
/// See [`StandardGeometric`](crate::StandardGeometric) for an optimised
/// implementation for `p = 0.5`.
///
/// # Example
/// # Density function
///
/// `f(k) = (1 - p)^k p` for `k >= 0`.
///
/// # Plot
///
/// The following plot illustrates the geometric distribution for various
/// values of `p`. Note how higher `p` values shift the distribution to
/// the left, and the mean of the distribution is `1/p`.
///
/// ![Geometric distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/geometric.svg)
///
/// # Example
/// ```
/// use rand_distr::{Geometric, Distribution};
///
@ -140,14 +151,17 @@ impl Distribution<u64> for Geometric {
}
}
/// Samples integers according to the geometric distribution with success
/// probability `p = 0.5`. This is equivalent to `Geometeric::new(0.5)`,
/// but faster.
/// The standard geometric distribution `Geometric(0.5)`.
///
/// This is equivalent to `Geometric::new(0.5)`, but faster.
///
/// See [`Geometric`](crate::Geometric) for the general geometric distribution.
///
/// Implemented via iterated
/// [`Rng::gen::<u64>().leading_zeros()`](Rng::gen::<u64>().leading_zeros()).
/// # Plot
///
/// The following plot illustrates the standard geometric distribution.
///
/// ![Standard Geometric distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/standard_geometric.svg)
///
/// # Example
/// ```
@ -157,6 +171,10 @@ impl Distribution<u64> for Geometric {
/// let v = StandardGeometric.sample(&mut thread_rng());
/// println!("{} is from a Geometric(0.5) distribution", v);
/// ```
///
/// # Notes
/// Implemented via iterated
/// [`Rng::gen::<u64>().leading_zeros()`](Rng::gen::<u64>().leading_zeros()).
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub struct StandardGeometric;

View File

@ -6,18 +6,32 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The Gumbel distribution.
//! The Gumbel distribution `Gumbel(μ, β)`.
use crate::{Distribution, OpenClosed01};
use core::fmt;
use num_traits::Float;
use rand::Rng;
/// Samples floating-point numbers according to the Gumbel distribution
/// The [Gumbel distribution](https://en.wikipedia.org/wiki/Gumbel_distribution) `Gumbel(μ, β)`.
///
/// This distribution has density function:
/// `f(x) = exp(-(z + exp(-z))) / σ`, where `z = (x - μ) / σ`,
/// `μ` is the location parameter, and `σ` the scale parameter.
/// The Gumbel distribution is a continuous probability distribution
/// with location parameter `μ` (`mu`) and scale parameter `β` (`beta`).
/// It is used to model the distribution of the maximum (or minimum)
/// of a number of samples of various distributions.
///
/// # Density function
///
/// `f(x) = exp(-(z + exp(-z))) / β`, where `z = (x - μ) / β`.
///
/// # Plot
///
/// The following plot illustrates the Gumbel distribution with various values of `μ` and `β`.
/// Note how the location parameter `μ` shifts the distribution along the x-axis,
/// and the scale parameter `β` changes the density around `μ`.
/// Note also the asymptotic behavior of the distribution towards the right.
///
/// ![Gumbel distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/gumbel.svg)
///
/// # Example
/// ```

View File

@ -1,4 +1,4 @@
//! The hypergeometric distribution.
//! The hypergeometric distribution `Hypergeometric(N, K, n)`.
use crate::Distribution;
use core::fmt;
@ -27,20 +27,29 @@ enum SamplingMethod {
},
}
/// The hypergeometric distribution `Hypergeometric(N, K, n)`.
/// The [hypergeometric distribution](https://en.wikipedia.org/wiki/Hypergeometric_distribution) `Hypergeometric(N, K, n)`.
///
/// This is the distribution of successes in samples of size `n` drawn without
/// replacement from a population of size `N` containing `K` success states.
/// It has the density function:
/// `f(k) = binomial(K, k) * binomial(N-K, n-k) / binomial(N, n)`,
/// where `binomial(a, b) = a! / (b! * (a - b)!)`.
///
/// The [binomial distribution](crate::Binomial) is the analogous distribution
/// See the [binomial distribution](crate::Binomial) for the analogous distribution
/// for sampling with replacement. It is a good approximation when the population
/// size is much larger than the sample size.
///
/// # Example
/// # Density function
///
/// `f(k) = binomial(K, k) * binomial(N-K, n-k) / binomial(N, n)`,
/// where `binomial(a, b) = a! / (b! * (a - b)!)`.
///
/// # Plot
///
/// The following plot of the hypergeometric distribution illustrates the probability of drawing
/// `k` successes in `n = 10` draws from a population of `N = 50` items, of which either `K = 12`
/// or `K = 35` are successes.
///
/// ![Hypergeometric distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/hypergeometric.svg)
///
/// # Example
/// ```
/// use rand_distr::{Distribution, Hypergeometric};
///

View File

@ -1,3 +1,5 @@
//! The inverse Gaussian distribution `IG(μ, λ)`.
use crate::{Distribution, Standard, StandardNormal};
use core::fmt;
use num_traits::Float;
@ -24,7 +26,27 @@ impl fmt::Display for Error {
#[cfg(feature = "std")]
impl std::error::Error for Error {}
/// The [inverse Gaussian distribution](https://en.wikipedia.org/wiki/Inverse_Gaussian_distribution)
/// The [inverse Gaussian distribution](https://en.wikipedia.org/wiki/Inverse_Gaussian_distribution) `IG(μ, λ)`.
///
/// This is a continuous probability distribution with mean parameter `μ` (`mu`)
/// and shape parameter `λ` (`lambda`), defined for `x > 0`.
/// It is also known as the Wald distribution.
///
/// # Plot
///
/// The following plot shows the inverse Gaussian distribution
/// with various values of `μ` and `λ`.
///
/// ![Inverse Gaussian distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/inverse_gaussian.svg)
///
/// # Example
/// ```
/// use rand_distr::{InverseGaussian, Distribution};
///
/// let inv_gauss = InverseGaussian::new(1.0, 2.0).unwrap();
/// let v = inv_gauss.sample(&mut rand::thread_rng());
/// println!("{} is from a inverse Gaussian(1, 2) distribution", v);
/// ```
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub struct InverseGaussian<F>

View File

@ -7,7 +7,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The normal and derived distributions.
//! The Normal and derived distributions.
use crate::utils::ziggurat;
use crate::{ziggurat_tables, Distribution, Open01};
@ -15,18 +15,17 @@ use core::fmt;
use num_traits::Float;
use rand::Rng;
/// Samples floating-point numbers according to the normal distribution
/// `N(0, 1)` (a.k.a. a standard normal, or Gaussian). This is equivalent to
/// `Normal::new(0.0, 1.0)` but faster.
/// The standard Normal distribution `N(0, 1)`.
///
/// See `Normal` for the general normal distribution.
/// This is equivalent to `Normal::new(0.0, 1.0)`, but faster.
///
/// Implemented via the ZIGNOR variant[^1] of the Ziggurat method.
/// See [`Normal`](crate::Normal) for the general Normal distribution.
///
/// [^1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
/// Generate Normal Random Samples*](
/// https://www.doornik.com/research/ziggurat.pdf).
/// Nuffield College, Oxford
/// # Plot
///
/// The following diagram shows the standard Normal distribution.
///
/// ![Standard Normal distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/standard_normal.svg)
///
/// # Example
/// ```
@ -36,6 +35,15 @@ use rand::Rng;
/// let val: f64 = thread_rng().sample(StandardNormal);
/// println!("{}", val);
/// ```
///
/// # Notes
///
/// Implemented via the ZIGNOR variant[^1] of the Ziggurat method.
///
/// [^1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
/// Generate Normal Random Samples*](
/// https://www.doornik.com/research/ziggurat.pdf).
/// Nuffield College, Oxford
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub struct StandardNormal;
@ -92,13 +100,28 @@ impl Distribution<f64> for StandardNormal {
}
}
/// The normal distribution `N(mean, std_dev**2)`.
/// The [Normal distribution](https://en.wikipedia.org/wiki/Normal_distribution) `N(μ, σ²)`.
///
/// This uses the ZIGNOR variant of the Ziggurat method, see [`StandardNormal`]
/// for more details.
/// The Normal distribution, also known as the Gaussian distribution or
/// bell curve, is a continuous probability distribution with mean
/// `μ` (`mu`) and standard deviation `σ` (`sigma`).
/// It is used to model continuous data that tend to cluster around a mean.
/// The Normal distribution is symmetric and characterized by its bell-shaped curve.
///
/// Note that [`StandardNormal`] is an optimised implementation for mean 0, and
/// standard deviation 1.
/// See [`StandardNormal`](crate::StandardNormal) for an
/// optimised implementation for `μ = 0` and `σ = 1`.
///
/// # Density function
///
/// `f(x) = (1 / sqrt(2π σ²)) * exp(-((x - μ)² / (2σ²)))`
///
/// # Plot
///
/// The following diagram shows the Normal distribution with various values of `μ`
/// and `σ`.
/// The blue curve is the [`StandardNormal`](crate::StandardNormal) distribution, `N(0, 1)`.
///
/// ![Normal distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/normal.svg)
///
/// # Example
///
@ -111,7 +134,14 @@ impl Distribution<f64> for StandardNormal {
/// println!("{} is from a N(2, 9) distribution", v)
/// ```
///
/// [`StandardNormal`]: crate::StandardNormal
/// # Notes
///
/// Implemented via the ZIGNOR variant[^1] of the Ziggurat method.
///
/// [^1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
/// Generate Normal Random Samples*](
/// https://www.doornik.com/research/ziggurat.pdf).
/// Nuffield College, Oxford
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub struct Normal<F>
@ -216,10 +246,18 @@ where
}
}
/// The log-normal distribution `ln N(mean, std_dev**2)`.
/// The [log-normal distribution](https://en.wikipedia.org/wiki/Log-normal_distribution) `ln N(μ, σ²)`.
///
/// If `X` is log-normal distributed, then `ln(X)` is `N(mean, std_dev**2)`
/// distributed.
/// This is the distribution of the random variable `X = exp(Y)` where `Y` is
/// normally distributed with mean `μ` and variance `σ²`. In other words, if
/// `X` is log-normal distributed, then `ln(X)` is `N(μ, σ²)` distributed.
///
/// # Plot
///
/// The following diagram shows the log-normal distribution with various values
/// of `μ` and `σ`.
///
/// ![Log-normal distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/log_normal.svg)
///
/// # Example
///

View File

@ -28,7 +28,26 @@ impl fmt::Display for Error {
#[cfg(feature = "std")]
impl std::error::Error for Error {}
/// The [normal-inverse Gaussian distribution](https://en.wikipedia.org/wiki/Normal-inverse_Gaussian_distribution)
/// The [normal-inverse Gaussian distribution](https://en.wikipedia.org/wiki/Normal-inverse_Gaussian_distribution) `NIG(α, β)`.
///
/// This is a continuous probability distribution with two parameters,
/// `α` (`alpha`) and `β` (`beta`), defined in `(-∞, ∞)`.
/// It is also known as the normal-Wald distribution.
///
/// # Plot
///
/// The following plot shows the normal-inverse Gaussian distribution with various values of `α` and `β`.
///
/// ![Normal-inverse Gaussian distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/normal_inverse_gaussian.svg)
///
/// # Example
/// ```
/// use rand_distr::{NormalInverseGaussian, Distribution};
///
/// let norm_inv_gauss = NormalInverseGaussian::new(2.0, 1.0).unwrap();
/// let v = norm_inv_gauss.sample(&mut rand::thread_rng());
/// println!("{} is from a normal-inverse Gaussian(2, 1) distribution", v);
/// ```
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub struct NormalInverseGaussian<F>

View File

@ -6,14 +6,26 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The Pareto distribution.
//! The Pareto distribution `Pareto(xₘ, α)`.
use crate::{Distribution, OpenClosed01};
use core::fmt;
use num_traits::Float;
use rand::Rng;
/// Samples floating-point numbers according to the Pareto distribution
/// The [Pareto distribution](https://en.wikipedia.org/wiki/Pareto_distribution) `Pareto(xₘ, α)`.
///
/// The Pareto distribution is a continuous probability distribution with
/// scale parameter `xₘ` ( or `k`) and shape parameter `α`.
///
/// # Plot
///
/// The following plot shows the Pareto distribution with various values of
/// `xₘ` and `α`.
/// Note how the shape parameter `α` corresponds to the height of the jump
/// in density at `x = xₘ`, and to the rate of decay in the tail.
///
/// ![Pareto distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/pareto.svg)
///
/// # Example
/// ```

View File

@ -12,13 +12,20 @@ use core::fmt;
use num_traits::Float;
use rand::Rng;
/// The PERT distribution.
/// The [PERT distribution](https://en.wikipedia.org/wiki/PERT_distribution) `PERT(min, max, mode, shape)`.
///
/// Similar to the [`Triangular`] distribution, the PERT distribution is
/// parameterised by a range and a mode within that range. Unlike the
/// [`Triangular`] distribution, the probability density function of the PERT
/// distribution is smooth, with a configurable weighting around the mode.
///
/// # Plot
///
/// The following plot shows the PERT distribution with `min = -1`, `max = 1`,
/// and various values of `mode` and `shape`.
///
/// ![PERT distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/pert.svg)
///
/// # Example
///
/// ```rust

View File

@ -7,17 +7,28 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The Poisson distribution.
//! The Poisson distribution `Poisson(λ)`.
use crate::{Cauchy, Distribution, Standard};
use core::fmt;
use num_traits::{Float, FloatConst};
use rand::Rng;
/// The Poisson distribution `Poisson(lambda)`.
/// The [Poisson distribution](https://en.wikipedia.org/wiki/Poisson_distribution) `Poisson(λ)`.
///
/// This distribution has a density function:
/// `f(k) = lambda^k * exp(-lambda) / k!` for `k >= 0`.
/// The Poisson distribution is a discrete probability distribution with
/// rate parameter `λ` (`lambda`). It models the number of events occurring in a fixed
/// interval of time or space.
///
/// This distribution has density function:
/// `f(k) = λ^k * exp(-λ) / k!` for `k >= 0`.
///
/// # Plot
///
/// The following plot shows the Poisson distribution with various values of `λ`.
/// Note how the expected number of events increases with `λ`.
///
/// ![Poisson distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/poisson.svg)
///
/// # Example
///

View File

@ -6,22 +6,38 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The Skew Normal distribution.
//! The Skew Normal distribution `SN(ξ, ω, α)`.
use crate::{Distribution, StandardNormal};
use core::fmt;
use num_traits::Float;
use rand::Rng;
/// The [skew normal distribution] `SN(location, scale, shape)`.
/// The [skew normal distribution](https://en.wikipedia.org/wiki/Skew_normal_distribution) `SN(ξ, ω, α)`.
///
/// The skew normal distribution is a generalization of the
/// [`Normal`] distribution to allow for non-zero skewness.
/// [`Normal`](crate::Normal) distribution to allow for non-zero skewness.
/// It has location parameter `ξ` (`xi`), scale parameter `ω` (`omega`),
/// and shape parameter `α` (`alpha`).
///
/// The `ξ` and `ω` parameters correspond to the mean `μ` and standard
/// deviation `σ` of the normal distribution, respectively.
/// The `α` parameter controls the skewness.
///
/// # Density function
///
/// It has the density function, for `scale > 0`,
/// `f(x) = 2 / scale * phi((x - location) / scale) * Phi(alpha * (x - location) / scale)`
/// where `phi` and `Phi` are the density and distribution of a standard normal variable.
///
/// # Plot
///
/// The following plot shows the skew normal distribution with `location = 0`, `scale = 1`
/// (corresponding to the [`standard normal distribution`](crate::StandardNormal)), and
/// various values of `shape`.
///
/// ![Skew normal distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/skew_normal.svg)
///
/// # Example
///
/// ```

View File

@ -12,7 +12,7 @@ use core::fmt;
use num_traits::Float;
use rand::Rng;
/// The triangular distribution.
/// The [triangular distribution](https://en.wikipedia.org/wiki/Triangular_distribution) `Triangular(min, max, mode)`.
///
/// A continuous probability distribution parameterised by a range, and a mode
/// (most likely value) within that range.
@ -20,6 +20,13 @@ use rand::Rng;
/// The probability density function is triangular. For a similar distribution
/// with a smooth PDF, see the [`Pert`] distribution.
///
/// # Plot
///
/// The following plot shows the triangular distribution with various values of
/// `min`, `max`, and `mode`.
///
/// ![Triangular distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/triangular.svg)
///
/// # Example
///
/// ```rust

View File

@ -10,11 +10,22 @@ use crate::{uniform::SampleUniform, Distribution, Uniform};
use num_traits::Float;
use rand::Rng;
/// Samples uniformly from the unit ball (surface and interior) in three
/// dimensions.
/// Samples uniformly from the volume of the unit ball in three dimensions.
///
/// Implemented via rejection sampling.
///
/// For a distribution that samples only from the surface of the unit ball,
/// see [`UnitSphere`](crate::UnitSphere).
///
/// For a similar distribution in two dimensions, see [`UnitDisc`](crate::UnitDisc).
///
/// # Plot
///
/// The following plot shows the unit ball in three dimensions.
/// This distribution samples individual points from the entire volume
/// of the ball.
///
/// ![Unit ball](https://raw.githubusercontent.com/rust-random/charts/main/charts/unit_ball.svg)
///
/// # Example
///

View File

@ -10,10 +10,20 @@ use crate::{uniform::SampleUniform, Distribution, Uniform};
use num_traits::Float;
use rand::Rng;
/// Samples uniformly from the edge of the unit circle in two dimensions.
/// Samples uniformly from the circumference of the unit circle in two dimensions.
///
/// Implemented via a method by von Neumann[^1].
///
/// For a distribution that also samples from the interior of the unit circle,
/// see [`UnitDisc`](crate::UnitDisc).
///
/// For a similar distribution in three dimensions, see [`UnitSphere`](crate::UnitSphere).
///
/// # Plot
///
/// The following plot shows the unit circle.
///
/// ![Unit circle](https://raw.githubusercontent.com/rust-random/charts/main/charts/unit_circle.svg)
///
/// # Example
///

View File

@ -14,6 +14,17 @@ use rand::Rng;
///
/// Implemented via rejection sampling.
///
/// For a distribution that samples only from the circumference of the unit disc,
/// see [`UnitCircle`](crate::UnitCircle).
///
/// For a similar distribution in three dimensions, see [`UnitBall`](crate::UnitBall).
///
/// # Plot
///
/// The following plot shows the unit disc.
/// This distribution samples individual points from the entire area of the disc.
///
/// ![Unit disc](https://raw.githubusercontent.com/rust-random/charts/main/charts/unit_disc.svg)
///
/// # Example
///

View File

@ -14,6 +14,18 @@ use rand::Rng;
///
/// Implemented via a method by Marsaglia[^1].
///
/// For a distribution that also samples from the interior of the sphere,
/// see [`UnitBall`](crate::UnitBall).
///
/// For a similar distribution in two dimensions, see [`UnitCircle`](crate::UnitCircle).
///
/// # Plot
///
/// The following plot shows the unit sphere as a wireframe.
/// The wireframe is meant to illustrate that this distribution samples
/// from the surface of the sphere only, not from the interior.
///
/// ![Unit sphere](https://raw.githubusercontent.com/rust-random/charts/main/charts/unit_sphere.svg)
///
/// # Example
///

View File

@ -6,14 +6,24 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The Weibull distribution.
//! The Weibull distribution `Weibull(λ, k)`
use crate::{Distribution, OpenClosed01};
use core::fmt;
use num_traits::Float;
use rand::Rng;
/// Samples floating-point numbers according to the Weibull distribution
/// The [Weibull distribution](https://en.wikipedia.org/wiki/Weibull_distribution) `Weibull(λ, k)`.
///
/// This is a family of continuous probability distributions with
/// scale parameter `λ` (`lambda`) and shape parameter `k`. It is used
/// to model reliability data, life data, and accelerated life testing data.
///
/// # Plot
///
/// The following plot shows the Weibull distribution with various values of `λ` and `k`.
///
/// ![Weibull distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/weibull.svg)
///
/// # Example
/// ```

View File

@ -13,14 +13,23 @@ use core::fmt;
use num_traits::Float;
use rand::{distributions::OpenClosed01, Rng};
/// Samples integers according to the [zeta distribution].
/// The [Zeta distribution](https://en.wikipedia.org/wiki/Zeta_distribution) `Zeta(a)`.
///
/// The zeta distribution is a limit of the [`Zipf`] distribution. Sometimes it
/// is called one of the following: discrete Pareto, Riemann-Zeta, Zipf, or
/// ZipfEstoup distribution.
/// The [Zeta distribution](https://en.wikipedia.org/wiki/Zeta_distribution)
/// is a discrete probability distribution with parameter `a`.
/// It is a special case of the [`Zipf`] distribution with `n = ∞`.
/// It is also known as the discrete Pareto, Riemann-Zeta, Zipf, or ZipfEstoup distribution.
///
/// It has the density function `f(k) = k^(-a) / C(a)` for `k >= 1`, where `a`
/// is the parameter and `C(a)` is the Riemann zeta function.
/// # Density function
///
/// `f(k) = k^(-a) / ζ(a)` for `k >= 1`, where `ζ` is the
/// [Riemann zeta function](https://en.wikipedia.org/wiki/Riemann_zeta_function).
///
/// # Plot
///
/// The following plot illustrates the zeta distribution for various values of `a`.
///
/// ![Zeta distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/zeta.svg)
///
/// # Example
/// ```
@ -31,7 +40,7 @@ use rand::{distributions::OpenClosed01, Rng};
/// println!("{}", val);
/// ```
///
/// # Remarks
/// # Notes
///
/// The zeta distribution has no upper limit. Sampled values may be infinite.
/// In particular, a value of infinity might be returned for the following
@ -41,11 +50,9 @@ use rand::{distributions::OpenClosed01, Rng};
///
/// # Implementation details
///
/// We are using the algorithm from [Non-Uniform Random Variate Generation],
/// We are using the algorithm from
/// [Non-Uniform Random Variate Generation](https://doi.org/10.1007/978-1-4613-8643-8),
/// Section 6.1, page 551.
///
/// [zeta distribution]: https://en.wikipedia.org/wiki/Zeta_distribution
/// [Non-Uniform Random Variate Generation]: https://doi.org/10.1007/978-1-4613-8643-8
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Zeta<F>
where
@ -125,15 +132,22 @@ where
}
}
/// Samples integers according to the Zipf distribution.
/// The Zipf (Zipfian) distribution `Zipf(n, s)`.
///
/// The samples follow Zipf's law: The frequency of each sample from a finite
/// set of size `n` is inversely proportional to a power of its frequency rank
/// (with exponent `s`).
/// The samples follow [Zipf's law](https://en.wikipedia.org/wiki/Zipf%27s_law):
/// The frequency of each sample from a finite set of size `n` is inversely
/// proportional to a power of its frequency rank (with exponent `s`).
///
/// For large `n`, this converges to the [`Zeta`] distribution.
/// For large `n`, this converges to the [`Zeta`](crate::Zeta) distribution.
///
/// For `s = 0`, this becomes a uniform distribution.
/// For `s = 0`, this becomes a [`uniform`](crate::Uniform) distribution.
///
/// # Plot
///
/// The following plot illustrates the Zipf distribution for `n = 10` and
/// various values of `s`.
///
/// ![Zipf distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/zipf.svg)
///
/// # Example
/// ```

View File

@ -6,7 +6,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The Bernoulli distribution.
//! The Bernoulli distribution `Bernoulli(p)`.
use crate::distributions::Distribution;
use crate::Rng;
@ -15,9 +15,18 @@ use core::fmt;
#[cfg(feature = "serde1")]
use serde::{Deserialize, Serialize};
/// The Bernoulli distribution.
/// The [Bernoulli distribution](https://en.wikipedia.org/wiki/Bernoulli_distribution) `Bernoulli(p)`.
///
/// This is a special case of the Binomial distribution where `n = 1`.
/// This distribution describes a single boolean random variable, which is true
/// with probability `p` and false with probability `1 - p`.
/// It is a special case of the Binomial distribution with `n = 1`.
///
/// # Plot
///
/// The following plot shows the Bernoulli distribution with `p = 0.1`,
/// `p = 0.5`, and `p = 0.9`.
///
/// ![Bernoulli distribution](https://raw.githubusercontent.com/rust-random/charts/main/charts/bernoulli.svg)
///
/// # Example
///

View File

@ -20,7 +20,7 @@ use core::fmt::Debug;
#[cfg(feature = "serde1")]
use serde::{Deserialize, Serialize};
/// A distribution using weighted sampling of discrete items
/// A distribution using weighted sampling of discrete items.
///
/// Sampling a `WeightedIndex` distribution returns the index of a randomly
/// selected element from the iterator used when the `WeightedIndex` was