gov.sandia.cognition.statistics.distribution.SnedecorFDistribution Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cognitive-foundry Show documentation
Show all versions of cognitive-foundry Show documentation
A single jar with all the Cognitive Foundry components.
/*
* File: SnedecorFDistribution.java
* Authors: Kevin R. Dixon
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright August 16, 2007, Sandia Corporation. Under the terms of Contract
* DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
* or on behalf of the U.S. Government. Export of this program may require a
* license from the United States Government. See CopyrightHistory.txt for
* complete details.
*
*/
package gov.sandia.cognition.statistics.distribution;
import gov.sandia.cognition.annotation.PublicationReference;
import gov.sandia.cognition.annotation.PublicationType;
import gov.sandia.cognition.math.UnivariateScalarFunction;
import gov.sandia.cognition.math.matrix.Vector;
import gov.sandia.cognition.math.matrix.VectorFactory;
import gov.sandia.cognition.statistics.AbstractClosedFormUnivariateDistribution;
import gov.sandia.cognition.statistics.ClosedFormCumulativeDistributionFunction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;
/**
* CDF of the Snedecor F-distribution (also known as Fisher F-distribution,
* Fisher-Snedecor F-distribution, or just plain old F-distribution). This is
* a type of Beta Distribution,
* where F(x,v1,v2) = 1-Beta(v2/(v2+v1*x),v2,v1)
*
* @author Kevin R. Dixon
* @since 2.0
*
*/
@PublicationReference(
author="Wikipedia",
title="F-distribution",
type=PublicationType.WebPage,
year=2009,
url="http://en.wikipedia.org/wiki/F-distribution"
)
public class SnedecorFDistribution
extends AbstractClosedFormUnivariateDistribution
{
/**
* Default value of v1, {@value}.
*/
public static final double DEFAULT_V1 = 3.0;
/**
* Default value of v2, {@value}.
*/
public static final double DEFAULT_V2 = 5.0;
/**
* First degree of freedom
*/
private double v1;
/**
* Second degree of freedom
*/
private double v2;
/**
* Default constructor
*/
public SnedecorFDistribution()
{
this( DEFAULT_V1, DEFAULT_V2 );
}
/**
* Creates a new instance of CumulativeDistribution
* @param v1
* First degree of freedom
* @param v2
* Second degree of freedom
*/
public SnedecorFDistribution(
final double v1,
final double v2 )
{
this.setV1( v1 );
this.setV2( v2 );
}
/**
* Copy Constructor
* @param other CumulativeDistribution to copy
*/
public SnedecorFDistribution(
final SnedecorFDistribution other )
{
this( other.getV1(), other.getV2() );
}
@Override
public SnedecorFDistribution clone()
{
return (SnedecorFDistribution) super.clone();
}
/**
* Getter for v1
* @return
* First degree of freedom
*/
public double getV1()
{
return this.v1;
}
/**
* Setter for v1
* @param v1
* First degree of freedom
*/
public void setV1(
final double v1 )
{
if( v1 <= 0.0 )
{
throw new IllegalArgumentException( "v1 must be > 0.0" );
}
this.v1 = v1;
}
/**
* Getter for v2
* @return
* Second degree of freedom
*/
public double getV2()
{
return this.v2;
}
/**
* Setter for v2
* @param v2
* Second degree of freedom
*/
public void setV2(
final double v2 )
{
if( v2 <= 0.0 )
{
throw new IllegalArgumentException( "v2 must be > 0.0" );
}
this.v2 = v2;
}
@Override
public Double getMean()
{
return this.getMeanAsDouble();
}
@Override
public double getMeanAsDouble()
{
if( this.v2 > 2.0 )
{
return this.v2 / (this.v2 - 2.0);
}
else
{
return this.v2;
}
}
@Override
public double getVariance()
{
if( this.v2 > 4.0 )
{
double t1 = 2.0 * this.v2*this.v2;
double t2 = this.v1 + this.v2 - 2.0;
double top = t1*t2;
double b1 = this.v2 - 2.0;
double b2 = this.v2 - 4.0;
double bottom = this.v1 * b1*b1 * b2;
return top / bottom;
}
else
{
return 1.0;
}
}
@Override
public Vector convertToVector()
{
return VectorFactory.getDefault().copyValues(
this.getV1(), this.getV2() );
}
@Override
public void convertFromVector(
final Vector parameters )
{
if( parameters.getDimensionality() != 2 )
{
throw new IllegalArgumentException(
"Parameters must have dimensionality 2" );
}
this.setV1( parameters.getElement( 0 ) );
this.setV2( parameters.getElement( 1 ) );
}
@Override
public void sampleInto(
final Random random,
final int sampleCount,
final Collection super Double> output)
{
final double[] g1 = GammaDistribution.sampleAsDoubles(
this.v1/2.0, 2.0/this.v1, random, sampleCount);
final double[] g2 = GammaDistribution.sampleAsDoubles(
this.v2/2.0, 2.0/this.v2, random, sampleCount);
for( int n = 0; n < sampleCount; n++ )
{
// TODO: Should there be a double[] version of this function too?
output.add( g1[n] / g2[n] );
}
}
@Override
public SnedecorFDistribution.CDF getCDF()
{
return new SnedecorFDistribution.CDF( this );
}
@Override
public Double getMinSupport()
{
return 0.0;
}
@Override
public Double getMaxSupport()
{
return Double.POSITIVE_INFINITY;
}
/**
* CDF of the F-distribution.
*/
public static class CDF
extends SnedecorFDistribution
implements ClosedFormCumulativeDistributionFunction,
UnivariateScalarFunction
{
/**
* Default constructor
*/
public CDF()
{
super();
}
/**
* Creates a new instance of CumulativeDistribution
* @param v1
* First degree of freedom
* @param v2
* Second degree of freedom
*/
public CDF(
final double v1,
final double v2 )
{
super( v1, v2 );
}
/**
* Copy Constructor
* @param other CumulativeDistribution to copy
*/
public CDF(
final SnedecorFDistribution other )
{
super( other );
}
@Override
public double evaluate(
final double input )
{
return evaluate( input, this.getV1(), this.getV2() );
}
@Override
public Double evaluate(
final Double input )
{
return this.evaluate( input.doubleValue() );
}
@Override
public double evaluateAsDouble(
final Double input)
{
return this.evaluate(input.doubleValue());
}
/**
* Evaluates the F-distribution CDF(input,v1,v2)
* @param input
* Input independent variable in the F-distribution
* @param v1
* First degree of freedom
* @param v2
* Second degree of freedom
* @return
* Probability of the CDF(input,v1,v2)
*/
public static double evaluate(
final double input,
final double v1,
final double v2 )
{
double p;
if (input < 0.0)
{
p = 0.0;
}
else
{
double a = BetaDistribution.CDF.evaluate(
v2 / (v2 + v1 * input), 0.5 * v2, 0.5 * v1 );
p = 1.0 - a;
}
return p;
}
@Override
public SnedecorFDistribution.CDF getCDF()
{
return this;
}
}
}