You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2010/10/03 18:39:17 UTC

svn commit: r1003993 - in /commons/proper/math/branches/MATH_2_X/src: main/java/org/apache/commons/math/linear/ site/xdoc/ test/java/org/apache/commons/math/linear/

Author: luc
Date: Sun Oct  3 16:39:16 2010
New Revision: 1003993

URL: http://svn.apache.org/viewvc?rev=1003993&view=rev
Log:
allow zero length vectors
JIRA: MATH-391

Modified:
    commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/linear/ArrayFieldVector.java
    commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/linear/ArrayRealVector.java
    commons/proper/math/branches/MATH_2_X/src/site/xdoc/changes.xml
    commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/linear/ArrayFieldVectorTest.java
    commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java

Modified: commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/linear/ArrayFieldVector.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/linear/ArrayFieldVector.java?rev=1003993&r1=1003992&r2=1003993&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/linear/ArrayFieldVector.java (original)
+++ commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/linear/ArrayFieldVector.java Sun Oct  3 16:39:16 2010
@@ -79,8 +79,15 @@ public class ArrayFieldVector<T extends 
 
     /**
      * 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.
      * @throws IllegalArgumentException if <code>d</code> is empty
+     * @see #ArrayFieldVector(Field, FieldElement[])
      */
     public ArrayFieldVector(T[] d)
         throws IllegalArgumentException {
@@ -94,28 +101,63 @@ public class ArrayFieldVector<T extends 
     }
 
     /**
+     * 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
      * 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>
+     * <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 copyArray if true, the input array will be copied, otherwise
      * it will be referenced
      * @throws IllegalArgumentException if <code>d</code> is empty
      * @throws NullPointerException if <code>d</code> is null
      * @see #ArrayFieldVector(FieldElement[])
+     * @see #ArrayFieldVector(Field, FieldElement[], boolean)
      */
     public ArrayFieldVector(T[] d, boolean copyArray)
         throws NullPointerException, IllegalArgumentException {
-        try {
-            field = d[0].getField();
-            data = copyArray ? d.clone() :  d;
-        } catch (ArrayIndexOutOfBoundsException e) {
+        if (d.length == 0) {
             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 
 
     /**
      * 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 v2 second vector (will be put at back of the new vector)
      * @exception IllegalArgumentException if both vectors are empty
+     * @see #ArrayFieldVector(Field, FieldElement[], FieldElement[])
      */
     public ArrayFieldVector(T[] v1, T[] v2) {
         try {
@@ -220,6 +269,24 @@ public class ArrayFieldVector<T extends 
         }
     }
 
+    /**
+     * 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.
      * @param length size of the array to build
      * @return a new array

Modified: commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/linear/ArrayRealVector.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/linear/ArrayRealVector.java?rev=1003993&r1=1003992&r2=1003993&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/linear/ArrayRealVector.java (original)
+++ commons/proper/math/branches/MATH_2_X/src/main/java/org/apache/commons/math/linear/ArrayRealVector.java Sun Oct  3 16:39:16 2010
@@ -91,18 +91,9 @@ public class ArrayRealVector extends Abs
      * @param d data for new vector
      * @param copyArray if true, the input array will be copied, otherwise
      * it will be referenced
-     * @throws IllegalArgumentException if <code>d</code> is empty
-     * @throws NullPointerException if <code>d</code> is null
      * @see #ArrayRealVector(double[])
      */
-    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);
-        }
+    public ArrayRealVector(double[] d, boolean copyArray) {
         data = copyArray ? d.clone() :  d;
     }
 

Modified: commons/proper/math/branches/MATH_2_X/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_X/src/site/xdoc/changes.xml?rev=1003993&r1=1003992&r2=1003993&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_X/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/branches/MATH_2_X/src/site/xdoc/changes.xml Sun Oct  3 16:39:16 2010
@@ -52,6 +52,9 @@ The <action> type attribute can be add,u
     If the output is not quite correct, check for invisible trailing spaces!
      -->
     <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">
         Fixed an error preventing ODE solvers to be restarted after they have been stopped by a discrete event
       </action>

Modified: commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/linear/ArrayFieldVectorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/linear/ArrayFieldVectorTest.java?rev=1003993&r1=1003992&r2=1003993&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/linear/ArrayFieldVectorTest.java (original)
+++ commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/linear/ArrayFieldVectorTest.java Sun Oct  3 16:39:16 2010
@@ -590,6 +590,35 @@ public class ArrayFieldVectorTest extend
         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 */
     protected void checkArray(String msg, Fraction[] m, Fraction[] n) {
         if (m.length != n.length) {

Modified: commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java?rev=1003993&r1=1003992&r2=1003993&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java (original)
+++ commons/proper/math/branches/MATH_2_X/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java Sun Oct  3 16:39:16 2010
@@ -24,6 +24,8 @@ import junit.framework.TestCase;
 import org.apache.commons.math.FunctionEvaluationException;
 import org.apache.commons.math.TestUtils;
 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;
 
 /**
@@ -607,20 +609,6 @@ public class ArrayRealVectorTest extends
         assertEquals("testData is 9.0 ", 9.0, v14.getEntry(2));
         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() {
@@ -1280,6 +1268,11 @@ public class ArrayRealVectorTest extends
         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()  {
         ArrayRealVector v1 = new ArrayRealVector(new double[] { 0, -6, 4, 12, 7 });