diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/data/SparseFloatVector.java')
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/data/SparseFloatVector.java | 282 |
1 files changed, 55 insertions, 227 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/data/SparseFloatVector.java b/src/de/lmu/ifi/dbs/elki/data/SparseFloatVector.java index b9066d40..1ce8c5f7 100644 --- a/src/de/lmu/ifi/dbs/elki/data/SparseFloatVector.java +++ b/src/de/lmu/ifi/dbs/elki/data/SparseFloatVector.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2011 + Copyright (C) 2012 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,16 +23,19 @@ package de.lmu.ifi.dbs.elki.data; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import gnu.trove.impl.unmodifiable.TUnmodifiableIntFloatMap; +import gnu.trove.iterator.TIntFloatIterator; +import gnu.trove.map.TIntFloatMap; +import gnu.trove.map.hash.TIntFloatHashMap; + import java.util.Arrays; import java.util.BitSet; -import java.util.List; -import java.util.Map; import de.lmu.ifi.dbs.elki.datasource.parser.SparseFloatVectorLabelParser; -import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; -import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil; -import de.lmu.ifi.dbs.elki.utilities.Util; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** * <p> @@ -47,6 +50,11 @@ import de.lmu.ifi.dbs.elki.utilities.Util; // TODO: implement ByteArraySerializer<SparseFloatVector> public class SparseFloatVector extends AbstractNumberVector<SparseFloatVector, Float> implements SparseNumberVector<SparseFloatVector, Float> { /** + * Static instance + */ + public static final SparseFloatVector STATIC = new SparseFloatVector(new int[0], new float[0], -1); + + /** * Indexes of values */ private int[] indexes; @@ -85,7 +93,7 @@ public class SparseFloatVector extends AbstractNumberVector<SparseFloatVector, F * to cover the given values (i.e., the maximum index of any value not * zero is bigger than the given dimensionality) */ - public SparseFloatVector(Map<Integer, Float> values, int dimensionality) throws IllegalArgumentException { + public SparseFloatVector(TIntFloatMap values, int dimensionality) throws IllegalArgumentException { if(values.size() > dimensionality) { throw new IllegalArgumentException("values.size() > dimensionality!"); } @@ -94,10 +102,10 @@ public class SparseFloatVector extends AbstractNumberVector<SparseFloatVector, F this.values = new float[values.size()]; // Import and sort the indexes { - int i = 0; - for(Integer index : values.keySet()) { - this.indexes[i] = index; - i++; + TIntFloatIterator iter = values.iterator(); + for (int i = 0; iter.hasNext(); i++) { + iter.advance(); + this.indexes[i] = iter.key(); } Arrays.sort(this.indexes); } @@ -160,6 +168,7 @@ public class SparseFloatVector extends AbstractNumberVector<SparseFloatVector, F if(value != 0.0f) { this.indexes[pos] = i + 1; this.values[pos] = value; + pos++; } } } @@ -226,172 +235,6 @@ public class SparseFloatVector extends AbstractNumberVector<SparseFloatVector, F return new Vector(values); } - @Override - public Matrix getRowVector() { - double[] values = getValues(); // already a copy - return new Matrix(new double[][] { values }); - } - - @Override - public SparseFloatVector plus(SparseFloatVector fv) { - if(fv.getDimensionality() != this.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + fv.getDimensionality() + "."); - } - // Compute size of result vector - int destsize = 0; - { - int po = 0; - int pt = 0; - while(po < fv.indexes.length && pt < this.indexes.length) { - final int delta = fv.indexes[po] - this.indexes[pt]; - if(delta == 0) { - final float fdelta = this.values[pt] - fv.values[po]; - if(fdelta != 0.0f) { - destsize++; - } - po++; - pt++; - } - else if(delta < 0) { - // next index in this bigger than in fv - po++; - destsize++; - } - else { - // next index in fv bigger than in this - pt++; - destsize++; - } - } - } - int[] newindexes = new int[destsize]; - float[] newvalues = new float[destsize]; - // Compute difference - { - int outp = 0; - int po = 0; - int pt = 0; - while(po < fv.indexes.length && pt < this.indexes.length) { - final int delta = fv.indexes[po] - this.indexes[pt]; - if(delta == 0) { - final float fdelta = this.values[pt] + fv.values[po]; - if(fdelta != 0.0f) { - newindexes[outp] = fv.indexes[po]; - newvalues[outp] = fdelta; - outp++; - } - po++; - pt++; - } - else if(delta < 0) { - // next index in this bigger than in fv - newindexes[outp] = fv.indexes[po]; - newvalues[outp] = fv.values[po]; - outp++; - po++; - } - else { - // next index in fv bigger than in this - newindexes[outp] = this.indexes[pt]; - newvalues[outp] = this.values[pt]; - outp++; - pt++; - } - } - } - return new SparseFloatVector(newindexes, newvalues, this.dimensionality); - } - - @Override - public SparseFloatVector minus(SparseFloatVector fv) { - if(fv.getDimensionality() != this.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + fv.getDimensionality() + "."); - } - // Compute size of result vector - int destsize = 0; - { - int po = 0; - int pt = 0; - while(po < fv.indexes.length && pt < this.indexes.length) { - final int delta = fv.indexes[po] - this.indexes[pt]; - if(delta == 0) { - final float fdelta = this.values[pt] - fv.values[po]; - if(fdelta != 0.0f) { - destsize++; - } - po++; - pt++; - } - else if(delta < 0) { - // next index in this bigger than in fv - po++; - destsize++; - } - else { - // next index in fv bigger than in this - pt++; - destsize++; - } - } - } - int[] newindexes = new int[destsize]; - float[] newvalues = new float[destsize]; - // Compute difference - { - int outp = 0; - int po = 0; - int pt = 0; - while(po < fv.indexes.length && pt < this.indexes.length) { - final int delta = fv.indexes[po] - this.indexes[pt]; - if(delta == 0) { - final float fdelta = this.values[pt] - fv.values[po]; - if(fdelta != 0.0f) { - newindexes[outp] = fv.indexes[po]; - newvalues[outp] = fdelta; - outp++; - } - po++; - pt++; - } - else if(delta < 0) { - // next index in this bigger than in fv - newindexes[outp] = fv.indexes[po]; - newvalues[outp] = -fv.values[po]; - outp++; - po++; - } - else { - // next index in fv bigger than in this - newindexes[outp] = this.indexes[pt]; - newvalues[outp] = this.values[pt]; - outp++; - pt++; - } - } - } - return new SparseFloatVector(newindexes, newvalues, this.dimensionality); - } - - @Override - public SparseFloatVector nullVector() { - return new SparseFloatVector(new int[] {}, new float[] {}, dimensionality); - } - - @Override - public SparseFloatVector negativeVector() { - return multiplicate(-1); - } - - @Override - public SparseFloatVector multiplicate(double k) { - int[] newindexes = indexes.clone(); - float[] newvalues = new float[this.values.length]; - for(int i = 0; i < this.indexes.length; i++) { - newvalues[i] = (float) (this.values[i] * k); - } - return new SparseFloatVector(newindexes, newvalues, this.dimensionality); - } - /** * <p> * Provides a String representation of this SparseFloatVector as suitable for @@ -440,60 +283,26 @@ public class SparseFloatVector extends AbstractNumberVector<SparseFloatVector, F return values; } - /** - * Provides the scalar product (inner product) of this and the given - * SparseFloatVector. - * - * @param fv the SparseFloatVector to compute the scalar product for - * @return the scalar product (inner product) of this and the given - * SparseFloatVector - */ @Override - public Float scalarProduct(SparseFloatVector fv) { - if(this.getDimensionality() != fv.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + fv.getDimensionality() + "."); - } - float result = 0.0f; - int po = 0; - int pt = 0; - while(po < fv.indexes.length && pt < this.indexes.length) { - final int delta = fv.indexes[po] - this.indexes[pt]; - if(delta == 0) { - result += fv.values[po] * this.values[pt]; - po++; - pt++; - } - else if(delta < 0) { - // next index in this bigger than in fv - po++; - } - else { - // next index in fv bigger than in this - pt++; - } + public <A> SparseFloatVector newFeatureVector(A array, ArrayAdapter<Float, A> adapter) { + int dim = adapter.size(array); + float[] values = new float[dim]; + for(int i = 0; i < dim; i++) { + values[i] = adapter.get(array, i); } - return result; + // TODO: inefficient + return new SparseFloatVector(values); } @Override - public SparseFloatVector newInstance(Vector values) { - return newInstance(values.getArrayRef()); - } - - @Override - public SparseFloatVector newInstance(double[] values) { - // FIXME: inefficient - return new SparseFloatVector(Util.convertToFloat(values)); - } - - @Override - public SparseFloatVector newInstance(List<Float> values) { - return new SparseFloatVector(Util.unboxToFloat(ClassGenericsUtil.toArray(values, Float.class))); - } - - @Override - public SparseFloatVector newInstance(Float[] values) { - return new SparseFloatVector(Util.unboxToFloat(values)); + public <A> SparseFloatVector newNumberVector(A array, NumberArrayAdapter<?, A> adapter) { + int dim = adapter.size(array); + float[] values = new float[dim]; + for(int i = 0; i < dim; i++) { + values[i] = adapter.getFloat(array, i); + } + // TODO: inefficient + return new SparseFloatVector(values); } @Override @@ -504,4 +313,23 @@ public class SparseFloatVector extends AbstractNumberVector<SparseFloatVector, F } return b; } -}
\ No newline at end of file + + /** + * Parameterization class + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected SparseFloatVector makeInstance() { + return STATIC; + } + } + + /** + * Empty map. + */ + public static final TIntFloatMap EMPTYMAP = new TUnmodifiableIntFloatMap(new TIntFloatHashMap()); +} |