summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/data/SparseFloatVector.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/data/SparseFloatVector.java')
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/SparseFloatVector.java282
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());
+}