diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/data')
80 files changed, 1455 insertions, 1741 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/data/AbstractNumberVector.java b/src/de/lmu/ifi/dbs/elki/data/AbstractNumberVector.java index 32d43d44..eb783ab5 100644 --- a/src/de/lmu/ifi/dbs/elki/data/AbstractNumberVector.java +++ b/src/de/lmu/ifi/dbs/elki/data/AbstractNumberVector.java @@ -1,10 +1,12 @@ package de.lmu.ifi.dbs.elki.data; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil; + /* 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 @@ -101,4 +103,9 @@ public abstract class AbstractNumberVector<V extends AbstractNumberVector<? exte public short shortValue(int dimension) { return (short) longValue(dimension); } + + @Override + public V newNumberVector(double[] values) { + return newNumberVector(values, ArrayLikeUtil.doubleArrayAdapter()); + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/Arithmetic.java b/src/de/lmu/ifi/dbs/elki/data/Arithmetic.java index 3a2959ca..75c3cad8 100644 --- a/src/de/lmu/ifi/dbs/elki/data/Arithmetic.java +++ b/src/de/lmu/ifi/dbs/elki/data/Arithmetic.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 diff --git a/src/de/lmu/ifi/dbs/elki/data/Bit.java b/src/de/lmu/ifi/dbs/elki/data/Bit.java index 3c77a4d5..7272e235 100644 --- a/src/de/lmu/ifi/dbs/elki/data/Bit.java +++ b/src/de/lmu/ifi/dbs/elki/data/Bit.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 diff --git a/src/de/lmu/ifi/dbs/elki/data/BitVector.java b/src/de/lmu/ifi/dbs/elki/data/BitVector.java index b51ed4e3..4756fef4 100644 --- a/src/de/lmu/ifi/dbs/elki/data/BitVector.java +++ b/src/de/lmu/ifi/dbs/elki/data/BitVector.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 @@ -26,12 +26,13 @@ package de.lmu.ifi.dbs.elki.data; import java.io.IOException; import java.nio.ByteBuffer; import java.util.BitSet; -import java.util.List; -import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil; import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer; +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; /** * Provides a BitVector wrapping a BitSet. @@ -40,6 +41,11 @@ import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer; */ public class BitVector extends AbstractNumberVector<BitVector, Bit> implements ByteBufferSerializer<BitVector> { /** + * Static instance. + */ + public static final BitVector STATIC = new BitVector(new BitSet(0), 0); + + /** * Storing the bits. */ private BitSet bits; @@ -80,21 +86,6 @@ public class BitVector extends AbstractNumberVector<BitVector, Bit> implements B } /** - * Provides a new BitVector corresponding to the bits in the given list. - * - * @param bits an array of bits specifying the bits in this bit vector - */ - public BitVector(List<Bit> bits) { - this.bits = new BitSet(bits.size()); - int i = 0; - for(Bit bit : bits) { - this.bits.set(i, bit.bitValue()); - i++; - } - this.dimensionality = bits.size(); - } - - /** * The dimensionality of the binary vector space of which this BitVector is an * element. * @@ -177,110 +168,6 @@ public class BitVector extends AbstractNumberVector<BitVector, Bit> implements B } /** - * Returns a Matrix representing in one row and - * <code>getDimensionality()</code> columns the values of this BitVector as - * double values. - * - * @return a Matrix representing in one row and - * <code>getDimensionality()</code> columns the values of this - * BitVector as double values - * - * @see de.lmu.ifi.dbs.elki.data.NumberVector#getRowVector() - */ - @Override - public Matrix getRowVector() { - double[] values = new double[dimensionality]; - for(int i = 0; i < dimensionality; i++) { - values[i] = bits.get(i) ? 1 : 0; - } - return new Matrix(new double[][] { values }); - } - - /** - * Returns a bit vector equal to this bit vector, if k is not 0, a bit vector - * with all components equal to zero otherwise. - * - * @param k used as multiplier 1 if k ≠ 0, otherwise the resulting bit - * vector will have all values equal to zero - * @return a bit vector equal to this bit vector, if k is not 0, a bit vector - * with all components equal to zero otherwise - */ - @Override - public BitVector multiplicate(double k) { - if(k == 0) { - return nullVector(); - } - else { - return new BitVector(bits, dimensionality); - } - } - - /** - * Returns the inverse of the bit vector. - * - * The result is the same as obtained by flipping all bits in the underlying - * BitSet. - * - * @return the inverse of the bit vector - * @see BitSet#flip(int,int) - */ - @Override - public BitVector negativeVector() { - BitSet newBits = (BitSet) bits.clone(); - newBits.flip(0, dimensionality); - return new BitVector(newBits, dimensionality); - } - - /** - * Returns a bit vector of equal dimensionality but containing 0 only. - * - * @return a bit vector of equal dimensionality but containing 0 only - */ - @Override - public BitVector nullVector() { - return new BitVector(new BitSet(), dimensionality); - } - - /** - * Returns a bit vector corresponding to an XOR operation on this and the - * specified bit vector. - * - * @param fv the bit vector to add - * @return a new bit vector corresponding to an XOR operation on this and the - * specified bit vector - */ - @Override - public BitVector plus(BitVector fv) { - if(this.getDimensionality() != fv.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + fv.getDimensionality() + "."); - } - - BitVector bv = new BitVector((BitSet) fv.bits.clone(), this.dimensionality); - bv.bits.xor(this.bits); - return bv; - } - - /** - * Returns a bit vector corresponding to an NXOR operation on this and the - * specified bit vector. - * - * @param fv the bit vector to add - * @return a new bit vector corresponding to an NXOR operation on this and the - * specified bit vector - */ - @Override - public BitVector minus(BitVector fv) { - if(this.getDimensionality() != fv.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + fv.getDimensionality() + "."); - } - - BitVector bv = new BitVector((BitSet) fv.bits.clone(), this.dimensionality); - bv.bits.flip(0, dimensionality); - bv.bits.xor(this.bits); - return bv; - } - - /** * Returns whether this BitVector contains all bits that are set to true in * the specified BitSet. * @@ -347,74 +234,29 @@ public class BitVector extends AbstractNumberVector<BitVector, Bit> implements B } } - /** - * Provides the scalar product (inner product) of this BitVector and the given - * BitVector. - * - * As multiplication of Bits, the logical AND operation is used. The result is - * 0 if the number of bits after the AND operation is a multiple of 2, - * otherwise the result is 1. - * - * @param fv the BitVector to compute the scalar product for - * @return the scalar product (inner product) of this and the given BitVector - */ - @Override - public Bit scalarProduct(BitVector fv) { - if(this.getDimensionality() != fv.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + fv.getDimensionality() + "."); - } - BitSet bs = (BitSet) this.bits.clone(); - bs.and(fv.bits); - - return new Bit(bs.cardinality() % 2 == 1); - } - @Override - public BitVector newInstance(double[] values) { - int dim = values.length; + public <A> BitVector newFeatureVector(A array, ArrayAdapter<Bit, A> adapter) { + int dim = adapter.size(array); BitSet bits = new BitSet(dim); for(int i = 0; i < dim; i++) { - if(values[i] >= 0.5) { - bits.set(i); - } + bits.set(i, adapter.get(array, i).bitValue()); + i++; } return new BitVector(bits, dim); } @Override - public BitVector newInstance(Vector values) { - int dim = values.getDimensionality(); + public <A> BitVector newNumberVector(A array, NumberArrayAdapter<?, A> adapter) { + int dim = adapter.size(array); BitSet bits = new BitSet(dim); for(int i = 0; i < dim; i++) { - if(values.get(i) >= 0.5) { + if(adapter.getDouble(array, i) >= 0.5) { bits.set(i); } } return new BitVector(bits, dim); } - /** - * Creates and returns a new BitVector based on the passed values. - * - * @return a new instance of this BitVector with the specified values - * - */ - @Override - public BitVector newInstance(Bit[] values) { - return new BitVector(values); - } - - /** - * Creates and returns a new BitVector based on the passed values. - * - * @return a new instance of this BitVector with the specified values - * - */ - @Override - public BitVector newInstance(List<Bit> values) { - return new BitVector(values); - } - @Override public BitVector fromByteBuffer(ByteBuffer buffer) throws IOException { short dimensionality = buffer.getShort(); @@ -425,9 +267,9 @@ public class BitVector extends AbstractNumberVector<BitVector, Bit> implements B // read values BitSet values = new BitSet(dimensionality); byte b = 0; - for(int i = 0; i < dimensionality; i ++) { + for(int i = 0; i < dimensionality; i++) { // read the next byte when needed. - if ((i & 7) == 0) { + if((i & 7) == 0) { b = buffer.get(); } final byte bit = (byte) (1 << (i & 7)); @@ -441,7 +283,7 @@ public class BitVector extends AbstractNumberVector<BitVector, Bit> implements B @Override public void toByteBuffer(ByteBuffer buffer, BitVector vec) throws IOException { final int len = getByteSize(vec); - assert(vec.getDimensionality() <= Short.MAX_VALUE); + assert (vec.getDimensionality() <= Short.MAX_VALUE); final short dim = (short) vec.getDimensionality(); if(buffer.remaining() < len) { throw new IOException("Not enough space for the bit vector!"); @@ -460,15 +302,29 @@ public class BitVector extends AbstractNumberVector<BitVector, Bit> implements B b &= ~mask; } // Write when appropriate - if ((i & 7) == 7 || i == dim - 1) { + if((i & 7) == 7 || i == dim - 1) { buffer.put(b); b = 0; } } } - + @Override public int getByteSize(BitVector vec) { return ByteArrayUtil.SIZE_SHORT + (vec.getDimensionality() + 7) / 8; } + + /** + * Parameterization class + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected BitVector makeInstance() { + return STATIC; + } + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/ClassLabel.java b/src/de/lmu/ifi/dbs/elki/data/ClassLabel.java index 3ec5874c..8a3b0b30 100644 --- a/src/de/lmu/ifi/dbs/elki/data/ClassLabel.java +++ b/src/de/lmu/ifi/dbs/elki/data/ClassLabel.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,6 +23,8 @@ package de.lmu.ifi.dbs.elki.data; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import java.util.HashMap; + import de.lmu.ifi.dbs.elki.utilities.InspectionUtilFrequentlyScanned; /** @@ -76,16 +78,27 @@ public abstract class ClassLabel implements Comparable<ClassLabel> { public int hashCode() { return toString().hashCode(); } - + /** * Class label factory * * @author Erich Schubert - * + * * @apiviz.has ClassLabel - - «creates» * @apiviz.stereotype factory */ public static abstract class Factory<L extends ClassLabel> implements InspectionUtilFrequentlyScanned { + /** + * Set for reusing the same objects. + */ + protected HashMap<String, L> existing = new HashMap<String, L>(); + + /** + * Convert a string into a class label + * + * @param lbl String to convert + * @return Class label instance. + */ public abstract L makeFromString(String lbl); } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/Cluster.java b/src/de/lmu/ifi/dbs/elki/data/Cluster.java index 7bc3fc30..6863e995 100644 --- a/src/de/lmu/ifi/dbs/elki/data/Cluster.java +++ b/src/de/lmu/ifi/dbs/elki/data/Cluster.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 diff --git a/src/de/lmu/ifi/dbs/elki/data/Clustering.java b/src/de/lmu/ifi/dbs/elki/data/Clustering.java index 13203175..eaac4418 100644 --- a/src/de/lmu/ifi/dbs/elki/data/Clustering.java +++ b/src/de/lmu/ifi/dbs/elki/data/Clustering.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 diff --git a/src/de/lmu/ifi/dbs/elki/data/DoubleVector.java b/src/de/lmu/ifi/dbs/elki/data/DoubleVector.java index 76405d60..a8f8db6d 100644 --- a/src/de/lmu/ifi/dbs/elki/data/DoubleVector.java +++ b/src/de/lmu/ifi/dbs/elki/data/DoubleVector.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,15 +23,20 @@ package de.lmu.ifi.dbs.elki.data; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import gnu.trove.list.TDoubleList; + import java.io.IOException; import java.nio.ByteBuffer; import java.util.Iterator; import java.util.List; -import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil; import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** * A DoubleVector is to store real values approximately as double values. @@ -42,6 +47,11 @@ import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer; */ public class DoubleVector extends AbstractNumberVector<DoubleVector, Double> implements ByteBufferSerializer<DoubleVector> { /** + * Static factory instance + */ + public static final DoubleVector STATIC = new DoubleVector(new double[0], true); + + /** * Keeps the values of the real vector */ private double[] values; @@ -101,7 +111,7 @@ public class DoubleVector extends AbstractNumberVector<DoubleVector, Double> imp * @param columnMatrix a matrix of one column */ public DoubleVector(Vector columnMatrix) { - values = new double[columnMatrix.getRowDimensionality()]; + values = new double[columnMatrix.getDimensionality()]; for(int i = 0; i < values.length; i++) { values[i] = columnMatrix.get(i); } @@ -188,74 +198,6 @@ public class DoubleVector extends AbstractNumberVector<DoubleVector, Double> imp } @Override - public Matrix getRowVector() { - return new Matrix(new double[][] { values.clone() }); - } - - @Override - public DoubleVector plus(DoubleVector fv) { - if(fv.getDimensionality() != this.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + fv.getDimensionality() + "."); - } - double[] values = new double[this.values.length]; - for(int i = 0; i < values.length; i++) { - values[i] = this.values[i] + fv.values[i]; - } - return new DoubleVector(values, true); - } - - @Override - public DoubleVector minus(DoubleVector fv) { - if(fv.getDimensionality() != this.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + fv.getDimensionality() + "."); - } - double[] values = new double[this.values.length]; - for(int i = 0; i < values.length; i++) { - values[i] = this.values[i] - fv.values[i]; - } - return new DoubleVector(values, true); - } - - @Override - public DoubleVector nullVector() { - return new DoubleVector(new double[this.values.length], true); - } - - @Override - public DoubleVector negativeVector() { - return multiplicate(-1); - } - - @Override - public DoubleVector multiplicate(double k) { - double[] values = new double[this.values.length]; - for(int i = 0; i < values.length; i++) { - values[i] = this.values[i] * k; - } - return new DoubleVector(values, true); - } - - /** - * Provides the scalar product (inner product) of this and the given - * DoubleVector. - * - * @param d the DoubleVector to compute the scalar product for - * @return the scalar product (inner product) of this and the given - * DoubleVector - */ - @Override - public Double scalarProduct(DoubleVector d) { - if(this.getDimensionality() != d.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + d.getDimensionality() + "."); - } - double result = 0.0; - for(int i = 0; i < this.getDimensionality(); i++) { - result += this.values[i] * d.values[i]; - } - return result; - } - - @Override public String toString() { StringBuffer featureLine = new StringBuffer(); for(int i = 0; i < values.length; i++) { @@ -268,23 +210,31 @@ public class DoubleVector extends AbstractNumberVector<DoubleVector, Double> imp } @Override - public DoubleVector newInstance(Vector values) { - return new DoubleVector(values); - } - - @Override - public DoubleVector newInstance(Double[] values) { + public DoubleVector newNumberVector(double[] values) { return new DoubleVector(values); } @Override - public DoubleVector newInstance(double[] values) { - return new DoubleVector(values); + public <A> DoubleVector newFeatureVector(A array, ArrayAdapter<Double, A> adapter) { + int dim = adapter.size(array); + double[] values = new double[dim]; + for(int i = 0; i < dim; i++) { + values[i] = adapter.get(array, i); + } + return new DoubleVector(values, true); } @Override - public DoubleVector newInstance(List<Double> values) { - return new DoubleVector(values); + public <A> DoubleVector newNumberVector(A array, NumberArrayAdapter<?, A> adapter) { + if(adapter == ArrayLikeUtil.TDOUBLELISTADAPTER) { + return new DoubleVector(((TDoubleList) array).toArray(), true); + } + final int dim = adapter.size(array); + double[] values = new double[dim]; + for(int i = 0; i < dim; i++) { + values[i] = adapter.getDouble(array, i); + } + return new DoubleVector(values, true); } @Override @@ -294,9 +244,9 @@ public class DoubleVector extends AbstractNumberVector<DoubleVector, Double> imp if(buffer.remaining() < len) { throw new IOException("Not enough data for a double vector!"); } - double[] values = new double[dimensionality]; + final double[] values = new double[dimensionality]; buffer.asDoubleBuffer().get(values); - return new DoubleVector(values, false); + return new DoubleVector(values, true); } @Override @@ -314,4 +264,18 @@ public class DoubleVector extends AbstractNumberVector<DoubleVector, Double> imp public int getByteSize(DoubleVector vec) { return ByteArrayUtil.SIZE_SHORT + ByteArrayUtil.SIZE_DOUBLE * vec.getDimensionality(); } + + /** + * Parameterization class + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected DoubleVector makeInstance() { + return STATIC; + } + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/ExternalID.java b/src/de/lmu/ifi/dbs/elki/data/ExternalID.java index 228b97d0..1fc9873c 100644 --- a/src/de/lmu/ifi/dbs/elki/data/ExternalID.java +++ b/src/de/lmu/ifi/dbs/elki/data/ExternalID.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 diff --git a/src/de/lmu/ifi/dbs/elki/data/FeatureVector.java b/src/de/lmu/ifi/dbs/elki/data/FeatureVector.java index c4a0fa1d..12999159 100644 --- a/src/de/lmu/ifi/dbs/elki/data/FeatureVector.java +++ b/src/de/lmu/ifi/dbs/elki/data/FeatureVector.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,7 +23,7 @@ package de.lmu.ifi.dbs.elki.data; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.List; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter; /** * Generic FeatureVector class that can contain any type of data (i.e. numerical @@ -65,16 +65,10 @@ public interface FeatureVector<V extends FeatureVector<? extends V, D>, D> { /** * Returns a new FeatureVector of V for the given values. * - * @param values the values of the featureVector + * @param array the values of the featureVector + * @param adapter adapter class + * @param <A> Array type * @return a new FeatureVector of V for the given values */ - V newInstance(D[] values); - - /** - * Returns a new FeatureVector of V for the given values. - * - * @param values the values of the featureVector - * @return a new FeatureVector of V for the given values - */ - V newInstance(List<D> values); + <A> V newFeatureVector(A array, ArrayAdapter<D, A> adapter); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/FloatVector.java b/src/de/lmu/ifi/dbs/elki/data/FloatVector.java index 6943eb8a..e34e97d9 100644 --- a/src/de/lmu/ifi/dbs/elki/data/FloatVector.java +++ b/src/de/lmu/ifi/dbs/elki/data/FloatVector.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 @@ -28,11 +28,13 @@ import java.nio.ByteBuffer; import java.util.Iterator; import java.util.List; -import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil; import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer; -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.ArrayLikeUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** * A FloatVector is to store real values approximately as float values. @@ -41,6 +43,11 @@ import de.lmu.ifi.dbs.elki.utilities.Util; */ public class FloatVector extends AbstractNumberVector<FloatVector, Float> implements ByteBufferSerializer<FloatVector> { /** + * Static factory instance + */ + public static final FloatVector STATIC = new FloatVector(new float[0], true); + + /** * Keeps the values of the float vector */ private float[] values; @@ -100,9 +107,9 @@ public class FloatVector extends AbstractNumberVector<FloatVector, Float> implem * @param columnMatrix a matrix of one column */ public FloatVector(Vector columnMatrix) { - values = new float[columnMatrix.getRowDimensionality()]; + values = new float[columnMatrix.getDimensionality()]; for(int i = 0; i < values.length; i++) { - values[i] = (float) columnMatrix.get(i, 0); + values[i] = (float) columnMatrix.get(i); } } @@ -143,75 +150,7 @@ public class FloatVector extends AbstractNumberVector<FloatVector, Float> implem @Override public Vector getColumnVector() { - return new Vector(Util.convertToDoubles(values)); - } - - @Override - public Matrix getRowVector() { - return new Matrix(new double[][] { Util.convertToDoubles(values) }); - } - - @Override - public FloatVector plus(FloatVector fv) { - if(fv.getDimensionality() != this.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + fv.getDimensionality() + "."); - } - float[] values = new float[this.values.length]; - for(int i = 0; i < values.length; i++) { - values[i] = this.values[i] + fv.getValue(i + 1); - } - return new FloatVector(values, true); - } - - @Override - public FloatVector minus(FloatVector fv) { - if(fv.getDimensionality() != this.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + fv.getDimensionality() + "."); - } - float[] values = new float[this.values.length]; - for(int i = 0; i < values.length; i++) { - values[i] = this.values[i] - fv.getValue(i + 1); - } - return new FloatVector(values, true); - } - - /** - * Provides the scalar product (inner product) of this and the given - * FloatVector. - * - * @param f the FloatVector to compute the scalar product for - * @return the scalar product (inner product) of this and the given - * FloatVector - */ - @Override - public Float scalarProduct(FloatVector f) { - if(this.getDimensionality() != f.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + f.getDimensionality() + "."); - } - float result = 0.0f; - for(int i = 0; i < this.getDimensionality(); i++) { - result += this.values[i] * f.values[i]; - } - return result; - } - - @Override - public FloatVector nullVector() { - return new FloatVector(new float[this.values.length], true); - } - - @Override - public FloatVector negativeVector() { - return multiplicate(-1); - } - - @Override - public FloatVector multiplicate(double k) { - float[] values = new float[this.values.length]; - for(int i = 0; i < values.length; i++) { - values[i] = (float) (this.values[i] * k); - } - return new FloatVector(values, true); + return new Vector(ArrayLikeUtil.toPrimitiveDoubleArray(values, ArrayLikeUtil.FLOATARRAYADAPTER)); } @Override @@ -226,30 +165,24 @@ public class FloatVector extends AbstractNumberVector<FloatVector, Float> implem return featureLine.toString(); } - /** - * @return a new FloatVector with the specified values - */ - @Override - public FloatVector newInstance(Vector values) { - return new FloatVector(values); - } - - /** - * @return a new FloatVector with the specified values - */ - @Override - public FloatVector newInstance(double[] values) { - return new FloatVector(Util.convertToFloat(values)); - } - @Override - public FloatVector newInstance(Float[] values) { - return new FloatVector(values); + public <A> FloatVector 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 new FloatVector(values, true); } @Override - public FloatVector newInstance(List<Float> values) { - return new FloatVector(values); + public <A> FloatVector 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); + } + return new FloatVector(values, true); } @Override @@ -281,4 +214,18 @@ public class FloatVector extends AbstractNumberVector<FloatVector, Float> implem public int getByteSize(FloatVector vec) { return ByteArrayUtil.SIZE_SHORT + ByteArrayUtil.SIZE_FLOAT * vec.getDimensionality(); } + + /** + * Parameterization class + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected FloatVector makeInstance() { + return STATIC; + } + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/HierarchicalClassLabel.java b/src/de/lmu/ifi/dbs/elki/data/HierarchicalClassLabel.java index 499a40be..5e958fd7 100644 --- a/src/de/lmu/ifi/dbs/elki/data/HierarchicalClassLabel.java +++ b/src/de/lmu/ifi/dbs/elki/data/HierarchicalClassLabel.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 @@ -77,7 +77,7 @@ public class HierarchicalClassLabel extends ClassLabel { this.separatorPattern = regex; this.separatorString = separator; String[] levelwiseStrings = separatorPattern.split(name); - this.levelwiseNames = new Comparable[levelwiseStrings.length]; + this.levelwiseNames = new Comparable<?>[levelwiseStrings.length]; for(int i = 0; i < levelwiseStrings.length; i++) { try { levelwiseNames[i] = new Integer(levelwiseStrings[i]); @@ -188,14 +188,19 @@ public class HierarchicalClassLabel extends ClassLabel { * Factory class * * @author Erich Schubert - * + * * @apiviz.has HierarchicalClassLabel - - «creates» * @apiviz.stereotype factory */ public static class Factory extends ClassLabel.Factory<HierarchicalClassLabel> { @Override public HierarchicalClassLabel makeFromString(String lbl) { - return new HierarchicalClassLabel(lbl); + HierarchicalClassLabel l = existing.get(lbl); + if(l == null) { + l = new HierarchicalClassLabel(lbl); + existing.put(lbl, l); + } + return l; } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/HyperBoundingBox.java b/src/de/lmu/ifi/dbs/elki/data/HyperBoundingBox.java index 3c4d50d6..feb5cace 100644 --- a/src/de/lmu/ifi/dbs/elki/data/HyperBoundingBox.java +++ b/src/de/lmu/ifi/dbs/elki/data/HyperBoundingBox.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 diff --git a/src/de/lmu/ifi/dbs/elki/data/IntegerVector.java b/src/de/lmu/ifi/dbs/elki/data/IntegerVector.java index af6d7299..ae0d8cce 100644 --- a/src/de/lmu/ifi/dbs/elki/data/IntegerVector.java +++ b/src/de/lmu/ifi/dbs/elki/data/IntegerVector.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 @@ -25,13 +25,13 @@ package de.lmu.ifi.dbs.elki.data; import java.io.IOException; import java.nio.ByteBuffer; -import java.util.Iterator; -import java.util.List; -import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil; import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer; +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; /** * An IntegerVector is to store integer values. @@ -40,6 +40,11 @@ import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer; */ public class IntegerVector extends AbstractNumberVector<IntegerVector, Integer> implements ByteBufferSerializer<IntegerVector> { /** + * Static instance (object factory) + */ + public static final IntegerVector STATIC = new IntegerVector(new int[0], true); + + /** * Keeps the values of the real vector */ private int[] values; @@ -58,20 +63,6 @@ public class IntegerVector extends AbstractNumberVector<IntegerVector, Integer> } /** - * Provides a feature vector consisting of int values according to the - * given Integer values. - * - * @param values the values to be set as values of the integer vector - */ - public IntegerVector(List<Integer> values) { - int i = 0; - this.values = new int[values.size()]; - for(Iterator<Integer> iter = values.iterator(); iter.hasNext(); i++) { - this.values[i] = (iter.next()); - } - } - - /** * Provides an IntegerVector consisting of the given integer values. * * @param values the values to be set as values of the IntegerVector @@ -81,39 +72,6 @@ public class IntegerVector extends AbstractNumberVector<IntegerVector, Integer> System.arraycopy(values, 0, this.values, 0, values.length); } - /** - * Provides an IntegerVector consisting of the given integer values. - * - * @param values the values to be set as values of the IntegerVector - */ - public IntegerVector(Integer[] values) { - this.values = new int[values.length]; - for(int i = 0; i < values.length; i++) { - this.values[i] = values[i]; - } - } - - /** - * Provides an IntegerVector consisting of the given double values. - * - * @param values the values to be set as values of the IntegerVector - */ - public IntegerVector(double[] values) { - this.values = new int[values.length]; - for(int i = 0; i < this.values.length; i++) { - this.values[i] = (int) values[i]; - } - } - - /** - * Provides an IntegerVector consisting of the given double vectors values. - * - * @param values the values to be set as values of the IntegerVector - */ - public IntegerVector(Vector values) { - this(values.getArrayRef()); - } - @Override public int getDimensionality() { return values.length; @@ -197,78 +155,6 @@ public class IntegerVector extends AbstractNumberVector<IntegerVector, Integer> } @Override - public Matrix getRowVector() { - double[] data = new double[values.length]; - for(int i = 0; i < values.length; i++) { - data[i] = values[i]; - } - return new Matrix(new double[][] { data }); - } - - @Override - public IntegerVector plus(IntegerVector fv) { - if(fv.getDimensionality() != this.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + fv.getDimensionality() + "."); - } - int[] values = new int[this.values.length]; - for(int i = 0; i < values.length; i++) { - values[i] = this.values[i] + fv.values[i]; - } - return new IntegerVector(values, true); - } - - @Override - public IntegerVector minus(IntegerVector fv) { - if(fv.getDimensionality() != this.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + fv.getDimensionality() + "."); - } - int[] values = new int[this.values.length]; - for(int i = 0; i < values.length; i++) { - values[i] = this.values[i] - fv.values[i]; - } - return new IntegerVector(values, true); - } - - @Override - public IntegerVector nullVector() { - return new IntegerVector(new int[this.values.length], true); - } - - @Override - public IntegerVector negativeVector() { - return multiplicate(-1); - } - - @Override - public IntegerVector multiplicate(double k) { - int[] values = new int[this.values.length]; - for(int i = 0; i < values.length; i++) { - values[i] = (int) (this.values[i] * k); - } - return new IntegerVector(values, true); - } - - /** - * Provides the scalar product (inner product) of this and the given - * IntegerVector. - * - * @param d the IntegerVector to compute the scalar product for - * @return the scalar product (inner product) of this and the given - * IntegerVector - */ - @Override - public Integer scalarProduct(IntegerVector d) { - if(this.getDimensionality() != d.getDimensionality()) { - throw new IllegalArgumentException("Incompatible dimensionality: " + this.getDimensionality() + " - " + d.getDimensionality() + "."); - } - double result = 0.0; - for(int i = 0; i < this.getDimensionality(); i++) { - result += this.values[i] * d.values[i]; - } - return (int) result; - } - - @Override public String toString() { StringBuffer featureLine = new StringBuffer(); for(int i = 0; i < values.length; i++) { @@ -281,23 +167,23 @@ public class IntegerVector extends AbstractNumberVector<IntegerVector, Integer> } @Override - public IntegerVector newInstance(Vector values) { - return new IntegerVector(values); - } - - @Override - public IntegerVector newInstance(Integer[] values) { - return new IntegerVector(values); - } - - @Override - public IntegerVector newInstance(double[] values) { - return new IntegerVector(values); + public <A> IntegerVector newFeatureVector(A array, ArrayAdapter<Integer, A> adapter) { + int dim = adapter.size(array); + int[] values = new int[dim]; + for(int i = 0; i < dim; i++) { + values[i] = adapter.get(array, i); + } + return new IntegerVector(values, true); } @Override - public IntegerVector newInstance(List<Integer> values) { - return new IntegerVector(values); + public <A> IntegerVector newNumberVector(A array, NumberArrayAdapter<?, A> adapter) { + int dim = adapter.size(array); + int[] values = new int[dim]; + for(int i = 0; i < dim; i++) { + values[i] = adapter.getInteger(array, i); + } + return new IntegerVector(values, true); } @Override @@ -327,4 +213,19 @@ public class IntegerVector extends AbstractNumberVector<IntegerVector, Integer> public int getByteSize(IntegerVector vec) { return ByteArrayUtil.SIZE_SHORT + ByteArrayUtil.SIZE_DOUBLE * vec.getDimensionality(); } + + + /** + * Parameterization class + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected IntegerVector makeInstance() { + return STATIC; + } + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/Interval.java b/src/de/lmu/ifi/dbs/elki/data/Interval.java index 87e1f1b9..1b16fb88 100644 --- a/src/de/lmu/ifi/dbs/elki/data/Interval.java +++ b/src/de/lmu/ifi/dbs/elki/data/Interval.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 diff --git a/src/de/lmu/ifi/dbs/elki/data/LabelList.java b/src/de/lmu/ifi/dbs/elki/data/LabelList.java index 9dc73c0f..b1182112 100644 --- a/src/de/lmu/ifi/dbs/elki/data/LabelList.java +++ b/src/de/lmu/ifi/dbs/elki/data/LabelList.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 @@ -24,6 +24,7 @@ package de.lmu.ifi.dbs.elki.data; */ import java.util.ArrayList; +import java.util.Collection; import de.lmu.ifi.dbs.elki.utilities.FormatUtil; @@ -50,7 +51,16 @@ public class LabelList extends ArrayList<String> { /** * Constructor. * - * @param initialCapacity + * @param c existing collection + */ + public LabelList(Collection<? extends String> c) { + super(c); + } + + /** + * Constructor. + * + * @param initialCapacity initial size */ public LabelList(int initialCapacity) { super(initialCapacity); @@ -60,4 +70,4 @@ public class LabelList extends ArrayList<String> { public String toString() { return FormatUtil.format(this, " "); } -} +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/ModifiableHyperBoundingBox.java b/src/de/lmu/ifi/dbs/elki/data/ModifiableHyperBoundingBox.java index 3bb7610c..b11411bd 100644 --- a/src/de/lmu/ifi/dbs/elki/data/ModifiableHyperBoundingBox.java +++ b/src/de/lmu/ifi/dbs/elki/data/ModifiableHyperBoundingBox.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 @@ -25,12 +25,12 @@ package de.lmu.ifi.dbs.elki.data; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil; +import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration; /** * MBR class allowing modifications (as opposed to {@link HyperBoundingBox}). * * @author Marisa Thoma - * */ public class ModifiableHyperBoundingBox extends HyperBoundingBox { /** @@ -115,4 +115,29 @@ public class ModifiableHyperBoundingBox extends HyperBoundingBox { public double[] getMaxRef() { return max; } -} + + /** + * Extend the bounding box by some other spatial object + * + * @param obj Spatial object to extend with + * @return true when the MBR changed. + */ + public boolean extend(SpatialComparable obj) { + final int dim = min.length; + assert (!LoggingConfiguration.DEBUG || (obj.getDimensionality() == dim)); + boolean extended = false; + for(int i = 0; i < dim; i++) { + final double omin = obj.getMin(i + 1); + final double omax = obj.getMax(i + 1); + if(omin < min[i]) { + min[i] = omin; + extended = true; + } + if(omax > max[i]) { + max[i] = omax; + extended = true; + } + } + return extended; + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/NumberVector.java b/src/de/lmu/ifi/dbs/elki/data/NumberVector.java index 409ea9b7..1964277c 100644 --- a/src/de/lmu/ifi/dbs/elki/data/NumberVector.java +++ b/src/de/lmu/ifi/dbs/elki/data/NumberVector.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 @@ -24,8 +24,9 @@ package de.lmu.ifi.dbs.elki.data; */ import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; -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.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; /** * Interface NumberVector defines the methods that should be implemented by any @@ -40,7 +41,7 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; * @apiviz.has Matrix * @apiviz.has Vector */ -public interface NumberVector<V extends NumberVector<? extends V, N>, N extends Number> extends FeatureVector<V, N>, SpatialComparable { +public interface NumberVector<V extends NumberVector<? extends V, N>, N extends Number> extends FeatureVector<V, N>, SpatialComparable, Parameterizable { /** * Returns the value in the specified dimension as double. * @@ -130,85 +131,20 @@ public interface NumberVector<V extends NumberVector<? extends V, N>, N extends Vector getColumnVector(); /** - * Returns a Matrix representing in one row and - * <code>getDimensionality()</code> columns the values of this NumberVector of - * V. - * - * @return a Matrix representing in one row and - * <code>getDimensionality()</code> columns the values of this - * NumberVector of V - */ - Matrix getRowVector(); - - /** - * Provides a null vector of the same Vector Space as this NumberVector of V - * (that is, of the same dimensionality). - * - * @return a null vector of the same Vector Space as this NumberVector of V - * (that is, of the same dimensionality) - */ - V nullVector(); - - /** - * Returns the additive inverse to this NumberVector of V. - * - * @return the additive inverse to this NumberVector of V - */ - V negativeVector(); - - /** - * Returns a new NumberVector of V that is the sum of this NumberVector of V - * and the given NumberVector of V. - * - * @param fv a NumberVector of V to be added to this NumberVector of V - * @return a new NumberVector of V that is the sum of this NumberVector of V - * and the given NumberVector of V - */ - V plus(V fv); - - /** - * Returns a new NumberVector of V that is the sum of this NumberVector of V - * and the negativeVector() of given NumberVector of V. - * - * @param fv a NumberVector of V to be subtracted to this NumberVector of V - * @return a new NumberVector of V that is the sum of this NumberVector of V - * and the negative of given NumberVector of V - */ - V minus(V fv); - - /** - * Provides the scalar product (inner product) of this NumberVector of V and - * the given NumberVector of V. - * - * @param fv the NumberVector of V to compute the scalar product for - * @return the scalar product (inner product) of this and the given - * NumberVector of V - */ - N scalarProduct(V fv); - - /** - * Returns a new NumberVector of V that is the result of a scalar - * multiplication with the given scalar. - * - * @param k a scalar to multiply this NumberVector of V with - * @return a new NumberVector of V that is the result of a scalar - * multiplication with the given scalar - */ - V multiplicate(double k); - - /** * Returns a new NumberVector of N for the given values. * * @param values the values of the NumberVector * @return a new NumberVector of N for the given values */ - V newInstance(double[] values); + V newNumberVector(double[] values); /** - * Returns a new NumberVector of N for the given values. + * Instantiate from any number-array like object. * - * @param values the values of the NumberVector - * @return a new NumberVector of N for the given values + * @param <A> Array type + * @param array Array + * @param adapter Adapter + * @return a new NumberVector of N for the given values. */ - V newInstance(Vector values); + <A> V newNumberVector(A array, NumberArrayAdapter<?, A> adapter); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/OneDimensionalDoubleVector.java b/src/de/lmu/ifi/dbs/elki/data/OneDimensionalDoubleVector.java index d686e6b2..382ff9ae 100644 --- a/src/de/lmu/ifi/dbs/elki/data/OneDimensionalDoubleVector.java +++ b/src/de/lmu/ifi/dbs/elki/data/OneDimensionalDoubleVector.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,20 +23,25 @@ package de.lmu.ifi.dbs.elki.data; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.List; - -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.datastructures.arraylike.ArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** * Specialized class implementing a one-dimensional double vector without using - * an array. Saves a little bit of memory, albeit we cannot avoid boxing as long as - * we want to implement the interface. + * an array. Saves a little bit of memory, albeit we cannot avoid boxing as long + * as we want to implement the interface. * * @author Erich Schubert */ public class OneDimensionalDoubleVector extends AbstractNumberVector<OneDimensionalDoubleVector, Double> { /** + * Static factory instance + */ + public static final OneDimensionalDoubleVector STATIC = new OneDimensionalDoubleVector(Double.NaN); + + /** * The actual data value */ double val; @@ -79,63 +84,28 @@ public class OneDimensionalDoubleVector extends AbstractNumberVector<OneDimensio } @Override - public Matrix getRowVector() { - return new Matrix(new double[][] { { val } }); + public <A> OneDimensionalDoubleVector newFeatureVector(A array, ArrayAdapter<Double, A> adapter) { + assert (adapter.size(array) == 1) : "Incorrect dimensionality for 1-dimensional vector."; + return new OneDimensionalDoubleVector(adapter.get(array, 0)); } @Override - public OneDimensionalDoubleVector nullVector() { - return new OneDimensionalDoubleVector(0.0); + public <A> OneDimensionalDoubleVector newNumberVector(A array, NumberArrayAdapter<?, A> adapter) { + assert (adapter.size(array) == 1) : "Incorrect dimensionality for 1-dimensional vector."; + return new OneDimensionalDoubleVector(adapter.getDouble(array, 0)); } - @Override - public OneDimensionalDoubleVector negativeVector() { - return new OneDimensionalDoubleVector(-this.val); - } - - @Override - public OneDimensionalDoubleVector plus(OneDimensionalDoubleVector fv) { - return new OneDimensionalDoubleVector(this.val + fv.val); - } - - @Override - public OneDimensionalDoubleVector minus(OneDimensionalDoubleVector fv) { - return new OneDimensionalDoubleVector(this.val - fv.val); - } - - @Override - public Double scalarProduct(OneDimensionalDoubleVector fv) { - return this.val * fv.val; - } - - @Override - public OneDimensionalDoubleVector multiplicate(double k) { - return new OneDimensionalDoubleVector(this.val * k); - } - - @Override - public OneDimensionalDoubleVector newInstance(double[] values) { - assert (values.length == 1) : "Incorrect dimensionality for 1-dimensional vector."; - return new OneDimensionalDoubleVector(values[0]); - } - - @Override - public OneDimensionalDoubleVector newInstance(Vector values) { - assert (values.getDimensionality() == 1) : "Incorrect dimensionality for 1-dimensional vector."; - return new OneDimensionalDoubleVector(values.get(0)); - } - - @Override - public OneDimensionalDoubleVector newInstance(Double[] values) { - assert (values != null) : "newInstace(null) is not allowed."; - assert (values.length == 1) : "Incorrect dimensionality for 1-dimensional vector."; - return new OneDimensionalDoubleVector(values[0]); - } - - @Override - public OneDimensionalDoubleVector newInstance(List<Double> values) { - assert (values != null) : "newInstace(null) is not allowed."; - assert (values.size() == 1) : "Incorrect dimensionality for 1-dimensional vector."; - return new OneDimensionalDoubleVector(values.get(0)); + /** + * Parameterization class + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected OneDimensionalDoubleVector makeInstance() { + return STATIC; + } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/ParameterizationFunction.java b/src/de/lmu/ifi/dbs/elki/data/ParameterizationFunction.java index b74c902d..29e46c96 100644 --- a/src/de/lmu/ifi/dbs/elki/data/ParameterizationFunction.java +++ b/src/de/lmu/ifi/dbs/elki/data/ParameterizationFunction.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 @@ -30,6 +30,9 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable; import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream; import de.lmu.ifi.dbs.elki.utilities.FormatUtil; +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; /** * A parameterization function describes all lines in a d-dimensional feature @@ -61,6 +64,11 @@ public class ParameterizationFunction extends DoubleVector implements TextWritea } /** + * Static factory + */ + public static final ParameterizationFunction STATIC = new ParameterizationFunction(new double[] { 0.0 }); + + /** * A small number to handle numbers near 0 as 0. */ public static final double DELTA = 1E-10; @@ -549,22 +557,41 @@ public class ParameterizationFunction extends DoubleVector implements TextWritea } @Override - public DoubleVector newInstance(double[] values) { + public ParameterizationFunction newNumberVector(double[] values) { return new ParameterizationFunction(values); } @Override - public DoubleVector newInstance(Vector values) { + public <A> ParameterizationFunction newFeatureVector(A array, ArrayAdapter<Double, A> adapter) { + final int dim = adapter.size(array); + double[] values = new double[dim]; + for(int i = 0; i < dim; i++) { + values[i] = adapter.get(array, i); + } return new ParameterizationFunction(values); } @Override - public DoubleVector newInstance(Double[] values) { + public <A> ParameterizationFunction newNumberVector(A array, NumberArrayAdapter<?, A> adapter) { + final int dim = adapter.size(array); + double[] values = new double[dim]; + for(int i = 0; i < dim; i++) { + values[i] = adapter.getDouble(array, i); + } return new ParameterizationFunction(values); } - @Override - public DoubleVector newInstance(List<Double> values) { - return new ParameterizationFunction(values); + /** + * Parameterization class + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected ParameterizationFunction makeInstance() { + return STATIC; + } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/RationalNumber.java b/src/de/lmu/ifi/dbs/elki/data/RationalNumber.java index ac26b926..5b2e08fa 100644 --- a/src/de/lmu/ifi/dbs/elki/data/RationalNumber.java +++ b/src/de/lmu/ifi/dbs/elki/data/RationalNumber.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 diff --git a/src/de/lmu/ifi/dbs/elki/data/SimpleClassLabel.java b/src/de/lmu/ifi/dbs/elki/data/SimpleClassLabel.java index b71dd9bb..ad88295e 100644 --- a/src/de/lmu/ifi/dbs/elki/data/SimpleClassLabel.java +++ b/src/de/lmu/ifi/dbs/elki/data/SimpleClassLabel.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,7 +23,6 @@ package de.lmu.ifi.dbs.elki.data; along with this program. If not, see <http://www.gnu.org/licenses/>. */ - /** * A simple class label casting a String as it is as label. * @@ -36,10 +35,10 @@ public class SimpleClassLabel extends ClassLabel { * Holds the String designating the label. */ private String label; - + /** * Constructor. - * + * * @param label Label */ public SimpleClassLabel(String label) { @@ -107,14 +106,19 @@ public class SimpleClassLabel extends ClassLabel { * Factory class * * @author Erich Schubert - * + * * @apiviz.has SimpleClassLabel - - «creates» * @apiviz.stereotype factory */ public static class Factory extends ClassLabel.Factory<SimpleClassLabel> { @Override public SimpleClassLabel makeFromString(String lbl) { - return new SimpleClassLabel(lbl); + SimpleClassLabel l = existing.get(lbl); + if(l == null) { + l = new SimpleClassLabel(lbl); + existing.put(lbl, l); + } + return l; } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/SparseFeatureVector.java b/src/de/lmu/ifi/dbs/elki/data/SparseFeatureVector.java index aad17813..4359d841 100644 --- a/src/de/lmu/ifi/dbs/elki/data/SparseFeatureVector.java +++ b/src/de/lmu/ifi/dbs/elki/data/SparseFeatureVector.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 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()); +} diff --git a/src/de/lmu/ifi/dbs/elki/data/SparseNumberVector.java b/src/de/lmu/ifi/dbs/elki/data/SparseNumberVector.java index 03038344..d337d08b 100644 --- a/src/de/lmu/ifi/dbs/elki/data/SparseNumberVector.java +++ b/src/de/lmu/ifi/dbs/elki/data/SparseNumberVector.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 diff --git a/src/de/lmu/ifi/dbs/elki/data/Subspace.java b/src/de/lmu/ifi/dbs/elki/data/Subspace.java index c0174fb2..cd9074a8 100644 --- a/src/de/lmu/ifi/dbs/elki/data/Subspace.java +++ b/src/de/lmu/ifi/dbs/elki/data/Subspace.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 @@ -62,9 +62,8 @@ public class Subspace<V extends FeatureVector<V, ?>> { * @param dimensions the dimensions building this subspace */ public Subspace(BitSet dimensions) { - for(int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) { - this.dimensions.set(d); - } + this.dimensions.clear(); + this.dimensions.or(dimensions); dimensionality = dimensions.cardinality(); } @@ -74,7 +73,7 @@ public class Subspace<V extends FeatureVector<V, ?>> { * @return the dimensions of this subspace */ public final BitSet getDimensions() { - return dimensions; + return (BitSet) dimensions.clone(); } /** diff --git a/src/de/lmu/ifi/dbs/elki/data/VectorUtil.java b/src/de/lmu/ifi/dbs/elki/data/VectorUtil.java index 159fd9a8..1607b482 100644 --- a/src/de/lmu/ifi/dbs/elki/data/VectorUtil.java +++ b/src/de/lmu/ifi/dbs/elki/data/VectorUtil.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,10 +23,13 @@ package de.lmu.ifi.dbs.elki.data; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import java.util.BitSet; import java.util.Random; +import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; import de.lmu.ifi.dbs.elki.math.DoubleMinMax; import de.lmu.ifi.dbs.elki.math.MathUtil; +import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; /** * Utility functions for use with vectors. @@ -35,17 +38,17 @@ import de.lmu.ifi.dbs.elki.math.MathUtil; * * @author Erich Schubert * - * @apiviz.uses de.lmu.ifi.dbs.elki.data.NumberVector + * @apiviz.uses NumberVector */ public final class VectorUtil { /** - * Return the range across all dimensions. Useful in particular for time series. + * Return the range across all dimensions. Useful in particular for time + * series. * * @param vec Vector to process. - * @param <V> Vector type * @return [min, max] */ - public static <V extends NumberVector<?, ?>> DoubleMinMax getRangeDouble(V vec) { + public static DoubleMinMax getRangeDouble(NumberVector<?, ?> vec) { DoubleMinMax minmax = new DoubleMinMax(); for(int i = 0; i < vec.getDimensionality(); i++) { @@ -64,7 +67,7 @@ public final class VectorUtil { * @return new instance */ public static <V extends NumberVector<V, ?>> V randomVector(V template, Random r) { - return template.newInstance(MathUtil.randomDoubleArray(template.getDimensionality(), r)); + return template.newNumberVector(MathUtil.randomDoubleArray(template.getDimensionality(), r)); } /** @@ -77,4 +80,192 @@ public final class VectorUtil { public static <V extends NumberVector<V, ?>> V randomVector(V template) { return randomVector(template, new Random()); } + + /** + * Compute the angle for sparse vectors. + * + * @param v1 First vector + * @param v2 Second vector + * @return angle + */ + public static double angleSparse(SparseNumberVector<?, ?> v1, SparseNumberVector<?, ?> v2) { + BitSet b1 = v1.getNotNullMask(); + BitSet b2 = v2.getNotNullMask(); + BitSet both = (BitSet) b1.clone(); + both.and(b2); + + // Length of first vector + double l1 = 0.0; + for(int i = b1.nextSetBit(0); i >= 0; i = b1.nextSetBit(i + 1)) { + final double val = v1.doubleValue(i); + l1 += val * val; + } + l1 = Math.sqrt(l1); + + // Length of second vector + double l2 = 0.0; + for(int i = b2.nextSetBit(0); i >= 0; i = b2.nextSetBit(i + 1)) { + final double val = v2.doubleValue(i); + l2 += val * val; + } + l2 = Math.sqrt(l2); + + // Cross product + double cross = 0.0; + for(int i = both.nextSetBit(0); i >= 0; i = both.nextSetBit(i + 1)) { + cross += v1.doubleValue(i) * v2.doubleValue(i); + } + return cross / (l1 * l2); + } + + /** + * Compute the angle between two vectors. + * + * @param v1 first vector + * @param v2 second vector + * @param o Origin + * @return Angle + */ + public static double angle(NumberVector<?, ?> v1, NumberVector<?, ?> v2, Vector o) { + // Essentially, we want to compute this: + // v1' = v1 - o, v2' = v2 - o + // v1'.transposeTimes(v2') / (v1'.euclideanLength()*v2'.euclideanLength()); + // We can just compute all three in parallel. + double[] oe = o.getArrayRef(); + final int dim = v1.getDimensionality(); + double s = 0, e1 = 0, e2 = 0; + for(int k = 0; k < dim; k++) { + final double r1 = v1.doubleValue(k + 1) - oe[k]; + final double r2 = v2.doubleValue(k + 1) - oe[k]; + s += r1 * r2; + e1 += r1 * r1; + e2 += r2 * r2; + } + return Math.sqrt((s / e1) * (s / e2)); + } + + /** + * Compute the angle between two vectors. + * + * @param v1 first vector + * @param v2 second vector + * @param o Origin + * @return Angle + */ + public static double angle(NumberVector<?, ?> v1, NumberVector<?, ?> v2, NumberVector<?, ?> o) { + // Essentially, we want to compute this: + // v1' = v1 - o, v2' = v2 - o + // v1'.transposeTimes(v2') / (v1'.euclideanLength()*v2'.euclideanLength()); + // We can just compute all three in parallel. + final int dim = v1.getDimensionality(); + double s = 0, e1 = 0, e2 = 0; + for(int k = 0; k < dim; k++) { + final double r1 = v1.doubleValue(k + 1) - o.doubleValue(k + 1); + final double r2 = v2.doubleValue(k + 1) - o.doubleValue(k + 1); + s += r1 * r2; + e1 += r1 * r1; + e2 += r2 * r2; + } + return Math.sqrt((s / e1) * (s / e2)); + } + + /** + * Compute the absolute cosine of the angle between two vectors. + * + * To convert it to radians, use <code>Math.acos(angle)</code>! + * + * @param v1 first vector + * @param v2 second vector + * @return Angle + */ + public static double cosAngle(NumberVector<?, ?> v1, NumberVector<?, ?> v2) { + if(v1 instanceof SparseNumberVector<?, ?> && v2 instanceof SparseNumberVector<?, ?>) { + return angleSparse((SparseNumberVector<?, ?>) v1, (SparseNumberVector<?, ?>) v2); + } + // Essentially, we want to compute this: + // v1.transposeTimes(v2) / (v1.euclideanLength() * v2.euclideanLength()); + // We can just compute all three in parallel. + final int d1 = v1.getDimensionality(); + final int d2 = v2.getDimensionality(); + final int dim = Math.min(d1, d2); + double s = 0, e1 = 0, e2 = 0; + for(int k = 0; k < dim; k++) { + final double r1 = v1.doubleValue(k + 1); + final double r2 = v2.doubleValue(k + 1); + s += r1 * r2; + e1 += r1 * r1; + e2 += r2 * r2; + } + for(int k = dim; k < d1; k++) { + final double r1 = v1.doubleValue(k + 1); + e1 += r1 * r1; + } + for(int k = dim; k < d2; k++) { + final double r2 = v2.doubleValue(k + 1); + e2 += r2 * r2; + } + return Math.min(Math.sqrt((s / e1) * (s / e2)), 1); + } + + // TODO: add more precise but slower O(n^2) angle computation according to: + // Computing the Angle between Vectors, P. Schatte + // Journal of Computing, Volume 63, Number 1 (1999) + + /** + * Compute the minimum angle between two rectangles. + * + * @param v1 first rectangle + * @param v2 second rectangle + * @return Angle + */ + public static double minCosAngle(SpatialComparable v1, SpatialComparable v2) { + if(v1 instanceof NumberVector<?, ?> && v2 instanceof NumberVector<?, ?>) { + return cosAngle((NumberVector<?, ?>) v1, (NumberVector<?, ?>) v2); + } + // Essentially, we want to compute this: + // absmax(v1.transposeTimes(v2))/(min(v1.euclideanLength())*min(v2.euclideanLength())); + // We can just compute all three in parallel. + final int dim = v1.getDimensionality(); + double s1 = 0, s2 = 0, e1 = 0, e2 = 0; + for(int k = 0; k < dim; k++) { + final double min1 = v1.getMin(k + 1), max1 = v1.getMax(k + 1); + final double min2 = v2.getMin(k + 1), max2 = v2.getMax(k + 1); + final double p1 = min1 * min2, p2 = min1 * max2; + final double p3 = max1 * min2, p4 = max1 * max2; + s1 += Math.max(Math.max(p1, p2), Math.max(p3, p4)); + s2 += Math.min(Math.min(p1, p2), Math.min(p3, p4)); + if(max1 < 0) { + e1 += max1 * max1; + } + else if(min1 > 0) { + e1 += min1 * min1; + } // else: 0 + if(max2 < 0) { + e2 += max2 * max2; + } + else if(min2 > 0) { + e2 += min2 * min2; + } // else: 0 + } + final double s = Math.max(s1, Math.abs(s2)); + return Math.min(Math.sqrt((s / e1) * (s / e2)), 1.0); + } + + /** + * Provides the scalar product (inner product) of this and the given + * DoubleVector. + * + * @param d1 the first vector to compute the scalar product for + * @param d2 the second vector to compute the scalar product for + * @return the scalar product (inner product) of this and the given + * DoubleVector + */ + public static double scalarProduct(NumberVector<?, ?> d1, NumberVector<?, ?> d2) { + final int dim = d1.getDimensionality(); + double result = 0.0; + for(int i = 1; i <= dim; i++) { + result += d1.doubleValue(i) * d2.doubleValue(i); + } + return result; + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/images/AbstractComputeColorHistogram.java b/src/de/lmu/ifi/dbs/elki/data/images/AbstractComputeColorHistogram.java index 70d635d1..cb6ca494 100644 --- a/src/de/lmu/ifi/dbs/elki/data/images/AbstractComputeColorHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/data/images/AbstractComputeColorHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.images; 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 @@ -27,30 +27,57 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; + /** * Abstract class for color histogram computation. - * + * * @author Erich Schubert * * @apiviz.uses ImageUtil */ public abstract class AbstractComputeColorHistogram implements ComputeColorHistogram { @Override - public double[] computeColorHistogram(File file) throws IOException { + public double[] computeColorHistogram(File file, File mask) throws IOException { BufferedImage image = ImageUtil.loadImage(file); int height = image.getHeight(); int width = image.getWidth(); + + BufferedImage maski = null; + if(mask != null) { + maski = ImageUtil.loadImage(mask); + if(maski.getHeight() != height || maski.getWidth() != width) { + throw new AbortException("Input image and mask do not agree on the image size!"); + } + } + double[] bins = new double[getNumBins()]; + long valid = 0; for(int x = 0; x < width; x++) { for(int y = 0; y < height; y++) { + if(maski != null) { + int col = maski.getRGB(x, y); + // More transparent than covering + if((col >>> 24) < 127) { + continue; + } + // More black than white: (R+G+B) > 1.5 * 255 + if(((col >>> 16) & 0xFF) + ((col >>> 8) & 0xFF) + (col & 0xFF) < 382) { + continue; + } + } int bin = getBinForColor(image.getRGB(x, y)); - assert(bin < bins.length); + assert (bin < bins.length); bins[bin] += 1; + valid += 1; } } - for (int i = 0; i < bins.length; i++) { - bins[i] /= height * width; + if (valid == 0) { + throw new AbortException("Mask apparently was all-black."); + } + for(int i = 0; i < bins.length; i++) { + bins[i] /= valid; } return bins; } diff --git a/src/de/lmu/ifi/dbs/elki/data/images/BlendComposite.java b/src/de/lmu/ifi/dbs/elki/data/images/BlendComposite.java index 459a8698..e45d27bd 100644 --- a/src/de/lmu/ifi/dbs/elki/data/images/BlendComposite.java +++ b/src/de/lmu/ifi/dbs/elki/data/images/BlendComposite.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.images; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/images/ComputeColorHistogram.java b/src/de/lmu/ifi/dbs/elki/data/images/ComputeColorHistogram.java index 2c82c5bd..a13a4086 100644 --- a/src/de/lmu/ifi/dbs/elki/data/images/ComputeColorHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/data/images/ComputeColorHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.images; 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 @@ -39,9 +39,14 @@ public interface ComputeColorHistogram extends Parameterizable { /** * Compute a color histogram given a file name. * + * The mask file (which may be null) is expected to use >50% transparent or + * black to mask pixels, Non-transparent white to keep pixels. Alpha values + * are not used. + * * @param file File name + * @param mask Mask file (optional) * @return Color histogram * @throws IOException on file read errors. */ - public double[] computeColorHistogram(File file) throws IOException; + public double[] computeColorHistogram(File file, File mask) throws IOException; }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/images/ComputeHSBColorHistogram.java b/src/de/lmu/ifi/dbs/elki/data/images/ComputeHSBColorHistogram.java index bec59540..e5d91aa4 100644 --- a/src/de/lmu/ifi/dbs/elki/data/images/ComputeHSBColorHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/data/images/ComputeHSBColorHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.images; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveHSBColorHistogram.java b/src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveHSBColorHistogram.java index ab912cff..4fb887e7 100644 --- a/src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveHSBColorHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveHSBColorHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.images; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveRGBColorHistogram.java b/src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveRGBColorHistogram.java index 2032bd62..3e6e8c64 100644 --- a/src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveRGBColorHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveRGBColorHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.images; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/images/ImageUtil.java b/src/de/lmu/ifi/dbs/elki/data/images/ImageUtil.java index 37079f96..10722c36 100644 --- a/src/de/lmu/ifi/dbs/elki/data/images/ImageUtil.java +++ b/src/de/lmu/ifi/dbs/elki/data/images/ImageUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.images; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/images/package-info.java b/src/de/lmu/ifi/dbs/elki/data/images/package-info.java index f78b52b9..c851a21a 100644 --- a/src/de/lmu/ifi/dbs/elki/data/images/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/data/images/package-info.java @@ -7,7 +7,7 @@ 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/model/BaseModel.java b/src/de/lmu/ifi/dbs/elki/data/model/BaseModel.java index f7f69e07..56d7cd3f 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/BaseModel.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/BaseModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model; 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 @@ -29,7 +29,6 @@ import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream; * Abstract base class for Cluster Models. * * @author Erich Schubert - * */ public abstract class BaseModel implements Model { /** diff --git a/src/de/lmu/ifi/dbs/elki/data/model/Bicluster.java b/src/de/lmu/ifi/dbs/elki/data/model/Bicluster.java index f06b321f..371c4d02 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/Bicluster.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/Bicluster.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model; 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 @@ -24,7 +24,6 @@ package de.lmu.ifi.dbs.elki.data.model; */ import java.util.Arrays; -import java.util.Collections; import java.util.Iterator; import de.lmu.ifi.dbs.elki.data.FeatureVector; @@ -86,7 +85,7 @@ public class Bicluster<V extends FeatureVector<?, ?>> implements TextWriteable, @Deprecated public Bicluster(int[] rowIDs, int[] colIDs, Relation<V> database) { ArrayModifiableDBIDs ids = DBIDUtil.newArray(rowIDs.length); - for (int rowid : rowIDs) { + for(int rowid : rowIDs) { ids.add(DBIDUtil.importInteger(rowid)); } this.rowIDs = ids; @@ -101,7 +100,7 @@ public class Bicluster<V extends FeatureVector<?, ?>> implements TextWriteable, if(!(this.rowIDs instanceof ModifiableDBIDs)) { this.rowIDs = DBIDUtil.newArray(this.rowIDs); } - Collections.sort(this.rowIDs); + ((ArrayModifiableDBIDs) this.rowIDs).sort(); Arrays.sort(this.colIDs); } diff --git a/src/de/lmu/ifi/dbs/elki/data/model/BiclusterWithInverted.java b/src/de/lmu/ifi/dbs/elki/data/model/BiclusterWithInverted.java index 1eb53b42..10f3bed2 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/BiclusterWithInverted.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/BiclusterWithInverted.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model; 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,8 +23,6 @@ package de.lmu.ifi.dbs.elki.data.model; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.Collections; - import de.lmu.ifi.dbs.elki.data.FeatureVector; import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs; @@ -95,7 +93,7 @@ public class BiclusterWithInverted<V extends FeatureVector<V, ?>> extends Biclus public void sortIDs() { super.sortIDs(); if(this.invertedRows != null) { - Collections.sort(this.invertedRows); + this.invertedRows.sort(); } } diff --git a/src/de/lmu/ifi/dbs/elki/data/model/ClusterModel.java b/src/de/lmu/ifi/dbs/elki/data/model/ClusterModel.java index f40b4b73..260c9a66 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/ClusterModel.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/ClusterModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model; 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,22 +23,22 @@ package de.lmu.ifi.dbs.elki.data.model; along with this program. If not, see <http://www.gnu.org/licenses/>. */ - /** - * Generic cluster model. Does not supply additional meta information except that it is a cluster. - * Since there is no meta information, you should use the static {@link #CLUSTER} object. + * Generic cluster model. Does not supply additional meta information except + * that it is a cluster. Since there is no meta information, you should use the + * static {@link #CLUSTER} object. * * @author Erich Schubert - * + * * @apiviz.landmark */ public final class ClusterModel extends BaseModel { /** - * Static cluster model that can be shared for all clusters (since the object doesn't include meta information. + * Static cluster model that can be shared for all clusters (since the object + * doesn't include meta information. */ public final static ClusterModel CLUSTER = new ClusterModel(); - /** {@inheritDoc} */ @Override public String toString() { return "ClusterModel"; diff --git a/src/de/lmu/ifi/dbs/elki/data/model/CorrelationAnalysisSolution.java b/src/de/lmu/ifi/dbs/elki/data/model/CorrelationAnalysisSolution.java index 2f8c2d15..e6cb893f 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/CorrelationAnalysisSolution.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/CorrelationAnalysisSolution.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model; 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 @@ -34,8 +34,8 @@ import de.lmu.ifi.dbs.elki.logging.LoggingUtil; import de.lmu.ifi.dbs.elki.math.linearalgebra.LinearEquationSystem; import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; -import de.lmu.ifi.dbs.elki.datasource.filter.NonNumericFeaturesException; -import de.lmu.ifi.dbs.elki.datasource.filter.Normalization; +import de.lmu.ifi.dbs.elki.datasource.filter.normalization.NonNumericFeaturesException; +import de.lmu.ifi.dbs.elki.datasource.filter.normalization.Normalization; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable; import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream; @@ -226,10 +226,9 @@ public class CorrelationAnalysisSolution<V extends NumberVector<V, ?>> implement Vector centered = p.getColumnVector().minus(centroid); Matrix sum = new Matrix(p.getDimensionality(), strongEigenvectors.getColumnDimensionality()); for(int i = 0; i < strongEigenvectors.getColumnDimensionality(); i++) { - Vector v_i = strongEigenvectors.getColumnVector(i); - Vector proj = v_i.times(centered.scalarProduct(v_i)); - - sum.setColumnVector(i, proj); + Vector v_i = strongEigenvectors.getCol(i); + v_i.timesEquals(centered.transposeTimes(v_i)); + sum.setCol(i, v_i); } return sum; } diff --git a/src/de/lmu/ifi/dbs/elki/data/model/CorrelationModel.java b/src/de/lmu/ifi/dbs/elki/data/model/CorrelationModel.java index 0aa56478..fa4d33fa 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/CorrelationModel.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/CorrelationModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/model/DendrogramModel.java b/src/de/lmu/ifi/dbs/elki/data/model/DendrogramModel.java index e0b39795..e4bcba52 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/DendrogramModel.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/DendrogramModel.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.data.model; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/model/DimensionModel.java b/src/de/lmu/ifi/dbs/elki/data/model/DimensionModel.java index 07857aa7..104ade9a 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/DimensionModel.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/DimensionModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/model/EMModel.java b/src/de/lmu/ifi/dbs/elki/data/model/EMModel.java index 62c5c2a5..3ba6a981 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/EMModel.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/EMModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/model/LinearEquationModel.java b/src/de/lmu/ifi/dbs/elki/data/model/LinearEquationModel.java index 3716ffa7..366c7717 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/LinearEquationModel.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/LinearEquationModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/model/MeanModel.java b/src/de/lmu/ifi/dbs/elki/data/model/MeanModel.java index b9747f75..761837be 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/MeanModel.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/MeanModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/model/Model.java b/src/de/lmu/ifi/dbs/elki/data/model/Model.java index d07fc926..4ffac679 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/Model.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/Model.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/model/OPTICSModel.java b/src/de/lmu/ifi/dbs/elki/data/model/OPTICSModel.java index eecf5e7a..16a9619b 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/OPTICSModel.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/OPTICSModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/model/SubspaceModel.java b/src/de/lmu/ifi/dbs/elki/data/model/SubspaceModel.java index ccaff24f..f4db1424 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/SubspaceModel.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/SubspaceModel.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/model/package-info.java b/src/de/lmu/ifi/dbs/elki/data/model/package-info.java index f150e98e..c8f514ec 100644 --- a/src/de/lmu/ifi/dbs/elki/data/model/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/data/model/package-info.java @@ -8,7 +8,7 @@ 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/package-info.java b/src/de/lmu/ifi/dbs/elki/data/package-info.java index 6cb2c08b..51c7c716 100644 --- a/src/de/lmu/ifi/dbs/elki/data/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/data/package-info.java @@ -9,7 +9,7 @@ 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/projection/AbstractFeatureSelection.java b/src/de/lmu/ifi/dbs/elki/data/projection/AbstractFeatureSelection.java new file mode 100644 index 00000000..fcd5fd84 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/data/projection/AbstractFeatureSelection.java @@ -0,0 +1,64 @@ +package de.lmu.ifi.dbs.elki.data.projection; + +import de.lmu.ifi.dbs.elki.data.FeatureVector; +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2012 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; +import de.lmu.ifi.dbs.elki.data.type.TypeInformation; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.SubsetArrayAdapter; + +/** + * Abstract feature selection projection + * + * @author Erich Schubert + * + * @param <V> Vector type + * @param <F> Feature type + */ +public abstract class AbstractFeatureSelection<V extends FeatureVector<V, F>, F> implements Projection<V, V> { + /** + * Array adapter + */ + protected SubsetArrayAdapter<F, V> adapter; + + /** + * Constructor. + * + * @param adapter Data adapter + */ + public AbstractFeatureSelection(SubsetArrayAdapter<F, V> adapter) { + super(); + this.adapter = adapter; + } + + @Override + public V project(V data) { + return data.newFeatureVector(data, adapter); + } + + @Override + abstract public SimpleTypeInformation<V> getOutputDataTypeInformation(); + + @Override + abstract public TypeInformation getInputDataTypeInformation(); +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/projection/FeatureSelection.java b/src/de/lmu/ifi/dbs/elki/data/projection/FeatureSelection.java new file mode 100644 index 00000000..fca75e3f --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/data/projection/FeatureSelection.java @@ -0,0 +1,104 @@ +package de.lmu.ifi.dbs.elki.data.projection; +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2012 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import de.lmu.ifi.dbs.elki.data.FeatureVector; +import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; +import de.lmu.ifi.dbs.elki.data.type.TypeInformation; +import de.lmu.ifi.dbs.elki.data.type.VectorTypeInformation; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.SubsetArrayAdapter; + +/** + * Projection class for number vectors. + * + * @author Erich Schubert + * + * @param <V> Vector type + * @param <F> Feature type + */ +public class FeatureSelection<V extends FeatureVector<V, F>, F> extends AbstractFeatureSelection<V, F> { + /** + * Minimum dimensionality required for projection + */ + private int mindim; + + /** + * Object factory + */ + private V factory; + + /** + * Output dimensionality + */ + private int dimensionality; + + /** + * Constructor. + * + * @param dims Dimensions + * @param factory Object factory + */ + public FeatureSelection(int[] dims, V factory) { + super(new SubsetArrayAdapter<F, V>(getAdapter(factory), dims)); + this.factory = factory; + this.dimensionality = dims.length; + + int mindim = 0; + for(int dim : dims) { + mindim = Math.max(mindim, dim + 1); + } + this.mindim = mindim; + } + + /** + * Choose the best adapter for this. + * + * @param factory Object factory, for type inference + * @return Adapter + */ + @SuppressWarnings("unchecked") + private static <V extends FeatureVector<V, F>, F> ArrayAdapter<F, ? super V> getAdapter(V factory) { + if(factory instanceof NumberVector) { + ArrayAdapter<?, ?> ret = ArrayLikeUtil.numberVectorAdapter((NumberVector<?, ?>) factory); + return (ArrayAdapter<F, ? super V>) ret; + } + return ArrayLikeUtil.featureVectorAdapter(factory); + } + + @Override + public SimpleTypeInformation<V> getOutputDataTypeInformation() { + @SuppressWarnings("unchecked") + final Class<V> cls = (Class<V>) factory.getClass(); + return new VectorTypeInformation<V>(cls, dimensionality, dimensionality); + } + + @Override + public TypeInformation getInputDataTypeInformation() { + @SuppressWarnings("unchecked") + final Class<V> cls = (Class<V>) factory.getClass(); + return new VectorTypeInformation<V>(cls, mindim, Integer.MAX_VALUE); + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/projection/NumericalFeatureSelection.java b/src/de/lmu/ifi/dbs/elki/data/projection/NumericalFeatureSelection.java new file mode 100644 index 00000000..7dfd580f --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/data/projection/NumericalFeatureSelection.java @@ -0,0 +1,104 @@ +package de.lmu.ifi.dbs.elki.data.projection; +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2012 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; +import de.lmu.ifi.dbs.elki.data.type.TypeInformation; +import de.lmu.ifi.dbs.elki.data.type.VectorTypeInformation; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.SubsetArrayAdapter; + +/** + * Projection class for number vectors. + * + * @author Erich Schubert + * + * @param <V> Vector type + * @param <N> Number type + */ +public class NumericalFeatureSelection<V extends NumberVector<V, N>, N extends Number> extends AbstractFeatureSelection<V, N> { + /** + * Minimum dimensionality required for projection + */ + private int mindim; + + /** + * Object factory + */ + private V factory; + + /** + * Output dimensionality + */ + private int dimensionality; + + /** + * Constructor. + * + * @param dims Dimensions + * @param factory Object factory + */ + public NumericalFeatureSelection(int[] dims, V factory) { + super(new SubsetArrayAdapter<N, V>(getAdapter(factory), dims)); + this.factory = factory; + this.dimensionality = dims.length; + + int mindim = 0; + for(int dim : dims) { + mindim = Math.max(mindim, dim + 1); + } + this.mindim = mindim; + } + + /** + * Choose the best adapter for this. + * + * @param factory Object factory, for type inference + * @return Adapter + */ + private static <V extends NumberVector<V, N>, N extends Number> NumberArrayAdapter<N, ? super V> getAdapter(V factory) { + return ArrayLikeUtil.numberVectorAdapter(factory); + } + + @SuppressWarnings("unchecked") + @Override + public V project(V data) { + return factory.newNumberVector(data, (NumberArrayAdapter<N, ? super V>) adapter); + } + + @Override + public SimpleTypeInformation<V> getOutputDataTypeInformation() { + @SuppressWarnings("unchecked") + final Class<V> cls = (Class<V>) factory.getClass(); + return new VectorTypeInformation<V>(cls, dimensionality, dimensionality); + } + + @Override + public TypeInformation getInputDataTypeInformation() { + @SuppressWarnings("unchecked") + final Class<V> cls = (Class<V>) factory.getClass(); + return new VectorTypeInformation<V>(cls, mindim, Integer.MAX_VALUE); + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/Distribution.java b/src/de/lmu/ifi/dbs/elki/data/projection/Projection.java index f93a6459..c9cd98d2 100644 --- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/Distribution.java +++ b/src/de/lmu/ifi/dbs/elki/data/projection/Projection.java @@ -1,10 +1,13 @@ -package de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution; +package de.lmu.ifi.dbs.elki.data.projection; + +import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; +import de.lmu.ifi.dbs.elki.data.type.TypeInformation; /* 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,30 +26,34 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution; along with this program. If not, see <http://www.gnu.org/licenses/>. */ - /** - * Interface for a simple distribution generator - * with a PDF, i.e. it can also compute a density + * Projection interface. * * @author Erich Schubert + * + * @param <IN> Input data type + * @param <OUT> Output data type */ -public interface Distribution { +public interface Projection<IN, OUT> { /** - * Generate a new random value - * @return new generated value + * Project a single instance. + * + * @param data Data to project + * @return Projected data */ - public double generate(); + public OUT project(IN data); + /** - * Return the density of an existing value - * @param val existing value - * @return distribution density + * Output type restriction + * + * @return Output type */ - public double explain(double val); - + public SimpleTypeInformation<OUT> getOutputDataTypeInformation(); + /** - * Describe the generator - * @return description + * Input type information. + * + * @return Type restriction */ - @Override - public String toString(); + public TypeInformation getInputDataTypeInformation(); } diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/package-info.java b/src/de/lmu/ifi/dbs/elki/data/projection/package-info.java index 6aab20ab..d39c51ba 100644 --- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/data/projection/package-info.java @@ -1,12 +1,11 @@ /** - * <p>Data generators used by the model-based generator.</p> - * + * <p>Data projections.</p> */ /* 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 @@ -24,4 +23,4 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution;
\ No newline at end of file +package de.lmu.ifi.dbs.elki.data.projection;
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/spatial/Polygon.java b/src/de/lmu/ifi/dbs/elki/data/spatial/Polygon.java index aa16c12e..f485c052 100644 --- a/src/de/lmu/ifi/dbs/elki/data/spatial/Polygon.java +++ b/src/de/lmu/ifi/dbs/elki/data/spatial/Polygon.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.spatial; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/spatial/PolygonsObject.java b/src/de/lmu/ifi/dbs/elki/data/spatial/PolygonsObject.java index d5d11c8d..17bed0e1 100644 --- a/src/de/lmu/ifi/dbs/elki/data/spatial/PolygonsObject.java +++ b/src/de/lmu/ifi/dbs/elki/data/spatial/PolygonsObject.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.spatial; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialComparable.java b/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialComparable.java index dc82a05b..eb9edf4e 100644 --- a/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialComparable.java +++ b/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialComparable.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.spatial; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialUtil.java b/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialUtil.java index f3bd030f..731c021a 100644 --- a/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialUtil.java +++ b/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.spatial; 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 @@ -24,6 +24,9 @@ package de.lmu.ifi.dbs.elki.data.spatial; */ import de.lmu.ifi.dbs.elki.data.HyperBoundingBox; +import de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox; +import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter; /** * Utility class with spatial functions. @@ -76,7 +79,7 @@ public final class SpatialUtil { public static boolean intersects(SpatialComparable box1, SpatialComparable box2) { final int dim = box1.getDimensionality(); if(dim != box2.getDimensionality()) { - throw new IllegalArgumentException("The spatial objects do not have the same dimensionality!"); + throw new IllegalArgumentException("The spatial objects do not have the same dimensionality: " + box1.getDimensionality() + " " + box2.getDimensionality()); } boolean intersect = true; for(int i = 1; i <= dim; i++) { @@ -146,19 +149,138 @@ public final class SpatialUtil { double vol = 1; final int dim = box.getDimensionality(); for(int i = 1; i <= dim; i++) { - vol *= box.getMax(i) - box.getMin(i); + double delta = box.getMax(i) - box.getMin(i); + if(delta == 0.0) { + return 0.0; + } + vol *= delta; + } + return vol; + } + + /** + * Compute the volume (area) of the union of two MBRs + * + * @param r1 First object + * @param r2 Second object + * @return Volume of union + */ + public static double volumeUnion(SpatialComparable r1, SpatialComparable r2) { + final int dim1 = r1.getDimensionality(); + final int dim2 = r2.getDimensionality(); + assert (!LoggingConfiguration.DEBUG || dim1 == dim2) : "Computing union with different dimensionality: " + dim1 + " vs. " + dim2; + double volume = 1.0; + for(int i = 1; i <= dim1; i++) { + final double min = Math.min(r1.getMin(i), r2.getMin(i)); + final double max = Math.max(r1.getMax(i), r2.getMax(i)); + volume *= (max - min); + } + return volume; + } + + /** + * Computes the volume of this SpatialComparable + * + * @param scale Scaling factor + * @return the volume of this SpatialComparable + */ + public static double volumeScaled(SpatialComparable box, double scale) { + double vol = 1; + final int dim = box.getDimensionality(); + for(int i = 1; i <= dim; i++) { + double delta = box.getMax(i) - box.getMin(i); + if(delta == 0.0) { + return 0.0; + } + vol *= delta * scale; } return vol; } /** + * Compute the volume (area) of the union of two MBRs + * + * @param r1 First object + * @param r2 Second object + * @param scale Scaling factor + * @return Volume of union + */ + public static double volumeUnionScaled(SpatialComparable r1, SpatialComparable r2, double scale) { + final int dim1 = r1.getDimensionality(); + final int dim2 = r2.getDimensionality(); + assert (!LoggingConfiguration.DEBUG || dim1 == dim2) : "Computing union with different dimensionality: " + dim1 + " vs. " + dim2; + double volume = 1.0; + for(int i = 1; i <= dim1; i++) { + final double min = Math.min(r1.getMin(i), r2.getMin(i)); + final double max = Math.max(r1.getMax(i), r2.getMax(i)); + volume *= (max - min) * scale; + } + return volume; + } + + /** + * Compute the enlargement obtained by adding an object to an existing object. + * + * @param exist Existing rectangle + * @param addit Additional rectangle + * @return Enlargement factor + */ + public static double enlargement(SpatialComparable exist, SpatialComparable addit) { + final int dim1 = exist.getDimensionality(); + final int dim2 = addit.getDimensionality(); + assert (!LoggingConfiguration.DEBUG || dim1 == dim2) : "Computing union with different dimensionality: " + dim1 + " vs. " + dim2; + double v1 = 1.0; + double v2 = 1.0; + for(int i = 1; i <= dim1; i++) { + final double emin = exist.getMin(i); + final double emax = exist.getMax(i); + final double amin = addit.getMin(i); + final double amax = addit.getMax(i); + + final double min = Math.min(emin, amin); + final double max = Math.max(emax, amax); + v1 *= (max - min); + v2 *= (emax - emin); + } + return v2 - v1; + } + + /** + * Compute the enlargement obtained by adding an object to an existing object. + * + * @param exist Existing rectangle + * @param addit Additional rectangle + * @param scale Scaling helper + * @return Enlargement factor + */ + public static double enlargementScaled(SpatialComparable exist, SpatialComparable addit, double scale) { + final int dim1 = exist.getDimensionality(); + final int dim2 = addit.getDimensionality(); + assert (!LoggingConfiguration.DEBUG || dim1 == dim2) : "Computing union with different dimensionality: " + dim1 + " vs. " + dim2; + double v1 = 1.0; + double v2 = 1.0; + for(int i = 1; i <= dim1; i++) { + final double emin = exist.getMin(i); + final double emax = exist.getMax(i); + final double amin = addit.getMin(i); + final double amax = addit.getMax(i); + + final double min = Math.min(emin, amin); + final double max = Math.max(emax, amax); + v1 *= (max - min) * scale; + v2 *= (emax - emin) * scale; + } + return v2 - v1; + } + + /** * Computes the perimeter of this SpatialComparable. * * @return the perimeter of this SpatialComparable */ public static double perimeter(SpatialComparable box) { - double perimeter = 0; final int dim = box.getDimensionality(); + double perimeter = 0; for(int i = 1; i <= dim; i++) { perimeter += box.getMax(i) - box.getMin(i); } @@ -166,15 +288,13 @@ public final class SpatialUtil { } /** - * Computes the volume of the overlapping box between two SpatialComparables - * and return the relation between the volume of the overlapping box and the - * volume of both SpatialComparable. + * Computes the volume of the overlapping box between two SpatialComparables. * * @param box1 the first SpatialComparable * @param box2 the second SpatialComparable - * @return the overlap volume in relation to the singular volumes. + * @return the overlap volume. */ - public static double relativeOverlap(SpatialComparable box1, SpatialComparable box2) { + public static double overlap(SpatialComparable box1, SpatialComparable box2) { final int dim = box1.getDimensionality(); if(dim != box2.getDimensionality()) { throw new IllegalArgumentException("This HyperBoundingBox and the given HyperBoundingBox need same dimensionality"); @@ -201,7 +321,49 @@ public final class SpatialUtil { overlap *= omax - omin; } - return overlap / (volume(box1) + volume(box2)); + return overlap; + } + + /** + * Computes the volume of the overlapping box between two SpatialComparables + * and return the relation between the volume of the overlapping box and the + * volume of both SpatialComparable. + * + * @param box1 the first SpatialComparable + * @param box2 the second SpatialComparable + * @return the overlap volume in relation to the singular volumes. + */ + public static double relativeOverlap(SpatialComparable box1, SpatialComparable box2) { + final int dim = box1.getDimensionality(); + if(dim != box2.getDimensionality()) { + throw new IllegalArgumentException("This HyperBoundingBox and the given HyperBoundingBox need same dimensionality"); + } + + // the overlap volume + double overlap = 1.0; + double vol1 = 1.0; + double vol2 = 1.0; + + for(int i = 1; i <= dim; i++) { + final double box1min = box1.getMin(i); + final double box1max = box1.getMax(i); + final double box2min = box2.getMin(i); + final double box2max = box2.getMax(i); + + final double omax = Math.min(box1max, box2max); + final double omin = Math.max(box1min, box2min); + + // if omax <= omin in any dimension, the overlap box has a volume of zero + if(omax <= omin) { + return 0.0; + } + + overlap *= omax - omin; + vol1 *= box1max - box1min; + vol2 *= box2max - box2min; + } + + return overlap / (vol1 + vol2); } /** @@ -212,7 +374,7 @@ public final class SpatialUtil { * @return the union HyperBoundingBox of this HyperBoundingBox and the given * HyperBoundingBox */ - public static HyperBoundingBox union(SpatialComparable box1, SpatialComparable box2) { + public static ModifiableHyperBoundingBox union(SpatialComparable box1, SpatialComparable box2) { final int dim = box1.getDimensionality(); if(dim != box2.getDimensionality()) { throw new IllegalArgumentException("This HyperBoundingBox and the given HyperBoundingBox need same dimensionality"); @@ -225,7 +387,7 @@ public final class SpatialUtil { min[i - 1] = Math.min(box1.getMin(i), box2.getMin(i)); max[i - 1] = Math.max(box1.getMax(i), box2.getMax(i)); } - return new HyperBoundingBox(min, max); + return new ModifiableHyperBoundingBox(min, max); } /** @@ -251,6 +413,34 @@ public final class SpatialUtil { } /** + * Compute the union of a number of objects as a flat MBR (low-level, for + * index structures) + * + * @param data Object + * @param getter Array adapter + * @return Flat MBR + */ + public static <E extends SpatialComparable, A> double[] unionFlatMBR(A data, ArrayAdapter<E, ? super A> getter) { + final int num = getter.size(data); + assert (num > 0) : "Cannot compute MBR of empty set."; + final E first = getter.get(data, 0); + final int dim = first.getDimensionality(); + double[] mbr = new double[2 * dim]; + for(int d = 0; d < dim; d++) { + mbr[d] = first.getMin(d + 1); + mbr[dim + d] = first.getMax(d + 1); + } + for(int i = 1; i < num; i++) { + E next = getter.get(data, i); + for(int d = 0; d < dim; d++) { + mbr[d] = Math.min(mbr[d], next.getMin(d + 1)); + mbr[dim + d] = Math.max(mbr[dim + d], next.getMax(d + 1)); + } + } + return mbr; + } + + /** * Returns the centroid of this SpatialComparable. * * @param obj Spatial object to process diff --git a/src/de/lmu/ifi/dbs/elki/data/spatial/package-info.java b/src/de/lmu/ifi/dbs/elki/data/spatial/package-info.java index 7474c14f..e418bcaf 100644 --- a/src/de/lmu/ifi/dbs/elki/data/spatial/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/data/spatial/package-info.java @@ -5,7 +5,7 @@ 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterface.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterface.java index 3c5853ed..363c6c3b 100644 --- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterface.java +++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterface.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel; 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 @@ -25,6 +25,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel; import java.util.List; +import de.lmu.ifi.dbs.elki.data.model.Model; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException; @@ -66,19 +67,15 @@ public interface GeneratorInterface { public abstract double getDensity(Vector p); /** - * Get points. - * - * NOTE: The list may be modified by the caller, it is not immutable. - * The class should not return a copy, but should allow modification. - * However when removing points, the called is expected to call setDiscarded. - * - * @return points - */ - public List<Vector> getPoints(); - - /** * Get cluster name * @return cluster name */ public String getName(); + + /** + * Make a cluster model for this cluster. + * + * @return Cluster model + */ + public Model makeModel(); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterfaceDynamic.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterfaceDynamic.java index 240cda31..cd3f18b7 100644 --- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterfaceDynamic.java +++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterfaceDynamic.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel; 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,7 +23,6 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel; along with this program. If not, see <http://www.gnu.org/licenses/>. */ - /** * Interface for a dynamic cluster generator. * @@ -41,15 +40,14 @@ public interface GeneratorInterfaceDynamic extends GeneratorInterface { public int getDiscarded(); /** - * Indicate that points were discarded. - * - * @param discarded number of points that were discarded. - */ - public void addDiscarded(int discarded); - - /** * Retrieve remaining number of retries. + * * @return remaining number of retries */ public int getRetries(); -} + + /** + * Increment the number of elements discarded. + */ + public void incrementDiscarded(); +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java index eef7b13d..6870fcaa 100644 --- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java +++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel; 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 @@ -31,6 +31,7 @@ import java.util.List; import de.lmu.ifi.dbs.elki.data.ClassLabel; import de.lmu.ifi.dbs.elki.data.DoubleVector; import de.lmu.ifi.dbs.elki.data.SimpleClassLabel; +import de.lmu.ifi.dbs.elki.data.model.Model; import de.lmu.ifi.dbs.elki.data.type.TypeUtil; import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation; import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle; @@ -91,26 +92,41 @@ public class GeneratorMain { * @throws UnableToComplyException when model not satisfiable or no clusters * specified. */ - public void generate() throws UnableToComplyException { + public MultipleObjectsBundle generate() throws UnableToComplyException { // we actually need some clusters. if(generators.size() < 1) { throw new UnableToComplyException("No clusters specified."); } // Assert that cluster dimensions agree. final int dim = generators.get(0).getDim(); - for(GeneratorInterface c : generators) { - if(c.getDim() != dim) { - throw new UnableToComplyException("Cluster dimensions do not agree."); + { + for(GeneratorInterface c : generators) { + if(c.getDim() != dim) { + throw new UnableToComplyException("Cluster dimensions do not agree."); + } } } + // Vector factory. TODO: make configurable + final DoubleVector factory = new DoubleVector(new double[dim]); + // Prepare result bundle + MultipleObjectsBundle bundle = new MultipleObjectsBundle(); + VectorFieldTypeInformation<DoubleVector> type = new VectorFieldTypeInformation<DoubleVector>(DoubleVector.class, dim, factory); + bundle.appendColumn(type, new ArrayList<Object>()); + bundle.appendColumn(TypeUtil.CLASSLABEL, new ArrayList<Object>()); + bundle.appendColumn(TypeUtil.MODEL, new ArrayList<Model>()); + // generate clusters for(GeneratorInterface curclus : generators) { - while(curclus.getPoints().size() < curclus.getSize()) { + ClassLabel l = new SimpleClassLabel(curclus.getName()); + Model model = curclus.makeModel(); + int kept = 0; + while(kept < curclus.getSize()) { // generate the "missing" number of points - List<Vector> newp = curclus.generate(curclus.getSize() - curclus.getPoints().size()); + List<Vector> newp = curclus.generate(curclus.getSize() - kept); if(curclus instanceof GeneratorInterfaceDynamic) { GeneratorInterfaceDynamic cursclus = (GeneratorInterfaceDynamic) curclus; for(Vector p : newp) { + boolean keep = true; if(testAgainstModel) { double max = 0.0; double is = 0.0; @@ -125,20 +141,23 @@ public class GeneratorMain { } // Only keep the point if the largest density was the cluster it // was generated for - if(is >= max) { - cursclus.getPoints().add(p); - } - else { - cursclus.addDiscarded(1); + if(is < max) { + keep = false; } } + if(keep) { + DoubleVector dv = new DoubleVector(p); + bundle.appendSimple(dv, l, model); + ++kept; + } else { - cursclus.getPoints().add(p); + cursclus.incrementDiscarded(); } } } } } + return bundle; } /** @@ -167,27 +186,4 @@ public class GeneratorMain { public List<GeneratorInterface> getGenerators() { return Collections.unmodifiableList(generators); } - - /** - * Get the objects bundle - * - * @return Bundle - */ - public MultipleObjectsBundle getBundle() { - final int dim = generators.get(0).getDim(); - final DoubleVector factory = new DoubleVector(new double[dim]); - MultipleObjectsBundle bundle = new MultipleObjectsBundle(); - VectorFieldTypeInformation<DoubleVector> type = new VectorFieldTypeInformation<DoubleVector>(DoubleVector.class, dim, factory); - bundle.appendColumn(type, new ArrayList<Object>()); - bundle.appendColumn(TypeUtil.CLASSLABEL, new ArrayList<Object>()); - - for(GeneratorInterface generator : generators) { - ClassLabel l = new SimpleClassLabel(generator.getName()); - for(Vector v : generator.getPoints()) { - DoubleVector dv = new DoubleVector(v); - bundle.appendSimple(dv, l); - } - } - return bundle; - } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorSingleCluster.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorSingleCluster.java index 3d54d937..f9818916 100644 --- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorSingleCluster.java +++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorSingleCluster.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel; 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,12 +23,14 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.LinkedList; +import java.util.ArrayList; +import java.util.List; import java.util.Random; -import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution.Distribution; +import de.lmu.ifi.dbs.elki.data.model.Model; import de.lmu.ifi.dbs.elki.math.linearalgebra.AffineTransformation; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; +import de.lmu.ifi.dbs.elki.math.statistics.distribution.Distribution; import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException; /** @@ -41,11 +43,11 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException; * @apiviz.composedOf Distribution * @apiviz.composedOf AffineTransformation */ -public class GeneratorSingleCluster implements GeneratorInterfaceDynamic { +public class GeneratorSingleCluster implements GeneratorInterfaceDynamic, Model { /** * The distribution generators for each axis */ - private LinkedList<Distribution> axes = new LinkedList<Distribution>(); + private List<Distribution> axes = new ArrayList<Distribution>(); /** * The transformation matrix @@ -91,11 +93,6 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic { private int discarded = 0; /** - * The generated cluster points. - */ - public LinkedList<Vector> points = new LinkedList<Vector>(); - - /** * Random generator (used for initializing random generators) */ private Random random; @@ -121,7 +118,8 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic { * so far! * * @param gen Distribution generator - * @throws UnableToComplyException thrown when no new generators may be added anymore + * @throws UnableToComplyException thrown when no new generators may be added + * anymore */ public void addGenerator(Distribution gen) throws UnableToComplyException { if(trans != null) { @@ -168,23 +166,23 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic { */ public void setClipping(Vector min, Vector max) throws UnableToComplyException { // if only one dimension was given, expand to all dimensions. - if(min.getRowDimensionality() == 1 && max.getRowDimensionality() == 1) { + if(min.getDimensionality() == 1 && max.getDimensionality() == 1) { if(min.get(0) >= max.get(0)) { throw new UnableToComplyException("Clipping range empty."); } clipmin = new Vector(dim); clipmax = new Vector(dim); for(int i = 0; i < dim; i++) { - clipmin.set(i, 0, min.get(0)); - clipmax.set(i, 0, max.get(0)); + clipmin.set(i, min.get(0)); + clipmax.set(i, max.get(0)); } return; } - if(dim != min.getRowDimensionality()) { - throw new UnableToComplyException("Clipping vector dimensionalities do not match: " + dim + " vs. " + min.getRowDimensionality()); + if(dim != min.getDimensionality()) { + throw new UnableToComplyException("Clipping vector dimensionalities do not match: " + dim + " vs. " + min.getDimensionality()); } - if(dim != max.getRowDimensionality()) { - throw new UnableToComplyException("Clipping vector dimensionalities do not match: " + dim + " vs. " + max.getRowDimensionality()); + if(dim != max.getDimensionality()) { + throw new UnableToComplyException("Clipping vector dimensionalities do not match: " + dim + " vs. " + max.getDimensionality()); } for(int i = 0; i < dim; i++) { if(min.get(i) >= max.get(i)) { @@ -215,7 +213,7 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic { if(clipmin == null || clipmax == null) { return false; } - for(int i = 0; i < p.getRowDimensionality(); i++) { + for(int i = 0; i < p.getDimensionality(); i++) { if(p.get(i) < clipmin.get(i)) { return true; } @@ -232,13 +230,13 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic { * @see de.lmu.ifi.dbs.elki.data.synthetic.bymodel.GeneratorInterface#generate(int) */ @Override - public LinkedList<Vector> generate(int count) throws UnableToComplyException { - LinkedList<Vector> result = new LinkedList<Vector>(); + public List<Vector> generate(int count) throws UnableToComplyException { + ArrayList<Vector> result = new ArrayList<Vector>(count); while(result.size() < count) { double[] d = new double[dim]; int i = 0; for(Distribution axis : axes) { - d[i] = axis.generate(); + d[i] = axis.nextRandom(); i++; } Vector p = new Vector(d); @@ -272,27 +270,18 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic { double density = 1.0; int i = 0; for(Distribution axis : axes) { - density = density * axis.explain(o.get(i)); + density = density * axis.pdf(o.get(i)); i++; } return density * densitycorrection; } /** - * Get axis generators. Used for printing model information - * - * @return list of distributions - */ - public LinkedList<Distribution> getAxes() { - return axes; - } - - /** * Get transformation * * @return transformation matrix, may be null. */ - public AffineTransformation getTrans() { + public AffineTransformation getTransformation() { return trans; } @@ -321,23 +310,6 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic { } /** - * Return the list of points (no copy) - */ - @Override - public LinkedList<Vector> getPoints() { - return points; - } - - /** - * Set the list of points in the cluster - * - * @param points New list of points in this cluster. - */ - public void setPoints(LinkedList<Vector> points) { - this.points = points; - } - - /** * Return the size * * @return size of this cluster. @@ -369,12 +341,10 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic { /** * Increase number of discarded points - * - * @param discarded number of points discarded. */ @Override - public void addDiscarded(int discarded) { - this.discarded += discarded; + public void incrementDiscarded() { + ++this.discarded; } /** @@ -413,4 +383,23 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic { public Random getNewRandomGenerator() { return new Random(random.nextLong()); } + + /** + * Make a cluster model for this cluster. + * + * @return Model + */ + public Model makeModel() { + return this; + } + + /** + * Get distribution along (generator) axis i. + * + * @param i Generator axis i + * @return Distribution + */ + public Distribution getDistribution(int i) { + return axes.get(i); + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorStatic.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorStatic.java index 6c44eaca..7075bcb4 100644 --- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorStatic.java +++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorStatic.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel; 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,12 +23,12 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.ArrayList; -import java.util.LinkedList; +import java.util.Collections; import java.util.List; +import de.lmu.ifi.dbs.elki.data.model.ClusterModel; +import de.lmu.ifi.dbs.elki.data.model.Model; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; -import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException; /** * Class for static clusters, that is an implementation of GeneratorInterface @@ -45,7 +45,7 @@ public class GeneratorStatic implements GeneratorInterface { /** * Cluster points */ - public LinkedList<Vector> points; + public List<Vector> points; /** * Construct generator using given name and points @@ -53,7 +53,7 @@ public class GeneratorStatic implements GeneratorInterface { * @param name Cluster name * @param points Cluster points */ - public GeneratorStatic(String name, LinkedList<Vector> points) { + public GeneratorStatic(String name, List<Vector> points) { super(); this.name = name; this.points = points; @@ -67,12 +67,9 @@ public class GeneratorStatic implements GeneratorInterface { */ @Override public List<Vector> generate(int count) { - return new ArrayList<Vector>(points); + return Collections.unmodifiableList(points); } - /** - * Get density at a given coordinate. - */ @Override public double getDensity(Vector p) { for(Vector my : points) { @@ -83,54 +80,23 @@ public class GeneratorStatic implements GeneratorInterface { return 0.0; } - /** - * Get cluster dimensionality - */ @Override public int getDim() { - return points.getFirst().getDimensionality(); + return points.get(0).getDimensionality(); } - /** - * Get number of discarded points - * - * @return number of discarded points - */ - public int getDiscarded() { - return 0; - } - - /** - * Get cluster name - */ @Override public String getName() { return name; } - /** - * Get cluster points - */ - @Override - public List<Vector> getPoints() { - return points; - } - - /** - * Get cluster size - */ @Override public int getSize() { return points.size(); } - /** - * Notify cluster of discarded points. Not supported for static generators. - * - * @param discarded parameter not supported. - * @throws UnableToComplyException always thrown, since the static generator doesn't supprot discards. - */ - public void setDiscarded(int discarded) throws UnableToComplyException { - throw new UnableToComplyException("Points in static clusters may never be discarded."); + @Override + public Model makeModel() { + return ClusterModel.CLUSTER; } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/GammaDistribution.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/GammaDistribution.java deleted file mode 100644 index 156ac3c4..00000000 --- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/GammaDistribution.java +++ /dev/null @@ -1,305 +0,0 @@ -package de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2011 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import java.util.Random; - -import de.lmu.ifi.dbs.elki.math.MathUtil; - -/** - * Simple generator for a Gamma Distribution - * - * @author Erich Schubert - */ -public final class GammaDistribution implements Distribution { - /** - * Alpha == k - */ - private final double k; - - /** - * Theta == 1 / Beta - */ - private final double theta; - - /** - * The random generator. - */ - private Random random; - - /** - * Constructor for Gamma distribution generator - * - * @param k k, alpha aka. "shape" parameter - * @param theta Theta = 1.0/Beta aka. "scaling" parameter - * @param random Random generator - */ - public GammaDistribution(double k, double theta, Random random) { - super(); - if(k <= 0.0 || theta <= 0.0) { - throw new IllegalArgumentException("Invalid parameters for Gamma distribution."); - } - - this.k = k; - this.theta = theta; - this.random = random; - } - - /** - * Gamma distribution PDF (with 0.0 for x < 0) - * - * @param x query value - * @param k Alpha - * @param theta Thetha = 1 / Beta - * @return probability density - */ - public static double pdf(double x, double k, double theta) { - if(x < 0) { - return 0.0; - } - if(x == 0) { - if(k == 1.0) { - return theta; - } - else { - return 0.0; - } - } - if(k == 1.0) { - return Math.exp(-x * theta) * theta; - } - - return Math.exp((k - 1.0) * Math.log(x * theta) - x * theta - MathUtil.logGamma(k)) * theta; - } - - /** - * Return the PDF of the generators distribution - */ - @Override - public double explain(double val) { - return pdf(val, k, theta); - } - - /** - * Generate a random value with the generators parameters. - * - * Along the lines of - * - * - J.H. Ahrens, U. Dieter (1974): Computer methods for sampling from gamma, - * beta, Poisson and binomial distributions, Computing 12, 223-246. - * - * - J.H. Ahrens, U. Dieter (1982): Generating gamma variates by a modified - * rejection technique, Communications of the ACM 25, 47-54. - */ - @Override - public double generate() { - /* Constants */ - final double q1 = 0.0416666664, q2 = 0.0208333723, q3 = 0.0079849875; - final double q4 = 0.0015746717, q5 = -0.0003349403, q6 = 0.0003340332; - final double q7 = 0.0006053049, q8 = -0.0004701849, q9 = 0.0001710320; - final double a1 = 0.333333333, a2 = -0.249999949, a3 = 0.199999867; - final double a4 = -0.166677482, a5 = 0.142873973, a6 = -0.124385581; - final double a7 = 0.110368310, a8 = -0.112750886, a9 = 0.104089866; - final double e1 = 1.000000000, e2 = 0.499999994, e3 = 0.166666848; - final double e4 = 0.041664508, e5 = 0.008345522, e6 = 0.001353826; - final double e7 = 0.000247453; - - if(k < 1.0) { // Base case, for small k - final double b = 1.0 + 0.36788794412 * k; // Step 1 - while(true) { - final double p = b * random.nextDouble(); - if(p <= 1.0) { // when gds <= 1 - final double gds = Math.exp(Math.log(p) / k); - if(Math.log(random.nextDouble()) <= -gds) { - return (gds / theta); - } - } - else { // when gds > 1 - final double gds = -Math.log((b - p) / k); - if(Math.log(random.nextDouble()) <= ((k - 1.0) * Math.log(gds))) { - return (gds / theta); - } - } - } - } - else { - // Step 1. Preparations - final double ss, s, d; - if(k != -1.0) { - ss = k - 0.5; - s = Math.sqrt(ss); - d = 5.656854249 - 12.0 * s; - } - else { - // For k == -1.0: - ss = 0.0; - s = 0.0; - d = 0.0; - } - // Random vector of maximum length 1 - final double v1, /* v2, */v12; - { // Temporary values - candidate - double tv1, tv2, tv12; - do { - tv1 = 2.0 * random.nextDouble() - 1.0; - tv2 = 2.0 * random.nextDouble() - 1.0; - tv12 = tv1 * tv1 + tv2 * tv2; - } - while(tv12 > 1.0); - v1 = tv1; - /* v2 = tv2; */ - v12 = tv12; - } - - // double b = 0.0, c = 0.0; - // double si = 0.0, q0 = 0.0; - final double b, c, si, q0; - - // Simpler accept cases & parameter computation - { - final double t = v1 * Math.sqrt(-2.0 * Math.log(v12) / v12); - final double x = s + 0.5 * t; - final double gds = x * x; - if(t >= 0.0) { - return (gds / theta); // Immediate acceptance - } - - // Random uniform - final double un = random.nextDouble(); - // Squeeze acceptance - if(d * un <= t * t * t) { - return (gds / theta); - } - - if(k != -1.0) { // Step 4. Set-up for hat case - final double r = 1.0 / k; - q0 = ((((((((q9 * r + q8) * r + q7) * r + q6) * r + q5) * r + q4) * r + q3) * r + q2) * r + q1) * r; - if(k > 3.686) { - if(k > 13.022) { - b = 1.77; - si = 0.75; - c = 0.1515 / s; - } - else { - b = 1.654 + 0.0076 * ss; - si = 1.68 / s + 0.275; - c = 0.062 / s + 0.024; - } - } - else { - b = 0.463 + s - 0.178 * ss; - si = 1.235; - c = 0.195 / s - 0.079 + 0.016 * s; - } - } - else { - // For k == -1.0: - b = 0.0; - c = 0.0; - si = 0.0; - q0 = 0.0; - } - // Compute v and q - if(x > 0.0) { - final double v = t / (s + s); - final double q; - if(Math.abs(v) > 0.25) { - q = q0 - s * t + 0.25 * t * t + (ss + ss) * Math.log(1.0 + v); - } - else { - q = q0 + 0.5 * t * t * ((((((((a9 * v + a8) * v + a7) * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v; - } - // Quotient acceptance: - if(Math.log(1.0 - un) <= q) { - return (gds / theta); - } - } - } - - // Double exponential deviate t - while(true) { - double e, u, sign_u, t; - // Retry until t is sufficiently large - do { - e = -Math.log(random.nextDouble()); - u = random.nextDouble(); - u = u + u - 1.0; - sign_u = (u > 0) ? 1.0 : -1.0; - t = b + (e * si) * sign_u; - } - while(t <= -0.71874483771719); - - // New v(t) and q(t) - final double v = t / (s + s); - final double q; - if(Math.abs(v) > 0.25) { - q = q0 - s * t + 0.25 * t * t + (ss + ss) * Math.log(1.0 + v); - } - else { - q = q0 + 0.5 * t * t * ((((((((a9 * v + a8) * v + a7) * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v; - } - if(q <= 0.0) { - continue; // retry - } - // Compute w(t) - final double w; - if(q > 0.5) { - w = Math.exp(q) - 1.0; - } - else { - w = ((((((e7 * q + e6) * q + e5) * q + e4) * q + e3) * q + e2) * q + e1) * q; - } - // Hat acceptance - if(c * u * sign_u <= w * Math.exp(e - 0.5 * t * t)) { - final double x = s + 0.5 * t; - return (x * x / theta); - } - } - } - } - - /** - * Simple toString explaining the distribution parameters. - * - * Used in producing a model description. - */ - @Override - public String toString() { - return "Gamma Distribution (k=" + k + ", theta=" + theta + ")"; - } - - /** - * @return the value of k - */ - public double getK() { - return k; - } - - /** - * @return the standard deviation - */ - public double getTheta() { - return theta; - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/NormalDistribution.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/NormalDistribution.java deleted file mode 100644 index 24f06f32..00000000 --- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/NormalDistribution.java +++ /dev/null @@ -1,127 +0,0 @@ -package de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2011 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import java.util.Random; - -import de.lmu.ifi.dbs.elki.math.MathUtil; - -/** - * Simple generator for a Gaussian = Normal Distribution - * - * @author Erich Schubert - */ -public final class NormalDistribution implements Distribution { - /** - * Mean value for the generator - */ - private double mean; - - /** - * Standard deviation - */ - private double stddev; - - /** - * The random generator. - */ - private Random random; - - /** - * Constructor for Gaussian generator - * - * @param mean Mean - * @param stddev Standard Deviation - * @param random Random generator - */ - public NormalDistribution(double mean, double stddev, Random random) { - this.mean = mean; - this.stddev = stddev; - this.random = random; - } - - /** - * Standardized Gaussian PDF - * - * @param x query value - * @return probability density - */ - // TODO: make a math.distributions package with various PDF, CDF, Error - // functions etc.? - private static double phi(double x) { - return Math.exp(-x * x / 2) / MathUtil.SQRTTWOPI; - } - - /** - * Gaussian distribution PDF - * - * @param x query value - * @param mu mean - * @param sigma standard distribution - * @return probability density - */ - public static double phi(double x, double mu, double sigma) { - return phi((x - mu) / sigma) / sigma; - } - - /** - * Return the PDF of the generators distribution - */ - @Override - public double explain(double val) { - return phi(val, mean, stddev); - } - - /** - * Generate a random value with the generators parameters - */ - @Override - public double generate() { - return mean + random.nextGaussian() * stddev; - } - - /** - * Simple toString explaining the distribution parameters. - * - * Used in producing a model description. - */ - @Override - public String toString() { - return "Normal Distribution (mean="+mean+", stddev="+stddev+")"; - } - - /** - * @return the mean - */ - public double getMean() { - return mean; - } - - /** - * @return the standard deviation - */ - public double getStddev() { - return stddev; - } -} diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/UniformDistribution.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/UniformDistribution.java deleted file mode 100644 index 0686f1a3..00000000 --- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/UniformDistribution.java +++ /dev/null @@ -1,116 +0,0 @@ -package de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2011 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import java.util.Random; - -/** - * Simple uniform distribution class - * - * @author Erich Schubert - */ -public final class UniformDistribution implements Distribution { - /** - * Minimum - */ - private double min; - - /** - * Maximum - */ - private double max; - - /** - * Len := max - min - */ - private double len; - - /** - * The random generator. - */ - private Random random; - - /** - * Constructor for a uniform distribution on the interval [min, max[ - * - * @param min Minimum value - * @param max Maximum value - * @param random Random generator - */ - public UniformDistribution(double min, double max, Random random) { - // Swap parameters if they were given incorrectly. - if(min > max) { - double tmp = min; - min = max; - max = tmp; - } - this.min = min; - this.max = max; - this.len = max - min; - this.random = random; - } - - /** - * Return the PDF of the generators distribution - */ - @Override - public double explain(double val) { - if(val < min || val >= max) { - return 0.0; - } - return 1.0 / len; - } - - /** - * Generate a random value with the generators parameters - */ - @Override - public double generate() { - return min + random.nextDouble() * len; - } - - /** - * Simple toString explaining the distribution parameters. - * - * Used in describing cluster models. - */ - @Override - public String toString() { - return "Uniform Distribution (min=" + min + ", max=" + max + ")"; - } - - /** - * @return the minimum value - */ - public double getMin() { - return min; - } - - /** - * @return the maximum value - */ - public double getMax() { - return max; - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/package-info.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/package-info.java index dd0d3e44..51dcd8e8 100644 --- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/package-info.java @@ -13,7 +13,7 @@ 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/package-info.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/package-info.java index 4151409d..c311cf0b 100644 --- a/src/de/lmu/ifi/dbs/elki/data/synthetic/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/package-info.java @@ -7,7 +7,7 @@ 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/type/AlternativeTypeInformation.java b/src/de/lmu/ifi/dbs/elki/data/type/AlternativeTypeInformation.java index 3d37c680..89fc760a 100644 --- a/src/de/lmu/ifi/dbs/elki/data/type/AlternativeTypeInformation.java +++ b/src/de/lmu/ifi/dbs/elki/data/type/AlternativeTypeInformation.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/type/CombinedTypeInformation.java b/src/de/lmu/ifi/dbs/elki/data/type/CombinedTypeInformation.java index 02a549f6..15712262 100644 --- a/src/de/lmu/ifi/dbs/elki/data/type/CombinedTypeInformation.java +++ b/src/de/lmu/ifi/dbs/elki/data/type/CombinedTypeInformation.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/type/NoSupportedDataTypeException.java b/src/de/lmu/ifi/dbs/elki/data/type/NoSupportedDataTypeException.java index 3bfef34f..9865e96f 100644 --- a/src/de/lmu/ifi/dbs/elki/data/type/NoSupportedDataTypeException.java +++ b/src/de/lmu/ifi/dbs/elki/data/type/NoSupportedDataTypeException.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/type/SimpleTypeInformation.java b/src/de/lmu/ifi/dbs/elki/data/type/SimpleTypeInformation.java index c169906e..7fb66462 100644 --- a/src/de/lmu/ifi/dbs/elki/data/type/SimpleTypeInformation.java +++ b/src/de/lmu/ifi/dbs/elki/data/type/SimpleTypeInformation.java @@ -1,10 +1,12 @@ package de.lmu.ifi.dbs.elki.data.type; +import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer; + /* 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,7 +25,6 @@ package de.lmu.ifi.dbs.elki.data.type; along with this program. If not, see <http://www.gnu.org/licenses/>. */ - /** * Class wrapping a particular data type. * @@ -36,13 +37,18 @@ public class SimpleTypeInformation<T> implements TypeInformation { * The restriction class we represent. */ private Class<? super T> cls; - + /** * Type label */ private String label = null; /** + * Type serializer + */ + private ByteBufferSerializer<? super T> serializer = null; + + /** * Constructor. * * @param cls restriction class @@ -65,6 +71,33 @@ public class SimpleTypeInformation<T> implements TypeInformation { } /** + * Constructor. + * + * @param cls restriction class + * @param serializer Serializer + */ + public SimpleTypeInformation(Class<? super T> cls, ByteBufferSerializer<? super T> serializer) { + super(); + this.cls = cls; + this.serializer = serializer; + } + + /** + * Constructor. + * + * @param cls restriction class + * @param label type label + * @param serializer Serializer + */ + public SimpleTypeInformation(Class<? super T> cls, String label, ByteBufferSerializer<? super T> serializer) { + super(); + this.cls = cls; + this.label = label; + this.serializer = serializer; + } + + + /** * Get the raw restriction class. * * @return Restriction class @@ -111,4 +144,13 @@ public class SimpleTypeInformation<T> implements TypeInformation { public String getLabel() { return label; } + + /** + * Get the serializer for this type. + * + * @return Type serializer + */ + public ByteBufferSerializer<? super T> getSerializer() { + return serializer; + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/data/type/TypeInformation.java b/src/de/lmu/ifi/dbs/elki/data/type/TypeInformation.java index b871f2a7..d39afcad 100644 --- a/src/de/lmu/ifi/dbs/elki/data/type/TypeInformation.java +++ b/src/de/lmu/ifi/dbs/elki/data/type/TypeInformation.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type; 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 diff --git a/src/de/lmu/ifi/dbs/elki/data/type/TypeUtil.java b/src/de/lmu/ifi/dbs/elki/data/type/TypeUtil.java index 7abad242..91257906 100644 --- a/src/de/lmu/ifi/dbs/elki/data/type/TypeUtil.java +++ b/src/de/lmu/ifi/dbs/elki/data/type/TypeUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type; 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 @@ -30,10 +30,13 @@ import de.lmu.ifi.dbs.elki.data.ExternalID; import de.lmu.ifi.dbs.elki.data.LabelList; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.SparseFloatVector; +import de.lmu.ifi.dbs.elki.data.model.Model; import de.lmu.ifi.dbs.elki.data.spatial.PolygonsObject; import de.lmu.ifi.dbs.elki.database.ids.DBID; +import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory; import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; +import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil; /** * Utility package containing various common types @@ -52,12 +55,12 @@ public final class TypeUtil { /** * Database IDs */ - public static final SimpleTypeInformation<DBID> DBID = new SimpleTypeInformation<DBID>(DBID.class); + public static final SimpleTypeInformation<DBID> DBID = new SimpleTypeInformation<DBID>(DBID.class, DBIDFactory.FACTORY.getDBIDSerializer()); /** * A string */ - public static final SimpleTypeInformation<String> STRING = new SimpleTypeInformation<String>(String.class); + public static final SimpleTypeInformation<String> STRING = new SimpleTypeInformation<String>(String.class, ByteArrayUtil.STRING_SERIALIZER); /** * A class label @@ -77,6 +80,11 @@ public final class TypeUtil { public static final TypeInformation GUESSED_LABEL = new AlternativeTypeInformation(LABELLIST, CLASSLABEL, STRING); /** + * Number vectors of <em>variable</em> length. + */ + public static final SimpleTypeInformation<? super NumberVector<?, ?>> NUMBER_VECTOR_VARIABLE_LENGTH = new SimpleTypeInformation<NumberVector<?, ?>>(NumberVector.class); + + /** * Input type for algorithms that require number vector fields. */ public static final VectorFieldTypeInformation<NumberVector<?, ?>> NUMBER_VECTOR_FIELD = new VectorFieldTypeInformation<NumberVector<?, ?>>(NumberVector.class); @@ -86,7 +94,7 @@ public final class TypeUtil { * * If possible, please use {@link #NUMBER_VECTOR_FIELD}! */ - public static final VectorFieldTypeInformation<DoubleVector> DOUBLE_VECTOR_FIELD = new VectorFieldTypeInformation<DoubleVector>(DoubleVector.class); + public static final VectorFieldTypeInformation<DoubleVector> DOUBLE_VECTOR_FIELD = new VectorFieldTypeInformation<DoubleVector>(DoubleVector.class, DoubleVector.STATIC); /** * Input type for algorithms that require number vector fields. @@ -111,12 +119,12 @@ public final class TypeUtil { /** * Double type, outlier scores etc. */ - public static final SimpleTypeInformation<Double> DOUBLE = new SimpleTypeInformation<Double>(Double.class); + public static final SimpleTypeInformation<Double> DOUBLE = new SimpleTypeInformation<Double>(Double.class, ByteArrayUtil.DOUBLE_SERIALIZER); /** * Integer type. */ - public static final SimpleTypeInformation<Integer> INTEGER = new SimpleTypeInformation<Integer>(Integer.class); + public static final SimpleTypeInformation<Integer> INTEGER = new SimpleTypeInformation<Integer>(Integer.class, ByteArrayUtil.INT_SERIALIZER); /** * Vector type. @@ -129,6 +137,11 @@ public final class TypeUtil { public static final SimpleTypeInformation<Matrix> MATRIX = new SimpleTypeInformation<Matrix>(Matrix.class); /** + * Cluster model type. + */ + public static final SimpleTypeInformation<Model> MODEL = new SimpleTypeInformation<Model>(Model.class); + + /** * Make a type array easily. * * @param ts Types diff --git a/src/de/lmu/ifi/dbs/elki/data/type/VectorFieldTypeInformation.java b/src/de/lmu/ifi/dbs/elki/data/type/VectorFieldTypeInformation.java index 99bed220..69e0c969 100644 --- a/src/de/lmu/ifi/dbs/elki/data/type/VectorFieldTypeInformation.java +++ b/src/de/lmu/ifi/dbs/elki/data/type/VectorFieldTypeInformation.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type; 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 @@ -24,6 +24,7 @@ package de.lmu.ifi.dbs.elki.data.type; */ import de.lmu.ifi.dbs.elki.data.FeatureVector; +import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer; /** * Type information to specify that a type has a fixed dimensionality. @@ -44,27 +45,86 @@ public class VectorFieldTypeInformation<V extends FeatureVector<?, ?>> extends V private String[] labels = null; /** - * Constructor for a request without fixed dimensionality. + * Constructor with given dimensionality and factory, so usually an instance. + * + * @param cls Restriction java class + * @param serializer Serializer + * @param dim Dimensionality + * @param labels Labels + * @param factory Factory class + */ + public VectorFieldTypeInformation(Class<? super V> cls, ByteBufferSerializer<? super V> serializer, int dim, String[] labels, V factory) { + super(cls, serializer, dim, dim); + this.labels = labels; + this.factory = factory; + assert (labels == null || labels.length == dim) : "Created vector field with incomplete labels."; + } + + /** + * Constructor for a request with minimum and maximum dimensionality. * * @param cls Vector restriction class. + * @param serializer Serializer + * @param mindim Minimum dimensionality request + * @param maxdim Maximum dimensionality request */ - public VectorFieldTypeInformation(Class<? super V> cls) { - super(cls); + public VectorFieldTypeInformation(Class<? super V> cls, ByteBufferSerializer<? super V> serializer, int mindim, int maxdim) { + super(cls, serializer, mindim, maxdim); this.factory = null; } /** + * Constructor with given dimensionality and factory, so usually an instance. + * + * @param cls Restriction java class + * @param serializer Serializer + * @param dim Dimensionality + * @param factory Factory class + */ + public VectorFieldTypeInformation(Class<? super V> cls, ByteBufferSerializer<? super V> serializer, int dim, V factory) { + super(cls, serializer, dim, dim); + this.factory = factory; + } + + /** * Constructor for a request with fixed dimensionality. * * @param cls Vector restriction class. + * @param serializer Serializer * @param dim Dimensionality request */ - public VectorFieldTypeInformation(Class<? super V> cls, int dim) { - super(cls, dim, dim); + public VectorFieldTypeInformation(Class<? super V> cls, ByteBufferSerializer<? super V> serializer, int dim) { + super(cls, serializer, dim, dim); + this.factory = null; + } + + /** + * Constructor for a request without fixed dimensionality. + * + * @param cls Vector restriction class. + * @param serializer Serializer + */ + public VectorFieldTypeInformation(Class<? super V> cls, ByteBufferSerializer<? super V> serializer) { + super(cls, serializer); this.factory = null; } /** + * Constructor with given dimensionality and factory, so usually an instance. + * + * @param cls Restriction java class + * @param dim Dimensionality + * @param labels Labels + * @param factory Factory class + */ + public VectorFieldTypeInformation(Class<? super V> cls, int dim, String[] labels, V factory) { + super(cls, dim, dim); + this.labels = labels; + this.factory = factory; + assert (labels == null || labels.length == dim) : "Created vector field with incomplete labels."; + } + + /** * Constructor for a request with minimum and maximum dimensionality. * * @param cls Vector restriction class. @@ -89,18 +149,24 @@ public class VectorFieldTypeInformation<V extends FeatureVector<?, ?>> extends V } /** - * Constructor with given dimensionality and factory, so usually an instance. + * Constructor for a request with fixed dimensionality. * - * @param cls Restriction java class - * @param dim Dimensionality - * @param labels Labels - * @param factory Factory class + * @param cls Vector restriction class. + * @param dim Dimensionality request */ - public VectorFieldTypeInformation(Class<? super V> cls, int dim, String[] labels, V factory) { + public VectorFieldTypeInformation(Class<? super V> cls, int dim) { super(cls, dim, dim); - this.labels = labels; - this.factory = factory; - assert (labels == null || labels.length == dim) : "Created vector field with incomplete labels."; + this.factory = null; + } + + /** + * Constructor for a request without fixed dimensionality. + * + * @param cls Vector restriction class. + */ + public VectorFieldTypeInformation(Class<? super V> cls) { + super(cls); + this.factory = null; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/data/type/VectorTypeInformation.java b/src/de/lmu/ifi/dbs/elki/data/type/VectorTypeInformation.java index a529ce7b..012cff48 100644 --- a/src/de/lmu/ifi/dbs/elki/data/type/VectorTypeInformation.java +++ b/src/de/lmu/ifi/dbs/elki/data/type/VectorTypeInformation.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type; 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 @@ -24,6 +24,7 @@ package de.lmu.ifi.dbs.elki.data.type; */ import de.lmu.ifi.dbs.elki.data.FeatureVector; +import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer; /** * Construct a type information for vector spaces with fixed dimensionality. @@ -47,11 +48,12 @@ public class VectorTypeInformation<V extends FeatureVector<?, ?>> extends Simple * Constructor. * * @param cls base class + * @param serializer Serializer * @param mindim Minimum dimensionality * @param maxdim Maximum dimensionality */ - public VectorTypeInformation(Class<? super V> cls, int mindim, int maxdim) { - super(cls); + public VectorTypeInformation(Class<? super V> cls, ByteBufferSerializer<? super V> serializer, int mindim, int maxdim) { + super(cls, serializer); assert (this.mindim <= this.maxdim); this.mindim = mindim; this.maxdim = maxdim; @@ -60,10 +62,31 @@ public class VectorTypeInformation<V extends FeatureVector<?, ?>> extends Simple /** * Constructor without size constraints. * + * @param cls base class + * @param serializer Serializer + */ + public VectorTypeInformation(Class<? super V> cls, ByteBufferSerializer<? super V> serializer) { + this(cls, serializer, -1, Integer.MAX_VALUE); + } + + /** + * Constructor. + * + * @param cls base class + * @param mindim Minimum dimensionality + * @param maxdim Maximum dimensionality + */ + public VectorTypeInformation(Class<? super V> cls, int mindim, int maxdim) { + this(cls, null, mindim, maxdim); + } + + /** + * Constructor without size constraints. + * * @param cls */ public VectorTypeInformation(Class<? super V> cls) { - this(cls, -1, Integer.MAX_VALUE); + this(cls, null, -1, Integer.MAX_VALUE); } @Override diff --git a/src/de/lmu/ifi/dbs/elki/data/type/package-info.java b/src/de/lmu/ifi/dbs/elki/data/type/package-info.java index 92a3e931..858efc7a 100644 --- a/src/de/lmu/ifi/dbs/elki/data/type/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/data/type/package-info.java @@ -5,7 +5,7 @@ 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 |