diff --git a/commons-math-legacy/pom.xml b/commons-math-legacy/pom.xml
index 06148bdfac..04f70542f4 100644
--- a/commons-math-legacy/pom.xml
+++ b/commons-math-legacy/pom.xml
@@ -56,6 +56,11 @@
* Throws
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.summary.SumOfLogs}.
*
* @param values the input array
* @return the sum of the natural logs of the values or Double.NaN if the array is empty
* @throws MathIllegalArgumentException if the array is null
*/
public static double sumLog(final double[] values) throws MathIllegalArgumentException {
- return SUM_OF_LOGS.evaluate(values);
+ if (verifyValues(values)) {
+ return SumOfLogs.of(values).getAsDouble();
+ }
+ return Double.NaN;
}
/**
@@ -199,8 +188,6 @@ public static double sumLog(final double[] values) throws MathIllegalArgumentExc
* the input array, or
* Throws
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.summary.SumOfLogs}.
*
* @param values the input array
* @param begin index of the first array element to include
@@ -212,7 +199,10 @@ public static double sumLog(final double[] values) throws MathIllegalArgumentExc
*/
public static double sumLog(final double[] values, final int begin, final int length)
throws MathIllegalArgumentException {
- return SUM_OF_LOGS.evaluate(values, begin, length);
+ if (MathArrays.verifyValues(values, begin, length)) {
+ return SumOfLogs.ofRange(values, begin, begin + length).getAsDouble();
+ }
+ return Double.NaN;
}
/**
@@ -220,16 +210,16 @@ public static double sumLog(final double[] values, final int begin, final int le
*
* Throws
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.moment.Mean} for
- * details on the computing algorithm.
*
* @param values the input array
* @return the mean of the values or Double.NaN if the array is empty
* @throws MathIllegalArgumentException if the array is null
*/
public static double mean(final double[] values) throws MathIllegalArgumentException {
- return MEAN.evaluate(values);
+ if (verifyValues(values)) {
+ return org.apache.commons.statistics.descriptive.Mean.of(values).getAsDouble();
+ }
+ return Double.NaN;
}
/**
@@ -238,9 +228,6 @@ public static double mean(final double[] values) throws MathIllegalArgumentExcep
* is empty.
*
* Throws
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.moment.Mean Mean} for
- * details on the computing algorithm.
*
* @param values the input array
* @param begin index of the first array element to include
@@ -251,7 +238,11 @@ public static double mean(final double[] values) throws MathIllegalArgumentExcep
*/
public static double mean(final double[] values, final int begin, final int length)
throws MathIllegalArgumentException {
- return MEAN.evaluate(values, begin, length);
+ if (MathArrays.verifyValues(values, begin, length)) {
+ return org.apache.commons.statistics.descriptive.Mean.ofRange(values, begin, begin + length)
+ .getAsDouble();
+ }
+ return Double.NaN;
}
/**
@@ -259,16 +250,16 @@ public static double mean(final double[] values, final int begin, final int leng
*
* Throws
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.moment.GeometricMean GeometricMean}
- * for details on the computing algorithm.
*
* @param values the input array
* @return the geometric mean of the values or Double.NaN if the array is empty
* @throws MathIllegalArgumentException if the array is null
*/
public static double geometricMean(final double[] values) throws MathIllegalArgumentException {
- return GEOMETRIC_MEAN.evaluate(values);
+ if (verifyValues(values)) {
+ return GeometricMean.of(values).getAsDouble();
+ }
+ return Double.NaN;
}
/**
@@ -277,9 +268,6 @@ public static double geometricMean(final double[] values) throws MathIllegalArgu
* is empty.
*
* Throws
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.moment.GeometricMean GeometricMean}
- * for details on the computing algorithm.
*
* @param values the input array
* @param begin index of the first array element to include
@@ -290,7 +278,10 @@ public static double geometricMean(final double[] values) throws MathIllegalArgu
*/
public static double geometricMean(final double[] values, final int begin, final int length)
throws MathIllegalArgumentException {
- return GEOMETRIC_MEAN.evaluate(values, begin, length);
+ if (MathArrays.verifyValues(values, begin, length)) {
+ return GeometricMean.ofRange(values, begin, begin + length).getAsDouble();
+ }
+ return Double.NaN;
}
/**
@@ -301,9 +292,6 @@ public static double geometricMean(final double[] values, final int begin, final
* the denominator). Use {@link #populationVariance(double[])} for the non-bias-corrected
* population variance.
*
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.moment.Variance Variance} for
- * details on the computing algorithm.
- *
* Returns 0 for a single-value (i.e. length = 1) sample.
*
* Throws
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.moment.Variance Variance} for
- * details on the computing algorithm.
- *
* Returns 0 for a single-value (i.e. length = 1) sample.
*
* Throws
- * This method returns the bias-corrected sample variance (using {@code n - 1} in
- * the denominator). Use {@link #populationVariance(double[], double, int, int)} for
- * the non-bias-corrected population variance.
- *
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.moment.Variance Variance} for
- * details on the computing algorithm.
- *
- * The formula used assumes that the supplied mean value is the arithmetic
- * mean of the sample data, not a known population parameter. This method
- * is supplied only to save computation when the mean has already been
- * computed.
- *
- * Returns 0 for a single-value (i.e. length = 1) sample.
- *
- * Throws
- * This method returns the bias-corrected sample variance (using {@code n - 1} in
- * the denominator). Use {@link #populationVariance(double[], double)} for the
- * non-bias-corrected population variance.
- *
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.moment.Variance Variance} for
- * details on the computing algorithm.
- *
- * The formula used assumes that the supplied mean value is the arithmetic
- * mean of the sample data, not a known population parameter. This method
- * is supplied only to save computation when the mean has already been
- * computed.
- *
- * Returns 0 for a single-value (i.e. length = 1) sample.
- *
- * Throws
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.moment.Variance Variance} for
- * details on the formula and computing algorithm.
- *
* Returns 0 for a single-value (i.e. length = 1) sample.
*
* Throws
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.moment.Variance Variance} for
- * details on the computing algorithm.
- *
* Returns 0 for a single-value (i.e. length = 1) sample.
*
* Throws
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.moment.Variance Variance} for
- * details on the computing algorithm.
- *
- * The formula used assumes that the supplied mean value is the arithmetic
- * mean of the sample data, not a known population parameter. This method
- * is supplied only to save computation when the mean has already been
- * computed.
- *
- * Returns 0 for a single-value (i.e. length = 1) sample.
- *
- * Throws
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.moment.Variance Variance} for
- * details on the computing algorithm.
- *
- * The formula used assumes that the supplied mean value is the arithmetic
- * mean of the sample data, not a known population parameter. This method is
- * supplied only to save computation when the mean has already been computed.
- *
- * Returns 0 for a single-value (i.e. length = 1) sample.
- *
- * Throws
* Throws
* Throws
* Throws
* Throws
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.rank.Percentile Percentile}
- * for a description of the percentile estimation algorithm used.
+ * See Commons Statistics {@link Quantile} for a description of the percentile estimation algorithm used.
*
* @param values input array of values
* @param p the percentile value to compute
* @return the percentile value or Double.NaN if the array is empty
- * @throws MathIllegalArgumentException if
- * See {@link org.apache.commons.math4.legacy.stat.descriptive.rank.Percentile Percentile}
- * for a description of the percentile estimation algorithm used.
+ * See Commons Statistics {@link Quantile} for a description of the percentile estimation algorithm used.
*
* @param values array of input values
* @param p the percentile to compute
* @param begin the first (0-based) element to include in the computation
* @param length the number of array elements to include
* @return the percentile value
- * @throws MathIllegalArgumentException if the parameters are not valid or the input array is null
+ * @throws IllegalArgumentException if the parameters are not valid or the input array is null
*/
public static double percentile(final double[] values, final int begin, final int length, final double p)
throws MathIllegalArgumentException {
- return PERCENTILE.evaluate(values, begin, length, p);
+ MathArrays.verifyValues(values, begin, length);
+ return QUANTILE.evaluateRange(values, begin, begin + length, p / 100);
}
/**
@@ -786,9 +644,8 @@ public static double[] normalize(final double[] sample) {
* @since 3.3
*/
public static double[] mode(double[] sample) throws MathIllegalArgumentException {
- if (sample == null) {
- throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
- }
+ // Zero length is allowed
+ verifyValues(sample);
return getMode(sample, 0, sample.length);
}
@@ -816,18 +673,7 @@ public static double[] mode(double[] sample) throws MathIllegalArgumentException
* @since 3.3
*/
public static double[] mode(double[] sample, final int begin, final int length) {
- if (sample == null) {
- throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
- }
-
- if (begin < 0) {
- throw new NotPositiveException(LocalizedFormats.START_POSITION, Integer.valueOf(begin));
- }
-
- if (length < 0) {
- throw new NotPositiveException(LocalizedFormats.LENGTH, Integer.valueOf(length));
- }
-
+ MathArrays.verifyValues(sample, begin, length);
return getMode(sample, begin, length);
}
@@ -852,4 +698,18 @@ private static double[] getMode(double[] values, final int begin, final int leng
// Convert the list to an array of primitive double
return list.stream().mapToDouble(Double::doubleValue).toArray();
}
+
+ /**
+ * This method is used to verify an array of positive length.
+ *
+ * @param values the input array
+ * @return true if the array is non-zero length
+ * @throws MathIllegalArgumentException if the array is null
+ */
+ private static boolean verifyValues(final double[] values) {
+ if (values == null) {
+ throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
+ }
+ return values.length != 0;
+ }
}
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/correlation/Covariance.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/correlation/Covariance.java
index 3677ffa278..5caf26ef65 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/correlation/Covariance.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/correlation/Covariance.java
@@ -21,8 +21,6 @@
import org.apache.commons.math4.legacy.exception.util.LocalizedFormats;
import org.apache.commons.math4.legacy.linear.BlockRealMatrix;
import org.apache.commons.math4.legacy.linear.RealMatrix;
-import org.apache.commons.math4.legacy.stat.descriptive.moment.Mean;
-import org.apache.commons.math4.legacy.stat.descriptive.moment.Variance;
/**
* Computes covariances for pairs of arrays or columns of a matrix.
@@ -162,7 +160,6 @@ public int getN() {
protected RealMatrix computeCovarianceMatrix(RealMatrix matrix, boolean biasCorrected)
throws MathIllegalArgumentException {
int dimension = matrix.getColumnDimension();
- Variance variance = new Variance(biasCorrected);
RealMatrix outMatrix = new BlockRealMatrix(dimension, dimension);
for (int i = 0; i < dimension; i++) {
for (int j = 0; j < i; j++) {
@@ -170,7 +167,8 @@ protected RealMatrix computeCovarianceMatrix(RealMatrix matrix, boolean biasCorr
outMatrix.setEntry(i, j, cov);
outMatrix.setEntry(j, i, cov);
}
- outMatrix.setEntry(i, i, variance.evaluate(matrix.getColumn(i)));
+ outMatrix.setEntry(i, i, org.apache.commons.statistics.descriptive.Variance.of(
+ matrix.getColumn(i)).setBiased(!biasCorrected).getAsDouble());
}
return outMatrix;
}
@@ -233,7 +231,6 @@ protected RealMatrix computeCovarianceMatrix(double[][] data)
*/
public double covariance(final double[] xArray, final double[] yArray, boolean biasCorrected)
throws MathIllegalArgumentException {
- Mean mean = new Mean();
double result = 0d;
int length = xArray.length;
if (length != yArray.length) {
@@ -243,8 +240,8 @@ public double covariance(final double[] xArray, final double[] yArray, boolean b
throw new MathIllegalArgumentException(
LocalizedFormats.INSUFFICIENT_OBSERVED_POINTS_IN_SAMPLE, length, 2);
} else {
- double xMean = mean.evaluate(xArray);
- double yMean = mean.evaluate(yArray);
+ double xMean = org.apache.commons.statistics.descriptive.Mean.of(xArray).getAsDouble();
+ double yMean = org.apache.commons.statistics.descriptive.Mean.of(yArray).getAsDouble();
for (int i = 0; i < length; i++) {
double xDev = xArray[i] - xMean;
double yDev = yArray[i] - yMean;
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/AbstractStorelessUnivariateStatistic.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/AbstractStorelessUnivariateStatistic.java
index 1ea77e0f53..b85402d8b6 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/AbstractStorelessUnivariateStatistic.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/AbstractStorelessUnivariateStatistic.java
@@ -20,7 +20,6 @@
import org.apache.commons.math4.legacy.exception.NullArgumentException;
import org.apache.commons.math4.legacy.exception.util.LocalizedFormats;
import org.apache.commons.math4.legacy.core.MathArrays;
-import org.apache.commons.numbers.core.Precision;
/**
* Abstract base class for implementations of the
@@ -155,36 +154,4 @@ public void incrementAll(double[] values, int begin, int length) throws MathIlle
}
}
}
-
- /**
- * Returns true iff This method returns the bias-corrected sample variance (using {@code n - 1} in
- * the denominator). Use {@link #getPopulationVariance()} for the non-bias-corrected
- * population variance.Double.NaN if the array is empty.
* IllegalArgumentException if the array is null.
- * Double.NaN if the designated subarray is empty.
* IllegalArgumentException if the array is null.
- * Double.NaN if the array is empty.
* IllegalArgumentException if the array is null.
- * IllegalArgumentException if the array is null.
- * Double.NaN if the array is empty.
* IllegalArgumentException if the array is null.
- * IllegalArgumentException if the array is null.
- * MathIllegalArgumentException if the array is null.
@@ -313,7 +301,10 @@ public static double geometricMean(final double[] values, final int begin, final
* @throws MathIllegalArgumentException if the array is null
*/
public static double variance(final double[] values) throws MathIllegalArgumentException {
- return VARIANCE.evaluate(values);
+ if (verifyValues(values)) {
+ return org.apache.commons.statistics.descriptive.Variance.of(values).getAsDouble();
+ }
+ return Double.NaN;
}
/**
@@ -325,9 +316,6 @@ public static double variance(final double[] values) throws MathIllegalArgumentE
* the denominator). Use {@link #populationVariance(double[], int, int)} for the non-bias-corrected
* population variance.
* MathIllegalArgumentException if the array is null or the
@@ -342,72 +330,11 @@ public static double variance(final double[] values) throws MathIllegalArgumentE
*/
public static double variance(final double[] values, final int begin, final int length)
throws MathIllegalArgumentException {
- return VARIANCE.evaluate(values, begin, length);
- }
-
- /**
- * Returns the variance of the entries in the specified portion of
- * the input array, using the precomputed mean value. Returns
- * Double.NaN if the designated subarray is empty.
- * MathIllegalArgumentException if the array is null or the
- * array index parameters are not valid.
- *
- * @param values the input array
- * @param mean the precomputed mean value
- * @param begin index of the first array element to include
- * @param length the number of elements to include
- * @return the variance of the values or Double.NaN if length = 0
- * @throws MathIllegalArgumentException if the array is null or the array index
- * parameters are not valid
- */
- public static double variance(final double[] values, final double mean, final int begin, final int length)
- throws MathIllegalArgumentException {
- return VARIANCE.evaluate(values, mean, begin, length);
- }
-
- /**
- * Returns the variance of the entries in the input array, using the
- * precomputed mean value. Returns Double.NaN if the array
- * is empty.
- * MathIllegalArgumentException if the array is null.
- *
- * @param values the input array
- * @param mean the precomputed mean value
- * @return the variance of the values or Double.NaN if the array is empty
- * @throws MathIllegalArgumentException if the array is null
- */
- public static double variance(final double[] values, final double mean) throws MathIllegalArgumentException {
- return VARIANCE.evaluate(values, mean);
+ if (MathArrays.verifyValues(values, begin, length)) {
+ return org.apache.commons.statistics.descriptive.Variance.ofRange(values, begin, begin + length)
+ .getAsDouble();
+ }
+ return Double.NaN;
}
/**
@@ -415,9 +342,6 @@ public static double variance(final double[] values, final double mean) throws M
* population variance of the entries in the input array, or
* Double.NaN if the array is empty.
* MathIllegalArgumentException if the array is null.
@@ -427,7 +351,11 @@ public static double variance(final double[] values, final double mean) throws M
* @throws MathIllegalArgumentException if the array is null
*/
public static double populationVariance(final double[] values) throws MathIllegalArgumentException {
- return new Variance(false).evaluate(values);
+ if (verifyValues(values)) {
+ return org.apache.commons.statistics.descriptive.Variance.of(values)
+ .setBiased(true).getAsDouble();
+ }
+ return Double.NaN;
}
/**
@@ -436,9 +364,6 @@ public static double populationVariance(final double[] values) throws MathIllega
* the input array, or Double.NaN if the designated subarray
* is empty.
* MathIllegalArgumentException if the array is null or the
@@ -453,66 +378,11 @@ public static double populationVariance(final double[] values) throws MathIllega
*/
public static double populationVariance(final double[] values, final int begin, final int length)
throws MathIllegalArgumentException {
- return new Variance(false).evaluate(values, begin, length);
- }
-
- /**
- * Returns the
- * population variance of the entries in the specified portion of
- * the input array, using the precomputed mean value. Returns
- * Double.NaN if the designated subarray is empty.
- * MathIllegalArgumentException if the array is null or the
- * array index parameters are not valid.
- *
- * @param values the input array
- * @param mean the precomputed mean value
- * @param begin index of the first array element to include
- * @param length the number of elements to include
- * @return the population variance of the values or Double.NaN if length = 0
- * @throws MathIllegalArgumentException if the array is null or the array index
- * parameters are not valid
- */
- public static double populationVariance(final double[] values, final double mean,
- final int begin, final int length)
- throws MathIllegalArgumentException {
- return new Variance(false).evaluate(values, mean, begin, length);
- }
-
- /**
- * Returns the
- * population variance of the entries in the input array, using the precomputed
- * mean value. Returns Double.NaN if the array is empty.
- * MathIllegalArgumentException if the array is null.
- *
- * @param values the input array
- * @param mean the precomputed mean value
- * @return the population variance of the values or Double.NaN if the array is empty
- * @throws MathIllegalArgumentException if the array is null
- */
- public static double populationVariance(final double[] values, final double mean)
- throws MathIllegalArgumentException {
- return new Variance(false).evaluate(values, mean);
+ if (MathArrays.verifyValues(values, begin, length)) {
+ return org.apache.commons.statistics.descriptive.Variance.ofRange(values, begin, begin + length)
+ .setBiased(true).getAsDouble();
+ }
+ return Double.NaN;
}
/**
@@ -520,19 +390,16 @@ public static double populationVariance(final double[] values, final double mean
* Double.NaN if the array is empty.
* MathIllegalArgumentException if the array is null.
- *
- *
*
* @param values the input array
* @return the maximum of the values or Double.NaN if the array is empty
* @throws MathIllegalArgumentException if the array is null
*/
public static double max(final double[] values) throws MathIllegalArgumentException {
- return MAX.evaluate(values);
+ if (verifyValues(values)) {
+ return Max.of(values).getAsDouble();
+ }
+ return Double.NaN;
}
/**
@@ -541,12 +408,6 @@ public static double max(final double[] values) throws MathIllegalArgumentExcept
* NaN iff all values are NaN
- * (i.e. NaN values have no impact on the value of the statistic).Double.POSITIVE_INFINITY,
- * the result is Double.POSITIVE_INFINITY.MathIllegalArgumentException if the array is null or
* the array index parameters are not valid.
- *
- *
*
* @param values the input array
* @param begin index of the first array element to include
@@ -557,7 +418,10 @@ public static double max(final double[] values) throws MathIllegalArgumentExcept
*/
public static double max(final double[] values, final int begin, final int length)
throws MathIllegalArgumentException {
- return MAX.evaluate(values, begin, length);
+ if (MathArrays.verifyValues(values, begin, length)) {
+ return Max.ofRange(values, begin, begin + length).getAsDouble();
+ }
+ return Double.NaN;
}
/**
@@ -565,19 +429,16 @@ public static double max(final double[] values, final int begin, final int lengt
* NaN iff all values are NaN
- * (i.e. NaN values have no impact on the value of the statistic).Double.POSITIVE_INFINITY,
- * the result is Double.POSITIVE_INFINITY.Double.NaN if the array is empty.
* MathIllegalArgumentException if the array is null.
- *
- *
*
* @param values the input array
* @return the minimum of the values or Double.NaN if the array is empty
* @throws MathIllegalArgumentException if the array is null
*/
public static double min(final double[] values) throws MathIllegalArgumentException {
- return MIN.evaluate(values);
+ if (verifyValues(values)) {
+ return Min.of(values).getAsDouble();
+ }
+ return Double.NaN;
}
/**
@@ -586,12 +447,6 @@ public static double min(final double[] values) throws MathIllegalArgumentExcept
* NaN iff all values are NaN
- * (i.e. NaN values have no impact on the value of the statistic).Double.NEGATIVE_INFINITY,
- * the result is Double.NEGATIVE_INFINITY.MathIllegalArgumentException if the array is null or
* the array index parameters are not valid.
- *
- *
*
* @param values the input array
* @param begin index of the first array element to include
@@ -602,7 +457,10 @@ public static double min(final double[] values) throws MathIllegalArgumentExcept
*/
public static double min(final double[] values, final int begin, final int length)
throws MathIllegalArgumentException {
- return MIN.evaluate(values, begin, length);
+ if (MathArrays.verifyValues(values, begin, length)) {
+ return Min.ofRange(values, begin, begin + length).getAsDouble();
+ }
+ return Double.NaN;
}
/**
@@ -618,16 +476,16 @@ public static double min(final double[] values, final int begin, final int lengt
* and less than or equal to 100)
*
* NaN iff all values are NaN
- * (i.e. NaN values have no impact on the value of the statistic).Double.NEGATIVE_INFINITY,
- * the result is Double.NEGATIVE_INFINITY.values is null or p is invalid
+ * @throws IllegalArgumentException if values is null or p is invalid
*/
public static double percentile(final double[] values, final double p) throws MathIllegalArgumentException {
- return PERCENTILE.evaluate(values,p);
+ verifyValues(values);
+ return QUANTILE.evaluate(values, p / 100);
}
/**
@@ -645,19 +503,19 @@ public static double percentile(final double[] values, final double p) throws Ma
* and less than or equal to 100)
*
* object is the same type of
- * {@link StorelessUnivariateStatistic} (the object's class equals this
- * instance) returning the same values as this for getResult()
- * and getN().
- *
- * @param object object to test equality against.
- * @return true if object returns the same value as this
- */
- @Override
- public boolean equals(Object object) {
- if (object == this ) {
- return true;
- }
- if (object == null || object.getClass() != this.getClass()) {
- return false;
- }
- StorelessUnivariateStatistic stat = (StorelessUnivariateStatistic) object;
- return Precision.equalsIncludingNaN(stat.getResult(), this.getResult()) &&
- Precision.equalsIncludingNaN(stat.getN(), this.getN());
- }
-
- /**
- * Returns hash code based on getResult() and getN().
- *
- * @return hash code
- */
- @Override
- public int hashCode() {
- return 31 * (31 + Double.hashCode(getResult())) + Double.hashCode(getN());
- }
}
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/AggregateSummaryStatistics.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/AggregateSummaryStatistics.java
index 1807e5c97e..058e7ebff3 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/AggregateSummaryStatistics.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/AggregateSummaryStatistics.java
@@ -19,7 +19,7 @@
import java.util.Collection;
import java.util.Iterator;
-
+import org.apache.commons.math4.core.jdkmath.JdkMath;
import org.apache.commons.math4.legacy.exception.NullArgumentException;
/**
@@ -209,56 +209,6 @@ public double getVariance() {
}
}
- /**
- * Returns the sum of the logs of all the aggregated data.
- *
- * @return the sum of logs
- * @see SummaryStatistics#getSumOfLogs()
- */
- public double getSumOfLogs() {
- synchronized (statistics) {
- return statistics.getSumOfLogs();
- }
- }
-
- /**
- * Returns the geometric mean of all the aggregated data.
- *
- * @return the geometric mean
- * @see SummaryStatistics#getGeometricMean()
- */
- public double getGeometricMean() {
- synchronized (statistics) {
- return statistics.getGeometricMean();
- }
- }
-
- /**
- * Returns the sum of the squares of all the aggregated data.
- *
- * @return The sum of squares
- * @see SummaryStatistics#getSumsq()
- */
- public double getSumsq() {
- synchronized (statistics) {
- return statistics.getSumsq();
- }
- }
-
- /**
- * Returns a statistic related to the Second Central Moment. Specifically,
- * what is returned is the sum of squared deviations from the sample mean
- * among the all of the aggregated data.
- *
- * @return second central moment statistic
- * @see SummaryStatistics#getSecondMoment()
- */
- public double getSecondMoment() {
- synchronized (statistics) {
- return statistics.getSecondMoment();
- }
- }
-
/**
* Return a {@link StatisticalSummaryValues} instance reporting current
* aggregate statistics.
@@ -315,17 +265,13 @@ public static StatisticalSummaryValues aggregate(Collection extends Statistica
double min = current.getMin();
double sum = current.getSum();
double max = current.getMax();
- double var = current.getVariance();
- double m2 = var * (n - 1d);
+ // Assume bias corrected variance to compute the sum-of-squared deviations from the mean
+ double m2 = current.getVariance() * (n - 1d);
double mean = current.getMean();
while (iterator.hasNext()) {
current = iterator.next();
- if (current.getMin() < min || Double.isNaN(min)) {
- min = current.getMin();
- }
- if (current.getMax() > max || Double.isNaN(max)) {
- max = current.getMax();
- }
+ min = JdkMath.min(min, current.getMin());
+ max = JdkMath.max(max, current.getMax());
sum += current.getSum();
final double oldN = n;
final double curN = current.getN();
@@ -353,12 +299,6 @@ public static StatisticalSummaryValues aggregate(Collection extends Statistica
* @since 2.0
*/
private static final class AggregatingSummaryStatistics extends SummaryStatistics {
-
- /**
- * The serialization version of this class.
- */
- private static final long serialVersionUID = 1L;
-
/**
* An additional SummaryStatistics into which values added to these.
* statistics (and possibly others) are aggregated
@@ -389,34 +329,5 @@ public void addValue(double value) {
aggregateStatistics.addValue(value);
}
}
-
- /**
- * Returns true iff object is a
- * SummaryStatistics instance and all statistics have the
- * same values as this.
- * @param object the object to test equality against.
- * @return true if object equals this
- */
- @Override
- public boolean equals(Object object) {
- if (object == this) {
- return true;
- }
- if (!(object instanceof AggregatingSummaryStatistics)) {
- return false;
- }
- AggregatingSummaryStatistics stat = (AggregatingSummaryStatistics)object;
- return super.equals(stat) &&
- aggregateStatistics.equals(stat.aggregateStatistics);
- }
-
- /**
- * Returns hash code based on values of statistics.
- * @return hash code
- */
- @Override
- public int hashCode() {
- return 123 + super.hashCode() + aggregateStatistics.hashCode();
- }
}
}
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/DescriptiveStatistics.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/DescriptiveStatistics.java
index 383fd77749..36ba82bcc7 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/DescriptiveStatistics.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/DescriptiveStatistics.java
@@ -19,21 +19,21 @@
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
+import org.apache.commons.math4.core.jdkmath.JdkMath;
import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
import org.apache.commons.math4.legacy.exception.MathIllegalStateException;
import org.apache.commons.math4.legacy.exception.NullArgumentException;
import org.apache.commons.math4.legacy.exception.util.LocalizedFormats;
-import org.apache.commons.math4.legacy.stat.descriptive.moment.GeometricMean;
-import org.apache.commons.math4.legacy.stat.descriptive.moment.Kurtosis;
-import org.apache.commons.math4.legacy.stat.descriptive.moment.Mean;
-import org.apache.commons.math4.legacy.stat.descriptive.moment.Skewness;
-import org.apache.commons.math4.legacy.stat.descriptive.moment.Variance;
-import org.apache.commons.math4.legacy.stat.descriptive.rank.Max;
-import org.apache.commons.math4.legacy.stat.descriptive.rank.Min;
-import org.apache.commons.math4.legacy.stat.descriptive.rank.Percentile;
-import org.apache.commons.math4.legacy.stat.descriptive.summary.Sum;
-import org.apache.commons.math4.legacy.stat.descriptive.summary.SumOfSquares;
-import org.apache.commons.math4.core.jdkmath.JdkMath;
+import org.apache.commons.math4.legacy.stat.descriptive.Statistics.GeometricMean;
+import org.apache.commons.math4.legacy.stat.descriptive.Statistics.Kurtosis;
+import org.apache.commons.math4.legacy.stat.descriptive.Statistics.Max;
+import org.apache.commons.math4.legacy.stat.descriptive.Statistics.Mean;
+import org.apache.commons.math4.legacy.stat.descriptive.Statistics.Min;
+import org.apache.commons.math4.legacy.stat.descriptive.Statistics.Percentile;
+import org.apache.commons.math4.legacy.stat.descriptive.Statistics.Skewness;
+import org.apache.commons.math4.legacy.stat.descriptive.Statistics.Sum;
+import org.apache.commons.math4.legacy.stat.descriptive.Statistics.SumOfSquares;
+import org.apache.commons.math4.legacy.stat.descriptive.Statistics.Variance;
/**
@@ -74,34 +74,34 @@ public class DescriptiveStatistics implements StatisticalSummary {
private ResizableDoubleArray eDA = new ResizableDoubleArray();
/** Mean statistic implementation - can be reset by setter. */
- private UnivariateStatistic meanImpl = new Mean();
+ private UnivariateStatistic meanImpl = Mean.getInstance();
/** Geometric mean statistic implementation - can be reset by setter. */
- private UnivariateStatistic geometricMeanImpl = new GeometricMean();
+ private UnivariateStatistic geometricMeanImpl = GeometricMean.getInstance();
/** Kurtosis statistic implementation - can be reset by setter. */
- private UnivariateStatistic kurtosisImpl = new Kurtosis();
+ private UnivariateStatistic kurtosisImpl = Kurtosis.getInstance();
/** Maximum statistic implementation - can be reset by setter. */
- private UnivariateStatistic maxImpl = new Max();
+ private UnivariateStatistic maxImpl = Max.getInstance();
/** Minimum statistic implementation - can be reset by setter. */
- private UnivariateStatistic minImpl = new Min();
+ private UnivariateStatistic minImpl = Min.getInstance();
/** Percentile statistic implementation - can be reset by setter. */
- private UnivariateStatistic percentileImpl = new Percentile();
+ private UnivariateStatistic percentileImpl = Percentile.create(50);
/** Skewness statistic implementation - can be reset by setter. */
- private UnivariateStatistic skewnessImpl = new Skewness();
+ private UnivariateStatistic skewnessImpl = Skewness.getInstance();
/** Variance statistic implementation - can be reset by setter. */
- private UnivariateStatistic varianceImpl = new Variance();
+ private UnivariateStatistic varianceImpl = Variance.getInstance();
/** Sum of squares statistic implementation - can be reset by setter. */
- private UnivariateStatistic sumsqImpl = new SumOfSquares();
+ private UnivariateStatistic sumsqImpl = SumOfSquares.getInstance();
/** Sum statistic implementation - can be reset by setter. */
- private UnivariateStatistic sumImpl = new Sum();
+ private UnivariateStatistic sumImpl = Sum.getInstance();
/**
* Construct a {@code DescriptiveStatistics} instance with an infinite
@@ -236,8 +236,7 @@ public double getGeometricMean() {
* Returns the (sample) variance of the available values.
*
*
Computes summary statistics for a stream of n-tuples added using the
@@ -117,13 +115,13 @@ public MultivariateSummaryStatistics(int k, boolean isCovarianceBiasCorrected) {
meanImpl = new StorelessUnivariateStatistic[k];
for (int i = 0; i < k; ++i) {
- sumImpl[i] = new Sum();
- sumSqImpl[i] = new SumOfSquares();
- minImpl[i] = new Min();
- maxImpl[i] = new Max();
- sumLogImpl[i] = new SumOfLogs();
- geoMeanImpl[i] = new GeometricMean();
- meanImpl[i] = new Mean();
+ sumImpl[i] = StorelessSum.create();
+ sumSqImpl[i] = StorelessSumOfSquares.create();
+ minImpl[i] = StorelessMin.create();
+ maxImpl[i] = StorelessMax.create();
+ sumLogImpl[i] = StorelessSumOfLogs.create();
+ geoMeanImpl[i] = StorelessGeometricMean.create();
+ meanImpl[i] = StorelessMean.create();
}
covarianceImpl =
@@ -362,52 +360,6 @@ public void clear() {
covarianceImpl.clear();
}
- /**
- * Returns true iff
@@ -39,13 +34,12 @@
* streams.
*
- * The {@link StorelessUnivariateStatistic} instances used to maintain summary
- * state and compute statistics are configurable via setters. For example, the
+ * Default implementations can be configured via setters. For example, the
* default implementation for the variance can be overridden by calling
* {@link #setVarianceImpl(StorelessUnivariateStatistic)}. Actual parameters to
* these methods must implement the {@link StorelessUnivariateStatistic}
* interface and configuration must be completed before
@@ -58,61 +52,38 @@ public class SummaryStatistics implements StatisticalSummary {
/** count of values that have been added. */
private long n;
- /** SecondMoment is used to compute the mean and variance. */
- private SecondMoment secondMoment = new SecondMoment();
-
- /** sum of values that have been added. */
- private Sum sum = new Sum();
-
- /** sum of the square of each value that has been added. */
- private SumOfSquares sumsq = new SumOfSquares();
-
- /** min of values that have been added. */
- private Min min = new Min();
-
- /** max of values that have been added. */
- private Max max = new Max();
-
- /** sumLog of values that have been added. */
- private SumOfLogs sumLog = new SumOfLogs();
-
- /** geoMean of values that have been added. */
- private GeometricMean geoMean = new GeometricMean(sumLog);
-
- /** mean of values that have been added. */
- private Mean mean = new Mean(secondMoment);
-
- /** variance of values that have been added. */
- private Variance variance = new Variance(secondMoment);
+ /** Default statistics. */
+ private final EnumSet
- * Double.NaN is returned if no values have been added.
- * This method returns the bias-corrected sample variance (using {@code n - 1} in
- * the denominator). Use {@link #getPopulationVariance()} for the non-bias-corrected
- * population variance. Double.NaN is returned if no values have been added. Double.NaN is returned if no values have been added.
- * Double.NaN is returned if no values have been added.
- *
- * Double.NaN is returned if no values have been added.
- *
- * Returns
- * Sets the implementation for the sum of squares.
- *
- * This method cannot be activated after data has been added - i.e.,
- * after {@link #addValue(double) addValue} has been used to add data.
- * If it is activated after data has been added, an IllegalStateException
- * will be thrown.
- *
- * Sets the implementation for the sum of logs.
- *
- * This method cannot be activated after data has been added - i.e.,
- * after {@link #addValue(double) addValue} has been used to add data.
- * If it is activated after data has been added, an IllegalStateException
- * will be thrown.
- *
- * Sets the implementation for the geometric mean.
- *
- * This method cannot be activated after data has been added - i.e.,
- * after {@link #addValue(double) addValue} has been used to add data.
- * If it is activated after data has been added, an IllegalStateException
- * will be thrown.
- *
- * mean = sum(x_i) / n
- * where
- * To limit numeric errors, the value of the statistic is computed using the
- * following recursive updating algorithm:
- * Returns
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the Neither source nor dest can be null.
- * (x_i - xbar) ^ 4,
- * where the x_i are the
- * sample observations and xbar is the sample mean.
- * The following recursive updating formula is used:
- * Let
- * new value = old value - 4 * (dev/n) * m3 + 6 * (dev/n)^2 * m2 +
- * Returns
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the Neither source nor dest can be null.
- * Uses a {@link SumOfLogs} instance to compute sum of logs and returns
- *
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the
- * See {@link GeometricMean} for details on the computing algorithm.
- * Throws Sets the implementation for the sum of logs. This method must be activated before any data has been added - i.e.,
- * before {@link #increment(double) increment} has been used to add data;
- * otherwise an IllegalStateException will be thrown. Neither source nor dest can be null.
- * We use the following (unbiased) formula to define kurtosis:
- * kurtosis = { [n(n+1) / (n -1)(n - 2)(n-3)] sum[(x_i - mean)^4] / std^4 } - [3(n-1)^2 / (n-2)(n-3)]
- *
- * where n is the number of values, mean is the {@link Mean} and std is the
- * {@link StandardDeviation}
- * Note that this statistic is undefined for {@code n < 4}.
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the
- * Statistics based on (constructed from) external moments cannot
- * be incremented or cleared. Note that when {@link #Kurtosis(FourthMoment)} is used to
- * create a Variance, this method does nothing. In that case, the
- * FourthMoment should be incremented directly.
- * See {@link Kurtosis} for details on the computing algorithm.
- * Throws Neither source nor dest can be null.
- * mean = sum(x_i) / n
- * where When {@link #increment(double)} is used to add data incrementally from a
- * stream of (unstored) values, the value of the statistic that
- * {@link #getResult()} returns is computed using the following recursive
- * updating algorithm: If {@link #evaluate(double[])} is used to compute the mean of an array
- * of stored values, a two-pass, corrected algorithm is used, starting with
- * the definitional formula computed using the array of stored values and then
- * correcting this by adding the mean deviation of the data values from the
- * arithmetic mean. See, e.g. "Comparison of Several Algorithms for Computing
- * Sample Means and Variances," Robert F. Ling, Journal of the American
- * Statistical Association, Vol. 69, No. 348 (Dec., 1974), pp. 859-866.
- * Returns
- * Statistics based on (constructed from) external moments cannot
- * be incremented or cleared. Note that when {@link #Mean(FirstMoment)} is used to
- * create a Mean, this method does nothing. In that case, the
- * FirstMoment should be incremented directly.
- * Throws
- * See {@link Mean} for details on the computing algorithm.
- * Throws
- * See {@link Mean} for details on the computing algorithm. The two-pass algorithm
- * described above is used here, with weights applied in computing both the original
- * estimate and the correction factor.
- * Throws
- * Throws
- * See {@link Mean} for details on the computing algorithm. The two-pass algorithm
- * described above is used here, with weights applied in computing both the original
- * estimate and the correction factor.
- * Throws Neither source nor dest can be null.
- * The following recursive updating formula is used:
- * Let
- * new value = old value + dev^2 * (n -1) / n.
- * Returns
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the Neither source nor dest can be null. The cutoff value defaults to the mean, bias correction defaults to If the input array is null, Neither source nor dest can be null. Returns the {@link SemiVariance} of the designated values against the mean, using
* instance properties varianceDirection and biasCorrection. Returns the {@link SemiVariance} of the designated values against the cutoff in the
- * given direction, using the current value of the biasCorrection instance property. Returns the {@link SemiVariance} of the designated values against the cutoff
+ * in the given direction with the provided bias correction. Returns object is a MultivariateSummaryStatistics
- * instance and all statistics have the same values as this.
- * @param object the object to test equality against.
- * @return true if object equals this
- */
- @Override
- public boolean equals(Object object) {
- if (object == this ) {
- return true;
- }
- if (!(object instanceof MultivariateSummaryStatistics)) {
- return false;
- }
- MultivariateSummaryStatistics stat = (MultivariateSummaryStatistics) object;
- return MathArrays.equalsIncludingNaN(stat.getGeometricMean(), getGeometricMean()) &&
- MathArrays.equalsIncludingNaN(stat.getMax(), getMax()) &&
- MathArrays.equalsIncludingNaN(stat.getMean(), getMean()) &&
- MathArrays.equalsIncludingNaN(stat.getMin(), getMin()) &&
- Precision.equalsIncludingNaN(stat.getN(), getN()) &&
- MathArrays.equalsIncludingNaN(stat.getSum(), getSum()) &&
- MathArrays.equalsIncludingNaN(stat.getSumSq(), getSumSq()) &&
- MathArrays.equalsIncludingNaN(stat.getSumLog(), getSumLog()) &&
- stat.getCovariance().equals( getCovariance());
- }
-
- /**
- * Returns hash code based on values of statistics.
- *
- * @return hash code
- */
- @Override
- public int hashCode() {
- int result = 31 + Arrays.hashCode(getGeometricMean());
- result = result * 31 + Arrays.hashCode(getGeometricMean());
- result = result * 31 + Arrays.hashCode(getMax());
- result = result * 31 + Arrays.hashCode(getMean());
- result = result * 31 + Arrays.hashCode(getMin());
- result = result * 31 + Double.hashCode(getN());
- result = result * 31 + Arrays.hashCode(getSum());
- result = result * 31 + Arrays.hashCode(getSumSq());
- result = result * 31 + Arrays.hashCode(getSumLog());
- result = result * 31 + getCovariance().hashCode();
- return result;
- }
-
// Getters and setters for statistics implementations
/**
* Sets statistics implementations.
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/ResizableDoubleArray.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/ResizableDoubleArray.java
index 0b3034c57e..47b075f923 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/ResizableDoubleArray.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/ResizableDoubleArray.java
@@ -16,8 +16,6 @@
*/
package org.apache.commons.math4.legacy.stat.descriptive;
-import java.util.Arrays;
-
import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
import org.apache.commons.math4.legacy.exception.MathIllegalStateException;
import org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException;
@@ -794,53 +792,4 @@ private boolean shouldContract() {
public ResizableDoubleArray copy() {
return new ResizableDoubleArray(this);
}
-
- /**
- * Returns true iff object is a ResizableDoubleArray with the same properties
- * as this and an identical internal storage array.
- *
- * @param object object to be compared for equality with this
- * @return true iff object is a ResizableDoubleArray with the same data and
- * properties as this
- * @since 2.0
- */
- @Override
- public boolean equals(Object object) {
- if (object == this ) {
- return true;
- }
- if (!(object instanceof ResizableDoubleArray)) {
- return false;
- }
- boolean result = true;
- final ResizableDoubleArray other = (ResizableDoubleArray) object;
- result = result && other.contractionCriterion == contractionCriterion;
- result = result && other.expansionFactor == expansionFactor;
- result = result && other.expansionMode == expansionMode;
- result = result && other.numElements == numElements;
- result = result && other.startIndex == startIndex;
- if (!result) {
- return false;
- } else {
- return Arrays.equals(internalArray, other.internalArray);
- }
- }
-
- /**
- * Returns a hash code consistent with equals.
- *
- * @return the hash code representing this {@code ResizableDoubleArray}.
- * @since 2.0
- */
- @Override
- public int hashCode() {
- final int[] hashData = new int[6];
- hashData[0] = Double.valueOf(expansionFactor).hashCode();
- hashData[1] = Double.valueOf(contractionCriterion).hashCode();
- hashData[2] = expansionMode.hashCode();
- hashData[3] = Arrays.hashCode(internalArray);
- hashData[4] = numElements;
- hashData[5] = startIndex;
- return Arrays.hashCode(hashData);
- }
}
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/StatisticalSummaryValues.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/StatisticalSummaryValues.java
index 135febce10..77fcf6c8c5 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/StatisticalSummaryValues.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/StatisticalSummaryValues.java
@@ -17,11 +17,9 @@
package org.apache.commons.math4.legacy.stat.descriptive;
import org.apache.commons.math4.core.jdkmath.JdkMath;
-import org.apache.commons.numbers.core.Precision;
/**
- * Value object representing the results of a univariate statistical summary.
- *
+ * Value object representing the results of a univariate statistical summary.
*/
public class StatisticalSummaryValues
implements StatisticalSummary {
@@ -120,47 +118,6 @@ public double getVariance() {
return variance;
}
- /**
- * Returns true iff object is a
- * StatisticalSummaryValues instance and all statistics have
- * the same values as this.
- *
- * @param object the object to test equality against.
- * @return true if object equals this
- */
- @Override
- public boolean equals(Object object) {
- if (object == this ) {
- return true;
- }
- if (!(object instanceof StatisticalSummaryValues)) {
- return false;
- }
- StatisticalSummaryValues stat = (StatisticalSummaryValues) object;
- return Precision.equalsIncludingNaN(stat.getMax(), getMax()) &&
- Precision.equalsIncludingNaN(stat.getMean(), getMean()) &&
- Precision.equalsIncludingNaN(stat.getMin(), getMin()) &&
- Precision.equalsIncludingNaN(stat.getN(), getN()) &&
- Precision.equalsIncludingNaN(stat.getSum(), getSum()) &&
- Precision.equalsIncludingNaN(stat.getVariance(), getVariance());
- }
-
- /**
- * Returns hash code based on values of statistics.
- *
- * @return hash code
- */
- @Override
- public int hashCode() {
- int result = 31 + Double.hashCode(getMax());
- result = result * 31 + Double.hashCode(getMean());
- result = result * 31 + Double.hashCode(getMin());
- result = result * 31 + Double.hashCode(getN());
- result = result * 31 + Double.hashCode(getSum());
- result = result * 31 + Double.hashCode(getVariance());
- return result;
- }
-
/**
* Generates a text report displaying values of statistics.
* Each statistic is displayed on a separate line.
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/Statistics.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/Statistics.java
new file mode 100644
index 0000000000..9445ea4c37
--- /dev/null
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/Statistics.java
@@ -0,0 +1,605 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math4.legacy.stat.descriptive;
+
+import java.util.function.BinaryOperator;
+import java.util.function.Supplier;
+import org.apache.commons.math4.legacy.core.MathArrays;
+import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
+import org.apache.commons.math4.legacy.exception.OutOfRangeException;
+import org.apache.commons.math4.legacy.exception.util.LocalizedFormats;
+import org.apache.commons.statistics.descriptive.DoubleStatistic;
+import org.apache.commons.statistics.descriptive.Quantile;
+import org.apache.commons.statistics.descriptive.StatisticResult;
+import org.apache.commons.statistics.descriptive.Quantile.EstimationMethod;
+
+/**
+ * Utility class delegating computations to Commons Statistics.
+ */
+final class Statistics {
+
+ /**
+ * Represents a function that accepts a range of {@code double[]} values and produces a result.
+ *
+ * @param addValue
- * is called. No configuration is necessary to use the default, commons-math
+ * is called. No configuration is necessary to use the default
* provided implementations.
* Double.NaN if no values have been added
+ * Gets the statistic from the overridden implementation, or from the default implementation.
+ *
+ * @param imp Statistics implementation.
+ * @param s Statistic
+ * @return the value
*/
- @Override
- public double getSum() {
- return sumImpl.getResult();
+ private double getStatistic(StorelessUnivariateStatistic imp, Statistic s) {
+ if (getN() == 0) {
+ return Double.NaN;
+ }
+ return imp != null ? imp.getResult() : values.getAsDouble(s);
}
/**
- * Returns the sum of the squares of the values that have been added.
- * Double.NaN if no values have been added
*/
- public double getSumsq() {
- return sumsqImpl.getResult();
+ @Override
+ public double getSum() {
+ return getStatistic(sumImpl, Statistic.SUM);
}
/**
@@ -198,7 +196,7 @@ public double getSumsq() {
*/
@Override
public double getMean() {
- return meanImpl.getResult();
+ return getStatistic(meanImpl, Statistic.MEAN);
}
/**
@@ -221,46 +219,16 @@ public double getStandardDeviation() {
return stdDev;
}
- /**
- * Returns the quadratic mean, a.k.a.
- *
- * root-mean-square of the available values
- * @return The quadratic mean or {@code Double.NaN} if no values
- * have been added.
- */
- public double getQuadraticMean() {
- final long size = getN();
- return size > 0 ? JdkMath.sqrt(getSumsq() / size) : Double.NaN;
- }
-
/**
* Returns the (sample) variance of the available values.
*
- * Double.NaN if no data values have been added and
- * returns 0 if there is just one value in the data set.
- * object is a
- * SummaryStatistics instance and all statistics have the
- * same values as this.
- * @param object the object to test equality against.
- * @return true if object equals this
+ * Clear the statistic if not null.
+ *
+ * @param s Statistic.
*/
- @Override
- public boolean equals(Object object) {
- if (object == this) {
- return true;
- }
- if (!(object instanceof SummaryStatistics)) {
- return false;
+ private static void clear(StorelessUnivariateStatistic s) {
+ if (s != null) {
+ s.clear();
}
- SummaryStatistics stat = (SummaryStatistics)object;
- return Precision.equalsIncludingNaN(stat.getGeometricMean(), getGeometricMean()) &&
- Precision.equalsIncludingNaN(stat.getMax(), getMax()) &&
- Precision.equalsIncludingNaN(stat.getMean(), getMean()) &&
- Precision.equalsIncludingNaN(stat.getMin(), getMin()) &&
- Precision.equalsIncludingNaN(stat.getN(), getN()) &&
- Precision.equalsIncludingNaN(stat.getSum(), getSum()) &&
- Precision.equalsIncludingNaN(stat.getSumsq(), getSumsq()) &&
- Precision.equalsIncludingNaN(stat.getVariance(), getVariance());
- }
-
- /**
- * Returns hash code based on values of statistics.
- * @return hash code
- */
- @Override
- public int hashCode() {
- int result = 31 + Double.hashCode(getGeometricMean());
- result = result * 31 + Double.hashCode(getGeometricMean());
- result = result * 31 + Double.hashCode(getMax());
- result = result * 31 + Double.hashCode(getMean());
- result = result * 31 + Double.hashCode(getMin());
- result = result * 31 + Double.hashCode(getN());
- result = result * 31 + Double.hashCode(getSum());
- result = result * 31 + Double.hashCode(getSumsq());
- result = result * 31 + Double.hashCode(getVariance());
- return result;
}
// Getters and setters for statistics implementations
+
/**
* Returns the currently configured Sum implementation.
+ * This will be null if using the default implementation.
* @return the StorelessUnivariateStatistic implementing the sum
* @since 1.2
*/
@@ -444,42 +335,12 @@ public StorelessUnivariateStatistic getSumImpl() {
*/
public void setSumImpl(StorelessUnivariateStatistic sumImpl)
throws MathIllegalStateException {
- checkEmpty();
- this.sumImpl = sumImpl;
- }
-
- /**
- * Returns the currently configured sum of squares implementation.
- * @return the StorelessUnivariateStatistic implementing the sum of squares
- * @since 1.2
- */
- public StorelessUnivariateStatistic getSumsqImpl() {
- return sumsqImpl;
- }
-
- /**
- * n is the number of observations.
- *
- * m = the first value
- * m = m + (new value - m) / (number of observations)Double.NaN if the dataset is empty. Note that
- * Double.NaN may also be returned if the input includes NaN and / or infinite
- * values.increment() or
- * clear() method, it must be synchronized externally.
- *
- * Then
- *
- * [n^2 - 3 * (n-1)] * dev^4 * (n-1) / n^3 Double.NaN if no data values have been added and
- * returns 0 if there is just one value in the data set. Note that
- * Double.NaN may also be returned if the input includes NaN and / or infinite
- * values. increment() or
- * clear() method, it must be synchronized externally. exp( 1/n (sum of logs) ). Therefore,
- *
- * NaN.Double.POSITIVE_INFINITY, but at least one value is 0, the
- * result is 0.Double.POSITIVE_INFINITY and
- * Double.NEGATIVE_INFINITY are among the values, the result is
- * NaN.increment() or
- * clear() method, it must be synchronized externally.IllegalArgumentException if the array is null.Double.Nan
- * is returned when there is not sufficient data to compute the statistic.
- * Note that Double.NaN may also be returned if the input includes NaN
- * and / or infinite values.increment() or
- * clear() method, it must be synchronized externally.IllegalArgumentException if the array is null.n is the number of observations.
- *
- *
- * m = the first value
- * m = m + (new value - m) / (number of observations)Double.NaN if the dataset is empty. Note that
- * Double.NaN may also be returned if the input includes NaN and / or infinite
- * values.
- * increment() or
- * clear() method, it must be synchronized externally.
- */
-public class Mean extends AbstractStorelessUnivariateStatistic
- implements WeightedEvaluation {
- /** First moment on which this statistic is based. */
- protected FirstMoment moment;
-
- /**
- * Determines whether or not this statistic can be incremented or cleared.
- * Double.NaN if the designated subarray
- * is empty.
- * IllegalArgumentException if the array is null.Double.NaN if the designated subarray
- * is empty.
- * IllegalArgumentException if either array is null.IllegalArgumentException if any of the following are true:
- *
- *
- * @param values the input array
- * @param weights the weights array
- * @param begin index of the first array element to include
- * @param length the number of elements to include
- * @return the mean of the values or Double.NaN if length = 0
- * @throws MathIllegalArgumentException if the parameters are not valid
- * @since 2.1
- */
- @Override
- public double evaluate(final double[] values, final double[] weights,
- final int begin, final int length) throws MathIllegalArgumentException {
- if (MathArrays.verifyValues(values, weights, begin, length)) {
- Sum sum = new Sum();
-
- // Compute initial estimate using definitional formula
- double sumw = sum.evaluate(weights,begin,length);
- double xbarw = sum.evaluate(values, weights, begin, length) / sumw;
-
- // Compute correction factor in second pass
- double correction = 0;
- for (int i = begin; i < begin + length; i++) {
- correction += weights[i] * (values[i] - xbarw);
- }
- return xbarw + (correction/sumw);
- }
- return Double.NaN;
- }
-
- /**
- * Returns the weighted arithmetic mean of the entries in the input array.
- * MathIllegalArgumentException if either array is null.MathIllegalArgumentException if any of the following are true:
- *
- *
- * @param values the input array
- * @param weights the weights array
- * @return the mean of the values or Double.NaN if length = 0
- * @throws MathIllegalArgumentException if the parameters are not valid
- * @since 2.1
- */
- @Override
- public double evaluate(final double[] values, final double[] weights)
- throws MathIllegalArgumentException {
- return evaluate(values, weights, 0, values.length);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Mean copy() {
- Mean result = new Mean();
- // No try-catch or advertised exception because args are guaranteed non-null
- copy(this, result);
- return result;
- }
-
- /**
- * Copies source to dest.
- *
- *
- * Then
- * Double.NaN if no data values have been added and
- * returns 0 if there is just one value in the data set.
- * Note that Double.NaN may also be returned if the input includes NaN
- * and / or infinite values.increment() or
- * clear() method, it must be synchronized externally.true
* and the "variance direction" (upside or downside) defaults to downside. The variance direction
- * and bias correction may be set using property setters or their values can provided as
- * parameters to {@link #evaluate(double[], double, Direction, boolean, int, int)}.evaluate methods throw
* IllegalArgumentException. If the array has length 1, 0
@@ -51,18 +51,6 @@
*/
public class SemiVariance extends AbstractUnivariateStatistic {
- /**
- * The UPSIDE Direction is used to specify that the observations above the
- * cutoff point will be used to calculate SemiVariance.
- */
- public static final Direction UPSIDE_VARIANCE = Direction.UPSIDE;
-
- /**
- * The DOWNSIDE Direction is used to specify that the observations below.
- * the cutoff point will be used to calculate SemiVariance
- */
- public static final Direction DOWNSIDE_VARIANCE = Direction.DOWNSIDE;
-
/**
* Determines whether or not bias correction is applied when computing the
* value of the statistic. True means that bias is corrected.
@@ -79,56 +67,7 @@ public class SemiVariance extends AbstractUnivariateStatistic {
* property and default (Downside) varianceDirection property.
*/
public SemiVariance() {
- }
-
- /**
- * Constructs a SemiVariance with the specified biasCorrected
- * property and default (Downside) varianceDirection property.
- *
- * @param biasCorrected setting for bias correction - true means
- * bias will be corrected and is equivalent to using the "no arg"
- * constructor
- */
- public SemiVariance(final boolean biasCorrected) {
- this.biasCorrected = biasCorrected;
- }
-
- /**
- * Constructs a SemiVariance with the specified Direction property.
- * and default (true) biasCorrected property
- *
- * @param direction setting for the direction of the SemiVariance
- * to calculate
- */
- public SemiVariance(final Direction direction) {
- this.varianceDirection = direction;
- }
-
- /**
- * Constructs a SemiVariance with the specified isBiasCorrected
- * property and the specified Direction property.
- *
- * @param corrected setting for bias correction - true means
- * bias will be corrected and is equivalent to using the "no arg"
- * constructor
- *
- * @param direction setting for the direction of the SemiVariance
- * to calculate
- */
- public SemiVariance(final boolean corrected, final Direction direction) {
- this.biasCorrected = corrected;
- this.varianceDirection = direction;
- }
-
- /**
- * Copy constructor, creates a new {@code SemiVariance} identical
- * to the {@code original}.
- *
- * @param original the {@code SemiVariance} instance to copy
- * @throws NullArgumentException if original is null
- */
- public SemiVariance(final SemiVariance original) throws NullArgumentException {
- copy(original, this);
+ // Do nothing
}
/**
@@ -137,27 +76,11 @@ public SemiVariance(final SemiVariance original) throws NullArgumentException {
@Override
public SemiVariance copy() {
SemiVariance result = new SemiVariance();
- // No try-catch or advertised exception because args are guaranteed non-null
- copy(this, result);
+ result.biasCorrected = biasCorrected;
+ result.varianceDirection = varianceDirection;
return result;
}
- /**
- * Copies source to dest.
- * NaN if the array is empty and throws
- * MathIllegalArgumentException if the array is null.IllegalArgumentException if the array is null.
Returns the {@link SemiVariance} of the designated values against the cutoff * in the given direction with the provided bias correction.
* - *Returns NaN if the array is empty and throws
- * IllegalArgumentException if the array is null.
Returns NaN if the array is empty.
- * We use the following (unbiased) formula to define skewness:
- *- * skewness = [n / (n -1) (n - 2)] sum[(x_i - mean)^3] / std^3
- *- * where n is the number of values, mean is the {@link Mean} and std is the - * {@link StandardDeviation}
- *
- * Note that this statistic is undefined for {@code n < 3}. Double.Nan
- * is returned when there is not sufficient data to compute the statistic.
- * Double.NaN may also be returned if the input includes NaN and / or
- * infinite values.
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the increment() or
- * clear() method, it must be synchronized externally.
- * Statistics based on (constructed from) external moments cannot - * be incremented or cleared.
- */ - protected boolean incMoment; - - /** - * Constructs a Skewness. - */ - public Skewness() { - incMoment = true; - moment = new ThirdMoment(); - } - - /** - * Constructs a Skewness with an external moment. - * @param m3 external moment - */ - public Skewness(final ThirdMoment m3) { - incMoment = false; - this.moment = m3; - } - - /** - * Copy constructor, creates a new {@code Skewness} identical - * to the {@code original}. - * - * @param original the {@code Skewness} instance to copy - * @throws NullArgumentException if original is null - */ - public Skewness(Skewness original) throws NullArgumentException { - copy(original, this); - } - - /** - * {@inheritDoc} - *Note that when {@link #Skewness(ThirdMoment)} is used to - * create a Skewness, this method does nothing. In that case, the - * ThirdMoment should be incremented directly.
- */ - @Override - public void increment(final double d) { - if (incMoment) { - moment.increment(d); - } - } - - /** - * Returns the value of the statistic based on the values that have been added. - *- * See {@link Skewness} for the definition used in the computation.
- * - * @return the skewness of the available values. - */ - @Override - public double getResult() { - - if (moment.n < 3) { - return Double.NaN; - } - double variance = moment.m2 / (moment.n - 1); - if (variance < ZERO_VARIANCE_THRESHOLD) { - return 0.0d; - } else { - double n0 = moment.getN(); - return (n0 * moment.m3) / - ((n0 - 1) * (n0 -2) * JdkMath.sqrt(variance) * variance); - } - } - - /** - * {@inheritDoc} - */ - @Override - public long getN() { - return moment.getN(); - } - - /** - * {@inheritDoc} - */ - @Override - public void clear() { - if (incMoment) { - moment.clear(); - } - } - - /** - * Returns the Skewness of the entries in the specified portion of the - * input array. - *- * See {@link Skewness} for the definition used in the computation.
- *
- * Throws IllegalArgumentException if the array is null.
Neither source nor dest can be null.
- * - * @param source Skewness to copy - * @param dest Skewness to copy to - * @throws NullArgumentException if either source or dest is null - */ - public static void copy(Skewness source, Skewness dest) - throws NullArgumentException { - NullArgumentException.check(source); - NullArgumentException.check(dest); - dest.moment = new ThirdMoment(source.moment.copy()); - dest.incMoment = source.incMoment; - } -} diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/StandardDeviation.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/StandardDeviation.java deleted file mode 100644 index 3d4a5b7856..0000000000 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/StandardDeviation.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.math4.legacy.stat.descriptive.moment; - -import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException; -import org.apache.commons.math4.legacy.exception.NullArgumentException; -import org.apache.commons.math4.legacy.stat.descriptive.AbstractStorelessUnivariateStatistic; -import org.apache.commons.math4.core.jdkmath.JdkMath; - -/** - * Computes the sample standard deviation. The standard deviation - * is the positive square root of the variance. This implementation wraps a - * {@link Variance} instance. TheisBiasCorrected property of the
- * wrapped Variance instance is exposed, so that this class can be used to
- * compute both the "sample standard deviation" (the square root of the
- * bias-corrected "sample variance") or the "population standard deviation"
- * (the square root of the non-bias-corrected "population variance"). See
- * {@link Variance} for more information.
- *
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the increment() or
- * clear() method, it must be synchronized externally.
isBiasCorrected property to true.
- */
- public StandardDeviation() {
- variance = new Variance();
- }
-
- /**
- * Constructs a StandardDeviation from an external second moment.
- *
- * @param m2 the external moment
- */
- public StandardDeviation(final SecondMoment m2) {
- variance = new Variance(m2);
- }
-
- /**
- * Copy constructor, creates a new {@code StandardDeviation} identical
- * to the {@code original}.
- *
- * @param original the {@code StandardDeviation} instance to copy
- * @throws NullArgumentException if original is null
- */
- public StandardDeviation(StandardDeviation original) throws NullArgumentException {
- copy(original, this);
- }
-
- /**
- * Constructs a StandardDeviation with the specified value for the
- * isBiasCorrected property. If this property is set to
- * true, the {@link Variance} used in computing results will
- * use the bias-corrected, or "sample" formula. See {@link Variance} for
- * details.
- *
- * @param isBiasCorrected whether or not the variance computation will use
- * the bias-corrected formula
- */
- public StandardDeviation(boolean isBiasCorrected) {
- variance = new Variance(isBiasCorrected);
- }
-
- /**
- * Constructs a StandardDeviation with the specified value for the
- * isBiasCorrected property and the supplied external moment.
- * If isBiasCorrected is set to true, the
- * {@link Variance} used in computing results will use the bias-corrected,
- * or "sample" formula. See {@link Variance} for details.
- *
- * @param isBiasCorrected whether or not the variance computation will use
- * the bias-corrected formula
- * @param m2 the external moment
- */
- public StandardDeviation(boolean isBiasCorrected, SecondMoment m2) {
- variance = new Variance(isBiasCorrected, m2);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void increment(final double d) {
- variance.increment(d);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public long getN() {
- return variance.getN();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public double getResult() {
- return JdkMath.sqrt(variance.getResult());
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void clear() {
- variance.clear();
- }
-
- /**
- * Returns the Standard Deviation of the entries in the input array, or
- * Double.NaN if the array is empty.
- * - * Returns 0 for a single-value (i.e. length = 1) sample.
- *
- * Throws MathIllegalArgumentException if the array is null.
- * Does not change the internal state of the statistic.
- * - * @param values the input array - * @return the standard deviation of the values or Double.NaN if length = 0 - * @throws MathIllegalArgumentException if the array is null - */ - @Override - public double evaluate(final double[] values) throws MathIllegalArgumentException { - return JdkMath.sqrt(variance.evaluate(values)); - } - - /** - * Returns the Standard Deviation of the entries in the specified portion of - * the input array, orDouble.NaN if the designated subarray
- * is empty.
- * - * Returns 0 for a single-value (i.e. length = 1) sample.
- *
- * Throws MathIllegalArgumentException if the array is null.
- * Does not change the internal state of the statistic.
- * - * @param values the input array - * @param begin index of the first array element to include - * @param length the number of elements to include - * @return the standard deviation of the values or Double.NaN if length = 0 - * @throws MathIllegalArgumentException if the array is null or the array index - * parameters are not valid - */ - @Override - public double evaluate(final double[] values, final int begin, final int length) - throws MathIllegalArgumentException { - return JdkMath.sqrt(variance.evaluate(values, begin, length)); - } - - /** - * Returns the Standard Deviation of the entries in the specified portion of - * the input array, using the precomputed mean value. Returns - *Double.NaN if the designated subarray is empty.
- * - * Returns 0 for a single-value (i.e. length = 1) sample.
- *- * The formula used assumes that the supplied mean value is the arithmetic - * mean of the sample data, not a known population parameter. This method - * is supplied only to save computation when the mean has already been - * computed.
- *
- * Throws IllegalArgumentException if the array is null.
- * Does not change the internal state of the statistic.
- * - * @param values the input array - * @param mean the precomputed mean value - * @param begin index of the first array element to include - * @param length the number of elements to include - * @return the standard deviation of the values or Double.NaN if length = 0 - * @throws MathIllegalArgumentException if the array is null or the array index - * parameters are not valid - */ - public double evaluate(final double[] values, final double mean, - final int begin, final int length) throws MathIllegalArgumentException { - return JdkMath.sqrt(variance.evaluate(values, mean, begin, length)); - } - - /** - * Returns the Standard Deviation of the entries in the input array, using - * the precomputed mean value. Returns - *Double.NaN if the designated subarray is empty.
- * - * Returns 0 for a single-value (i.e. length = 1) sample.
- *- * The formula used assumes that the supplied mean value is the arithmetic - * mean of the sample data, not a known population parameter. This method - * is supplied only to save computation when the mean has already been - * computed.
- *
- * Throws MathIllegalArgumentException if the array is null.
- * Does not change the internal state of the statistic.
- * - * @param values the input array - * @param mean the precomputed mean value - * @return the standard deviation of the values or Double.NaN if length = 0 - * @throws MathIllegalArgumentException if the array is null - */ - public double evaluate(final double[] values, final double mean) - throws MathIllegalArgumentException { - return JdkMath.sqrt(variance.evaluate(values, mean)); - } - - /** - * @return the isBiasCorrected. - */ - public boolean isBiasCorrected() { - return variance.isBiasCorrected(); - } - - /** - * @param isBiasCorrected The isBiasCorrected to set. - */ - public void setBiasCorrected(boolean isBiasCorrected) { - variance.setBiasCorrected(isBiasCorrected); - } - - /** - * {@inheritDoc} - */ - @Override - public StandardDeviation copy() { - StandardDeviation result = new StandardDeviation(); - // No try-catch or advertised exception because args are guaranteed non-null - copy(this, result); - return result; - } - - /** - * Copies source to dest. - *Neither source nor dest can be null.
- * - * @param source StandardDeviation to copy - * @param dest StandardDeviation to copy to - * @throws NullArgumentException if either source or dest is null - */ - public static void copy(StandardDeviation source, StandardDeviation dest) throws NullArgumentException { - NullArgumentException.check(source); - NullArgumentException.check(dest); - dest.variance = source.variance.copy(); - } -} diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/ThirdMoment.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/ThirdMoment.java deleted file mode 100644 index 56ea0c7e94..0000000000 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/ThirdMoment.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.math4.legacy.stat.descriptive.moment; - -import org.apache.commons.math4.legacy.exception.NullArgumentException; - - -/** - * Computes a statistic related to the Third Central Moment. Specifically, - * what is computed is the sum of cubed deviations from the sample mean. - *- * The following recursive updating formula is used:
- *- * Let
- * new value = old value - 3 * (dev/n) * m2 + (n-1) * (n -2) * (dev^3/n^2)
- *
- * Returns Double.NaN if no data values have been added and
- * returns 0 if there is just one value in the data set.
- * Note that Double.NaN may also be returned if the input includes NaN
- * and / or infinite values.
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the increment() or
- * clear() method, it must be synchronized externally.
Neither source nor dest can be null.
- * - * @param source ThirdMoment to copy - * @param dest ThirdMoment to copy to - * @throws NullArgumentException if either source or dest is null - */ - public static void copy(ThirdMoment source, ThirdMoment dest) - throws NullArgumentException { - NullArgumentException.check(source); - NullArgumentException.check(dest); - SecondMoment.copy(source, dest); - dest.m3 = source.m3; - dest.nDevSq = source.nDevSq; - } -} diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/VectorialCovariance.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/VectorialCovariance.java index af8c4be1fe..5948581eb2 100644 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/VectorialCovariance.java +++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/VectorialCovariance.java @@ -110,38 +110,4 @@ public void clear() { Arrays.fill(sums, 0.0); Arrays.fill(productsSums, 0.0); } - - /** {@inheritDoc} */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (isBiasCorrected ? 1231 : 1237); - result = prime * result + (int) (n ^ (n >>> 32)); - result = prime * result + Arrays.hashCode(productsSums); - result = prime * result + Arrays.hashCode(sums); - return result; - } - - /** {@inheritDoc} */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof VectorialCovariance)) { - return false; - } - VectorialCovariance other = (VectorialCovariance) obj; - if (isBiasCorrected != other.isBiasCorrected) { - return false; - } - if (n != other.n) { - return false; - } - if (!Arrays.equals(productsSums, other.productsSums)) { - return false; - } - return Arrays.equals(sums, other.sums); - } } diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/VectorialMean.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/VectorialMean.java index af9e161872..1409973d0c 100644 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/VectorialMean.java +++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/VectorialMean.java @@ -16,8 +16,6 @@ */ package org.apache.commons.math4.legacy.stat.descriptive.moment; -import java.util.Arrays; - import org.apache.commons.math4.legacy.exception.DimensionMismatchException; /** @@ -26,15 +24,17 @@ */ public class VectorialMean { /** Means for each component. */ - private final Mean[] means; + private final org.apache.commons.statistics.descriptive.Mean[] means; + /** Sample count. */ + private long n; /** Constructs a VectorialMean. * @param dimension vectors dimension */ public VectorialMean(int dimension) { - means = new Mean[dimension]; + means = new org.apache.commons.statistics.descriptive.Mean[dimension]; for (int i = 0; i < dimension; ++i) { - means[i] = new Mean(); + means[i] = org.apache.commons.statistics.descriptive.Mean.create(); } } @@ -48,8 +48,9 @@ public void increment(double[] v) throws DimensionMismatchException { throw new DimensionMismatchException(v.length, means.length); } for (int i = 0; i < v.length; ++i) { - means[i].increment(v[i]); + means[i].accept(v[i]); } + n++; } /** @@ -59,7 +60,7 @@ public void increment(double[] v) throws DimensionMismatchException { public double[] getResult() { double[] result = new double[means.length]; for (int i = 0; i < result.length; ++i) { - result[i] = means[i].getResult(); + result[i] = means[i].getAsDouble(); } return result; } @@ -69,28 +70,6 @@ public double[] getResult() { * @return number of vectors in the sample */ public long getN() { - return (means.length == 0) ? 0 : means[0].getN(); - } - - /** {@inheritDoc} */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + Arrays.hashCode(means); - return result; - } - - /** {@inheritDoc} */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof VectorialMean)) { - return false; - } - VectorialMean other = (VectorialMean) obj; - return Arrays.equals(means, other.means); + return (means.length == 0) ? 0 : n; } } diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/WeightedMean.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/WeightedMean.java new file mode 100644 index 0000000000..bea1ff5840 --- /dev/null +++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/moment/WeightedMean.java @@ -0,0 +1,173 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.math4.legacy.stat.descriptive.moment; + +import org.apache.commons.math4.legacy.core.MathArrays; +import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException; +import org.apache.commons.math4.legacy.stat.descriptive.WeightedEvaluation; + +/** + * Computes the weighted mean of a set of values. Uses the formula: + *+ * mean = sum(w_i * x_i) / sum(w_i) + *
+ *where w_i is the weight for observation x_i.
+ *
If used to compute the mean of an array + * of stored values, a two-pass, corrected algorithm is used, starting with + * the definitional formula computed using the array of stored values and then + * correcting this by adding the mean deviation of the data values from the + * arithmetic mean. See, e.g. "Comparison of Several Algorithms for Computing + * Sample Means and Variances," Robert F. Ling, Journal of the American + * Statistical Association, Vol. 69, No. 348 (Dec., 1974), pp. 859-866.
+ *
+ * Returns Double.NaN if the dataset is empty. Note that
+ * Double.NaN may also be returned if the input includes NaN and / or infinite
+ * values.
+ *
Double.NaN if the designated subarray
+ * is empty.
+ *
+ * Throws IllegalArgumentException if either array is null.
+ * See {@link WeightedMean} for details on the computing algorithm. The two-pass algorithm + * described above is used here, with weights applied in computing both the original + * estimate and the correction factor.
+ *
+ * Throws IllegalArgumentException if any of the following are true:
+ *
+ * Throws MathIllegalArgumentException if either array is null.
+ * See {@link WeightedMean} for details on the computing algorithm. The two-pass algorithm + * described above is used here, with weights applied in computing both the original + * estimate and the correction factor.
+ *
+ * Throws MathIllegalArgumentException if any of the following are true:
+ *
- * variance = sum((x_i - mean)^2) / (n - 1)
- *
- * where mean is the {@link Mean} and n is the number
- * of sample observations.
- * The definitional formula does not have good numerical properties, so - * this implementation does not compute the statistic using the definitional - * formula.
getResult method computes the variance using
- * updating formulas based on West's algorithm, as described in
- * Chan, T. F. and
- * J. G. Lewis 1979, Communications of the ACM,
- * vol. 22 no. 9, pp. 526-531.evaluate methods leverage the fact that they have the
- * full array of values in memory to execute a two-pass algorithm.
- * Specifically, these methods use the "corrected two-pass algorithm" from
- * Chan, Golub, Levesque, Algorithms for Computing the Sample Variance,
- * American Statistician, vol. 37, no. 3 (1983) pp. 242-247.increment or
- * incrementAll and then executing getResult will
- * sometimes give a different, less accurate, result than executing
- * evaluate with the full array of values. The former approach
- * should only be used when the full array of values is not available.
+ * where mean is the {@link WeightedMean} and w_i is the weight for
+ * observation x_i.
*
- * The "population variance" ( sum((x_i - mean)^2) / n ) can also
+ * The "population variance" using the denominator as sum(w_i) can also
* be computed using this statistic. The isBiasCorrected
* property determines whether the "population" or "sample" value is
- * returned by the evaluate and getResult methods.
+ * returned by the evaluate methods.
* To compute population variances, set this property to false.
*
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the increment() or
- * clear() method, it must be synchronized externally.
isBiasCorrected
- * property.
- */
- public Variance() {
- moment = new SecondMoment();
- }
-
- /**
- * Constructs a Variance based on an external second moment.
- *
- * When this constructor is used, the statistic may only be
- * incremented via the moment, i.e., {@link #increment(double)}
- * does nothing; whereas {@code m2.increment(value)} increments
- * both {@code m2} and the Variance instance constructed from it.
- *
- * @param m2 the SecondMoment (Third or Fourth moments work here as well.)
- */
- public Variance(final SecondMoment m2) {
- incMoment = false;
- this.moment = m2;
- }
-
- /**
- * Constructs a Variance with the specified isBiasCorrected
- * property.
- *
- * @param isBiasCorrected setting for bias correction - true means
- * bias will be corrected and is equivalent to using the "no arg"
- * constructor
- */
- public Variance(boolean isBiasCorrected) {
- moment = new SecondMoment();
- this.isBiasCorrected = isBiasCorrected;
- }
-
- /**
- * Constructs a Variance with the specified isBiasCorrected
- * property and the supplied external second moment.
- *
- * @param isBiasCorrected setting for bias correction - true means
- * bias will be corrected
- * @param m2 the SecondMoment (Third or Fourth moments work
- * here as well.)
- */
- public Variance(boolean isBiasCorrected, SecondMoment m2) {
- incMoment = false;
- this.moment = m2;
- this.isBiasCorrected = isBiasCorrected;
- }
-
- /**
- * Copy constructor, creates a new {@code Variance} identical
- * to the {@code original}.
- *
- * @param original the {@code Variance} instance to copy
- * @throws NullArgumentException if original is null
- */
- public Variance(Variance original) throws NullArgumentException {
- copy(original, this);
- }
-
- /**
- * {@inheritDoc}
- *
If all values are available, it is more accurate to use
- * {@link #evaluate(double[])} rather than adding values one at a time
- * using this method and then executing {@link #getResult}, since
- * evaluate leverages the fact that is has the full
- * list of values together to execute a two-pass algorithm.
- * See {@link Variance}.
Note also that when {@link #Variance(SecondMoment)} is used to - * create a Variance, this method does nothing. In that case, the - * SecondMoment should be incremented directly.
- */ - @Override - public void increment(final double d) { - if (incMoment) { - moment.increment(d); - } - } - - /** - * {@inheritDoc} - */ - @Override - public double getResult() { - if (moment.n == 0) { - return Double.NaN; - } else if (moment.n == 1) { - return 0d; - } else { - if (isBiasCorrected) { - return moment.m2 / (moment.n - 1d); - } else { - return moment.m2 / (moment.n); - } - } - } - - /** - * {@inheritDoc} - */ - @Override - public long getN() { - return moment.getN(); - } - - /** - * {@inheritDoc} + * Constructs a Variance. */ - @Override - public void clear() { - if (incMoment) { - moment.clear(); - } + private WeightedVariance() { + // Do nothing } /** - * Returns the variance of the entries in the input array, or - *Double.NaN if the array is empty.
- * - * See {@link Variance} for details on the computing algorithm.
- *- * Returns 0 for a single-value (i.e. length = 1) sample.
- *
- * Throws MathIllegalArgumentException if the array is null.
- * Does not change the internal state of the statistic.
+ * Gets a new instance. * - * @param values the input array - * @return the variance of the values or Double.NaN if length = 0 - * @throws MathIllegalArgumentException if the array is null + * @return an instance */ - @Override - public double evaluate(final double[] values) throws MathIllegalArgumentException { - if (values == null) { - throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); - } - return evaluate(values, 0, values.length); - } - - /** - * Returns the variance of the entries in the specified portion of - * the input array, orDouble.NaN if the designated subarray
- * is empty. Note that Double.NaN may also be returned if the input
- * includes NaN and / or infinite values.
- * - * See {@link Variance} for details on the computing algorithm.
- *- * Returns 0 for a single-value (i.e. length = 1) sample.
- *- * Does not change the internal state of the statistic.
- *
- * Throws MathIllegalArgumentException if the array is null.
Double.NaN if the designated subarray is empty.
- * - * See {@link Variance} for details on the computing algorithm.
- *- * The formula used assumes that the supplied mean value is the arithmetic - * mean of the sample data, not a known population parameter. This method - * is supplied only to save computation when the mean has already been - * computed.
- *- * Returns 0 for a single-value (i.e. length = 1) sample.
- *
- * Throws MathIllegalArgumentException if the array is null.
- * Does not change the internal state of the statistic.
- * - * @param values the input array - * @param mean the precomputed mean value - * @param begin index of the first array element to include - * @param length the number of elements to include - * @return the variance of the values or Double.NaN if length = 0 - * @throws MathIllegalArgumentException if the array is null or the array index - * parameters are not valid - */ - public double evaluate(final double[] values, final double mean, - final int begin, final int length) throws MathIllegalArgumentException { - - double var = Double.NaN; - - if (MathArrays.verifyValues(values, begin, length)) { - if (length == 1) { - var = 0.0; - } else if (length > 1) { - double accum = 0.0; - double dev = 0.0; - double accum2 = 0.0; - for (int i = begin; i < begin + length; i++) { - dev = values[i] - mean; - accum += dev * dev; - accum2 += dev; - } - double len = length; - if (isBiasCorrected) { - var = (accum - (accum2 * accum2 / len)) / (len - 1.0); - } else { - var = (accum - (accum2 * accum2 / len)) / len; - } - } - } - return var; - } - - /** - * Returns the variance of the entries in the input array, using the - * precomputed mean value. ReturnsDouble.NaN if the array
- * is empty.
- * - * See {@link Variance} for details on the computing algorithm.
- *
- * If isBiasCorrected is true the formula used
- * assumes that the supplied mean value is the arithmetic mean of the
- * sample data, not a known population parameter. If the mean is a known
- * population parameter, or if the "population" version of the variance is
- * desired, set isBiasCorrected to false before
- * invoking this method.
- * Returns 0 for a single-value (i.e. length = 1) sample.
- *
- * Throws MathIllegalArgumentException if the array is null.
- * Does not change the internal state of the statistic.
- * - * @param values the input array - * @param mean the precomputed mean value - * @return the variance of the values or Double.NaN if the array is empty - * @throws MathIllegalArgumentException if the array is null - */ - public double evaluate(final double[] values, final double mean) throws MathIllegalArgumentException { - return evaluate(values, mean, 0, values.length); - } - /** * Returns the weighted variance of the entries in the specified portion of * the input array, using the precomputed weighted mean value. Returns @@ -512,14 +225,12 @@ public double evaluate(final double[] values, final double[] weights, double accum = 0.0; double dev = 0.0; double accum2 = 0.0; - for (int i = begin; i < begin + length; i++) { + double sumWts = 0; + int end = begin + length; + for (int i = begin; i < end; i++) { dev = values[i] - mean; accum += weights[i] * (dev * dev); accum2 += weights[i] * dev; - } - - double sumWts = 0; - for (int i = begin; i < begin + length; i++) { sumWts += weights[i]; } @@ -597,32 +308,4 @@ public boolean isBiasCorrected() { public void setBiasCorrected(boolean biasCorrected) { this.isBiasCorrected = biasCorrected; } - - /** - * {@inheritDoc} - */ - @Override - public Variance copy() { - Variance result = new Variance(); - // No try-catch or advertised exception because parameters are guaranteed non-null - copy(this, result); - return result; - } - - /** - * Copies source to dest. - *Neither source nor dest can be null.
- * - * @param source Variance to copy - * @param dest Variance to copy to - * @throws NullArgumentException if either source or dest is null - */ - public static void copy(Variance source, Variance dest) - throws NullArgumentException { - NullArgumentException.check(source); - NullArgumentException.check(dest); - dest.moment = source.moment.copy(); - dest.isBiasCorrected = source.isBiasCorrected; - dest.incMoment = source.incMoment; - } } diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/CentralPivotingStrategy.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/CentralPivotingStrategy.java deleted file mode 100644 index 833d1594f9..0000000000 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/CentralPivotingStrategy.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.math4.legacy.stat.descriptive.rank; - -import org.apache.commons.math4.legacy.core.MathArrays; - -/** - * A mid point strategy based on the average of begin and end indices. - * @since 3.4 - */ -public class CentralPivotingStrategy implements PivotingStrategy { - /** - * {@inheritDoc} - * This in particular picks a average of begin and end indices - * @return The index corresponding to a simple average of - * the first and the last element indices of the array slice - * @throws org.apache.commons.math4.legacy.exception.MathIllegalArgumentException MathIllegalArgumentException when indices exceeds range - */ - @Override - public int pivotIndex(final double[] work, final int begin, final int end) { - MathArrays.verifyValues(work, begin, end - begin); - return begin + (end - begin)/2; - } -} diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/KthSelector.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/KthSelector.java deleted file mode 100644 index cad4a4940d..0000000000 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/KthSelector.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.math4.legacy.stat.descriptive.rank; - -import java.util.Arrays; - -import org.apache.commons.math4.legacy.exception.NullArgumentException; -import org.apache.commons.math4.core.jdkmath.JdkMath; - -/** - * A Simple Kth selector implementation to pick up the - * Kth ordered element from a work array containing the input - * numbers. - * @since 3.4 - */ -public class KthSelector { - /** Minimum selection size for insertion sort rather than selection. */ - private static final int MIN_SELECT_SIZE = 15; - - /** A {@link PivotingStrategy} used for pivoting. */ - private final PivotingStrategy pivotingStrategy; - - /** - * Constructor with default {@link MedianOf3PivotingStrategy median of 3} pivoting strategy. - */ - public KthSelector() { - this.pivotingStrategy = new MedianOf3PivotingStrategy(); - } - - /** - * Constructor with specified pivoting strategy. - * - * @param pivotingStrategy pivoting strategy to use - * @throws NullArgumentException when pivotingStrategy is null - * @see MedianOf3PivotingStrategy - * @see RandomPivotingStrategy - * @see CentralPivotingStrategy - */ - public KthSelector(final PivotingStrategy pivotingStrategy) { - NullArgumentException.check(pivotingStrategy); - this.pivotingStrategy = pivotingStrategy; - } - - /** Get the pivoting strategy. - * @return pivoting strategy - */ - public PivotingStrategy getPivotingStrategy() { - return pivotingStrategy; - } - - /** - * Select Kth value in the array. - * - * @param work work array to use to find out the Kth value - * @param pivotsHeap cached pivots heap that can be used for efficient estimation - * @param k the index whose value in the array is of interest - * @return Kth value - */ - public double select(final double[] work, final int[] pivotsHeap, final int k) { - int begin = 0; - int end = work.length; - int node = 0; - final boolean usePivotsHeap = pivotsHeap != null; - while (end - begin > MIN_SELECT_SIZE) { - final int pivot; - - if (usePivotsHeap && node < pivotsHeap.length && - pivotsHeap[node] >= 0) { - // the pivot has already been found in a previous call - // and the array has already been partitioned around it - pivot = pivotsHeap[node]; - } else { - // select a pivot and partition work array around it - pivot = partition(work, begin, end, pivotingStrategy.pivotIndex(work, begin, end)); - if (usePivotsHeap && node < pivotsHeap.length) { - pivotsHeap[node] = pivot; - } - } - - if (k == pivot) { - // the pivot was exactly the element we wanted - return work[k]; - } else if (k < pivot) { - // the element is in the left partition - end = pivot; - node = JdkMath.min(2 * node + 1, usePivotsHeap ? pivotsHeap.length : end); - } else { - // the element is in the right partition - begin = pivot + 1; - node = JdkMath.min(2 * node + 2, usePivotsHeap ? pivotsHeap.length : end); - } - } - Arrays.sort(work, begin, end); - return work[k]; - } - - /** - * Partition an array slice around a pivot.Partitioning exchanges array - * elements such that all elements smaller than pivot are before it and - * all elements larger than pivot are after it. - * - * @param work work array - * @param begin index of the first element of the slice of work array - * @param end index after the last element of the slice of work array - * @param pivot initial index of the pivot - * @return index of the pivot after partition - */ - private int partition(final double[] work, final int begin, final int end, final int pivot) { - - final double value = work[pivot]; - work[pivot] = work[begin]; - - int i = begin + 1; - int j = end - 1; - while (i < j) { - while (i < j && Double.compare(work[j], value) > 0) { - --j; - } - while (i < j && Double.compare(work[i], value) < 0) { - ++i; - } - - if (i < j) { - final double tmp = work[i]; - work[i++] = work[j]; - work[j--] = tmp; - } - } - - if (i >= end || Double.compare(work[i], value) > 0) { - --i; - } - work[begin] = work[i]; - work[i] = value; - return i; - } -} diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/Max.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/Max.java deleted file mode 100644 index 038ab5d9a9..0000000000 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/Max.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.math4.legacy.stat.descriptive.rank; - -import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException; -import org.apache.commons.math4.legacy.exception.NullArgumentException; -import org.apache.commons.math4.legacy.stat.descriptive.AbstractStorelessUnivariateStatistic; -import org.apache.commons.math4.legacy.core.MathArrays; - -/** - * Returns the maximum of the available values. - *NaN iff all values are NaN
- * (i.e. NaN values have no impact on the value of the statistic).Double.POSITIVE_INFINITY,
- * the result is Double.POSITIVE_INFINITY.
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the increment() or
- * clear() method, it must be synchronized externally.
Double.NaN if the designated subarray
- * is empty.
- *
- * Throws MathIllegalArgumentException if the array is null or
- * the array index parameters are not valid.
NaN iff all values are NaN
- * (i.e. NaN values have no impact on the value of the statistic).Double.POSITIVE_INFINITY,
- * the result is Double.POSITIVE_INFINITY.Neither source nor dest can be null.
- * - * @param source Max to copy - * @param dest Max to copy to - * @throws NullArgumentException if either source or dest is null - */ - public static void copy(Max source, Max dest) - throws NullArgumentException { - NullArgumentException.check(source); - NullArgumentException.check(dest); - dest.n = source.n; - dest.value = source.value; - } -} diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/Median.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/Median.java deleted file mode 100644 index dc772698b4..0000000000 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/Median.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.math4.legacy.stat.descriptive.rank; - -import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException; -import org.apache.commons.math4.legacy.exception.NullArgumentException; -import org.apache.commons.statistics.ranking.NaNStrategy; - - -/** - * Returns the median of the available values. This is the same as the 50th percentile. - * See {@link Percentile} for a description of the algorithm used. - *
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the increment() or
- * clear() method, it must be synchronized externally.
NaN iff all values are NaN
- * (i.e. NaN values have no impact on the value of the statistic).Double.NEGATIVE_INFINITY,
- * the result is Double.NEGATIVE_INFINITY.
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the increment() or
- * clear() method, it must be synchronized externally.
Double.NaN if the designated subarray
- * is empty.
- *
- * Throws MathIllegalArgumentException if the array is null or
- * the array index parameters are not valid.
NaN iff all values are NaN
- * (i.e. NaN values have no impact on the value of the statistic).Double.NEGATIVE_INFINITY,
- * the result is Double.NEGATIVE_INFINITY.Neither source nor dest can be null.
- * - * @param source Min to copy - * @param dest Min to copy to - * @throws NullArgumentException if either source or dest is null - */ - public static void copy(Min source, Min dest) - throws NullArgumentException { - NullArgumentException.check(source); - NullArgumentException.check(dest); - dest.n = source.n; - dest.value = source.value; - } -} diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/PSquarePercentile.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/PSquarePercentile.java index 8184fb71d3..dd234aa07c 100644 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/PSquarePercentile.java +++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/PSquarePercentile.java @@ -18,7 +18,6 @@ import java.text.DecimalFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -47,7 +46,8 @@ ** Note: This implementation is not synchronized and produces an approximate * result. For small samples, where data can be stored and processed in memory, - * {@link Percentile} should be used.
+ * {@link org.apache.commons.math4.legacy.stat.StatUtils#percentile(double[], double) StatUtils.percentile} + * should be used. */ public class PSquarePercentile extends AbstractStorelessUnivariateStatistic implements StorelessUnivariateStatistic { @@ -124,44 +124,6 @@ public PSquarePercentile(final double p) { this(DEFAULT_QUANTILE_DESIRED); } - /** - * {@inheritDoc} - */ - @Override - public int hashCode() { - double result = getResult(); - result = Double.isNaN(result) ? 37 : result; - final double markersHash = markers == null ? 0 : markers.hashCode(); - final double[] toHash = {result, quantile, markersHash, countOfObservations}; - return Arrays.hashCode(toHash); - } - - /** - * Returns true iff {@code o} is a {@code PSquarePercentile} returning the. - * same values as this for {@code getResult()} and {@code getN()} and also - * having equal markers - * - * @param o object to compare - * @return true if {@code o} is a {@code PSquarePercentile} with - * equivalent internal state - */ - @Override - public boolean equals(Object o) { - boolean result = false; - if (this == o) { - result = true; - } else if (o instanceof PSquarePercentile) { - PSquarePercentile that = (PSquarePercentile) o; - boolean isNotNull = markers != null && that.markers != null; - boolean isNull = markers == null && that.markers == null; - result = isNotNull ? markers.equals(that.markers) : isNull; - // markers as in the case of first - // five observations - result = result && getN() == that.getN(); - } - return result; - } - /** * {@inheritDoc}The internal state updated due to the new value in this * context is basically of the marker positions and computation of the @@ -377,33 +339,6 @@ private static Marker[] createMarkerArray( new Marker(initialFive.get(4), 5, 1, 5) }; } - /** - * {@inheritDoc} - */ - @Override - public int hashCode() { - return Arrays.deepHashCode(markerArray); - } - - /** - * {@inheritDoc}.This equals method basically checks for marker array to - * be deep equals. - * - * @param o is the other object - * @return true if the object compares with this object are equivalent - */ - @Override - public boolean equals(Object o) { - boolean result = false; - if (this == o) { - result = true; - } else if (o instanceof Markers) { - Markers that = (Markers) o; - result = Arrays.deepEquals(markerArray, that.markerArray); - } - return result; - } - /** * Process a data point. * @@ -750,49 +685,6 @@ private boolean isEstimateBad(final double[] y, final double yD) { return yD <= y[0] || yD >= y[2]; } - /** - * {@inheritDoc}This equals method checks for marker attributes and - * as well checks if navigation pointers (next and previous) are the same - * between this and passed in object - * - * @param o Other object - * @return true if this equals passed in other object o - */ - @Override - public boolean equals(Object o) { - boolean result = false; - if (this == o) { - result = true; - } else if (o instanceof Marker) { - Marker that = (Marker) o; - - result = Double.compare(markerHeight, that.markerHeight) == 0; - result = - result && - Double.compare(intMarkerPosition, - that.intMarkerPosition) == 0; - result = - result && - Double.compare(desiredMarkerPosition, - that.desiredMarkerPosition) == 0; - result = - result && - Double.compare(desiredMarkerIncrement, - that.desiredMarkerIncrement) == 0; - - result = result && next.index == that.next.index; - result = result && previous.index == that.previous.index; - } - return result; - } - - /** {@inheritDoc} */ - @Override - public int hashCode() { - return Arrays.hashCode(new double[] {markerHeight, intMarkerPosition, - desiredMarkerIncrement, desiredMarkerPosition, previous.index, next.index}); - } - /** * Copy this instance. * @@ -877,7 +769,7 @@ public boolean addAll(Collection extends E> collection) { * @param p the quantile desired * @return an instance of PSquareMarkers */ - public static PSquareMarkers newMarkers(final List- * There are several commonly used methods for estimating percentiles (a.k.a. - * quantiles) based on sample data. For large samples, the different methods - * agree closely, but when sample sizes are small, different methods will give - * significantly different results. The algorithm implemented here works as follows: - *
n be the length of the (sorted) array and
- * 0 < p <= 100 be the desired percentile. n = 1 return the unique array element (regardless of
- * the value of p); otherwise pos = p * (n + 1) / 100 and the difference, d
- * between pos and floor(pos) (i.e. the fractional
- * part of pos).pos < 1 return the smallest element in the array.pos >= n return the largest element in the array.lower be the element in position
- * floor(pos) in the array and let upper be the
- * next element in the array. Return lower + d * (upper - lower)
- *
- * To compute percentiles, the data must be at least partially ordered. Input
- * arrays are copied and recursively partitioned using an ordering definition.
- * The ordering used by Arrays.sort(double[]) is the one determined
- * by {@link java.lang.Double#compareTo(Double)}. This ordering makes
- * Double.NaN larger than any other value (including
- * Double.POSITIVE_INFINITY). Therefore, for example, the median
- * (50th percentile) of
- * {0, 1, 2, 3, 4, Double.NaN} evaluates to 2.5.
- * Since percentile estimation usually involves interpolation between array
- * elements, arrays containing NaN or infinite values will often
- * result in NaN or infinite values returned.
- * Further, to include different estimation types such as R1, R2 as mentioned in - * Quantile page(wikipedia), - * a type specific NaN handling strategy is used to closely match with the - * typically observed results from popular tools like R(R1-R9), Excel(R7).
- *- * Since 2.2, Percentile uses only selection instead of complete sorting - * and caches selection algorithm state between calls to the various - * {@code evaluate} methods. This greatly improves efficiency, both for a single - * percentile and multiple percentile computations. To maximize performance when - * multiple percentiles are computed based on the same data, users should set the - * data array once using either one of the {@link #evaluate(double[], double)} or - * {@link #setData(double[])} methods and thereafter {@link #evaluate(double)} - * with just the percentile provided. - *
- *
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the increment() or
- * clear() method, it must be synchronized externally.
- * The stored array is the one which was set by previous calls to - * {@link #setData(double[])} or {@link #setData(double[], double[], int, int)} - *
- * @param p the percentile value to compute - * @return the value of the statistic applied to the stored data - * @throws MathIllegalArgumentException if lengths of values and weights are not equal or values or weights is null - * @throws NotPositiveException if begin, length is negative - * @throws org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException if any weight is not positive - * @throws org.apache.commons.math4.legacy.exception.NotANumberException if any weight is NaN - * @throws OutOfRangeException if p is invalid - * @throws NumberIsTooLargeException if begin + length is greater than values.length - * (p must be greater than 0 and less than or equal to 100) - */ - public double evaluate(final double p) { - if (weights == null) { - return evaluate(getDataRef(), p); - } else { - return evaluate(getDataRef(), weights, p); - } - } - - /** - * Returns an estimate of thepth percentile of the values
- * in the values array.
- *
- * Calls to this method do not modify the internal quantile
- * state of this statistic.
Double.NaN if values has length
- * 0p) values[0]
- * if values has length 1MathIllegalArgumentException if values
- * is null or p is not a valid quantile value (p must be greater than 0
- * and less than or equal to 100) - * See {@link Percentile} for a description of the percentile estimation - * algorithm used.
- * - * @param values input array of values - * @param p the percentile value to compute - * @return the percentile value or Double.NaN if the array is empty - * @throws MathIllegalArgumentException ifvalues is null or p is invalid
- */
- public double evaluate(final double[] values, final double p) {
- MathArrays.verifyValues(values, 0, 0);
- return evaluate(values, 0, values.length, p);
- }
- /**
- * Returns an estimate of the pth percentile of the values
- * in the values array with their weights.
- * - * See {@link Percentile} for a description of the percentile estimation - * algorithm used.
- * @param values input array of values - * @param sampleWeights weights of values - * @param p the percentile value to compute - * @return the weighted percentile value or Double.NaN if the array is empty - * @throws MathIllegalArgumentException if lengths of values and weights are not equal or values or weights is null - * @throws NotPositiveException if begin, length is negative - * @throws org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException if any weight is not positive - * @throws org.apache.commons.math4.legacy.exception.NotANumberException if any weight is NaN - * @throws OutOfRangeException if p is invalid - * @throws NumberIsTooLargeException if begin + length is greater than values.length - */ - public double evaluate(final double[] values, final double[] sampleWeights, final double p) { - MathArrays.verifyValues(values, 0, 0); - MathArrays.verifyValues(sampleWeights, 0, 0); - return evaluate(values, sampleWeights, 0, values.length, p); - } - - /** - * Returns an estimate of thequantileth percentile of the
- * designated values in the values array. The quantile
- * estimated is determined by the quantile property.
- * Double.NaN if length = 0quantile)
- * values[begin] if length = 1 MathIllegalArgumentException if values
- * is null, or start or length is invalid- * See {@link Percentile} for a description of the percentile estimation - * algorithm used.
- * - * @param values the input array - * @param start index of the first array element to include - * @param length the number of elements to include - * @return the percentile value - * @throws MathIllegalArgumentException if the parameters are not valid - * - */ - @Override - public double evaluate(final double[] values, final int start, final int length) { - return evaluate(values, start, length, quantile); - } - /** - * Returns an estimate of the weightedquantileth percentile of the
- * designated values in the values array. The quantile
- * estimated is determined by the quantile property.
- * - * See {@link Percentile} for a description of the percentile estimation - * algorithm used.
- * - * @param values the input array - * @param sampleWeights the weights of values - * @param start index of the first array element to include - * @param length the number of elements to include - * @return the percentile value - * @throws MathIllegalArgumentException if lengths of values and weights are not equal or values or weights is null - * @throws NotPositiveException if begin, length is negative - * @throws org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException if any weight is not positive - * @throws org.apache.commons.math4.legacy.exception.NotANumberException if any weight is NaN - * @throws OutOfRangeException if p is invalid - * @throws NumberIsTooLargeException if begin + length is greater than values.length - */ - public double evaluate(final double[] values, final double[] sampleWeights, - final int start, final int length) { - return evaluate(values, sampleWeights, start, length, quantile); - } - - /** - * Returns an estimate of thepth percentile of the values
- * in the values array, starting with the element in (0-based)
- * position begin in the array and including length
- * values.
- *
- * Calls to this method do not modify the internal quantile
- * state of this statistic.
Double.NaN if length = 0p) values[begin]
- * if length = 1 MathIllegalArgumentException if values
- * is null , begin or length is invalid, or
- * p is not a valid quantile value (p must be greater than 0
- * and less than or equal to 100)- * See {@link Percentile} for a description of the percentile estimation - * algorithm used.
- * - * @param values array of input values - * @param p the percentile to compute - * @param begin the first (0-based) element to include in the computation - * @param length the number of array elements to include - * @return the percentile value. - * @throws MathIllegalArgumentException if the parameters are not valid. - */ - public double evaluate(final double[] values, final int begin, - final int length, final double p) { - MathArrays.verifyValues(values, begin, length); - if (p > 100 || p <= 0) { - throw new OutOfRangeException(LocalizedFormats.OUT_OF_BOUNDS_QUANTILE_VALUE, - p, 0, 100); - } - if (length == 0) { - return Double.NaN; - } - if (length == 1) { - return values[begin]; // always return single value for n = 1 - } - - final double[] work = getWorkArray(values, begin, length); - final int[] pivotsHeap = getPivots(values); - return work.length == 0 ? - Double.NaN : - estimationType.evaluate(work, pivotsHeap, p, kthSelector); - } - /** - * Returns an estimate of thepth percentile of the values
- * in the values array with sampleWeights, starting with the element in (0-based)
- * position begin in the array and including length
- * values.
- * - * See {@link Percentile} for a description of the percentile estimation - * algorithm used.
- * - * @param values array of input values - * @param sampleWeights positive and non-NaN weights of values - * @param begin the first (0-based) element to include in the computation - * @param length the number of array elements to include - * @param p percentile to compute - * @return the weighted percentile value - * @throws MathIllegalArgumentException if lengths of values and weights are not equal or values or weights is null - * @throws NotPositiveException if begin, length is negative - * @throws org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException if any weight is not positive - * @throws org.apache.commons.math4.legacy.exception.NotANumberException if any weight is NaN - * @throws OutOfRangeException if p is invalid - * @throws NumberIsTooLargeException if begin + length is greater than values.length - */ - public double evaluate(final double[] values, final double[] sampleWeights, final int begin, - final int length, final double p) { - if (values == null || sampleWeights == null) { - throw new MathIllegalArgumentException(LocalizedFormats.NULL_NOT_ALLOWED); - } - // Check length - if (values.length != sampleWeights.length) { - throw new MathIllegalArgumentException(LocalizedFormats.LENGTH, - values, sampleWeights); - } - MathArrays.verifyValues(values, begin, length); - MathArrays.verifyValues(sampleWeights, begin, length); - MathArrays.checkPositive(sampleWeights); - MathArrays.checkNotNaN(sampleWeights); - - if (p > 100 || p <= 0) { - throw new OutOfRangeException(LocalizedFormats.OUT_OF_BOUNDS_QUANTILE_VALUE, - p, 0, 100); - } - if (length == 0) { - return Double.NaN; - } - if (length == 1) { - // Always return single value for n = 1 - return values[begin]; - } - - final double[] work = getWorkArray(values, begin, length); - final double[] workWeights = getWorkArray(values, sampleWeights, begin, length); - return work.length == 0 ? Double.NaN : - estimationType.evaluate(work, workWeights, p); - } - /** - * Returns the value of the quantile field (determines what percentile is - * computed when evaluate() is called with no quantile argument). - * - * @return quantile set while construction or {@link #setQuantile(double)} - */ - public double getQuantile() { - return quantile; - } - - /** - * Sets the value of the quantile field (determines what percentile is - * computed when evaluate() is called with no quantile argument). - * - * @param p a value between 0 < p <= 100 - * @throws MathIllegalArgumentException if p is not greater than 0 and less - * than or equal to 100 - */ - public void setQuantile(final double p) { - if (p <= 0 || p > 100) { - throw new OutOfRangeException(LocalizedFormats.OUT_OF_BOUNDS_QUANTILE_VALUE, - p, 0, 100); - } - quantile = p; - } - - /** - * {@inheritDoc} - */ - @Override - public Percentile copy() { - return new Percentile(this); - } - - /** - * Get the work array to operate. Makes use of prior {@code storedData} if - * it exists or else do a check on NaNs and copy a subset of the array - * defined by begin and length parameters. The set {@link #nanStrategy} will - * be used to either retain/remove/replace any NaNs present before returning - * the resultant array. - * - * @param values the array of numbers - * @param begin index to start reading the array - * @param length the length of array to be read from the begin index - * @return work array sliced from values in the range [begin,begin+length) - * @throws MathIllegalArgumentException if values or indices are invalid - */ - private double[] getWorkArray(final double[] values, final int begin, final int length) { - final double[] work; - if (values == getDataRef()) { - work = getDataRef(); - } else { - switch (nanStrategy) { - case MAXIMAL: // Replace NaNs with +INFs - work = replaceAndSlice(values, begin, length, Double.NaN, Double.POSITIVE_INFINITY); - break; - case MINIMAL: // Replace NaNs with -INFs - work = replaceAndSlice(values, begin, length, Double.NaN, Double.NEGATIVE_INFINITY); - break; - case REMOVED: // Drop NaNs from data - work = removeAndSlice(values, begin, length, Double.NaN); - break; - case FAILED: // NaN is not acceptable - work = copyOf(values, begin, length); - MathArrays.checkNotNaN(work); - break; - default: // FIXED - work = copyOf(values,begin,length); - break; - } - } - return work; - } - /** - * Get the work arrays of weights to operate. - * - * @param values the array of numbers - * @param sampleWeights the array of weights - * @param begin index to start reading the array - * @param length the length of array to be read from the begin index - * @return work array sliced from values in the range [begin,begin+length) - */ - protected double[] getWorkArray(final double[] values, final double[] sampleWeights, - final int begin, final int length) { - final double[] work; - if (values == getDataRef()) { - work = this.weights; - } else { - switch (nanStrategy) { - case REMOVED: // Drop weight if the data is NaN - work = removeAndSliceByRef(values, sampleWeights, begin, length, Double.NaN); - break; - default: // FIXED - work = copyOf(sampleWeights, begin, length); - break; - } - } - return work; - } - /** - * Make a copy of the array for the slice defined by array part from. - * [begin, begin+length) - * @param values the input array - * @param begin start index of the array to include - * @param length number of elements to include from begin - * @return copy of a slice of the original array - */ - private static double[] copyOf(final double[] values, final int begin, final int length) { - MathArrays.verifyValues(values, begin, length); - return Arrays.copyOfRange(values, begin, begin + length); - } - - /** - * Replace every occurrence of a given value with a replacement value in a - * copied slice of array defined by array part from [begin, begin+length). - * - * @param values the input array - * @param begin start index of the array to include - * @param length number of elements to include from begin - * @param original the value to be replaced with - * @param replacement the value to be used for replacement - * @return the copy of sliced array with replaced values - */ - private static double[] replaceAndSlice(final double[] values, - final int begin, final int length, - final double original, - final double replacement) { - final double[] temp = copyOf(values, begin, length); - for(int i = 0; i < length; i++) { - temp[i] = Precision.equalsIncludingNaN(original, temp[i]) ? - replacement : - temp[i]; - } - - return temp; - } - /** - * Remove the occurrence of a given value in a copied slice of array - * defined by the array part from [begin, begin+length). - * @param values the input array - * @param begin start index of the array to include - * @param length number of elements to include from begin - * @param removedValue the value to be removed from the sliced array - * @return the copy of the sliced array after removing the removedValue - */ - private static double[] removeAndSlice(final double[] values, - final int begin, final int length, - final double removedValue) { - MathArrays.verifyValues(values, begin, length); - final double[] temp; - // Indicates where the removedValue is located - final BitSet bits = new BitSet(length); - for (int i = begin; i < begin+length; i++) { - if (Precision.equalsIncludingNaN(removedValue, values[i])) { - bits.set(i - begin); - } - } - // Check if empty then create a new copy - if (bits.isEmpty()) { - // Nothing removed, just copy - temp = copyOf(values, begin, length); - } else if(bits.cardinality() == length) { - // All removed, just empty - temp = new double[0]; - } else { - // Some removable, so new - temp = new double[length - bits.cardinality()]; - // Index from source array (i.e values) - int start = begin; - // Index in destination array(i.e temp) - int dest = 0; - // Index of bit set of next one - int nextOne = -1; - // Start index pointer of bitset - int bitSetPtr = 0; - while ((nextOne = bits.nextSetBit(bitSetPtr)) != -1) { - final int lengthToCopy = nextOne - bitSetPtr; - System.arraycopy(values, start, temp, dest, lengthToCopy); - dest += lengthToCopy; - start = begin + (bitSetPtr = bits.nextClearBit(nextOne)); - } - // Copy any residue past start index till begin+length - if (start < begin + length) { - System.arraycopy(values,start,temp,dest,begin + length - start); - } - } - return temp; - } - /** - * Remove weights element if the corresponding data is equal to the given value. - * in [begin, begin+length) - * - * @param values the input array - * @param sampleWeights weights of the input array - * @param begin start index of the array to include - * @param length number of elements to include from begin - * @param removedValue the value to be removed from the sliced array - * @return the copy of the sliced array after removing weights - */ - private static double[] removeAndSliceByRef(final double[] values, - final double[] sampleWeights, - final int begin, final int length, - final double removedValue) { - MathArrays.verifyValues(values, begin, length); - final double[] temp; - //BitSet(length) to indicate where the removedValue is located - final BitSet bits = new BitSet(length); - for (int i = begin; i < begin+length; i++) { - if (Precision.equalsIncludingNaN(removedValue, values[i])) { - bits.set(i - begin); - } - } - //Check if empty then create a new copy - if (bits.isEmpty()) { - temp = copyOf(sampleWeights, begin, length); // Nothing removed, just copy - } else if(bits.cardinality() == length) { - temp = new double[0]; // All removed, just empty - }else { // Some removable, so new - temp = new double[length - bits.cardinality()]; - int start = begin; //start index from source array (i.e sampleWeights) - int dest = 0; //dest index in destination array(i.e temp) - int nextOne = -1; //nextOne is the index of bit set of next one - int bitSetPtr = 0; //bitSetPtr is start index pointer of bitset - while ((nextOne = bits.nextSetBit(bitSetPtr)) != -1) { - final int lengthToCopy = nextOne - bitSetPtr; - System.arraycopy(sampleWeights, start, temp, dest, lengthToCopy); - dest += lengthToCopy; - start = begin + (bitSetPtr = bits.nextClearBit(nextOne)); - } - //Copy any residue past start index till begin+length - if (start < begin + length) { - System.arraycopy(sampleWeights,start,temp,dest,begin + length - start); - } - } - return temp; - } - /** - * Get pivots which is either cached or a newly created one. - * - * @param values array containing the input numbers - * @return cached pivots or a newly created one - */ - private int[] getPivots(final double[] values) { - final int[] pivotsHeap; - if (values == getDataRef()) { - pivotsHeap = cachedPivots; - } else { - pivotsHeap = new int[PIVOTS_HEAP_LENGTH]; - Arrays.fill(pivotsHeap, -1); - } - return pivotsHeap; - } - - /** - * Get the estimation {@link EstimationType type} used for computation. - * - * @return the {@code estimationType} set - */ - public EstimationType getEstimationType() { - return estimationType; - } - - /** - * Build a new instance similar to the current one except for the - * {@link EstimationType estimation type}. - *- * This method is intended to be used as part of a fluent-type builder - * pattern. Building finely tune instances should be done as follows: - *
- *- * Percentile customized = new Percentile(quantile). - * withEstimationType(estimationType). - * withNaNStrategy(nanStrategy). - * withKthSelector(kthSelector); - *- *
- * If any of the {@code withXxx} method is omitted, the default value for - * the corresponding customization parameter will be used. - *
- * @param newEstimationType estimation type for the new instance. - * Cannot be {@code null}. - * @return a new instance, with changed estimation type - */ - public Percentile withEstimationType(final EstimationType newEstimationType) { - return new Percentile(quantile, newEstimationType, nanStrategy, kthSelector); - } - - /** - * Get the {@link NaNStrategy NaN Handling} strategy used for computation. - * @return {@code NaN Handling} strategy set during construction - */ - public NaNStrategy getNaNStrategy() { - return nanStrategy; - } - - /** - * Build a new instance similar to the current one except for the - * {@link NaNStrategy NaN handling} strategy. - *- * This method is intended to be used as part of a fluent-type builder - * pattern. Building finely tune instances should be done as follows: - *
- *- * Percentile customized = new Percentile(quantile). - * withEstimationType(estimationType). - * withNaNStrategy(nanStrategy). - * withKthSelector(kthSelector); - *- *
- * If any of the {@code withXxx} method is omitted, the default value for - * the corresponding customization parameter will be used. - *
- * @param newNaNStrategy NaN strategy for the new instance. - * Cannot be {@code null}. - * @return a new instance, with changed NaN handling strategy - */ - public Percentile withNaNStrategy(final NaNStrategy newNaNStrategy) { - return new Percentile(quantile, estimationType, newNaNStrategy, kthSelector); - } - - /** - * Get the {@link KthSelector kthSelector} used for computation. - * @return the {@code kthSelector} set - */ - public KthSelector getKthSelector() { - return kthSelector; - } - - /** - * Get the {@link PivotingStrategy} used in KthSelector for computation. - * @return the pivoting strategy set - */ - public PivotingStrategy getPivotingStrategy() { - return kthSelector.getPivotingStrategy(); - } - - /** - * Build a new instance similar to the current one except for the - * {@link KthSelector kthSelector} instance specifically set. - *- * This method is intended to be used as part of a fluent-type builder - * pattern. Building finely tune instances should be done as follows: - *
- *- * Percentile customized = new Percentile(quantile). - * withEstimationType(estimationType). - * withNaNStrategy(nanStrategy). - * withKthSelector(newKthSelector); - *- *
- * If any of the {@code withXxx} method is omitted, the default value for - * the corresponding customization parameter will be used. - *
- * @param newKthSelector KthSelector for the new instance. - * Cannot be {@code null}. - * @return a new instance, with changed KthSelector - */ - public Percentile withKthSelector(final KthSelector newKthSelector) { - return new Percentile(quantile, estimationType, nanStrategy, newKthSelector); - } - - /** - * An enum for various estimation strategies of a percentile referred in - * wikipedia on quantile - * with the names of enum matching those of types mentioned in - * wikipedia. - *- * Each enum corresponding to the specific type of estimation in wikipedia - * implements the respective formulae that specializes in the below aspects - *
- * Users can now create {@link Percentile} by explicitly passing this enum; - * such as by invoking {@link Percentile#withEstimationType(EstimationType)} - *
- * References: - *
- * Note: This method computes the index in a manner very close to
- * the default Commons Math Percentile existing implementation. However
- * the difference to be noted is in picking up the limits with which
- * first element (p<1(N+1)) and last elements (p>N/(N+1))are done.
- * While in default case; these are done with p=0 and p=1 respectively.
- */
- R_6("R-6") {
-
- @Override
- protected double index(final double p, final int length) {
- final double minLimit = 1d / (length + 1);
- final double maxLimit = 1d * length / (length + 1);
- return Double.compare(p, minLimit) < 0 ? 0 :
- Double.compare(p, maxLimit) >= 0 ?
- length : (length + 1) * p;
- }
- @Override
- public double evaluate(final double[] work, final double[] sampleWeights,
- final double p) {
- throw new MathIllegalArgumentException(LocalizedFormats.UNSUPPORTED_OPERATION);
- }
- },
-
- /**
- * The method R_7 implements Microsoft Excel style computation has the
- * following formulae for index and estimates.
- * \( \begin{align}
- * &index = (N-1)p + 1 \\
- * &estimate = x_{\lfloor h \rfloor} + (h -
- * \lfloor h \rfloor) (x_{\lfloor h \rfloor + 1} - x_{\lfloor h
- * \rfloor}) \\
- * &minLimit = 0 \\
- * &maxLimit = 1 \\
- * \end{align}\)
- * The formula to evaluate weighted percentiles is as following.
- * \( \begin{align}
- * &S_k = (k-1)w_k + (n-1)\sum_{i=1}^{k-1}w_i
- * &Then find k s.t. \frac{S_k}{S_n}\leq p \leq \frac{S_{k+1}}{S_n}
- * \end{align}\)
- */
- R_7("R-7") {
- @Override
- protected double index(final double p, final int length) {
- final double minLimit = 0d;
- final double maxLimit = 1d;
- return Double.compare(p, minLimit) == 0 ? 0 :
- Double.compare(p, maxLimit) == 0 ?
- length : 1 + (length - 1) * p;
- }
-
- @Override
- public double evaluate(final double[] work, final double[] sampleWeights,
- final double p) {
- SortInPlace.ASCENDING.apply(work, sampleWeights);
- double[] sk = new double[work.length];
- for(int k = 0; k < work.length; k++) {
- sk[k] = 0;
- for (int j = 0; j < k; j++) {
- sk[k] += sampleWeights[j];
- }
- sk[k] = k * sampleWeights[k] + (work.length - 1) * sk[k];
- }
-
- double qsn = (p / 100) * sk[sk.length-1];
- int k = searchSk(qsn, sk, 0, work.length - 1);
-
- double ret;
- if (qsn == sk[k] && k == work.length - 1) {
- ret = work[k] - (work[k] - work[k-1]) * (1 - (qsn - sk[k]) / (sk[k] - sk[k-1]));
- } else {
- ret = work[k] + (work[k+1] - work[k]) * (qsn - sk[k]) / (sk[k+1] - sk[k]);
- }
- return ret;
- }
- },
-
- /**
- * The method R_8 has the following formulae for index and estimates.
- * \( \begin{align}
- * &index = (N + 1/3)p + 1/3 \\
- * &estimate = x_{\lfloor h \rfloor} + (h -
- \lfloor h \rfloor) (x_{\lfloor h \rfloor + 1} - x_{\lfloor h
- * \rfloor}) \\
- * &minLimit = (2/3)/(N+1/3) \\
- * &maxLimit = (N-1/3)/(N+1/3) \\
- * \end{align}\)
- *
- * As per Ref [2,3] this approach is most recommended as it provides
- * an approximate median-unbiased estimate regardless of distribution.
- */
- R_8("R-8") {
- @Override
- protected double index(final double p, final int length) {
- final double minLimit = 2 * (1d / 3) / (length + 1d / 3);
- final double maxLimit =
- (length - 1d / 3) / (length + 1d / 3);
- return Double.compare(p, minLimit) < 0 ? 0 :
- Double.compare(p, maxLimit) >= 0 ? length :
- (length + 1d / 3) * p + 1d / 3;
- }
- @Override
- public double evaluate(final double[] work, final double[] sampleWeights,
- final double p) {
- throw new MathIllegalArgumentException(LocalizedFormats.UNSUPPORTED_OPERATION);
- }
- },
-
- /**
- * The method R_9 has the following formulae for index and estimates.
- * \( \begin{align}
- * &index = (N + 1/4)p + 3/8\\
- * &estimate = x_{\lfloor h \rfloor} + (h -
- \lfloor h \rfloor) (x_{\lfloor h \rfloor + 1} - x_{\lfloor h
- * \rfloor}) \\
- * &minLimit = (5/8)/(N+1/4) \\
- * &maxLimit = (N-3/8)/(N+1/4) \\
- * \end{align}\)
- */
- R_9("R-9") {
- @Override
- protected double index(final double p, final int length) {
- final double minLimit = 5d/8 / (length + 0.25);
- final double maxLimit = (length - 3d/8) / (length + 0.25);
- return Double.compare(p, minLimit) < 0 ? 0 :
- Double.compare(p, maxLimit) >= 0 ? length :
- (length + 0.25) * p + 3d/8;
- }
- @Override
- public double evaluate(final double[] work, final double[] sampleWeights,
- final double p) {
- throw new MathIllegalArgumentException(LocalizedFormats.UNSUPPORTED_OPERATION);
- }
- },
- ;
-
- /** Simple name such as R-1, R-2 corresponding to those in wikipedia. */
- private final String name;
-
- /**
- * Constructor.
- *
- * @param type name of estimation type as per wikipedia
- */
- EstimationType(final String type) {
- this.name = type;
- }
-
- /**
- * Finds the index of array that can be used as starting index to
- * {@link #estimate(double[], int[], double, int, KthSelector) estimate}
- * percentile. The calculation of index calculation is specific to each
- * {@link EstimationType}.
- *
- * @param p the pth quantile
- * @param length the total number of array elements in the work array
- * @return a computed real valued index as explained in the wikipedia
- */
- protected abstract double index(double p, int length);
-
- /**
- * Estimation based on Kth selection. This may be overridden
- * in specific enums to compute slightly different estimations.
- *
- * @param work array of numbers to be used for finding the percentile
- * @param pos indicated positional index prior computed from calling
- * {@link #index(double, int)}
- * @param pivotsHeap an earlier populated cache if exists; will be used
- * @param length size of array considered
- * @param selector a {@link KthSelector} used for pivoting during search
- * @return estimated percentile
- */
- protected double estimate(final double[] work, final int[] pivotsHeap,
- final double pos, final int length,
- final KthSelector selector) {
-
- final double fpos = JdkMath.floor(pos);
- final int intPos = (int) fpos;
- final double dif = pos - fpos;
-
- if (pos < 1) {
- return selector.select(work, pivotsHeap, 0);
- }
- if (pos >= length) {
- return selector.select(work, pivotsHeap, length - 1);
- }
-
- final double lower = selector.select(work, pivotsHeap, intPos - 1);
- final double upper = selector.select(work, pivotsHeap, intPos);
- return lower + dif * (upper - lower);
- }
-
- /**
- * Evaluate method to compute the percentile for a given bounded array
- * using earlier computed pivots heap.
- * This basically calls the {@link #index(double, int) index} and then
- * {@link #estimate(double[], int[], double, int, KthSelector) estimate}
- * functions to return the estimated percentile value.
- *
- * @param work array of numbers to be used for finding the percentile.
- * Cannot be {@code null}.
- * @param pivotsHeap a prior cached heap which can speed up estimation
- * @param p the pth quantile to be computed
- * @param selector a {@link KthSelector} used for pivoting during search
- * @return estimated percentile
- * @throws OutOfRangeException if p is out of range
- */
- protected double evaluate(final double[] work, final int[] pivotsHeap, final double p,
- final KthSelector selector) {
- NullArgumentException.check(work);
- if (p > 100 || p <= 0) {
- throw new OutOfRangeException(LocalizedFormats.OUT_OF_BOUNDS_QUANTILE_VALUE,
- p, 0, 100);
- }
- return estimate(work, pivotsHeap, index(p/100d, work.length), work.length, selector);
- }
-
- /**
- * Evaluate method to compute the percentile for a given bounded array.
- * This basically calls the {@link #index(double, int) index} and then
- * {@link #estimate(double[], int[], double, int, KthSelector) estimate}
- * functions to return the estimated percentile value. Please
- * note that this method does not make use of cached pivots.
- *
- * @param work array of numbers to be used for finding the percentile.
- * Cannot be {@code null}.
- * @param p the pth quantile to be computed
- * @return estimated percentile
- * @param selector a {@link KthSelector} used for pivoting during search
- * @throws OutOfRangeException if length or p is out of range
- */
- public double evaluate(final double[] work, final double p, final KthSelector selector) {
- return this.evaluate(work, null, p, selector);
- }
- /**
- * Evaluate weighted percentile by estimation rule specified in {@link EstimationType}.
- * @param work array of numbers to be used for finding the percentile
- * @param sampleWeights the corresponding weights of data in work
- * @param p the pth quantile to be computed
- * @return estimated weighted percentile
- * @throws MathIllegalArgumentException if weighted percentile is not supported by the current estimationType
- */
- public abstract double evaluate(double[] work, double[] sampleWeights,
- double p);
- /**
- * Search the interval q*sn locates in.
- * @param qsn q*sn, where n refers to the data size
- * @param sk the cumulative weights array
- * @param lo start position to search qsn
- * @param hi end position to search qsn
- * @return the index of lower bound qsn locates in
- */
- private static int searchSk(double qsn, double[] sk, int lo, int hi) {
- if (sk.length == 1) {
- return 0;
- }
- if (hi - lo == 1) {
- if (qsn == sk[hi]) {
- return hi;
- }
- return lo;
- } else {
- int mid = (lo + hi) >>> 1;
- if (qsn == sk[mid]) {
- return mid;
- } else if (qsn > sk[mid]) {
- return searchSk(qsn, sk, mid, hi);
- } else {
- return searchSk(qsn, sk, lo, mid);
- }
- }
- }
- /**
- * Gets the name of the enum.
- *
- * @return the name
- */
- String getName() {
- return name;
- }
- }
-}
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/PivotingStrategy.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/PivotingStrategy.java
deleted file mode 100644
index 21905028ef..0000000000
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/PivotingStrategy.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.math4.legacy.stat.descriptive.rank;
-
-/**
- * A strategy to pick a pivoting index of an array for doing partitioning.
- *
- * @see MedianOf3PivotingStrategy
- * @see RandomPivotingStrategy
- * @see CentralPivotingStrategy
- * @since 4.0
- */
-public interface PivotingStrategy {
- /**
- * Find pivot index of the array so that partition and Kth
- * element selection can be made.
- * @param work data array
- * @param begin index of the first element of the slice
- * @param end index after the last element of the slice
- * @return the index of the pivot element chosen between the
- * first and the last element of the array slice
- * @throws IllegalArgumentException when indices exceeds range
- */
- int pivotIndex(double[] work, int begin, int end);
-}
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/RandomPivotingStrategy.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/RandomPivotingStrategy.java
deleted file mode 100644
index 044c7cd416..0000000000
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/rank/RandomPivotingStrategy.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.math4.legacy.stat.descriptive.rank;
-
-import org.apache.commons.math4.legacy.core.MathArrays;
-import org.apache.commons.rng.RestorableUniformRandomProvider;
-import org.apache.commons.rng.simple.RandomSource;
-
-/**
- * A strategy of selecting random index between begin and end indices.
- *
- * @since 3.4
- */
-public class RandomPivotingStrategy implements PivotingStrategy {
- /** Source of randomness. */
- private final RandomSource randomSource;
- /** Random generator to use for selecting pivot. */
- private transient RestorableUniformRandomProvider random;
-
- /**
- * Simple constructor.
- *
- * @param randomSource RNG to use for selecting pivot.
- * @param seed Seed for initializing the RNG.
- *
- * @since 4.0
- */
- public RandomPivotingStrategy(RandomSource randomSource,
- long seed) {
- this.randomSource = randomSource;
- random = randomSource.create(seed);
- }
-
- /**
- * {@inheritDoc}
- *
- * A uniform random pivot selection between begin and end indices.
- *
- * @return The index corresponding to a random uniformly selected
- * value between first and the last indices of the array slice
- * @throws org.apache.commons.math4.legacy.exception.MathIllegalArgumentException MathIllegalArgumentException when indices exceeds range
- */
- @Override
- public int pivotIndex(final double[] work, final int begin, final int end) {
- MathArrays.verifyValues(work, begin, end - begin);
- return begin + random.nextInt(end - begin - 1);
- }
-}
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/SumOfLogs.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/SumOfLogs.java
deleted file mode 100644
index d56d271da6..0000000000
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/SumOfLogs.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.math4.legacy.stat.descriptive.summary;
-
-import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
-import org.apache.commons.math4.legacy.exception.NullArgumentException;
-import org.apache.commons.math4.legacy.stat.descriptive.AbstractStorelessUnivariateStatistic;
-import org.apache.commons.math4.core.jdkmath.JdkMath;
-import org.apache.commons.math4.legacy.core.MathArrays;
-
-/**
- * Returns the sum of the natural logs for this collection of values.
- *
- * Uses {@link org.apache.commons.math4.core.jdkmath.JdkMath#log(double)} to compute the logs. - * Therefore, - *
NaN.Double.POSITIVE_INFINITY, but at least one value is 0, the
- * result is Double.NEGATIVE_INFINITY.Double.POSITIVE_INFINITY and
- * Double.NEGATIVE_INFINITY are among the values, the result is
- * NaN.
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the increment() or
- * clear() method, it must be synchronized externally.
Double.NaN if the designated subarray
- * is empty.
- *
- * Throws MathIllegalArgumentException if the array is null.
- * See {@link SumOfLogs}.
- * - * @param values the input array - * @param begin index of the first array element to include - * @param length the number of elements to include - * @return the sum of the natural logs of the values or 0 if - * length = 0 - * @throws MathIllegalArgumentException if the array is null or the array index - * parameters are not valid - */ - @Override - public double evaluate(final double[] values, final int begin, final int length) - throws MathIllegalArgumentException { - - double sumLog = Double.NaN; - if (MathArrays.verifyValues(values, begin, length, true)) { - sumLog = 0.0; - for (int i = begin; i < begin + length; i++) { - sumLog += JdkMath.log(values[i]); - } - } - return sumLog; - } - - /** - * {@inheritDoc} - */ - @Override - public SumOfLogs copy() { - SumOfLogs result = new SumOfLogs(); - // No try-catch or advertised exception here because args are valid - copy(this, result); - return result; - } - - /** - * Copies source to dest. - *Neither source nor dest can be null.
- * - * @param source SumOfLogs to copy - * @param dest SumOfLogs to copy to - * @throws NullArgumentException if either source or dest is null - */ - public static void copy(SumOfLogs source, SumOfLogs dest) - throws NullArgumentException { - NullArgumentException.check(source); - NullArgumentException.check(dest); - dest.n = source.n; - dest.value = source.value; - } -} diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/SumOfSquares.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/SumOfSquares.java deleted file mode 100644 index 9c28aa7134..0000000000 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/SumOfSquares.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.math4.legacy.stat.descriptive.summary; - -import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException; -import org.apache.commons.math4.legacy.exception.NullArgumentException; -import org.apache.commons.math4.legacy.stat.descriptive.AbstractStorelessUnivariateStatistic; -import org.apache.commons.math4.legacy.core.MathArrays; - -/** - * Returns the sum of the squares of the available values. - *
- * If there are no values in the dataset, then 0 is returned.
- * If any of the values are
- * NaN, then NaN is returned.
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the increment() or
- * clear() method, it must be synchronized externally.
Double.NaN if the designated subarray
- * is empty.
- *
- * Throws MathIllegalArgumentException if the array is null.
Neither source nor dest can be null.
- * - * @param source SumOfSquares to copy - * @param dest SumOfSquares to copy to - * @throws NullArgumentException if either source or dest is null - */ - public static void copy(SumOfSquares source, SumOfSquares dest) - throws NullArgumentException { - NullArgumentException.check(source); - NullArgumentException.check(dest); - dest.n = source.n; - dest.value = source.value; - } -} diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/Product.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/WeightedProduct.java similarity index 55% rename from commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/Product.java rename to commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/WeightedProduct.java index 88c8c4b16e..d78c305504 100644 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/Product.java +++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/WeightedProduct.java @@ -16,117 +16,39 @@ */ package org.apache.commons.math4.legacy.stat.descriptive.summary; -import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException; -import org.apache.commons.math4.legacy.exception.NullArgumentException; -import org.apache.commons.math4.legacy.stat.descriptive.AbstractStorelessUnivariateStatistic; -import org.apache.commons.math4.legacy.stat.descriptive.WeightedEvaluation; import org.apache.commons.math4.core.jdkmath.JdkMath; import org.apache.commons.math4.legacy.core.MathArrays; +import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException; +import org.apache.commons.math4.legacy.stat.descriptive.WeightedEvaluation; /** - * Returns the product of the available values. + * Returns the weighted product of the available values. *
* If there are no values in the dataset, then 1 is returned.
- * If any of the values are
+ * If any of the values are
* NaN, then NaN is returned.
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the increment() or
- * clear() method, it must be synchronized externally.
Double.NaN if the designated subarray
- * is empty.
- *
- * Throws MathIllegalArgumentException if the array is null.
Returns the weighted product of the entries in the specified portion of
- * the input array, or Double.NaN if the designated subarray
+ * the input array, or 1 if the designated subarray
* is empty.
Throws MathIllegalArgumentException if any of the following are true:
@@ -193,31 +115,4 @@ public double evaluate(final double[] values, final double[] weights,
public double evaluate(final double[] values, final double[] weights) throws MathIllegalArgumentException {
return evaluate(values, weights, 0, values.length);
}
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Product copy() {
- Product result = new Product();
- // No try-catch or advertised exception because args are valid
- copy(this, result);
- return result;
- }
-
- /**
- * Copies source to dest.
- *
Neither source nor dest can be null.
- * - * @param source Product to copy - * @param dest Product to copy to - * @throws NullArgumentException if either source or dest is null - */ - public static void copy(Product source, Product dest) - throws NullArgumentException { - NullArgumentException.check(source); - NullArgumentException.check(dest); - dest.n = source.n; - dest.value = source.value; - } } diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/Sum.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/WeightedSum.java similarity index 50% rename from commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/Sum.java rename to commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/WeightedSum.java index 2522652f1b..45819d0a0e 100644 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/Sum.java +++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/summary/WeightedSum.java @@ -17,110 +17,32 @@ package org.apache.commons.math4.legacy.stat.descriptive.summary; import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException; -import org.apache.commons.math4.legacy.exception.NullArgumentException; -import org.apache.commons.math4.legacy.stat.descriptive.AbstractStorelessUnivariateStatistic; +import org.apache.commons.math4.legacy.stat.descriptive.WeightedEvaluation; import org.apache.commons.math4.legacy.core.MathArrays; - /** - * Returns the sum of the available values. + * Returns the weighted sum of the available values. *
* If there are no values in the dataset, then 0 is returned.
* If any of the values are
- * NaN, then NaN is returned.
- * Note that this implementation is not synchronized. If
- * multiple threads access an instance of this class concurrently, and at least
- * one of the threads invokes the increment() or
- * clear() method, it must be synchronized externally.
- * Throws MathIllegalArgumentException if the array is null.
Neither source nor dest can be null.
- * - * @param source Sum to copy - * @param dest Sum to copy to - * @throws NullArgumentException if either source or dest is null - */ - public static void copy(Sum source, Sum dest) - throws NullArgumentException { - NullArgumentException.check(source); - NullArgumentException.check(dest); - dest.n = source.n; - dest.value = source.value; - } } diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/regression/AbstractMultipleLinearRegression.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/regression/AbstractMultipleLinearRegression.java index c23e7dbc33..727551e10c 100644 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/regression/AbstractMultipleLinearRegression.java +++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/regression/AbstractMultipleLinearRegression.java @@ -27,7 +27,7 @@ import org.apache.commons.math4.legacy.linear.NonSquareMatrixException; import org.apache.commons.math4.legacy.linear.RealMatrix; import org.apache.commons.math4.legacy.linear.RealVector; -import org.apache.commons.math4.legacy.stat.descriptive.moment.Variance; +import org.apache.commons.statistics.descriptive.Variance; import org.apache.commons.math4.core.jdkmath.JdkMath; /** @@ -347,7 +347,7 @@ public double estimateRegressionStandardError() { * @return Y variance */ protected double calculateYVariance() { - return new Variance().evaluate(yVector.toArray()); + return Variance.of(yVector.toArray()).getAsDouble(); } /** diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/regression/OLSMultipleLinearRegression.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/regression/OLSMultipleLinearRegression.java index 6318dc0a7d..123e9570d2 100644 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/regression/OLSMultipleLinearRegression.java +++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/regression/OLSMultipleLinearRegression.java @@ -23,7 +23,7 @@ import org.apache.commons.math4.legacy.linear.RealMatrix; import org.apache.commons.math4.legacy.linear.RealVector; import org.apache.commons.math4.legacy.stat.StatUtils; -import org.apache.commons.math4.legacy.stat.descriptive.moment.SecondMoment; +import org.apache.commons.statistics.descriptive.Mean; /** *Implements ordinary least squares (OLS) to estimate the parameters of a
@@ -161,10 +161,17 @@ public RealMatrix calculateHat() {
* @since 2.2
*/
public double calculateTotalSumOfSquares() {
+ final double[] y = getY().toArray();
if (isNoIntercept()) {
- return StatUtils.sumSq(getY().toArray());
+ return StatUtils.sumSq(y);
} else {
- return new SecondMoment().evaluate(getY().toArray());
+ final double m = Mean.of(y).getAsDouble();
+ double s = 0;
+ for (final double v : y) {
+ final double d = v - m;
+ s += d * d;
+ }
+ return s;
}
}
diff --git a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/distribution/fitting/MultivariateNormalMixtureExpectationMaximizationTest.java b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/distribution/fitting/MultivariateNormalMixtureExpectationMaximizationTest.java
index 2810364562..ed039b30cf 100644
--- a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/distribution/fitting/MultivariateNormalMixtureExpectationMaximizationTest.java
+++ b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/distribution/fitting/MultivariateNormalMixtureExpectationMaximizationTest.java
@@ -26,7 +26,6 @@
import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
import org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
-import org.apache.commons.math4.legacy.linear.Array2DRowRealMatrix;
import org.apache.commons.math4.legacy.linear.RealMatrix;
import org.apache.commons.math4.legacy.core.Pair;
import org.junit.Assert;
@@ -153,24 +152,21 @@ public void testInitialMixture() {
{5.090902706507635, 8.68540656355283},
};
- final RealMatrix[] correctCovMats = new Array2DRowRealMatrix[2];
-
- correctCovMats[0] = new Array2DRowRealMatrix(new double[][] {
- { 4.537422569229048, 3.5266152281729304 },
- { 3.5266152281729304, 6.175448814169779 } });
-
- correctCovMats[1] = new Array2DRowRealMatrix( new double[][] {
- { 2.886778573963039, 1.5257474543463154 },
- { 1.5257474543463154, 3.3794567673616918 } });
+ final double[][][] correctCovMats = new double[][][] {
+ {{4.537422569229048, 3.5266152281729304},
+ {3.5266152281729304, 6.175448814169779}},
+ {{2.886778573963039, 1.5257474543463154},
+ {1.5257474543463154, 3.3794567673616918}}
+ };
final MultivariateNormalDistribution[] correctMVNs = new
MultivariateNormalDistribution[2];
correctMVNs[0] = new MultivariateNormalDistribution(correctMeans[0],
- correctCovMats[0].getData());
+ correctCovMats[0]);
correctMVNs[1] = new MultivariateNormalDistribution(correctMeans[1],
- correctCovMats[1].getData());
+ correctCovMats[1]);
final MixtureMultivariateNormalDistribution initialMix
= MultivariateNormalMixtureExpectationMaximization.estimate(getTestSamples(), 2);
@@ -185,7 +181,7 @@ public void testInitialMixture() {
Assert.assertArrayEquals(correctMeans[i], means, 0.0);
final RealMatrix covMat = component.getValue().getCovariances();
- Assert.assertEquals(correctCovMats[i], covMat);
+ assertArrayEquals(correctCovMats[i], covMat.getData(), 1e-15);
i++;
}
}
@@ -305,6 +301,13 @@ private static void assertFit(double[][] data, int numComponents,
}
}
+ private static void assertArrayEquals(double[][] e, double[][] a, double relError) {
+ Assert.assertEquals("length", e.length, a.length);
+ for (int i = 0; i < e.length; i++) {
+ assertArrayEquals(e[i], a[i], relError);
+ }
+ }
+
private static void assertArrayEquals(double[] e, double[] a, double relError) {
Assert.assertEquals("length", e.length, a.length);
for (int i = 0; i < e.length; i++) {
diff --git a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/StatUtilsTest.java b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/StatUtilsTest.java
index 41257c7ed4..b5a8dcd5c8 100644
--- a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/StatUtilsTest.java
+++ b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/StatUtilsTest.java
@@ -25,6 +25,7 @@
import org.apache.commons.numbers.core.Precision;
import org.junit.Assert;
import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
/**
* Test cases for the {@link StatUtils} class.
@@ -51,7 +52,6 @@ public void testStats() {
Assert.assertEquals("sum", SUM, StatUtils.sum(values), TOLERANCE);
Assert.assertEquals("sumsq", SUMSQ, StatUtils.sumSq(values), TOLERANCE);
Assert.assertEquals("var", VAR, StatUtils.variance(values), TOLERANCE);
- Assert.assertEquals("var with mean", VAR, StatUtils.variance(values, MEAN), TOLERANCE);
Assert.assertEquals("mean", MEAN, StatUtils.mean(values), TOLERANCE);
Assert.assertEquals("min", MIN, StatUtils.min(values), TOLERANCE);
Assert.assertEquals("max", MAX, StatUtils.max(values), TOLERANCE);
@@ -109,6 +109,41 @@ public void testArrayIndexConditions() {
}
}
+ @Test
+ public void testSum() {
+ double[] x = null;
+
+ // test null
+ try {
+ StatUtils.sum(x);
+ Assert.fail("null is not a valid data array.");
+ } catch (NullArgumentException ex) {
+ // success
+ }
+
+ try {
+ StatUtils.sum(x, 0, 4);
+ Assert.fail("null is not a valid data array.");
+ } catch (NullArgumentException ex) {
+ // success
+ }
+
+ // test empty
+ x = new double[] {};
+ TestUtils.assertEquals(Double.NaN, StatUtils.sum(x), TOLERANCE);
+ TestUtils.assertEquals(Double.NaN, StatUtils.sum(x, 0, 0), TOLERANCE);
+
+ // test one
+ x = new double[] {TWO};
+ TestUtils.assertEquals(2, StatUtils.sum(x), TOLERANCE);
+ TestUtils.assertEquals(2, StatUtils.sum(x, 0, 1), TOLERANCE);
+
+ // test many
+ x = new double[] {ONE, TWO, TWO, THREE};
+ TestUtils.assertEquals(8, StatUtils.sum(x), TOLERANCE);
+ TestUtils.assertEquals(4, StatUtils.sum(x, 1, 2), TOLERANCE);
+ }
+
@Test
public void testSumSq() {
double[] x = null;
@@ -130,8 +165,8 @@ public void testSumSq() {
// test empty
x = new double[] {};
- TestUtils.assertEquals(0, StatUtils.sumSq(x), TOLERANCE);
- TestUtils.assertEquals(0, StatUtils.sumSq(x, 0, 0), TOLERANCE);
+ TestUtils.assertEquals(Double.NaN, StatUtils.sumSq(x), TOLERANCE);
+ TestUtils.assertEquals(Double.NaN, StatUtils.sumSq(x, 0, 0), TOLERANCE);
// test one
x = new double[] {TWO};
@@ -165,8 +200,8 @@ public void testProduct() {
// test empty
x = new double[] {};
- TestUtils.assertEquals(1, StatUtils.product(x), TOLERANCE);
- TestUtils.assertEquals(1, StatUtils.product(x, 0, 0), TOLERANCE);
+ TestUtils.assertEquals(Double.NaN, StatUtils.product(x), TOLERANCE);
+ TestUtils.assertEquals(Double.NaN, StatUtils.product(x, 0, 0), TOLERANCE);
// test one
x = new double[] {TWO};
@@ -200,8 +235,8 @@ public void testSumLog() {
// test empty
x = new double[] {};
- TestUtils.assertEquals(0, StatUtils.sumLog(x), TOLERANCE);
- TestUtils.assertEquals(0, StatUtils.sumLog(x, 0, 0), TOLERANCE);
+ TestUtils.assertEquals(Double.NaN, StatUtils.sumLog(x), TOLERANCE);
+ TestUtils.assertEquals(Double.NaN, StatUtils.sumLog(x, 0, 0), TOLERANCE);
// test one
x = new double[] {TWO};
@@ -227,14 +262,17 @@ public void testMean() {
// test empty
x = new double[] {};
+ TestUtils.assertEquals(Double.NaN, StatUtils.mean(x), TOLERANCE);
TestUtils.assertEquals(Double.NaN, StatUtils.mean(x, 0, 0), TOLERANCE);
// test one
x = new double[] {TWO};
+ TestUtils.assertEquals(TWO, StatUtils.mean(x), TOLERANCE);
TestUtils.assertEquals(TWO, StatUtils.mean(x, 0, 1), TOLERANCE);
// test many
x = new double[] {ONE, TWO, TWO, THREE};
+ TestUtils.assertEquals(2, StatUtils.mean(x), TOLERANCE);
TestUtils.assertEquals(2.5, StatUtils.mean(x, 2, 2), TOLERANCE);
}
@@ -251,19 +289,18 @@ public void testVariance() {
// test empty
x = new double[] {};
+ TestUtils.assertEquals(Double.NaN, StatUtils.variance(x), TOLERANCE);
TestUtils.assertEquals(Double.NaN, StatUtils.variance(x, 0, 0), TOLERANCE);
// test one
x = new double[] {TWO};
+ TestUtils.assertEquals(0.0, StatUtils.variance(x), TOLERANCE);
TestUtils.assertEquals(0.0, StatUtils.variance(x, 0, 1), TOLERANCE);
// test many
x = new double[] {ONE, TWO, TWO, THREE};
+ TestUtils.assertEquals(2.0 / 3, StatUtils.variance(x), TOLERANCE);
TestUtils.assertEquals(0.5, StatUtils.variance(x, 2, 2), TOLERANCE);
-
- // test precomputed mean
- x = new double[] {ONE, TWO, TWO, THREE};
- TestUtils.assertEquals(0.5, StatUtils.variance(x,2.5, 2, 2), TOLERANCE);
}
@Test
@@ -279,19 +316,18 @@ public void testPopulationVariance() {
// test empty
x = new double[] {};
+ TestUtils.assertEquals(Double.NaN, StatUtils.populationVariance(x), TOLERANCE);
TestUtils.assertEquals(Double.NaN, StatUtils.populationVariance(x, 0, 0), TOLERANCE);
// test one
x = new double[] {TWO};
TestUtils.assertEquals(0.0, StatUtils.populationVariance(x, 0, 1), TOLERANCE);
+ TestUtils.assertEquals(0.0, StatUtils.populationVariance(x, 0, 1), TOLERANCE);
// test many
x = new double[] {ONE, TWO, TWO, THREE};
+ TestUtils.assertEquals(0.5, StatUtils.populationVariance(x), TOLERANCE);
TestUtils.assertEquals(0.25, StatUtils.populationVariance(x, 0, 2), TOLERANCE);
-
- // test precomputed mean
- x = new double[] {ONE, TWO, TWO, THREE};
- TestUtils.assertEquals(0.25, StatUtils.populationVariance(x, 2.5, 2, 2), TOLERANCE);
}
@@ -308,27 +344,32 @@ public void testMax() {
// test empty
x = new double[] {};
+ TestUtils.assertEquals(Double.NaN, StatUtils.max(x), TOLERANCE);
TestUtils.assertEquals(Double.NaN, StatUtils.max(x, 0, 0), TOLERANCE);
// test one
x = new double[] {TWO};
+ TestUtils.assertEquals(TWO, StatUtils.max(x), TOLERANCE);
TestUtils.assertEquals(TWO, StatUtils.max(x, 0, 1), TOLERANCE);
// test many
x = new double[] {ONE, TWO, TWO, THREE};
- TestUtils.assertEquals(THREE, StatUtils.max(x, 1, 3), TOLERANCE);
-
- // test first nan is ignored
- x = new double[] {NAN, TWO, THREE};
TestUtils.assertEquals(THREE, StatUtils.max(x), TOLERANCE);
+ TestUtils.assertEquals(THREE, StatUtils.max(x, 1, 3), TOLERANCE);
- // test middle nan is ignored
- x = new double[] {ONE, NAN, THREE};
- TestUtils.assertEquals(THREE, StatUtils.max(x), TOLERANCE);
+ // Legacy behaviour
- // test last nan is ignored
- x = new double[] {ONE, TWO, NAN};
- TestUtils.assertEquals(TWO, StatUtils.max(x), TOLERANCE);
+// // test first nan is ignored
+// x = new double[] {NAN, TWO, THREE};
+// TestUtils.assertEquals(THREE, StatUtils.max(x), TOLERANCE);
+//
+// // test middle nan is ignored
+// x = new double[] {ONE, NAN, THREE};
+// TestUtils.assertEquals(THREE, StatUtils.max(x), TOLERANCE);
+//
+// // test last nan is ignored
+// x = new double[] {ONE, TWO, NAN};
+// TestUtils.assertEquals(TWO, StatUtils.max(x), TOLERANCE);
// test all nan returns nan
x = new double[] {NAN, NAN, NAN};
@@ -348,27 +389,32 @@ public void testMin() {
// test empty
x = new double[] {};
+ TestUtils.assertEquals(Double.NaN, StatUtils.min(x), TOLERANCE);
TestUtils.assertEquals(Double.NaN, StatUtils.min(x, 0, 0), TOLERANCE);
// test one
x = new double[] {TWO};
+ TestUtils.assertEquals(TWO, StatUtils.min(x), TOLERANCE);
TestUtils.assertEquals(TWO, StatUtils.min(x, 0, 1), TOLERANCE);
// test many
x = new double[] {ONE, TWO, TWO, THREE};
+ TestUtils.assertEquals(ONE, StatUtils.min(x), TOLERANCE);
TestUtils.assertEquals(TWO, StatUtils.min(x, 1, 3), TOLERANCE);
- // test first nan is ignored
- x = new double[] {NAN, TWO, THREE};
- TestUtils.assertEquals(TWO, StatUtils.min(x), TOLERANCE);
-
- // test middle nan is ignored
- x = new double[] {ONE, NAN, THREE};
- TestUtils.assertEquals(ONE, StatUtils.min(x), TOLERANCE);
+ // Legacy behaviour
- // test last nan is ignored
- x = new double[] {ONE, TWO, NAN};
- TestUtils.assertEquals(ONE, StatUtils.min(x), TOLERANCE);
+// // test first nan is ignored
+// x = new double[] {NAN, TWO, THREE};
+// TestUtils.assertEquals(TWO, StatUtils.min(x), TOLERANCE);
+//
+// // test middle nan is ignored
+// x = new double[] {ONE, NAN, THREE};
+// TestUtils.assertEquals(ONE, StatUtils.min(x), TOLERANCE);
+//
+// // test last nan is ignored
+// x = new double[] {ONE, TWO, NAN};
+// TestUtils.assertEquals(ONE, StatUtils.min(x), TOLERANCE);
// test all nan returns nan
x = new double[] {NAN, NAN, NAN};
@@ -427,6 +473,13 @@ public void testDifferenceStats() {
} catch (MathIllegalArgumentException ex) {
// expected
}
+ try {
+ double[] empty = {};
+ StatUtils.meanDifference(empty, empty);
+ Assert.fail("Expecting MathIllegalArgumentException");
+ } catch (MathIllegalArgumentException ex) {
+ // expected
+ }
try {
StatUtils.varianceDifference(sample1, small, meanDifference);
Assert.fail("Expecting MathIllegalArgumentException");
@@ -544,5 +597,15 @@ public void testMode() {
} catch (NullArgumentException ex) {
// Expected
}
+
+ // Range tests
+ Assertions.assertArrayEquals(new double[] {0}, StatUtils.mode(singleMode, 0, 4));
+ Assertions.assertArrayEquals(new double[] {0, 2, 7, 11}, StatUtils.mode(singleMode, 2, 4));
+ Assertions.assertArrayEquals(new double[] {0}, StatUtils.mode(twoMode, 0, 4));
+ Assertions.assertArrayEquals(new double[] {0, 2}, StatUtils.mode(twoMode, 0, 5));
+ Assertions.assertThrows(NullArgumentException.class, () -> StatUtils.mode(null, 0, 5));
+ Assertions.assertThrows(MathIllegalArgumentException.class, () -> StatUtils.mode(singleMode, -1, 1));
+ Assertions.assertThrows(MathIllegalArgumentException.class, () -> StatUtils.mode(singleMode, 0, -1));
+ Assertions.assertThrows(MathIllegalArgumentException.class, () -> StatUtils.mode(singleMode, 0, 100));
}
}
diff --git a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/correlation/CovarianceTest.java b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/correlation/CovarianceTest.java
index 5fc107d55a..099aceb1ee 100644
--- a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/correlation/CovarianceTest.java
+++ b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/correlation/CovarianceTest.java
@@ -21,7 +21,6 @@
import org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.legacy.linear.Array2DRowRealMatrix;
import org.apache.commons.math4.legacy.linear.RealMatrix;
-import org.apache.commons.math4.legacy.stat.descriptive.moment.Variance;
import org.junit.Assert;
import org.junit.Test;
@@ -204,9 +203,9 @@ public void testConsistency() {
final RealMatrix covarianceMatrix = new Covariance(matrix).getCovarianceMatrix();
// Variances on the diagonal
- Variance variance = new Variance();
for (int i = 0; i < 5; i++) {
- Assert.assertEquals(variance.evaluate(matrix.getColumn(i)), covarianceMatrix.getEntry(i,i), 10E-14);
+ Assert.assertEquals(org.apache.commons.statistics.descriptive.Variance.of(matrix.getColumn(i)).getAsDouble(),
+ covarianceMatrix.getEntry(i,i), 10E-14);
}
// Symmetry, column-consistency
@@ -220,7 +219,7 @@ public void testConsistency() {
repeatedColumns.setColumnMatrix(i, matrix.getColumnMatrix(0));
}
RealMatrix repeatedCovarianceMatrix = new Covariance(repeatedColumns).getCovarianceMatrix();
- double columnVariance = variance.evaluate(matrix.getColumn(0));
+ double columnVariance = org.apache.commons.statistics.descriptive.Variance.of(matrix.getColumn(0)).getAsDouble();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
Assert.assertEquals(columnVariance, repeatedCovarianceMatrix.getEntry(i, j), 10E-14);
diff --git a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/descriptive/AggregateSummaryStatisticsTest.java b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/descriptive/AggregateSummaryStatisticsTest.java
index ce640751e9..4e971947ff 100644
--- a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/descriptive/AggregateSummaryStatisticsTest.java
+++ b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/descriptive/AggregateSummaryStatisticsTest.java
@@ -117,9 +117,23 @@ public void testAggregationConsistency() {
* Note that guaranteed success of this comparison depends on the
* fact that
- The stat package includes a framework and default implementations for
- the following Descriptive statistics:
-
-
+ Univariate statistics are now available in the
+
+ Commons Statistics component in the commons-statistics-descriptive module.
+ The Commons Statistics API supports Java streams for double, int
+ and long values and computation on corresponding data types for
+ arrays and array ranges. Integer type specialisations are used where possible
+ for increased accuracy and performance over using double values.
- With the exception of percentiles and the median, all of these - statistics can be computed without maintaining the full list of input - data values in memory. The stat package provides interfaces and + Many implementations found in previous versions of Commons Math have been removed + as their functionality is entirely superceded by Commons Statistics. + The summary statistic functionality in Commons Math now + uses Commons Statistics to compute the results. + The statistics framework is maintained to support the remaining functionality in + Commons Math described in the following sections. +
++ The stat package provides framework interfaces for implementations that do not require value storage as well as implementations that operate on arrays of stored values.
@@ -63,7 +66,7 @@ The top level interface is UnivariateStatistic. - This interface, implemented by all statistics, consists of + This interface consists ofevaluate() methods that take double[] arrays as arguments
and return the value of the statistic. This interface is extended by
@@ -81,12 +84,10 @@
AbstractStorelessUnivariateStatistic respectively.
- Each statistic is implemented as a separate class, in one of the + Statistic implementations are provided as a separate class, in one of the subpackages (moment, rank, summary) and each extends one of the abstract classes above (depending on whether or not value storage is required to - compute the statistic). There are several ways to instantiate and use statistics. - Statistics can be instantiated and used directly, but it is generally more convenient - (and efficient) to access them using the provided aggregates, + compute the statistic). Computation of multiple statistics is performed by DescriptiveStatistics and @@ -112,10 +113,16 @@ sum, sum of squares, standard deviation, variance, percentiles, skewness, kurtosis, median
+ Both DescriptiveStatistics and SummaryStatistics allow
+ the implementation for the statistic to be changed. This requires an instance
+ of either UnivariateStatistic or StorelessUnivariateStatistic
+ respectively.
+