Add working equals to SparseRealVector.

hashCode implementation is minimal, but I can't see a use case for using a SparseRealVector as a key.

Remove unused imports from OpenInToDoubleHashMap.

Some cleanup for optimized methods, and javadoc fixes.


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@744614 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
William Barker 2009-02-15 06:46:15 +00:00
parent e01294b158
commit 63e1a2c76c
3 changed files with 76 additions and 28 deletions

View File

@ -21,7 +21,7 @@ import org.apache.commons.math.util.OpenIntToDoubleHashMap;
import org.apache.commons.math.util.OpenIntToDoubleHashMap.Iterator;
/**
* This class implements the {@link RealVector} interface with a {@link OpenIntToDoubleHashMap}.
* This class implements the {@link RealVector} interface with a {@link OpenIntToDoubleHashMap} backing store.
* @version $Revision: 728186 $ $Date$
* @since 2.0
*/
@ -230,23 +230,18 @@ public class SparseRealVector implements RealVector {
* Optimized method to add two SparseRealVectors
* @param v Vector to add with
* @return The sum of <code>this</code> with <code>v</code>
* @throws IllegalArgumentException If the dimensions don't match
*/
public SparseRealVector add(SparseRealVector v) {
public SparseRealVector add(SparseRealVector v) throws IllegalArgumentException{
checkVectorDimensions(v.getDimension());
SparseRealVector res = (SparseRealVector) copy();
Iterator iter = res.getEntries().iterator();
SparseRealVector res = (SparseRealVector)copy();
Iterator iter = v.getEntries().iterator();
while (iter.hasNext()) {
iter.advance();
int key = iter.key();
if (v.getEntries().containsKey(key)) {
res.setEntry(key, iter.value() + v.getEntry(key));
}
}
iter = v.getEntries().iterator();
while (iter.hasNext()) {
iter.advance();
int key = iter.key();
if (!entries.containsKey(key)) {
if (entries.containsKey(key)) {
res.setEntry(key, entries.get(key) + iter.value());
} else {
res.setEntry(key, iter.value());
}
}
@ -419,8 +414,9 @@ public class SparseRealVector implements RealVector {
* Optimized method to compute distance
* @param v The vector to compute distance to
* @return The distance from <code>this</code> and <code>v</code>
* @throws IllegalArgumentException If the dimensions don't match
*/
public double getDistance(SparseRealVector v) {
public double getDistance(SparseRealVector v) throws IllegalArgumentException {
Iterator iter = entries.iterator();
double res = 0;
while (iter.hasNext()) {
@ -1013,8 +1009,9 @@ public class SparseRealVector implements RealVector {
* Optimized method to compute the outer product
* @param v The vector to comput the outer product on
* @return The outer product of <code>this</code> and <code>v</code>
* @throws IllegalArgumentException If the dimensions don't match
*/
public SparseRealMatrix outerproduct(SparseRealVector v){
public SparseRealMatrix outerproduct(SparseRealVector v) throws IllegalArgumentException{
checkVectorDimensions(v.getDimension());
SparseRealMatrix res = new SparseRealMatrix(virtualSize, virtualSize);
Iterator iter = entries.iterator();
@ -1109,19 +1106,23 @@ public class SparseRealVector implements RealVector {
}
}
/** {@inheritDoc} */
public SparseRealVector subtract(SparseRealVector v) {
/**
* Optimized method to subtract SparseRealVectors
* @param v The vector to subtract from <code>this</code>
* @return The difference of <code>this</code> and <code>v</code>
* @throws IllegalArgumentException If the dimensions don't match
*/
public SparseRealVector subtract(SparseRealVector v) throws IllegalArgumentException{
checkVectorDimensions(v.getDimension());
SparseRealVector res = new SparseRealVector(this);
SparseRealVector res = (SparseRealVector)copy();
Iterator iter = v.getEntries().iterator();
OpenIntToDoubleHashMap values = res.getEntries();
while (iter.hasNext()) {
iter.advance();
int key = iter.key();
if (entries.containsKey(key)) {
values.put(key, entries.get(key) - iter.value());
res.setEntry(key, entries.get(key) - iter.value());
} else {
values.put(key, -iter.value());
res.setEntry(key, -iter.value());
}
}
return res;
@ -1210,4 +1211,52 @@ public class SparseRealVector implements RealVector {
return getData();
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(epsilon);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + virtualSize;
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof SparseRealVector))
return false;
SparseRealVector other = (SparseRealVector) obj;
if (virtualSize != other.virtualSize)
return false;
if (Double.doubleToLongBits(epsilon) != Double
.doubleToLongBits(other.epsilon))
return false;
Iterator iter = entries.iterator();
while(iter.hasNext()){
iter.advance();
double test = iter.value() - other.getEntry(iter.key());
if(Math.abs(test) > epsilon)
return false;
}
iter = other.getEntries().iterator();
while(iter.hasNext()){
iter.advance();
double test = iter.value() - getEntry(iter.key());
if(!isZero(test))
return false;
}
return true;
}
}

View File

@ -20,7 +20,6 @@ package org.apache.commons.math.util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.NoSuchElementException;
@ -476,6 +475,7 @@ public class OpenIntToDoubleHashMap implements Serializable {
return h ^ (h >>> 7) ^ (h >>> 4);
}
/** Iterator class for the map. */
public class Iterator {
@ -595,5 +595,5 @@ public class OpenIntToDoubleHashMap implements Serializable {
count = 0;
}
}

View File

@ -1124,12 +1124,11 @@ public class SparseRealVectorTest extends TestCase {
v.setEntry(1, 1);
assertTrue(v.isInfinite());
//TODO: backing store doesn't implement equals
//TODO: differeciate from resetting to zero
//v.setEntry(0, 0);
//assertEquals(v, new SparseRealVector(new double[] { 0, 1, 2 }));
//assertNotSame(v, new SparseRealVector(new double[] { 0, 1, 2 + Math.ulp(2)}));
//assertNotSame(v, new SparseRealVector(new double[] { 0, 1, 2, 3 }));
v.setEntry(0, 0);
assertEquals(v, new SparseRealVector(new double[] { 0, 1, 2 }));
assertNotSame(v, new SparseRealVector(new double[] { 0, 1, 2 + Math.ulp(2)}));
assertNotSame(v, new SparseRealVector(new double[] { 0, 1, 2, 3 }));
//assertEquals(new SparseRealVector(new double[] { Double.NaN, 1, 2 }).hashCode(),
// new SparseRealVector(new double[] { 0, Double.NaN, 2 }).hashCode());