8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- //! Sampling from random distributions
11
+ /*!
12
+ Sampling from random distributions.
12
13
13
- // Some implementations use the Ziggurat method
14
- // https://en.wikipedia.org/wiki/Ziggurat_algorithm
15
- //
16
- // The version used here is ZIGNOR [Doornik 2005, "An Improved
17
- // Ziggurat Method to Generate Normal Random Samples"] which is slower
18
- // (about double, it generates an extra random number) than the
19
- // canonical version [Marsaglia & Tsang 2000, "The Ziggurat Method for
20
- // Generating Random Variables"], but more robust. If one wanted, one
21
- // could implement VIZIGNOR the ZIGNOR paper for more speed.
14
+ This is a generalization of `Rand` to allow parameters to control the
15
+ exact properties of the generated values, e.g. the mean and standard
16
+ deviation of a normal distribution. The `Sample` trait is the most
17
+ general, and allows for generating values that change some state
18
+ internally. The `IndependentSample` trait is for generating values
19
+ that do not need to record state.
20
+
21
+ */
22
22
23
23
use num;
24
24
use rand:: { Rng , Rand } ;
@@ -27,16 +27,18 @@ pub use self::range::Range;
27
27
28
28
pub mod range;
29
29
30
- /// Things that can be used to create a random instance of `Support`.
30
+ /// Types that can be used to create a random instance of `Support`.
31
31
pub trait Sample < Support > {
32
32
/// Generate a random value of `Support`, using `rng` as the
33
33
/// source of randomness.
34
34
fn sample < R : Rng > ( & mut self , rng : & mut R ) -> Support ;
35
35
}
36
36
37
- /// `Sample`s that do not require keeping track of state, so each
38
- /// sample is (statistically) independent of all others, assuming the
39
- /// `Rng` used has this property.
37
+ /// `Sample`s that do not require keeping track of state.
38
+ ///
39
+ /// Since no state is recored, each sample is (statistically)
40
+ /// independent of all others, assuming the `Rng` used has this
41
+ /// property.
40
42
// XXX maybe having this separate is overkill (the only reason is to
41
43
// take &self rather than &mut self)? or maybe this should be the
42
44
// trait called `Sample` and the other should be `DependentSample`.
@@ -91,13 +93,19 @@ fn ziggurat<R:Rng>(rng: &mut R,
91
93
}
92
94
}
93
95
94
- /// A wrapper around an `f64` to generate N(0, 1) random numbers (a.k.a. a
95
- /// standard normal, or Gaussian). Multiplying the generated values by the
96
- /// desired standard deviation `sigma` then adding the desired mean `mu` will
97
- /// give N(mu, sigma^2) distributed random numbers.
96
+ /// A wrapper around an `f64` to generate N(0, 1) random numbers
97
+ /// (a.k.a. a standard normal, or Gaussian).
98
98
///
99
- /// Note that this has to be unwrapped before use as an `f64` (using either
100
- /// `*` or `cast::transmute` is safe).
99
+ /// See `Normal` for the general normal distribution. That this has to
100
+ /// be unwrapped before use as an `f64` (using either `*` or
101
+ /// `cast::transmute` is safe).
102
+ ///
103
+ /// Implemented via the ZIGNOR variant[1] of the Ziggurat method.
104
+ ///
105
+ /// [1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
106
+ /// Generate Normal Random
107
+ /// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
108
+ /// College, Oxford
101
109
pub struct StandardNormal ( f64 ) ;
102
110
103
111
impl Rand for StandardNormal {
@@ -135,8 +143,10 @@ impl Rand for StandardNormal {
135
143
}
136
144
}
137
145
138
- /// The `N(mean, std_dev**2)` distribution, i.e. samples from a normal
139
- /// distribution with mean `mean` and standard deviation `std_dev`.
146
+ /// The normal distribution `N(mean, std_dev**2)`.
147
+ ///
148
+ /// This uses the ZIGNOR variant of the Ziggurat method, see
149
+ /// `StandardNormal` for more details.
140
150
///
141
151
/// # Example
142
152
///
@@ -175,12 +185,20 @@ impl IndependentSample<f64> for Normal {
175
185
}
176
186
}
177
187
178
- /// A wrapper around an `f64` to generate Exp(1) random numbers. Dividing by
179
- /// the desired rate `lambda` will give Exp(lambda) distributed random
180
- /// numbers.
188
+ /// A wrapper around an `f64` to generate Exp(1) random numbers.
181
189
///
182
- /// Note that this has to be unwrapped before use as an `f64` (using either
190
+ /// See `Exp` for the general exponential distribution.Note that this
191
+ // has to be unwrapped before use as an `f64` (using either
183
192
/// `*` or `cast::transmute` is safe).
193
+ ///
194
+ /// Implemented via the ZIGNOR variant[1] of the Ziggurat method. The
195
+ /// exact description in the paper was adjusted to use tables for the
196
+ /// exponential distribution rather than normal.
197
+ ///
198
+ /// [1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
199
+ /// Generate Normal Random
200
+ /// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
201
+ /// College, Oxford
184
202
pub struct Exp1 ( f64 ) ;
185
203
186
204
// This could be done via `-rng.gen::<f64>().ln()` but that is slower.
@@ -203,8 +221,7 @@ impl Rand for Exp1 {
203
221
}
204
222
}
205
223
206
- /// The `Exp(lambda)` distribution; i.e. samples from the exponential
207
- /// distribution with rate parameter `lambda`.
224
+ /// The exponential distribution `Exp(lambda)`.
208
225
///
209
226
/// This distribution has density function: `f(x) = lambda *
210
227
/// exp(-lambda * x)` for `x > 0`.
0 commit comments