All Downloads are FREE. Search and download functionalities are using the official Maven repository.

math.stats.distribution.FisherF Maven / Gradle / Ivy

There is a newer version: 0.9.5
Show newest version
/*
 * Copyright 2013 SPZ
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package math.stats.distribution;

import math.rng.DefaultRng;
import math.rng.PseudoRandom;

/**
 * TODO
 * 

* https://en.wikipedia.org/wiki/F-distribution */ public class FisherF extends AbstractContinuousDistribution { private final int d1; // numerator DF private final int d2; // denominator DF private final Beta beta; public FisherF(final int numeratorDF, final int denominatorDF) { this(DefaultRng.newPseudoRandom(), numeratorDF, denominatorDF); } public FisherF(final PseudoRandom prng, final int numeratorDF, final int denominatorDF) { super(prng); if (numeratorDF < 1) { throw new IllegalArgumentException("numeratorDF < 1 : " + numeratorDF); } if (denominatorDF < 1) { throw new IllegalArgumentException("denominatorDF < 1 : " + denominatorDF); } this.d1 = numeratorDF; this.d2 = denominatorDF; this.beta = new Beta(this.prng, (d1 / 2.0), (d2 / 2.0)); } @Override public double pdf(final double x) { if (x < 0.0) { return 0.0; } if (x == 0.0) { if (d1 == 1) { return Double.POSITIVE_INFINITY; } if (d1 == 2) { return 1.0; } return 0.0; } // A quite clever variable substitution approach: final double w = d2 / (d2 + (d1 * x)); // Fact: if X ~ F(d1, d1) then (1 - W) ~ Beta(d1/2, d2/2). // // Further note that (1): (1 - w) = (d1 / d2) * x * w // and (2): (1 / w) = 1 + (d1 / d2) * x // // First write out the density of the Beta((1-w); d1/2, d2/2) // and then substitute (1) into the resulting (1 - w) term. // // Then multiply the density by (w * w * (d1/d2)); finally // replace the remaining "w" term with the inverse of (2). // // Compare your result with the density of the F(x; d1, d2) // - both are identical! This proves that the following is // the correct transformation: return (((w * d1) * w) * beta.pdf(1.0 - w)) / d2; } @Override public double cdf(final double x) { if (x <= 0.0) { return 0.0; } final double z = d1 * x; final double y = z / (d2 + z); return beta.cdf(y); } @Override public double sample() { final double y = beta.sample(); return (y * d2) / (d1 - d1 * y); } @Override public double mean() { if (d2 <= 2) { return Double.NaN; } return d2 / ((double) d2 - 2.0); } @Override public double variance() { if (d2 <= 4) { return Double.NaN; } final double z = d2 - 2.0; return 2.0 * d2 * d2 * (d1 + z) / (d1 * z * z * (d2 - 4.0)); } public int getNumeratorDegreesOfFreedom() { return d1; } public int getDenominatorDegreesOfFreedom() { return d2; } @Override public String toString() { return getSimpleName(d1, d2); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy