You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mahout.apache.org by sr...@apache.org on 2010/04/21 09:41:56 UTC

svn commit: r936183 [2/3] - in /lucene/mahout/trunk: core/src/main/java/org/apache/mahout/cf/taste/hadoop/item/ core/src/main/java/org/apache/mahout/clustering/canopy/ core/src/main/java/org/apache/mahout/clustering/fuzzykmeans/ core/src/main/java/org/...

Modified: lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/AbstractVector.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/AbstractVector.java?rev=936183&r1=936182&r2=936183&view=diff
==============================================================================
--- lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/AbstractVector.java (original)
+++ lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/AbstractVector.java Wed Apr 21 07:41:55 2010
@@ -37,30 +37,16 @@ public abstract class AbstractVector imp
    * with each vector instance.
    */
   private transient Map<String, Integer> bindings;
-
-  private String name;
-
-  protected int size;
-
+  private int size;
   protected double lengthSquared = -1.0;
 
-  protected AbstractVector() {
-    this(null, 0);
-  }
-
-  protected AbstractVector(String name) {
-    this(name, 0);
-  }
-
-  protected AbstractVector(String name, int size) {
-    this.name = name;
+  protected AbstractVector(int size) {
     this.size = size;
   }
 
   public double aggregate(BinaryFunction aggregator, UnaryFunction map) {
     double result = 0.0;
-    int size = size();
-    for(int i=0; i<size; i++) {
+    for (int i=0; i < size; i++) {
       result = aggregator.apply(result, map.apply(getQuick(i)) );
     }
     return result;
@@ -68,8 +54,7 @@ public abstract class AbstractVector imp
 
   public double aggregate(Vector other, BinaryFunction aggregator, BinaryFunction combiner) {
     double result = 0.0;
-    int size = size();
-    for(int i=0; i<size; i++) {
+    for (int i=0; i < size; i++) {
       result = aggregator.apply(result, combiner.apply(getQuick(i), other.getQuick(i)));
     }
     return result;
@@ -85,11 +70,11 @@ public abstract class AbstractVector imp
   protected abstract Matrix matrixLike(int rows, int columns);
 
   public Vector viewPart(int offset, int length) {
-    if (length > size) {
-      throw new CardinalityException();
+    if (offset < 0) {
+      throw new IndexException(offset, size);
     }
-    if (offset < 0 || offset + length > size) {
-      throw new IndexException();
+    if (offset + length > size) {
+      throw new IndexException(offset + length, size);
     }
     return new VectorView(this, offset, length);
   }
@@ -123,8 +108,8 @@ public abstract class AbstractVector imp
   }
 
   public double dot(Vector x) {
-    if (size() != x.size()) {
-      throw new CardinalityException(size(), x.size());
+    if (size != x.size()) {
+      throw new CardinalityException(size, x.size());
     }
     if (this == x) {
       return dotSelf();
@@ -140,52 +125,48 @@ public abstract class AbstractVector imp
   
   public double dotSelf() {
     double result = 0.0;
-    if (this instanceof DenseVector) {
-      for (int i = 0; i < size(); i++) {
-        double value = this.getQuick(i);
-        result += value * value;
-      }
-      return result;
-    } else {
-      Iterator<Element> iter = iterateNonZero();
-      while (iter.hasNext()) {
-        double value = iter.next().get();
-        result += value * value;
-      }
-      return result;
+    Iterator<Element> iter = iterateNonZero();
+    while (iter.hasNext()) {
+      double value = iter.next().get();
+      result += value * value;
     }
+    return result;
   }
 
   public double get(int index) {
-    if (index >= 0 && index < size()) {
-      return getQuick(index);
-    } else {
-      throw new IndexException();
+    if (index < 0 || index >= size) {
+      throw new IndexException(index, size);
     }
+    return getQuick(index);
   }
 
-  public Vector minus(Vector x) {
-    if (size() != x.size()) {
-      throw new CardinalityException();
-    }
-    if (x instanceof RandomAccessSparseVector || x instanceof DenseVector) {
-      // TODO: if both are RandomAccess check the numNonDefault to determine which to iterate
-      Vector result = x.clone();
-      Iterator<Element> iter = iterateNonZero();
-      while (iter.hasNext()) {
-        Element e = iter.next();
-        result.setQuick(e.index(), e.get() - result.getQuick(e.index()));
+  public Element getElement(final int index) {
+    return new Element() {
+      public double get() {
+        return AbstractVector.this.get(index);
       }
-      return result;
-    } else { // TODO: check the numNonDefault elements to further optimize 
-      Vector result = clone();
-      Iterator<Element> iter = x.iterateNonZero();
-      while (iter.hasNext()) {
-        Element e = iter.next();
-        result.setQuick(e.index(), getQuick(e.index()) - e.get());
+      public int index() {
+        return index;
       }
-      return result;
+      public void set(double value) {
+        AbstractVector.this.set(index, value);
+      }
+    };
+  }
+
+  public Vector minus(Vector that) {
+    if (size != that.size()) {
+      throw new CardinalityException(size, that.size());
+    }
+    // TODO: check the numNonDefault elements to further optimize
+    Vector result = this.clone();
+    Iterator<Element> iter = that.iterateNonZero();
+    while (iter.hasNext()) {
+      Element thatElement = iter.next();
+      int index = thatElement.index();
+      result.setQuick(index, this.getQuick(index) - thatElement.get());
     }
+    return result;
   }
 
   public Vector normalize() {
@@ -244,8 +225,8 @@ public abstract class AbstractVector imp
   }
 
   public double getDistanceSquared(Vector v) {
-    if(v.size() != size()) {
-      throw new CardinalityException();
+    if (size != v.size()) {
+      throw new CardinalityException(size, v.size());
     }
     // if this and v has a cached lengthSquared, dot product is quickest way to compute this.
     if(lengthSquared >= 0 && v instanceof AbstractVector && ((AbstractVector)v).lengthSquared >= 0) {
@@ -281,7 +262,7 @@ public abstract class AbstractVector imp
       Element element = iter.next();
       result = Math.max(result, element.get());
     }
-    if (nonZeroElements < size()) {
+    if (nonZeroElements < size) {
       return Math.max(result, 0.0);
     }
     return result;
@@ -303,12 +284,9 @@ public abstract class AbstractVector imp
     }
     // if the maxElement is negative and the vector is sparse then any
     // unfilled element(0.0) could be the maxValue hence return -1;
-    if (nonZeroElements < size() && max < 0.0) {
-      iter = this.iterateAll();
-      while (iter.hasNext()) {
-        Element element = iter.next();
-        double tmp = element.get();
-        if (tmp == 0.0) {
+    if (nonZeroElements < size && max < 0.0) {
+      for (Element element : this) {
+        if (element.get() == 0.0) {
           return element.index();
         }
       }
@@ -329,8 +307,8 @@ public abstract class AbstractVector imp
   }
 
   public Vector plus(Vector x) {
-    if (size() != x.size()) {
-      throw new CardinalityException();
+    if (size != x.size()) {
+      throw new CardinalityException(size, x.size());
     }
     //TODO: get smarter about this, if we are adding a dense to a sparse, then we should return a dense
     Vector result = clone();
@@ -353,11 +331,10 @@ public abstract class AbstractVector imp
   }
 
   public void set(int index, double value) {
-    if (index >= 0 && index < size()) {
-      setQuick(index, value);
-    } else {
-      throw new IndexException(index, size());
+    if (index < 0 || index >= size) {
+      throw new IndexException(index, size);
     }
+    setQuick(index, value);
   }
 
   public Vector times(double x) {
@@ -378,8 +355,8 @@ public abstract class AbstractVector imp
   }
 
   public Vector times(Vector x) {
-    if (size() != x.size()) {
-      throw new CardinalityException();
+    if (size != x.size()) {
+      throw new CardinalityException(size, x.size());
     }
     Vector result = clone();
     Iterator<Element> iter = result.iterateNonZero();
@@ -402,7 +379,6 @@ public abstract class AbstractVector imp
   }
 
   public Vector assign(double value) {
-    int size = size();
     for (int i = 0; i < size; i++) {
       setQuick(i, value);
     }
@@ -410,10 +386,9 @@ public abstract class AbstractVector imp
   }
 
   public Vector assign(double[] values) {
-    if (values.length != size()) {
-      throw new CardinalityException();
+    if (size != values.length) {
+      throw new CardinalityException(size, values.length);
     }
-    int size = size();
     for (int i = 0; i < size; i++) {
       setQuick(i, values[i]);
     }
@@ -421,10 +396,9 @@ public abstract class AbstractVector imp
   }
 
   public Vector assign(Vector other) {
-    if (other.size() != size()) {
-      throw new CardinalityException();
+    if (size != other.size()) {
+      throw new CardinalityException(size, other.size());
     }
-    int size = size();
     for (int i = 0; i < size; i++) {
       setQuick(i, other.getQuick(i));
     }
@@ -436,7 +410,7 @@ public abstract class AbstractVector imp
     if(f.apply(0, y) == 0) {
       it = iterateNonZero();
     } else {
-      it = iterateAll();
+      it = iterator();
     }
     while(it.hasNext()) {
       Element e = it.next();
@@ -450,7 +424,7 @@ public abstract class AbstractVector imp
     if(function.apply(0) == 0) {
       it = iterateNonZero();
     } else {
-      it = iterateAll();
+      it = iterator();
     }
     while(it.hasNext()) {
       Element e = it.next();
@@ -460,18 +434,18 @@ public abstract class AbstractVector imp
   }
 
   public Vector assign(Vector other, BinaryFunction function) {
-    if (other.size() != size()) {
-      throw new CardinalityException();
+    if (size != other.size()) {
+      throw new CardinalityException(size, other.size());
     }
-    for (int i = 0; i < size(); i++) {
+    for (int i = 0; i < size; i++) {
       setQuick(i, function.apply(getQuick(i), other.getQuick(i)));
     }
     return this;
   }
 
   public Matrix cross(Vector other) {
-    Matrix result = matrixLike(size(), other.size());
-    for (int row = 0; row < size(); row++) {
+    Matrix result = matrixLike(size, other.size());
+    for (int row = 0; row < size; row++) {
       result.assignRow(row, other.times(getQuick(row)));
     }
     return result;
@@ -493,15 +467,7 @@ public abstract class AbstractVector imp
     return gson.fromJson(formattedString, vectorType);
   }
 
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public int size() {
+  public final int size() {
     return size;  
   }
 
@@ -514,87 +480,61 @@ public abstract class AbstractVector imp
     return gson.toJson(this, vectorType);
   }
 
-  /**
-   * Compare whether two Vector implementations have the same elements, regardless of the implementation and name. Two
-   * Vectors are equivalent if they have the same cardinality and all of their values are the same. <p/> Does not
-   * compare {@link Vector#getName()}.
-   *
-   * @param left  The left hand Vector to compare
-   * @param right The right hand Vector
-   * @return true if the two Vectors have the same cardinality and the same values
-   * @see #strictEquivalence(Vector, Vector)
-   * @see Vector#equals(Object)
-   */
-  public static boolean equivalent(Vector left, Vector right) {
-    if (left == right) {
-      return true;
-    }
-    int leftCardinality = left.size();
-    if (leftCardinality == right.size()) {
-      for (int i = 0; i < leftCardinality; i++) {
-        if (left.getQuick(i) != right.getQuick(i)) {
-          return false;
-        }
-
-      }
-    } else {
-      return false;
+  @Override
+  public int hashCode() {
+    int result = size;
+    Iterator<Element> iter = iterateNonZero();
+    while (iter.hasNext()) {
+      Element ele = iter.next();
+      long v = Double.doubleToLongBits(ele.get());
+      result += ele.index() * (int) (v ^ (v >>> 32));
     }
-    return true;
-  }
+    return result;
+   }
 
   /**
-   * Compare whether two Vector implementations are the same, including the underlying implementation. Two Vectors are
-   * the same if they have the same cardinality, same name and all of their values are the same.
-   *
-   * @param left  The left hand Vector to compare
-   * @param right The right hand Vector
-   * @return true if the two Vectors have the same cardinality and the same values
+   * Determines whether this {@link Vector} represents the same logical vector as another
+   * object. Two {@link Vector}s are equal (regardless of implementation) if the value at
+   * each index is the same, and the cardinalities are the same.
    */
-  public static boolean strictEquivalence(Vector left, Vector right) {
-    if (left == right) {
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
       return true;
     }
-    if (!(left.getClass().equals(right.getClass()))) {
+    if (!(o instanceof Vector)) {
       return false;
     }
-    String leftName = left.getName();
-    String rightName = right.getName();
-    if (leftName != null && rightName != null && !leftName.equals(rightName)) {
-      return false;
-    } else if ((leftName != null && rightName == null)
-        || (rightName != null && leftName == null)) {
+    Vector that = (Vector) o;
+    if (size != that.size()) {
       return false;
     }
-
-    int leftCardinality = left.size();
-    if (leftCardinality == right.size()) {
-      for (int i = 0; i < leftCardinality; i++) {
-        if (left.getQuick(i) != right.getQuick(i)) {
-          return false;
-        }
-
+    for (int index = 0; index < size; index++) {
+      if (getQuick(index) != that.getQuick(index)) {
+        return false;
       }
-    } else {
-      return false;
     }
     return true;
   }
 
   @Override
-  public int hashCode() {
-    int prime = 31;
-    int result = prime + ((name == null) ? 0 : name.hashCode());
-    result = prime * result + size();
-    Iterator<Element> iter = iterateNonZero();
-    while (iter.hasNext()) {
-      Element ele = iter.next();
-      long v = Double.doubleToLongBits(ele.get());
-      result += (ele.index() * (int)(v^(v>>32)));
+  public String toString() {
+    StringBuilder result = new StringBuilder();
+    result.append('{');
+    for (int index = 0; index < size; index++) {
+      double value = getQuick(index);
+      if (value != 0.0) {
+        result.append(index);
+        result.append(':');
+        result.append(value);
+        result.append(',');
+      }
     }
-    return result;
-   }
-
+    if (result.length() > 1) {
+      result.setCharAt(result.length() - 1, '}');
+    }
+    return result.toString();
+  }
 
   public double get(String label) throws IndexException, UnboundLabelException {
     if (bindings == null) {

Modified: lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/DenseVector.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/DenseVector.java?rev=936183&r1=936182&r2=936183&view=diff
==============================================================================
--- lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/DenseVector.java (original)
+++ lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/DenseVector.java Wed Apr 21 07:41:55 2010
@@ -27,14 +27,11 @@ import org.apache.mahout.math.function.P
 /** Implements vector as an array of doubles */
 public class DenseVector extends AbstractVector {
 
-  protected double[] values;
+  private double[] values;
 
   /** For serialization purposes only */
   public DenseVector() {
-  }
-
-  public DenseVector(String name) {
-    super(name);
+    super(0);
   }
 
   /** Construct a new instance using provided values */
@@ -43,6 +40,7 @@ public class DenseVector extends Abstrac
   }
 
   public DenseVector(double[] values, boolean shallowCopy) {
+    super(values.length);
     this.values = shallowCopy ? values : values.clone();
   }
 
@@ -50,18 +48,9 @@ public class DenseVector extends Abstrac
     this(values.values, shallowCopy);
   }
 
-  public DenseVector(String name, double[] values) {
-    super(name);
-    this.values = values.clone();
-  }
-
   /** Construct a new instance of the given cardinality */
   public DenseVector(int cardinality) {
-    this(null, cardinality);
-  }
-
-  public DenseVector(String name, int cardinality) {
-    super(name);
+    super(cardinality);
     this.values = new double[cardinality];
   }
 
@@ -70,11 +59,11 @@ public class DenseVector extends Abstrac
    * @param vector
    */
   public DenseVector(Vector vector) {
-    super(vector.getName());
+    super(vector.size());
     values = new double[vector.size()];
-    Iterator<Vector.Element> it = vector.iterateNonZero();
-    while(it.hasNext()) {
-      Vector.Element e = it.next();
+    Iterator<Element> it = vector.iterateNonZero();
+    while (it.hasNext()) {
+      Element e = it.next();
       values[e.index()] = e.get();
     }
   }
@@ -85,17 +74,23 @@ public class DenseVector extends Abstrac
   }
 
   @Override
-  public int size() {
-    return values.length;
-  }
-
-  @Override
   public DenseVector clone() {
     DenseVector clone = (DenseVector) super.clone();
     clone.values = values.clone();
     return clone;
   }
 
+  @Override
+  public double dotSelf() {
+    double result = 0.0;
+    int max = size();
+    for (int i = 0; i < max; i++) {
+      double value = this.getQuick(i);
+      result += value * value;
+    }
+    return result;
+  }
+
   public double getQuick(int index) {
     return values[index];
   }
@@ -126,13 +121,13 @@ public class DenseVector extends Abstrac
   
   @Override
   public Vector assign(Vector other, BinaryFunction function) {
-    if (other.size() != size()) {
-      throw new CardinalityException();
+    if (size() != other.size()) {
+      throw new CardinalityException(size(), other.size());
     }
     // is there some other way to know if function.apply(0, x) = x for all x?
     if(function instanceof PlusMult) {
-      Iterator<Vector.Element> it = other.iterateNonZero();
-      Vector.Element e;
+      Iterator<Element> it = other.iterateNonZero();
+      Element e;
       while(it.hasNext() && (e = it.next()) != null) {
         values[e.index()] = function.apply(values[e.index()], e.get());
       }
@@ -151,152 +146,35 @@ public class DenseVector extends Abstrac
 
   @Override
   public Vector viewPart(int offset, int length) {
-    if (length > values.length) {
-      throw new CardinalityException();
+    if (offset < 0) {
+      throw new IndexException(offset, size());
     }
-    if (offset < 0 || offset + length > values.length) {
-      throw new IndexException();
+    if (offset + length > size()) {
+      throw new IndexException(offset + length, size());
     }
     return new VectorView(this, offset, length);
   }
 
   /**
    * Returns an iterator that traverses this Vector from 0 to cardinality-1, in that order.
-   *
-   * @see Iterable#iterator
    */
-  public Iterator<Vector.Element> iterateNonZero() {
-    return new NonZeroIterator();
+  public Iterator<Element> iterateNonZero() {
+    return new NonDefaultIterator();
   }
 
-  public Iterator<Vector.Element> iterateAll() {
+  public Iterator<Element> iterator() {
     return new AllIterator();
   }
 
-  private class NonZeroIterator implements Iterator<Vector.Element> {
-
-    private final Element element = new Element(0);
-    private int offset;
-
-    private NonZeroIterator() {
-      goToNext();
-    }
-
-    private void goToNext() {
-      while (offset < values.length && values[offset] == 0) {
-        offset++;
-      }
-    }
-
-    public boolean hasNext() {
-      return offset < values.length;
-    }
-
-    public Vector.Element next() {
-      if (offset >= values.length) {
-        throw new NoSuchElementException();
-      }
-      element.ind = offset;
-      offset++;
-      goToNext();
-      return element;
-    }
-
-    public void remove() {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  private class AllIterator implements Iterator<Vector.Element> {
-
-    private final Element element = new Element(-1);
-
-    public boolean hasNext() {
-      return element.ind + 1 < values.length;
-    }
-
-    public Vector.Element next() {
-      if (!hasNext()) {
-        throw new NoSuchElementException();
-      }
-      element.ind++;
-      return element;
-    }
-
-    public void remove() {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  public class Element implements Vector.Element {
-
-    private int ind;
-
-    public Element(int ind) {
-      this.ind = ind;
-    }
-
-    public double get() {
-      return values[ind];
-    }
-
-    public int index() {
-      return ind;
-    }
-
-    public void set(double value) {
-      lengthSquared = -1.0;
-      values[ind] = value;
-    }
-  }
-
-  public Vector.Element getElement(int index) {
-    return new Element(index);
-  }
-
-  /**
-   * Indicate whether the two objects are the same or not. Two {@link org.apache.mahout.math.Vector}s can be equal
-   * even if the underlying implementation is not equal.
-   *
-   * @param o The object to compare
-   * @return true if the objects have the same cell values and same name, false otherwise.
-   * @see AbstractVector#strictEquivalence(Vector, Vector)
-   * @see AbstractVector#equivalent(Vector, Vector)
-   */
   @Override
   public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (!(o instanceof Vector)) {
-      return false;
+    if (o instanceof DenseVector) {
+      // Speedup for DenseVectors
+      return Arrays.equals(values, ((DenseVector) o).values);
     }
-
-    Vector that = (Vector) o;
-    String thisName = getName();
-    String thatName = that.getName();
-    if (this.size() != that.size()) {
-      return false;
-    }
-    if (thisName != null && thatName != null && !thisName.equals(thatName)) {
-      return false;
-    } else if ((thisName != null && thatName == null)
-        || (thatName != null && thisName == null)) {
-      return false;
-    }
-
-    if (that instanceof DenseVector) {
-      if (!Arrays.equals(values, ((DenseVector) that).values)) {
-        return false;
-      }
-    } else {
-      return equivalent(this, that);
-    }
-
-    return true;
+    return super.equals(o);
   }
 
-
   @Override
   public double getLengthSquared() {
     if (lengthSquared >= 0.0) {
@@ -314,8 +192,8 @@ public class DenseVector extends Abstrac
 
   @Override
   public void addTo(Vector v) {
-    if (v.size() != size()) {
-      throw new CardinalityException();
+    if (size() != v.size()) {
+      throw new CardinalityException(size(), v.size());
     }
     for (int i = 0; i < values.length; i++) {
       v.setQuick(i, values[i] + v.getQuick(i));
@@ -323,13 +201,13 @@ public class DenseVector extends Abstrac
   }
   
   public void addAll(Vector v) {
-    if (v.size() != size()) {
-      throw new CardinalityException();
+    if (size() != v.size()) {
+      throw new CardinalityException(size(), v.size());
     }
     
-    Iterator<org.apache.mahout.math.Vector.Element> iter = v.iterateNonZero();
+    Iterator<Element> iter = v.iterateNonZero();
     while (iter.hasNext()) {
-      org.apache.mahout.math.Vector.Element element = iter.next();
+      Element element = iter.next();
       values[element.index()] += element.get();
     }
   }
@@ -340,7 +218,9 @@ public class DenseVector extends Abstrac
     if (size() != x.size()) {
       throw new CardinalityException(size(), x.size());
     }
-    if(this == x) return dotSelf();
+    if (this == x) {
+      return dotSelf();
+    }
     
     double result = 0;
     if (x instanceof DenseVector) {
@@ -350,12 +230,93 @@ public class DenseVector extends Abstrac
       return result;
     } else {
       // Try to get the speed boost associated fast/normal seq access on x and quick lookup on this
-      Iterator<org.apache.mahout.math.Vector.Element> iter = x.iterateNonZero();
+      Iterator<Element> iter = x.iterateNonZero();
       while (iter.hasNext()) {
-        org.apache.mahout.math.Vector.Element element = iter.next();
+        Element element = iter.next();
         result += element.get() * this.values[element.index()];
       }
       return result;
     }
   }
+
+
+  private final class NonDefaultIterator implements Iterator<Element> {
+
+    private final DenseElement element = new DenseElement();
+    private int index = 0;
+
+    private NonDefaultIterator() {
+      goToNext();
+    }
+
+    private void goToNext() {
+      while (index < size() && values[index] == 0.0) {
+        index++;
+      }
+    }
+
+    public boolean hasNext() {
+      return index < size();
+    }
+
+    public Element next() {
+      if (index >= size()) {
+        throw new NoSuchElementException();
+      } else {
+        element.index = index;
+        index++;
+        goToNext();
+        return element;
+      }
+    }
+
+    public void remove() {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  private final class AllIterator implements Iterator<Element> {
+
+    private final DenseElement element = new DenseElement();
+
+    private AllIterator() {
+      element.index = -1;
+    }
+
+    public boolean hasNext() {
+      return element.index+1 < size();
+    }
+
+    public Element next() {
+      if (element.index+1 >= size()) {
+        throw new NoSuchElementException();
+      } else {
+        element.index++;
+        return element;
+      }
+    }
+
+    public void remove() {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  private final class DenseElement implements Element {
+
+    int index;
+
+    public double get() {
+      return values[index];
+    }
+
+    public int index() {
+      return index;
+    }
+
+    public void set(double value) {
+      lengthSquared = -1;
+      values[index] = value;
+    }
+  }
+
 }

Added: lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/NamedVector.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/NamedVector.java?rev=936183&view=auto
==============================================================================
--- lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/NamedVector.java (added)
+++ lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/NamedVector.java Wed Apr 21 07:41:55 2010
@@ -0,0 +1,244 @@
+/**
+ * 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.mahout.math;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.mahout.math.function.BinaryFunction;
+import org.apache.mahout.math.function.UnaryFunction;
+
+public class NamedVector implements Vector {
+
+  private Vector delegate;
+  private String name;
+
+  public NamedVector() {
+  }
+
+  public NamedVector(NamedVector other) {
+    this.delegate = other.getDelegate();
+    this.name = other.getName();
+  }
+
+  public NamedVector(Vector delegate, String name) {
+    if (delegate == null) {
+      throw new IllegalArgumentException();
+    }
+    this.delegate = delegate;
+    this.name = name;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public Vector getDelegate() {
+    return delegate;
+  }
+
+  public int hashCode() {
+    return delegate.hashCode();
+  }
+
+  /**
+   * To not break transitivity with other {@link Vector}s, this does not compare name.
+   */
+  public boolean equals(Object other) {
+    return delegate.equals(other);
+  }
+
+  @Override
+  public Vector clone() {
+    return new NamedVector(delegate.clone(), name);
+  }
+
+
+  public String asFormatString() {
+    return delegate.asFormatString();
+  }
+
+  public Vector assign(double value) {
+    return delegate.assign(value);
+  }
+
+  public Vector assign(double[] values) {
+    return delegate.assign(values);
+  }
+
+  public Vector assign(Vector other) {
+    return delegate.assign(other);
+  }
+
+  public Vector assign(UnaryFunction function) {
+    return delegate.assign(function);
+  }
+
+  public Vector assign(Vector other, BinaryFunction function) {
+    return delegate.assign(other, function);
+  }
+
+  public Vector assign(BinaryFunction f, double y) {
+    return delegate.assign(f, y);
+  }
+
+  public int size() {
+    return delegate.size();
+  }
+
+  public Iterator<Element> iterator() {
+    return delegate.iterator();
+  }
+
+  public Iterator<Element> iterateNonZero() {
+    return delegate.iterateNonZero();
+  }
+
+  public double get(String label) throws IndexException, UnboundLabelException {
+    return delegate.get(label);
+  }
+
+  public Map<String, Integer> getLabelBindings() {
+    return delegate.getLabelBindings();
+  }
+
+  public Element getElement(int index) {
+    return delegate.getElement(index);
+  }
+
+  public Vector divide(double x) {
+    return delegate.divide(x);
+  }
+
+  public double dot(Vector x) {
+    return delegate.dot(x);
+  }
+
+  public double get(int index) {
+    return delegate.get(index);
+  }
+
+  public double getQuick(int index) {
+    return delegate.getQuick(index);
+  }
+
+  public Vector like() {
+    return delegate.like();
+  }
+
+  public Vector like(int cardinality) {
+    return delegate.like(cardinality);
+  }
+
+  public Vector minus(Vector x) {
+    return delegate.minus(x);
+  }
+
+  public Vector normalize() {
+    return delegate.normalize();
+  }
+
+  public Vector normalize(double power) {
+    return delegate.normalize(power);
+  }
+
+  public double norm(double power) {
+    return delegate.norm(power);
+  }
+
+  public double maxValue() {
+    return delegate.maxValue();
+  }
+
+  public int maxValueIndex() {
+    return delegate.maxValueIndex();
+  }
+
+  public Vector plus(double x) {
+    return delegate.plus(x);
+  }
+
+  public Vector plus(Vector x) {
+    return delegate.plus(x);
+  }
+
+  public void set(String label, double value) throws IndexException, UnboundLabelException {
+    delegate.set(label, value);
+  }
+
+  public void set(String label, int index, double value) throws IndexException {
+    delegate.set(label, index, value);
+  }
+
+  public void setLabelBindings(Map<String, Integer> bindings) {
+    delegate.setLabelBindings(bindings);
+  }
+
+  public void set(int index, double value) {
+    delegate.set(index, value);
+  }
+
+  public void setQuick(int index, double value) {
+    delegate.setQuick(index, value);
+  }
+
+  public int getNumNondefaultElements() {
+    return delegate.getNumNondefaultElements();
+  }
+
+  public Vector times(double x) {
+    return delegate.times(x);
+  }
+
+  public Vector times(Vector x) {
+    return delegate.times(x);
+  }
+
+  public Vector viewPart(int offset, int length) {
+    return delegate.viewPart(offset, length);
+  }
+
+  public double zSum() {
+    return delegate.zSum();
+  }
+
+  public Matrix cross(Vector other) {
+    return delegate.cross(other);
+  }
+
+  public double aggregate(BinaryFunction aggregator, UnaryFunction map) {
+    return delegate.aggregate(aggregator, map);
+  }
+
+  public double aggregate(Vector other, BinaryFunction aggregator, BinaryFunction combiner) {
+    return delegate.aggregate(other, aggregator, combiner);
+  }
+
+  public double getLengthSquared() {
+    return delegate.getLengthSquared();
+  }
+
+  public double getDistanceSquared(Vector v) {
+    return delegate.getDistanceSquared(v);
+  }
+
+  public void addTo(Vector v) {
+    delegate.addTo(v);
+  }
+
+}

Modified: lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/OrderedIntDoubleMapping.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/OrderedIntDoubleMapping.java?rev=936183&r1=936182&r2=936183&view=diff
==============================================================================
--- lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/OrderedIntDoubleMapping.java (original)
+++ lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/OrderedIntDoubleMapping.java Wed Apr 21 07:41:55 2010
@@ -21,7 +21,7 @@ import java.io.Serializable;
 
 final class OrderedIntDoubleMapping implements Serializable, Cloneable {
 
-  private static final double DEFAULT_VALUE = 0.0;
+  static final double DEFAULT_VALUE = 0.0;
 
   private int[] indices;
   private double[] values;

Modified: lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/RandomAccessSparseVector.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/RandomAccessSparseVector.java?rev=936183&r1=936182&r2=936183&view=diff
==============================================================================
--- lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/RandomAccessSparseVector.java (original)
+++ lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/RandomAccessSparseVector.java Wed Apr 21 07:41:55 2010
@@ -29,42 +29,39 @@ import org.apache.mahout.math.map.OpenIn
 public class RandomAccessSparseVector extends AbstractVector {
 
   private static final int INITIAL_SIZE = 11;
-  protected OpenIntDoubleHashMap values;
+
+  private OpenIntDoubleHashMap values;
 
   /** For serialization purposes only. */
   public RandomAccessSparseVector() {
+    super(0);
   }
 
   public RandomAccessSparseVector(int cardinality) {
-    this(null, cardinality, Math.min(cardinality, INITIAL_SIZE)); // arbitrary estimate of
-    // 'sparseness'
+    this(cardinality, Math.min(cardinality, INITIAL_SIZE)); // arbitrary estimate of 'sparseness'
   }
 
   public RandomAccessSparseVector(int cardinality, int size) {
-    this(null, cardinality, size);
-  }
-
-  public RandomAccessSparseVector(String name, int cardinality) {
-    this(name, cardinality, Math.min(cardinality, INITIAL_SIZE)); // arbitrary estimate of
-    // 'sparseness'
-  }
-
-  public RandomAccessSparseVector(String name, int cardinality, int size) {
-    super(name, cardinality);
+    super(cardinality);
     values = new OpenIntDoubleHashMap(size);
   }
 
   public RandomAccessSparseVector(Vector other) {
-    this(other.getName(), other.size(), other.getNumNondefaultElements());
-    Iterator<Vector.Element> it = other.iterateNonZero();
-    Vector.Element e;
+    this(other.size(), other.getNumNondefaultElements());
+    Iterator<Element> it = other.iterateNonZero();
+    Element e;
     while(it.hasNext() && (e = it.next()) != null) {
       values.put(e.index(), e.get());
     }
   }
 
+  RandomAccessSparseVector(int cardinality, OpenIntDoubleHashMap values) {
+    super(cardinality);
+    this.values = values;
+  }
+
   public RandomAccessSparseVector(RandomAccessSparseVector other, boolean shallowCopy) {
-    super(other.getName(), other.size());
+    super(other.size());
     values = shallowCopy ? other.values : (OpenIntDoubleHashMap)other.values.clone() ;
   }
 
@@ -83,12 +80,12 @@ public class RandomAccessSparseVector ex
 
   @Override
   public Vector assign(Vector other) {
-    if (other.size() != size()) {
-      throw new CardinalityException();
+    if (size() != other.size()) {
+      throw new CardinalityException(size(), other.size());
     }
     values.clear();
-    Iterator<Vector.Element> it = other.iterateNonZero();
-    Vector.Element e;
+    Iterator<Element> it = other.iterateNonZero();
+    Element e;
     while(it.hasNext() && (e = it.next()) != null) {
       setQuick(e.index(), e.get());
     }
@@ -128,65 +125,86 @@ public class RandomAccessSparseVector ex
    * NOTE: this implementation reuses the Vector.Element instance for each call of next(). If you need to preserve the
    * instance, you need to make a copy of it
    *
-   * @return an {@link NonZeroIterator} over the Elements.
+   * @return an {@link Iterator} over the Elements.
    * @see #getElement(int)
    */
-  public java.util.Iterator<Vector.Element> iterateNonZero() {
-    return new NonZeroIterator(false);
+  public Iterator<Element> iterateNonZero() {
+    return new NonDefaultIterator();
   }
   
-  public Iterator<Vector.Element> iterateAll() {
+  public Iterator<Element> iterator() {
     return new AllIterator();
   }
 
-  /**
-   * Indicate whether the two objects are the same or not. Two {@link org.apache.mahout.math.Vector}s can be equal
-   * even if the underlying implementation is not equal.
-   *
-   * @param o The object to compare
-   * @return true if the objects have the same cell values and same name, false otherwise. <p/> * @see
-   *         AbstractVector#strictEquivalence(Vector, Vector)
-   * @see AbstractVector#equivalent(Vector, Vector)
-   */
   @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (!(o instanceof Vector)) {
-      return false;
+  public void addTo(Vector v) {
+    if (v.size() != size()) {
+      throw new CardinalityException(size(), v.size());
     }
+    values.forEachPair(new AddToVector(v));
+  }
 
-    Vector that = (Vector) o;
-    String thisName = getName();
-    String thatName = that.getName();
-    if (this.size() != that.size()) {
-      return false;
+  @Override
+  public double dot(Vector x) {
+    if (size() != x.size()) {
+      throw new CardinalityException(size(), x.size());
     }
-    if (thisName != null && thatName != null && !thisName.equals(thatName)) {
-      return false;
-    } else if ((thisName != null && thatName == null)
-        || (thatName != null && thisName == null)) {
-      return false;
+    if (this == x) {
+      return dotSelf();
+    }
+    
+    double result = 0;
+    if (x instanceof SequentialAccessSparseVector) {
+      Iterator<Element> iter = x.iterateNonZero();
+      while (iter.hasNext()) {
+        Element element = iter.next();
+        result += element.get() * getQuick(element.index());
+      }
+      return result;
+    } else { 
+      Iterator<Element> iter = iterateNonZero();
+      while (iter.hasNext()) {
+        Element element = iter.next();
+        result += element.get() * x.getQuick(element.index());
+      }
+      return result;
     }
+  }
+
 
-    return equivalent(this, that);
+  private static class AddToVector implements IntDoubleProcedure {
+    private final Vector v;
+    private AddToVector(Vector v) {
+      this.v = v;
+    }
+    public boolean apply(int key, double value) {
+      v.set(key, value + v.get(key));
+      return true;
+    }
   }
 
-  private class AllIterator implements java.util.Iterator<Vector.Element> {
-    private int offset = 0;
-    private final Element element = new Element(0);
+  private final class NonDefaultIterator implements Iterator<Element> {
+
+    private final RandomAccessElement element = new RandomAccessElement();
+    private final IntArrayList indices = new IntArrayList();
+    private int offset;
+
+    private NonDefaultIterator() {
+      values.keys(indices);
+    }
 
     public boolean hasNext() {
-      return offset < size();
+      return offset < indices.size();
     }
 
-    public Vector.Element next() {
-      if (offset >= size()) {
+    public Element next() {
+      if (offset >= indices.size()) {
         throw new NoSuchElementException();
+      } else {
+        element.index = indices.get(offset);
+        offset++;
+        return element;
       }
-      element.ind = offset++;
-      return element;
     }
 
     public void remove() {
@@ -194,29 +212,25 @@ public class RandomAccessSparseVector ex
     }
   }
 
+  private final class AllIterator implements Iterator<Element> {
 
-  private class NonZeroIterator implements java.util.Iterator<Vector.Element> {
-    private int offset = 0;
-    private final Element element = new Element(0);
+    private final RandomAccessElement element = new RandomAccessElement();
 
-    private final IntArrayList intArrList =  values.keys();
-    
-    private NonZeroIterator(boolean sorted) {
-      if (sorted) {
-        intArrList.sort();
-      }      
+    private AllIterator() {
+      element.index = -1;
     }
 
     public boolean hasNext() {
-      return offset < intArrList.size();
+      return element.index+1 < size();
     }
 
     public Element next() {
-      if (offset < intArrList.size()) {
-        element.ind = intArrList.get(offset++);
+      if (element.index+1 >= size()) {
+        throw new NoSuchElementException();
+      } else {
+        element.index++;
         return element;
       }
-      throw new NoSuchElementException();
     }
 
     public void remove() {
@@ -224,73 +238,21 @@ public class RandomAccessSparseVector ex
     }
   }
 
-  public Vector.Element getElement(int index) {
-    return new Element(index);
-  }
-
-  public class Element implements Vector.Element {
-    private int ind;
+  private final class RandomAccessElement implements Element {
 
-    public Element(int ind) {
-      this.ind = ind;
-    }
+    int index;
 
     public double get() {
-      return values.get(ind);
+      return values.get(index);
     }
 
     public int index() {
-      return ind;
+      return index;
     }
 
     public void set(double value) {
-      lengthSquared = -1.0;
-      values.put(ind, value);
-    }
-  }
-
-  private static class AddToVector implements IntDoubleProcedure {
-    private final Vector v;
-
-    private AddToVector(Vector v) {
-      this.v = v;
-    }
-
-    public boolean apply(int key, double value) {
-      v.set(key, value + v.get(key));
-      return true;
-    }
-  }
-
-  @Override
-  public void addTo(Vector v) {
-    if (v.size() != size()) {
-      throw new CardinalityException(size(), v.size());
-    }
-    values.forEachPair(new AddToVector(v));
-  }
-  @Override
-  public double dot(Vector x) {
-    if (size() != x.size()) {
-      throw new CardinalityException(size(), x.size());
-    }
-    if(this == x) return dotSelf();
-    
-    double result = 0;
-    if (x instanceof SequentialAccessSparseVector) {
-      Iterator<org.apache.mahout.math.Vector.Element> iter = x.iterateNonZero();
-      while (iter.hasNext()) {
-        org.apache.mahout.math.Vector.Element element = iter.next();
-        result += element.get() * getQuick(element.index());
-      }
-      return result;
-    } else { 
-      Iterator<org.apache.mahout.math.Vector.Element> iter = iterateNonZero();
-      while (iter.hasNext()) {
-        org.apache.mahout.math.Vector.Element element = iter.next();
-        result += element.get() * x.getQuick(element.index());
-      }
-      return result;
+      lengthSquared = -1;
+      values.put(index, value);
     }
   }
   

Modified: lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/SequentialAccessSparseVector.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/SequentialAccessSparseVector.java?rev=936183&r1=936182&r2=936183&view=diff
==============================================================================
--- lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/SequentialAccessSparseVector.java (original)
+++ lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/SequentialAccessSparseVector.java Wed Apr 21 07:41:55 2010
@@ -20,7 +20,7 @@ package org.apache.mahout.math;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
-import org.apache.mahout.math.Vector.Element;
+import org.apache.mahout.math.function.Functions;
 
 /**
  * <p>
@@ -45,35 +45,24 @@ import org.apache.mahout.math.Vector.Ele
  */
 public class SequentialAccessSparseVector extends AbstractVector {
 
-  protected OrderedIntDoubleMapping values;
-
+  private OrderedIntDoubleMapping values;
 
   /** For serialization purposes only. */
   public SequentialAccessSparseVector() {
-    super(null, 0);
+    super(0);
   }
 
-  public SequentialAccessSparseVector(int cardinality, int size) {
-    this(null, cardinality, size);
+  public SequentialAccessSparseVector(int cardinality) {
+    this(cardinality, cardinality / 8); // arbitrary estimate of 'sparseness'
   }
 
-  public SequentialAccessSparseVector(String name, int cardinality, int size) {
-    super(name, cardinality);
+  public SequentialAccessSparseVector(int cardinality, int size) {
+    super(cardinality);
     values = new OrderedIntDoubleMapping(size);
   }
 
-  public SequentialAccessSparseVector(String name, int cardinality) {
-    this(name, cardinality, cardinality / 8); // arbitrary estimate of
-    // 'sparseness'
-  }
-
-  public SequentialAccessSparseVector(int cardinality) {
-    this(null, cardinality, cardinality / 8); // arbitrary estimate of
-    // 'sparseness'
-  }
-
   public SequentialAccessSparseVector(Vector other) {
-    this(other.getName(), other.size(), other.getNumNondefaultElements());
+    this(other.size(), other.getNumNondefaultElements());
     Iterator<Element> it = other.iterateNonZero();
     Element e;
     while(it.hasNext() && (e = it.next()) != null) {
@@ -82,15 +71,20 @@ public class SequentialAccessSparseVecto
   }
 
   public SequentialAccessSparseVector(SequentialAccessSparseVector other, boolean shallowCopy) {
-    super(other.getName(), other.size());
+    super(other.size());
     values = shallowCopy ? other.values : other.values.clone();
   }
 
   public SequentialAccessSparseVector(SequentialAccessSparseVector other) {
-    this(other.getName(), other.size(), other.getNumNondefaultElements());
+    this(other.size(), other.getNumNondefaultElements());
     values = other.values.clone();
   }
 
+  SequentialAccessSparseVector(int cardinality, OrderedIntDoubleMapping values) {
+    super(cardinality);
+    this.values = values;
+  }
+
   @Override
   protected Matrix matrixLike(int rows, int columns) {
     int[] cardinality = {rows, columns};
@@ -134,77 +128,96 @@ public class SequentialAccessSparseVecto
   }
 
   public Iterator<Element> iterateNonZero() {
-    return new IntDoublePairIterator(this);
+    return new NonDefaultIterator();
   }
 
-  public Iterator<Element> iterateAll() {
-    return new IntDoublePairIterator(this, size());
+  public Iterator<Element> iterator() {
+    return new AllIterator();
   }
-
-  /**
-   * Indicate whether the two objects are the same or not. Two {@link org.apache.mahout.math.Vector}s can be equal
-   * even if the underlying implementation is not equal.
-   *
-   * @param o The object to compare
-   * @return true if the objects have the same cell values and same name, false otherwise. <p/> * @see
-   *         AbstractVector#strictEquivalence(Vector, Vector)
-   * @see AbstractVector#equivalent(Vector, Vector)
-   */
+    
   @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
+  public double dot(Vector x) {
+    if (size() != x.size()) {
+      throw new CardinalityException(size(), x.size());
     }
-    if (!(o instanceof Vector)) {
-      return false;
+    if (this == x) {
+      return dotSelf();
     }
+    
+    double result = 0;
+    if (x instanceof SequentialAccessSparseVector) {
+      // For sparse SeqAccVectors. do dot product without lookup in a linear fashion
+      Iterator<Element> myIter = iterateNonZero();
+      Iterator<Element> otherIter = x.iterateNonZero();
+      Element myCurrent = null;
+      Element otherCurrent = null;
+      while (myIter.hasNext() && otherIter.hasNext()) {
+        if (myCurrent == null) {
+          myCurrent = myIter.next();
+        }
+        if (otherCurrent == null) {
+          otherCurrent = otherIter.next();
+        }
 
-    Vector that = (Vector) o;
-    String thisName = getName();
-    String thatName = that.getName();
-    if (this.size() != that.size()) {
-      return false;
-    }
-    if (thisName != null && thatName != null && !thisName.equals(thatName)) {
-      return false;
-    } else if ((thisName != null && thatName == null)
-        || (thatName != null && thisName == null)) {
-      return false;
+        int myIndex = myCurrent.index();
+        int otherIndex = otherCurrent.index();
+        
+        if (myIndex < otherIndex) {
+          // due to the sparseness skipping occurs more hence checked before equality
+          myCurrent = null;
+        } else if (myIndex > otherIndex){
+          otherCurrent = null;
+        } else { // both are equal 
+          result += myCurrent.get() * otherCurrent.get();
+          myCurrent = null;
+          otherCurrent = null;
+        } 
+      }
+      return result;
+    } else { // seq.rand. seq.dense
+      Iterator<Element> iter = iterateNonZero();
+      while (iter.hasNext()) {
+        Element element = iter.next();
+        result += element.get() * x.getQuick(element.index());
+      }
+      return result;
     }
+  }
 
-    if (that instanceof SequentialAccessSparseVector) {
-      return (values == null ? ((SequentialAccessSparseVector) that).values == null : values
-          .equals(((SequentialAccessSparseVector) that).values));
-    } else {
-      return equivalent(this, that);
+  @Override
+  public Vector minus(Vector that) {
+    if (size() != that.size()) {
+      throw new CardinalityException(size(), that.size());
     }
-
+    // Here we compute "that - this" since it's not fast to randomly access "this"
+    // and then invert at the end
+    Vector result = that.clone();
+    Iterator<Element> iter = this.iterateNonZero();
+    while (iter.hasNext()) {
+      Element thisElement = iter.next();
+      int index = thisElement.index();
+      result.setQuick(index, that.getQuick(index) - thisElement.get());
+    }
+    result.assign(Functions.negate);
+    return result;
   }
 
-  private static final class IntDoublePairIterator implements java.util.Iterator<Element> {
-    private int offset = 0;
-    private final AbstractElement element;
-    private final int maxOffset;
 
-    IntDoublePairIterator(SequentialAccessSparseVector v) {
-      element = new SparseElement(offset, v);
-      maxOffset = v.values.getNumMappings();
-    }
-    IntDoublePairIterator(SequentialAccessSparseVector v, int cardinality) {
-      element = new DenseElement(offset, v);
-      maxOffset = cardinality;
-    }
+  private final class NonDefaultIterator implements Iterator<Element> {
+
+    private final NonDefaultElement element = new NonDefaultElement();
 
     public boolean hasNext() {
-      return offset < maxOffset;
+      return element.getNextOffset() < values.getNumMappings();
     }
 
     public Element next() {
-      if (offset >= maxOffset) {
+      if (element.getNextOffset() >= values.getNumMappings()) {
         throw new NoSuchElementException();
+      } else {
+        element.advanceOffset();
+        return element;
       }
-      element.offset = offset++;
-      return element;
     }
 
     public void remove() {
@@ -212,119 +225,88 @@ public class SequentialAccessSparseVecto
     }
   }
 
-  public Element getElement(int index) {
-    return new DenseElement(index, this);
-  }
+  private final class AllIterator implements Iterator<Element> {
+
+    private final AllElement element = new AllElement();
 
+    public boolean hasNext() {
+      return element.getNextIndex() < values.getIndices()[values.getNumMappings()-1];
+    }
 
-  private abstract static class AbstractElement implements Element {
-    int offset;
-    final OrderedIntDoubleMapping mapping;
-    int[] indices;
-    double[] values;
+    public Element next() {
+      if (element.getNextIndex() >= values.getIndices()[values.getNumMappings()-1]) {
+        throw new NoSuchElementException();
+      } else {
+        element.advanceIndex();
+        return element;
+      }
+    }
 
-    AbstractElement(int ind, SequentialAccessSparseVector v) {
-      offset = ind;
-      mapping = v.values;
-      values = mapping.getValues();
-      indices = mapping.getIndices();
+    public void remove() {
+      throw new UnsupportedOperationException();
     }
   }
 
-  private static final class DenseElement extends AbstractElement {
+  private final class NonDefaultElement implements Element {
 
-    private int index;
-    private final SequentialAccessSparseVector v;
+    private int offset = -1;
 
-    DenseElement(int ind, SequentialAccessSparseVector v) {
-      super(ind, v);
-      this.v = v;
-      index = ind;
+    void advanceOffset() {
+      offset++;
+    }
+
+    int getNextOffset() {
+      return offset + 1;
     }
 
     public double get() {
-      if(index >= indices.length) return 0.0;
-      int cur = indices[index];
-      while(cur < offset && index < indices.length - 1) cur = indices[++index];
-      if(cur == offset) return values[index];
-      return 0.0;
+      return values.getValues()[offset];
     }
 
     public int index() {
-      return offset;
+      return values.getIndices()[offset];
     }
 
     public void set(double value) {
-      v.set(offset, value);
-      // indices and values may have changed, must re-grab them.
-      indices = mapping.getIndices();
-      values = mapping.getValues();
+      lengthSquared = -1;      
+      values.getValues()[offset] = value;
     }
   }
 
-  private static final class SparseElement extends AbstractElement {
+  private final class AllElement implements Element {
+
+    private int index = -1;
+    private int nextOffset = 0;
 
-    private final SequentialAccessSparseVector v;
+    void advanceIndex() {
+      index++;
+      if (index > values.getIndices()[nextOffset]) {
+        nextOffset++;
+      }
+    }
 
-    SparseElement(int ind, SequentialAccessSparseVector v) {
-      super(ind, v);
-      this.v = v;
+    int getNextIndex() {
+      return index + 1;
     }
 
     public double get() {
-      return values[offset];
+      if (index == values.getIndices()[nextOffset]) {
+        return values.getValues()[nextOffset];
+      }
+      return OrderedIntDoubleMapping.DEFAULT_VALUE;
     }
 
     public int index() {
-      return indices[offset];
+      return index;
     }
 
     public void set(double value) {
-      v.lengthSquared = -1;
-      values[offset] = value;
-    }
-  }
-  
-  @Override
-  public double dot(Vector x) {
-    if (size() != x.size()) {
-      throw new CardinalityException(size(), x.size());
-    }
-    if(this == x) return dotSelf();
-    
-    double result = 0;
-    if (x instanceof SequentialAccessSparseVector) {
-      // For sparse SeqAccVectors. do dot product without lookup in a linear fashion
-      Iterator<Element> myIter = iterateNonZero();
-      Iterator<Element> otherIter = x.iterateNonZero();
-      Element myCurrent = null;
-      Element otherCurrent = null;
-      while (myIter.hasNext() && otherIter.hasNext()) {
-        if (myCurrent == null) myCurrent = myIter.next();
-        if (otherCurrent == null) otherCurrent = otherIter.next();
-        
-        int myIndex = myCurrent.index();
-        int otherIndex = otherCurrent.index();
-        
-        if (myIndex < otherIndex) {
-          // due to the sparseness skipping occurs more hence checked before equality
-          myCurrent = null;
-        } else if (myIndex > otherIndex){
-          otherCurrent = null;
-        } else { // both are equal 
-          result += myCurrent.get() * otherCurrent.get();
-          myCurrent = null;
-          otherCurrent = null;
-        } 
+      if (index == values.getIndices()[nextOffset]) {
+        values.getValues()[nextOffset] = value;
+      } else {
+        // Yes, this works; the offset into indices of the new value's index will still be nextOffset
+        values.set(index, value);
       }
-      return result;
-    } else { // seq.rand. seq.dense
-      Iterator<Element> iter = iterateNonZero();
-      while (iter.hasNext()) {
-        Element element = iter.next();
-        result += element.get() * x.getQuick(element.index());
-      }
-      return result;
     }
   }
   

Modified: lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/Vector.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/Vector.java?rev=936183&r1=936182&r2=936183&view=diff
==============================================================================
--- lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/Vector.java (original)
+++ lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/Vector.java Wed Apr 21 07:41:55 2010
@@ -29,22 +29,7 @@ import java.util.Map;
  * constructor that takes an int for cardinality and a no-arg constructor that can be used for marshalling the Writable
  * instance <p/> NOTE: Implementations may choose to reuse the Vector.Element in the Iterable methods
  */
-public interface Vector extends Cloneable {
-
-  /**
-   * Vectors may have a name associated with them, which makes them easy to identify
-   *
-   * @return The name, or null if one has not been set
-   */
-  String getName();
-
-  /**
-   * Set a name for this vector.  Need not be unique in a set of Vectors, but probably is more useful if it is. In other
-   * words, Mahout does not check for uniqueness.
-   *
-   * @param name The name
-   */
-  void setName(String name);
+public interface Vector extends Cloneable, Iterable<Vector.Element> {
 
   /** @return a formatted String suitable for output */
   String asFormatString();
@@ -67,7 +52,7 @@ public interface Vector extends Cloneabl
   Vector assign(double[] values);
 
   /**
-   * Assign the other matrix values to the receiver
+   * Assign the other vector values to the receiver
    *
    * @param other a Vector
    * @return the modified receiver
@@ -122,7 +107,7 @@ public interface Vector extends Cloneabl
    *
    * @return An {@link Iterator} over all elements
    */
-  Iterator<Element> iterateAll();
+  Iterator<Element> iterator();
 
   /**
    * Iterates over all non-zero elements. <p/> NOTE: Implementations may choose to reuse the Element returned for
@@ -175,7 +160,7 @@ public interface Vector extends Cloneabl
   }
 
   /**
-   * Return a new matrix containing the values of the recipient divided by the argument
+   * Return a new vector containing the values of the recipient divided by the argument
    *
    * @param x a double value
    * @return a new Vector
@@ -209,14 +194,14 @@ public interface Vector extends Cloneabl
   double getQuick(int index);
 
   /**
-   * Return an empty matrix of the same underlying class as the receiver
+   * Return an empty vector of the same underlying class as the receiver
    *
    * @return a Vector
    */
   Vector like();
 
   /**
-   * Return an empty matrix of the same underlying class as the receiver and of the given cardinality
+   * Return an empty vector of the same underlying class as the receiver and of the given cardinality
    *
    * @param cardinality an int specifying the desired cardinality
    * @return a Vector
@@ -224,7 +209,7 @@ public interface Vector extends Cloneabl
   Vector like(int cardinality);
 
   /**
-   * Return a new matrix containing the element by element difference of the recipient and the argument
+   * Return a new vector containing the element by element difference of the recipient and the argument
    *
    * @param x a Vector
    * @return a new Vector
@@ -233,7 +218,7 @@ public interface Vector extends Cloneabl
   Vector minus(Vector x);
 
   /**
-   * Return a new matrix containing the normalized (L_2 norm) values of the recipient
+   * Return a new vector containing the normalized (L_2 norm) values of the recipient
    *
    * @return a new Vector
    */
@@ -269,7 +254,7 @@ public interface Vector extends Cloneabl
   int maxValueIndex();
 
   /**
-   * Return a new matrix containing the sum of each value of the recipient and the argument
+   * Return a new vector containing the sum of each value of the recipient and the argument
    *
    * @param x a double
    * @return a new Vector
@@ -277,7 +262,7 @@ public interface Vector extends Cloneabl
   Vector plus(double x);
 
   /**
-   * Return a new matrix containing the element by element sum of the recipient and the argument
+   * Return a new vector containing the element by element sum of the recipient and the argument
    *
    * @param x a Vector
    * @return a new Vector
@@ -335,7 +320,7 @@ public interface Vector extends Cloneabl
   int getNumNondefaultElements();
 
   /**
-   * Return a new matrix containing the product of each value of the recipient and the argument
+   * Return a new vector containing the product of each value of the recipient and the argument
    *
    * @param x a double argument
    * @return a new Vector
@@ -343,7 +328,7 @@ public interface Vector extends Cloneabl
   Vector times(double x);
 
   /**
-   * Return a new matrix containing the element-wise product of the recipient and the argument
+   * Return a new vector containing the element-wise product of the recipient and the argument
    *
    * @param x a Vector argument
    * @return a new Vector
@@ -352,7 +337,7 @@ public interface Vector extends Cloneabl
   Vector times(Vector x);
 
   /**
-   * Return a new matrix containing the subset of the recipient
+   * Return a new vector containing the subset of the recipient
    *
    * @param offset an int offset into the receiver
    * @param length the cardinality of the desired result

Modified: lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/VectorView.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/VectorView.java?rev=936183&r1=936182&r2=936183&view=diff
==============================================================================
--- lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/VectorView.java (original)
+++ lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/VectorView.java Wed Apr 21 07:41:55 2010
@@ -28,17 +28,15 @@ public class VectorView extends Abstract
   // the offset into the Vector
   private int offset;
 
-  // the cardinality of the view
-  private int cardinality;
-
   /** For serialization purposes only */
   public VectorView() {
+    super(0);
   }
 
   public VectorView(Vector vector, int offset, int cardinality) {
+    super(cardinality);
     this.vector = vector;
     this.offset = offset;
-    this.cardinality = cardinality;
   }
 
   @Override
@@ -47,11 +45,6 @@ public class VectorView extends Abstract
   }
 
   @Override
-  public int size() {
-    return cardinality;
-  }
-
-  @Override
   public Vector clone() {
     VectorView clone = (VectorView) super.clone();
     clone.vector = vector.clone();
@@ -75,41 +68,41 @@ public class VectorView extends Abstract
   }
 
   public int getNumNondefaultElements() {
-    return cardinality;
+    return size();
   }
 
   @Override
   public Vector viewPart(int offset, int length) {
-    if (length > cardinality) {
-      throw new CardinalityException();
+    if (offset < 0) {
+      throw new IndexException(offset, size());
     }
-    if (offset < 0 || offset + length > cardinality) {
-      throw new IndexException();
+    if (offset + length > size()) {
+      throw new IndexException(offset + length, size());
     }
     return new VectorView(vector, offset + this.offset, length);
   }
 
   /** @return true if index is a valid index in the underlying Vector */
   private boolean isInView(int index) {
-    return index >= offset && index < offset + cardinality;
+    return index >= offset && index < offset + size();
   }
 
-  public Iterator<Vector.Element> iterateNonZero() {
+  public Iterator<Element> iterateNonZero() {
     return new NonZeroIterator();
   }
 
-  public Iterator<Vector.Element> iterateAll() {
+  public Iterator<Element> iterator() {
     return new AllIterator();
   }
 
-  public class NonZeroIterator implements Iterator<Vector.Element> {
+  public class NonZeroIterator implements Iterator<Element> {
 
-    private final Iterator<Vector.Element> it;
+    private final Iterator<Element> it;
 
-    private Vector.Element el;
+    private Element el;
 
     private NonZeroIterator() {
-      it = vector.iterateAll();
+      it = vector.iterator();
       buffer();
     }
 
@@ -117,8 +110,8 @@ public class VectorView extends Abstract
       while (it.hasNext()) {
         el = it.next();
         if (isInView(el.index()) && el.get() != 0) {
-          final Vector.Element decorated = vector.getElement(el.index());
-          el = new Vector.Element() {
+          final Element decorated = vector.getElement(el.index());
+          el = new Element() {
             public double get() {
               return decorated.get();
             }
@@ -137,11 +130,11 @@ public class VectorView extends Abstract
       el = null; // No element was found
     }
 
-    public Vector.Element next() {
+    public Element next() {
       if (!hasNext()) {
         throw new NoSuchElementException();
       }
-      Vector.Element buffer = el;
+      Element buffer = el;
       buffer();
       return buffer;
     }
@@ -156,14 +149,14 @@ public class VectorView extends Abstract
     }
   }
 
-  public class AllIterator implements Iterator<Vector.Element> {
+  public class AllIterator implements Iterator<Element> {
 
-    private final Iterator<Vector.Element> it;
+    private final Iterator<Element> it;
 
-    private Vector.Element el;
+    private Element el;
 
     private AllIterator() {
-      it = vector.iterateAll();
+      it = vector.iterator();
       buffer();
     }
 
@@ -171,8 +164,8 @@ public class VectorView extends Abstract
       while (it.hasNext()) {
         el = it.next();
         if (isInView(el.index())) {
-          final Vector.Element decorated = vector.getElement(el.index());
-          el = new Vector.Element() {
+          final Element decorated = vector.getElement(el.index());
+          el = new Element() {
             public double get() {
               return decorated.get();
             }
@@ -191,11 +184,11 @@ public class VectorView extends Abstract
       el = null; // No element was found
     }
 
-    public Vector.Element next() {
+    public Element next() {
       if (!hasNext()) {
         throw new NoSuchElementException();
       }
-      Vector.Element buffer = el;
+      Element buffer = el;
       buffer();
       return buffer;
     }
@@ -214,7 +207,7 @@ public class VectorView extends Abstract
   @Override
   public double dot(Vector x) {
     if (size() != x.size()) {
-      throw new CardinalityException();
+      throw new CardinalityException(size(), x.size());
     }
     double result = 0;
     for (int i = 0; i < size(); i++) {
@@ -223,49 +216,11 @@ public class VectorView extends Abstract
     return result;
   }
 
-  public Vector.Element getElement(int index) {
-    return new Element(index);
-  }
-
-  public class Element implements Vector.Element {
-
-    private final int ind;
-
-    private Element(int ind) {
-      this.ind = ind;
-    }
-
-    public double get() {
-      return getQuick(ind);
-    }
-
-    public int index() {
-      return ind;
-    }
-
-    public void set(double value) {
-      setQuick(ind, value);
-    }
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    return this == o || (o instanceof Vector && equivalent(this, (Vector) o));
-
-  }
-
-  @Override
-  public int hashCode() {
-    int result = vector.hashCode();
-    result = 31 * result + offset;
-    result = 31 * result + cardinality;
-    return result;
-  }
-
   @Override
   public double getLengthSquared() {
     double result = 0.0;
-    for (int i = 0; i < cardinality; i++) {
+    int size = size();
+    for (int i = 0; i < size; i++) {
       double value = getQuick(i);
       result += value * value;
     }
@@ -275,7 +230,8 @@ public class VectorView extends Abstract
   @Override
   public double getDistanceSquared(Vector v) {
     double result = 0.0;
-    for (int i = 0; i < cardinality; i++) {
+    int size = size();
+    for (int i = 0; i < size; i++) {
       double delta = getQuick(i) - v.getQuick(i);
       result += delta * delta;
     }
@@ -284,9 +240,9 @@ public class VectorView extends Abstract
 
   @Override
   public void addTo(Vector v) {
-    Iterator<Vector.Element> iter = iterateNonZero();
+    Iterator<Element> iter = iterateNonZero();
     while (iter.hasNext()) {
-      Vector.Element elt = iter.next();
+      Element elt = iter.next();
       v.set(elt.index(), elt.get() + v.get(elt.index()));
     }
   }

Modified: lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/decomposer/hebbian/TrainingState.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/decomposer/hebbian/TrainingState.java?rev=936183&r1=936182&r2=936183&view=diff
==============================================================================
--- lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/decomposer/hebbian/TrainingState.java (original)
+++ lucene/mahout/trunk/math/src/main/java/org/apache/mahout/math/decomposer/hebbian/TrainingState.java Wed Apr 21 07:41:55 2010
@@ -25,19 +25,7 @@ import org.apache.mahout.math.Matrix;
 import org.apache.mahout.math.Vector;
 import org.apache.mahout.math.decomposer.EigenStatus;
 
-
 public class TrainingState {
-  TrainingState(Matrix eigens, Matrix projections) {
-    setCurrentEigens(eigens);
-    setTrainingProjections(projections);
-    setTrainingIndex(0);
-    setHelperVector(new DenseVector("helper", eigens.numRows()));
-    setFirstPass(true);
-    setStatusProgress(new ArrayList<EigenStatus>());
-    setActivationNumerator(0);
-    setActivationDenominatorSquared(0);
-    setNumEigensProcessed(0);
-  }
 
   private Matrix currentEigens;
   private int numEigensProcessed;
@@ -50,14 +38,27 @@ public class TrainingState {
   private double activationNumerator;
   private double activationDenominatorSquared;
 
+  TrainingState(Matrix eigens, Matrix projections) {
+    currentEigens = eigens;
+    trainingProjections = projections;
+    trainingIndex = 0;
+    helperVector = new DenseVector(eigens.numRows());
+    firstPass = true;
+    statusProgress = new ArrayList<EigenStatus>();
+    activationNumerator = 0;
+    activationDenominatorSquared = 0;
+    numEigensProcessed = 0;
+  }
+
   public Vector mostRecentEigen() {
-    return getCurrentEigens().getRow(getNumEigensProcessed() - 1);
+    return currentEigens.getRow(numEigensProcessed - 1);
   }
 
   public Vector currentTrainingProjection() {
-    if (getTrainingProjections().getRow(getTrainingIndex()) == null)
-      getTrainingProjections().assignRow(getTrainingIndex(), new DenseVector(getCurrentEigens().numCols()));
-    return getTrainingProjections().getRow(getTrainingIndex());
+    if (trainingProjections.getRow(trainingIndex) == null) {
+      trainingProjections.assignRow(trainingIndex, new DenseVector(currentEigens.numCols()));
+    }
+    return trainingProjections.getRow(trainingIndex);
   }
 
   public Matrix getCurrentEigens() {

Copied: lucene/mahout/trunk/math/src/test/java/org/apache/mahout/math/AbstractTestVector.java (from r935497, lucene/mahout/trunk/math/src/test/java/org/apache/mahout/math/TestSparseVector.java)
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/math/src/test/java/org/apache/mahout/math/AbstractTestVector.java?p2=lucene/mahout/trunk/math/src/test/java/org/apache/mahout/math/AbstractTestVector.java&p1=lucene/mahout/trunk/math/src/test/java/org/apache/mahout/math/TestSparseVector.java&r1=935497&r2=936183&rev=936183&view=diff
==============================================================================
--- lucene/mahout/trunk/math/src/test/java/org/apache/mahout/math/TestSparseVector.java (original)
+++ lucene/mahout/trunk/math/src/test/java/org/apache/mahout/math/AbstractTestVector.java Wed Apr 21 07:41:55 2010
@@ -24,22 +24,30 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
+abstract class AbstractTestVector extends TestCase {
 
-public class TestSparseVector extends TestCase {
+  private static final double[] values = {1.1, 2.2, 3.3};
+  private static final double[] gold = {0.0, 1.1, 0.0, 2.2, 0.0, 3.3, 0.0};
+  private static final double EPSILON = 0.0000000001;
 
-  private final double[] values = {1.1, 2.2, 3.3};
-  private final double[] gold = {0, 1.1, 2.2, 3.3, 0};
-  private final Vector test = new RandomAccessSparseVector(values.length + 2);
+  private Vector test;
 
-  public TestSparseVector(String name) {
+  AbstractTestVector(String name) {
     super(name);
   }
 
+  abstract Vector generateTestVector(int cardinality);
+
+  Vector getTestVector() {
+    return test;
+  }
+
   @Override
   protected void setUp() throws Exception {
     super.setUp();
+    test = generateTestVector(2 * values.length + 1);
     for (int i = 0; i < values.length; i++) {
-      test.set(i + 1, values[i]);
+      test.set(2*i + 1, values[i]);
     }
   }
 
@@ -50,14 +58,14 @@ public class TestSparseVector extends Te
   }
 
   public void testCardinality() {
-    assertEquals("size", 5, test.size());
+    assertEquals("size", 7, test.size());
   }
 
   public void testIterator() throws Exception {
     Iterator<Vector.Element> iterator = test.iterateNonZero();
     checkIterator(iterator, gold);
 
-    iterator = test.iterateAll();
+    iterator = test.iterator();
     checkIterator(iterator, gold);
 
     double[] doubles = {0.0, 5.0, 0, 3.0};
@@ -67,7 +75,7 @@ public class TestSparseVector extends Te
     }
     iterator = zeros.iterateNonZero();
     checkIterator(iterator, doubles);
-    iterator = zeros.iterateAll();
+    iterator = zeros.iterator();
     checkIterator(iterator, doubles);
 
     doubles = new double[]{0.0, 0.0, 0, 0.0};
@@ -77,7 +85,7 @@ public class TestSparseVector extends Te
     }
     iterator = zeros.iterateNonZero();
     checkIterator(iterator, doubles);
-    iterator = zeros.iterateAll();
+    iterator = zeros.iterator();
     checkIterator(iterator, doubles);
 
   }
@@ -90,6 +98,31 @@ public class TestSparseVector extends Te
     }
   }
 
+  public void testIteratorSet() {
+    Vector clone = test.clone();
+    Iterator<Vector.Element> it = clone.iterateNonZero();
+    while (it.hasNext()) {
+      Vector.Element e = it.next();
+      e.set(e.get() * 2.0);
+    }
+    it = clone.iterateNonZero();
+    while (it.hasNext()) {
+      Vector.Element e = it.next();
+      assertEquals(test.get(e.index()) * 2.0, e.get());
+    }
+    clone = test.clone();
+    it = clone.iterator();
+    while (it.hasNext()) {
+      Vector.Element e = it.next();
+      e.set(e.get() * 2.0);
+    }
+    it = clone.iterator();
+    while (it.hasNext()) {
+      Vector.Element e = it.next();
+      assertEquals(test.get(e.index()) * 2.0, e.get());
+    }
+  }
+
   public void testCopy() throws Exception {
     Vector copy = test.clone();
     for (int i = 0; i < test.size(); i++) {
@@ -99,10 +132,10 @@ public class TestSparseVector extends Te
 
   public void testGet() throws Exception {
     for (int i = 0; i < test.size(); i++) {
-      if (i > 0 && i < 4) {
-        assertEquals("get [" + i + ']', values[i - 1], test.get(i));
-      } else {
+      if (i % 2 == 0) {
         assertEquals("get [" + i + ']', 0.0, test.get(i));
+      } else {
+        assertEquals("get [" + i + ']', values[i/2], test.get(i));
       }
     }
   }
@@ -112,7 +145,6 @@ public class TestSparseVector extends Te
       test.get(test.size());
       fail("expected exception");
     } catch (IndexException e) {
-      assertTrue(true);
     }
   }
 
@@ -121,19 +153,18 @@ public class TestSparseVector extends Te
       test.get(-1);
       fail("expected exception");
     } catch (IndexException e) {
-      assertTrue(true);
     }
   }
 
   public void testSet() throws Exception {
-    test.set(2, 4.5);
+    test.set(3, 4.5);
     for (int i = 0; i < test.size(); i++) {
-      if (i == 0 || i == 4) {
+      if (i % 2 == 0) {
         assertEquals("get [" + i + ']', 0.0, test.get(i));
-      } else if (i == 2) {
+      } else if (i == 3) {
         assertEquals("set [" + i + ']', 4.5, test.get(i));
       } else {
-        assertEquals("set [" + i + ']', values[i - 1], test.get(i));
+        assertEquals("set [" + i + ']', values[i/2], test.get(i));
       }
     }
   }
@@ -146,7 +177,7 @@ public class TestSparseVector extends Te
     Vector part = test.viewPart(1, 2);
     assertEquals("part size", 2, part.getNumNondefaultElements());
     for (int i = 0; i < part.size(); i++) {
-      assertEquals("part[" + i + ']', values[i], part.get(i));
+      assertEquals("part[" + i + ']', test.get(i+1), part.get(i));
     }
   }
 
@@ -154,32 +185,23 @@ public class TestSparseVector extends Te
     try {
       test.viewPart(-1, values.length);
       fail("no exception");
-    } catch (CardinalityException e) {
-      fail("wrong exception");
     } catch (IndexException e) {
-      assertTrue(true);
     }
   }
 
   public void testViewPartOver() {
     try {
-      test.viewPart(2, 5);
+      test.viewPart(2, 7);
       fail("no exception");
-    } catch (CardinalityException e) {
-      fail("wrong exception");
     } catch (IndexException e) {
-      assertTrue(true);
     }
   }
 
   public void testViewPartCardinality() {
     try {
-      test.viewPart(1, 6);
+      test.viewPart(1, 8);
       fail("no exception");
-    } catch (CardinalityException e) {
-      assertTrue(true);
     } catch (IndexException e) {
-      fail("wrong exception");
     }
   }
 
@@ -201,7 +223,7 @@ public class TestSparseVector extends Te
   public void testDot() throws Exception {
     double res = test.dot(test);
     double expected = 3.3 * 3.3 + 2.2 * 2.2 + 1.1 * 1.1;
-    assertEquals("dot", expected, res);
+    assertEquals("dot", expected, res, EPSILON);
   }
 
   public void testDotCardinality() {
@@ -209,7 +231,6 @@ public class TestSparseVector extends Te
       test.dot(new DenseVector(test.size() + 1));
       fail("expected exception");
     } catch (CardinalityException e) {
-      assertTrue(true);
     }
   }
 
@@ -217,10 +238,10 @@ public class TestSparseVector extends Te
     Vector val = test.normalize();
     double mag = Math.sqrt(1.1 * 1.1 + 2.2 * 2.2 + 3.3 * 3.3);
     for (int i = 0; i < test.size(); i++) {
-      if (i == 0 || i == 4) {
+      if (i % 2 == 0) {
         assertEquals("get [" + i + ']', 0.0, val.get(i));
       } else {
-        assertEquals("dot", values[i - 1] / mag, val.get(i));
+        assertEquals("dot", values[i/2] / mag, val.get(i));
       }
     }
   }
@@ -231,6 +252,12 @@ public class TestSparseVector extends Te
     for (int i = 0; i < test.size(); i++) {
       assertEquals("get [" + i + ']', 0.0, val.get(i));
     }
+
+    val = test.minus(test).minus(test);
+    assertEquals("cardinality", test.size(), val.size());
+    for (int i = 0; i < test.size(); i++) {
+      assertEquals("get [" + i + ']', 0.0, val.get(i) + test.get(i));
+    }
     
     Vector val1 = test.plus(1);
     val = val1.minus(test);
@@ -249,10 +276,10 @@ public class TestSparseVector extends Te
     Vector val = test.plus(1);
     assertEquals("size", test.size(), val.size());
     for (int i = 0; i < test.size(); i++) {
-      if (i == 0 || i == 4) {
+      if (i % 2 == 0) {
         assertEquals("get [" + i + ']', 1.0, val.get(i));
       } else {
-        assertEquals("get [" + i + ']', values[i - 1] + 1, val.get(i));
+        assertEquals("get [" + i + ']', values[i/2] + 1.0, val.get(i));
       }
     }
   }
@@ -261,10 +288,10 @@ public class TestSparseVector extends Te
     Vector val = test.plus(test);
     assertEquals("size", test.size(), val.size());
     for (int i = 0; i < test.size(); i++) {
-      if (i == 0 || i == 4) {
+      if (i % 2 == 0) {
         assertEquals("get [" + i + ']', 0.0, val.get(i));
       } else {
-        assertEquals("get [" + i + ']', values[i - 1] * 2, val.get(i));
+        assertEquals("get [" + i + ']', values[i/2] * 2.0, val.get(i));
       }
     }
   }
@@ -274,7 +301,6 @@ public class TestSparseVector extends Te
       test.plus(new DenseVector(test.size() + 1));
       fail("expected exception");
     } catch (CardinalityException e) {
-      assertTrue(true);
     }
   }
 
@@ -282,10 +308,10 @@ public class TestSparseVector extends Te
     Vector val = test.times(3);
     assertEquals("size", test.size(), val.size());
     for (int i = 0; i < test.size(); i++) {
-      if (i == 0 || i == 4) {
+      if (i % 2 == 0) {
         assertEquals("get [" + i + ']', 0.0, val.get(i));
       } else {
-        assertEquals("get [" + i + ']', values[i - 1] * 3, val.get(i));
+        assertEquals("get [" + i + ']', values[i/2] * 3.0, val.get(i));
       }
     }
   }
@@ -294,10 +320,10 @@ public class TestSparseVector extends Te
     Vector val = test.divide(3);
     assertEquals("size", test.size(), val.size());
     for (int i = 0; i < test.size(); i++) {
-      if (i == 0 || i == 4) {
+      if (i % 2 == 0) {
         assertEquals("get [" + i + ']', 0.0, val.get(i));
       } else {
-        assertEquals("get [" + i + ']', values[i - 1] / 3, val.get(i));
+        assertEquals("get [" + i + ']', values[i/2] / 3.0, val.get(i), EPSILON);
       }
     }
   }
@@ -306,11 +332,10 @@ public class TestSparseVector extends Te
     Vector val = test.times(test);
     assertEquals("size", test.size(), val.size());
     for (int i = 0; i < test.size(); i++) {
-      if (i == 0 || i == 4) {
+      if (i % 2 == 0) {
         assertEquals("get [" + i + ']', 0.0, val.get(i));
       } else {
-        assertEquals("get [" + i + ']', values[i - 1] * values[i - 1], val
-            .get(i));
+        assertEquals("get [" + i + ']', values[i/2] * values[i/2], val.get(i));
       }
     }
   }
@@ -320,7 +345,6 @@ public class TestSparseVector extends Te
       test.times(new DenseVector(test.size() + 1));
       fail("expected exception");
     } catch (CardinalityException e) {
-      assertTrue(true);
     }
   }
 
@@ -364,7 +388,6 @@ public class TestSparseVector extends Te
       test.assign(array);
       fail("cardinality exception expected");
     } catch (CardinalityException e) {
-      assertTrue(true);
     }
   }
 
@@ -382,21 +405,20 @@ public class TestSparseVector extends Te
       test.assign(other);
       fail("cardinality exception expected");
     } catch (CardinalityException e) {
-      assertTrue(true);
     }
   }
 
   public void testAssignUnaryFunction() {
     test.assign(negate);
-    for (int i = 0; i < values.length; i++) {
-      assertEquals("value[" + i + ']', -values[i], test.getQuick(i+1));
+    for (int i = 1; i < values.length; i += 2) {
+      assertEquals("value[" + i + ']', -values[i], test.getQuick(i+2));
     }
   }
 
   public void testAssignBinaryFunction() throws Exception {
     test.assign(test, plus);
     for (int i = 0; i < values.length; i++) {
-      if (i == 0 || i == 4) {
+      if (i % 2 == 0) {
         assertEquals("get [" + i + ']', 0.0, test.get(i));
       } else {
         assertEquals("value[" + i + ']', 2 * values[i - 1], test.getQuick(i));
@@ -407,7 +429,7 @@ public class TestSparseVector extends Te
   public void testAssignBinaryFunction2() throws Exception {
     test.assign(plus(4));
     for (int i = 0; i < values.length; i++) {
-      if (i == 0 || i == 4) {
+      if (i % 2 == 0) {
         assertEquals("get [" + i + ']', 4.0, test.get(i));
       } else {
         assertEquals("value[" + i + ']', values[i - 1] + 4, test.getQuick(i));
@@ -418,7 +440,7 @@ public class TestSparseVector extends Te
   public void testAssignBinaryFunction3() throws Exception {
     test.assign(mult(4));
     for (int i = 0; i < values.length; i++) {
-      if (i == 0 || i == 4) {
+      if (i % 2 == 0) {
         assertEquals("get [" + i + ']', 0.0, test.get(i));
       } else {
         assertEquals("value[" + i + ']', values[i - 1] * 4, test.getQuick(i));
@@ -431,19 +453,18 @@ public class TestSparseVector extends Te
       test.assign(test.like(2), plus);
       fail("Cardinality exception expected");
     } catch (CardinalityException e) {
-      assertTrue(true);
     }
   }
 
   public void testLike() {
     Vector other = test.like();
-    assertTrue("not like", other instanceof RandomAccessSparseVector);
+    assertTrue("not like", test.getClass().isAssignableFrom(other.getClass()));
     assertEquals("size", test.size(), other.size());
   }
 
   public void testLikeN() {
     Vector other = test.like(8);
-    assertTrue("not like", other instanceof RandomAccessSparseVector);
+    assertTrue("not like", test.getClass().isAssignableFrom(other.getClass()));
     assertEquals("size", 8, other.size());
   }
 

Propchange: lucene/mahout/trunk/math/src/test/java/org/apache/mahout/math/AbstractTestVector.java
------------------------------------------------------------------------------
    svn:eol-style = native