diff --git a/src/main/java/org/apache/commons/math/distribution/AbstractContinuousDistribution.java b/src/main/java/org/apache/commons/math/distribution/AbstractContinuousDistribution.java
index 0fce633cc..7f232c19c 100644
--- a/src/main/java/org/apache/commons/math/distribution/AbstractContinuousDistribution.java
+++ b/src/main/java/org/apache/commons/math/distribution/AbstractContinuousDistribution.java
@@ -219,4 +219,18 @@ public abstract class AbstractContinuousDistribution
protected double getSolverAbsoluteAccuracy() {
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();
}
diff --git a/src/main/java/org/apache/commons/math/distribution/AbstractDistribution.java b/src/main/java/org/apache/commons/math/distribution/AbstractDistribution.java
index 7d4a1ce7d..ed59f6743 100644
--- a/src/main/java/org/apache/commons/math/distribution/AbstractDistribution.java
+++ b/src/main/java/org/apache/commons/math/distribution/AbstractDistribution.java
@@ -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.
*/
@@ -65,4 +71,93 @@ public abstract class AbstractDistribution
}
return cumulativeProbability(x1) - cumulativeProbability(x0);
}
+
+ /**
+ * 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;
+ }
}
diff --git a/src/main/java/org/apache/commons/math/distribution/AbstractIntegerDistribution.java b/src/main/java/org/apache/commons/math/distribution/AbstractIntegerDistribution.java
index 256fe7428..7625c0333 100644
--- a/src/main/java/org/apache/commons/math/distribution/AbstractIntegerDistribution.java
+++ b/src/main/java/org/apache/commons/math/distribution/AbstractIntegerDistribution.java
@@ -289,4 +289,42 @@ public abstract class AbstractIntegerDistribution extends AbstractDistribution
* @return the domain value upper bound, i.e. {@code P(X < 'upper bound') > p}.
*/
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;
+ }
}
diff --git a/src/main/java/org/apache/commons/math/distribution/BetaDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/BetaDistributionImpl.java
index 06812be8a..f02bb2cb4 100644
--- a/src/main/java/org/apache/commons/math/distribution/BetaDistributionImpl.java
+++ b/src/main/java/org/apache/commons/math/distribution/BetaDistributionImpl.java
@@ -184,4 +184,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 s1
and
+ * second shape parameter s2
, the mean is
+ * s1 / (s1 + s2)
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected double calculateNumericalMean() {
+ final double alpha = getAlpha();
+ return alpha / (alpha + getBeta());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For first shape parameter s1
and
+ * second shape parameter s2
,
+ * the variance is
+ * [ s1 * s2 ] / [ (s1 + s2)^2 * (s1 + s2 + 1) ]
+ *
+ * @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;
+ }
}
diff --git a/src/main/java/org/apache/commons/math/distribution/BinomialDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/BinomialDistributionImpl.java
index a75b1f53a..dcea662de 100644
--- a/src/main/java/org/apache/commons/math/distribution/BinomialDistributionImpl.java
+++ b/src/main/java/org/apache/commons/math/distribution/BinomialDistributionImpl.java
@@ -164,4 +164,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 n
number of trials and
+ * probability parameter p
, the mean is
+ * n * p
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected double calculateNumericalMean() {
+ return (double)getNumberOfTrials() * getProbabilityOfSuccess();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For n
number of trials and
+ * probability parameter p
, the variance is
+ * n * p * (1 - p)
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected double calculateNumericalVariance() {
+ final double p = getProbabilityOfSuccess();
+ return (double)getNumberOfTrials() * p * (1 - p);
+ }
}
diff --git a/src/main/java/org/apache/commons/math/distribution/CauchyDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/CauchyDistributionImpl.java
index 7d13c8afd..b67fc2236 100644
--- a/src/main/java/org/apache/commons/math/distribution/CauchyDistributionImpl.java
+++ b/src/main/java/org/apache/commons/math/distribution/CauchyDistributionImpl.java
@@ -163,7 +163,7 @@ public class CauchyDistributionImpl extends AbstractContinuousDistribution
}
return ret;
- }
+ }
/**
* Access the domain value upper bound, based on p
, used to
@@ -220,4 +220,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;
+ }
}
diff --git a/src/main/java/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.java
index 7a78be737..2ea2fe3b4 100644
--- a/src/main/java/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.java
+++ b/src/main/java/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.java
@@ -193,4 +193,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 k
degrees of freedom, the mean is
+ * k
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected double calculateNumericalMean() {
+ return getDegreesOfFreedom();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For k
degrees of freedom, the variance is
+ * 2 * k
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected double calculateNumericalVariance() {
+ return 2*getDegreesOfFreedom();
+ }
+
+ @Override
+ public boolean isSupportLowerBoundInclusive() {
+ return true;
+ }
+
+ @Override
+ public boolean isSupportUpperBoundInclusive() {
+ return false;
+ }
}
diff --git a/src/main/java/org/apache/commons/math/distribution/Distribution.java b/src/main/java/org/apache/commons/math/distribution/Distribution.java
index fda80033b..3edc3a4d2 100644
--- a/src/main/java/org/apache/commons/math/distribution/Distribution.java
+++ b/src/main/java/org/apache/commons/math/distribution/Distribution.java
@@ -52,4 +52,59 @@ public interface Distribution {
* @throws IllegalArgumentException if x0 > x1
*/
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();
}
diff --git a/src/main/java/org/apache/commons/math/distribution/ExponentialDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/ExponentialDistributionImpl.java
index 5782c0462..1e685d499 100644
--- a/src/main/java/org/apache/commons/math/distribution/ExponentialDistributionImpl.java
+++ b/src/main/java/org/apache/commons/math/distribution/ExponentialDistributionImpl.java
@@ -222,4 +222,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 k
, the mean is
+ * k
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected double calculateNumericalMean() {
+ return getMean();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For mean parameter k
, the variance is
+ * k^2
+ *
+ * @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;
+ }
}
diff --git a/src/main/java/org/apache/commons/math/distribution/FDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/FDistributionImpl.java
index 8fdf19ebe..88fd82b08 100644
--- a/src/main/java/org/apache/commons/math/distribution/FDistributionImpl.java
+++ b/src/main/java/org/apache/commons/math/distribution/FDistributionImpl.java
@@ -235,4 +235,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 b
,
+ * the mean is
+ *
b > 2
then b / (b - 2)
undefined
+ * a
+ * and denominator degrees of freedom parameter b
,
+ * the variance is
+ * b > 4
then
+ * [ 2 * b^2 * (a + b - 2) ] / [ a * (b - 2)^2 * (b - 4) ]
+ * undefined
+ * alpha
and scale
+ * parameter beta
, the mean is
+ * alpha * beta
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected double calculateNumericalMean() {
+ return getAlpha() * getBeta();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For shape parameter alpha
and scale
+ * parameter beta
, the variance is
+ * alpha * beta^2
+ *
+ * @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;
+ }
}
diff --git a/src/main/java/org/apache/commons/math/distribution/HypergeometricDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/HypergeometricDistributionImpl.java
index 9fca2f2bb..0c7fb5ca1 100644
--- a/src/main/java/org/apache/commons/math/distribution/HypergeometricDistributionImpl.java
+++ b/src/main/java/org/apache/commons/math/distribution/HypergeometricDistributionImpl.java
@@ -284,4 +284,69 @@ public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
}
return ret;
}
+
+ /**
+ * {@inheritDoc}
+ *
+ * For population size N
,
+ * number of successes m
, and
+ * sample size n
,
+ * the lower bound of the support is
+ * max(0, n + m - N)
+ *
+ * @return lower bound of the support
+ */
+ @Override
+ public int getSupportLowerBound() {
+ return FastMath.max(0,
+ getSampleSize() + getNumberOfSuccesses() - getPopulationSize());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For number of successes m
and
+ * sample size n
,
+ * the upper bound of the support is
+ * min(m, n)
+ *
+ * @return upper bound of the support
+ */
+ @Override
+ public int getSupportUpperBound() {
+ return FastMath.min(getNumberOfSuccesses(), getSampleSize());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For population size N
,
+ * number of successes m
, and
+ * sample size n
, the mean is
+ * n * m / N
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected double calculateNumericalMean() {
+ return (double)(getSampleSize() * getNumberOfSuccesses()) / (double)getPopulationSize();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For population size N
,
+ * number of successes m
, and
+ * sample size n
, the variance is
+ * [ n * m * (N - n) * (N - m) ] / [ N^2 * (N - 1) ]
+ *
+ * @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)) );
+ }
}
diff --git a/src/main/java/org/apache/commons/math/distribution/NormalDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/NormalDistributionImpl.java
index 4f3a618d8..7a5bec6df 100644
--- a/src/main/java/org/apache/commons/math/distribution/NormalDistributionImpl.java
+++ b/src/main/java/org/apache/commons/math/distribution/NormalDistributionImpl.java
@@ -241,4 +241,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 mu
, the mean is mu
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected double calculateNumericalMean() {
+ return getMean();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For standard deviation parameter s
,
+ * the variance is s^2
+ *
+ * @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;
+ }
}
diff --git a/src/main/java/org/apache/commons/math/distribution/PascalDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/PascalDistributionImpl.java
index 3f2d7dd1e..9e7029fd7 100644
--- a/src/main/java/org/apache/commons/math/distribution/PascalDistributionImpl.java
+++ b/src/main/java/org/apache/commons/math/distribution/PascalDistributionImpl.java
@@ -165,4 +165,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 Integer.MAX_VALUE
together with
+ * {@link #isSupportUpperBoundInclusive()} being false
+ *
+ * @return upper bound of the support (always Integer.MAX_VALUE
for positive infinity)
+ */
+ @Override
+ public int getSupportUpperBound() {
+ return Integer.MAX_VALUE;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For number of successes r
and
+ * probability of success p
, the mean is
+ * ( r * p ) / ( 1 - p )
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected double calculateNumericalMean() {
+ final double p = getProbabilityOfSuccess();
+ final double r = getNumberOfSuccesses();
+ return ( r * p ) / ( 1 - p );
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For number of successes r
and
+ * probability of success p
, the mean is
+ * ( r * p ) / ( 1 - p )^2
+ *
+ * @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;
+ }
}
diff --git a/src/main/java/org/apache/commons/math/distribution/PoissonDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/PoissonDistributionImpl.java
index 35261f5f7..688850c13 100644
--- a/src/main/java/org/apache/commons/math/distribution/PoissonDistributionImpl.java
+++ b/src/main/java/org/apache/commons/math/distribution/PoissonDistributionImpl.java
@@ -230,4 +230,60 @@ public class PoissonDistributionImpl extends AbstractIntegerDistribution
protected int getDomainUpperBound(double p) {
return Integer.MAX_VALUE;
}
+
+ /**
+ * {@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 Integer.MAX_VALUE
and
+ * {@link #isSupportUpperBoundInclusive()} returns true
.
+ *
+ * @return upper bound of the support (always Integer.MAX_VALUE
for positive infinity)
+ */
+ @Override
+ public int getSupportUpperBound() {
+ return Integer.MAX_VALUE;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For mean parameter p
, the mean is p
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected double calculateNumericalMean() {
+ return getMean();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For mean parameter p
, the variance is p
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ protected double calculateNumericalVariance() {
+ return getMean();
+ }
+
+ @Override
+ public boolean isSupportUpperBoundInclusive() {
+ return true;
+ }
}
diff --git a/src/main/java/org/apache/commons/math/distribution/TDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/TDistributionImpl.java
index 3b0daadb2..1255a2b6f 100644
--- a/src/main/java/org/apache/commons/math/distribution/TDistributionImpl.java
+++ b/src/main/java/org/apache/commons/math/distribution/TDistributionImpl.java
@@ -199,4 +199,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
+ * df > 1
then 0
undefined
df > 2
then df / (df - 2)
1 < df <= 2
then positive infinity
undefined
scale * Gamma(1 + (1 / shape))
+ * where Gamma(...)
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
+ * scale^2 * Gamma(1 + (2 / shape)) - mean^2
+ * where Gamma(...)
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;
+ }
}
diff --git a/src/main/java/org/apache/commons/math/distribution/ZipfDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/ZipfDistributionImpl.java
index 928ae8514..40e793017 100644
--- a/src/main/java/org/apache/commons/math/distribution/ZipfDistributionImpl.java
+++ b/src/main/java/org/apache/commons/math/distribution/ZipfDistributionImpl.java
@@ -147,4 +147,76 @@ 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
+ * Hs1 / Hs
where
+ * Hs1 = generalizedHarmonic(N, s - 1)
Hs = generalizedHarmonic(N, s)
(Hs2 / Hs) - (Hs1^2 / Hs^2)
where
+ * Hs2 = generalizedHarmonic(N, s - 2)
Hs1 = generalizedHarmonic(N, s - 1)
Hs = generalizedHarmonic(N, s)