allow zero length vectors
JIRA: MATH-391 git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/branches/MATH_2_X@1003993 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6793b921a0
commit
1b9e8dd09f
|
@ -79,8 +79,15 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a vector from an array, copying the input array.
|
* Construct a vector from an array, copying the input array.
|
||||||
|
* <p>
|
||||||
|
* This constructor need a non-empty {@code d} array to retrieve
|
||||||
|
* the field from its first element. This implies it cannot build
|
||||||
|
* 0 length vectors. To build vectors from any size, one should
|
||||||
|
* use the {@link #ArrayFieldVector(Field, FieldElement[])} constructor.
|
||||||
|
* </p>
|
||||||
* @param d array of Ts.
|
* @param d array of Ts.
|
||||||
* @throws IllegalArgumentException if <code>d</code> is empty
|
* @throws IllegalArgumentException if <code>d</code> is empty
|
||||||
|
* @see #ArrayFieldVector(Field, FieldElement[])
|
||||||
*/
|
*/
|
||||||
public ArrayFieldVector(T[] d)
|
public ArrayFieldVector(T[] d)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
@ -93,6 +100,17 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a vector from an array, copying the input array.
|
||||||
|
* @param field field to which the elements belong
|
||||||
|
* @param d array of Ts.
|
||||||
|
* @see #ArrayFieldVector(FieldElement[])
|
||||||
|
*/
|
||||||
|
public ArrayFieldVector(Field<T> field, T[] d) {
|
||||||
|
this.field = field;
|
||||||
|
data = d.clone();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new ArrayFieldVector using the input array as the underlying
|
* Create a new ArrayFieldVector using the input array as the underlying
|
||||||
* data array.
|
* data array.
|
||||||
|
@ -100,22 +118,46 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
|
||||||
* ArrayFieldVector and not used directly, the <code>copyArray</code> may be
|
* ArrayFieldVector and not used directly, the <code>copyArray</code> may be
|
||||||
* set to <code>false</code. This will prevent the copying and improve
|
* set to <code>false</code. This will prevent the copying and improve
|
||||||
* performance as no new array will be built and no data will be copied.</p>
|
* performance as no new array will be built and no data will be copied.</p>
|
||||||
|
* <p>
|
||||||
|
* This constructor need a non-empty {@code d} array to retrieve
|
||||||
|
* the field from its first element. This implies it cannot build
|
||||||
|
* 0 length vectors. To build vectors from any size, one should
|
||||||
|
* use the {@link #ArrayFieldVector(Field, FieldElement[], boolean)} constructor.
|
||||||
|
* </p>
|
||||||
* @param d data for new vector
|
* @param d data for new vector
|
||||||
* @param copyArray if true, the input array will be copied, otherwise
|
* @param copyArray if true, the input array will be copied, otherwise
|
||||||
* it will be referenced
|
* it will be referenced
|
||||||
* @throws IllegalArgumentException if <code>d</code> is empty
|
* @throws IllegalArgumentException if <code>d</code> is empty
|
||||||
* @throws NullPointerException if <code>d</code> is null
|
* @throws NullPointerException if <code>d</code> is null
|
||||||
* @see #ArrayFieldVector(FieldElement[])
|
* @see #ArrayFieldVector(FieldElement[])
|
||||||
|
* @see #ArrayFieldVector(Field, FieldElement[], boolean)
|
||||||
*/
|
*/
|
||||||
public ArrayFieldVector(T[] d, boolean copyArray)
|
public ArrayFieldVector(T[] d, boolean copyArray)
|
||||||
throws NullPointerException, IllegalArgumentException {
|
throws NullPointerException, IllegalArgumentException {
|
||||||
try {
|
if (d.length == 0) {
|
||||||
field = d[0].getField();
|
|
||||||
data = copyArray ? d.clone() : d;
|
|
||||||
} catch (ArrayIndexOutOfBoundsException e) {
|
|
||||||
throw MathRuntimeException.createIllegalArgumentException(
|
throw MathRuntimeException.createIllegalArgumentException(
|
||||||
LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
|
LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
|
||||||
}
|
}
|
||||||
|
field = d[0].getField();
|
||||||
|
data = copyArray ? d.clone() : d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ArrayFieldVector using the input array as the underlying
|
||||||
|
* data array.
|
||||||
|
* <p>If an array is built specially in order to be embedded in a
|
||||||
|
* ArrayFieldVector and not used directly, the <code>copyArray</code> may be
|
||||||
|
* set to <code>false</code. This will prevent the copying and improve
|
||||||
|
* performance as no new array will be built and no data will be copied.</p>
|
||||||
|
* @param field field to which the elements belong
|
||||||
|
* @param d data for new vector
|
||||||
|
* @param copyArray if true, the input array will be copied, otherwise
|
||||||
|
* it will be referenced
|
||||||
|
* @see #ArrayFieldVector(FieldElement[], boolean)
|
||||||
|
*/
|
||||||
|
public ArrayFieldVector(Field<T> field, T[] d, boolean copyArray) {
|
||||||
|
this.field = field;
|
||||||
|
data = copyArray ? d.clone() : d;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -204,9 +246,16 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a vector by appending one vector to another vector.
|
* Construct a vector by appending one vector to another vector.
|
||||||
|
* <p>
|
||||||
|
* This constructor need at least one non-empty array to retrieve
|
||||||
|
* the field from its first element. This implies it cannot build
|
||||||
|
* 0 length vectors. To build vectors from any size, one should
|
||||||
|
* use the {@link #ArrayFieldVector(Field, FieldElement[], FieldElement[])} constructor.
|
||||||
|
* </p>
|
||||||
* @param v1 first vector (will be put in front of the new vector)
|
* @param v1 first vector (will be put in front of the new vector)
|
||||||
* @param v2 second vector (will be put at back of the new vector)
|
* @param v2 second vector (will be put at back of the new vector)
|
||||||
* @exception IllegalArgumentException if both vectors are empty
|
* @exception IllegalArgumentException if both vectors are empty
|
||||||
|
* @see #ArrayFieldVector(Field, FieldElement[], FieldElement[])
|
||||||
*/
|
*/
|
||||||
public ArrayFieldVector(T[] v1, T[] v2) {
|
public ArrayFieldVector(T[] v1, T[] v2) {
|
||||||
try {
|
try {
|
||||||
|
@ -220,6 +269,24 @@ public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a vector by appending one vector to another vector.
|
||||||
|
* @param field field to which the elements belong
|
||||||
|
* @param v1 first vector (will be put in front of the new vector)
|
||||||
|
* @param v2 second vector (will be put at back of the new vector)
|
||||||
|
* @see #ArrayFieldVector(FieldElement[], FieldElement[])
|
||||||
|
*/
|
||||||
|
public ArrayFieldVector(Field<T> field, T[] v1, T[] v2) {
|
||||||
|
if (v1.length + v2.length == 0) {
|
||||||
|
throw MathRuntimeException.createIllegalArgumentException(
|
||||||
|
LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
|
||||||
|
}
|
||||||
|
data = buildArray(v1.length + v2.length);
|
||||||
|
System.arraycopy(v1, 0, data, 0, v1.length);
|
||||||
|
System.arraycopy(v2, 0, data, v1.length, v2.length);
|
||||||
|
this.field = data[0].getField();
|
||||||
|
}
|
||||||
|
|
||||||
/** Build an array of elements.
|
/** Build an array of elements.
|
||||||
* @param length size of the array to build
|
* @param length size of the array to build
|
||||||
* @return a new array
|
* @return a new array
|
||||||
|
|
|
@ -91,18 +91,9 @@ public class ArrayRealVector extends AbstractRealVector implements Serializable
|
||||||
* @param d data for new vector
|
* @param d data for new vector
|
||||||
* @param copyArray if true, the input array will be copied, otherwise
|
* @param copyArray if true, the input array will be copied, otherwise
|
||||||
* it will be referenced
|
* it will be referenced
|
||||||
* @throws IllegalArgumentException if <code>d</code> is empty
|
|
||||||
* @throws NullPointerException if <code>d</code> is null
|
|
||||||
* @see #ArrayRealVector(double[])
|
* @see #ArrayRealVector(double[])
|
||||||
*/
|
*/
|
||||||
public ArrayRealVector(double[] d, boolean copyArray)
|
public ArrayRealVector(double[] d, boolean copyArray) {
|
||||||
throws NullPointerException, IllegalArgumentException {
|
|
||||||
if (d == null) {
|
|
||||||
throw new NullPointerException();
|
|
||||||
}
|
|
||||||
if (d.length == 0) {
|
|
||||||
throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
|
|
||||||
}
|
|
||||||
data = copyArray ? d.clone() : d;
|
data = copyArray ? d.clone() : d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,9 @@ The <action> type attribute can be add,update,fix,remove.
|
||||||
If the output is not quite correct, check for invisible trailing spaces!
|
If the output is not quite correct, check for invisible trailing spaces!
|
||||||
-->
|
-->
|
||||||
<release version="2.2" date="TBD" description="TBD">
|
<release version="2.2" date="TBD" description="TBD">
|
||||||
|
<action dev="luc" type="fix" issue="MATH-391">
|
||||||
|
Fixed an error preventing zero length vectors to be built by some constructors
|
||||||
|
</action>
|
||||||
<action dev="luc" type="fix" issue="MATH-421">
|
<action dev="luc" type="fix" issue="MATH-421">
|
||||||
Fixed an error preventing ODE solvers to be restarted after they have been stopped by a discrete event
|
Fixed an error preventing ODE solvers to be restarted after they have been stopped by a discrete event
|
||||||
</action>
|
</action>
|
||||||
|
|
|
@ -590,6 +590,35 @@ public class ArrayFieldVectorTest extends TestCase {
|
||||||
assertEquals(v,TestUtils.serializeAndRecover(v));
|
assertEquals(v,TestUtils.serializeAndRecover(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testZeroVectors() {
|
||||||
|
|
||||||
|
// when the field is not specified, array cannot be empty
|
||||||
|
try {
|
||||||
|
new ArrayFieldVector<Fraction>(new Fraction[0]);
|
||||||
|
fail("IllegalArgumentException expected");
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
// expected behavior
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
new ArrayFieldVector<Fraction>(new Fraction[0], true);
|
||||||
|
fail("IllegalArgumentException expected");
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
// expected behavior
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
new ArrayFieldVector<Fraction>(new Fraction[0], false);
|
||||||
|
fail("IllegalArgumentException expected");
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
// expected behavior
|
||||||
|
}
|
||||||
|
|
||||||
|
// when the field is specified, array can be empty
|
||||||
|
assertEquals(0, new ArrayFieldVector<Fraction>(FractionField.getInstance(), new Fraction[0]).getDimension());
|
||||||
|
assertEquals(0, new ArrayFieldVector<Fraction>(FractionField.getInstance(), new Fraction[0], true).getDimension());
|
||||||
|
assertEquals(0, new ArrayFieldVector<Fraction>(FractionField.getInstance(), new Fraction[0], false).getDimension());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/** verifies that two vectors are equals */
|
/** verifies that two vectors are equals */
|
||||||
protected void checkArray(String msg, Fraction[] m, Fraction[] n) {
|
protected void checkArray(String msg, Fraction[] m, Fraction[] n) {
|
||||||
if (m.length != n.length) {
|
if (m.length != n.length) {
|
||||||
|
|
|
@ -24,6 +24,8 @@ import junit.framework.TestCase;
|
||||||
import org.apache.commons.math.FunctionEvaluationException;
|
import org.apache.commons.math.FunctionEvaluationException;
|
||||||
import org.apache.commons.math.TestUtils;
|
import org.apache.commons.math.TestUtils;
|
||||||
import org.apache.commons.math.analysis.UnivariateRealFunction;
|
import org.apache.commons.math.analysis.UnivariateRealFunction;
|
||||||
|
import org.apache.commons.math.fraction.Fraction;
|
||||||
|
import org.apache.commons.math.fraction.FractionField;
|
||||||
import org.apache.commons.math.util.FastMath;
|
import org.apache.commons.math.util.FastMath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -607,20 +609,6 @@ public class ArrayRealVectorTest extends TestCase {
|
||||||
assertEquals("testData is 9.0 ", 9.0, v14.getEntry(2));
|
assertEquals("testData is 9.0 ", 9.0, v14.getEntry(2));
|
||||||
assertEquals("testData is 1.0 ", 1.0, v14.getEntry(3));
|
assertEquals("testData is 1.0 ", 1.0, v14.getEntry(3));
|
||||||
|
|
||||||
try {
|
|
||||||
new ArrayRealVector((double[]) null, false);
|
|
||||||
fail("expected exception");
|
|
||||||
} catch (NullPointerException npe) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
new ArrayRealVector(new double[0], false);
|
|
||||||
fail("expected exception");
|
|
||||||
} catch (IllegalArgumentException iae) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDataInOut() {
|
public void testDataInOut() {
|
||||||
|
@ -1280,6 +1268,11 @@ public class ArrayRealVectorTest extends TestCase {
|
||||||
assertEquals(v,TestUtils.serializeAndRecover(v));
|
assertEquals(v,TestUtils.serializeAndRecover(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testZeroVectors() {
|
||||||
|
assertEquals(0, new ArrayRealVector(new double[0]).getDimension());
|
||||||
|
assertEquals(0, new ArrayRealVector(new double[0], true).getDimension());
|
||||||
|
assertEquals(0, new ArrayRealVector(new double[0], false).getDimension());
|
||||||
|
}
|
||||||
|
|
||||||
public void testMinMax() {
|
public void testMinMax() {
|
||||||
ArrayRealVector v1 = new ArrayRealVector(new double[] { 0, -6, 4, 12, 7 });
|
ArrayRealVector v1 = new ArrayRealVector(new double[] { 0, -6, 4, 12, 7 });
|
||||||
|
|
Loading…
Reference in New Issue