@@ -225,6 +225,55 @@ impl IndependentSample<f64> for ChiSquared {
225225 }
226226}
227227
228+ /// The Fisher F distribution `F(m, n)`.
229+ ///
230+ /// This distribution is equivalent to the ratio of two normalised
231+ /// chi-squared distributions, that is, `F(m,n) = (χ²(m)/m) /
232+ /// (χ²(n)/n)`.
233+ ///
234+ /// # Example
235+ ///
236+ /// ```rust
237+ /// use std::rand;
238+ /// use std::rand::distributions::{FisherF, IndependentSample};
239+ ///
240+ /// fn main() {
241+ /// let f = FisherF::new(2.0, 32.0);
242+ /// let v = f.ind_sample(&mut rand::task_rng());
243+ /// println!("{} is from an F(2, 32) distribution", v)
244+ /// }
245+ /// ```
246+ pub struct FisherF {
247+ priv numer : ChiSquared ,
248+ priv denom : ChiSquared ,
249+ // denom_dof / numer_dof so that this can just be a straight
250+ // multiplication, rather than a division.
251+ priv dof_ratio : f64 ,
252+ }
253+
254+ impl FisherF {
255+ /// Create a new `FisherF` distribution, with the given
256+ /// parameter. Fails if either `m` or `n` are not positive.
257+ pub fn new ( m : f64 , n : f64 ) -> FisherF {
258+ assert ! ( m > 0.0 , "FisherF::new called with `m < 0`" ) ;
259+ assert ! ( n > 0.0 , "FisherF::new called with `n < 0`" ) ;
260+
261+ FisherF {
262+ numer : ChiSquared :: new ( m) ,
263+ denom : ChiSquared :: new ( n) ,
264+ dof_ratio : n / m
265+ }
266+ }
267+ }
268+ impl Sample < f64 > for FisherF {
269+ fn sample < R : Rng > ( & mut self , rng : & mut R ) -> f64 { self . ind_sample ( rng) }
270+ }
271+ impl IndependentSample < f64 > for FisherF {
272+ fn ind_sample < R : Rng > ( & self , rng : & mut R ) -> f64 {
273+ self . numer . ind_sample ( rng) / self . denom . ind_sample ( rng) * self . dof_ratio
274+ }
275+ }
276+
228277#[ cfg( test) ]
229278mod test {
230279 use rand:: * ;
@@ -264,6 +313,16 @@ mod test {
264313 fn test_log_normal_invalid_dof ( ) {
265314 ChiSquared :: new ( -1.0 ) ;
266315 }
316+
317+ #[ test]
318+ fn test_f ( ) {
319+ let mut f = FisherF :: new ( 2.0 , 32.0 ) ;
320+ let mut rng = task_rng ( ) ;
321+ for _ in range ( 0 , 1000 ) {
322+ f. sample ( & mut rng) ;
323+ f. ind_sample ( & mut rng) ;
324+ }
325+ }
267326}
268327
269328#[ cfg( test) ]
0 commit comments