commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From l..@apache.org
Subject svn commit: r1570536 - in /commons/proper/math/trunk/src: changes/ main/java/org/apache/commons/math3/linear/ test/java/org/apache/commons/math3/linear/
Date Fri, 21 Feb 2014 11:26:10 GMT
Author: luc
Date: Fri Feb 21 11:26:09 2014
New Revision: 1570536

URL: http://svn.apache.org/r1570536
Log:
Field vectors now implement the visitor pattern just like real vectors.

JIRA: MATH-820

Added:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/FieldVectorChangingVisitor.java   (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/FieldVectorPreservingVisitor.java   (with props)
Modified:
    commons/proper/math/trunk/src/changes/changes.xml
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/ArrayFieldVector.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SparseFieldVector.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/ArrayFieldVectorTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SparseFieldVectorTest.java

Modified: commons/proper/math/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/changes/changes.xml?rev=1570536&r1=1570535&r2=1570536&view=diff
==============================================================================
--- commons/proper/math/trunk/src/changes/changes.xml (original)
+++ commons/proper/math/trunk/src/changes/changes.xml Fri Feb 21 11:26:09 2014
@@ -51,6 +51,9 @@ If the output is not quite correct, chec
   </properties>
   <body>
     <release version="3.3" date="TBD" description="TBD">
+      <action dev="luc" type="add" issue="MATH-820">
+        Field vectors now implement the visitor pattern just like real vectors.
+      </action>
       <action dev="luc" type="fix" issue="MATH-875">
         Un-deprecated RealVector.sparseIterator, documenting explicitly that entries
         not iterated above are the zero ones.

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/ArrayFieldVector.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/ArrayFieldVector.java?rev=1570536&r1=1570535&r2=1570536&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/ArrayFieldVector.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/ArrayFieldVector.java Fri Feb 21 11:26:09 2014
@@ -26,6 +26,7 @@ import org.apache.commons.math3.exceptio
 import org.apache.commons.math3.exception.NotPositiveException;
 import org.apache.commons.math3.exception.NullArgumentException;
 import org.apache.commons.math3.exception.NumberIsTooLargeException;
+import org.apache.commons.math3.exception.NumberIsTooSmallException;
 import org.apache.commons.math3.exception.OutOfRangeException;
 import org.apache.commons.math3.exception.ZeroException;
 import org.apache.commons.math3.exception.util.LocalizedFormats;
@@ -897,6 +898,166 @@ public class ArrayFieldVector<T extends 
     }
 
     /**
+     * Visits (but does not alter) all entries of this vector in default order
+     * (increasing index).
+     *
+     * @param visitor the visitor to be used to process the entries of this
+     * vector
+     * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
+     * at the end of the walk
+     * @since 3.3
+     */
+    public T walkInDefaultOrder(final FieldVectorPreservingVisitor<T> visitor) {
+        final int dim = getDimension();
+        visitor.start(dim, 0, dim - 1);
+        for (int i = 0; i < dim; i++) {
+            visitor.visit(i, getEntry(i));
+        }
+        return visitor.end();
+    }
+
+    /**
+     * Visits (but does not alter) some entries of this vector in default order
+     * (increasing index).
+     *
+     * @param visitor visitor to be used to process the entries of this vector
+     * @param start the index of the first entry to be visited
+     * @param end the index of the last entry to be visited (inclusive)
+     * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
+     * at the end of the walk
+     * @throws NumberIsTooSmallException if {@code end < start}.
+     * @throws OutOfRangeException if the indices are not valid.
+     * @since 3.3
+     */
+    public T walkInDefaultOrder(final FieldVectorPreservingVisitor<T> visitor,
+                                final int start, final int end)
+        throws NumberIsTooSmallException, OutOfRangeException {
+        checkIndices(start, end);
+        visitor.start(getDimension(), start, end);
+        for (int i = start; i <= end; i++) {
+            visitor.visit(i, getEntry(i));
+        }
+        return visitor.end();
+    }
+
+    /**
+     * Visits (but does not alter) all entries of this vector in optimized
+     * order. The order in which the entries are visited is selected so as to
+     * lead to the most efficient implementation; it might depend on the
+     * concrete implementation of this abstract class.
+     *
+     * @param visitor the visitor to be used to process the entries of this
+     * vector
+     * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
+     * at the end of the walk
+     * @since 3.3
+     */
+    public T walkInOptimizedOrder(final FieldVectorPreservingVisitor<T> visitor) {
+        return walkInDefaultOrder(visitor);
+    }
+
+    /**
+     * Visits (but does not alter) some entries of this vector in optimized
+     * order. The order in which the entries are visited is selected so as to
+     * lead to the most efficient implementation; it might depend on the
+     * concrete implementation of this abstract class.
+     *
+     * @param visitor visitor to be used to process the entries of this vector
+     * @param start the index of the first entry to be visited
+     * @param end the index of the last entry to be visited (inclusive)
+     * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
+     * at the end of the walk
+     * @throws NumberIsTooSmallException if {@code end < start}.
+     * @throws OutOfRangeException if the indices are not valid.
+     * @since 3.3
+     */
+    public T walkInOptimizedOrder(final FieldVectorPreservingVisitor<T> visitor,
+                                  final int start, final int end)
+        throws NumberIsTooSmallException, OutOfRangeException {
+        return walkInDefaultOrder(visitor, start, end);
+    }
+
+    /**
+     * Visits (and possibly alters) all entries of this vector in default order
+     * (increasing index).
+     *
+     * @param visitor the visitor to be used to process and modify the entries
+     * of this vector
+     * @return the value returned by {@link FieldVectorChangingVisitor#end()}
+     * at the end of the walk
+     * @since 3.3
+     */
+    public T walkInDefaultOrder(final FieldVectorChangingVisitor<T> visitor) {
+        final int dim = getDimension();
+        visitor.start(dim, 0, dim - 1);
+        for (int i = 0; i < dim; i++) {
+            setEntry(i, visitor.visit(i, getEntry(i)));
+        }
+        return visitor.end();
+    }
+
+    /**
+     * Visits (and possibly alters) some entries of this vector in default order
+     * (increasing index).
+     *
+     * @param visitor visitor to be used to process the entries of this vector
+     * @param start the index of the first entry to be visited
+     * @param end the index of the last entry to be visited (inclusive)
+     * @return the value returned by {@link FieldVectorChangingVisitor#end()}
+     * at the end of the walk
+     * @throws NumberIsTooSmallException if {@code end < start}.
+     * @throws OutOfRangeException if the indices are not valid.
+     * @since 3.3
+     */
+    public T walkInDefaultOrder(final FieldVectorChangingVisitor<T> visitor,
+                                final int start, final int end)
+        throws NumberIsTooSmallException, OutOfRangeException {
+        checkIndices(start, end);
+        visitor.start(getDimension(), start, end);
+        for (int i = start; i <= end; i++) {
+            setEntry(i, visitor.visit(i, getEntry(i)));
+        }
+        return visitor.end();
+    }
+
+    /**
+     * Visits (and possibly alters) all entries of this vector in optimized
+     * order. The order in which the entries are visited is selected so as to
+     * lead to the most efficient implementation; it might depend on the
+     * concrete implementation of this abstract class.
+     *
+     * @param visitor the visitor to be used to process the entries of this
+     * vector
+     * @return the value returned by {@link FieldVectorChangingVisitor#end()}
+     * at the end of the walk
+     * @since 3.3
+     */
+    public T walkInOptimizedOrder(final FieldVectorChangingVisitor<T> visitor) {
+        return walkInDefaultOrder(visitor);
+    }
+
+    /**
+     * Visits (and possibly change) some entries of this vector in optimized
+     * order. The order in which the entries are visited is selected so as to
+     * lead to the most efficient implementation; it might depend on the
+     * concrete implementation of this abstract class.
+     *
+     * @param visitor visitor to be used to process the entries of this vector
+     * @param start the index of the first entry to be visited
+     * @param end the index of the last entry to be visited (inclusive)
+     * @return the value returned by {@link FieldVectorChangingVisitor#end()}
+     * at the end of the walk
+     * @throws NumberIsTooSmallException if {@code end < start}.
+     * @throws OutOfRangeException if the indices are not valid.
+     * @since 3.3
+     */
+    public T walkInOptimizedOrder(final FieldVectorChangingVisitor<T> visitor,
+                                  final int start, final int end)
+        throws NumberIsTooSmallException, OutOfRangeException {
+        return walkInDefaultOrder(visitor, start, end);
+    }
+
+    /**
      * Test for the equality of two vectors.
      *
      * @param other Object to test for equality.
@@ -957,4 +1118,31 @@ public class ArrayFieldVector<T extends 
                                           index, 0, getDimension() - 1);
         }
     }
+
+    /**
+     * Checks that the indices of a subvector are valid.
+     *
+     * @param start the index of the first entry of the subvector
+     * @param end the index of the last entry of the subvector (inclusive)
+     * @throws OutOfRangeException if {@code start} of {@code end} are not valid
+     * @throws NumberIsTooSmallException if {@code end < start}
+     * @since 3.3
+     */
+    private void checkIndices(final int start, final int end)
+        throws NumberIsTooSmallException, OutOfRangeException {
+        final int dim = getDimension();
+        if ((start < 0) || (start >= dim)) {
+            throw new OutOfRangeException(LocalizedFormats.INDEX, start, 0,
+                                          dim - 1);
+        }
+        if ((end < 0) || (end >= dim)) {
+            throw new OutOfRangeException(LocalizedFormats.INDEX, end, 0,
+                                          dim - 1);
+        }
+        if (end < start) {
+            throw new NumberIsTooSmallException(LocalizedFormats.INITIAL_ROW_AFTER_FINAL_ROW,
+                                                end, start, false);
+        }
+    }
+
 }

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/FieldVectorChangingVisitor.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/FieldVectorChangingVisitor.java?rev=1570536&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/FieldVectorChangingVisitor.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/FieldVectorChangingVisitor.java Fri Feb 21 11:26:09 2014
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.linear;
+
+import org.apache.commons.math3.FieldElement;
+
+/**
+ * This interface defines a visitor for the entries of a vector. Visitors
+ * implementing this interface may alter the entries of the vector being
+ * visited.
+ *
+ * @param <T> the type of the field elements
+ * @version $Id$
+ * @since 3.3
+ */
+public interface FieldVectorChangingVisitor<T extends FieldElement<?>> {
+    /**
+     * Start visiting a vector. This method is called once, before any entry
+     * of the vector is visited.
+     *
+     * @param dimension the size of the vector
+     * @param start the index of the first entry to be visited
+     * @param end the index of the last entry to be visited (inclusive)
+     */
+    void start(int dimension, int start, int end);
+
+    /**
+     * Visit one entry of the vector.
+     *
+     * @param index the index of the entry being visited
+     * @param value the value of the entry being visited
+     * @return the new value of the entry being visited
+     */
+    T visit(int index, T value);
+
+    /**
+     * End visiting a vector. This method is called once, after all entries of
+     * the vector have been visited.
+     *
+     * @return the value returned after visiting all entries
+     */
+    T end();
+}

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/FieldVectorChangingVisitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/FieldVectorChangingVisitor.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/FieldVectorPreservingVisitor.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/FieldVectorPreservingVisitor.java?rev=1570536&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/FieldVectorPreservingVisitor.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/FieldVectorPreservingVisitor.java Fri Feb 21 11:26:09 2014
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.linear;
+
+import org.apache.commons.math3.FieldElement;
+
+/**
+ * This interface defines a visitor for the entries of a vector. Visitors
+ * implementing this interface do not alter the entries of the vector being
+ * visited.
+ *
+ * @param <T> the type of the field elements
+ * @version $Id$
+ * @since 3.3
+ */
+public interface FieldVectorPreservingVisitor<T extends FieldElement<?>> {
+    /**
+     * Start visiting a vector. This method is called once, before any entry
+     * of the vector is visited.
+     *
+     * @param dimension the size of the vector
+     * @param start the index of the first entry to be visited
+     * @param end the index of the last entry to be visited (inclusive)
+     */
+    void start(int dimension, int start, int end);
+
+    /**
+     * Visit one entry of the vector.
+     *
+     * @param index the index of the entry being visited
+     * @param value the value of the entry being visited
+     */
+    void visit(int index, T value);
+
+    /**
+     * End visiting a vector. This method is called once, after all entries of
+     * the vector have been visited.
+     *
+     * @return the value returned after visiting all entries
+     */
+    T end();
+}

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/FieldVectorPreservingVisitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/FieldVectorPreservingVisitor.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SparseFieldVector.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SparseFieldVector.java?rev=1570536&r1=1570535&r2=1570536&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SparseFieldVector.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SparseFieldVector.java Fri Feb 21 11:26:09 2014
@@ -24,6 +24,7 @@ import org.apache.commons.math3.exceptio
 import org.apache.commons.math3.exception.MathArithmeticException;
 import org.apache.commons.math3.exception.NotPositiveException;
 import org.apache.commons.math3.exception.NullArgumentException;
+import org.apache.commons.math3.exception.NumberIsTooSmallException;
 import org.apache.commons.math3.exception.OutOfRangeException;
 import org.apache.commons.math3.exception.util.LocalizedFormats;
 import org.apache.commons.math3.util.MathArrays;
@@ -515,6 +516,32 @@ public class SparseFieldVector<T extends
     }
 
     /**
+     * Checks that the indices of a subvector are valid.
+     *
+     * @param start the index of the first entry of the subvector
+     * @param end the index of the last entry of the subvector (inclusive)
+     * @throws OutOfRangeException if {@code start} of {@code end} are not valid
+     * @throws NumberIsTooSmallException if {@code end < start}
+     * @since 3.3
+     */
+    private void checkIndices(final int start, final int end)
+        throws NumberIsTooSmallException, OutOfRangeException {
+        final int dim = getDimension();
+        if ((start < 0) || (start >= dim)) {
+            throw new OutOfRangeException(LocalizedFormats.INDEX, start, 0,
+                                          dim - 1);
+        }
+        if ((end < 0) || (end >= dim)) {
+            throw new OutOfRangeException(LocalizedFormats.INDEX, end, 0,
+                                          dim - 1);
+        }
+        if (end < start) {
+            throw new NumberIsTooSmallException(LocalizedFormats.INITIAL_ROW_AFTER_FINAL_ROW,
+                                                end, start, false);
+        }
+    }
+
+    /**
      * Check if instance dimension is equal to some expected value.
      *
      * @param n Expected dimension.
@@ -543,6 +570,166 @@ public class SparseFieldVector<T extends
         }
     }
 
+    /**
+     * Visits (but does not alter) all entries of this vector in default order
+     * (increasing index).
+     *
+     * @param visitor the visitor to be used to process the entries of this
+     * vector
+     * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
+     * at the end of the walk
+     * @since 3.3
+     */
+    public T walkInDefaultOrder(final FieldVectorPreservingVisitor<T> visitor) {
+        final int dim = getDimension();
+        visitor.start(dim, 0, dim - 1);
+        for (int i = 0; i < dim; i++) {
+            visitor.visit(i, getEntry(i));
+        }
+        return visitor.end();
+    }
+
+    /**
+     * Visits (but does not alter) some entries of this vector in default order
+     * (increasing index).
+     *
+     * @param visitor visitor to be used to process the entries of this vector
+     * @param start the index of the first entry to be visited
+     * @param end the index of the last entry to be visited (inclusive)
+     * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
+     * at the end of the walk
+     * @throws NumberIsTooSmallException if {@code end < start}.
+     * @throws OutOfRangeException if the indices are not valid.
+     * @since 3.3
+     */
+    public T walkInDefaultOrder(final FieldVectorPreservingVisitor<T> visitor,
+                                final int start, final int end)
+        throws NumberIsTooSmallException, OutOfRangeException {
+        checkIndices(start, end);
+        visitor.start(getDimension(), start, end);
+        for (int i = start; i <= end; i++) {
+            visitor.visit(i, getEntry(i));
+        }
+        return visitor.end();
+    }
+
+    /**
+     * Visits (but does not alter) all entries of this vector in optimized
+     * order. The order in which the entries are visited is selected so as to
+     * lead to the most efficient implementation; it might depend on the
+     * concrete implementation of this abstract class.
+     *
+     * @param visitor the visitor to be used to process the entries of this
+     * vector
+     * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
+     * at the end of the walk
+     * @since 3.3
+     */
+    public T walkInOptimizedOrder(final FieldVectorPreservingVisitor<T> visitor) {
+        return walkInDefaultOrder(visitor);
+    }
+
+    /**
+     * Visits (but does not alter) some entries of this vector in optimized
+     * order. The order in which the entries are visited is selected so as to
+     * lead to the most efficient implementation; it might depend on the
+     * concrete implementation of this abstract class.
+     *
+     * @param visitor visitor to be used to process the entries of this vector
+     * @param start the index of the first entry to be visited
+     * @param end the index of the last entry to be visited (inclusive)
+     * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
+     * at the end of the walk
+     * @throws NumberIsTooSmallException if {@code end < start}.
+     * @throws OutOfRangeException if the indices are not valid.
+     * @since 3.3
+     */
+    public T walkInOptimizedOrder(final FieldVectorPreservingVisitor<T> visitor,
+                                  final int start, final int end)
+        throws NumberIsTooSmallException, OutOfRangeException {
+        return walkInDefaultOrder(visitor, start, end);
+    }
+
+    /**
+     * Visits (and possibly alters) all entries of this vector in default order
+     * (increasing index).
+     *
+     * @param visitor the visitor to be used to process and modify the entries
+     * of this vector
+     * @return the value returned by {@link FieldVectorChangingVisitor#end()}
+     * at the end of the walk
+     * @since 3.3
+     */
+    public T walkInDefaultOrder(final FieldVectorChangingVisitor<T> visitor) {
+        final int dim = getDimension();
+        visitor.start(dim, 0, dim - 1);
+        for (int i = 0; i < dim; i++) {
+            setEntry(i, visitor.visit(i, getEntry(i)));
+        }
+        return visitor.end();
+    }
+
+    /**
+     * Visits (and possibly alters) some entries of this vector in default order
+     * (increasing index).
+     *
+     * @param visitor visitor to be used to process the entries of this vector
+     * @param start the index of the first entry to be visited
+     * @param end the index of the last entry to be visited (inclusive)
+     * @return the value returned by {@link FieldVectorChangingVisitor#end()}
+     * at the end of the walk
+     * @throws NumberIsTooSmallException if {@code end < start}.
+     * @throws OutOfRangeException if the indices are not valid.
+     * @since 3.3
+     */
+    public T walkInDefaultOrder(final FieldVectorChangingVisitor<T> visitor,
+                                final int start, final int end)
+        throws NumberIsTooSmallException, OutOfRangeException {
+        checkIndices(start, end);
+        visitor.start(getDimension(), start, end);
+        for (int i = start; i <= end; i++) {
+            setEntry(i, visitor.visit(i, getEntry(i)));
+        }
+        return visitor.end();
+    }
+
+    /**
+     * Visits (and possibly alters) all entries of this vector in optimized
+     * order. The order in which the entries are visited is selected so as to
+     * lead to the most efficient implementation; it might depend on the
+     * concrete implementation of this abstract class.
+     *
+     * @param visitor the visitor to be used to process the entries of this
+     * vector
+     * @return the value returned by {@link FieldVectorChangingVisitor#end()}
+     * at the end of the walk
+     * @since 3.3
+     */
+    public T walkInOptimizedOrder(final FieldVectorChangingVisitor<T> visitor) {
+        return walkInDefaultOrder(visitor);
+    }
+
+    /**
+     * Visits (and possibly change) some entries of this vector in optimized
+     * order. The order in which the entries are visited is selected so as to
+     * lead to the most efficient implementation; it might depend on the
+     * concrete implementation of this abstract class.
+     *
+     * @param visitor visitor to be used to process the entries of this vector
+     * @param start the index of the first entry to be visited
+     * @param end the index of the last entry to be visited (inclusive)
+     * @return the value returned by {@link FieldVectorChangingVisitor#end()}
+     * at the end of the walk
+     * @throws NumberIsTooSmallException if {@code end < start}.
+     * @throws OutOfRangeException if the indices are not valid.
+     * @since 3.3
+     */
+    public T walkInOptimizedOrder(final FieldVectorChangingVisitor<T> visitor,
+                                  final int start, final int end)
+        throws NumberIsTooSmallException, OutOfRangeException {
+        return walkInDefaultOrder(visitor, start, end);
+    }
+
     /** {@inheritDoc} */
     @Override
     public int hashCode() {

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/ArrayFieldVectorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/ArrayFieldVectorTest.java?rev=1570536&r1=1570535&r2=1570536&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/ArrayFieldVectorTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/ArrayFieldVectorTest.java Fri Feb 21 11:26:09 2014
@@ -18,11 +18,13 @@ package org.apache.commons.math3.linear;
 
 import java.io.Serializable;
 import java.lang.reflect.Array;
+import java.util.Arrays;
 
 import org.apache.commons.math3.Field;
 import org.apache.commons.math3.FieldElement;
 import org.apache.commons.math3.TestUtils;
 import org.apache.commons.math3.exception.MathIllegalArgumentException;
+import org.apache.commons.math3.exception.NumberIsTooSmallException;
 import org.apache.commons.math3.exception.OutOfRangeException;
 import org.apache.commons.math3.fraction.Fraction;
 import org.apache.commons.math3.fraction.FractionField;
@@ -48,7 +50,7 @@ public class ArrayFieldVectorTest {
     protected Fraction[] vec4 = { new Fraction(1), new Fraction(2), new Fraction(3),
                                   new Fraction(4), new Fraction(5), new Fraction(6),
                                   new Fraction(7), new Fraction(8), new Fraction(9)};
-    protected Fraction[] vec_null = {new Fraction(0), new Fraction(0), new Fraction(0)};
+    protected Fraction[] vec_null = {Fraction.ZERO, Fraction.ZERO, Fraction.ZERO};
     protected Fraction[] dvec1 = {new Fraction(1), new Fraction(2), new Fraction(3),
                                   new Fraction(4), new Fraction(5), new Fraction(6),
                                   new Fraction(7), new Fraction(8), new Fraction(9)};
@@ -262,7 +264,7 @@ public class ArrayFieldVectorTest {
 
         ArrayFieldVector<Fraction> v1 = new ArrayFieldVector<Fraction>(FractionField.getInstance(), 7);
         Assert.assertEquals(7, v1.getDimension());
-        Assert.assertEquals(new Fraction(0), v1.getEntry(6));
+        Assert.assertEquals(Fraction.ZERO, v1.getEntry(6));
 
         ArrayFieldVector<Fraction> v2 = new ArrayFieldVector<Fraction>(5, new Fraction(123, 100));
         Assert.assertEquals(5, v2.getDimension());
@@ -302,7 +304,7 @@ public class ArrayFieldVectorTest {
 
         ArrayFieldVector<Fraction> v7 = new ArrayFieldVector<Fraction>(v1);
         Assert.assertEquals(7, v7.getDimension());
-        Assert.assertEquals(new Fraction(0), v7.getEntry(6));
+        Assert.assertEquals(Fraction.ZERO, v7.getEntry(6));
 
         FieldVectorTestImpl<Fraction> v7_i = new FieldVectorTestImpl<Fraction>(vec1);
 
@@ -312,15 +314,15 @@ public class ArrayFieldVectorTest {
 
         ArrayFieldVector<Fraction> v8 = new ArrayFieldVector<Fraction>(v1, true);
         Assert.assertEquals(7, v8.getDimension());
-        Assert.assertEquals(new Fraction(0), v8.getEntry(6));
+        Assert.assertEquals(Fraction.ZERO, v8.getEntry(6));
         Assert.assertNotSame("testData not same object ", v1.getDataRef(), v8.getDataRef());
 
         ArrayFieldVector<Fraction> v8_2 = new ArrayFieldVector<Fraction>(v1, false);
         Assert.assertEquals(7, v8_2.getDimension());
-        Assert.assertEquals(new Fraction(0), v8_2.getEntry(6));
+        Assert.assertEquals(Fraction.ZERO, v8_2.getEntry(6));
         Assert.assertArrayEquals(v1.getDataRef(), v8_2.getDataRef());
 
-        ArrayFieldVector<Fraction> v9 = new ArrayFieldVector<Fraction>(v1, v3);
+        ArrayFieldVector<Fraction> v9 = new ArrayFieldVector<Fraction>((FieldVector<Fraction>) v1, (FieldVector<Fraction>) v3);
         Assert.assertEquals(10, v9.getDimension());
         Assert.assertEquals(new Fraction(1), v9.getEntry(7));
 
@@ -348,7 +350,7 @@ public class ArrayFieldVectorTest {
 
         FieldVector<Fraction> v_copy = v1.copy();
         Assert.assertEquals(3, v_copy.getDimension());
-        Assert.assertNotSame("testData not same object ", v1.getDataRef(), v_copy.getData());
+        Assert.assertNotSame("testData not same object ", v1.getDataRef(), v_copy.toArray());
 
         Fraction[] a_frac = v1.toArray();
         Assert.assertEquals(3, a_frac.length);
@@ -439,13 +441,13 @@ public class ArrayFieldVectorTest {
 
         //octave =  v1 .- 2.0
         FieldVector<Fraction> v_mapSubtract = v1.mapSubtract(new Fraction(2));
-        Fraction[] result_mapSubtract = {new Fraction(-1), new Fraction(0), new Fraction(1)};
+        Fraction[] result_mapSubtract = {new Fraction(-1), Fraction.ZERO, new Fraction(1)};
         checkArray("compare vectors" ,result_mapSubtract,v_mapSubtract.toArray());
 
         //octave =  v1 .- 2.0
         FieldVector<Fraction> v_mapSubtractToSelf = v1.copy();
         v_mapSubtractToSelf.mapSubtractToSelf(new Fraction(2));
-        Fraction[] result_mapSubtractToSelf = {new Fraction(-1), new Fraction(0), new Fraction(1)};
+        Fraction[] result_mapSubtractToSelf = {new Fraction(-1), Fraction.ZERO, new Fraction(1)};
         checkArray("compare vectors" ,result_mapSubtractToSelf,v_mapSubtractToSelf.toArray());
 
         //octave =  v1 .* 2.0
@@ -657,4 +659,539 @@ public class ArrayFieldVectorTest {
         }
     }
 
+    /*
+     * TESTS OF THE VISITOR PATTERN
+     */
+
+    /** The whole vector is visited. */
+    @Test
+    public void testWalkInDefaultOrderPreservingVisitor1() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
+        final FieldVectorPreservingVisitor<Fraction> visitor;
+        visitor = new FieldVectorPreservingVisitor<Fraction>() {
+
+            private int expectedIndex;
+
+            public void visit(final int actualIndex, final Fraction actualValue) {
+                Assert.assertEquals(expectedIndex, actualIndex);
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+                ++expectedIndex;
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(0, actualStart);
+                Assert.assertEquals(data.length - 1, actualEnd);
+                expectedIndex = 0;
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInDefaultOrder(visitor);
+    }
+
+    /** Visiting an invalid subvector. */
+    @Test
+    public void testWalkInDefaultOrderPreservingVisitor2() {
+        final ArrayFieldVector<Fraction> v = create(5);
+        final FieldVectorPreservingVisitor<Fraction> visitor;
+        visitor = new FieldVectorPreservingVisitor<Fraction>() {
+
+            public void visit(int index, Fraction value) {
+                // Do nothing
+            }
+
+            public void start(int dimension, int start, int end) {
+                // Do nothing
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        try {
+            v.walkInDefaultOrder(visitor, -1, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 5, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 0, -1);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 0, 5);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 4, 0);
+            Assert.fail();
+        } catch (NumberIsTooSmallException e) {
+            // Expected behavior
+        }
+    }
+
+    /** Visiting a valid subvector. */
+    @Test
+    public void testWalkInDefaultOrderPreservingVisitor3() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
+        final int expectedStart = 2;
+        final int expectedEnd = 7;
+        final FieldVectorPreservingVisitor<Fraction> visitor;
+        visitor = new FieldVectorPreservingVisitor<Fraction>() {
+
+            private int expectedIndex;
+
+            public void visit(final int actualIndex, final Fraction actualValue) {
+                Assert.assertEquals(expectedIndex, actualIndex);
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+                ++expectedIndex;
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(expectedStart, actualStart);
+                Assert.assertEquals(expectedEnd, actualEnd);
+                expectedIndex = expectedStart;
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInDefaultOrder(visitor, expectedStart, expectedEnd);
+    }
+
+    /** The whole vector is visited. */
+    @Test
+    public void testWalkInOptimizedOrderPreservingVisitor1() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
+        final FieldVectorPreservingVisitor<Fraction> visitor;
+        visitor = new FieldVectorPreservingVisitor<Fraction>() {
+            private final boolean[] visited = new boolean[data.length];
+
+            public void visit(final int actualIndex, final Fraction actualValue) {
+                visited[actualIndex] = true;
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(0, actualStart);
+                Assert.assertEquals(data.length - 1, actualEnd);
+                Arrays.fill(visited, false);
+            }
+
+            public Fraction end() {
+                for (int i = 0; i < data.length; i++) {
+                    Assert.assertTrue("entry " + i + "has not been visited",
+                                      visited[i]);
+                }
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInOptimizedOrder(visitor);
+    }
+
+    /** Visiting an invalid subvector. */
+    @Test
+    public void testWalkInOptimizedOrderPreservingVisitor2() {
+        final ArrayFieldVector<Fraction> v = create(5);
+        final FieldVectorPreservingVisitor<Fraction> visitor;
+        visitor = new FieldVectorPreservingVisitor<Fraction>() {
+
+            public void visit(int index, Fraction value) {
+                // Do nothing
+            }
+
+            public void start(int dimension, int start, int end) {
+                // Do nothing
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        try {
+            v.walkInOptimizedOrder(visitor, -1, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 5, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 0, -1);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 0, 5);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 4, 0);
+            Assert.fail();
+        } catch (NumberIsTooSmallException e) {
+            // Expected behavior
+        }
+    }
+
+    /** Visiting a valid subvector. */
+    @Test
+    public void testWalkInOptimizedOrderPreservingVisitor3() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
+        final int expectedStart = 2;
+        final int expectedEnd = 7;
+        final FieldVectorPreservingVisitor<Fraction> visitor;
+        visitor = new FieldVectorPreservingVisitor<Fraction>() {
+            private final boolean[] visited = new boolean[data.length];
+
+            public void visit(final int actualIndex, final Fraction actualValue) {
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+                visited[actualIndex] = true;
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(expectedStart, actualStart);
+                Assert.assertEquals(expectedEnd, actualEnd);
+                Arrays.fill(visited, true);
+            }
+
+            public Fraction end() {
+                for (int i = expectedStart; i <= expectedEnd; i++) {
+                    Assert.assertTrue("entry " + i + "has not been visited",
+                                      visited[i]);
+                }
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInOptimizedOrder(visitor, expectedStart, expectedEnd);
+    }
+
+    /** The whole vector is visited. */
+    @Test
+    public void testWalkInDefaultOrderChangingVisitor1() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
+        final FieldVectorChangingVisitor<Fraction> visitor;
+        visitor = new FieldVectorChangingVisitor<Fraction>() {
+
+            private int expectedIndex;
+
+            public Fraction visit(final int actualIndex, final Fraction actualValue) {
+                Assert.assertEquals(expectedIndex, actualIndex);
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+                ++expectedIndex;
+                return actualValue.add(actualIndex);
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(0, actualStart);
+                Assert.assertEquals(data.length - 1, actualEnd);
+                expectedIndex = 0;
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInDefaultOrder(visitor);
+        for (int i = 0; i < data.length; i++) {
+            Assert.assertEquals("entry " + i, data[i].add(i), v.getEntry(i));
+        }
+    }
+
+    /** Visiting an invalid subvector. */
+    @Test
+    public void testWalkInDefaultOrderChangingVisitor2() {
+        final ArrayFieldVector<Fraction> v = create(5);
+        final FieldVectorChangingVisitor<Fraction> visitor;
+        visitor = new FieldVectorChangingVisitor<Fraction>() {
+
+            public Fraction visit(int index, Fraction value) {
+                return Fraction.ZERO;
+            }
+
+            public void start(int dimension, int start, int end) {
+                // Do nothing
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        try {
+            v.walkInDefaultOrder(visitor, -1, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 5, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 0, -1);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 0, 5);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 4, 0);
+            Assert.fail();
+        } catch (NumberIsTooSmallException e) {
+            // Expected behavior
+        }
+    }
+
+    /** Visiting a valid subvector. */
+    @Test
+    public void testWalkInDefaultOrderChangingVisitor3() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
+        final int expectedStart = 2;
+        final int expectedEnd = 7;
+        final FieldVectorChangingVisitor<Fraction> visitor;
+        visitor = new FieldVectorChangingVisitor<Fraction>() {
+
+            private int expectedIndex;
+
+            public Fraction visit(final int actualIndex, final Fraction actualValue) {
+                Assert.assertEquals(expectedIndex, actualIndex);
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+                ++expectedIndex;
+                return actualValue.add(actualIndex);
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(expectedStart, actualStart);
+                Assert.assertEquals(expectedEnd, actualEnd);
+                expectedIndex = expectedStart;
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInDefaultOrder(visitor, expectedStart, expectedEnd);
+        for (int i = expectedStart; i <= expectedEnd; i++) {
+            Assert.assertEquals("entry " + i, data[i].add(i), v.getEntry(i));
+        }
+    }
+
+    /** The whole vector is visited. */
+    @Test
+    public void testWalkInOptimizedOrderChangingVisitor1() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
+        final FieldVectorChangingVisitor<Fraction> visitor;
+        visitor = new FieldVectorChangingVisitor<Fraction>() {
+            private final boolean[] visited = new boolean[data.length];
+
+            public Fraction visit(final int actualIndex, final Fraction actualValue) {
+                visited[actualIndex] = true;
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+                return actualValue.add(actualIndex);
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(0, actualStart);
+                Assert.assertEquals(data.length - 1, actualEnd);
+                Arrays.fill(visited, false);
+            }
+
+            public Fraction end() {
+                for (int i = 0; i < data.length; i++) {
+                    Assert.assertTrue("entry " + i + "has not been visited",
+                                      visited[i]);
+                }
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInOptimizedOrder(visitor);
+        for (int i = 0; i < data.length; i++) {
+            Assert.assertEquals("entry " + i, data[i].add(i), v.getEntry(i));
+        }
+    }
+
+    /** Visiting an invalid subvector. */
+    @Test
+    public void testWalkInOptimizedOrderChangingVisitor2() {
+        final ArrayFieldVector<Fraction> v = create(5);
+        final FieldVectorChangingVisitor<Fraction> visitor;
+        visitor = new FieldVectorChangingVisitor<Fraction>() {
+
+            public Fraction visit(int index, Fraction value) {
+                return Fraction.ZERO;
+            }
+
+            public void start(int dimension, int start, int end) {
+                // Do nothing
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        try {
+            v.walkInOptimizedOrder(visitor, -1, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 5, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 0, -1);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 0, 5);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 4, 0);
+            Assert.fail();
+        } catch (NumberIsTooSmallException e) {
+            // Expected behavior
+        }
+    }
+
+    /** Visiting a valid subvector. */
+    @Test
+    public void testWalkInOptimizedOrderChangingVisitor3() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final ArrayFieldVector<Fraction> v = new ArrayFieldVector<Fraction>(data);
+        final int expectedStart = 2;
+        final int expectedEnd = 7;
+        final FieldVectorChangingVisitor<Fraction> visitor;
+        visitor = new FieldVectorChangingVisitor<Fraction>() {
+            private final boolean[] visited = new boolean[data.length];
+
+            public Fraction visit(final int actualIndex, final Fraction actualValue) {
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+                visited[actualIndex] = true;
+                return actualValue.add(actualIndex);
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(expectedStart, actualStart);
+                Assert.assertEquals(expectedEnd, actualEnd);
+                Arrays.fill(visited, true);
+            }
+
+            public Fraction end() {
+                for (int i = expectedStart; i <= expectedEnd; i++) {
+                    Assert.assertTrue("entry " + i + "has not been visited",
+                                      visited[i]);
+                }
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInOptimizedOrder(visitor, expectedStart, expectedEnd);
+        for (int i = expectedStart; i <= expectedEnd; i++) {
+            Assert.assertEquals("entry " + i, data[i].add(i), v.getEntry(i));
+        }
+    }
+
+    private ArrayFieldVector<Fraction> create(int n) {
+        Fraction[] t = new Fraction[n];
+        for (int i = 0; i < n; ++i) {
+            t[i] = Fraction.ZERO;
+        }
+        return new ArrayFieldVector<Fraction>(t);
+    }
 }

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SparseFieldVectorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SparseFieldVectorTest.java?rev=1570536&r1=1570535&r2=1570536&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SparseFieldVectorTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SparseFieldVectorTest.java Fri Feb 21 11:26:09 2014
@@ -17,10 +17,14 @@
 package org.apache.commons.math3.linear;
 
 
+import java.util.Arrays;
+
 import org.apache.commons.math3.fraction.Fraction;
 import org.apache.commons.math3.fraction.FractionConversionException;
 import org.apache.commons.math3.fraction.FractionField;
 import org.apache.commons.math3.exception.MathIllegalArgumentException;
+import org.apache.commons.math3.exception.NumberIsTooSmallException;
+import org.apache.commons.math3.exception.OutOfRangeException;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -240,4 +244,539 @@ public class SparseFieldVectorTest {
         }
     }
 
+    /*
+     * TESTS OF THE VISITOR PATTERN
+     */
+
+    /** The whole vector is visited. */
+    @Test
+    public void testWalkInDefaultOrderPreservingVisitor1() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
+        final FieldVectorPreservingVisitor<Fraction> visitor;
+        visitor = new FieldVectorPreservingVisitor<Fraction>() {
+
+            private int expectedIndex;
+
+            public void visit(final int actualIndex, final Fraction actualValue) {
+                Assert.assertEquals(expectedIndex, actualIndex);
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+                ++expectedIndex;
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(0, actualStart);
+                Assert.assertEquals(data.length - 1, actualEnd);
+                expectedIndex = 0;
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInDefaultOrder(visitor);
+    }
+
+    /** Visiting an invalid subvector. */
+    @Test
+    public void testWalkInDefaultOrderPreservingVisitor2() {
+        final SparseFieldVector<Fraction> v = create(5);
+        final FieldVectorPreservingVisitor<Fraction> visitor;
+        visitor = new FieldVectorPreservingVisitor<Fraction>() {
+
+            public void visit(int index, Fraction value) {
+                // Do nothing
+            }
+
+            public void start(int dimension, int start, int end) {
+                // Do nothing
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        try {
+            v.walkInDefaultOrder(visitor, -1, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 5, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 0, -1);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 0, 5);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 4, 0);
+            Assert.fail();
+        } catch (NumberIsTooSmallException e) {
+            // Expected behavior
+        }
+    }
+
+    /** Visiting a valid subvector. */
+    @Test
+    public void testWalkInDefaultOrderPreservingVisitor3() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
+        final int expectedStart = 2;
+        final int expectedEnd = 7;
+        final FieldVectorPreservingVisitor<Fraction> visitor;
+        visitor = new FieldVectorPreservingVisitor<Fraction>() {
+
+            private int expectedIndex;
+
+            public void visit(final int actualIndex, final Fraction actualValue) {
+                Assert.assertEquals(expectedIndex, actualIndex);
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+                ++expectedIndex;
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(expectedStart, actualStart);
+                Assert.assertEquals(expectedEnd, actualEnd);
+                expectedIndex = expectedStart;
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInDefaultOrder(visitor, expectedStart, expectedEnd);
+    }
+
+    /** The whole vector is visited. */
+    @Test
+    public void testWalkInOptimizedOrderPreservingVisitor1() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
+        final FieldVectorPreservingVisitor<Fraction> visitor;
+        visitor = new FieldVectorPreservingVisitor<Fraction>() {
+            private final boolean[] visited = new boolean[data.length];
+
+            public void visit(final int actualIndex, final Fraction actualValue) {
+                visited[actualIndex] = true;
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(0, actualStart);
+                Assert.assertEquals(data.length - 1, actualEnd);
+                Arrays.fill(visited, false);
+            }
+
+            public Fraction end() {
+                for (int i = 0; i < data.length; i++) {
+                    Assert.assertTrue("entry " + i + "has not been visited",
+                                      visited[i]);
+                }
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInOptimizedOrder(visitor);
+    }
+
+    /** Visiting an invalid subvector. */
+    @Test
+    public void testWalkInOptimizedOrderPreservingVisitor2() {
+        final SparseFieldVector<Fraction> v = create(5);
+        final FieldVectorPreservingVisitor<Fraction> visitor;
+        visitor = new FieldVectorPreservingVisitor<Fraction>() {
+
+            public void visit(int index, Fraction value) {
+                // Do nothing
+            }
+
+            public void start(int dimension, int start, int end) {
+                // Do nothing
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        try {
+            v.walkInOptimizedOrder(visitor, -1, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 5, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 0, -1);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 0, 5);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 4, 0);
+            Assert.fail();
+        } catch (NumberIsTooSmallException e) {
+            // Expected behavior
+        }
+    }
+
+    /** Visiting a valid subvector. */
+    @Test
+    public void testWalkInOptimizedOrderPreservingVisitor3() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
+        final int expectedStart = 2;
+        final int expectedEnd = 7;
+        final FieldVectorPreservingVisitor<Fraction> visitor;
+        visitor = new FieldVectorPreservingVisitor<Fraction>() {
+            private final boolean[] visited = new boolean[data.length];
+
+            public void visit(final int actualIndex, final Fraction actualValue) {
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+                visited[actualIndex] = true;
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(expectedStart, actualStart);
+                Assert.assertEquals(expectedEnd, actualEnd);
+                Arrays.fill(visited, true);
+            }
+
+            public Fraction end() {
+                for (int i = expectedStart; i <= expectedEnd; i++) {
+                    Assert.assertTrue("entry " + i + "has not been visited",
+                                      visited[i]);
+                }
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInOptimizedOrder(visitor, expectedStart, expectedEnd);
+    }
+
+    /** The whole vector is visited. */
+    @Test
+    public void testWalkInDefaultOrderChangingVisitor1() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
+        final FieldVectorChangingVisitor<Fraction> visitor;
+        visitor = new FieldVectorChangingVisitor<Fraction>() {
+
+            private int expectedIndex;
+
+            public Fraction visit(final int actualIndex, final Fraction actualValue) {
+                Assert.assertEquals(expectedIndex, actualIndex);
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+                ++expectedIndex;
+                return actualValue.add(actualIndex);
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(0, actualStart);
+                Assert.assertEquals(data.length - 1, actualEnd);
+                expectedIndex = 0;
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInDefaultOrder(visitor);
+        for (int i = 0; i < data.length; i++) {
+            Assert.assertEquals("entry " + i, data[i].add(i), v.getEntry(i));
+        }
+    }
+
+    /** Visiting an invalid subvector. */
+    @Test
+    public void testWalkInDefaultOrderChangingVisitor2() {
+        final SparseFieldVector<Fraction> v = create(5);
+        final FieldVectorChangingVisitor<Fraction> visitor;
+        visitor = new FieldVectorChangingVisitor<Fraction>() {
+
+            public Fraction visit(int index, Fraction value) {
+                return Fraction.ZERO;
+            }
+
+            public void start(int dimension, int start, int end) {
+                // Do nothing
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        try {
+            v.walkInDefaultOrder(visitor, -1, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 5, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 0, -1);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 0, 5);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInDefaultOrder(visitor, 4, 0);
+            Assert.fail();
+        } catch (NumberIsTooSmallException e) {
+            // Expected behavior
+        }
+    }
+
+    /** Visiting a valid subvector. */
+    @Test
+    public void testWalkInDefaultOrderChangingVisitor3() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
+        final int expectedStart = 2;
+        final int expectedEnd = 7;
+        final FieldVectorChangingVisitor<Fraction> visitor;
+        visitor = new FieldVectorChangingVisitor<Fraction>() {
+
+            private int expectedIndex;
+
+            public Fraction visit(final int actualIndex, final Fraction actualValue) {
+                Assert.assertEquals(expectedIndex, actualIndex);
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+                ++expectedIndex;
+                return actualValue.add(actualIndex);
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(expectedStart, actualStart);
+                Assert.assertEquals(expectedEnd, actualEnd);
+                expectedIndex = expectedStart;
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInDefaultOrder(visitor, expectedStart, expectedEnd);
+        for (int i = expectedStart; i <= expectedEnd; i++) {
+            Assert.assertEquals("entry " + i, data[i].add(i), v.getEntry(i));
+        }
+    }
+
+    /** The whole vector is visited. */
+    @Test
+    public void testWalkInOptimizedOrderChangingVisitor1() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
+        final FieldVectorChangingVisitor<Fraction> visitor;
+        visitor = new FieldVectorChangingVisitor<Fraction>() {
+            private final boolean[] visited = new boolean[data.length];
+
+            public Fraction visit(final int actualIndex, final Fraction actualValue) {
+                visited[actualIndex] = true;
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+                return actualValue.add(actualIndex);
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(0, actualStart);
+                Assert.assertEquals(data.length - 1, actualEnd);
+                Arrays.fill(visited, false);
+            }
+
+            public Fraction end() {
+                for (int i = 0; i < data.length; i++) {
+                    Assert.assertTrue("entry " + i + "has not been visited",
+                                      visited[i]);
+                }
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInOptimizedOrder(visitor);
+        for (int i = 0; i < data.length; i++) {
+            Assert.assertEquals("entry " + i, data[i].add(i), v.getEntry(i));
+        }
+    }
+
+    /** Visiting an invalid subvector. */
+    @Test
+    public void testWalkInOptimizedOrderChangingVisitor2() {
+        final SparseFieldVector<Fraction> v = create(5);
+        final FieldVectorChangingVisitor<Fraction> visitor;
+        visitor = new FieldVectorChangingVisitor<Fraction>() {
+
+            public Fraction visit(int index, Fraction value) {
+                return Fraction.ZERO;
+            }
+
+            public void start(int dimension, int start, int end) {
+                // Do nothing
+            }
+
+            public Fraction end() {
+                return Fraction.ZERO;
+            }
+        };
+        try {
+            v.walkInOptimizedOrder(visitor, -1, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 5, 4);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 0, -1);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 0, 5);
+            Assert.fail();
+        } catch (OutOfRangeException e) {
+            // Expected behavior
+        }
+        try {
+            v.walkInOptimizedOrder(visitor, 4, 0);
+            Assert.fail();
+        } catch (NumberIsTooSmallException e) {
+            // Expected behavior
+        }
+    }
+
+    /** Visiting a valid subvector. */
+    @Test
+    public void testWalkInOptimizedOrderChangingVisitor3() {
+        final Fraction[] data = new Fraction[] {
+            Fraction.ZERO, Fraction.ONE, Fraction.ZERO,
+            Fraction.ZERO, Fraction.TWO, Fraction.ZERO,
+            Fraction.ZERO, Fraction.ZERO, new Fraction(3)
+        };
+        final SparseFieldVector<Fraction> v = new SparseFieldVector<Fraction>(field, data);
+        final int expectedStart = 2;
+        final int expectedEnd = 7;
+        final FieldVectorChangingVisitor<Fraction> visitor;
+        visitor = new FieldVectorChangingVisitor<Fraction>() {
+            private final boolean[] visited = new boolean[data.length];
+
+            public Fraction visit(final int actualIndex, final Fraction actualValue) {
+                Assert.assertEquals(Integer.toString(actualIndex),
+                                    data[actualIndex], actualValue);
+                visited[actualIndex] = true;
+                return actualValue.add(actualIndex);
+            }
+
+            public void start(final int actualSize, final int actualStart,
+                              final int actualEnd) {
+                Assert.assertEquals(data.length, actualSize);
+                Assert.assertEquals(expectedStart, actualStart);
+                Assert.assertEquals(expectedEnd, actualEnd);
+                Arrays.fill(visited, true);
+            }
+
+            public Fraction end() {
+                for (int i = expectedStart; i <= expectedEnd; i++) {
+                    Assert.assertTrue("entry " + i + "has not been visited",
+                                      visited[i]);
+                }
+                return Fraction.ZERO;
+            }
+        };
+        v.walkInOptimizedOrder(visitor, expectedStart, expectedEnd);
+        for (int i = expectedStart; i <= expectedEnd; i++) {
+            Assert.assertEquals("entry " + i, data[i].add(i), v.getEntry(i));
+        }
+    }
+
+    private SparseFieldVector<Fraction> create(int n) {
+        Fraction[] t = new Fraction[n];
+        for (int i = 0; i < n; ++i) {
+            t[i] = Fraction.ZERO;
+        }
+        return new SparseFieldVector<Fraction>(field, t);
+    }
 }



Mime
View raw message