pub struct F { /* private fields */ }Expand description
§The F Distribution
§Description:
Density, distribution function, quantile function and random generation for the F distribution with ‘df1’ and ‘df2’ degrees of freedom (and optional non-centrality parameter ‘ncp’).
§Arguments:
- df1, df2: degrees of freedom. ‘Inf’ is allowed.
- ncp: non-centrality parameter. If omitted the central F is assumed.
§Details:
The F distribution with ‘df1 =’ n1 and ‘df2 =’ n2 degrees of freedom has density
$f(x) = \frac{\Gamma(\frac{n1 + n2}{2})}{\Gamma(\frac{n1}{2}) \Gamma(\frac{n2}{2})} (\frac{n1}{n2})^{\frac{n1}{2}} x^{\frac{n1}{2} - 1} (1 + \frac{n1}{n2} x)^{-\frac{n1 + n2}{2}}$
for $x > 0$.
It is the distribution of the ratio of the mean squares of n1 and n2 independent standard normals, and hence of the ratio of two independent chi-squared variates each divided by its degrees of freedom. Since the ratio of a normal and the root mean-square of m independent normals has a Student’s t_m distribution, the square of a t_m variate has a F distribution on 1 and m degrees of freedom.
The non-central F distribution is again the ratio of mean squares of independent normals of unit variance, but those in the numerator are allowed to have non-zero means and ‘ncp’ is the sum of squares of the means. See Chisquare for further details on non-central distributions.
§Value:
‘df’ gives the density, ‘pf’ gives the distribution function ‘qf’ gives the quantile function, and ‘rf’ generates random deviates.
Invalid arguments will result in return value ‘NaN’, with a warning.
The length of the result is determined by ‘n’ for ‘rf’, and is the maximum of the lengths of the numerical arguments for the other functions.
The numerical arguments other than ‘n’ are recycled to the length of the result. Only the first elements of the logical arguments are used.
§Density Plot
let f = FBuilder::new().build();
let x = <[f64]>::sequence(-0.5, 4.0, 1000);
let y = x
.iter()
.map(|x| f.density(x).unwrap())
.collect::<Vec<_>>();
let root = SVGBackend::new("density.svg", (1024, 768)).into_drawing_area();
Plot::new()
.with_options(PlotOptions {
x_axis_label: "x".to_string(),
y_axis_label: "density".to_string(),
..Default::default()
})
.with_plottable(Line {
x,
y,
color: BLACK,
..Default::default()
})
.plot(&root)
.unwrap();§Note:
Supplying ‘ncp = 0’ uses the algorithm for the non-central distribution, which is not the same algorithm used if ‘ncp’ is omitted. This is to give consistent behaviour in extreme cases with values of ‘ncp’ very near zero.
The code for non-zero ‘ncp’ is principally intended to be used for moderate values of ‘ncp’: it will not be highly accurate, especially in the tails, for large values.
§Source:
For the central case of ‘df’, computed via a binomial probability, code contributed by Catherine Loader (see ‘dbinom’); for the non-central case computed via ‘dbeta’, code contributed by Peter Ruckdeschel.
For ‘pf’, via ‘pbeta’ (or for large ‘df2’, via ‘pchisq’).
For ‘qf’, via ‘qchisq’ for large ‘df2’, else via ‘qbeta’.
§References:
Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New S Language. Wadsworth & Brooks/Cole.
Johnson, N. L., Kotz, S. and Balakrishnan, N. (1995) Continuous Univariate Distributions, volume 2, chapters 27 and 30. Wiley, New York.
§See Also:
Distributions for other standard distributions, including ‘dchisq’ for chi-squared and ‘dt’ for Student’s t distributions.
§Examples:
Lower Tails
let x = <[f64]>::sequence(0.001, 5.0, 100);
let nu = 4.0;
let t = TBuilder::new().with_df(nu).unwrap().build();
let f = FBuilder::new().with_df1(1).with_df2(nu).build();
let r1 = x
.iter()
.map(|x| 2.0 * t.probability(x, true).unwrap() - 1.0)
.collect::<Vec<_>>();
let r2 = x
.iter()
.map(|x| f.probability(x.powi(2), true).unwrap())
.collect::<Vec<_>>();
println!("{r1:?}");
println!("{r2:?}");Upper Tails
let x = <[f64]>::sequence(0.001, 5.0, 100);
let nu = 4.0;
let t = TBuilder::new().with_df(nu).unwrap().build();
let f = FBuilder::new().with_df1(1).with_df2(nu).build();
let r1 = x
.iter()
.map(|x| 2.0 * t.probability(x, false).unwrap())
.collect::<Vec<_>>();
let r2 = x
.iter()
.map(|x| f.probability(x.powi(2), false).unwrap())
.collect::<Vec<_>>();
println!("{r1:?}");
println!("{r2:?}");The density of the square of a $t_m$ is $2*\frac{{t-density}(x, m)}{2*x}$
Check this is the same as the density of $F_{1,m}$
let x = <[f64]>::sequence(0.001, 5.0, 100);
let nu = 5.0;
let t = TBuilder::new().with_df(nu).unwrap().build();
let f = FBuilder::new().with_df1(1).with_df2(nu).build();
let r1 = x
.iter()
.map(|x| t.density(x).unwrap() / x)
.collect::<Vec<_>>();
let r2 = x
.iter()
.map(|x| f.density(x.powi(2)).unwrap())
.collect::<Vec<_>>();
println!("{r1:?}");
println!("{r2:?}");Identity: qf(2*p - 1, 1, df) == qt(p, df)^2 for p >= 1/2
use r2rs_base::traits::{QuantileType, StatisticalSlice};
use r2rs_nmath::{
distribution::{FBuilder, TBuilder},
traits::Distribution,
};
use strafe_type::FloatConstraint;
let p = <[f64]>::sequence(0.5, 0.99, 50);
let df = 10.0;
let rel_err = |x: &[f64], y: &[f64]| {
let mean = x
.iter()
.chain(y.iter())
.map(|f| f.abs())
.collect::<Vec<_>>()
.mean();
x.iter()
.zip(y.iter())
.map(|(x, y)| if x == y { 0.0 } else { (x - y).abs() / mean })
.collect::<Vec<_>>()
};
let t = TBuilder::new().with_df(df).unwrap().build();
let f = FBuilder::new().with_df1(1).with_df2(df).build();
let r1 = p
.iter()
.map(|p| t.quantile(p, true).unwrap().powi(2))
.collect::<Vec<_>>();
let r2 = p
.iter()
.map(|p| f.quantile(2.0 * p - 1.0, true).unwrap())
.collect::<Vec<_>>();
let error = rel_err(&r1, &r2).quantile(&[0.9], QuantileType::S);
println!("{error:?}");Trait Implementations§
Source§impl Distribution for F
impl Distribution for F
Source§fn log_density<R: Into<Real64>>(&self, x: R) -> Real64
fn log_density<R: Into<Real64>>(&self, x: R) -> Real64
Source§fn probability<R: Into<Real64>>(&self, q: R, lower_tail: bool) -> Probability64
fn probability<R: Into<Real64>>(&self, q: R, lower_tail: bool) -> Probability64
Source§fn log_probability<R: Into<Real64>>(
&self,
q: R,
lower_tail: bool,
) -> LogProbability64
fn log_probability<R: Into<Real64>>( &self, q: R, lower_tail: bool, ) -> LogProbability64
Source§fn quantile<P: Into<Probability64>>(&self, p: P, lower_tail: bool) -> Real64
fn quantile<P: Into<Probability64>>(&self, p: P, lower_tail: bool) -> Real64
Source§fn log_quantile<LP: Into<LogProbability64>>(
&self,
p: LP,
lower_tail: bool,
) -> Real64
fn log_quantile<LP: Into<LogProbability64>>( &self, p: LP, lower_tail: bool, ) -> Real64
Auto Trait Implementations§
impl Freeze for F
impl RefUnwindSafe for F
impl Send for F
impl Sync for F
impl Unpin for F
impl UnwindSafe for F
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.