Skip to content

Commit 9bdd3df

Browse files
authored
Merge pull request #433 from rust-lang-nursery/distributions
Distributions documentation
2 parents 2c3d34d + 161f31f commit 9bdd3df

File tree

3 files changed

+413
-162
lines changed

3 files changed

+413
-162
lines changed

src/distributions/mod.rs

Lines changed: 171 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,50 +8,188 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//! Sampling from random distributions.
12-
//!
13-
//! Distributions are stateless (i.e. immutable) objects controlling the
14-
//! production of values of some type `T` from a presumed uniform randomness
15-
//! source. These objects may have internal parameters set at contruction time
16-
//! (e.g. [`Uniform`], which has configurable bounds) or may have no internal
17-
//! parameters (e.g. [`Standard`]).
18-
//!
19-
//! All distributions support the [`Distribution`] trait, and support usage
20-
//! via `distr.sample(&mut rng)` as well as via `rng.sample(distr)`.
21-
//!
11+
//! Generating random samples from probability distributions.
12+
//!
13+
//! This module is the home of the [`Distribution`] trait and several of its
14+
//! implementations. It is the workhorse behind some of the convenient
15+
//! functionality of the [`Rng`] trait, including [`gen`], [`gen_range`] and
16+
//! of course [`sample`].
17+
//!
18+
//! Abstractly, a [probability distribution] describes the probability of
19+
//! occurance of each value in its sample space.
20+
//!
21+
//! More concretely, an implementation of `Distribution<T>` for type `X` is an
22+
//! algorithm for choosing values from the sample space (a subset of `T`)
23+
//! according to the distribution `X` represents, using an external source of
24+
//! randomness (an RNG supplied to the `sample` function).
25+
//!
26+
//! A type `X` may implement `Distribution<T>` for multiple types `T`.
27+
//! Any type implementing [`Distribution`] is stateless (i.e. immutable),
28+
//! but it may have internal parameters set at construction time (for example,
29+
//! [`Uniform`] allows specification of its sample space as a range within `T`).
30+
//!
31+
//!
32+
//! # The `Standard` distribution
33+
//!
34+
//! The [`Standard`] distribution is important to mention. This is the
35+
//! distribution used by [`Rng::gen()`] and represents the "default" way to
36+
//! produce a random value for many different types, including most primitive
37+
//! types, tuples, arrays, and a few derived types. See the documentation of
38+
//! [`Standard`] for more details.
39+
//!
40+
//! Implementing `Distribution<T>` for [`Standard`] for user types `T` makes it
41+
//! possible to generate type `T` with [`Rng::gen()`], and by extension also
42+
//! with the [`random()`] function.
43+
//!
44+
//!
45+
//! # Distribution to sample from a `Uniform` range
46+
//!
47+
//! The [`Uniform`] distribution is more flexible than [`Standard`], but also
48+
//! more specialised: it supports fewer target types, but allows the sample
49+
//! space to be specified as an arbitrary range within its target type `T`.
50+
//! Both [`Standard`] and [`Uniform`] are in some sense uniform distributions.
51+
//!
52+
//! Values may be sampled from this distribution using [`Rng::gen_range`] or
53+
//! by creating a distribution object with [`Uniform::new`],
54+
//! [`Uniform::new_inclusive`] or `From<Range>`. When the range limits are not
55+
//! known at compile time it is typically faster to reuse an existing
56+
//! distribution object than to call [`Rng::gen_range`].
57+
//!
58+
//! User types `T` may also implement `Distribution<T>` for [`Uniform`],
59+
//! although this is less straightforward than for [`Standard`] (see the
60+
//! documentation in the [`uniform` module]. Doing so enables generation of
61+
//! values of type `T` with [`Rng::gen_range`].
62+
//!
63+
//!
64+
//! # Other distributions
65+
//!
66+
//! There are surprisingly many ways to uniformly generate random floats. A
67+
//! range between 0 and 1 is standard, but the exact bounds (open vs closed)
68+
//! and accuracy differ. In addition to the [`Standard`] distribution Rand offers
69+
//! [`Open01`] and [`OpenClosed01`]. See [Floating point implementation] for
70+
//! more details.
71+
//!
72+
//! [`Alphanumeric`] is a simple distribution to sample random letters and
73+
//! numbers of the `char` type; in contrast [`Standard`] may sample any valid
74+
//! `char`.
75+
//!
76+
//!
77+
//! # Non-uniform probability distributions
78+
//!
79+
//! Rand currently provides the following probability distributions:
80+
//!
81+
//! - Related to real-valued quantities that grow linearly
82+
//! (e.g. errors, offsets):
83+
//! - [`Normal`] distribution, and [`StandardNormal`] as a primitive
84+
//! - Related to Bernoulli trials (yes/no events, with a given probability):
85+
//! - [`Binomial`] distribution
86+
//! - Related to positive real-valued quantities that grow exponentially
87+
//! (e.g. prices, incomes, populations):
88+
//! - [`LogNormal`] distribution
89+
//! - Related to rate of occurrance of indenpendant events:
90+
//! with a given rate)
91+
//! - [`Poisson`] distribution
92+
//! - [`Exp`]onential distribution, and [`Exp1`] as a primitive
93+
//! - Gamma and derived distributions:
94+
//! - [`Gamma`] distribution
95+
//! - [`ChiSquared`] distribution
96+
//! - [`StudentT`] distribution
97+
//! - [`FisherF`] distribution
98+
//!
99+
//!
100+
//! # Examples
101+
//!
102+
//! Sampling from a distribution:
103+
//!
104+
//! ```
105+
//! use rand::{thread_rng, Rng};
106+
//! use rand::distributions::Exp;
107+
//!
108+
//! let exp = Exp::new(2.0);
109+
//! let v = thread_rng().sample(exp);
110+
//! println!("{} is from an Exp(2) distribution", v);
111+
//! ```
112+
//!
113+
//! Implementing the [`Standard`] distribution for a user type:
114+
//!
115+
//! ```
116+
//! # #![allow(dead_code)]
117+
//! use rand::Rng;
118+
//! use rand::distributions::{Distribution, Standard};
119+
//!
120+
//! struct MyF32 {
121+
//! x: f32,
122+
//! }
123+
//!
124+
//! impl Distribution<MyF32> for Standard {
125+
//! fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> MyF32 {
126+
//! MyF32 { x: rng.gen() }
127+
//! }
128+
//! }
129+
//! ```
130+
//!
131+
//!
132+
//! [probability distribution]: https://en.wikipedia.org/wiki/Probability_distribution
22133
//! [`Distribution`]: trait.Distribution.html
23-
//! [`Uniform`]: uniform/struct.Uniform.html
134+
//! [`gen_range`]: ../trait.Rng.html#method.gen_range
135+
//! [`gen`]: ../trait.Rng.html#method.gen
136+
//! [`sample`]: ../trait.Rng.html#method.sample
137+
//! [`new_inclusive`]: struct.Uniform.html#method.new_inclusive
138+
//! [`random()`]: ../fn.random.html
139+
//! [`Rng::gen_bool`]: ../trait.Rng.html#method.gen_bool
140+
//! [`Rng::gen_range`]: ../trait.Rng.html#method.gen_range
141+
//! [`Rng::gen()`]: ../trait.Rng.html#method.gen
142+
//! [`Rng`]: ../trait.Rng.html
143+
//! [`sample_iter`]: trait.Distribution.html#method.sample_iter
144+
//! [`uniform` module]: uniform/index.html
145+
//! [Floating point implementation]: struct.Standard.html#floating-point-implementation
146+
// distributions
147+
//! [`Alphanumeric`]: struct.Alphanumeric.html
148+
//! [`Binomial`]: struct.Binomial.html
149+
//! [`ChiSquared`]: struct.ChiSquared.html
150+
//! [`Exp`]: struct.Exp.html
151+
//! [`Exp1`]: struct.Exp1.html
152+
//! [`FisherF`]: struct.FisherF.html
153+
//! [`Gamma`]: struct.Gamma.html
154+
//! [`LogNormal`]: struct.LogNormal.html
155+
//! [`Normal`]: struct.Normal.html
156+
//! [`Open01`]: struct.Open01.html
157+
//! [`OpenClosed01`]: struct.OpenClosed01.html
158+
//! [`Poisson`]: struct.Poisson.html
24159
//! [`Standard`]: struct.Standard.html
160+
//! [`StandardNormal`]: struct.StandardNormal.html
161+
//! [`StudentT`]: struct.StudentT.html
162+
//! [`Uniform`]: struct.Uniform.html
25163
26164
use Rng;
27165

28-
pub use self::other::Alphanumeric;
29-
pub use self::uniform::Uniform;
30-
pub use self::float::{OpenClosed01, Open01};
166+
#[doc(inline)] pub use self::other::Alphanumeric;
167+
#[doc(inline)] pub use self::uniform::Uniform;
168+
#[doc(inline)] pub use self::float::{OpenClosed01, Open01};
31169
#[deprecated(since="0.5.0", note="use Uniform instead")]
32170
pub use self::uniform::Uniform as Range;
33171
#[cfg(feature="std")]
34-
pub use self::gamma::{Gamma, ChiSquared, FisherF, StudentT};
172+
#[doc(inline)] pub use self::gamma::{Gamma, ChiSquared, FisherF, StudentT};
35173
#[cfg(feature="std")]
36-
pub use self::normal::{Normal, LogNormal, StandardNormal};
174+
#[doc(inline)] pub use self::normal::{Normal, LogNormal, StandardNormal};
37175
#[cfg(feature="std")]
38-
pub use self::exponential::{Exp, Exp1};
176+
#[doc(inline)] pub use self::exponential::{Exp, Exp1};
39177
#[cfg(feature = "std")]
40-
pub use self::poisson::Poisson;
178+
#[doc(inline)] pub use self::poisson::Poisson;
41179
#[cfg(feature = "std")]
42-
pub use self::binomial::Binomial;
180+
#[doc(inline)] pub use self::binomial::Binomial;
43181

44182
pub mod uniform;
45183
#[cfg(feature="std")]
46-
pub mod gamma;
184+
#[doc(hidden)] pub mod gamma;
47185
#[cfg(feature="std")]
48-
pub mod normal;
186+
#[doc(hidden)] pub mod normal;
49187
#[cfg(feature="std")]
50-
pub mod exponential;
188+
#[doc(hidden)] pub mod exponential;
51189
#[cfg(feature = "std")]
52-
pub mod poisson;
190+
#[doc(hidden)] pub mod poisson;
53191
#[cfg(feature = "std")]
54-
pub mod binomial;
192+
#[doc(hidden)] pub mod binomial;
55193

56194
mod float;
57195
mod integer;
@@ -148,6 +286,11 @@ mod impls {
148286

149287
/// Types (distributions) that can be used to create a random instance of `T`.
150288
///
289+
/// It is possible to sample from a distribution through both the
290+
/// [`Distribution`] and [`Rng`] traits, via `distr.sample(&mut rng)` and
291+
/// `rng.sample(distr)`. They also both offer the [`sample_iter`] method, which
292+
/// produces an iterator that samples from the distribution.
293+
///
151294
/// All implementations are expected to be immutable; this has the significant
152295
/// advantage of not needing to consider thread safety, and for most
153296
/// distributions efficient state-less sampling algorithms are available.
@@ -160,7 +303,7 @@ pub trait Distribution<T> {
160303
///
161304
/// # Example
162305
///
163-
/// ```rust
306+
/// ```
164307
/// use rand::thread_rng;
165308
/// use rand::distributions::{Distribution, Alphanumeric, Uniform, Standard};
166309
///
@@ -256,7 +399,7 @@ impl<'a, D, R, T> Iterator for DistIter<'a, D, R, T>
256399
/// probability 0.5; otherwise generates a random `x: T` and returns `Some(x)`.
257400
///
258401
/// # Example
259-
/// ```rust
402+
/// ```
260403
/// use rand::{FromEntropy, SmallRng, Rng};
261404
/// use rand::distributions::Standard;
262405
///
@@ -314,7 +457,7 @@ pub struct Weighted<T> {
314457
///
315458
/// # Example
316459
///
317-
/// ```rust
460+
/// ```
318461
/// use rand::distributions::{Weighted, WeightedChoice, Distribution};
319462
///
320463
/// let mut items = vec!(Weighted { weight: 2, item: 'a' },

0 commit comments

Comments
 (0)