gov.sandia.cognition.statistics.distribution.ChiSquareDistribution 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: ChiSquareDistribution.java
* Authors: Kevin R. Dixon
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright September 7, 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.matrix.VectorFactory;
import gov.sandia.cognition.math.matrix.Vector;
import gov.sandia.cognition.statistics.AbstractClosedFormSmoothUnivariateDistribution;
import gov.sandia.cognition.statistics.UnivariateProbabilityDensityFunction;
import gov.sandia.cognition.statistics.SmoothCumulativeDistributionFunction;
import java.util.ArrayList;
import java.util.Random;
/**
* Describes a Chi-Square Distribution. The Chi-Square distribution occurs
* when Y = X1^2 + X2^2 + ... + Xn^2. In this case, Y will be a Chi-Square
* Random Variable with "n" degrees of freedom, iff the Xi are independent
* Gaussian Random Variables.
* The chi-square distribution is a member of the Gamma-distribution family.
*
* @author Kevin R. Dixon
* @since 2.0
*
*/
@PublicationReference(
author="Wikipedia",
title="Chi-square distribution",
type=PublicationType.WebPage,
year=2009,
url="http://en.wikipedia.org/wiki/Chi-square_distribution"
)
public class ChiSquareDistribution
extends AbstractClosedFormSmoothUnivariateDistribution
{
/**
* Default degrees of freedom, {@value}.
*/
public static final double DEFAULT_DEGREES_OF_FREEDOM = 2.0;
/**
* Number of degrees of freedom in the distribution,
* must be greater than 0.0
*/
private double degreesOfFreedom;
/**
* Default constructor.
*/
public ChiSquareDistribution()
{
this( DEFAULT_DEGREES_OF_FREEDOM );
}
/**
* Creates a new instance of ChiSquareDistribution
* @param degreesOfFreedom
* Number of degrees of freedom in the distribution,
* must be greater than 0.0
*/
public ChiSquareDistribution(
final double degreesOfFreedom )
{
this.setDegreesOfFreedom( degreesOfFreedom );
}
/**
* Copy constructor
* @param other
* ChiSquareDistribution to copy
*/
public ChiSquareDistribution(
final ChiSquareDistribution other )
{
this( other.getDegreesOfFreedom() );
}
@Override
public ChiSquareDistribution clone()
{
return (ChiSquareDistribution) super.clone();
}
/**
* Getter for degrees of freedom
* @return
* Number of degrees of freedom in the distribution,
* must be greater than 0.0
*/
public double getDegreesOfFreedom()
{
return this.degreesOfFreedom;
}
/**
* Setter for degrees of freedom
* @param degreesOfFreedom
* Number of degrees of freedom in the distribution,
* must be greater than 0.0
*/
public void setDegreesOfFreedom(
final double degreesOfFreedom )
{
if (degreesOfFreedom <= 0.0)
{
throw new IllegalArgumentException(
"Degrees of Freedom must be > 0.0" );
}
this.degreesOfFreedom = degreesOfFreedom;
}
@Override
public double getMeanAsDouble()
{
return this.getDegreesOfFreedom();
}
@Override
public double getVariance()
{
return 2.0 * this.getDegreesOfFreedom();
}
/**
* Returns the parameter of the chi-square PDF
* @return
* 1-dimensional Vector containing the degrees of freedom
*/
@Override
public Vector convertToVector()
{
return VectorFactory.getDefault().copyValues( this.getDegreesOfFreedom() );
}
/**
* Sets the parameter of the chi-square PDF
* @param parameters
* 1-dimensional Vector containing the degrees of freedom
*/
@Override
public void convertFromVector(
final Vector parameters )
{
if (parameters.getDimensionality() != 1)
{
throw new IllegalArgumentException(
"Expected 1-dimensional Vector of parameters!" );
}
this.setDegreesOfFreedom( parameters.getElement( 0 ) );
}
@Override
public void sampleInto(
final Random random,
final double[] output,
final int start,
final int length)
{
GammaDistribution.sampleInto(
degreesOfFreedom/2.0, 2.0, random, output, start, length);
}
/**
* Samples from a Chi-Square distribution with the given degrees of freedom
* @param degreesOfFreedom
* Degrees of freedom of the Chi-Square distribution
* @param random
* Random number generator
* @param numSamples
* Number of samples to generate
* @return
* Samples from the GammaDistribution using the Chi-Square DOFs.
*/
public static double[] sampleAsDoubles(
final double degreesOfFreedom,
final Random random,
final int numSamples )
{
return GammaDistribution.sampleAsDoubles(
degreesOfFreedom/2.0, 2.0, random, numSamples);
}
/**
* Samples from a Chi-Square distribution with the given degrees of freedom
* @param degreesOfFreedom
* Degrees of freedom of the Chi-Square distribution
* @param random
* Random number generator
* @param numSamples
* Number of samples to generate
* @return
* Samples from the GammaDistribution using the Chi-Square DOFs.
*/
public static ArrayList sample(
final double degreesOfFreedom,
final Random random,
final int numSamples )
{
return GammaDistribution.sample(
degreesOfFreedom/2.0, 2.0, random, numSamples);
}
@Override
public ChiSquareDistribution.CDF getCDF()
{
return new ChiSquareDistribution.CDF( this );
}
@Override
public ChiSquareDistribution.PDF getProbabilityFunction()
{
return new ChiSquareDistribution.PDF( this );
}
@Override
public Double getMinSupport()
{
return 0.0;
}
@Override
public Double getMaxSupport()
{
return Double.POSITIVE_INFINITY;
}
/**
* PDF of the Chi-Square distribution
*/
public static class PDF
extends ChiSquareDistribution
implements UnivariateProbabilityDensityFunction
{
/**
* Default constructor.
*/
public PDF()
{
super();
}
/**
* Creates a new instance of ChiSquareDistribution
* @param degreesOfFreedom
* Number of degrees of freedom in the distribution,
* must be greater than 0.0
*/
public PDF(
final double degreesOfFreedom )
{
super( degreesOfFreedom );
}
/**
* Copy constructor
* @param other
* ChiSquareDistribution to copy
*/
public PDF(
final ChiSquareDistribution other )
{
super( other );
}
@Override
public Double evaluate(
final Double input )
{
return this.evaluate( input.doubleValue() );
}
@Override
public double evaluateAsDouble(
final Double input)
{
return this.evaluate(input.doubleValue());
}
@Override
public double evaluate(
final double input )
{
return evaluate( input, this.getDegreesOfFreedom() );
}
/**
* Evaluates the chi-square PDF for the given input and DOFs
* @param x
* Input to the PDF
* @param degreesOfFreedom
* DOFs of the PDF
* @return
* p(x|dof)
*/
public static double evaluate(
final double x,
final double degreesOfFreedom )
{
return Math.exp(logEvaluate(x, degreesOfFreedom));
}
@Override
public double logEvaluate(
final Double input)
{
return this.logEvaluate((double) input);
}
@Override
public double logEvaluate(
final double input)
{
return logEvaluate(input, this.getDegreesOfFreedom());
}
/**
* Computes the natural logarithm of the PDF.
* @param x
* Input to the PDF
* @param degreesOfFreedom
* DOFs of the PDF
* @return
* Natural logarithm of the PDF.
*/
public static double logEvaluate(
final double x,
final double degreesOfFreedom )
{
return GammaDistribution.PDF.logEvaluate( x, degreesOfFreedom/2.0, 2.0 );
}
@Override
public ChiSquareDistribution.PDF getProbabilityFunction()
{
return this;
}
}
/**
* Cumulative Distribution Function (CDF) of a Chi-Square Distribution
*/
public static class CDF
extends ChiSquareDistribution
implements SmoothCumulativeDistributionFunction
{
/**
* Default constructor.
*/
public CDF()
{
super();
}
/**
* Creates a new instance of ChiSquareDistribution
* @param degreesOfFreedom
* Number of degrees of freedom in the distribution,
* must be greater than 0.0
*/
public CDF(
final double degreesOfFreedom )
{
super( degreesOfFreedom );
}
/**
* Copy constructor
* @param other
* ChiSquareDistribution to copy
*/
public CDF(
final ChiSquareDistribution other )
{
super( other );
}
@Override
public double evaluate(
final double input )
{
return evaluate( input, this.getDegreesOfFreedom() );
}
@Override
public Double evaluate(
final Double input )
{
return this.evaluate( input.doubleValue() );
}
@Override
public double evaluateAsDouble(
final Double input)
{
return this.evaluate(input.doubleValue());
}
/**
* Computes the values of the Chi-Square CDF for the given input and
* degrees of freedom
* @param input
* Input about which to evaluate the CDF
* @param degreesOfFreedom
* Number of degrees of freedom in the distribution
* @return
* Pr{ y <= input | degreesOfFreedom }
*/
public static double evaluate(
final double input,
final double degreesOfFreedom )
{
if( degreesOfFreedom <= 0.0 )
{
throw new IllegalArgumentException(
"Degrees of Freedom must be > 0.0" );
}
return GammaDistribution.CDF.evaluate(
input, degreesOfFreedom / 2.0, 2.0 );
}
@Override
public ChiSquareDistribution.CDF getCDF()
{
return this;
}
@Override
public ChiSquareDistribution.PDF getDerivative()
{
return this.getProbabilityFunction();
}
@Override
public Double differentiate(
final Double input)
{
return this.getDerivative().evaluate(input);
}
}
}