From cb5e94419fd43756bd2abda1e9a25ebde7e8a6c9 Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Mon, 11 Mar 2013 17:00:41 +0000 Subject: [PATCH] Improved checking of null vector elements. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The suggestions by Sébastien have been added and the second implementation of FieldVector (SparseFieldVector) has been adapted accordingly, despite it is deprecated. JIRA: MATH-861 git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1455233 13f79535-47bb-0310-9956-ffa450edef68 --- src/changes/changes.xml | 3 + .../math3/linear/ArrayFieldVector.java | 70 ++++++------------- .../commons/math3/linear/FieldVector.java | 7 ++ .../math3/linear/SparseFieldVector.java | 24 +++++-- 4 files changed, 50 insertions(+), 54 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 08474dd78..a0e254985 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -55,6 +55,9 @@ This is a minor release: It combines bug fixes and new features. Changes to existing features were made in a backwards-compatible way such as to allow drop-in replacement of the v3.1[.1] JAR file. "> + + Improved checking of null vector elements. + Added utilities for prime numbers. diff --git a/src/main/java/org/apache/commons/math3/linear/ArrayFieldVector.java b/src/main/java/org/apache/commons/math3/linear/ArrayFieldVector.java index 64c75e535..5592ba6fa 100644 --- a/src/main/java/org/apache/commons/math3/linear/ArrayFieldVector.java +++ b/src/main/java/org/apache/commons/math3/linear/ArrayFieldVector.java @@ -30,6 +30,7 @@ import org.apache.commons.math3.exception.OutOfRangeException; import org.apache.commons.math3.exception.ZeroException; import org.apache.commons.math3.exception.util.LocalizedFormats; import org.apache.commons.math3.util.MathArrays; +import org.apache.commons.math3.util.MathUtils; /** * This class implements the {@link FieldVector} interface with a {@link FieldElement} array. @@ -97,9 +98,7 @@ public class ArrayFieldVector> implements FieldVector< */ public ArrayFieldVector(T[] d) throws NullArgumentException, ZeroException { - if (d == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(d); try { field = d[0].getField(); data = d.clone(); @@ -118,9 +117,7 @@ public class ArrayFieldVector> implements FieldVector< */ public ArrayFieldVector(Field field, T[] d) throws NullArgumentException { - if (d == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(d); this.field = field; data = d.clone(); } @@ -148,9 +145,7 @@ public class ArrayFieldVector> implements FieldVector< */ public ArrayFieldVector(T[] d, boolean copyArray) throws NullArgumentException, ZeroException { - if (d == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(d); if (d.length == 0) { throw new ZeroException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT); } @@ -175,9 +170,7 @@ public class ArrayFieldVector> implements FieldVector< */ public ArrayFieldVector(Field field, T[] d, boolean copyArray) throws NullArgumentException { - if (d == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(d); this.field = field; data = copyArray ? d.clone() : d; } @@ -194,9 +187,7 @@ public class ArrayFieldVector> implements FieldVector< */ public ArrayFieldVector(T[] d, int pos, int size) throws NullArgumentException, NumberIsTooLargeException { - if (d == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(d); if (d.length < pos + size) { throw new NumberIsTooLargeException(pos + size, d.length, true); } @@ -218,9 +209,7 @@ public class ArrayFieldVector> implements FieldVector< */ public ArrayFieldVector(Field field, T[] d, int pos, int size) throws NullArgumentException, NumberIsTooLargeException { - if (d == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(d); if (d.length < pos + size) { throw new NumberIsTooLargeException(pos + size, d.length, true); } @@ -237,9 +226,7 @@ public class ArrayFieldVector> implements FieldVector< */ public ArrayFieldVector(FieldVector v) throws NullArgumentException { - if (v == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(v); field = v.getField(); data = MathArrays.buildArray(field, v.getDimension()); for (int i = 0; i < data.length; ++i) { @@ -255,9 +242,7 @@ public class ArrayFieldVector> implements FieldVector< */ public ArrayFieldVector(ArrayFieldVector v) throws NullArgumentException { - if (v == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(v); field = v.getField(); data = v.data.clone(); } @@ -272,9 +257,7 @@ public class ArrayFieldVector> implements FieldVector< */ public ArrayFieldVector(ArrayFieldVector v, boolean deep) throws NullArgumentException { - if (v == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(v); field = v.getField(); data = deep ? v.data.clone() : v.data; } @@ -289,9 +272,8 @@ public class ArrayFieldVector> implements FieldVector< */ public ArrayFieldVector(ArrayFieldVector v1, ArrayFieldVector v2) throws NullArgumentException { - if (v1 == null || v2 == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(v1); + MathUtils.checkNotNull(v2); field = v1.getField(); data = MathArrays.buildArray(field, v1.data.length + v2.data.length); System.arraycopy(v1.data, 0, data, 0, v1.data.length); @@ -308,9 +290,8 @@ public class ArrayFieldVector> implements FieldVector< */ public ArrayFieldVector(ArrayFieldVector v1, T[] v2) throws NullArgumentException { - if (v1 == null || v2 == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(v1); + MathUtils.checkNotNull(v2); field = v1.getField(); data = MathArrays.buildArray(field, v1.data.length + v2.length); System.arraycopy(v1.data, 0, data, 0, v1.data.length); @@ -327,9 +308,8 @@ public class ArrayFieldVector> implements FieldVector< */ public ArrayFieldVector(T[] v1, ArrayFieldVector v2) throws NullArgumentException { - if (v1 == null || v2 == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(v1); + MathUtils.checkNotNull(v2); field = v2.getField(); data = MathArrays.buildArray(field, v1.length + v2.data.length); System.arraycopy(v1, 0, data, 0, v1.length); @@ -353,9 +333,8 @@ public class ArrayFieldVector> implements FieldVector< */ public ArrayFieldVector(T[] v1, T[] v2) throws NullArgumentException, ZeroException { - if (v1 == null || v2 == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(v1); + MathUtils.checkNotNull(v2); if (v1.length + v2.length == 0) { throw new ZeroException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT); } @@ -378,9 +357,8 @@ public class ArrayFieldVector> implements FieldVector< */ public ArrayFieldVector(Field field, T[] v1, T[] v2) throws NullArgumentException, ZeroException { - if (v1 == null || v2 == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(v1); + MathUtils.checkNotNull(v2); if (v1.length + v2.length == 0) { throw new ZeroException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT); } @@ -518,9 +496,7 @@ public class ArrayFieldVector> implements FieldVector< /** {@inheritDoc} */ public FieldVector mapDivide(T d) throws NullArgumentException, MathArithmeticException { - if (d == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(d); T[] out = MathArrays.buildArray(field, data.length); for (int i = 0; i < data.length; i++) { out[i] = data[i].divide(d); @@ -531,9 +507,7 @@ public class ArrayFieldVector> implements FieldVector< /** {@inheritDoc} */ public FieldVector mapDivideToSelf(T d) throws NullArgumentException, MathArithmeticException { - if (d == null) { - throw new NullArgumentException(); - } + MathUtils.checkNotNull(d); for (int i = 0; i < data.length; i++) { data[i] = data[i].divide(d); } diff --git a/src/main/java/org/apache/commons/math3/linear/FieldVector.java b/src/main/java/org/apache/commons/math3/linear/FieldVector.java index 428629ee4..b2f060aa6 100644 --- a/src/main/java/org/apache/commons/math3/linear/FieldVector.java +++ b/src/main/java/org/apache/commons/math3/linear/FieldVector.java @@ -43,6 +43,13 @@ import org.apache.commons.math3.exception.OutOfRangeException; *
  *   RealVector result = v.mapAddToSelf(3.0).mapTanToSelf().mapSquareToSelf();
  * 
+ *

+ * Note that as almost all operations on {@link FieldElement} throw {@link + * NullArgumentException} when operating on a null element, it is the responsibility + * of FieldVector implementations to make sure no null elements + * are inserted into the vector. This must be done in all constructors and + * all setters. + *

* * @param the type of the field elements * @version $Id$ diff --git a/src/main/java/org/apache/commons/math3/linear/SparseFieldVector.java b/src/main/java/org/apache/commons/math3/linear/SparseFieldVector.java index 1f5d6e74d..9468a5ec0 100644 --- a/src/main/java/org/apache/commons/math3/linear/SparseFieldVector.java +++ b/src/main/java/org/apache/commons/math3/linear/SparseFieldVector.java @@ -27,6 +27,7 @@ import org.apache.commons.math3.exception.NullArgumentException; import org.apache.commons.math3.exception.OutOfRangeException; import org.apache.commons.math3.exception.util.LocalizedFormats; import org.apache.commons.math3.util.MathArrays; +import org.apache.commons.math3.util.MathUtils; import org.apache.commons.math3.util.OpenIntToFieldHashMap; /** @@ -109,8 +110,10 @@ public class SparseFieldVector> implements FieldVector * * @param field Field to which the elements belong. * @param values Set of values to create from. + * @exception NullArgumentException if values is null */ - public SparseFieldVector(Field field, T[] values) { + public SparseFieldVector(Field field, T[] values) throws NullArgumentException { + MathUtils.checkNotNull(values); this.field = field; virtualSize = values.length; entries = new OpenIntToFieldHashMap(field); @@ -197,8 +200,11 @@ public class SparseFieldVector> implements FieldVector } } - /** {@inheritDoc} */ - public FieldVector append(T d) { + /** {@inheritDoc} + * @exception NullArgumentException if d is null + */ + public FieldVector append(T d) throws NullArgumentException { + MathUtils.checkNotNull(d); FieldVector res = new SparseFieldVector(this, 1); res.setEntry(virtualSize, d); return res; @@ -409,15 +415,21 @@ public class SparseFieldVector> implements FieldVector return v.mapMultiply(dotProduct(v).divide(v.dotProduct(v))); } - /** {@inheritDoc} */ + /** {@inheritDoc} + * @exception NullArgumentException if value is null + */ public void set(T value) { + MathUtils.checkNotNull(value); for (int i = 0; i < virtualSize; i++) { setEntry(i, value); } } - /** {@inheritDoc} */ - public void setEntry(int index, T value) throws OutOfRangeException { + /** {@inheritDoc} + * @exception NullArgumentException if value is null + */ + public void setEntry(int index, T value) throws NullArgumentException, OutOfRangeException { + MathUtils.checkNotNull(value); checkIndex(index); entries.put(index, value); }