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

gov.sandia.cognition.statistics.distribution.SnedecorFDistribution Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
    /*
 * 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 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;
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy