gov.sandia.cognition.statistics.distribution.InverseGammaDistribution 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: InverseGammaDistribution.java
* Authors: Kevin R. Dixon
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright Mar 10, 2010, 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.MathUtil;
import gov.sandia.cognition.math.matrix.Vector;
import gov.sandia.cognition.math.matrix.VectorFactory;
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;
/**
* Defines an inverse-gamma distribution. That is, if X is drawn from IG(a,b),
* then 1/X follows a Gamma(a,1.0/b) distribution.
* @author Kevin R. Dixon
* @since 3.0
*/
@PublicationReference(
author="Wikipedia",
title="Inverse-gamma distribution",
type=PublicationType.WebPage,
year=2010,
url="http://en.wikipedia.org/wiki/Inverse-gamma_distribution"
)
public class InverseGammaDistribution
extends AbstractClosedFormSmoothUnivariateDistribution
{
/**
* Default shape, {@value}.
*/
public static final double DEFAULT_SHAPE = 3.0;
/**
* Default scale, {@value}.
*/
public static final double DEFAULT_SCALE = 1.0;
/**
* Shape parameter, must be greater than zero.
*/
protected double shape;
/**
* Scale parameter, must be greater than zero.
*/
protected double scale;
/**
* Creates a new instance of InverseGammaDistribution
*/
public InverseGammaDistribution()
{
this( DEFAULT_SHAPE, DEFAULT_SCALE );
}
/**
* Creates a new instance of InverseGammaDistribution
* @param shape
* Shape parameter, must be greater than zero.
* @param scale
* Scale parameter, must be greater than zero.
*/
public InverseGammaDistribution(
final double shape,
final double scale)
{
this.shape = shape;
this.scale = scale;
}
/**
* Copy constructor
* @param other
* InverseGammaDistribution to copy
*/
public InverseGammaDistribution(
final InverseGammaDistribution other )
{
this( other.getShape(), other.getScale() );
}
@Override
public InverseGammaDistribution clone()
{
return (InverseGammaDistribution) super.clone();
}
/**
* Getter for shape
* @return
* Shape parameter, must be greater than zero.
*/
public double getShape()
{
return this.shape;
}
/**
* Setter for shape
* @param shape
* Shape parameter, must be greater than zero.
*/
public void setShape(
final double shape)
{
if( shape <= 0.0 )
{
throw new IllegalArgumentException(
"Shape must be > 0.0" );
}
this.shape = shape;
}
/**
* Getter for scale
* @return
* Scale parameter, must be greater than zero.
*/
public double getScale()
{
return this.scale;
}
/**
* Setter for scale
* @param scale the scale to set
* Scale parameter, must be greater than zero.
*/
public void setScale(
final double scale)
{
if( scale <= 0.0 )
{
throw new IllegalArgumentException(
"Scale must be > 0.0" );
}
this.scale = scale;
}
@Override
public double sampleAsDouble(
final Random random)
{
final double g = GammaDistribution.sampleAsDouble(
this.shape, 1.0 / this.scale, random);
return 1.0 / g;
}
@Override
public void sampleInto(
final Random random,
final double[] output,
final int start,
final int length)
{
// Sample the requested number of gammas.
GammaDistribution.sampleInto(this.shape, 1.0 / this.scale,
random, output, start, length);
// Now invert the gammas.
final int end = start + length;
for (int i = start; i < end; i++)
{
output[i] = 1.0 / output[i];
}
}
@Override
public Vector convertToVector()
{
return VectorFactory.getDefault().copyValues( this.shape, this.scale );
}
@Override
public void convertFromVector(
Vector parameters)
{
parameters.assertDimensionalityEquals(2);
this.setShape( parameters.getElement(0) );
this.setScale( parameters.getElement(1) );
}
@Override
public double getMeanAsDouble()
{
if( this.shape > 1.0 )
{
return this.scale / (this.shape - 1.0);
}
else
{
throw new IllegalArgumentException(
"Shape must be > 1.0" );
}
}
@Override
public double getVariance()
{
if( this.shape > 2.0 )
{
final double am1 = this.shape - 1.0;
final double am2 = this.shape - 2.0;
return this.scale*this.scale / (am1*am1*am2);
}
else
{
throw new IllegalArgumentException(
"Shape must be > 2.0" );
}
}
@Override
public InverseGammaDistribution.CDF getCDF()
{
return new InverseGammaDistribution.CDF( this );
}
@Override
public InverseGammaDistribution.PDF getProbabilityFunction()
{
return new InverseGammaDistribution.PDF( this );
}
@Override
public String toString()
{
return "Shape = " + this.getShape() + ", Scale = " + this.getScale();
}
@Override
public Double getMinSupport()
{
return 0.0;
}
@Override
public Double getMaxSupport()
{
return Double.POSITIVE_INFINITY;
}
/**
* CDF of the inverseRootFinder-gamma distribution.
*/
public static class CDF
extends InverseGammaDistribution
implements SmoothCumulativeDistributionFunction
{
/**
* Default constructor
*/
public CDF()
{
super();
}
/**
* Creates a new instance of InverseGammaDistribution
* @param shape
* Shape parameter, must be greater than zero.
* @param scale
* Scale parameter, must be greater than zero.
*/
public CDF(
final double shape,
final double scale)
{
super( shape, scale );
}
/**
* Copy constructor
* @param other
* InverseGammaDistribution to copy
*/
public CDF(
final InverseGammaDistribution 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)
{
if( input > 0.0 )
{
return 1.0-GammaDistribution.CDF.evaluate(1.0/input, shape, 1.0/scale);
}
else
{
return 0.0;
}
}
@Override
public InverseGammaDistribution.CDF getCDF()
{
return this;
}
@Override
public InverseGammaDistribution.PDF getDerivative()
{
return this.getProbabilityFunction();
}
@Override
public Double differentiate(
final Double input)
{
return this.getDerivative().evaluate(input);
}
}
/**
* PDF of the inverseRootFinder-Gamma distribution.
*/
public static class PDF
extends InverseGammaDistribution
implements UnivariateProbabilityDensityFunction
{
/**
* Default constructor
*/
public PDF()
{
super();
}
/**
* Creates a new instance of InverseGammaDistribution
* @param shape
* Shape parameter, must be greater than zero.
* @param scale
* Scale parameter, must be greater than zero.
*/
public PDF(
final double shape,
final double scale)
{
super( shape, scale );
}
/**
* Copy constructor
* @param other
* InverseGammaDistribution to copy
*/
public PDF(
final InverseGammaDistribution other )
{
super( other );
}
@Override
public InverseGammaDistribution.PDF getProbabilityFunction()
{
return this;
}
@Override
public double logEvaluate(
final Double input)
{
return this.logEvaluate((double) input);
}
@Override
public double logEvaluate(
final double input)
{
if( input > 0.0 )
{
double logSum = 0.0;
logSum += this.shape * Math.log(this.scale);
logSum -= MathUtil.logGammaFunction( this.shape );
logSum -= (this.shape+1.0) * Math.log(input);
logSum -= this.scale / input;
return logSum;
}
else
{
return Math.log(0.0);
}
}
@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 Math.exp(this.logEvaluate(input));
}
}
}