F

Struct F 

Source
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

Source§

fn density<R: Into<Real64>>(&self, x: R) -> Real64

The density of the values at a given point
Source§

fn log_density<R: Into<Real64>>(&self, x: R) -> Real64

The logarithmic density of the values at a given point
Source§

fn probability<R: Into<Real64>>(&self, q: R, lower_tail: bool) -> Probability64

PDF; The probability that a value is found in a distribution (inverse of quantile)
Source§

fn log_probability<R: Into<Real64>>( &self, q: R, lower_tail: bool, ) -> LogProbability64

log(PDF); The logarithmic probability that a value is found in a distribution (inverse of quantile)
Source§

fn quantile<P: Into<Probability64>>(&self, p: P, lower_tail: bool) -> Real64

The value in the distribution that is associated with a probability (inverse of probability)
Source§

fn log_quantile<LP: Into<LogProbability64>>( &self, p: LP, lower_tail: bool, ) -> Real64

The logarithmic value in the distribution that is associated with a probability (inverse of probability)
Source§

fn random_sample<R: RNG>(&self, rng: &mut R) -> Real64

Generates a random sample from the distribution

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.