Fixes MATH-385
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/branches/MATH_2_X@1052978 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
1f8cd503b1
commit
f237f93ed2
|
@ -228,4 +228,17 @@ public abstract class AbstractContinuousDistribution
|
|||
return solverAbsoluteAccuracy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access the lower bound of the support.
|
||||
*
|
||||
* @return lower bound of the support (might be Double.NEGATIVE_INFINITY)
|
||||
*/
|
||||
public abstract double getSupportLowerBound();
|
||||
|
||||
/**
|
||||
* Access the upper bound of the support.
|
||||
*
|
||||
* @return upper bound of the support (might be Double.POSITIVE_INFINITY)
|
||||
*/
|
||||
public abstract double getSupportUpperBound();
|
||||
}
|
||||
|
|
|
@ -33,6 +33,12 @@ public abstract class AbstractDistribution
|
|||
/** Serializable version identifier */
|
||||
private static final long serialVersionUID = -38038050983108802L;
|
||||
|
||||
private double numericalMean = Double.NaN;
|
||||
private boolean numericalMeanIsCalculated = false;
|
||||
|
||||
private double numericalVariance = Double.NaN;
|
||||
private boolean numericalVarianceIsCalculated = false;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
|
@ -66,4 +72,106 @@ public abstract class AbstractDistribution
|
|||
}
|
||||
return cumulativeProbability(x1) - cumulativeProbability(x0);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method invalidates cached moments when parameters change.
|
||||
* Usually it is called from a sub-class when the distribution
|
||||
* gets its parameters updated.
|
||||
*
|
||||
* @deprecated as of 2.2 (sub-classes will become immutable in 3.0)
|
||||
*/
|
||||
@Deprecated
|
||||
protected void invalidateParameterDependentMoments() {
|
||||
numericalMeanIsCalculated = false;
|
||||
numericalVarianceIsCalculated = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this method to actually calculate the mean for the
|
||||
* specific distribution. Use {@link #getNumericalMean()}
|
||||
* (which implements caching) to actually get the mean.
|
||||
*
|
||||
* @return the mean or Double.NaN if it's not defined
|
||||
*/
|
||||
protected abstract double calculateNumericalMean();
|
||||
|
||||
/**
|
||||
* Use this method to get the numerical value of the mean of this
|
||||
* distribution.
|
||||
*
|
||||
* @return the mean or Double.NaN if it's not defined
|
||||
*/
|
||||
public double getNumericalMean() {
|
||||
if (!numericalMeanIsCalculated) {
|
||||
numericalMean = calculateNumericalMean();
|
||||
numericalMeanIsCalculated = true;
|
||||
}
|
||||
|
||||
return numericalMean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this method to actually calculate the variance for the
|
||||
* specific distribution. Use {@link #getNumericalVariance()}
|
||||
* (which implements caching) to actually get the variance.
|
||||
*
|
||||
* @return the variance or Double.NaN if it's not defined
|
||||
*/
|
||||
protected abstract double calculateNumericalVariance();
|
||||
|
||||
/**
|
||||
* Use this method to get the numerical value of the variance of this
|
||||
* distribution.
|
||||
*
|
||||
* @return the variance (possibly Double.POSITIVE_INFINITY as
|
||||
* for certain cases in {@link TDistributionImpl}) or
|
||||
* Double.NaN if it's not defined
|
||||
*/
|
||||
public double getNumericalVariance() {
|
||||
if (!numericalVarianceIsCalculated) {
|
||||
numericalVariance = calculateNumericalVariance();
|
||||
numericalVarianceIsCalculated = true;
|
||||
}
|
||||
|
||||
return numericalVariance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this method to get information about whether the lower bound
|
||||
* of the support is inclusive or not.
|
||||
*
|
||||
* @return whether the lower bound of the support is inclusive or not
|
||||
*/
|
||||
public abstract boolean isSupportLowerBoundInclusive();
|
||||
|
||||
/**
|
||||
* Use this method to get information about whether the upper bound
|
||||
* of the support is inclusive or not.
|
||||
*
|
||||
* @return whether the upper bound of the support is inclusive or not
|
||||
*/
|
||||
public abstract boolean isSupportUpperBoundInclusive();
|
||||
|
||||
/**
|
||||
* Use this method to get information about whether the support is connected,
|
||||
* i.e. whether all values between the lower and upper bound of the support
|
||||
* is included in the support.
|
||||
*
|
||||
* For {@link AbstractIntegerDistribution} the support is discrete, so
|
||||
* if this is true, then the support is
|
||||
* {lower bound, lower bound + 1, ..., upper bound}.
|
||||
*
|
||||
* For {@link AbstractContinuousDistribution} the support is continuous, so
|
||||
* if this is true, then the support is the interval
|
||||
* [lower bound, upper bound]
|
||||
* where the limits are inclusive or not according to
|
||||
* {@link #isSupportLowerBoundInclusive()} and {@link #isSupportUpperBoundInclusive()}
|
||||
* (in the example both are true). If both are false, then the support is the interval
|
||||
* (lower bound, upper bound)
|
||||
*
|
||||
* @return whether the support limits given by subclassed methods are connected or not
|
||||
*/
|
||||
public boolean isSupportConnected() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -291,4 +291,42 @@ public abstract class AbstractIntegerDistribution extends AbstractDistribution
|
|||
* P(X < <i>upper bound</i>) > <code>p</code>
|
||||
*/
|
||||
protected abstract int getDomainUpperBound(double p);
|
||||
|
||||
/**
|
||||
* Access the lower bound of the support.
|
||||
*
|
||||
* @return lower bound of the support (Integer.MIN_VALUE for negative infinity)
|
||||
*/
|
||||
public abstract int getSupportLowerBound();
|
||||
|
||||
/**
|
||||
* Access the upper bound of the support.
|
||||
*
|
||||
* @return upper bound of the support (Integer.MAX_VALUE for positive infinity)
|
||||
*/
|
||||
public abstract int getSupportUpperBound();
|
||||
|
||||
/**
|
||||
* Use this method to get information about whether the lower bound
|
||||
* of the support is inclusive or not. For discrete support,
|
||||
* only true here is meaningful.
|
||||
*
|
||||
* @return true (always but at Integer.MIN_VALUE because of the nature of discrete support)
|
||||
*/
|
||||
@Override
|
||||
public boolean isSupportLowerBoundInclusive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this method to get information about whether the upper bound
|
||||
* of the support is inclusive or not. For discrete support,
|
||||
* only true here is meaningful.
|
||||
*
|
||||
* @return true (always but at Integer.MAX_VALUE because of the nature of discrete support)
|
||||
*/
|
||||
@Override
|
||||
public boolean isSupportUpperBoundInclusive() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,6 +92,7 @@ public class BetaDistributionImpl
|
|||
public void setAlpha(double alpha) {
|
||||
this.alpha = alpha;
|
||||
z = Double.NaN;
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
|
@ -106,6 +107,7 @@ public class BetaDistributionImpl
|
|||
public void setBeta(double beta) {
|
||||
this.beta = beta;
|
||||
z = Double.NaN;
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
|
@ -223,4 +225,71 @@ public class BetaDistributionImpl
|
|||
protected double getSolverAbsoluteAccuracy() {
|
||||
return solverAbsoluteAccuracy;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The lower bound of the support is always 0 no matter the parameters.
|
||||
*
|
||||
* @return lower bound of the support (always 0)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportLowerBound() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The upper bound of the support is always 1 no matter the parameters.
|
||||
*
|
||||
* @return upper bound of the support (always 1)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportUpperBound() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For first shape parameter <code>s1</code> and
|
||||
* second shape parameter <code>s2</code>, the mean is
|
||||
* <code>s1 / (s1 + s2)</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalMean() {
|
||||
final double alpha = getAlpha();
|
||||
return alpha / (alpha + getBeta());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For first shape parameter <code>s1</code> and
|
||||
* second shape parameter <code>s2</code>,
|
||||
* the variance is
|
||||
* <code>[ s1 * s2 ] / [ (s1 + s2)^2 * (s1 + s2 + 1) ]</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalVariance() {
|
||||
final double alpha = getAlpha();
|
||||
final double beta = getBeta();
|
||||
final double alphabetasum = alpha + beta;
|
||||
return (alpha * beta) / ((alphabetasum * alphabetasum) * (alphabetasum + 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportLowerBoundInclusive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportUpperBoundInclusive() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,9 @@ public class BinomialDistributionImpl extends AbstractIntegerDistribution
|
|||
@Deprecated
|
||||
public void setNumberOfTrials(int trials) {
|
||||
setNumberOfTrialsInternal(trials);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the number of trials for this distribution.
|
||||
*
|
||||
|
@ -110,7 +112,9 @@ public class BinomialDistributionImpl extends AbstractIntegerDistribution
|
|||
@Deprecated
|
||||
public void setProbabilityOfSuccess(double p) {
|
||||
setProbabilityOfSuccessInternal(p);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the probability of success for this distribution.
|
||||
*
|
||||
|
@ -220,4 +224,58 @@ public class BinomialDistributionImpl extends AbstractIntegerDistribution
|
|||
// use default bisection impl
|
||||
return super.inverseCumulativeProbability(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The lower bound of the support is always 0 no matter the number of trials
|
||||
* and probability parameter.
|
||||
*
|
||||
* @return lower bound of the support (always 0)
|
||||
*/
|
||||
@Override
|
||||
public int getSupportLowerBound() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The upper bound of the support is the number of trials.
|
||||
*
|
||||
* @return upper bound of the support (equal to number of trials)
|
||||
*/
|
||||
@Override
|
||||
public int getSupportUpperBound() {
|
||||
return getNumberOfTrials();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For <code>n</code> number of trials and
|
||||
* probability parameter <code>p</code>, the mean is
|
||||
* <code>n * p</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalMean() {
|
||||
return (double)getNumberOfTrials() * getProbabilityOfSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For <code>n</code> number of trials and
|
||||
* probability parameter <code>p</code>, the variance is
|
||||
* <code>n * p * (1 - p)</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalVariance() {
|
||||
final double p = getProbabilityOfSuccess();
|
||||
return (double)getNumberOfTrials() * p * (1 - p);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -157,7 +157,9 @@ public class CauchyDistributionImpl extends AbstractContinuousDistribution
|
|||
@Deprecated
|
||||
public void setMedian(double median) {
|
||||
setMedianInternal(median);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the median.
|
||||
* @param newMedian for this distribution
|
||||
|
@ -175,7 +177,9 @@ public class CauchyDistributionImpl extends AbstractContinuousDistribution
|
|||
@Deprecated
|
||||
public void setScale(double s) {
|
||||
setScaleInternal(s);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the scale parameter.
|
||||
* @param s scale parameter for this distribution
|
||||
|
@ -267,4 +271,64 @@ public class CauchyDistributionImpl extends AbstractContinuousDistribution
|
|||
protected double getSolverAbsoluteAccuracy() {
|
||||
return solverAbsoluteAccuracy;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The lower bound of the support is always negative infinity no matter
|
||||
* the parameters.
|
||||
*
|
||||
* @return lower bound of the support (always Double.NEGATIVE_INFINITY)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportLowerBound() {
|
||||
return Double.NEGATIVE_INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The upper bound of the support is always positive infinity no matter
|
||||
* the parameters.
|
||||
*
|
||||
* @return upper bound of the support (always Double.POSITIVE_INFINITY)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportUpperBound() {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The mean is always undefined no matter the parameters.
|
||||
*
|
||||
* @return mean (always Double.NaN)
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalMean() {
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The variance is always undefined no matter the parameters.
|
||||
*
|
||||
* @return variance (always Double.NaN)
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalVariance() {
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportLowerBoundInclusive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportUpperBoundInclusive() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ public class ChiSquaredDistributionImpl
|
|||
@Deprecated
|
||||
public void setDegreesOfFreedom(double degreesOfFreedom) {
|
||||
setDegreesOfFreedomInternal(degreesOfFreedom);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
/**
|
||||
* Modify the degrees of freedom.
|
||||
|
@ -269,4 +270,66 @@ public class ChiSquaredDistributionImpl
|
|||
protected double getSolverAbsoluteAccuracy() {
|
||||
return solverAbsoluteAccuracy;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The lower bound of the support is always 0 no matter the
|
||||
* degrees of freedom.
|
||||
*
|
||||
* @return lower bound of the support (always 0)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportLowerBound() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The upper bound of the support is always positive infinity no matter the
|
||||
* degrees of freedom.
|
||||
*
|
||||
* @return upper bound of the support (always Double.POSITIVE_INFINITY)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportUpperBound() {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For <code>k</code> degrees of freedom, the mean is
|
||||
* <code>k</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalMean() {
|
||||
return getDegreesOfFreedom();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For <code>k</code> degrees of freedom, the variance is
|
||||
* <code>2 * k</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalVariance() {
|
||||
return 2*getDegreesOfFreedom();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportLowerBoundInclusive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportUpperBoundInclusive() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,4 +52,59 @@ public interface Distribution {
|
|||
* @throws IllegalArgumentException if <code>x0 > x1</code>
|
||||
*/
|
||||
double cumulativeProbability(double x0, double x1) throws MathException;
|
||||
|
||||
/**
|
||||
* Use this method to get the numerical value of the mean of this
|
||||
* distribution.
|
||||
*
|
||||
* @return the mean or Double.NaN if it's not defined
|
||||
*/
|
||||
double getNumericalMean();
|
||||
|
||||
/**
|
||||
* Use this method to get the numerical value of the variance of this
|
||||
* distribution.
|
||||
*
|
||||
* @return the variance (possibly Double.POSITIVE_INFINITY as
|
||||
* for certain cases in {@link TDistributionImpl}) or
|
||||
* Double.NaN if it's not defined
|
||||
*/
|
||||
double getNumericalVariance();
|
||||
|
||||
/**
|
||||
* Use this method to get information about whether the lower bound
|
||||
* of the support is inclusive or not.
|
||||
*
|
||||
* @return whether the lower bound of the support is inclusive or not
|
||||
*/
|
||||
boolean isSupportLowerBoundInclusive();
|
||||
|
||||
/**
|
||||
* Use this method to get information about whether the upper bound
|
||||
* of the support is inclusive or not.
|
||||
*
|
||||
* @return whether the upper bound of the support is inclusive or not
|
||||
*/
|
||||
boolean isSupportUpperBoundInclusive();
|
||||
|
||||
/**
|
||||
* Use this method to get information about whether the support is connected,
|
||||
* i.e. whether all values between the lower and upper bound of the support
|
||||
* is included in the support.
|
||||
*
|
||||
* For {@link AbstractIntegerDistribution} the support is discrete, so
|
||||
* if this is true, then the support is
|
||||
* {lower bound, lower bound + 1, ..., upper bound}.
|
||||
*
|
||||
* For {@link AbstractContinuousDistribution} the support is continuous, so
|
||||
* if this is true, then the support is the interval
|
||||
* [lower bound, upper bound]
|
||||
* where the limits are inclusive or not according to
|
||||
* {@link #isSupportLowerBoundInclusive()} and {@link #isSupportUpperBoundInclusive()}
|
||||
* (in the example both are true). If both are false, then the support is the interval
|
||||
* (lower bound, upper bound)
|
||||
*
|
||||
* @return whether the support limits given by subclassed methods are connected or not
|
||||
*/
|
||||
boolean isSupportConnected();
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ public class ExponentialDistributionImpl extends AbstractContinuousDistribution
|
|||
@Deprecated
|
||||
public void setMean(double mean) {
|
||||
setMeanInternal(mean);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
/**
|
||||
* Modify the mean.
|
||||
|
@ -263,4 +264,66 @@ public class ExponentialDistributionImpl extends AbstractContinuousDistribution
|
|||
protected double getSolverAbsoluteAccuracy() {
|
||||
return solverAbsoluteAccuracy;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The lower bound of the support is always 0 no matter the mean parameter.
|
||||
*
|
||||
* @return lower bound of the support (always 0)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportLowerBound() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The upper bound of the support is always positive infinity
|
||||
* no matter the mean parameter.
|
||||
*
|
||||
* @return upper bound of the support (always Double.POSITIVE_INFINITY)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportUpperBound() {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For mean parameter <code>k</code>, the mean is
|
||||
* <code>k</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalMean() {
|
||||
return getMean();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For mean parameter <code>k</code>, the variance is
|
||||
* <code>k^2</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalVariance() {
|
||||
final double mean = getMean();
|
||||
return mean * mean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportLowerBoundInclusive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportUpperBoundInclusive() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -209,6 +209,7 @@ public class FDistributionImpl
|
|||
@Deprecated
|
||||
public void setNumeratorDegreesOfFreedom(double degreesOfFreedom) {
|
||||
setNumeratorDegreesOfFreedomInternal(degreesOfFreedom);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -243,6 +244,7 @@ public class FDistributionImpl
|
|||
@Deprecated
|
||||
public void setDenominatorDegreesOfFreedom(double degreesOfFreedom) {
|
||||
setDenominatorDegreesOfFreedomInternal(degreesOfFreedom);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -278,4 +280,93 @@ public class FDistributionImpl
|
|||
protected double getSolverAbsoluteAccuracy() {
|
||||
return solverAbsoluteAccuracy;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The lower bound of the support is always 0 no matter the parameters.
|
||||
*
|
||||
* @return lower bound of the support (always 0)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportLowerBound() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The upper bound of the support is always positive infinity
|
||||
* no matter the parameters.
|
||||
*
|
||||
* @return upper bound of the support (always Double.POSITIVE_INFINITY)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportUpperBound() {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For denominator degrees of freedom parameter <code>b</code>,
|
||||
* the mean is
|
||||
* <ul>
|
||||
* <li>if <code>b > 2</code> then <code>b / (b - 2)</code></li>
|
||||
* <li>else <code>undefined</code>
|
||||
* </ul>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalMean() {
|
||||
final double denominatorDF = getDenominatorDegreesOfFreedom();
|
||||
|
||||
if (denominatorDF > 2) {
|
||||
return denominatorDF / (denominatorDF - 2);
|
||||
}
|
||||
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For numerator degrees of freedom parameter <code>a</code>
|
||||
* and denominator degrees of freedom parameter <code>b</code>,
|
||||
* the variance is
|
||||
* <ul>
|
||||
* <li>
|
||||
* if <code>b > 4</code> then
|
||||
* <code>[ 2 * b^2 * (a + b - 2) ] / [ a * (b - 2)^2 * (b - 4) ]</code>
|
||||
* </li>
|
||||
* <li>else <code>undefined</code>
|
||||
* </ul>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalVariance() {
|
||||
final double denominatorDF = getDenominatorDegreesOfFreedom();
|
||||
|
||||
if (denominatorDF > 4) {
|
||||
final double numeratorDF = getNumeratorDegreesOfFreedom();
|
||||
final double denomDFMinusTwo = denominatorDF - 2;
|
||||
|
||||
return ( 2 * (denominatorDF * denominatorDF) * (numeratorDF + denominatorDF - 2) )
|
||||
/ ( (numeratorDF * (denomDFMinusTwo * denomDFMinusTwo) * (denominatorDF - 4)) );
|
||||
}
|
||||
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportLowerBoundInclusive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportUpperBoundInclusive() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,6 +137,7 @@ public class GammaDistributionImpl extends AbstractContinuousDistribution
|
|||
@Deprecated
|
||||
public void setAlpha(double alpha) {
|
||||
setAlphaInternal(alpha);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -170,6 +171,7 @@ public class GammaDistributionImpl extends AbstractContinuousDistribution
|
|||
@Deprecated
|
||||
public void setBeta(double newBeta) {
|
||||
setBetaInternal(newBeta);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -298,4 +300,68 @@ public class GammaDistributionImpl extends AbstractContinuousDistribution
|
|||
protected double getSolverAbsoluteAccuracy() {
|
||||
return solverAbsoluteAccuracy;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The lower bound of the support is always 0 no matter the parameters.
|
||||
*
|
||||
* @return lower bound of the support (always 0)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportLowerBound() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The upper bound of the support is always positive infinity
|
||||
* no matter the parameters.
|
||||
*
|
||||
* @return upper bound of the support (always Double.POSITIVE_INFINITY)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportUpperBound() {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For shape parameter <code>alpha</code> and scale
|
||||
* parameter <code>beta</code>, the mean is
|
||||
* <code>alpha * beta</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalMean() {
|
||||
return getAlpha() * getBeta();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For shape parameter <code>alpha</code> and scale
|
||||
* parameter <code>beta</code>, the variance is
|
||||
* <code>alpha * beta^2</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalVariance() {
|
||||
final double beta = getBeta();
|
||||
return getAlpha() * beta * beta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportLowerBoundInclusive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportUpperBoundInclusive() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -241,7 +241,9 @@ public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
|
|||
@Deprecated
|
||||
public void setNumberOfSuccesses(int num) {
|
||||
setNumberOfSuccessesInternal(num);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the number of successes.
|
||||
*
|
||||
|
@ -266,7 +268,9 @@ public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
|
|||
@Deprecated
|
||||
public void setPopulationSize(int size) {
|
||||
setPopulationSizeInternal(size);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the population size.
|
||||
*
|
||||
|
@ -291,6 +295,7 @@ public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
|
|||
@Deprecated
|
||||
public void setSampleSize(int size) {
|
||||
setSampleSizeInternal(size);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
/**
|
||||
* Modify the sample size.
|
||||
|
@ -351,4 +356,69 @@ public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For population size <code>N</code>,
|
||||
* number of successes <code>m</code>, and
|
||||
* sample size <code>n</code>,
|
||||
* the lower bound of the support is
|
||||
* <code>max(0, n + m - N)</code>
|
||||
*
|
||||
* @return lower bound of the support
|
||||
*/
|
||||
@Override
|
||||
public int getSupportLowerBound() {
|
||||
return FastMath.max(0,
|
||||
getSampleSize() + getNumberOfSuccesses() - getPopulationSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For number of successes <code>m</code> and
|
||||
* sample size <code>n</code>,
|
||||
* the upper bound of the support is
|
||||
* <code>min(m, n)</code>
|
||||
*
|
||||
* @return upper bound of the support
|
||||
*/
|
||||
@Override
|
||||
public int getSupportUpperBound() {
|
||||
return FastMath.min(getNumberOfSuccesses(), getSampleSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For population size <code>N</code>,
|
||||
* number of successes <code>m</code>, and
|
||||
* sample size <code>n</code>, the mean is
|
||||
* <code>n * m / N</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalMean() {
|
||||
return (double)(getSampleSize() * getNumberOfSuccesses()) / (double)getPopulationSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For population size <code>N</code>,
|
||||
* number of successes <code>m</code>, and
|
||||
* sample size <code>n</code>, the variance is
|
||||
* <code>[ n * m * (N - n) * (N - m) ] / [ N^2 * (N - 1) ]</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalVariance() {
|
||||
final double N = getPopulationSize();
|
||||
final double m = getNumberOfSuccesses();
|
||||
final double n = getSampleSize();
|
||||
return ( n * m * (N - n) * (N - m) ) / ( (N*N * (N - 1)) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,9 @@ public class NormalDistributionImpl extends AbstractContinuousDistribution
|
|||
@Deprecated
|
||||
public void setMean(double mean) {
|
||||
setMeanInternal(mean);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the mean.
|
||||
* @param newMean for this distribution
|
||||
|
@ -130,7 +132,9 @@ public class NormalDistributionImpl extends AbstractContinuousDistribution
|
|||
@Deprecated
|
||||
public void setStandardDeviation(double sd) {
|
||||
setStandardDeviationInternal(sd);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the standard deviation.
|
||||
* @param sd standard deviation for this distribution
|
||||
|
@ -304,4 +308,66 @@ public class NormalDistributionImpl extends AbstractContinuousDistribution
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The lower bound of the support is always negative infinity
|
||||
* no matter the parameters.
|
||||
*
|
||||
* @return lower bound of the support (always Double.NEGATIVE_INFINITY)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportLowerBound() {
|
||||
return Double.NEGATIVE_INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The upper bound of the support is always positive infinity
|
||||
* no matter the parameters.
|
||||
*
|
||||
* @return upper bound of the support (always Double.POSITIVE_INFINITY)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportUpperBound() {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For mean parameter <code>mu</code>, the mean is <code>mu</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalMean() {
|
||||
return getMean();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For standard deviation parameter <code>s</code>,
|
||||
* the variance is <code>s^2</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalVariance() {
|
||||
final double s = getStandardDeviation();
|
||||
return s * s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportLowerBoundInclusive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportUpperBoundInclusive() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,9 @@ public class PascalDistributionImpl extends AbstractIntegerDistribution
|
|||
@Deprecated
|
||||
public void setNumberOfSuccesses(int successes) {
|
||||
setNumberOfSuccessesInternal(successes);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the number of successes for this distribution.
|
||||
* @param successes the new number of successes
|
||||
|
@ -106,7 +108,9 @@ public class PascalDistributionImpl extends AbstractIntegerDistribution
|
|||
@Deprecated
|
||||
public void setProbabilityOfSuccess(double p) {
|
||||
setProbabilityOfSuccessInternal(p);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the probability of success for this distribution.
|
||||
* @param p the new probability of success
|
||||
|
@ -211,4 +215,69 @@ public class PascalDistributionImpl extends AbstractIntegerDistribution
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The lower bound of the support is always 0 no matter the parameters.
|
||||
*
|
||||
* @return lower bound of the support (always 0)
|
||||
*/
|
||||
@Override
|
||||
public int getSupportLowerBound() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The upper bound of the support is always positive infinity
|
||||
* no matter the parameters. Positive infinity is symbolised
|
||||
* by <code>Integer.MAX_VALUE</code> together with
|
||||
* {@link #isSupportUpperBoundInclusive()} being <code>false</code>
|
||||
*
|
||||
* @return upper bound of the support (always <code>Integer.MAX_VALUE</code> for positive infinity)
|
||||
*/
|
||||
@Override
|
||||
public int getSupportUpperBound() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For number of successes <code>r</code> and
|
||||
* probability of success <code>p</code>, the mean is
|
||||
* <code>( r * p ) / ( 1 - p )</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalMean() {
|
||||
final double p = getProbabilityOfSuccess();
|
||||
final double r = getNumberOfSuccesses();
|
||||
return ( r * p ) / ( 1 - p );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For number of successes <code>r</code> and
|
||||
* probability of success <code>p</code>, the mean is
|
||||
* <code>( r * p ) / ( 1 - p )^2</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalVariance() {
|
||||
final double p = getProbabilityOfSuccess();
|
||||
final double r = getNumberOfSuccesses();
|
||||
final double pInv = 1 - p;
|
||||
return ( r * p ) / (pInv * pInv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportUpperBoundInclusive() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -157,6 +157,7 @@ public class PoissonDistributionImpl extends AbstractIntegerDistribution
|
|||
@Deprecated
|
||||
public void setMean(double p) {
|
||||
setNormalAndMeanInternal(normal, p);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
/**
|
||||
* Set the Poisson mean for the distribution. The mean value must be
|
||||
|
@ -300,4 +301,60 @@ public class PoissonDistributionImpl extends AbstractIntegerDistribution
|
|||
public void setNormal(NormalDistribution value) {
|
||||
setNormalAndMeanInternal(value, mean);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The lower bound of the support is always 0 no matter the mean parameter.
|
||||
*
|
||||
* @return lower bound of the support (always 0)
|
||||
*/
|
||||
@Override
|
||||
public int getSupportLowerBound() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The upper bound of the support is positive infinity,
|
||||
* regardless of the parameter values. There is no integer infinity,
|
||||
* so this method returns <code>Integer.MAX_VALUE</code> and
|
||||
* {@link #isSupportUpperBoundInclusive()} returns <code>true</code>.
|
||||
*
|
||||
* @return upper bound of the support (always <code>Integer.MAX_VALUE</code> for positive infinity)
|
||||
*/
|
||||
@Override
|
||||
public int getSupportUpperBound() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For mean parameter <code>p</code>, the mean is <code>p</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalMean() {
|
||||
return getMean();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For mean parameter <code>p</code>, the variance is <code>p</code>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalVariance() {
|
||||
return getMean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportUpperBoundInclusive() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,7 +81,9 @@ public class TDistributionImpl
|
|||
@Deprecated
|
||||
public void setDegreesOfFreedom(double degreesOfFreedom) {
|
||||
setDegreesOfFreedomInternal(degreesOfFreedom);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the degrees of freedom.
|
||||
* @param newDegreesOfFreedom the new degrees of freedom.
|
||||
|
@ -223,4 +225,89 @@ public class TDistributionImpl
|
|||
protected double getSolverAbsoluteAccuracy() {
|
||||
return solverAbsoluteAccuracy;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The lower bound of the support is always negative infinity
|
||||
* no matter the parameters.
|
||||
*
|
||||
* @return lower bound of the support (always Double.NEGATIVE_INFINITY)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportLowerBound() {
|
||||
return Double.NEGATIVE_INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The upper bound of the support is always positive infinity
|
||||
* no matter the parameters.
|
||||
*
|
||||
* @return upper bound of the support (always Double.POSITIVE_INFINITY)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportUpperBound() {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For degrees of freedom parameter df, the mean is
|
||||
* <ul>
|
||||
* <li>if <code>df > 1</code> then <code>0</code></li>
|
||||
* <li>else <code>undefined</code></li>
|
||||
* </ul>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalMean() {
|
||||
final double df = getDegreesOfFreedom();
|
||||
|
||||
if (df > 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For degrees of freedom parameter df, the variance is
|
||||
* <ul>
|
||||
* <li>if <code>df > 2</code> then <code>df / (df - 2)</code> </li>
|
||||
* <li>if <code>1 < df <= 2</code> then <code>positive infinity</code></li>
|
||||
* <li>else <code>undefined</code></li>
|
||||
* </ul>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalVariance() {
|
||||
final double df = getDegreesOfFreedom();
|
||||
|
||||
if (df > 2) {
|
||||
return df / (df - 2);
|
||||
}
|
||||
|
||||
if (df > 1 && df <= 2) {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportLowerBoundInclusive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportUpperBoundInclusive() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.io.Serializable;
|
|||
|
||||
import org.apache.commons.math.MathRuntimeException;
|
||||
import org.apache.commons.math.exception.util.LocalizedFormats;
|
||||
import org.apache.commons.math.special.Gamma;
|
||||
import org.apache.commons.math.util.FastMath;
|
||||
|
||||
/**
|
||||
|
@ -170,6 +171,7 @@ public class WeibullDistributionImpl extends AbstractContinuousDistribution
|
|||
@Deprecated
|
||||
public void setShape(double alpha) {
|
||||
setShapeInternal(alpha);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
/**
|
||||
* Modify the shape parameter.
|
||||
|
@ -192,6 +194,7 @@ public class WeibullDistributionImpl extends AbstractContinuousDistribution
|
|||
@Deprecated
|
||||
public void setScale(double beta) {
|
||||
setScaleInternal(beta);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
/**
|
||||
* Modify the scale parameter.
|
||||
|
@ -259,4 +262,75 @@ public class WeibullDistributionImpl extends AbstractContinuousDistribution
|
|||
protected double getSolverAbsoluteAccuracy() {
|
||||
return solverAbsoluteAccuracy;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The lower bound of the support is always 0 no matter the parameters.
|
||||
*
|
||||
* @return lower bound of the support (always 0)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportLowerBound() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The upper bound of the support is always positive infinity
|
||||
* no matter the parameters.
|
||||
*
|
||||
* @return upper bound of the support (always Double.POSITIVE_INFINITY)
|
||||
*/
|
||||
@Override
|
||||
public double getSupportUpperBound() {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The mean is <code>scale * Gamma(1 + (1 / shape))</code>
|
||||
* where <code>Gamma(...)</code> is the Gamma-function
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalMean() {
|
||||
final double shape = getShape();
|
||||
final double scale = getScale();
|
||||
|
||||
return scale * FastMath.exp(Gamma.logGamma(1 + (1 / shape)));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The variance is
|
||||
* <code>scale^2 * Gamma(1 + (2 / shape)) - mean^2</code>
|
||||
* where <code>Gamma(...)</code> is the Gamma-function
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalVariance() {
|
||||
final double shape = getShape();
|
||||
final double scale = getScale();
|
||||
final double mean = getNumericalMean();
|
||||
|
||||
return (scale * scale) *
|
||||
FastMath.exp(Gamma.logGamma(1 + (2 / shape))) -
|
||||
(mean * mean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportLowerBoundInclusive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportUpperBoundInclusive() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ public class ZipfDistributionImpl extends AbstractIntegerDistribution
|
|||
@Deprecated
|
||||
public void setNumberOfElements(final int n) {
|
||||
setNumberOfElementsInternal(n);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
/**
|
||||
* Set the number of elements (e.g. corpus size) for the distribution.
|
||||
|
@ -115,7 +116,9 @@ public class ZipfDistributionImpl extends AbstractIntegerDistribution
|
|||
@Deprecated
|
||||
public void setExponent(final double s) {
|
||||
setExponentInternal(s);
|
||||
invalidateParameterDependentMoments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the exponent characterising the distribution.
|
||||
* The parameter value must be positive; otherwise an
|
||||
|
@ -211,4 +214,75 @@ public class ZipfDistributionImpl extends AbstractIntegerDistribution
|
|||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The lower bound of the support is always 1 no matter the parameters.
|
||||
*
|
||||
* @return lower bound of the support (always 1)
|
||||
*/
|
||||
@Override
|
||||
public int getSupportLowerBound() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* The upper bound of the support is the number of elements
|
||||
*
|
||||
* @return upper bound of the support
|
||||
*/
|
||||
@Override
|
||||
public int getSupportUpperBound() {
|
||||
return getNumberOfElements();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For number of elements N and exponent s, the mean is
|
||||
* <code>Hs1 / Hs</code> where
|
||||
* <ul>
|
||||
* <li><code>Hs1 = generalizedHarmonic(N, s - 1)</code></li>
|
||||
* <li><code>Hs = generalizedHarmonic(N, s)</code></li>
|
||||
* </ul>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalMean() {
|
||||
final int N = getNumberOfElements();
|
||||
final double s = getExponent();
|
||||
|
||||
final double Hs1 = generalizedHarmonic(N, s - 1);
|
||||
final double Hs = generalizedHarmonic(N, s);
|
||||
|
||||
return Hs1 / Hs;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* For number of elements N and exponent s, the mean is
|
||||
* <code>(Hs2 / Hs) - (Hs1^2 / Hs^2)</code> where
|
||||
* <ul>
|
||||
* <li><code>Hs2 = generalizedHarmonic(N, s - 2)</code></li>
|
||||
* <li><code>Hs1 = generalizedHarmonic(N, s - 1)</code></li>
|
||||
* <li><code>Hs = generalizedHarmonic(N, s)</code></li>
|
||||
* </ul>
|
||||
*
|
||||
* @return {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected double calculateNumericalVariance() {
|
||||
final int N = getNumberOfElements();
|
||||
final double s = getExponent();
|
||||
|
||||
final double Hs2 = generalizedHarmonic(N, s - 2);
|
||||
final double Hs1 = generalizedHarmonic(N, s - 1);
|
||||
final double Hs = generalizedHarmonic(N, s);
|
||||
|
||||
return (Hs2 / Hs) - ((Hs1 * Hs1) / (Hs * Hs));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.apache.commons.math.distribution;
|
|||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.commons.math.MathException;
|
||||
import org.apache.commons.math.util.FastMath;
|
||||
|
||||
public class BetaDistributionTest extends TestCase {
|
||||
public void testCumulative() throws MathException {
|
||||
|
@ -286,4 +287,18 @@ public class BetaDistributionTest extends TestCase {
|
|||
assertEquals(String.format("density at x=%.1f for alpha=%.1f, beta=%.1f", x[i], alpha, beta), expected[i], d.density(x[i]), 1e-5);
|
||||
}
|
||||
}
|
||||
|
||||
public void testMomonts() {
|
||||
final double tol = 1e-9;
|
||||
BetaDistribution dist;
|
||||
|
||||
dist = new BetaDistributionImpl(1, 1);
|
||||
assertEquals(dist.getNumericalMean(), 0.5, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 1.0 / 12.0, tol);
|
||||
|
||||
dist.setAlpha(2);
|
||||
dist.setBeta(5);
|
||||
assertEquals(dist.getNumericalMean(), 2.0 / 7.0, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 10.0 / (49.0 * 8.0), tol);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,4 +113,18 @@ public class BinomialDistributionTest extends IntegerDistributionAbstractTest {
|
|||
verifyInverseCumulativeProbabilities();
|
||||
}
|
||||
|
||||
public void testMomonts() {
|
||||
final double tol = 1e-9;
|
||||
BinomialDistribution dist;
|
||||
|
||||
dist = new BinomialDistributionImpl(10, 0.5);
|
||||
assertEquals(dist.getNumericalMean(), 10d * 0.5d, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 10d * 0.5d * 0.5d, tol);
|
||||
|
||||
dist.setNumberOfTrials(30);
|
||||
dist.setProbabilityOfSuccess(0.3);
|
||||
assertEquals(dist.getNumericalMean(), 30d * 0.3d, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 30d * 0.3d * (1d - 0.3d), tol);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -113,4 +113,18 @@ public class CauchyDistributionTest extends ContinuousDistributionAbstractTest
|
|||
// success
|
||||
}
|
||||
}
|
||||
|
||||
public void testMomonts() {
|
||||
final double tol = 1e-9;
|
||||
CauchyDistribution dist;
|
||||
|
||||
dist = new CauchyDistributionImpl(10.2, 0.15);
|
||||
assertEquals(dist.getNumericalMean(), Double.NaN, tol);
|
||||
assertEquals(dist.getNumericalVariance(), Double.NaN, tol);
|
||||
|
||||
dist.setMedian(23.12);
|
||||
dist.setScale(2.12);
|
||||
assertEquals(dist.getNumericalMean(), Double.NaN, tol);
|
||||
assertEquals(dist.getNumericalVariance(), Double.NaN, tol);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,4 +132,17 @@ public class ChiSquareDistributionTest extends ContinuousDistributionAbstractTes
|
|||
}
|
||||
}
|
||||
|
||||
public void testMomonts() {
|
||||
final double tol = 1e-9;
|
||||
ChiSquaredDistribution dist;
|
||||
|
||||
dist = new ChiSquaredDistributionImpl(1500);
|
||||
assertEquals(dist.getNumericalMean(), 1500, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 3000, tol);
|
||||
|
||||
dist.setDegreesOfFreedom(1.12);
|
||||
assertEquals(dist.getNumericalMean(), 1.12, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 2.24, tol);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -121,4 +121,17 @@ public class ExponentialDistributionTest extends ContinuousDistributionAbstractT
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void testMomonts() {
|
||||
final double tol = 1e-9;
|
||||
ExponentialDistribution dist;
|
||||
|
||||
dist = new ExponentialDistributionImpl(11d);
|
||||
assertEquals(dist.getNumericalMean(), 11d, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 11d * 11d, tol);
|
||||
|
||||
dist.setMean(10.5d);
|
||||
assertEquals(dist.getNumericalMean(), 10.5d, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 10.5d * 10.5d, tol);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,4 +129,22 @@ public class FDistributionTest extends ContinuousDistributionAbstractTest {
|
|||
assertEquals(0.975, x, 1.0e-5);
|
||||
}
|
||||
|
||||
public void testMomonts() {
|
||||
final double tol = 1e-9;
|
||||
FDistribution dist;
|
||||
|
||||
dist = new FDistributionImpl(1, 2);
|
||||
assertEquals(dist.getNumericalMean(), Double.NaN, tol);
|
||||
assertEquals(dist.getNumericalVariance(), Double.NaN, tol);
|
||||
|
||||
dist.setNumeratorDegreesOfFreedom(1);
|
||||
dist.setDenominatorDegreesOfFreedom(3);
|
||||
assertEquals(dist.getNumericalMean(), 3d / (3d - 2d), tol);
|
||||
assertEquals(dist.getNumericalVariance(), Double.NaN, tol);
|
||||
|
||||
dist.setNumeratorDegreesOfFreedom(1);
|
||||
dist.setDenominatorDegreesOfFreedom(5);
|
||||
assertEquals(dist.getNumericalMean(), 5d / (5d - 2d), tol);
|
||||
assertEquals(dist.getNumericalVariance(), (2d * 5d * 5d * 4d) / 9d, tol);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,4 +152,18 @@ public class GammaDistributionTest extends ContinuousDistributionAbstractTest {
|
|||
setInverseCumulativeTestValues(new double[] {0, Double.POSITIVE_INFINITY});
|
||||
verifyInverseCumulativeProbabilities();
|
||||
}
|
||||
|
||||
public void testMomonts() {
|
||||
final double tol = 1e-9;
|
||||
GammaDistribution dist;
|
||||
|
||||
dist = new GammaDistributionImpl(1, 2);
|
||||
assertEquals(dist.getNumericalMean(), 2, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 4, tol);
|
||||
|
||||
dist.setAlpha(1.1);
|
||||
dist.setBeta(4.2);
|
||||
assertEquals(dist.getNumericalMean(), 1.1d * 4.2d, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 1.1d * 4.2d * 4.2d, tol);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,4 +211,19 @@ public class HypergeometricDistributionTest extends IntegerDistributionAbstractT
|
|||
};
|
||||
testHypergeometricDistributionProbabilities(populationSize, sampleSize, numberOfSucceses, data);
|
||||
}
|
||||
|
||||
public void testMomonts() {
|
||||
final double tol = 1e-9;
|
||||
HypergeometricDistribution dist;
|
||||
|
||||
dist = new HypergeometricDistributionImpl(1500, 40, 100);
|
||||
assertEquals(dist.getNumericalMean(), 40d * 100d / 1500d, tol);
|
||||
assertEquals(dist.getNumericalVariance(), ( 100d * 40d * (1500d - 100d) * (1500d - 40d) ) / ( (1500d * 1500d * 1499d) ), tol);
|
||||
|
||||
dist.setPopulationSize(3000);
|
||||
dist.setNumberOfSuccesses(55);
|
||||
dist.setSampleSize(200);
|
||||
assertEquals(dist.getNumericalMean(), 55d * 200d / 3000d, tol);
|
||||
assertEquals(dist.getNumericalVariance(), ( 200d * 55d * (3000d - 200d) * (3000d - 55d) ) / ( (3000d * 3000d * 2999d) ), tol);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -204,4 +204,22 @@ public class NormalDistributionTest extends ContinuousDistributionAbstractTest
|
|||
assertEquals(2.0, result, defaultTolerance);
|
||||
}
|
||||
|
||||
public void testMomonts() {
|
||||
final double tol = 1e-9;
|
||||
NormalDistribution dist;
|
||||
|
||||
dist = new NormalDistributionImpl(0, 1);
|
||||
assertEquals(dist.getNumericalMean(), 0, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 1, tol);
|
||||
|
||||
dist.setMean(2.2);
|
||||
dist.setStandardDeviation(1.4);
|
||||
assertEquals(dist.getNumericalMean(), 2.2, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 1.4 * 1.4, tol);
|
||||
|
||||
dist.setMean(-2000.9);
|
||||
dist.setStandardDeviation(10.4);
|
||||
assertEquals(dist.getNumericalMean(), -2000.9, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 10.4 * 10.4, tol);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,4 +119,18 @@ public class PascalDistributionTest extends IntegerDistributionAbstractTest {
|
|||
verifyCumulativeProbabilities();
|
||||
verifyInverseCumulativeProbabilities();
|
||||
}
|
||||
|
||||
public void testMomonts() {
|
||||
final double tol = 1e-9;
|
||||
PascalDistribution dist;
|
||||
|
||||
dist = new PascalDistributionImpl(10, 0.5);
|
||||
assertEquals(dist.getNumericalMean(), ( 10d * 0.5d ) / 0.5d, tol);
|
||||
assertEquals(dist.getNumericalVariance(), ( 10d * 0.5d ) / (0.5d * 0.5d), tol);
|
||||
|
||||
dist.setNumberOfSuccesses(25);
|
||||
dist.setProbabilityOfSuccess(0.3);
|
||||
assertEquals(dist.getNumericalMean(), ( 25d * 0.3d ) / 0.7d, tol);
|
||||
assertEquals(dist.getNumericalVariance(), ( 25d * 0.3d ) / (0.7d * 0.7d), tol);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -217,4 +217,17 @@ public class PoissonDistributionTest extends IntegerDistributionAbstractTest {
|
|||
mean *= 10.0;
|
||||
}
|
||||
}
|
||||
|
||||
public void testMomonts() {
|
||||
final double tol = 1e-9;
|
||||
PoissonDistribution dist;
|
||||
|
||||
dist = new PoissonDistributionImpl(1);
|
||||
assertEquals(dist.getNumericalMean(), 1, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 1, tol);
|
||||
|
||||
dist.setMean(11.23);
|
||||
assertEquals(dist.getNumericalMean(), 11.23, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 11.23, tol);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,4 +116,20 @@ public class TDistributionTest extends ContinuousDistributionAbstractTest {
|
|||
}
|
||||
}
|
||||
|
||||
public void testMomonts() {
|
||||
final double tol = 1e-9;
|
||||
TDistribution dist;
|
||||
|
||||
dist = new TDistributionImpl(1);
|
||||
assertEquals(dist.getNumericalMean(), Double.NaN, tol);
|
||||
assertEquals(dist.getNumericalVariance(), Double.NaN, tol);
|
||||
|
||||
dist.setDegreesOfFreedom(1.5);
|
||||
assertEquals(dist.getNumericalMean(), 0, tol);
|
||||
assertEquals(dist.getNumericalVariance(), Double.POSITIVE_INFINITY, tol);
|
||||
|
||||
dist.setDegreesOfFreedom(5);
|
||||
assertEquals(dist.getNumericalMean(), 0, tol);
|
||||
assertEquals(dist.getNumericalVariance(), 5d / (5d - 2d), tol);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.commons.math.distribution;
|
||||
|
||||
import org.apache.commons.math.special.Gamma;
|
||||
import org.apache.commons.math.util.FastMath;
|
||||
|
||||
/**
|
||||
|
@ -121,4 +122,23 @@ public class WeibullDistributionTest extends ContinuousDistributionAbstractTest
|
|||
// success
|
||||
}
|
||||
}
|
||||
|
||||
public void testMomonts() {
|
||||
final double tol = 1e-9;
|
||||
WeibullDistribution dist;
|
||||
|
||||
dist = new WeibullDistributionImpl(2.5, 3.5);
|
||||
// In R: 3.5*gamma(1+(1/2.5)) (or emperically: mean(rweibull(10000, 2.5, 3.5)))
|
||||
assertEquals(dist.getNumericalMean(), 3.5 * FastMath.exp(Gamma.logGamma(1 + (1 / 2.5))), tol);
|
||||
assertEquals(dist.getNumericalVariance(), (3.5 * 3.5) *
|
||||
FastMath.exp(Gamma.logGamma(1 + (2 / 2.5))) -
|
||||
(dist.getNumericalMean() * dist.getNumericalMean()), tol);
|
||||
|
||||
dist.setShape(10.4);
|
||||
dist.setScale(2.222);
|
||||
assertEquals(dist.getNumericalMean(), 2.222 * FastMath.exp(Gamma.logGamma(1 + (1 / 10.4))), tol);
|
||||
assertEquals(dist.getNumericalVariance(), (2.222 * 2.222) *
|
||||
FastMath.exp(Gamma.logGamma(1 + (2 / 10.4))) -
|
||||
(dist.getNumericalMean() * dist.getNumericalMean()), tol);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.apache.commons.math.distribution;
|
||||
|
||||
import org.apache.commons.math.util.FastMath;
|
||||
|
||||
/**
|
||||
* Test cases for {@link ZipfDistribution}.
|
||||
* Extends IntegerDistributionAbstractTest. See class javadoc for
|
||||
|
@ -75,4 +77,13 @@ public class ZipfDistributionTest extends IntegerDistributionAbstractTest {
|
|||
public int[] makeInverseCumulativeTestValues() {
|
||||
return new int[] {0, 0, 0, 0, 0, 0, 1, 9, 9, 9, 8, 7, 10};
|
||||
}
|
||||
|
||||
public void testMomonts() {
|
||||
final double tol = 1e-9;
|
||||
ZipfDistribution dist;
|
||||
|
||||
dist = new ZipfDistributionImpl(2, 0.5);
|
||||
assertEquals(dist.getNumericalMean(), FastMath.sqrt(2), tol);
|
||||
assertEquals(dist.getNumericalVariance(), 0.24264068711928521, tol);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue