diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatistic.java b/src/main/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatistic.java index ddfaa44ad..72db02639 100644 --- a/src/main/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatistic.java +++ b/src/main/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatistic.java @@ -79,29 +79,54 @@ public abstract class AbstractUnivariateStatistic final double[] values, final int begin, final int length) { + return test(values, begin, length, false); + } + + /** + * This method is used by evaluate(double[], int, int) methods + * to verify that the input parameters designate a subarray of positive length. + *

+ *

+ * + * @param values the input array + * @param begin index of the first array element to include + * @param length the number of elements to include + * @param allowEmpty if true then zero length arrays are allowed + * @return true if the parameters are valid + * @throws IllegalArgumentException if the indices are invalid or the array is null + * @since 3.0 + */ + protected boolean test(final double[] values, final int begin, final int length, final boolean allowEmpty){ - if (values == null) { - throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); - } + if (values == null) { + throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); + } - if (begin < 0) { - throw new NotPositiveException(LocalizedFormats.START_POSITION, begin); - } + if (begin < 0) { + throw new NotPositiveException(LocalizedFormats.START_POSITION, begin); + } - if (length < 0) { - throw new NotPositiveException(LocalizedFormats.LENGTH, length); - } + if (length < 0) { + throw new NotPositiveException(LocalizedFormats.LENGTH, length); + } - if (begin + length > values.length) { - throw MathRuntimeException.createIllegalArgumentException( - LocalizedFormats.SUBARRAY_ENDS_AFTER_ARRAY_END); - } + if (begin + length > values.length) { + throw MathRuntimeException.createIllegalArgumentException( + LocalizedFormats.SUBARRAY_ENDS_AFTER_ARRAY_END); + } - if (length == 0) { - return false; - } + if (length == 0 && !allowEmpty) { + return false; + } - return true; + return true; } @@ -139,6 +164,40 @@ public abstract class AbstractUnivariateStatistic final double[] weights, final int begin, final int length) { + return test(values, weights, begin, length, false); + } + + /** + * This method is used by evaluate(double[], double[], int, int) methods + * to verify that the begin and length parameters designate a subarray of positive length + * and the weights are all non-negative, non-NaN, finite, and not all zero. + *

+ *

+ * + * @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 + * @param allowEmpty if true than allow zero length arrays to pass + * @return true if the parameters are valid + * @throws IllegalArgumentException if the indices are invalid or the array is null + * @since 3.0 + */ + protected boolean test(final double[] values, final double[] weights, final int begin, final int length, final boolean allowEmpty){ if (weights == null) { throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); @@ -172,7 +231,7 @@ public abstract class AbstractUnivariateStatistic LocalizedFormats.WEIGHT_AT_LEAST_ONE_NON_ZERO); } - return test(values, begin, length); + return test(values, begin, length, allowEmpty); } } diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/summary/Product.java b/src/main/java/org/apache/commons/math/stat/descriptive/summary/Product.java index da6e3809d..f9796b458 100644 --- a/src/main/java/org/apache/commons/math/stat/descriptive/summary/Product.java +++ b/src/main/java/org/apache/commons/math/stat/descriptive/summary/Product.java @@ -25,7 +25,8 @@ import org.apache.commons.math.util.FastMath; /** * Returns the product of the available values. *

- * If there are no values in the dataset, or any of the values are + * If there are no values in the dataset, then 1 is returned. + * If any of the values are * NaN, then NaN is returned.

*

* Note that this implementation is not synchronized. If @@ -53,7 +54,7 @@ public class Product extends AbstractStorelessUnivariateStatistic implements Ser */ public Product() { n = 0; - value = Double.NaN; + value = 1; } /** @@ -71,11 +72,7 @@ public class Product extends AbstractStorelessUnivariateStatistic implements Ser */ @Override public void increment(final double d) { - if (n == 0) { - value = d; - } else { - value *= d; - } + value *= d; n++; } @@ -99,7 +96,7 @@ public class Product extends AbstractStorelessUnivariateStatistic implements Ser */ @Override public void clear() { - value = Double.NaN; + value = 1; n = 0; } @@ -113,14 +110,14 @@ public class Product extends AbstractStorelessUnivariateStatistic implements Ser * @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 product of the values or Double.NaN if length = 0 + * @return the product of the values or 1 if length = 0 * @throws IllegalArgumentException 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) { double product = Double.NaN; - if (test(values, begin, length)) { + if (test(values, begin, length, true)) { product = 1.0; for (int i = begin; i < begin + length; i++) { product *= values[i]; @@ -153,14 +150,14 @@ public class Product extends AbstractStorelessUnivariateStatistic implements Ser * @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 product of the values or Double.NaN if length = 0 + * @return the product of the values or 1 if length = 0 * @throws IllegalArgumentException if the parameters are not valid * @since 2.1 */ public double evaluate(final double[] values, final double[] weights, final int begin, final int length) { double product = Double.NaN; - if (test(values, weights, begin, length)) { + if (test(values, weights, begin, length, true)) { product = 1.0; for (int i = begin; i < begin + length; i++) { product *= FastMath.pow(values[i], weights[i]); diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/summary/Sum.java b/src/main/java/org/apache/commons/math/stat/descriptive/summary/Sum.java index 2b0fd9b75..3543575de 100644 --- a/src/main/java/org/apache/commons/math/stat/descriptive/summary/Sum.java +++ b/src/main/java/org/apache/commons/math/stat/descriptive/summary/Sum.java @@ -24,7 +24,8 @@ import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStati /** * Returns the sum of the available values. *

- * If there are no values in the dataset, or any of the values are + * 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 @@ -52,7 +53,7 @@ public class Sum extends AbstractStorelessUnivariateStatistic implements Seriali */ public Sum() { n = 0; - value = Double.NaN; + value = 0; } /** @@ -70,11 +71,7 @@ public class Sum extends AbstractStorelessUnivariateStatistic implements Seriali */ @Override public void increment(final double d) { - if (n == 0) { - value = d; - } else { - value += d; - } + value += d; n++; } @@ -98,13 +95,13 @@ public class Sum extends AbstractStorelessUnivariateStatistic implements Seriali */ @Override public void clear() { - value = Double.NaN; + value = 0; n = 0; } /** * The sum of the entries in the specified portion of - * the input array, or Double.NaN if the designated subarray + * the input array, or 0 if the designated subarray * is empty. *

* Throws IllegalArgumentException if the array is null.

@@ -112,14 +109,14 @@ public class Sum extends AbstractStorelessUnivariateStatistic implements Seriali * @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 values or Double.NaN if length = 0 + * @return the sum of the values or 0 if length = 0 * @throws IllegalArgumentException 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) { double sum = Double.NaN; - if (test(values, begin, length)) { + if (test(values, begin, length, true)) { sum = 0.0; for (int i = begin; i < begin + length; i++) { sum += values[i]; @@ -130,7 +127,7 @@ public class Sum extends AbstractStorelessUnivariateStatistic implements Seriali /** * The weighted sum of the entries in the specified portion of - * the input array, or Double.NaN if the designated subarray + * the input array, or 0 if the designated subarray * is empty. *

* Throws IllegalArgumentException if any of the following are true: @@ -151,14 +148,14 @@ public class Sum extends AbstractStorelessUnivariateStatistic implements Seriali * @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 sum of the values or Double.NaN if length = 0 + * @return the sum of the values or 0 if length = 0 * @throws IllegalArgumentException if the parameters are not valid * @since 2.1 */ public double evaluate(final double[] values, final double[] weights, final int begin, final int length) { double sum = Double.NaN; - if (test(values, weights, begin, length)) { + if (test(values, weights, begin, length, true)) { sum = 0.0; for (int i = begin; i < begin + length; i++) { sum += values[i] * weights[i]; diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/summary/SumOfLogs.java b/src/main/java/org/apache/commons/math/stat/descriptive/summary/SumOfLogs.java index b4280cc82..24960e3d4 100644 --- a/src/main/java/org/apache/commons/math/stat/descriptive/summary/SumOfLogs.java +++ b/src/main/java/org/apache/commons/math/stat/descriptive/summary/SumOfLogs.java @@ -24,7 +24,7 @@ import org.apache.commons.math.util.FastMath; /** * Returns the sum of the natural logs for this collection of values. *

- * Uses {@link java.lang.Math#log(double)} to compute the logs. Therefore, + * Uses {@link org.apache.commons.Math.util.FastMath#log(double)} to compute the logs. Therefore, *