12
12
use rand:: Rng ;
13
13
use crate :: { ziggurat_tables, Distribution } ;
14
14
use crate :: utils:: ziggurat;
15
+ use num_traits:: Float ;
15
16
16
17
/// Samples floating-point numbers according to the exponential distribution,
17
18
/// with rate parameter `λ = 1`. This is equivalent to `Exp::new(1.0)` or
@@ -39,6 +40,15 @@ use crate::utils::ziggurat;
39
40
#[ derive( Clone , Copy , Debug ) ]
40
41
pub struct Exp1 ;
41
42
43
+ impl Distribution < f32 > for Exp1 {
44
+ #[ inline]
45
+ fn sample < R : Rng + ?Sized > ( & self , rng : & mut R ) -> f32 {
46
+ // TODO: use optimal 32-bit implementation
47
+ let x: f64 = self . sample ( rng) ;
48
+ x as f32
49
+ }
50
+ }
51
+
42
52
// This could be done via `-rng.gen::<f64>().ln()` but that is slower.
43
53
impl Distribution < f64 > for Exp1 {
44
54
#[ inline]
@@ -76,9 +86,9 @@ impl Distribution<f64> for Exp1 {
76
86
/// println!("{} is from a Exp(2) distribution", v);
77
87
/// ```
78
88
#[ derive( Clone , Copy , Debug ) ]
79
- pub struct Exp {
89
+ pub struct Exp < N > {
80
90
/// `lambda` stored as `1/lambda`, since this is what we scale by.
81
- lambda_inverse : f64
91
+ lambda_inverse : N
82
92
}
83
93
84
94
/// Error type returned from `Exp::new`.
@@ -88,22 +98,25 @@ pub enum Error {
88
98
LambdaTooSmall ,
89
99
}
90
100
91
- impl Exp {
101
+ impl < N : Float > Exp < N >
102
+ where Exp1 : Distribution < N >
103
+ {
92
104
/// Construct a new `Exp` with the given shape parameter
93
105
/// `lambda`.
94
106
#[ inline]
95
- pub fn new ( lambda : f64 ) -> Result < Exp , Error > {
96
- if !( lambda > 0.0 ) {
107
+ pub fn new ( lambda : N ) -> Result < Exp < N > , Error > {
108
+ if !( lambda > N :: zero ( ) ) {
97
109
return Err ( Error :: LambdaTooSmall ) ;
98
110
}
99
- Ok ( Exp { lambda_inverse : 1.0 / lambda } )
111
+ Ok ( Exp { lambda_inverse : N :: one ( ) / lambda } )
100
112
}
101
113
}
102
114
103
- impl Distribution < f64 > for Exp {
104
- fn sample < R : Rng + ?Sized > ( & self , rng : & mut R ) -> f64 {
105
- let n: f64 = rng. sample ( Exp1 ) ;
106
- n * self . lambda_inverse
115
+ impl < N : Float > Distribution < N > for Exp < N >
116
+ where Exp1 : Distribution < N >
117
+ {
118
+ fn sample < R : Rng + ?Sized > ( & self , rng : & mut R ) -> N {
119
+ rng. sample ( Exp1 ) * self . lambda_inverse
107
120
}
108
121
}
109
122
0 commit comments