
gov.sandia.cognition.statistics.distribution.UniformIntegerDistribution 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: UniformIntegerDistribution.java
* Authors: Justin Basilico
* Project: Cognitive Foundry
*
* Copyright 2015 Cognitive Foundry. All rights reserved.
*/
package gov.sandia.cognition.statistics.distribution;
import gov.sandia.cognition.annotation.PublicationReference;
import gov.sandia.cognition.annotation.PublicationType;
import gov.sandia.cognition.collection.IntegerSpan;
import gov.sandia.cognition.math.LogMath;
import gov.sandia.cognition.math.MathUtil;
import gov.sandia.cognition.math.UnivariateStatisticsUtil;
import gov.sandia.cognition.math.matrix.Vector;
import gov.sandia.cognition.math.matrix.VectorFactory;
import gov.sandia.cognition.statistics.AbstractClosedFormIntegerDistribution;
import gov.sandia.cognition.statistics.ClosedFormCumulativeDistributionFunction;
import gov.sandia.cognition.statistics.ClosedFormDiscreteUnivariateDistribution;
import gov.sandia.cognition.statistics.DistributionEstimator;
import gov.sandia.cognition.statistics.EstimableDistribution;
import gov.sandia.cognition.statistics.ProbabilityMassFunction;
import gov.sandia.cognition.util.AbstractCloneableSerializable;
import gov.sandia.cognition.util.Pair;
import java.util.Collection;
import java.util.Random;
import java.util.Set;
/**
* Contains the (very simple) definition of a continuous Uniform distribution,
* parameterized between the minimum and maximum bounds. The uniform
* distribution has equal mass on all of the integers between the two bounds,
* and including them. For example, if the bounds were (10, 14) then the values
* 10, 11, 12, 13, and 14 would all have probability 1/5 of being sampled.
*
* @author Justin Basilico
* @since 3.4.3
*/
@PublicationReference(
author="Wikipedia",
title="Uniform distribution (discrete)",
type=PublicationType.WebPage,
year=2015,
url="https://en.wikipedia.org/wiki/Uniform_distribution_(discrete)"
)
public class UniformIntegerDistribution
extends AbstractClosedFormIntegerDistribution
implements ClosedFormDiscreteUnivariateDistribution,
EstimableDistribution
{
/** The default minimum support is {@value}. */
public static final int DEFAULT_MIN_SUPPORT = 0;
/** The default maximum support is {@value}. */
public static final int DEFAULT_MAX_SUPPORT = 0;
/** The minimum bound on the distribution (inclusive). */
private int minSupport;
/** The maximum bound on the distribution (inclusive). */
private int maxSupport;
/**
* Creates a new {@link UniformIntegerDistribution} with default parameters.
*/
public UniformIntegerDistribution()
{
this(DEFAULT_MIN_SUPPORT, DEFAULT_MAX_SUPPORT);
}
/**
* Creates a new {@link UniformIntegerDistribution} with the given bounds.
*
* @param minSupport
* The minimum bound on the distribution (inclusive).
* @param maxSupport
* The maximum bound on the distribution (exclusive).
*/
public UniformIntegerDistribution(
final int minSupport,
final int maxSupport)
{
super();
this.setMinSupport(minSupport);
this.setMaxSupport(maxSupport);
}
/**
* Creates a new {@link UniformIntegerDistribution} that is a copy of the
* given other distribution.
*
* @param other
* The distribution to copy.
*/
public UniformIntegerDistribution(
final UniformIntegerDistribution other)
{
this(other.getMinSupport(), other.getMaxSupport());
}
@Override
public UniformIntegerDistribution clone()
{
return (UniformIntegerDistribution) super.clone();
}
@Override
public UniformIntegerDistribution.PMF getProbabilityFunction()
{
return new UniformIntegerDistribution.PMF(this);
}
@Override
public UniformIntegerDistribution.CDF getCDF()
{
return new UniformIntegerDistribution.CDF(this);
}
@Override
public Number getMean()
{
return this.getMeanAsDouble();
}
@Override
public Vector convertToVector()
{
return VectorFactory.getDenseDefault().copyValues(
this.getMinSupport(), this.getMaxSupport());
}
@Override
public void convertFromVector(
final Vector parameters)
{
parameters.assertDimensionalityEquals(2);
final int a = (int) parameters.getElement(0);
final int b = (int) parameters.getElement(1);
this.setMinSupport(Math.min(a, b));
this.setMaxSupport(Math.max(a, b));
}
@Override
public Integer getMinSupport()
{
return this.minSupport;
}
/**
* Sets the minimum support. It is the smallest value in the uniform
* distribution, and is inclusive. It should be less than (or equal to)
* the maximum support.
*
* @param minSupport
* The minimum support.
*/
public void setMinSupport(
final int minSupport)
{
this.minSupport = minSupport;
}
@Override
public Integer getMaxSupport()
{
return this.maxSupport;
}
/**
* Sets the maximum support. It is the largest value in the uniform
* distribution, and is inclusive. It should be greater than (or equal to)
* the minimum support.
*
* @param maxSupport
* The maximum support.
*/
public void setMaxSupport(
final int maxSupport)
{
this.maxSupport = maxSupport;
}
@Override
public double getMeanAsDouble()
{
return (this.maxSupport + this.minSupport) / 2.0;
}
@Override
public double getVariance()
{
final double difference = this.maxSupport - this.minSupport + 1;
return (difference * difference - 1) / 12.0;
}
@Override
public Set extends Number> getDomain()
{
return new IntegerSpan(this.minSupport, this.maxSupport);
}
@Override
public int getDomainSize()
{
return (this.maxSupport - this.minSupport + 1);
}
@Override
public int sampleAsInt(
final Random random)
{
return this.minSupport
+ random.nextInt(this.maxSupport - this.minSupport + 1);
}
@Override
public void sampleInto(
final Random random,
final int sampleCount,
final Collection super Number> output)
{
for (int i = 0; i < sampleCount; i++)
{
output.add(this.sampleAsInt(random));
}
}
@Override
public UniformIntegerDistribution.MaximumLikelihoodEstimator getEstimator()
{
return new MaximumLikelihoodEstimator();
}
/**
* Probability mass function of a discrete uniform distribution.
*/
public static class PMF
extends UniformIntegerDistribution
implements ProbabilityMassFunction
{
/**
* Creates a new {@link UniformIntegerDistribution.PMF} with min and
* max 0.
*/
public PMF()
{
super();
}
/**
* Creates a new {@link UniformIntegerDistribution.PMF} with the given
* min and max.
*
* @param minSupport
* The minimum support. Should be less-than-or-equal to the max
* support.
* @param maxSupport
* The maximum support. Should be greater-than-or-equal to the min
* support.
*/
public PMF(
final int minSupport,
final int maxSupport)
{
super(minSupport, maxSupport);
}
/**
* Creates a new {@link UniformIntegerDistribution.PMF} as a copy
* of the given other uniform distribution.
*
* @param other
* The other distribution.
*/
public PMF(
final UniformIntegerDistribution other)
{
super(other);
}
@Override
public double getEntropy()
{
return MathUtil.log2(this.getDomainSize());
}
@Override
public double logEvaluate(
final Number input)
{
return logEvaluate(input.intValue(),
this.getMinSupport(), this.getMaxSupport());
}
@Override
public Double evaluate(
final Number input)
{
return this.evaluateAsDouble(input.intValue());
}
/**
* Evaluates the input value for the PMF to compute its mass as a
* double.
*
* @param input
* The input value.
* @return
* The probability mass for the input value.
*/
public double evaluateAsDouble(
final int input)
{
return evaluate(input, this.getMinSupport(), this.getMaxSupport());
}
/**
* Evaluates the probability mass function of the discrete uniform
* distribution. The mass is a uniform value if the input is between
* the supports (inclusive) and 0 if it is not.
*
* @param input
* The input value.
* @param minSupport
* The minimum support. Should be less-than-or-equal to the max
* support.
* @param maxSupport
* The maximum support. Should be greater-than-or-equal to the min
* support.
* @return
* The probability mass value for the input.
*/
public static double evaluate(
final int input,
final int minSupport,
final int maxSupport)
{
if (input < minSupport || input > maxSupport)
{
// Outside the support range.
return 0.0;
}
else
{
// Uniform within support range.
return 1.0 / (maxSupport - minSupport + 1);
}
}
/**
* Evaluates the log of the probability mass function of the discrete
* uniform distribution. The mass is a uniform value if the input is
* between the supports (inclusive) and 0 if it is not.
*
* @param input
* The input value.
* @param minSupport
* The minimum support. Should be less-than-or-equal to the max
* support.
* @param maxSupport
* The maximum support. Should be greater-than-or-equal to the min
* support.
* @return
* The log of the probability mass value for the input.
*/
public static double logEvaluate(
final int input,
final int minSupport,
final int maxSupport)
{
if (input < minSupport || input > maxSupport)
{
return LogMath.LOG_0;
}
else
{
return -Math.log(maxSupport - minSupport + 1);
}
}
@Override
public PMF getProbabilityFunction()
{
return this;
}
}
/**
* Implements the cumulative distribution function for the discrete
* uniform distribution.
*/
public static class CDF
extends UniformIntegerDistribution
implements ClosedFormCumulativeDistributionFunction
{
/**
* Creates a new {@link UniformIntegerDistribution.PMF} with min and
* max 0.
*/
public CDF()
{
super();
}
/**
* Creates a new {@link UniformIntegerDistribution.CDF} with the given
* min and max.
*
* @param minSupport
* The minimum support. Should be less-than-or-equal to the max
* support.
* @param maxSupport
* The maximum support. Should be greater-than-or-equal to the min
* support.
*/
public CDF(
final int minSupport,
final int maxSupport)
{
super(minSupport, maxSupport);
}
/**
* Creates a new {@link UniformIntegerDistribution.CDF} as a copy
* of the given other uniform distribution.
*
* @param other
* The other distribution.
*/
public CDF(
final UniformIntegerDistribution other)
{
super(other);
}
@Override
public Double evaluate(
final Number input)
{
return this.evaluateAsDouble(input.intValue());
}
/**
* Evaluates the cumulative distribution function for the input.
*
* @param input
* The input value.
* @return
* The cumulative distribution value at the input.
*/
public double evaluateAsDouble(
final int input)
{
return evaluate(input, this.getMinSupport(), this.getMaxSupport());
}
/**
* Evaluates the cumulative density function of the discrete uniform
* distribution.
*
* @param input
* The input value.
* @param minSupport
* The minimum support. Should be less-than-or-equal to the max
* support.
* @param maxSupport
* The maximum support. Should be greater-than-or-equal to the min
* support.
* @return
* The cumulative density value for the input.
*/
public static double evaluate(
final int input,
final int minSupport,
final int maxSupport)
{
final double p;
if (input < minSupport)
{
// Before the support range.
p = 0.0;
}
else if (input > maxSupport)
{
// After the support range.
p = 1.0;
}
else
{
// Within the support range.
p = (input - minSupport + 1.0) / (maxSupport - minSupport + 1.0);
}
return p;
}
@Override
public UniformIntegerDistribution.CDF getCDF()
{
return this;
}
}
/**
* Implements a maximum likelihood estimator for the discrete uniform
* distribution.
*/
@PublicationReference(
author="Wikipedia",
title="German tank problem",
type=PublicationType.WebPage,
year=2010,
url="http://en.wikipedia.org/wiki/German_tank_problem"
)
public static class MaximumLikelihoodEstimator
extends AbstractCloneableSerializable
implements DistributionEstimator
{
/**
* Creates a new {@link UniformIntegerDistribution.MaximumLikelihoodEstimator}.
*/
public MaximumLikelihoodEstimator()
{
super();
}
@Override
public UniformIntegerDistribution.PMF learn(
final Collection extends Number> data)
{
final Pair result =
UnivariateStatisticsUtil.computeMinAndMax(data);
final int min = result.getFirst().intValue();
final int max = result.getSecond().intValue();
return new UniformIntegerDistribution.PMF(min, max);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy