8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- //! The normal distribution .
11
+ //! The normal and derived distributions .
12
12
13
13
use rand:: { Rng , Rand , Open01 } ;
14
14
use rand:: distributions:: { ziggurat, ziggurat_tables, Sample , IndependentSample } ;
@@ -108,6 +108,46 @@ impl IndependentSample<f64> for Normal {
108
108
}
109
109
}
110
110
111
+
112
+ /// The log-normal distribution `ln N(mean, std_dev**2)`.
113
+ ///
114
+ /// If `X` is log-normal distributed, then `ln(X)` is `N(mean,
115
+ /// std_dev**2)` distributed.
116
+ ///
117
+ /// # Example
118
+ ///
119
+ /// ```rust
120
+ /// use std::rand;
121
+ /// use std::rand::distributions::{LogNormal, IndependentSample};
122
+ ///
123
+ /// fn main() {
124
+ /// // mean 2, standard deviation 3
125
+ /// let log_normal = LogNormal::new(2.0, 3.0);
126
+ /// let v = normal.ind_sample(&mut rand::task_rng());
127
+ /// println!("{} is from an ln N(2, 9) distribution", v)
128
+ /// }
129
+ /// ```
130
+ pub struct LogNormal {
131
+ priv norm : Normal
132
+ }
133
+
134
+ impl LogNormal {
135
+ /// Construct a new `LogNormal` distribution with the given mean
136
+ /// and standard deviation. Fails if `std_dev < 0`.
137
+ pub fn new ( mean : f64 , std_dev : f64 ) -> LogNormal {
138
+ assert ! ( std_dev >= 0.0 , "LogNormal::new called with `std_dev` < 0" ) ;
139
+ LogNormal { norm : Normal :: new ( mean, std_dev) }
140
+ }
141
+ }
142
+ impl Sample < f64 > for LogNormal {
143
+ fn sample < R : Rng > ( & mut self , rng : & mut R ) -> f64 { self . ind_sample ( rng) }
144
+ }
145
+ impl IndependentSample < f64 > for LogNormal {
146
+ fn ind_sample < R : Rng > ( & self , rng : & mut R ) -> f64 {
147
+ self . norm . ind_sample ( rng) . exp ( )
148
+ }
149
+ }
150
+
111
151
#[ cfg( test) ]
112
152
mod tests {
113
153
use rand:: * ;
@@ -129,6 +169,22 @@ mod tests {
129
169
fn test_normal_invalid_sd ( ) {
130
170
Normal :: new ( 10.0 , -1.0 ) ;
131
171
}
172
+
173
+
174
+ #[ test]
175
+ fn test_log_normal ( ) {
176
+ let mut lnorm = LogNormal :: new ( 10.0 , 10.0 ) ;
177
+ let mut rng = task_rng ( ) ;
178
+ for _ in range ( 0 , 1000 ) {
179
+ lnorm. sample ( & mut rng) ;
180
+ lnorm. ind_sample ( & mut rng) ;
181
+ }
182
+ }
183
+ #[ test]
184
+ #[ should_fail]
185
+ fn test_log_normal_invalid_sd ( ) {
186
+ LogNormal :: new ( 10.0 , -1.0 ) ;
187
+ }
132
188
}
133
189
134
190
#[ cfg( test) ]
0 commit comments