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.
+ *
+ *
true
iff the parameters designate a subarray of
+ * non-negative lengthIllegalArgumentException
if the array is null or
+ * or the indices are invalidfalse
length
is 0 unless allowEmpty
is true
+ * 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.
+ * + *
true
iff the parameters designate a subarray of
+ * non-negative length and the weights array contains legitimate values.IllegalArgumentException
if any of the following are true:
+ * false
length
is 0 unless allowEmpty
is true
.
+ * 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.
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, *
NaN.
- * 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 @@ -51,7 +52,7 @@ public class SumOfSquares extends AbstractStorelessUnivariateStatistic implement */ public SumOfSquares() { n = 0; - value = Double.NaN; + value = 0; } /** @@ -69,11 +70,7 @@ public class SumOfSquares extends AbstractStorelessUnivariateStatistic implement */ @Override public void increment(final double d) { - if (n == 0) { - value = d * d; - } else { - value += d * d; - } + value += d * d; n++; } @@ -97,7 +94,7 @@ public class SumOfSquares extends AbstractStorelessUnivariateStatistic implement */ @Override public void clear() { - value = Double.NaN; + value = 0; n = 0; } @@ -111,14 +108,14 @@ public class SumOfSquares extends AbstractStorelessUnivariateStatistic implement * @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 squares of the values or Double.NaN if length = 0 + * @return the sum of the squares 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 sumSq = Double.NaN; - if (test(values, begin, length)) { + if (test(values, begin, length, true)) { sumSq = 0.0; for (int i = begin; i < begin + length; i++) { sumSq += values[i] * values[i]; diff --git a/src/test/java/org/apache/commons/math/stat/StatUtilsTest.java b/src/test/java/org/apache/commons/math/stat/StatUtilsTest.java index 68bb42971..1a2d19101 100644 --- a/src/test/java/org/apache/commons/math/stat/StatUtilsTest.java +++ b/src/test/java/org/apache/commons/math/stat/StatUtilsTest.java @@ -131,8 +131,8 @@ public final class StatUtilsTest extends TestCase { // test empty x = new double[] {}; - TestUtils.assertEquals(Double.NaN, StatUtils.sumSq(x), tolerance); - TestUtils.assertEquals(Double.NaN, StatUtils.sumSq(x, 0, 0), tolerance); + TestUtils.assertEquals(0, StatUtils.sumSq(x), tolerance); + TestUtils.assertEquals(0, StatUtils.sumSq(x, 0, 0), tolerance); // test one x = new double[] {two}; @@ -165,8 +165,8 @@ public final class StatUtilsTest extends TestCase { // test empty x = new double[] {}; - TestUtils.assertEquals(Double.NaN, StatUtils.product(x), tolerance); - TestUtils.assertEquals(Double.NaN, StatUtils.product(x, 0, 0), tolerance); + TestUtils.assertEquals(1, StatUtils.product(x), tolerance); + TestUtils.assertEquals(1, StatUtils.product(x, 0, 0), tolerance); // test one x = new double[] {two}; @@ -199,8 +199,8 @@ public final class StatUtilsTest extends TestCase { // test empty x = new double[] {}; - TestUtils.assertEquals(Double.NaN, StatUtils.sumLog(x), tolerance); - TestUtils.assertEquals(Double.NaN, StatUtils.sumLog(x, 0, 0), tolerance); + TestUtils.assertEquals(0, StatUtils.sumLog(x), tolerance); + TestUtils.assertEquals(0, StatUtils.sumLog(x, 0, 0), tolerance); // test one x = new double[] {two}; diff --git a/src/test/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatisticTest.java b/src/test/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatisticTest.java index bac615f1d..373e69fe9 100644 --- a/src/test/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatisticTest.java +++ b/src/test/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatisticTest.java @@ -45,6 +45,7 @@ public class AbstractUnivariateStatisticTest extends TestCase { } } assertTrue(testStatistic.test(singletonArray, 0, 1)); + assertTrue(testStatistic.test(singletonArray, 0, 0, true)); } public void testTestNegative() { diff --git a/src/test/java/org/apache/commons/math/stat/descriptive/StorelessUnivariateStatisticAbstractTest.java b/src/test/java/org/apache/commons/math/stat/descriptive/StorelessUnivariateStatisticAbstractTest.java index dd37e12cb..5785e344e 100644 --- a/src/test/java/org/apache/commons/math/stat/descriptive/StorelessUnivariateStatisticAbstractTest.java +++ b/src/test/java/org/apache/commons/math/stat/descriptive/StorelessUnivariateStatisticAbstractTest.java @@ -68,11 +68,15 @@ public abstract class StorelessUnivariateStatisticAbstractTest statistic.clear(); // Cleared - assertTrue(Double.isNaN(statistic.getResult())); + checkClearValue(statistic); assertEquals(0, statistic.getN()); } + protected void checkClearValue(StorelessUnivariateStatistic statistic){ + assertTrue(Double.isNaN(statistic.getResult())); + } + public void testSerialization() throws Exception { StorelessUnivariateStatistic statistic = @@ -94,7 +98,7 @@ public abstract class StorelessUnivariateStatisticAbstractTest statistic.clear(); - assertTrue(Double.isNaN(statistic.getResult())); + checkClearValue(statistic); } diff --git a/src/test/java/org/apache/commons/math/stat/descriptive/summary/ProductTest.java b/src/test/java/org/apache/commons/math/stat/descriptive/summary/ProductTest.java index 7ddf5e6f9..0f85d556d 100644 --- a/src/test/java/org/apache/commons/math/stat/descriptive/summary/ProductTest.java +++ b/src/test/java/org/apache/commons/math/stat/descriptive/summary/ProductTest.java @@ -16,6 +16,7 @@ */ package org.apache.commons.math.stat.descriptive.summary; +import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; @@ -65,7 +66,7 @@ public class ProductTest extends StorelessUnivariateStatisticAbstractTest{ public void testSpecialValues() { Product product = new Product(); - assertTrue(Double.isNaN(product.getResult())); + assertEquals(1, product.getResult(), 0); product.increment(1); assertEquals(1, product.getResult(), 0); product.increment(Double.POSITIVE_INFINITY); @@ -83,5 +84,10 @@ public class ProductTest extends StorelessUnivariateStatisticAbstractTest{ assertEquals(expectedWeightedValue(), product.evaluate(testArray, testWeightsArray, 0, testArray.length),getTolerance()); assertEquals(expectedValue(), product.evaluate(testArray, unitWeightsArray, 0, testArray.length), getTolerance()); } + + protected void checkClearValue(StorelessUnivariateStatistic statistic){ + assertEquals(1, statistic.getResult(), 0); + } + } diff --git a/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumLogTest.java b/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumLogTest.java index f8f2314f8..d822e955f 100644 --- a/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumLogTest.java +++ b/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumLogTest.java @@ -16,6 +16,7 @@ */ package org.apache.commons.math.stat.descriptive.summary; +import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; @@ -53,7 +54,7 @@ public class SumLogTest extends StorelessUnivariateStatisticAbstractTest{ public void testSpecialValues() { SumOfLogs sum = new SumOfLogs(); // empty - assertTrue(Double.isNaN(sum.getResult())); + assertEquals(0, sum.getResult(), 0); // finite data sum.increment(1d); @@ -69,7 +70,7 @@ public class SumLogTest extends StorelessUnivariateStatisticAbstractTest{ // clear sum.clear(); - assertTrue(Double.isNaN(sum.getResult())); + assertEquals(0, sum.getResult(), 0); // positive infinity by itself sum.increment(Double.POSITIVE_INFINITY); @@ -79,5 +80,10 @@ public class SumLogTest extends StorelessUnivariateStatisticAbstractTest{ sum.increment(-2d); assertTrue(Double.isNaN(sum.getResult())); } + + protected void checkClearValue(StorelessUnivariateStatistic statistic){ + assertEquals(0, statistic.getResult(), 0); + } + } diff --git a/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumSqTest.java b/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumSqTest.java index 87d5c2727..727ca5db7 100644 --- a/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumSqTest.java +++ b/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumSqTest.java @@ -16,6 +16,7 @@ */ package org.apache.commons.math.stat.descriptive.summary; +import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; @@ -53,7 +54,7 @@ public class SumSqTest extends StorelessUnivariateStatisticAbstractTest{ public void testSpecialValues() { SumOfSquares sumSq = new SumOfSquares(); - assertTrue(Double.isNaN(sumSq.getResult())); + assertEquals(0, sumSq.getResult(), 0); sumSq.increment(2d); assertEquals(4d, sumSq.getResult(), 0); sumSq.increment(Double.POSITIVE_INFINITY); @@ -65,5 +66,10 @@ public class SumSqTest extends StorelessUnivariateStatisticAbstractTest{ sumSq.increment(1); assertTrue(Double.isNaN(sumSq.getResult())); } + + protected void checkClearValue(StorelessUnivariateStatistic statistic){ + assertEquals(0, statistic.getResult(), 0); + } + } diff --git a/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumTest.java b/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumTest.java index 6af90d394..18a425215 100644 --- a/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumTest.java +++ b/src/test/java/org/apache/commons/math/stat/descriptive/summary/SumTest.java @@ -16,6 +16,7 @@ */ package org.apache.commons.math.stat.descriptive.summary; +import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic; import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatisticAbstractTest; import org.apache.commons.math.stat.descriptive.UnivariateStatistic; @@ -57,7 +58,7 @@ public class SumTest extends StorelessUnivariateStatisticAbstractTest{ public void testSpecialValues() { Sum sum = new Sum(); - assertTrue(Double.isNaN(sum.getResult())); + assertEquals(0, sum.getResult(), 0); sum.increment(1); assertEquals(1, sum.getResult(), 0); sum.increment(Double.POSITIVE_INFINITY); @@ -73,5 +74,10 @@ public class SumTest extends StorelessUnivariateStatisticAbstractTest{ assertEquals(expectedWeightedValue(), sum.evaluate(testArray, testWeightsArray, 0, testArray.length), getTolerance()); assertEquals(expectedValue(), sum.evaluate(testArray, unitWeightsArray, 0, testArray.length), getTolerance()); } + + protected void checkClearValue(StorelessUnivariateStatistic statistic){ + assertEquals(0, statistic.getResult(), 0); + } + }