Improved checking of null vector elements.

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
This commit is contained in:
Luc Maisonobe 2013-03-11 17:00:41 +00:00
parent 6f3165670c
commit cb5e94419f
4 changed files with 50 additions and 54 deletions

View File

@ -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 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. way such as to allow drop-in replacement of the v3.1[.1] JAR file.
"> ">
<action dev="luc" type="fix" issue="MATH-861" due-to="Sébastien Brisard" >
Improved checking of null vector elements.
</action>
<action dev="luc" type="add" issue="MATH-845" due-to="Sébastien Riou" > <action dev="luc" type="add" issue="MATH-845" due-to="Sébastien Riou" >
Added utilities for prime numbers. Added utilities for prime numbers.
</action> </action>

View File

@ -30,6 +30,7 @@ import org.apache.commons.math3.exception.OutOfRangeException;
import org.apache.commons.math3.exception.ZeroException; import org.apache.commons.math3.exception.ZeroException;
import org.apache.commons.math3.exception.util.LocalizedFormats; import org.apache.commons.math3.exception.util.LocalizedFormats;
import org.apache.commons.math3.util.MathArrays; 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. * This class implements the {@link FieldVector} interface with a {@link FieldElement} array.
@ -97,9 +98,7 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
*/ */
public ArrayFieldVector(T[] d) public ArrayFieldVector(T[] d)
throws NullArgumentException, ZeroException { throws NullArgumentException, ZeroException {
if (d == null) { MathUtils.checkNotNull(d);
throw new NullArgumentException();
}
try { try {
field = d[0].getField(); field = d[0].getField();
data = d.clone(); data = d.clone();
@ -118,9 +117,7 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
*/ */
public ArrayFieldVector(Field<T> field, T[] d) public ArrayFieldVector(Field<T> field, T[] d)
throws NullArgumentException { throws NullArgumentException {
if (d == null) { MathUtils.checkNotNull(d);
throw new NullArgumentException();
}
this.field = field; this.field = field;
data = d.clone(); data = d.clone();
} }
@ -148,9 +145,7 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
*/ */
public ArrayFieldVector(T[] d, boolean copyArray) public ArrayFieldVector(T[] d, boolean copyArray)
throws NullArgumentException, ZeroException { throws NullArgumentException, ZeroException {
if (d == null) { MathUtils.checkNotNull(d);
throw new NullArgumentException();
}
if (d.length == 0) { if (d.length == 0) {
throw new ZeroException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT); throw new ZeroException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
} }
@ -175,9 +170,7 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
*/ */
public ArrayFieldVector(Field<T> field, T[] d, boolean copyArray) public ArrayFieldVector(Field<T> field, T[] d, boolean copyArray)
throws NullArgumentException { throws NullArgumentException {
if (d == null) { MathUtils.checkNotNull(d);
throw new NullArgumentException();
}
this.field = field; this.field = field;
data = copyArray ? d.clone() : d; data = copyArray ? d.clone() : d;
} }
@ -194,9 +187,7 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
*/ */
public ArrayFieldVector(T[] d, int pos, int size) public ArrayFieldVector(T[] d, int pos, int size)
throws NullArgumentException, NumberIsTooLargeException { throws NullArgumentException, NumberIsTooLargeException {
if (d == null) { MathUtils.checkNotNull(d);
throw new NullArgumentException();
}
if (d.length < pos + size) { if (d.length < pos + size) {
throw new NumberIsTooLargeException(pos + size, d.length, true); throw new NumberIsTooLargeException(pos + size, d.length, true);
} }
@ -218,9 +209,7 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
*/ */
public ArrayFieldVector(Field<T> field, T[] d, int pos, int size) public ArrayFieldVector(Field<T> field, T[] d, int pos, int size)
throws NullArgumentException, NumberIsTooLargeException { throws NullArgumentException, NumberIsTooLargeException {
if (d == null) { MathUtils.checkNotNull(d);
throw new NullArgumentException();
}
if (d.length < pos + size) { if (d.length < pos + size) {
throw new NumberIsTooLargeException(pos + size, d.length, true); throw new NumberIsTooLargeException(pos + size, d.length, true);
} }
@ -237,9 +226,7 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
*/ */
public ArrayFieldVector(FieldVector<T> v) public ArrayFieldVector(FieldVector<T> v)
throws NullArgumentException { throws NullArgumentException {
if (v == null) { MathUtils.checkNotNull(v);
throw new NullArgumentException();
}
field = v.getField(); field = v.getField();
data = MathArrays.buildArray(field, v.getDimension()); data = MathArrays.buildArray(field, v.getDimension());
for (int i = 0; i < data.length; ++i) { for (int i = 0; i < data.length; ++i) {
@ -255,9 +242,7 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
*/ */
public ArrayFieldVector(ArrayFieldVector<T> v) public ArrayFieldVector(ArrayFieldVector<T> v)
throws NullArgumentException { throws NullArgumentException {
if (v == null) { MathUtils.checkNotNull(v);
throw new NullArgumentException();
}
field = v.getField(); field = v.getField();
data = v.data.clone(); data = v.data.clone();
} }
@ -272,9 +257,7 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
*/ */
public ArrayFieldVector(ArrayFieldVector<T> v, boolean deep) public ArrayFieldVector(ArrayFieldVector<T> v, boolean deep)
throws NullArgumentException { throws NullArgumentException {
if (v == null) { MathUtils.checkNotNull(v);
throw new NullArgumentException();
}
field = v.getField(); field = v.getField();
data = deep ? v.data.clone() : v.data; data = deep ? v.data.clone() : v.data;
} }
@ -289,9 +272,8 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
*/ */
public ArrayFieldVector(ArrayFieldVector<T> v1, ArrayFieldVector<T> v2) public ArrayFieldVector(ArrayFieldVector<T> v1, ArrayFieldVector<T> v2)
throws NullArgumentException { throws NullArgumentException {
if (v1 == null || v2 == null) { MathUtils.checkNotNull(v1);
throw new NullArgumentException(); MathUtils.checkNotNull(v2);
}
field = v1.getField(); field = v1.getField();
data = MathArrays.buildArray(field, v1.data.length + v2.data.length); data = MathArrays.buildArray(field, v1.data.length + v2.data.length);
System.arraycopy(v1.data, 0, data, 0, v1.data.length); System.arraycopy(v1.data, 0, data, 0, v1.data.length);
@ -308,9 +290,8 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
*/ */
public ArrayFieldVector(ArrayFieldVector<T> v1, T[] v2) public ArrayFieldVector(ArrayFieldVector<T> v1, T[] v2)
throws NullArgumentException { throws NullArgumentException {
if (v1 == null || v2 == null) { MathUtils.checkNotNull(v1);
throw new NullArgumentException(); MathUtils.checkNotNull(v2);
}
field = v1.getField(); field = v1.getField();
data = MathArrays.buildArray(field, v1.data.length + v2.length); data = MathArrays.buildArray(field, v1.data.length + v2.length);
System.arraycopy(v1.data, 0, data, 0, v1.data.length); System.arraycopy(v1.data, 0, data, 0, v1.data.length);
@ -327,9 +308,8 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
*/ */
public ArrayFieldVector(T[] v1, ArrayFieldVector<T> v2) public ArrayFieldVector(T[] v1, ArrayFieldVector<T> v2)
throws NullArgumentException { throws NullArgumentException {
if (v1 == null || v2 == null) { MathUtils.checkNotNull(v1);
throw new NullArgumentException(); MathUtils.checkNotNull(v2);
}
field = v2.getField(); field = v2.getField();
data = MathArrays.buildArray(field, v1.length + v2.data.length); data = MathArrays.buildArray(field, v1.length + v2.data.length);
System.arraycopy(v1, 0, data, 0, v1.length); System.arraycopy(v1, 0, data, 0, v1.length);
@ -353,9 +333,8 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
*/ */
public ArrayFieldVector(T[] v1, T[] v2) public ArrayFieldVector(T[] v1, T[] v2)
throws NullArgumentException, ZeroException { throws NullArgumentException, ZeroException {
if (v1 == null || v2 == null) { MathUtils.checkNotNull(v1);
throw new NullArgumentException(); MathUtils.checkNotNull(v2);
}
if (v1.length + v2.length == 0) { if (v1.length + v2.length == 0) {
throw new ZeroException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT); throw new ZeroException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
} }
@ -378,9 +357,8 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
*/ */
public ArrayFieldVector(Field<T> field, T[] v1, T[] v2) public ArrayFieldVector(Field<T> field, T[] v1, T[] v2)
throws NullArgumentException, ZeroException { throws NullArgumentException, ZeroException {
if (v1 == null || v2 == null) { MathUtils.checkNotNull(v1);
throw new NullArgumentException(); MathUtils.checkNotNull(v2);
}
if (v1.length + v2.length == 0) { if (v1.length + v2.length == 0) {
throw new ZeroException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT); throw new ZeroException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
} }
@ -518,9 +496,7 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
/** {@inheritDoc} */ /** {@inheritDoc} */
public FieldVector<T> mapDivide(T d) public FieldVector<T> mapDivide(T d)
throws NullArgumentException, MathArithmeticException { throws NullArgumentException, MathArithmeticException {
if (d == null) { MathUtils.checkNotNull(d);
throw new NullArgumentException();
}
T[] out = MathArrays.buildArray(field, data.length); T[] out = MathArrays.buildArray(field, data.length);
for (int i = 0; i < data.length; i++) { for (int i = 0; i < data.length; i++) {
out[i] = data[i].divide(d); out[i] = data[i].divide(d);
@ -531,9 +507,7 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
/** {@inheritDoc} */ /** {@inheritDoc} */
public FieldVector<T> mapDivideToSelf(T d) public FieldVector<T> mapDivideToSelf(T d)
throws NullArgumentException, MathArithmeticException { throws NullArgumentException, MathArithmeticException {
if (d == null) { MathUtils.checkNotNull(d);
throw new NullArgumentException();
}
for (int i = 0; i < data.length; i++) { for (int i = 0; i < data.length; i++) {
data[i] = data[i].divide(d); data[i] = data[i].divide(d);
} }

View File

@ -43,6 +43,13 @@ import org.apache.commons.math3.exception.OutOfRangeException;
* <pre> * <pre>
* RealVector result = v.mapAddToSelf(3.0).mapTanToSelf().mapSquareToSelf(); * RealVector result = v.mapAddToSelf(3.0).mapTanToSelf().mapSquareToSelf();
* </pre> * </pre>
* <p>
* Note that as almost all operations on {@link FieldElement} throw {@link
* NullArgumentException} when operating on a null element, it is the responsibility
* of <code>FieldVector</code> implementations to make sure no null elements
* are inserted into the vector. This must be done in all constructors and
* all setters.
* <p>
* *
* @param <T> the type of the field elements * @param <T> the type of the field elements
* @version $Id$ * @version $Id$

View File

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