commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From er...@apache.org
Subject svn commit: r1162511 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/linear/ site/xdoc/ test/java/org/apache/commons/math/linear/
Date Sun, 28 Aug 2011 12:58:58 GMT
Author: erans
Date: Sun Aug 28 12:58:57 2011
New Revision: 1162511

URL: http://svn.apache.org/viewvc?rev=1162511&view=rev
Log:
MATH-653
Renamed "AbstracRealVector" to "RealVector" (getting rid of the "interface").
Changed "SparseRealVector" from "interface" to "abstract" class.
Modified subclasses ("extends" instead of "implements") and unit test name
("RealVectorTest" instead of "AbstractRealVectorTest") accordingly.
Slightly modified "UnmodifiableRealVectorAbstractTest" to exclude methods
that are now inherited from "Object".
Changed unmodifiable vector view from a static inner class to an anonymous
class.

Added:
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/RealVectorTest.java
      - copied, changed from r1162253, commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/AbstractRealVectorTest.java
Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/ArrayRealVector.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/OpenMapRealVector.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/RealVector.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SparseRealVector.java
    commons/proper/math/trunk/src/site/xdoc/changes.xml
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/AbstractRealVectorTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/SparseRealVectorTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/UnmodifiableRealVectorAbstractTest.java

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/ArrayRealVector.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/ArrayRealVector.java?rev=1162511&r1=1162510&r2=1162511&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/ArrayRealVector.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/ArrayRealVector.java Sun Aug 28 12:58:57 2011
@@ -34,7 +34,7 @@ import org.apache.commons.math.util.Fast
  * @version $Id$
  * @since 2.0
  */
-public class ArrayRealVector extends AbstractRealVector implements Serializable {
+public class ArrayRealVector extends RealVector implements Serializable {
     /** Serializable version identifier. */
     private static final long serialVersionUID = -1097961340710804027L;
     /** Default format. */

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/OpenMapRealVector.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/OpenMapRealVector.java?rev=1162511&r1=1162510&r2=1162511&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/OpenMapRealVector.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/OpenMapRealVector.java Sun Aug 28 12:58:57 2011
@@ -30,8 +30,8 @@ import org.apache.commons.math.util.Fast
  * @version $Id$
  * @since 2.0
 */
-public class OpenMapRealVector extends AbstractRealVector
-    implements SparseRealVector, Serializable {
+public class OpenMapRealVector extends SparseRealVector
+    implements Serializable {
     /** Default Tolerance for having a value considered zero. */
     public static final double DEFAULT_ZERO_TOLERANCE = 1.0e-12;
     /** Serializable version identifier. */

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/RealVector.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/RealVector.java?rev=1162511&r1=1162510&r2=1162511&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/RealVector.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/RealVector.java Sun Aug 28 12:58:57 2011
@@ -14,15 +14,26 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.math.linear;
 
 import java.util.Iterator;
+import java.util.NoSuchElementException;
 
+import org.apache.commons.math.exception.MathUnsupportedOperationException;
+import org.apache.commons.math.exception.DimensionMismatchException;
+import org.apache.commons.math.exception.OutOfRangeException;
+import org.apache.commons.math.exception.MathArithmeticException;
+import org.apache.commons.math.analysis.FunctionUtils;
+import org.apache.commons.math.analysis.function.Add;
+import org.apache.commons.math.analysis.function.Multiply;
+import org.apache.commons.math.analysis.function.Divide;
 import org.apache.commons.math.analysis.UnivariateRealFunction;
-
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
 
 /**
- * Interface defining a real-valued vector with basic algebraic operations.
+ * Class defining a real-valued vector with basic algebraic operations.
  * <p>
  * vector element indexing is 0-based -- e.g., {@code getEntry(0)}
  * returns the first element of the vector.
@@ -42,100 +53,148 @@ import org.apache.commons.math.analysis.
  * </pre>
  *
  * @version $Id$
- * @since 2.0
+ * @since 2.1
  */
-public interface RealVector {
+public abstract class RealVector {
     /**
-     * Acts as if it is implemented as:
-     * <pre>
-     *  Entry e = null;
-     *  for(Iterator<Entry> it = iterator(); it.hasNext(); e = it.next()) {
-     *      e.setValue(function.value(e.getValue()));
-     *  }
-     * </pre>
+     * Returns the size of the vector.
      *
-     * @param function Function to apply to each entry.
-     * @return this vector.
-     * @throws org.apache.commons.math.exception.MathUserException
-     * if the function throws it.
+     * @return size
      */
-    RealVector mapToSelf(UnivariateRealFunction function);
+    public abstract int getDimension();
 
     /**
-     * Acts as if implemented as:
-     * <pre>
-     *  return copy().map(function);
-     * </pre>
+     * Returns the entry in the specified index.
      *
-     * @param function Function to apply to each entry.
-     * @return a new vector.
-     * @throws org.apache.commons.math.exception.MathUserException
-     * if the function throws it.
+     * @param index Index location of entry to be fetched.
+     * @return the vector entry at {@code index}.
+     * @throws org.apache.commons.math.exception.OutOfRangeException
+     * if the index is not valid.
+     * @see #setEntry(int, double)
      */
-    RealVector map(UnivariateRealFunction function);
+    public abstract double getEntry(int index);
 
-    /** Class representing a modifiable entry in the vector. */
-    public abstract class Entry {
-        /** Index of the entry. */
-        private int index;
+    /**
+     * Set a single element.
+     * @param index element index.
+     * @param value new value for the element.
+     * @throws org.apache.commons.math.exception.OutOfRangeException
+     * if the index is not valid.
+     * @see #getEntry(int)
+     */
+    public abstract void setEntry(int index, double value);
 
-        /**
-         * Get the value of the entry.
-         *
-         * @return the value of the entry.
-         */
-        public abstract double getValue();
-        /**
-         * Set the value of the entry.
-         *
-         * @param value New value for the entry.
-         */
-        public abstract void setValue(double value);
-        /**
-         * Get the index of the entry.
-         *
-         * @return the index of the entry.
-         */
-        public int getIndex() {
-            return index;
-        }
-        /**
-         * Set the index of the entry.
-         *
-         * @param index New index for the entry.
-         */
-        public void setIndex(int index) {
-            this.index = index;
-        }
-    }
+    /**
+     * Construct a vector by appending a vector to this vector.
+     *
+     * @param v vector to append to this one.
+     * @return a new vector
+     */
+    public abstract RealVector append(RealVector v);
 
     /**
-     * Generic dense iterator.
-     * It iterates in increasing order of the vector index.
+     * Construct a vector by appending a double to this vector.
      *
-     * @return a dense iterator
+     * @param d double to append.
+     * @return a new vector
      */
-    Iterator<Entry> iterator();
+    public abstract RealVector append(double d);
 
     /**
-     * Specialized implementations may choose to not iterate over all
-     * dimensions, either because those values are unset, or are equal
-     * to defaultValue(), or are small enough to be ignored for the
-     * purposes of iteration.
-     * No guarantees are made about order of iteration.
-     * In dense implementations, this method will often delegate to
-     * {@link #iterator()}.
+     * Construct a vector by appending a double array to this vector.
      *
-     * @return a sparse iterator
+     * @param a double array to append.
+     * @return a new vector
      */
-    Iterator<Entry> sparseIterator();
+    public abstract RealVector append(double[] a);
 
     /**
-     * Returns a (deep) copy of this vector.
+     * Get a subvector from consecutive elements.
      *
-     * @return a vector copy.
+     * @param index index of first element.
+     * @param n number of elements to be retrieved.
+     * @return a vector containing n elements.
+     * @throws org.apache.commons.math.exception.OutOfRangeException
+     * if the index is not valid.
+     */
+    public abstract RealVector getSubVector(int index, int n);
+
+    /**
+     * Set a set of consecutive elements.
+     *
+     * @param index index of first element to be set.
+     * @param v vector containing the values to set.
+     * @throws org.apache.commons.math.exception.OutOfRangeException
+     * if the index is not valid.
+     * @see #setSubVector(int, double[])
+     */
+    public abstract void setSubVector(int index, RealVector v);
+
+    /**
+     * Set a set of consecutive elements.
+     *
+     * @param index index of first element to be set.
+     * @param v vector containing the values to set.
+     * @throws org.apache.commons.math.exception.OutOfRangeException
+     * if the index is not valid.
+     * @see #setSubVector(int, RealVector)
+     */
+    public abstract void setSubVector(int index, double[] v);
+
+    /**
+     * Check whether any coordinate of this vector is {@code NaN}.
+     *
+     * @return {@code true} if any coordinate of this vector is {@code NaN},
+     * {@code false} otherwise.
+     */
+    public abstract boolean isNaN();
+
+    /**
+     * Check whether any coordinate of this vector is infinite and none are {@code NaN}.
+     *
+     * @return {@code true} if any coordinate of this vector is infinite and
+     * none are {@code NaN}, {@code false} otherwise.
+     */
+    public abstract boolean isInfinite();
+
+    /**
+     * Check if instance and specified vectors have the same dimension.
+     *
+     * @param v Vector to compare instance with.
+     * @throws DimensionMismatchException if the vectors do not
+     * have the same dimension.
+     */
+    protected void checkVectorDimensions(RealVector v) {
+        checkVectorDimensions(v.getDimension());
+    }
+
+    /**
+     * Check if instance dimension is equal to some expected value.
+     *
+     * @param n Expected dimension.
+     * @throws DimensionMismatchException if the dimension is
+     * inconsistent with the vector size.
+     */
+    protected void checkVectorDimensions(int n) {
+        int d = getDimension();
+        if (d != n) {
+            throw new DimensionMismatchException(d, n);
+        }
+    }
+
+    /**
+     * Check if an index is valid.
+     *
+     * @param index Index to check.
+     * @exception OutOfRangeException if {@code index} is not valid.
      */
-    RealVector copy();
+    protected void checkIndex(final int index) {
+        if (index < 0 ||
+            index >= getDimension()) {
+            throw new OutOfRangeException(LocalizedFormats.INDEX,
+                                          index, 0, getDimension() - 1);
+        }
+    }
 
     /**
      * Compute the sum of this vector and {@code v}.
@@ -145,7 +204,15 @@ public interface RealVector {
      * @throws org.apache.commons.math.exception.DimensionMismatchException
      * if {@code v} is not the same size as this vector.
      */
-    RealVector add(RealVector v);
+    public RealVector add(double[] v) {
+        double[] result = v.clone();
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            result[e.getIndex()] += e.getValue();
+        }
+        return new ArrayRealVector(result, false);
+    }
 
     /**
      * Compute the sum of this vector and {@code v}.
@@ -155,8 +222,20 @@ public interface RealVector {
      * @throws org.apache.commons.math.exception.DimensionMismatchException
      * if {@code v} is not the same size as this vector.
      */
-    RealVector add(double[] v);
-
+    public RealVector add(RealVector v) {
+        if (v instanceof ArrayRealVector) {
+            double[] values = ((ArrayRealVector)v).getDataRef();
+            return add(values);
+        }
+        RealVector result = v.copy();
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            final int index = e.getIndex();
+            result.setEntry(index, e.getValue() + result.getEntry(index));
+        }
+        return result;
+    }
 
     /**
      * Subtract {@code v} from this vector.
@@ -166,7 +245,16 @@ public interface RealVector {
      * @throws org.apache.commons.math.exception.DimensionMismatchException
      * if {@code v} is not the same size as this vector.
      */
-    RealVector subtract(RealVector v);
+    public RealVector subtract(double[] v) {
+        double[] result = v.clone();
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            final int index = e.getIndex();
+            result[index] = e.getValue() - result[index];
+        }
+        return new ArrayRealVector(result, false);
+    }
 
     /**
      * Subtract {@code v} from this vector.
@@ -176,7 +264,20 @@ public interface RealVector {
      * @throws org.apache.commons.math.exception.DimensionMismatchException
      * if {@code v} is not the same size as this vector.
      */
-    RealVector subtract(double[] v);
+    public RealVector subtract(RealVector v) {
+        if (v instanceof ArrayRealVector) {
+            double[] values = ((ArrayRealVector)v).getDataRef();
+            return add(values);
+        }
+        RealVector result = v.copy();
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            final int index = e.getIndex();
+            v.setEntry(index, e.getValue() - result.getEntry(index));
+        }
+        return result;
+    }
 
     /**
      * Add a value to each entry.
@@ -184,7 +285,9 @@ public interface RealVector {
      * @param d Value to be added to each entry.
      * @return {@code this} + {@code d}.
      */
-    RealVector mapAdd(double d);
+    public RealVector mapAdd(double d) {
+        return copy().mapAddToSelf(d);
+    }
 
     /**
      * Add a value to each entry.
@@ -193,136 +296,163 @@ public interface RealVector {
      * @param d Value to be added to each entry.
      * @return {@code this}.
      */
-    RealVector mapAddToSelf(double d);
+    public RealVector mapAddToSelf(double d) {
+        if (d != 0) {
+            return mapToSelf(FunctionUtils.fix2ndArgument(new Add(), d));
+        }
+        return this;
+    }
 
     /**
-     * Subtract a value from each entry.
+     * Returns a (deep) copy of this vector.
      *
-     * @param d Value to be subtracted.
-     * @return {@code this} - {@code d}.
+     * @return a vector copy.
      */
-    RealVector mapSubtract(double d);
+    public abstract RealVector copy();
 
     /**
-     * Subtract a value from each entry.
-     * The instance is changed in-place.
-     *
-     * @param d Value to be subtracted.
-     * @return {@code this}.
+     * Compute the dot product.
+     * @param v vector with which dot product should be computed
+     * @return the scalar dot product between instance and v
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
      */
-    RealVector mapSubtractToSelf(double d);
+    public double dotProduct(double[] v) {
+        return dotProduct(new ArrayRealVector(v, false));
+    }
 
     /**
-     * Multiply each entry.
+     * Compute the dot product.
+     * @param v vector with which dot product should be computed
+     * @return the scalar dot product between instance and v
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    public double dotProduct(RealVector v) {
+        checkVectorDimensions(v);
+        double d = 0;
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            d += e.getValue() * v.getEntry(e.getIndex());
+        }
+        return d;
+    }
+
+    /**
+     * Computes the cosine of the angle between this vector and the
+     * argument.
      *
-     * @param d Multiplication factor.
-     * @return {@code this} * {@code d}.
+     * @param v Vector.
+     * @return the cosine of the angle between this vector and {@code v}.
      */
-    RealVector mapMultiply(double d);
+    public double cosine(RealVector v) {
+        final double norm = getNorm();
+        final double vNorm = v.getNorm();
+
+        if (norm == 0 ||
+            vNorm == 0) {
+            throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
+        }
+        return dotProduct(v) / (norm * vNorm);
+    }
 
     /**
-     * Multiply each entry.
-     * The instance is changed in-place.
+     * Computes the cosine of the angle between this vector and the
+     * vector whose components are given as argument.
      *
-     * @param d Multiplication factor.
-     * @return {@code this}.
+     * @param v Components of a vector.
+     * @return the cosine of the angle between this vector and {@code v}.
      */
-    RealVector mapMultiplyToSelf(double d);
+    public double cosine(double[] v) {
+        return cosine(new ArrayRealVector(v, false));
+    }
 
     /**
-     * Divide each entry.
+     * Element-by-element division.
      *
-     * @param d Value to divide by.
-     * @return {@code this} / {@code d}.
+     * @param v vector by which instance elements must be divided
+     * @return a vector containing this[i] / v[i] for all i
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
      */
-    RealVector mapDivide(double d);
+    public abstract RealVector ebeDivide(RealVector v);
 
     /**
-     * Divide each entry.
-     * The instance is changed in-place.
+     * Element-by-element division.
      *
-     * @param d Value to divide by.
-     * @return {@code this}.
+     * @param v vector by which instance elements must be divided
+     * @return a vector containing this[i] / v[i] for all i
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
      */
-    RealVector mapDivideToSelf(double d);
+    public RealVector ebeDivide(double[] v) {
+        return ebeDivide(new ArrayRealVector(v, false));
+    }
 
     /**
      * Element-by-element multiplication.
+     *
      * @param v vector by which instance elements must be multiplied
      * @return a vector containing this[i] * v[i] for all i
      * @throws org.apache.commons.math.exception.DimensionMismatchException
      * if {@code v} is not the same size as this vector.
      */
-    RealVector ebeMultiply(RealVector v);
+    public abstract RealVector ebeMultiply(RealVector v);
 
     /**
      * Element-by-element multiplication.
+     *
      * @param v vector by which instance elements must be multiplied
      * @return a vector containing this[i] * v[i] for all i
      * @throws org.apache.commons.math.exception.DimensionMismatchException
      * if {@code v} is not the same size as this vector.
      */
-    RealVector ebeMultiply(double[] v);
+    public RealVector ebeMultiply(double[] v) {
+        return ebeMultiply(new ArrayRealVector(v, false));
+    }
 
     /**
-     * Element-by-element division.
-     * @param v vector by which instance elements must be divided
-     * @return a vector containing this[i] / v[i] for all i
+     * Distance between two vectors.
+     * <p>This method computes the distance consistent with the
+     * L<sub>2</sub> norm, i.e. the square root of the sum of
+     * elements differences, or euclidian distance.</p>
+     * @param v vector to which distance is requested
+     * @return distance between two vectors.
      * @throws org.apache.commons.math.exception.DimensionMismatchException
      * if {@code v} is not the same size as this vector.
+     * @see #getL1Distance(RealVector)
+     * @see #getLInfDistance(RealVector)
+     * @see #getNorm()
      */
-    RealVector ebeDivide(RealVector v);
+    public double getDistance(RealVector v) {
+        checkVectorDimensions(v);
+        double d = 0;
+        Iterator<Entry> it = iterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            final double diff = e.getValue() - v.getEntry(e.getIndex());
+            d += diff * diff;
+        }
+        return FastMath.sqrt(d);
+    }
 
     /**
-     * Element-by-element division.
-     * @param v vector by which instance elements must be divided
-     * @return a vector containing this[i] / v[i] for all i
+     * Distance between two vectors.
+     * <p>This method computes the distance consistent with the
+     * L<sub>2</sub> norm, i.e. the square root of the sum of
+     * elements differences, or euclidian distance.</p>
+     * @param v vector to which distance is requested
+     * @return distance between two vectors.
      * @throws org.apache.commons.math.exception.DimensionMismatchException
      * if {@code v} is not the same size as this vector.
+     * @see #getL1Distance(double[])
+     * @see #getLInfDistance(double[])
+     * @see #getNorm()
      */
-    RealVector ebeDivide(double[] v);
-
-    /**
-     * Returns vector entries as a double array.
-     * @return double array of entries
-     */
-     double[] getData();
-
-    /**
-     * Compute the dot product.
-     * @param v vector with which dot product should be computed
-     * @return the scalar dot product between instance and v
-     * @throws org.apache.commons.math.exception.DimensionMismatchException
-     * if {@code v} is not the same size as this vector.
-     */
-    double dotProduct(RealVector v);
-
-    /**
-     * Compute the dot product.
-     * @param v vector with which dot product should be computed
-     * @return the scalar dot product between instance and v
-     * @throws org.apache.commons.math.exception.DimensionMismatchException
-     * if {@code v} is not the same size as this vector.
-     */
-    double dotProduct(double[] v);
-
-    /**
-     * Computes the cosine of the angle between this vector and the
-     * argument.
-     *
-     * @param v Vector.
-     * @return the cosine of the angle between this vector and {@code v}.
-     */
-    double cosine(RealVector v);
-
-    /**
-     * Computes the cosine of the angle between this vector and the
-     * vector whose components are given as argument.
-     *
-     * @param v Components of a vector.
-     * @return the cosine of the angle between this vector and {@code v}.
-     */
-    double cosine(double[] v);
+    public double getDistance(double[] v) {
+        return getDistance(new ArrayRealVector(v,false));
+    }
 
     /**
      * Returns the L<sub>2</sub> norm of the vector.
@@ -333,7 +463,16 @@ public interface RealVector {
      * @see #getLInfNorm()
      * @see #getDistance(RealVector)
      */
-    double getNorm();
+    public double getNorm() {
+        double sum = 0;
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            final double value = e.getValue();
+            sum += value * value;
+        }
+        return FastMath.sqrt(sum);
+    }
 
     /**
      * Returns the L<sub>1</sub> norm of the vector.
@@ -344,7 +483,15 @@ public interface RealVector {
      * @see #getLInfNorm()
      * @see #getL1Distance(RealVector)
      */
-    double getL1Norm();
+    public double getL1Norm() {
+        double norm = 0;
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            norm += FastMath.abs(e.getValue());
+        }
+        return norm;
+    }
 
     /**
      * Returns the L<sub>&infin;</sub> norm of the vector.
@@ -355,37 +502,15 @@ public interface RealVector {
      * @see #getL1Norm()
      * @see #getLInfDistance(RealVector)
      */
-    double getLInfNorm();
-
-    /**
-     * Distance between two vectors.
-     * <p>This method computes the distance consistent with the
-     * L<sub>2</sub> norm, i.e. the square root of the sum of
-     * elements differences, or euclidian distance.</p>
-     * @param v vector to which distance is requested
-     * @return distance between two vectors.
-     * @throws org.apache.commons.math.exception.DimensionMismatchException
-     * if {@code v} is not the same size as this vector.
-     * @see #getL1Distance(RealVector)
-     * @see #getLInfDistance(RealVector)
-     * @see #getNorm()
-     */
-    double getDistance(RealVector v);
-
-    /**
-     * Distance between two vectors.
-     * <p>This method computes the distance consistent with the
-     * L<sub>2</sub> norm, i.e. the square root of the sum of
-     * elements differences, or euclidian distance.</p>
-     * @param v vector to which distance is requested
-     * @return distance between two vectors.
-     * @throws org.apache.commons.math.exception.DimensionMismatchException
-     * if {@code v} is not the same size as this vector.
-     * @see #getL1Distance(double[])
-     * @see #getLInfDistance(double[])
-     * @see #getNorm()
-     */
-    double getDistance(double[] v);
+    public double getLInfNorm() {
+        double norm = 0;
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            norm = FastMath.max(norm, FastMath.abs(e.getValue()));
+        }
+        return norm;
+    }
 
     /**
      * Distance between two vectors.
@@ -396,11 +521,20 @@ public interface RealVector {
      * @return distance between two vectors.
      * @throws org.apache.commons.math.exception.DimensionMismatchException
      * if {@code v} is not the same size as this vector.
-     * @see #getDistance(RealVector)
-     * @see #getLInfDistance(RealVector)
+     * @see #getDistance(double[])
+     * @see #getLInfDistance(double[])
      * @see #getL1Norm()
      */
-    double getL1Distance(RealVector v);
+    public double getL1Distance(RealVector v) {
+        checkVectorDimensions(v);
+        double d = 0;
+        Iterator<Entry> it = iterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            d += FastMath.abs(e.getValue() - v.getEntry(e.getIndex()));
+        }
+        return d;
+    }
 
     /**
      * Distance between two vectors.
@@ -415,7 +549,16 @@ public interface RealVector {
      * @see #getLInfDistance(double[])
      * @see #getL1Norm()
      */
-    double getL1Distance(double[] v);
+    public double getL1Distance(double[] v) {
+        checkVectorDimensions(v.length);
+        double d = 0;
+        Iterator<Entry> it = iterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            d += FastMath.abs(e.getValue() - v[e.getIndex()]);
+        }
+        return d;
+    }
 
     /**
      * Distance between two vectors.
@@ -430,7 +573,16 @@ public interface RealVector {
      * @see #getL1Distance(RealVector)
      * @see #getLInfNorm()
      */
-    double getLInfDistance(RealVector v);
+    public double getLInfDistance(RealVector v) {
+        checkVectorDimensions(v);
+        double d = 0;
+        Iterator<Entry> it = iterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            d = FastMath.max(FastMath.abs(e.getValue() - v.getEntry(e.getIndex())), d);
+        }
+        return d;
+    }
 
     /**
      * Distance between two vectors.
@@ -445,135 +597,204 @@ public interface RealVector {
      * @see #getL1Distance(double[])
      * @see #getLInfNorm()
      */
-    double getLInfDistance(double[] v);
+    public double getLInfDistance(double[] v) {
+        checkVectorDimensions(v.length);
+        double d = 0;
+        Iterator<Entry> it = iterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            d = FastMath.max(FastMath.abs(e.getValue() - v[e.getIndex()]), d);
+        }
+        return d;
+    }
 
-    /** Creates a unit vector pointing in the direction of this vector.
-     * <p>The instance is not changed by this method.</p>
-     * @return a unit vector pointing in direction of this vector
-     * @exception ArithmeticException if the norm is null
-     */
-    RealVector unitVector();
+    /** Get the index of the minimum entry.
+     * @return index of the minimum entry or -1 if vector length is 0
+     * or all entries are NaN
+     */
+    public int getMinIndex() {
+        int minIndex    = -1;
+        double minValue = Double.POSITIVE_INFINITY;
+        Iterator<Entry> iterator = iterator();
+        while (iterator.hasNext()) {
+            final Entry entry = iterator.next();
+            if (entry.getValue() <= minValue) {
+                minIndex = entry.getIndex();
+                minValue = entry.getValue();
+            }
+        }
+        return minIndex;
+    }
 
-    /** Converts this vector into a unit vector.
-     * <p>The instance itself is changed by this method.</p>
-     * @throws  org.apache.commons.math.exception.MathArithmeticException
-     * if the norm is zero.
+    /** Get the value of the minimum entry.
+     * @return value of the minimum entry or NaN if all entries are NaN
      */
-    void unitize();
+    public double getMinValue() {
+        final int minIndex = getMinIndex();
+        return minIndex < 0 ? Double.NaN : getEntry(minIndex);
+    }
 
-    /** Find the orthogonal projection of this vector onto another vector.
-     * @param v vector onto which instance must be projected
-     * @return projection of the instance onto v
-     * @throws org.apache.commons.math.exception.DimensionMismatchException
-     * if {@code v} is not the same size as this vector.
-     */
-    RealVector projection(RealVector v);
+    /** Get the index of the maximum entry.
+     * @return index of the maximum entry or -1 if vector length is 0
+     * or all entries are NaN
+     */
+    public int getMaxIndex() {
+        int maxIndex    = -1;
+        double maxValue = Double.NEGATIVE_INFINITY;
+        Iterator<Entry> iterator = iterator();
+        while (iterator.hasNext()) {
+            final Entry entry = iterator.next();
+            if (entry.getValue() >= maxValue) {
+                maxIndex = entry.getIndex();
+                maxValue = entry.getValue();
+            }
+        }
+        return maxIndex;
+    }
 
-    /** Find the orthogonal projection of this vector onto another vector.
-     * @param v vector onto which instance must be projected
-     * @return projection of the instance onto v
-     * @throws org.apache.commons.math.exception.DimensionMismatchException
-     * if {@code v} is not the same size as this vector.
+    /** Get the value of the maximum entry.
+     * @return value of the maximum entry or NaN if all entries are NaN
      */
-    RealVector projection(double[] v);
+    public double getMaxValue() {
+        final int maxIndex = getMaxIndex();
+        return maxIndex < 0 ? Double.NaN : getEntry(maxIndex);
+    }
 
-    /**
-     * Compute the outer product.
-     * @param v vector with which outer product should be computed
-     * @return the matrix outer product between instance and v
-     */
-    RealMatrix outerProduct(RealVector v);
 
     /**
-     * Compute the outer product.
-     * @param v vector with which outer product should be computed
-     * @return the matrix outer product between instance and v
+     * Multiply each entry.
+     *
+     * @param d Multiplication factor.
+     * @return {@code this} * {@code d}.
      */
-    RealMatrix outerProduct(double[] v);
+    public RealVector mapMultiply(double d) {
+        return copy().mapMultiplyToSelf(d);
+    }
 
     /**
-     * Returns the entry in the specified index.
+     * Multiply each entry.
+     * The instance is changed in-place.
      *
-     * @param index Index location of entry to be fetched.
-     * @return the vector entry at {@code index}.
-     * @throws org.apache.commons.math.exception.OutOfRangeException
-     * if the index is not valid.
-     * @see #setEntry(int, double)
+     * @param d Multiplication factor.
+     * @return {@code this}.
      */
-    double getEntry(int index);
+    public RealVector mapMultiplyToSelf(double d){
+        return mapToSelf(FunctionUtils.fix2ndArgument(new Multiply(), d));
+    }
 
     /**
-     * Set a single element.
-     * @param index element index.
-     * @param value new value for the element.
-     * @throws org.apache.commons.math.exception.OutOfRangeException
-     * if the index is not valid.
-     * @see #getEntry(int)
+     * Subtract a value from each entry.
+     *
+     * @param d Value to be subtracted.
+     * @return {@code this} - {@code d}.
      */
-    void setEntry(int index, double value);
+    public RealVector mapSubtract(double d) {
+        return copy().mapSubtractToSelf(d);
+    }
 
     /**
-     * Returns the size of the vector.
-     * @return size
+     * Subtract a value from each entry.
+     * The instance is changed in-place.
+     *
+     * @param d Value to be subtracted.
+     * @return {@code this}.
      */
-    int getDimension();
+    public RealVector mapSubtractToSelf(double d){
+        return mapAddToSelf(-d);
+    }
 
     /**
-     * Construct a vector by appending a vector to this vector.
-     * @param v vector to append to this one.
-     * @return a new vector
+     * Divide each entry.
+     *
+     * @param d Value to divide by.
+     * @return {@code this} / {@code d}.
      */
-    RealVector append(RealVector v);
+    public RealVector mapDivide(double d) {
+        return copy().mapDivideToSelf(d);
+    }
 
     /**
-     * Construct a vector by appending a double to this vector.
-     * @param d double to append.
-     * @return a new vector
+     * Divide each entry.
+     * The instance is changed in-place.
+     *
+     * @param d Value to divide by.
+     * @return {@code this}.
      */
-    RealVector append(double d);
+    public RealVector mapDivideToSelf(double d){
+        return mapToSelf(FunctionUtils.fix2ndArgument(new Divide(), d));
+    }
 
     /**
-     * Construct a vector by appending a double array to this vector.
-     * @param a double array to append.
-     * @return a new vector
+     * Compute the outer product.
+     * @param v vector with which outer product should be computed
+     * @return the matrix outer product between instance and v
      */
-    RealVector append(double[] a);
+    public RealMatrix outerProduct(RealVector v) {
+        RealMatrix product;
+        if (v instanceof SparseRealVector || this instanceof SparseRealVector) {
+            product = new OpenMapRealMatrix(this.getDimension(),
+                                            v.getDimension());
+        } else {
+            product = new Array2DRowRealMatrix(this.getDimension(),
+                                               v.getDimension());
+        }
+        Iterator<Entry> thisIt = sparseIterator();
+        Entry thisE = null;
+        while (thisIt.hasNext() && (thisE = thisIt.next()) != null) {
+            Iterator<Entry> otherIt = v.sparseIterator();
+            Entry otherE = null;
+            while (otherIt.hasNext() && (otherE = otherIt.next()) != null) {
+                product.setEntry(thisE.getIndex(), otherE.getIndex(),
+                                 thisE.getValue() * otherE.getValue());
+            }
+        }
+
+        return product;
+
+    }
 
     /**
-     * Get a subvector from consecutive elements.
-     * @param index index of first element.
-     * @param n number of elements to be retrieved.
-     * @return a vector containing n elements.
-     * @throws org.apache.commons.math.exception.OutOfRangeException
-     * if the index is not valid.
+     * Compute the outer product.
+     * @param v vector with which outer product should be computed
+     * @return the matrix outer product between instance and v
      */
-    RealVector getSubVector(int index, int n);
+    public RealMatrix outerProduct(double[] v) {
+        return outerProduct(new ArrayRealVector(v, false));
+    }
 
     /**
-     * Set a set of consecutive elements.
-     * @param index index of first element to be set.
-     * @param v vector containing the values to set.
-     * @throws org.apache.commons.math.exception.OutOfRangeException
-     * if the index is not valid.
-     * @see #setSubVector(int, double[])
+     * Find the orthogonal projection of this vector onto another vector.
+     *
+     * @param v vector onto which instance must be projected.
+     * @return projection of the instance onto {@code v}.
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
      */
-    void setSubVector(int index, RealVector v);
+    public abstract RealVector projection(RealVector v);
 
     /**
-     * Set a set of consecutive elements.
-     * @param index index of first element to be set.
-     * @param v vector containing the values to set.
-     * @throws org.apache.commons.math.exception.OutOfRangeException
-     * if the index is not valid.
-     * @see #setSubVector(int, RealVector)
+     * Find the orthogonal projection of this vector onto another vector.
+     *
+     * @param v vector onto which instance must be projected.
+     * @return projection of the instance onto v.
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
      */
-    void setSubVector(int index, double[] v);
+    public RealVector projection(double[] v) {
+        return projection(new ArrayRealVector(v, false));
+    }
 
     /**
      * Set all elements to a single value.
      * @param value single value to set for all elements
      */
-    void set(double value);
+    public void set(double value) {
+        Iterator<Entry> it = iterator();
+        Entry e = null;
+        while (it.hasNext() && (e = it.next()) != null) {
+            e.setValue(value);
+        }
+    }
 
     /**
      * Convert the vector to a double array.
@@ -581,22 +802,134 @@ public interface RealVector {
      * are copied.</p>
      * @return array containing a copy of vector elements
      */
-    double[] toArray();
+    public double[] toArray() {
+        int dim = getDimension();
+        double[] values = new double[dim];
+        for (int i = 0; i < dim; i++) {
+            values[i] = getEntry(i);
+        }
+        return values;
+    }
 
     /**
-     * Check whether any coordinate of this vector is {@code NaN}.
-     * @return {@code true} if any coordinate of this vector is {@code NaN},
-     * {@code false} otherwise.
+     * Returns vector entries as a double array.
+     *
+     * @return double array of entries.
      */
-    boolean isNaN();
+    public double[] getData() {
+        return toArray();
+    }
 
     /**
-     * Check whether any coordinate of this vector is infinite and none are {@code NaN}.
+     * Creates a unit vector pointing in the direction of this vector.
+     * The instance is not changed by this method.
      *
-     * @return {@code true} if any coordinate of this vector is infinite and
-     * none are {@code NaN}, {@code false} otherwise.
+     * @return a unit vector pointing in direction of this vector
+     * @exception ArithmeticException if the norm is null
      */
-    boolean isInfinite();
+    public RealVector unitVector() {
+        RealVector copy = copy();
+        copy.unitize();
+        return copy;
+    }
+
+    /**
+     * Converts this vector into a unit vector.
+     * The instance itself is changed by this method.
+     *
+     * @throws org.apache.commons.math.exception.MathArithmeticException
+     * if the norm is zero.
+     */
+    public void unitize() {
+        mapDivideToSelf(getNorm());
+    }
+
+    /**
+     * Specialized implementations may choose to not iterate over all
+     * dimensions, either because those values are unset, or are equal
+     * to defaultValue(), or are small enough to be ignored for the
+     * purposes of iteration.
+     * No guarantees are made about order of iteration.
+     * In dense implementations, this method will often delegate to
+     * {@link #iterator()}.
+     *
+     * @return a sparse iterator.
+     */
+    public Iterator<Entry> sparseIterator() {
+        return new SparseEntryIterator();
+    }
+
+    /**
+     * Generic dense iterator.
+     * It iterates in increasing order of the vector index.
+     *
+     * @return a dense iterator.
+     */
+    public Iterator<Entry> iterator() {
+        final int dim = getDimension();
+        return new Iterator<Entry>() {
+
+            /** Current index. */
+            private int i = 0;
+
+            /** Current entry. */
+            private Entry e = new Entry();
+
+            /** {@inheritDoc} */
+            public boolean hasNext() {
+                return i < dim;
+            }
+
+            /** {@inheritDoc} */
+            public Entry next() {
+                e.setIndex(i++);
+                return e;
+            }
+
+            /** {@inheritDoc} */
+            public void remove() {
+                throw new MathUnsupportedOperationException();
+            }
+        };
+    }
+
+    /**
+     * Acts as if implemented as:
+     * <pre>
+     *  return copy().mapToSelf(function);
+     * </pre>
+     *
+     * @param function Function to apply to each entry.
+     * @return a new vector.
+     * @throws org.apache.commons.math.exception.MathUserException
+     * if the function throws it.
+     */
+    public RealVector map(UnivariateRealFunction function) {
+        return copy().mapToSelf(function);
+    }
+
+    /**
+     * Acts as if it is implemented as:
+     * <pre>
+     *  Entry e = null;
+     *  for(Iterator<Entry> it = iterator(); it.hasNext(); e = it.next()) {
+     *      e.setValue(function.value(e.getValue()));
+     *  }
+     * </pre>
+     *
+     * @param function Function to apply to each entry.
+     * @return this vector.
+     * @throws org.apache.commons.math.exception.MathUserException
+     * if the function throws it.
+     */
+    public RealVector mapToSelf(UnivariateRealFunction function) {
+        Iterator<Entry> it = (function.value(0) == 0) ? sparseIterator() : iterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            e.setValue(function.value(e.getValue()));
+        }
+        return this;
+    }
 
     /**
      * Returns the linear combination of {@code this} and {@code y}.
@@ -609,7 +942,9 @@ public interface RealVector {
      * @throws org.apache.commons.math.exception.DimensionMismatchException
      * if {@code y} is not the same size as this vector.
      */
-    RealVector combine(double a, double b, double[] y);
+    public RealVector combine(double a, double b, double[] y) {
+        return copy().combineToSelf(a, b, y);
+    }
 
     /**
      * Returns the linear combination of {@code this} and {@code y}.
@@ -622,7 +957,9 @@ public interface RealVector {
      * @throws org.apache.commons.math.exception.DimensionMismatchException
      * if {@code y} is not the same size as this vector.
      */
-    RealVector combine(double a, double b, RealVector y);
+    public RealVector combine(double a, double b, RealVector y) {
+        return copy().combineToSelf(a, b, y);
+    }
 
     /**
      * Updates {@code this} with the linear combination of {@code this} and
@@ -636,7 +973,9 @@ public interface RealVector {
      * @throws org.apache.commons.math.exception.DimensionMismatchException
      * if {@code y} is not the same size as this vector.
      */
-    RealVector combineToSelf(double a, double b, double[] y);
+    public RealVector combineToSelf(double a, double b, double[] y) {
+        return combineToSelf(a, b, new ArrayRealVector(y, false));
+    }
 
     /**
      * Updates {@code this} with the linear combination of {@code this} and
@@ -650,5 +989,574 @@ public interface RealVector {
      * @throws org.apache.commons.math.exception.DimensionMismatchException
      * if {@code y} is not the same size as this vector.
      */
-    RealVector combineToSelf(double a, double b, RealVector y);
+    public RealVector combineToSelf(double a, double b, RealVector y) {
+        checkVectorDimensions(y);
+        for (int i = 0; i < getDimension(); i++) {
+            final double xi = getEntry(i);
+            final double yi = y.getEntry(i);
+            setEntry(i, a * xi + b * yi);
+        }
+        return this;
+    }
+
+    /** An entry in the vector. */
+    protected class Entry {
+        /** Index of this entry. */
+        private int index;
+
+        /** Simple constructor. */
+        public Entry() {
+            setIndex(0);
+        }
+
+        /**
+         * Get the value of the entry.
+         *
+         * @return the value of the entry.
+         */
+        public double getValue() {
+            return getEntry(getIndex());
+        }
+
+        /**
+         * Set the value of the entry.
+         *
+         * @param value New value for the entry.
+         */
+        public void setValue(double value) {
+            setEntry(getIndex(), value);
+        }
+
+        /**
+         * Get the index of the entry.
+         *
+         * @return the index of the entry.
+         */
+        public int getIndex() {
+            return index;
+        }
+
+        /**
+         * Set the index of the entry.
+         *
+         * @param index New index for the entry.
+         */
+        public void setIndex(int index) {
+            this.index = index;
+        }
+    }
+
+    /**
+     * This class should rare be used, but is here to provide
+     * a default implementation of sparseIterator(), which is implemented
+     * by walking over the entries, skipping those whose values are the default one.
+     *
+     * Concrete subclasses which are SparseVector implementations should
+     * make their own sparse iterator, not use this one.
+     *
+     * This implementation might be useful for ArrayRealVector, when expensive
+     * operations which preserve the default value are to be done on the entries,
+     * and the fraction of non-default values is small (i.e. someone took a
+     * SparseVector, and passed it into the copy-constructor of ArrayRealVector)
+     */
+    protected class SparseEntryIterator implements Iterator<Entry> {
+        /** Dimension of the vector. */
+        private final int dim;
+        /** Last entry returned by {@link #next()}. */
+        private Entry current;
+        /** Next entry for {@link #next()} to return. */
+        private Entry next;
+
+        /** Simple constructor. */
+        protected SparseEntryIterator() {
+            dim = getDimension();
+            current = new Entry();
+            next = new Entry();
+            if (next.getValue() == 0) {
+                advance(next);
+            }
+        }
+
+        /**
+         * Advance an entry up to the next nonzero one.
+         *
+         * @param e entry to advance.
+         */
+        protected void advance(Entry e) {
+            if (e == null) {
+                return;
+            }
+            do {
+                e.setIndex(e.getIndex() + 1);
+            } while (e.getIndex() < dim && e.getValue() == 0);
+            if (e.getIndex() >= dim) {
+                e.setIndex(-1);
+            }
+        }
+
+        /** {@inheritDoc} */
+        public boolean hasNext() {
+            return next.getIndex() >= 0;
+        }
+
+        /** {@inheritDoc} */
+        public Entry next() {
+            int index = next.getIndex();
+            if (index < 0) {
+                throw new NoSuchElementException();
+            }
+            current.setIndex(index);
+            advance(next);
+            return current;
+        }
+
+        /** {@inheritDoc} */
+        public void remove() {
+            throw new MathUnsupportedOperationException();
+        }
+    }
+
+    /**
+     * Returns an unmodifiable view of the specified vector.
+     * The returned vector has read-only access. An attempt to modify it will
+     * result in a {@link MathUnsupportedOperationException}. However, the
+     * returned vector is <em>not</em> immutable, since any modification of
+     * {@code v} will also change the returned view.
+     * For example, in the following piece of code
+     * <pre>
+     *     RealVector v = new ArrayRealVector(2);
+     *     RealVector w = RealVector.unmodifiableRealVector(v);
+     *     v.setEntry(0, 1.2);
+     *     v.setEntry(1, -3.4);
+     * </pre>
+     * the changes will be seen in the {@code w} view of {@code v}.
+     *
+     * @param v Vector for which an unmodifiable view is to be returned.
+     * @return an unmodifiable view of {@code v}.
+     */
+    public static RealVector unmodifiableRealVector(final RealVector v) {
+        /**
+         * This anonymous class is an implementation of {@link RealVector}
+         * with read-only access.
+         * It wraps any {@link RealVector}, and exposes all methods which
+         * do not modify it. Invoking methods which should normally result
+         * in the modification of the calling {@link RealVector} results in
+         * a {@link MathUnsupportedOperationException}. It should be noted
+         * that {@link UnmodifiableVector} is <em>not</em> immutable.
+         */
+        return new RealVector() {
+            /** {@inheritDoc} */
+            @Override
+            public RealVector mapToSelf(UnivariateRealFunction function) {
+                throw new MathUnsupportedOperationException();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector map(UnivariateRealFunction function) {
+                return v.map(function);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public Iterator<Entry> iterator() {
+                final Iterator<Entry> i = v.iterator();
+                return new Iterator<Entry>() {
+                    /** The current entry. */
+                    private final UnmodifiableEntry e = new UnmodifiableEntry();
+
+                    /** {@inheritDoc} */
+                    @Override
+                    public boolean hasNext() {
+                        return i.hasNext();
+                    }
+
+                    /** {@inheritDoc} */
+                    @Override
+                    public Entry next() {
+                        e.setIndex(i.next().getIndex());
+                        return e;
+                    }
+
+                    /** {@inheritDoc} */
+                    @Override
+                    public void remove() {
+                        throw new MathUnsupportedOperationException();
+                    }
+                };
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public Iterator<Entry> sparseIterator() {
+                final Iterator<Entry> i = v.sparseIterator();
+
+                return new Iterator<Entry>() {
+                    /** The current entry. */
+                    private final UnmodifiableEntry e = new UnmodifiableEntry();
+
+                    /** {@inheritDoc} */
+                    @Override
+                    public boolean hasNext() {
+                        return i.hasNext();
+                    }
+
+                    /** {@inheritDoc} */
+                    @Override
+                    public Entry next() {
+                        e.setIndex(i.next().getIndex());
+                        return e;
+                    }
+
+                    /** {@inheritDoc} */
+                    @Override
+                    public void remove() {
+                        throw new MathUnsupportedOperationException();
+                    }
+                };
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector copy() {
+                return v.copy();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector add(RealVector w) {
+                return v.add(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector add(double[] w) {
+                return v.add(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector subtract(RealVector w) {
+                return v.subtract(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector subtract(double[] w) {
+                return v.subtract(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector mapAdd(double d) {
+                return v.mapAdd(d);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector mapAddToSelf(double d) {
+                throw new MathUnsupportedOperationException();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector mapSubtract(double d) {
+                return v.mapSubtract(d);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector mapSubtractToSelf(double d) {
+                throw new MathUnsupportedOperationException();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector mapMultiply(double d) {
+                return v.mapMultiply(d);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector mapMultiplyToSelf(double d) {
+                throw new MathUnsupportedOperationException();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector mapDivide(double d) {
+                return v.mapDivide(d);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector mapDivideToSelf(double d) {
+                throw new MathUnsupportedOperationException();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector ebeMultiply(RealVector w) {
+                return v.ebeMultiply(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector ebeMultiply(double[] w) {
+                return v.ebeMultiply(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector ebeDivide(RealVector w) {
+                return v.ebeDivide(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector ebeDivide(double[] w) {
+                return v.ebeDivide(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double[] getData() {
+                // TODO It is not specified in the javadoc that getData should
+                // return a
+                // deep copy
+                return v.getData();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double dotProduct(RealVector w) {
+                return v.dotProduct(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double dotProduct(double[] w) {
+                return v.dotProduct(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double cosine(RealVector w) {
+                return v.cosine(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double cosine(double[] w) {
+                return v.cosine(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double getNorm() {
+                return v.getNorm();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double getL1Norm() {
+                return v.getL1Norm();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double getLInfNorm() {
+                return v.getLInfNorm();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double getDistance(RealVector w) {
+                return v.getDistance(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double getDistance(double[] w) {
+                return v.getDistance(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double getL1Distance(RealVector w) {
+                return v.getL1Distance(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double getL1Distance(double[] w) {
+                return v.getL1Distance(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double getLInfDistance(RealVector w) {
+                return v.getLInfDistance(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double getLInfDistance(double[] w) {
+                return v.getLInfDistance(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector unitVector() {
+                return v.unitVector();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public void unitize() {
+                throw new MathUnsupportedOperationException();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector projection(RealVector w) {
+                return v.projection(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector projection(double[] w) {
+                return v.projection(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealMatrix outerProduct(RealVector w) {
+                return v.outerProduct(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealMatrix outerProduct(double[] w) {
+                return v.outerProduct(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double getEntry(int index) {
+                return v.getEntry(index);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public void setEntry(int index, double value) {
+                throw new MathUnsupportedOperationException();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public int getDimension() {
+                return v.getDimension();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector append(RealVector w) {
+                return v.append(w);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector append(double d) {
+                return v.append(d);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector append(double[] a) {
+                return v.append(a);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector getSubVector(int index, int n) {
+                return v.getSubVector(index, n);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public void setSubVector(int index, RealVector w) {
+                throw new MathUnsupportedOperationException();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public void setSubVector(int index, double[] w) {
+                throw new MathUnsupportedOperationException();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public void set(double value) {
+                throw new MathUnsupportedOperationException();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public double[] toArray() {
+                return v.toArray();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public boolean isNaN() {
+                return v.isNaN();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public boolean isInfinite() {
+                return v.isInfinite();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector combine(double a, double b, double[] y) {
+                return v.combine(a, b, y);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector combine(double a, double b, RealVector y) {
+                return v.combine(a, b, y);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector combineToSelf(double a, double b, double[] y) {
+                throw new MathUnsupportedOperationException();
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public RealVector combineToSelf(double a, double b, RealVector y) {
+                throw new MathUnsupportedOperationException();
+            }
+
+            /** An entry in the vector. */
+            class UnmodifiableEntry extends Entry {
+                /** {@inheritDoc} */
+                @Override
+                    public double getValue() {
+                    return v.getEntry(getIndex());
+                }
+
+                /** {@inheritDoc} */
+                @Override
+                    public void setValue(double value) {
+                    throw new MathUnsupportedOperationException();
+                }
+            }
+        };
+    }
 }

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SparseRealVector.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SparseRealVector.java?rev=1162511&r1=1162510&r2=1162511&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SparseRealVector.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SparseRealVector.java Sun Aug 28 12:58:57 2011
@@ -17,11 +17,9 @@
 package org.apache.commons.math.linear;
 
 /**
- * Marker interface for RealVectors that require sparse backing storage
+ * Marker class for RealVectors that require sparse backing storage
  * @version $Id$
  * @since 2.0
  *
  */
-public interface SparseRealVector extends RealVector {
-
-}
+public abstract class SparseRealVector extends RealVector {}

Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=1162511&r1=1162510&r2=1162511&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Sun Aug 28 12:58:57 2011
@@ -52,6 +52,13 @@ The <action> type attribute can be add,u
     If the output is not quite correct, check for invisible trailing spaces!
      -->
     <release version="3.0" date="TBD" description="TBD">
+      <action dev="erans" type="fix" issue="MATH-653">
+         Renamed "AbstractRealVector" to "RealVector". The interface was removed
+         in favour of its unique (abstract) implementation.
+      </action>
+      <action dev="erans" type="add" issue="MATH-646" due-to="Sébastien Brisard">
+         Unmodifiable view of a "RealVector".
+      </action>
       <action dev="luc" type="fix" issue="MATH-501" >
           Refactored integration API for consistency with solvers API. Now the main convergence
           parameters are set in the constructor and remain fixed.

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java?rev=1162511&r1=1162510&r2=1162511&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java Sun Aug 28 12:58:57 2011
@@ -78,7 +78,8 @@ public class ArrayRealVectorTest {
 
     // Testclass to test the RealVector interface
     // only with enough content to support the test
-    public static class RealVectorTestImpl implements RealVector, Serializable {
+    public static class RealVectorTestImpl extends RealVector
+        implements Serializable {
 
         /** Serializable version identifier. */
         private static final long serialVersionUID = 4715341047369582908L;

Copied: commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/RealVectorTest.java (from r1162253, commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/AbstractRealVectorTest.java)
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/RealVectorTest.java?p2=commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/RealVectorTest.java&p1=commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/AbstractRealVectorTest.java&r1=1162253&r2=1162511&rev=1162511&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/AbstractRealVectorTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/RealVectorTest.java Sun Aug 28 12:58:57 2011
@@ -26,13 +26,13 @@ import java.util.Iterator;
 import java.util.Random;
 
 /**
- *
+ * Tests for {@link RealVector}.
  */
-public class AbstractRealVectorTest {
+public class RealVectorTest {
     private double[] vec1 = { 1d, 2d, 3d, 4d, 5d };
     private double[] vec2 = { -3d, 0d, 0d, 2d, 1d };
 
-    private static class TestVectorImpl extends AbstractRealVector {
+    private static class TestVectorImpl extends RealVector {
         private double[] values;
 
         TestVectorImpl(double[] values) {
@@ -43,11 +43,10 @@ public class AbstractRealVectorTest {
         public double[] getData() { return values; }
 
         @Override
-        public AbstractRealVector copy() {
+        public RealVector copy() {
             return new TestVectorImpl(values.clone());
         }
 
-
         UnsupportedOperationException unsupported() {
             return new UnsupportedOperationException("Test implementation only supports methods necessary for testing");
         }
@@ -156,6 +155,13 @@ public class AbstractRealVectorTest {
             throw unsupported();
         }
 
+        public void setSubVector(int index, double[] v) {
+            throw unsupported();
+        }
+        public void setSubVector(int index, RealVector v) {
+            throw unsupported();
+        }
+
         public boolean isNaN() {
             throw unsupported();
         }

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/SparseRealVectorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/SparseRealVectorTest.java?rev=1162511&r1=1162510&r2=1162511&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/SparseRealVectorTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/SparseRealVectorTest.java Sun Aug 28 12:58:57 2011
@@ -76,7 +76,7 @@ public class SparseRealVectorTest {
 
     // Testclass to test the RealVector interface
     // only with enough content to support the test
-    public static class SparseRealVectorTestImpl extends AbstractRealVector implements Serializable {
+    public static class SparseRealVectorTestImpl extends RealVector implements Serializable {
 
         private static final long serialVersionUID = -6251371752518113791L;
         /** Entries of the vector. */
@@ -106,7 +106,7 @@ public class SparseRealVectorTest {
         }
 
         @Override
-        public AbstractRealVector copy() {
+        public RealVector copy() {
             return new SparseRealVectorTestImpl(data);
         }
 

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/UnmodifiableRealVectorAbstractTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/UnmodifiableRealVectorAbstractTest.java?rev=1162511&r1=1162510&r2=1162511&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/UnmodifiableRealVectorAbstractTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/UnmodifiableRealVectorAbstractTest.java Sun Aug 28 12:58:57 2011
@@ -18,7 +18,8 @@ package org.apache.commons.math.linear;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.util.ArrayList;
+import java.util.Set;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Random;
 
@@ -31,10 +32,12 @@ import org.apache.commons.math.linear.Re
 import org.junit.Test;
 
 /**
- * This is an abstract test of the {@link AbstractRealVector.UnmodifiableVector}
+ * This is an abstract test of the {@link
+ * RealVector#unmodifiableRealVector(RealVector) unmodifiable vector}
  * implementation. These unmodifiable vectors decorate a (modifiable)
- * {@link RealVector}; therefore, a new implementation of this abstract test
- * should be considered for each implementation of {@link RealVector}.
+ * {@link RealVector}; therefore, a new implementation of this abstract
+ * test should be considered for each implementation of
+ * {@link RealVector}.
  *
  * @version $Id$
  *
@@ -48,18 +51,22 @@ public abstract class UnmodifiableRealVe
      * The list of methods which are excluded from the general test
      * {@link #testAllButExcluded()}.
      */
-    protected static final ArrayList<String> EXCLUDE;
+    protected static final Set<String> EXCLUDE = new HashSet<String>();
     /** The random number generator (always initialized with the same seed. */
     protected static final Random RANDOM;
 
     static {
-        EXCLUDE = new ArrayList<String>();
         EXCLUDE.add("getEntry");
         EXCLUDE.add("setEntry");
         EXCLUDE.add("getSubVector");
         EXCLUDE.add("setSubVector");
         EXCLUDE.add("iterator");
         EXCLUDE.add("sparseIterator");
+
+        // Excluded because they are inherited from "Object".
+        for (Method m : Object.class.getMethods()) {
+            EXCLUDE.add(m.getName());
+        }
         RANDOM = new Random(20110813);
     }
 
@@ -234,7 +241,7 @@ public abstract class UnmodifiableRealVe
 
     /**
      * Creates a new random vector of a specified type. This vector is then to
-     * be wrapped in a {@link AbstractRealVector.UnmodifiableVector}.
+     * be wrapped in an unmodifiable vector.
      *
      * @return a new random vector.
      */
@@ -243,11 +250,10 @@ public abstract class UnmodifiableRealVe
     /**
      * Creates a new random object of the specified type.
      *
-     * @param c
-     *            the class of the object to be created.
+     * @param c Class of the object to be created.
      * @return a new random object.
-     * @throws IllegalArgumentException
-     *             if the specified class is not recognized by this method.
+     * @throws IllegalArgumentException if the specified class is not
+     * recognized by this method.
      */
     public Object createParameter(final Class<?> c) {
         if (c == Integer.TYPE) {
@@ -270,8 +276,9 @@ public abstract class UnmodifiableRealVe
     }
 
     /**
-     * This is the general test of most methods in
-     * {@link AbstractRealVector.UnmodifiableVector}. It works as follows.
+     * This is the general test of most methods in the
+     * {@link RealVector#unmodifiableRealVector(RealVector) unmodifiable vector}.
+     * It works as follows.
      * First, an unmodifiable view of a copy of the specified random vector
      * {@code u} is created: this defines {@code v}. Then the <em>same</em>
      * method {@code m} is invoked on {@code u} and {@code v}, with randomly
@@ -288,19 +295,21 @@ public abstract class UnmodifiableRealVe
      *constructed.
      * @param args Arguments to be passed to method {@code m}.
      */
-    private void callMethod(final Method m, final RealVector u,
-            final Object... args) throws IllegalAccessException,
-            IllegalArgumentException, InvocationTargetException {
+    private void callMethod(final Method m,
+                            final RealVector u,
+                            final Object... args)
+        throws IllegalAccessException,
+               IllegalArgumentException,
+               InvocationTargetException {
         final RealVector uu = u.copy();
-        final RealVector v = AbstractRealVector
-                .unmodifiableRealVector(u.copy());
+        final RealVector v = RealVector.unmodifiableRealVector(u.copy());
         Object exp = m.invoke(u, args);
         if (equals(uu, u)) {
             Object act = m.invoke(v, args);
-            Assert.assertTrue(m.toGenericString()
-                    + ", unmodifiable vector has changed", equals(uu, v));
+            Assert.assertTrue(m.toGenericString() + ", unmodifiable vector has changed",
+                              equals(uu, v));
             Assert.assertTrue(m.toGenericString() + ", wrong result",
-                    equals(exp, act));
+                              equals(exp, act));
 
         } else {
             boolean flag = false;
@@ -322,8 +331,10 @@ public abstract class UnmodifiableRealVe
      * {@link #EXCLUDE}), they must be handled by separate tests.
      */
     @Test
-    public void testAllButExcluded() throws IllegalAccessException,
-            IllegalArgumentException, InvocationTargetException {
+    public void testAllButExcluded()
+        throws IllegalAccessException,
+               IllegalArgumentException,
+               InvocationTargetException {
         Method[] method = RealVector.class.getMethods();
         for (int i = 0; i < method.length; i++) {
             Method m = method[i];
@@ -342,7 +353,7 @@ public abstract class UnmodifiableRealVe
     @Test
     public void testGetEntry() {
         RealVector u = createVector();
-        RealVector v = AbstractRealVector.unmodifiableRealVector(u);
+        RealVector v = RealVector.unmodifiableRealVector(u);
         for (int i = 0; i < DIM; i++) {
             Assert.assertTrue(equals(u.getEntry(i), v.getEntry(i)));
         }
@@ -351,7 +362,7 @@ public abstract class UnmodifiableRealVe
     @Test(expected = MathUnsupportedOperationException.class)
     public void testSetEntry() {
         RealVector u = createVector();
-        RealVector v = AbstractRealVector.unmodifiableRealVector(u);
+        RealVector v = RealVector.unmodifiableRealVector(u);
         for (int i = 0; i < DIM; i++) {
             v.setEntry(i, 0d);
         }
@@ -360,7 +371,7 @@ public abstract class UnmodifiableRealVe
     @Test
     public void testGetSubVector() {
         RealVector u = createVector();
-        RealVector v = AbstractRealVector.unmodifiableRealVector(u);
+        RealVector v = RealVector.unmodifiableRealVector(u);
         for (int i = 0; i < DIM; i++) {
             for (int n = 1; n < DIM - i; n++) {
                 RealVector exp = u.getSubVector(i, n);
@@ -373,7 +384,7 @@ public abstract class UnmodifiableRealVe
     @Test(expected = MathUnsupportedOperationException.class)
     public void testSetSubVector() {
         RealVector u = createVector();
-        RealVector v = AbstractRealVector.unmodifiableRealVector(u);
+        RealVector v = RealVector.unmodifiableRealVector(u);
         v.setSubVector(0, new ArrayRealVector());
     }
 
@@ -381,7 +392,7 @@ public abstract class UnmodifiableRealVe
     public void testIterator() {
         RealVector u = createVector();
         Iterator<Entry> i = u.iterator();
-        RealVector v = AbstractRealVector.unmodifiableRealVector(u.copy());
+        RealVector v = RealVector.unmodifiableRealVector(u.copy());
         Iterator<Entry> j = v.iterator();
         boolean flag;
         while (i.hasNext()) {
@@ -407,7 +418,7 @@ public abstract class UnmodifiableRealVe
     public void testSparseIterator() {
         RealVector u = createVector();
         Iterator<Entry> i = u.sparseIterator();
-        RealVector v = AbstractRealVector.unmodifiableRealVector(u.copy());
+        RealVector v = RealVector.unmodifiableRealVector(u.copy());
         Iterator<Entry> j = v.sparseIterator();
         boolean flag;
         while (i.hasNext()) {



Mime
View raw message