diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 50686f29d..5097032a7 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -51,6 +51,10 @@ If the output is not quite correct, check for invisible trailing spaces! + + AbstractUnivariateStatistic.test(double[] values, int begin, int length, boolean allowEmpty) + has uses outside subclasses; implementation moved to MathArrays. + The "KalmanFilter" wrongly enforced a column dimension of 1 for the provided control and measurement noise matrix. diff --git a/src/main/java/org/apache/commons/math3/stat/descriptive/AbstractUnivariateStatistic.java b/src/main/java/org/apache/commons/math3/stat/descriptive/AbstractUnivariateStatistic.java index 646696847..07b2db5d2 100644 --- a/src/main/java/org/apache/commons/math3/stat/descriptive/AbstractUnivariateStatistic.java +++ b/src/main/java/org/apache/commons/math3/stat/descriptive/AbstractUnivariateStatistic.java @@ -22,6 +22,7 @@ import org.apache.commons.math3.exception.NullArgumentException; import org.apache.commons.math3.exception.NumberIsTooLargeException; import org.apache.commons.math3.exception.MathIllegalArgumentException; import org.apache.commons.math3.exception.util.LocalizedFormats; +import org.apache.commons.math3.util.MathArrays; /** * Abstract base class for all implementations of the @@ -151,12 +152,14 @@ public abstract class AbstractUnivariateStatistic * @param length the number of elements to include * @return true if the parameters are valid and designate a subarray of positive length * @throws MathIllegalArgumentException if the indices are invalid or the array is null + * @deprecated 3.3 Use {@link MathArrays#test(double[], int, int)} instead */ + @Deprecated protected boolean test( final double[] values, final int begin, final int length) throws MathIllegalArgumentException { - return test(values, begin, length, false); + return MathArrays.test(values, begin, length, false); } /** @@ -179,33 +182,12 @@ public abstract class AbstractUnivariateStatistic * @return true if the parameters are valid * @throws MathIllegalArgumentException if the indices are invalid or the array is null * @since 3.0 + * @deprecated 3.3 Use {@link MathArrays#test(double[], int, int, boolean)} instead */ + @Deprecated protected boolean test(final double[] values, final int begin, final int length, final boolean allowEmpty) throws MathIllegalArgumentException { - - if (values == null) { - throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); - } - - if (begin < 0) { - throw new NotPositiveException(LocalizedFormats.START_POSITION, begin); - } - - if (length < 0) { - throw new NotPositiveException(LocalizedFormats.LENGTH, length); - } - - if (begin + length > values.length) { - throw new NumberIsTooLargeException(LocalizedFormats.SUBARRAY_ENDS_AFTER_ARRAY_END, - begin + length, values.length, true); - } - - if (length == 0 && !allowEmpty) { - return false; - } - - return true; - + return MathArrays.test(values, begin, length, allowEmpty); } /** @@ -236,13 +218,15 @@ public abstract class AbstractUnivariateStatistic * @return true if the parameters are valid and designate a subarray of positive length * @throws MathIllegalArgumentException if the indices are invalid or the array is null * @since 2.1 + * @deprecated 3.3 Use {@link MathArrays#test(double[], double[], int, int)} instead */ + @Deprecated protected boolean test( final double[] values, final double[] weights, final int begin, final int length) throws MathIllegalArgumentException { - return test(values, weights, begin, length, false); + return MathArrays.test(values, weights, begin, length, false); } /** @@ -277,39 +261,13 @@ public abstract class AbstractUnivariateStatistic * the weights array contains NaN, infinite or negative elements, or there * are no positive weights. * @since 3.0 + * @deprecated 3.3 Use {@link MathArrays#test(double[], double[], int, int, boolean)} instead */ + @Deprecated protected boolean test(final double[] values, final double[] weights, final int begin, final int length, final boolean allowEmpty) throws MathIllegalArgumentException { - if (weights == null || values == null) { - throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); - } - - if (weights.length != values.length) { - throw new DimensionMismatchException(weights.length, values.length); - } - - boolean containsPositiveWeight = false; - for (int i = begin; i < begin + length; i++) { - if (Double.isNaN(weights[i])) { - throw new MathIllegalArgumentException(LocalizedFormats.NAN_ELEMENT_AT_INDEX, i); - } - if (Double.isInfinite(weights[i])) { - throw new MathIllegalArgumentException(LocalizedFormats.INFINITE_ARRAY_ELEMENT, weights[i], i); - } - if (weights[i] < 0) { - throw new MathIllegalArgumentException(LocalizedFormats.NEGATIVE_ELEMENT_AT_INDEX, i, weights[i]); - } - if (!containsPositiveWeight && weights[i] > 0.0) { - containsPositiveWeight = true; - } - } - - if (!containsPositiveWeight) { - throw new MathIllegalArgumentException(LocalizedFormats.WEIGHT_AT_LEAST_ONE_NON_ZERO); - } - - return test(values, begin, length, allowEmpty); + return MathArrays.test(values, weights, begin, length, allowEmpty); } } diff --git a/src/main/java/org/apache/commons/math3/util/MathArrays.java b/src/main/java/org/apache/commons/math3/util/MathArrays.java index 61fdbea78..3cd70a621 100644 --- a/src/main/java/org/apache/commons/math3/util/MathArrays.java +++ b/src/main/java/org/apache/commons/math3/util/MathArrays.java @@ -37,6 +37,7 @@ import org.apache.commons.math3.exception.NonMonotonicSequenceException; import org.apache.commons.math3.exception.NotPositiveException; import org.apache.commons.math3.exception.NotStrictlyPositiveException; import org.apache.commons.math3.exception.NullArgumentException; +import org.apache.commons.math3.exception.NumberIsTooLargeException; import org.apache.commons.math3.exception.util.LocalizedFormats; /** @@ -1547,4 +1548,184 @@ public class MathArrays { } return a; } + /** + * This method is used + * 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 + * @return true if the parameters are valid and designate a subarray of positive length + * @throws MathIllegalArgumentException if the indices are invalid or the array is null + * @since 3.3 + */ + public static boolean test( + final double[] values, + final int begin, + final int length) throws MathIllegalArgumentException { + return test(values, begin, length, false); + } + + /** + * This method is used + * to verify that the input parameters designate a subarray of positive length. + *

+ *

    + *
  • returns true iff the parameters designate a subarray of + * non-negative length
  • + *
  • throws IllegalArgumentException if the array is null or + * or the indices are invalid
  • + *
  • returns false
  • if the array is non-null, but + * length is 0 unless allowEmpty is true + *

+ * + * @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 MathIllegalArgumentException if the indices are invalid or the array is null + * @since 3.3 + */ + public static boolean test(final double[] values, final int begin, + final int length, final boolean allowEmpty) throws MathIllegalArgumentException { + + if (values == 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)); + } + + if (begin + length > values.length) { + throw new NumberIsTooLargeException(LocalizedFormats.SUBARRAY_ENDS_AFTER_ARRAY_END, + Integer.valueOf(begin + length), Integer.valueOf(values.length), true); + } + + if (length == 0 && !allowEmpty) { + return false; + } + + return true; + + } + + /** + * This method is used + * 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. + *

+ *

    + *
  • returns true iff the parameters designate a subarray of + * positive length and the weights array contains legitimate values.
  • + *
  • throws IllegalArgumentException if any of the following are true: + *
    • the values array is null
    • + *
    • the weights array is null
    • + *
    • the weights array does not have the same length as the values array
    • + *
    • the weights array contains one or more infinite values
    • + *
    • the weights array contains one or more NaN values
    • + *
    • the weights array contains negative values
    • + *
    • the start and length arguments do not determine a valid array
    + *
  • + *
  • returns false
  • if the array is non-null, but + * length is 0. + *

+ * + * @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 true if the parameters are valid and designate a subarray of positive length + * @throws MathIllegalArgumentException if the indices are invalid or the array is null + * @since 3.3 + */ + public static boolean test( + final double[] values, + final double[] weights, + final int begin, + final int length) throws MathIllegalArgumentException { + return test(values, weights, begin, length, false); + } + + /** + * This method is used + * 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. + *

+ *

    + *
  • returns true iff the parameters designate a subarray of + * non-negative length and the weights array contains legitimate values.
  • + *
  • throws MathIllegalArgumentException if any of the following are true: + *
    • the values array is null
    • + *
    • the weights array is null
    • + *
    • the weights array does not have the same length as the values array
    • + *
    • the weights array contains one or more infinite values
    • + *
    • the weights array contains one or more NaN values
    • + *
    • the weights array contains negative values
    • + *
    • the start and length arguments do not determine a valid array
    + *
  • + *
  • returns false
  • if the array is non-null, but + * length is 0 unless allowEmpty is 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. + * @param allowEmpty if {@code true} than allow zero length arrays to pass. + * @return {@code true} if the parameters are valid. + * @throws NullArgumentException if either of the arrays are null + * @throws MathIllegalArgumentException if the array indices are not valid, + * the weights array contains NaN, infinite or negative elements, or there + * are no positive weights. + * @since 3.3 + */ + public static boolean test(final double[] values, final double[] weights, + final int begin, final int length, final boolean allowEmpty) throws MathIllegalArgumentException { + + if (weights == null || values == null) { + throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); + } + + if (weights.length != values.length) { + throw new DimensionMismatchException(weights.length, values.length); + } + + boolean containsPositiveWeight = false; + for (int i = begin; i < begin + length; i++) { + final double weight = weights[i]; + if (Double.isNaN(weight)) { + throw new MathIllegalArgumentException(LocalizedFormats.NAN_ELEMENT_AT_INDEX, Integer.valueOf(i)); + } + if (Double.isInfinite(weight)) { + throw new MathIllegalArgumentException(LocalizedFormats.INFINITE_ARRAY_ELEMENT, Double.valueOf(weight), Integer.valueOf(i)); + } + if (weight < 0) { + throw new MathIllegalArgumentException(LocalizedFormats.NEGATIVE_ELEMENT_AT_INDEX, Integer.valueOf(i), Double.valueOf(weight)); + } + if (!containsPositiveWeight && weight > 0.0) { + containsPositiveWeight = true; + } + } + + if (!containsPositiveWeight) { + throw new MathIllegalArgumentException(LocalizedFormats.WEIGHT_AT_LEAST_ONE_NON_ZERO); + } + + return test(values, begin, length, allowEmpty); + } }