diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/distance')
157 files changed, 3513 insertions, 3415 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/distance/DistanceUtil.java b/src/de/lmu/ifi/dbs/elki/distance/DistanceUtil.java index eaa6c96c..8c1b2035 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/DistanceUtil.java +++ b/src/de/lmu/ifi/dbs/elki/distance/DistanceUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDBIDDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDBIDDistanceFunction.java index 9216c4ac..84fa0fbe 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDBIDDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDBIDDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -37,6 +37,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * * @author Arthur Zimek * + * @apiviz.excludeSubtypes + * * @param <D> the type of Distance used */ public abstract class AbstractDBIDDistanceFunction<D extends Distance<D>> implements DBIDDistanceFunction<D> { @@ -73,6 +75,6 @@ public abstract class AbstractDBIDDistanceFunction<D extends Distance<D>> implem @SuppressWarnings("unchecked") @Override final public <O extends DBID> DistanceQuery<O, D> instantiate(Relation<O> database) { - return (DistanceQuery<O, D>) new DBIDDistanceQuery<D>((Relation<DBID>) database, this); + return (DistanceQuery<O, D>) new DBIDDistanceQuery<>((Relation<DBID>) database, this); } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDatabaseDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDatabaseDistanceFunction.java index 845ea0ea..3bad6528 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDatabaseDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDatabaseDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -33,6 +33,7 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @author Elke Achtert * * @apiviz.has AbstractDatabaseDistanceFunction.Instance + * @apiviz.excludeSubtypes * * @param <O> the type of DatabaseObject to compute the distances in between * @param <D> the type of Distance used diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractIndexBasedDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractIndexBasedDistanceFunction.java index 48947692..618a238d 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractIndexBasedDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractIndexBasedDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -40,6 +40,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; * * @apiviz.has AbstractIndexBasedDistanceFunction.Instance * @apiviz.composedOf IndexFactory + * @apiviz.excludeSubtypes * * @param <O> the type of object to compute the distances in between * @param <I> the type of Index used @@ -147,7 +148,7 @@ public abstract class AbstractIndexBasedDistanceFunction<O, I extends Index, D e * @param defaultClass Default value */ public void configIndexFactory(Parameterization config, Class<?> restriction, Class<?> defaultClass) { - ObjectParameter<F> param = new ObjectParameter<F>(INDEX_ID, restriction, defaultClass); + ObjectParameter<F> param = new ObjectParameter<>(INDEX_ID, restriction, defaultClass); if(config.grab(param)) { factory = param.instantiateClass(config); } diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractPrimitiveDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractPrimitiveDistanceFunction.java index 1c94bc28..7aefd19c 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractPrimitiveDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractPrimitiveDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -33,6 +33,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * * @author Arthur Zimek * + * @apiviz.excludeSubtypes + * * @param <O> the type of objects to compute the distances in between * @param <D> the type of Distance used */ @@ -70,6 +72,6 @@ public abstract class AbstractPrimitiveDistanceFunction<O, D extends Distance<D> */ @Override public <T extends O> DistanceQuery<T, D> instantiate(Relation<T> relation) { - return new PrimitiveDistanceQuery<T, D>(relation, this); + return new PrimitiveDistanceQuery<>(relation, this); } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDoubleDistanceFunction.java new file mode 100644 index 00000000..ef1b28b9 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDoubleDistanceFunction.java @@ -0,0 +1,52 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2013 + 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.spatial.SpatialComparable; +import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery; +import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; + +/** + * Abstract base class for typical distance functions that allow + * rectangle-to-rectangle lower bounds. These distances can then be used with + * R*-trees for acceleration. + * + * This class is largely a convenience class, to make implementing this type of + * distance functions easier. + * + * @author Erich Schubert + */ +public abstract class AbstractSpatialDoubleDistanceFunction extends AbstractVectorDoubleDistanceFunction implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { + @Override + final public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) { + return new DoubleDistance(doubleMinDist(mbr1, mbr2)); + } + + @Override + public <T extends NumberVector<?>> SpatialPrimitiveDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) { + return new SpatialPrimitiveDistanceQuery<>(relation, this); + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDoubleDistanceNorm.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDoubleDistanceNorm.java new file mode 100644 index 00000000..e350f880 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDoubleDistanceNorm.java @@ -0,0 +1,54 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2013 + 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.spatial.SpatialComparable; +import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery; +import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; + +/** + * Abstract base class for typical distance functions that allow + * rectangle-to-rectangle lower bounds. These distances can then be used with + * R*-trees for acceleration. + * + * This class is largely a convenience class, to make implementing this type of + * distance functions easier. + * + * @author Erich Schubert + * + * @apiviz.landmark + */ +public abstract class AbstractSpatialDoubleDistanceNorm extends AbstractVectorDoubleDistanceNorm implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { + @Override + final public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) { + return new DoubleDistance(doubleMinDist(mbr1, mbr2)); + } + + @Override + public <T extends NumberVector<?>> SpatialPrimitiveDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) { + return new SpatialPrimitiveDistanceQuery<>(relation, this); + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceFunction.java index 24288ec1..ea178bbb 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 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.distance.distancefunction; */ import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; import de.lmu.ifi.dbs.elki.data.type.TypeUtil; import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; @@ -35,6 +36,7 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; * @author Erich Schubert * * @apiviz.landmark + * @apiviz.excludeSubtypes * @apiviz.uses NumberVector * @apiviz.has DoubleDistance */ @@ -60,4 +62,41 @@ public abstract class AbstractVectorDoubleDistanceFunction extends AbstractPrimi public DoubleDistance getDistanceFactory() { return DoubleDistance.FACTORY; } -}
\ No newline at end of file + + /** + * Get the common dimensionality of the two objects. Throw an + * {@link IllegalArgumentException} otherwise. + * + * @param o1 First vector / MBR + * @param o2 Second vector / MBR + * @return Common dimensionality + * @throws IllegalArgumentException when dimensionalities are not the same. + */ + public static final int dimensionality(SpatialComparable o1, SpatialComparable o2) { + final int dim1 = o1.getDimensionality(); + final int dim2 = o2.getDimensionality(); + if (dim1 != dim2) { + throw new IllegalArgumentException("Objects do not have the same dimensionality."); + } + return dim1; + } + + /** + * Get the common dimensionality of the two objects. Throw an + * {@link IllegalArgumentException} otherwise. + * + * @param o1 First vector / MBR + * @param o2 Second vector / MBR + * @param expect Expected dimensionality + * @return Common dimensionality + * @throws IllegalArgumentException when dimensionalities are not the same. + */ + public static final int dimensionality(SpatialComparable o1, SpatialComparable o2, int expect) { + final int dim1 = o1.getDimensionality(); + final int dim2 = o2.getDimensionality(); + if (dim1 != dim2 || dim1 != expect) { + throw new IllegalArgumentException("Objects do not have the expected dimensionality of " + expect); + } + return expect; + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceNorm.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceNorm.java index 16d4160c..7555bb3a 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceNorm.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceNorm.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -31,6 +31,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; * norms. * * @author Erich Schubert + * + * @apiviz.landmark */ public abstract class AbstractVectorDoubleDistanceNorm extends AbstractVectorDoubleDistanceFunction implements DoubleNorm<NumberVector<?>> { @Override diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ArcCosineDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ArcCosineDistanceFunction.java index 344bb3ca..c95038cc 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ArcCosineDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ArcCosineDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -28,10 +28,7 @@ import de.lmu.ifi.dbs.elki.data.VectorUtil; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; import de.lmu.ifi.dbs.elki.data.type.TypeUtil; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialDistanceQuery; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.utilities.Alias; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** @@ -42,7 +39,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; * * @author Arthur Zimek */ -public class ArcCosineDistanceFunction extends AbstractVectorDoubleDistanceFunction implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { +@Alias({ "arccos" }) +public class ArcCosineDistanceFunction extends AbstractSpatialDoubleDistanceFunction { /** * Static instance */ @@ -71,7 +69,7 @@ public class ArcCosineDistanceFunction extends AbstractVectorDoubleDistanceFunct @Override public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { double d = Math.acos(VectorUtil.cosAngle(v1, v2)); - if(d < 0) { + if (d < 0) { d = 0; } return d; @@ -80,39 +78,29 @@ public class ArcCosineDistanceFunction extends AbstractVectorDoubleDistanceFunct @Override public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { double d = Math.acos(VectorUtil.minCosAngle(mbr1, mbr2)); - if(d < 0) { + if (d < 0) { d = 0; } return d; } @Override - public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) { - return new DoubleDistance(doubleMinDist(mbr1, mbr2)); - } - - @Override public String toString() { return "ArcCosineDistance"; } @Override public boolean equals(Object obj) { - if(obj == null) { + if (obj == null) { return false; } - if(obj == this) { + if (obj == this) { return true; } return this.getClass().equals(obj.getClass()); } @Override - public <T extends NumberVector<?>> SpatialDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) { - return new SpatialPrimitiveDistanceQuery<T, DoubleDistance>(relation, this); - } - - @Override public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH; } @@ -130,4 +118,4 @@ public class ArcCosineDistanceFunction extends AbstractVectorDoubleDistanceFunct return ArcCosineDistanceFunction.STATIC; } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/BrayCurtisDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/BrayCurtisDistanceFunction.java new file mode 100644 index 00000000..20a989fc --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/BrayCurtisDistanceFunction.java @@ -0,0 +1,149 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2013 + 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.spatial.SpatialComparable; +import de.lmu.ifi.dbs.elki.utilities.Alias; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Bray-Curtis distance function / Sørensen–Dice coefficient for continuous + * spaces. + * + * Reference: + * <p> + * J. R. Bray and J. T. Curtis<br /> + * An ordination of the upland forest communities of southern Wisconsin<br /> + * Ecological monographs 27.4 + * </p> + * Also: + * <p> + * T. Sørensen<br /> + * A method of establishing groups of equal amplitude in plant sociology based + * on similarity of species and its application to analyses of the vegetation on + * Danish commons<br /> + * Kongelige Danske Videnskabernes Selskab 5 (4) + * </p> + * and: + * <p> + * L. R. Dice<br /> + * Measures of the Amount of Ecologic Association Between Species<br /> + * Ecology 26 (3) + * </p> + * + * + * Note: we modified the usual definition of Bray-Curtis for use with negative + * values. In essence, this function is defined as: + * + * ManhattanDistance(v1, v2) / (ManhattanNorm(v1) + ManhattanNorm(v2)) + * + * This obviously limits the usefulness of this distance function for cases + * where this kind of normalization is desired. In particular in low dimensional + * data it should be used with care. + * + * TODO: add a version optimized for sparse vectors / binary data. + * + * @author Erich Schubert + */ +@Alias({ "bray-curtis", "braycurtis", "sorensen", "dice", "sorensen-dice" }) +@Reference(authors = "J. R. Bray and J. T. Curtis", title = "An ordination of the upland forest communities of southern Wisconsin", booktitle = "Ecological monographs 27.4", url = "http://dx.doi.org/10.2307/1942268") +public class BrayCurtisDistanceFunction extends AbstractSpatialDoubleDistanceFunction { + /** + * Static instance. + */ + public static final BrayCurtisDistanceFunction STATIC_CONTINUOUS = new BrayCurtisDistanceFunction(); + + /** + * Constructor. + * + * @deprecated Use {@link #STATIC_CONTINUOUS} instance instead. + */ + @Deprecated + public BrayCurtisDistanceFunction() { + super(); + } + + /** + * Dummy method, just to attach a second reference. + */ + @Reference(authors = "T. Sørensen", title = "A method of establishing groups of equal amplitude in plant sociology based on similarity of species and its application to analyses of the vegetation on Danish commons", booktitle = "Kongelige Danske Videnskabernes Selskab 5 (4)") + static void secondReference() { + // Empty, just to attach a second reference + }; + + /** + * Dummy method, just to attach a third reference. + */ + @Reference(authors = "L. R. Dice", title = "Measures of the Amount of Ecologic Association Between Species", booktitle = "Ecology 26 (3)") + static void thirdReference() { + // Empty, just to attach a second reference + }; + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2); + double sumdiff = 0., sumsum = 0.; + for (int d = 0; d < dim; d++) { + double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + sumdiff += Math.abs(xd - yd); + sumsum += Math.abs(xd) + Math.abs(yd); + } + return sumdiff / sumsum; + } + + @Override + public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + final int dim = dimensionality(mbr1, mbr2); + double sumdiff = 0., sumsum = 0.; + for (int d = 0; d < dim; d++) { + final double min1 = mbr1.getMin(d), max1 = mbr1.getMax(d); + final double min2 = mbr2.getMin(d), max2 = mbr2.getMax(d); + if (max1 < min2) { + sumdiff += min2 - max1; + } else if (min1 > max2) { + sumdiff += min1 - max2; + } else { + // Minimum difference is 0 + } + sumsum += Math.max(-min1, max1) + Math.max(-min2, max2); + } + return sumdiff / sumsum; + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected BrayCurtisDistanceFunction makeInstance() { + return BrayCurtisDistanceFunction.STATIC_CONTINUOUS; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CanberraDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CanberraDistanceFunction.java index f6db7439..97ef19ce 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CanberraDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CanberraDistanceFunction.java @@ -24,10 +24,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; */ import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialDistanceQuery; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.utilities.Alias; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; @@ -45,7 +42,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; * @author Erich Schubert */ @Reference(authors = "G. N. Lance, W. T. Williams", title = "Computer programs for hierarchical polythetic classification (similarity analysis).", booktitle = "Computer Journal, Volume 9, Issue 1", url = "http://comjnl.oxfordjournals.org/content/9/1/60.short") -public class CanberraDistanceFunction extends AbstractVectorDoubleDistanceFunction implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { +@Alias({ "canberra" }) +public class CanberraDistanceFunction extends AbstractSpatialDoubleDistanceFunction { /** * Static instance. Use this! */ @@ -59,56 +57,46 @@ public class CanberraDistanceFunction extends AbstractVectorDoubleDistanceFuncti } @Override - public double doubleDistance(NumberVector<?> o1, NumberVector<?> o2) { - final int dim = o1.getDimensionality(); - double sum = 0.0; - for(int i = 0; i < dim; i++) { - double v1 = o1.doubleValue(i); - double v2 = o2.doubleValue(i); - final double div = Math.abs(v1) + Math.abs(v2); + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + final double div = Math.abs(xd) + Math.abs(yd); if (div > 0) { - sum += Math.abs(v1 - v2) / div; + agg += Math.abs(xd - yd) / div; } } - return sum; + return agg; } @Override public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { - final int dim = mbr1.getDimensionality(); - double sum = 0.0; - for(int d = 0; d < dim; d++) { - final double m1, m2; - if(mbr1.getMax(d) < mbr2.getMin(d)) { - m1 = mbr2.getMin(d); - m2 = mbr1.getMax(d); - } - else if(mbr1.getMin(d) > mbr2.getMax(d)) { - m1 = mbr1.getMin(d); - m2 = mbr2.getMax(d); - } - else { // The mbrs intersect! + final int dim = dimensionality(mbr1, mbr2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double diff; + if (mbr1.getMax(d) < mbr2.getMin(d)) { + diff = mbr2.getMin(d) - mbr1.getMax(d); + } else if (mbr1.getMin(d) > mbr2.getMax(d)) { + diff = mbr1.getMin(d) - mbr2.getMax(d); + } else { // The mbrs intersect! continue; } - final double manhattanI = m1 - m2; final double a1 = Math.max(-mbr1.getMin(d), mbr1.getMax(d)); final double a2 = Math.max(-mbr2.getMin(d), mbr2.getMax(d)); final double div = a1 + a2; - if (div > 0) { - sum += manhattanI / div; - } + // Cannot be 0, because then diff = 0 and we continued above. + agg += diff / div; } - return sum; - } - - @Override - public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) { - return new DoubleDistance(doubleMinDist(mbr1, mbr2)); + return agg; } @Override - public <T extends NumberVector<?>> SpatialDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) { - return new SpatialPrimitiveDistanceQuery<T, DoubleDistance>(relation, this); + public boolean isMetric() { + // As this is also reffered to as "canberra metric", it is probably a metric + // But *maybe* only for positive numbers only? + return true; } /** @@ -124,4 +112,4 @@ public class CanberraDistanceFunction extends AbstractVectorDoubleDistanceFuncti return CanberraDistanceFunction.STATIC; } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ClarkDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ClarkDistanceFunction.java new file mode 100644 index 00000000..221a7db1 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ClarkDistanceFunction.java @@ -0,0 +1,112 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2013 + 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.spatial.SpatialComparable; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Clark distance function for vector spaces. + * + * Reference: + * <p> + * M.-M. Deza and E. Deza<br /> + * Dictionary of distances + * </p> + * + * @author Erich Schubert + */ +@Reference(authors = "M.-M. Deza and E. Deza", title = "Dictionary of distances", booktitle = "Dictionary of distances") +public class ClarkDistanceFunction extends AbstractSpatialDoubleDistanceFunction { + /** + * Static instance. + */ + public static final ClarkDistanceFunction STATIC = new ClarkDistanceFunction(); + + /** + * Constructor. + * + * @deprecated Use {@link #STATIC} instance instead. + */ + @Deprecated + public ClarkDistanceFunction() { + super(); + } + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + final double div = Math.abs(xd) + Math.abs(yd); + if (div > 0.) { + final double v = (xd - yd) / div; + agg += v * v; + } + } + return Math.sqrt(agg / dim); + } + + @Override + public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + final int dim = dimensionality(mbr1, mbr2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double min1 = mbr1.getMin(d), max1 = mbr1.getMax(d); + final double min2 = mbr2.getMin(d), max2 = mbr2.getMax(d); + final double diff; + if (max1 < min2) { + diff = min2 - max1; + } else if (min1 > max2) { + diff = min1 - max2; + } else { + // Minimum difference is 0 + continue; + } + final double absmax1 = Math.max(-min1, max1); + final double absmax2 = Math.max(-min2, max2); + // Division by 0 cannot happen: then diff = 0 and we continued above! + final double v = diff / (absmax1 + absmax2); + agg += v * v; + } + return Math.sqrt(agg / dim); + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected ClarkDistanceFunction makeInstance() { + return ClarkDistanceFunction.STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CosineDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CosineDistanceFunction.java index f333f6e2..bc86b6cf 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CosineDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CosineDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -28,10 +28,7 @@ import de.lmu.ifi.dbs.elki.data.VectorUtil; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; import de.lmu.ifi.dbs.elki.data.type.TypeUtil; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialDistanceQuery; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.utilities.Alias; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** @@ -42,7 +39,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; * * @author Arthur Zimek */ -public class CosineDistanceFunction extends AbstractVectorDoubleDistanceFunction implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { +@Alias({ "cosine" }) +public class CosineDistanceFunction extends AbstractSpatialDoubleDistanceFunction { /** * Static instance */ @@ -71,7 +69,7 @@ public class CosineDistanceFunction extends AbstractVectorDoubleDistanceFunction @Override public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { double d = 1 - VectorUtil.cosAngle(v1, v2); - if(d < 0) { + if (d < 0) { d = 0; } return d; @@ -80,39 +78,29 @@ public class CosineDistanceFunction extends AbstractVectorDoubleDistanceFunction @Override public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { double d = 1 - VectorUtil.minCosAngle(mbr1, mbr2); - if(d < 0) { + if (d < 0) { d = 0; } return d; } @Override - public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) { - return new DoubleDistance(doubleMinDist(mbr1, mbr2)); - } - - @Override public String toString() { return "CosineDistance"; } @Override public boolean equals(Object obj) { - if(obj == null) { + if (obj == null) { return false; } - if(obj == this) { + if (obj == this) { return true; } return this.getClass().equals(obj.getClass()); } @Override - public <T extends NumberVector<?>> SpatialDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) { - return new SpatialPrimitiveDistanceQuery<T, DoubleDistance>(relation, this); - } - - @Override public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH; } @@ -130,4 +118,4 @@ public class CosineDistanceFunction extends AbstractVectorDoubleDistanceFunction return CosineDistanceFunction.STATIC; } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DBIDDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DBIDDistanceFunction.java index 857b96e1..aea91f40 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DBIDDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DBIDDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DistanceFunction.java index 0d38b418..ae5d2780 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DoubleNorm.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DoubleNorm.java index 3d7ed70f..6ba5246a 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DoubleNorm.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DoubleNorm.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/EuclideanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/EuclideanDistanceFunction.java deleted file mode 100644 index 6bb910a4..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/EuclideanDistanceFunction.java +++ /dev/null @@ -1,179 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distancefunction; - -/* - 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.spatial.SpatialComparable; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; - -/** - * Provides the Euclidean distance for FeatureVectors. - * - * @author Arthur Zimek - */ -public class EuclideanDistanceFunction extends LPNormDistanceFunction implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { - /** - * Static instance. Use this! - */ - public static final EuclideanDistanceFunction STATIC = new EuclideanDistanceFunction(); - - /** - * Provides a Euclidean distance function that can compute the Euclidean - * distance (that is a DoubleDistance) for FeatureVectors. - * - * @deprecated Use static instance! - */ - @Deprecated - public EuclideanDistanceFunction() { - super(2.0); - } - - @Override - public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { - final int dim1 = v1.getDimensionality(); - if(dim1 != v2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of FeatureVectors" + "\n first argument: " + v1.toString() + "\n second argument: " + v2.toString() + "\n" + v1.getDimensionality() + "!=" + v2.getDimensionality()); - } - double sqrDist = 0; - for(int i = 0; i < dim1; i++) { - final double delta = v1.doubleValue(i) - v2.doubleValue(i); - sqrDist += delta * delta; - } - return Math.sqrt(sqrDist); - } - - @Override - public double doubleNorm(NumberVector<?> v) { - final int dim = v.getDimensionality(); - double sqrDist = 0; - for(int i = 0; i < dim; i++) { - final double delta = v.doubleValue(i); - sqrDist += delta * delta; - } - return Math.sqrt(sqrDist); - } - - protected double doubleMinDistObject(SpatialComparable mbr, NumberVector<?> v) { - final int dim = mbr.getDimensionality(); - if(dim != v.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr.toString() + "\n " + "second argument: " + v.toString() + "\n" + dim + "!=" + v.getDimensionality()); - } - - double sqrDist = 0; - for(int d = 0; d < dim; d++) { - double value = v.doubleValue(d); - double r; - if(value < mbr.getMin(d)) { - r = mbr.getMin(d); - } - else if(value > mbr.getMax(d)) { - r = mbr.getMax(d); - } - else { - r = value; - } - - final double manhattanI = value - r; - sqrDist += manhattanI * manhattanI; - } - return Math.sqrt(sqrDist); - } - - @Override - public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { - // Some optimizations for simpler cases. - if(mbr1 instanceof NumberVector) { - if(mbr2 instanceof NumberVector) { - return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); - } - else { - return doubleMinDistObject(mbr2, (NumberVector<?>) mbr1); - } - } - else if(mbr2 instanceof NumberVector) { - return doubleMinDistObject(mbr1, (NumberVector<?>) mbr2); - } - final int dim1 = mbr1.getDimensionality(); - if(dim1 != mbr2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr1.toString() + "\n " + "second argument: " + mbr2.toString()); - } - - double sqrDist = 0; - for(int d = 0; d < dim1; d++) { - final double m1, m2; - if(mbr1.getMax(d) < mbr2.getMin(d)) { - m1 = mbr2.getMin(d); - m2 = mbr1.getMax(d); - } - else if(mbr1.getMin(d) > mbr2.getMax(d)) { - m1 = mbr1.getMin(d); - m2 = mbr2.getMax(d); - } - else { // The mbrs intersect! - continue; - } - final double manhattanI = m1 - m2; - sqrDist += manhattanI * manhattanI; - } - return Math.sqrt(sqrDist); - } - - @Override - public boolean isMetric() { - return true; - } - - @Override - public String toString() { - return "EuclideanDistance"; - } - - @Override - public boolean equals(Object obj) { - if(obj == null) { - return false; - } - if(obj == this) { - return true; - } - if(this.getClass().equals(obj.getClass())) { - return true; - } - return super.equals(obj); - } - - /** - * Parameterization class. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - public static class Parameterizer extends AbstractParameterizer { - @Override - protected EuclideanDistanceFunction makeInstance() { - return EuclideanDistanceFunction.STATIC; - } - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/FilteredLocalPCABasedDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/FilteredLocalPCABasedDistanceFunction.java index 2cf11a54..da2bb2ec 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/FilteredLocalPCABasedDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/FilteredLocalPCABasedDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/IndexBasedDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/IndexBasedDistanceFunction.java index ba7d87d7..b8f02e94 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/IndexBasedDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/IndexBasedDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Kulczynski1DistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Kulczynski1DistanceFunction.java new file mode 100644 index 00000000..59b9a29d --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Kulczynski1DistanceFunction.java @@ -0,0 +1,103 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2013 + 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.spatial.SpatialComparable; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Kulczynski similarity 1, in distance form. + * + * Reference: + * <p> + * M.-M. Deza and E. Deza<br /> + * Dictionary of distances + * </p> + * + * @author Erich Schubert + */ +@Reference(authors = "M.-M. Deza and E. Deza", title = "Dictionary of distances", booktitle = "Dictionary of distances") +public class Kulczynski1DistanceFunction extends AbstractSpatialDoubleDistanceFunction { + /** + * Static instance. + */ + public static final Kulczynski1DistanceFunction STATIC = new Kulczynski1DistanceFunction(); + + /** + * Constructor. + * + * @deprecated Use {@link #STATIC} instance instead. + */ + @Deprecated + public Kulczynski1DistanceFunction() { + super(); + } + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2); + double sumdiff = 0., summin = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + sumdiff += Math.abs(xd - yd); + summin += Math.min(xd, yd); + } + return sumdiff / summin; + } + + @Override + public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + final int dim = dimensionality(mbr1, mbr2); + double sumdiff = 0., summin = 0.; + for (int d = 0; d < dim; d++) { + final double min1 = mbr1.getMin(d), max1 = mbr1.getMax(d); + final double min2 = mbr2.getMin(d), max2 = mbr2.getMax(d); + if (max1 < min2) { + sumdiff += min2 - max1; + } else if (min1 > max2) { + sumdiff += min1 - max2; + } else { + // Minimum difference is 0 + } + summin += Math.min(min1, min2); + } + return sumdiff / summin; + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected Kulczynski1DistanceFunction makeInstance() { + return Kulczynski1DistanceFunction.STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LocallyWeightedDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LocallyWeightedDistanceFunction.java index 2ff0252c..024240b6 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LocallyWeightedDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LocallyWeightedDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -78,7 +78,7 @@ public class LocallyWeightedDistanceFunction<V extends NumberVector<?>> extends // Generics (AFAICT) @SuppressWarnings("unchecked") LocalProjectionIndex<T, ?> indexinst = (LocalProjectionIndex<T, ?>) indexFactory.instantiate((Relation<V>) database); - return new Instance<T>(database, indexinst, this); + return new Instance<>(database, indexinst, this); } @Override @@ -254,7 +254,7 @@ public class LocallyWeightedDistanceFunction<V extends NumberVector<?>> extends @Override protected LocallyWeightedDistanceFunction<V> makeInstance() { - return new LocallyWeightedDistanceFunction<V>(factory); + return new LocallyWeightedDistanceFunction<>(factory); } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LorentzianDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LorentzianDistanceFunction.java new file mode 100644 index 00000000..51140f36 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LorentzianDistanceFunction.java @@ -0,0 +1,115 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2013 + 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.spatial.SpatialComparable; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Lorentzian distance function for vector spaces. + * + * Reference: + * <p> + * M.-M. Deza and E. Deza<br /> + * Dictionary of distances + * </p> + * + * @author Erich Schubert + */ +@Reference(authors = "M.-M. Deza and E. Deza", title = "Dictionary of distances", booktitle = "Dictionary of distances") +public class LorentzianDistanceFunction extends AbstractSpatialDoubleDistanceNorm { + /** + * Static instance. + */ + public static final LorentzianDistanceFunction STATIC = new LorentzianDistanceFunction(); + + /** + * Constructor. + * + * @deprecated Use {@link #STATIC} instance instead. + */ + @Deprecated + public LorentzianDistanceFunction() { + super(); + } + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + agg += Math.log(1 + Math.abs(xd - yd)); + } + return agg; + } + + @Override + public double doubleNorm(NumberVector<?> v1) { + final int dim = v1.getDimensionality(); + double agg = 0.; + for (int i = 0; i < dim; i++) { + final double xi = v1.doubleValue(i); + agg += Math.log(1. + Math.abs(xi)); + } + return agg; + } + + @Override + public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + final int dim = dimensionality(mbr1, mbr2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double min1 = mbr1.getMin(d), max1 = mbr1.getMax(d); + final double min2 = mbr2.getMin(d), max2 = mbr2.getMax(d); + final double diff; + if (max1 < min2) { + diff = min2 - max1; + } else if (min1 > max2) { + diff = min1 - max2; + } else { + // Minimum difference is 0 + continue; + } + agg += Math.log(1. + diff); + } + return agg; + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected LorentzianDistanceFunction makeInstance() { + return LorentzianDistanceFunction.STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinKDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinKDistance.java index 294b7e40..5e29ec51 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinKDistance.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinKDistance.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,13 +26,14 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; import de.lmu.ifi.dbs.elki.data.type.TypeInformation; import de.lmu.ifi.dbs.elki.database.QueryUtil; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; +import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList; import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery; import de.lmu.ifi.dbs.elki.database.query.distance.AbstractDatabaseDistanceQuery; import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.distance.DistanceUtil; -import de.lmu.ifi.dbs.elki.distance.distanceresultlist.KNNResult; +import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction; import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; @@ -115,7 +116,7 @@ public class MinKDistance<O, D extends Distance<D>> extends AbstractDatabaseDist @Override public <T extends O> DistanceQuery<T, D> instantiate(Relation<T> relation) { - return new Instance<T>(relation, k, parentDistance); + return new Instance<>(relation, k, parentDistance); } /** @@ -157,7 +158,7 @@ public class MinKDistance<O, D extends Distance<D>> extends AbstractDatabaseDist @Override public D distance(DBIDRef id1, DBIDRef id2) { - KNNResult<D> neighborhood = knnQuery.getKNNForDBID(id1, k); + KNNList<D> neighborhood = knnQuery.getKNNForDBID(id1, k); D truedist = parentDistanceQuery.distance(id1, id2); return computeReachdist(neighborhood, truedist); } @@ -176,7 +177,7 @@ public class MinKDistance<O, D extends Distance<D>> extends AbstractDatabaseDist * @param truedist True distance * @return Reachability distance */ - protected D computeReachdist(KNNResult<D> neighborhood, D truedist) { + protected D computeReachdist(KNNList<D> neighborhood, D truedist) { // TODO: need to check neighborhood size? // TODO: Do we need to check we actually got the object itself in the // neighborhood? @@ -243,7 +244,7 @@ public class MinKDistance<O, D extends Distance<D>> extends AbstractDatabaseDist k = kP.getValue(); } - final ObjectParameter<DistanceFunction<? super O, D>> parentDistanceP = new ObjectParameter<DistanceFunction<? super O, D>>(DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class); + final ObjectParameter<DistanceFunction<? super O, D>> parentDistanceP = new ObjectParameter<>(DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class); if (config.grab(parentDistanceP)) { parentDistance = parentDistanceP.instantiateClass(config); } @@ -251,7 +252,7 @@ public class MinKDistance<O, D extends Distance<D>> extends AbstractDatabaseDist @Override protected MinKDistance<O, D> makeInstance() { - return new MinKDistance<O, D>(parentDistance, k + (objectIsInKNN ? 0 : 1)); + return new MinKDistance<>(parentDistance, k + (objectIsInKNN ? 0 : 1)); } } } diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Norm.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Norm.java index 98ef1f1d..ae6605f2 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Norm.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Norm.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDistanceFunction.java index f8b62225..8d293e9a 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDoubleDistanceFunction.java index e4d19702..321885b9 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDoubleDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDoubleDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ProxyDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ProxyDistanceFunction.java index 48d49a0c..58dd512a 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ProxyDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ProxyDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -61,7 +61,7 @@ public class ProxyDistanceFunction<O, D extends Distance<D>> extends AbstractDBI * @return Proxy object */ public static <O, D extends Distance<D>> ProxyDistanceFunction<O, D> proxy(DistanceQuery<O, D> inner) { - return new ProxyDistanceFunction<O, D>(inner); + return new ProxyDistanceFunction<>(inner); } @Override diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/RandomStableDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/RandomStableDistanceFunction.java index e57ae501..3d6d1128 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/RandomStableDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/RandomStableDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SharedNearestNeighborJaccardDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SharedNearestNeighborJaccardDistanceFunction.java index 5ff9a433..29732783 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SharedNearestNeighborJaccardDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SharedNearestNeighborJaccardDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -61,7 +61,7 @@ public class SharedNearestNeighborJaccardDistanceFunction<O> extends AbstractInd @Override public <T extends O> Instance<T> instantiate(Relation<T> database) { SharedNearestNeighborIndex<O> indexi = indexFactory.instantiate((Relation<O>) database); - return (Instance<T>) new Instance<O>((Relation<O>) database, indexi, this); + return (Instance<T>) new Instance<>((Relation<O>) database, indexi, this); } /** @@ -157,7 +157,7 @@ public class SharedNearestNeighborJaccardDistanceFunction<O> extends AbstractInd @Override protected SharedNearestNeighborJaccardDistanceFunction<O> makeInstance() { - return new SharedNearestNeighborJaccardDistanceFunction<O>(factory); + return new SharedNearestNeighborJaccardDistanceFunction<>(factory); } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDistanceFunction.java index 27dd1219..0a2b7840 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDoubleDistanceFunction.java index 9ae39089..25a996c6 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDoubleDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDoubleDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SquaredEuclideanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SquaredEuclideanDistanceFunction.java deleted file mode 100644 index ff17f388..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SquaredEuclideanDistanceFunction.java +++ /dev/null @@ -1,196 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distancefunction; - -/* - 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.spatial.SpatialComparable; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; - -/** - * Provides the squared Euclidean distance for FeatureVectors. This results in - * the same rankings, but saves computing the square root as often. - * - * @author Arthur Zimek - */ -public class SquaredEuclideanDistanceFunction extends AbstractVectorDoubleDistanceNorm implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { - /** - * Static instance. Use this! - */ - public static final SquaredEuclideanDistanceFunction STATIC = new SquaredEuclideanDistanceFunction(); - - /** - * Provides a Euclidean distance function that can compute the Euclidean - * distance (that is a DoubleDistance) for FeatureVectors. - * - * @deprecated Use static instance! - */ - @Deprecated - public SquaredEuclideanDistanceFunction() { - super(); - } - - @Override - public double doubleNorm(NumberVector<?> v) { - final int dim = v.getDimensionality(); - double sum = 0; - for(int i = 0; i < dim; i++) { - final double val = v.doubleValue(i); - sum += val * val; - } - return sum; - } - - /** - * Provides the squared Euclidean distance between the given two vectors. - * - * @return the squared Euclidean distance between the given two vectors as raw - * double value - */ - @Override - public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { - final int dim1 = v1.getDimensionality(); - if(dim1 != v2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of FeatureVectors" + "\n first argument: " + v1.toString() + "\n second argument: " + v2.toString() + "\n" + v1.getDimensionality() + "!=" + v2.getDimensionality()); - } - double sqrDist = 0; - for(int i = 0; i < dim1; i++) { - final double delta = v1.doubleValue(i) - v2.doubleValue(i); - sqrDist += delta * delta; - } - return sqrDist; - } - - protected double doubleMinDistObject(SpatialComparable mbr, NumberVector<?> v) { - final int dim = mbr.getDimensionality(); - if(dim != v.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr.toString() + "\n " + "second argument: " + v.toString() + "\n" + dim + "!=" + v.getDimensionality()); - } - - double sqrDist = 0; - for(int d = 0; d < dim; d++) { - double value = v.doubleValue(d); - double r; - if(value < mbr.getMin(d)) { - r = mbr.getMin(d); - } - else if(value > mbr.getMax(d)) { - r = mbr.getMax(d); - } - else { - r = value; - } - - final double manhattanI = value - r; - sqrDist += manhattanI * manhattanI; - } - return sqrDist; - } - - @Override - public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { - // Some optimizations for simpler cases. - if(mbr1 instanceof NumberVector) { - if(mbr2 instanceof NumberVector) { - return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); - } - else { - return doubleMinDistObject(mbr2, (NumberVector<?>) mbr1); - } - } - else if(mbr2 instanceof NumberVector) { - return doubleMinDistObject(mbr1, (NumberVector<?>) mbr2); - } - final int dim1 = mbr1.getDimensionality(); - if(dim1 != mbr2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr1.toString() + "\n " + "second argument: " + mbr2.toString()); - } - - double sqrDist = 0; - for(int d = 0; d < dim1; d++) { - final double m1, m2; - if(mbr1.getMax(d) < mbr2.getMin(d)) { - m1 = mbr2.getMin(d); - m2 = mbr1.getMax(d); - } - else if(mbr1.getMin(d) > mbr2.getMax(d)) { - m1 = mbr1.getMin(d); - m2 = mbr2.getMax(d); - } - else { // The mbrs intersect! - continue; - } - final double manhattanI = m1 - m2; - sqrDist += manhattanI * manhattanI; - } - return sqrDist; - } - - @Override - public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) { - return new DoubleDistance(doubleMinDist(mbr1, mbr2)); - } - - @Override - public boolean isMetric() { - return false; - } - - @Override - public <T extends NumberVector<?>> SpatialPrimitiveDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) { - return new SpatialPrimitiveDistanceQuery<T, DoubleDistance>(relation, this); - } - - @Override - public String toString() { - return "SquaredEuclideanDistance"; - } - - @Override - public boolean equals(Object obj) { - if(obj == null) { - return false; - } - if(obj == this) { - return true; - } - return this.getClass().equals(obj.getClass()); - } - - /** - * Parameterization class. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - public static class Parameterizer extends AbstractParameterizer { - @Override - protected SquaredEuclideanDistanceFunction makeInstance() { - return SquaredEuclideanDistanceFunction.STATIC; - } - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedCanberraDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedCanberraDistanceFunction.java new file mode 100644 index 00000000..66321b36 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedCanberraDistanceFunction.java @@ -0,0 +1,91 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction; + +/* + 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 de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; + +/** + * Weighted Canberra distance function, a variation of Manhattan distance. + * + * TODO: add parameterizer. As of now, this can only be used from Java code. + * + * @author Erich Schubert + */ +public class WeightedCanberraDistanceFunction extends AbstractSpatialDoubleDistanceFunction { + /** + * Weight array + */ + protected double[] weights; + + /** + * Constructor. + */ + public WeightedCanberraDistanceFunction(double[] weights) { + super(); + this.weights = weights; + } + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2, weights.length); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + final double div = Math.abs(xd) + Math.abs(yd); + if (div > 0.) { + agg += weights[d] * Math.abs(xd - yd) / div; + } + } + return agg; + } + + @Override + public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + final int dim = dimensionality(mbr1, mbr2, weights.length); + double agg = 0.0; + for (int d = 0; d < dim; d++) { + final double diff; + if (mbr1.getMax(d) < mbr2.getMin(d)) { + diff = mbr2.getMin(d) - mbr1.getMax(d); + } else if (mbr1.getMin(d) > mbr2.getMax(d)) { + diff = mbr1.getMin(d) - mbr2.getMax(d); + } else { // The mbrs intersect! + continue; + } + final double a1 = Math.max(-mbr1.getMin(d), mbr1.getMax(d)); + final double a2 = Math.max(-mbr2.getMin(d), mbr2.getMax(d)); + final double div = a1 + a2; + // Cannot be 0, because then diff = 0, and we continued before. + agg += weights[d] * diff / div; + } + return agg; + } + + @Override + public boolean isMetric() { + // As this is also reffered to as "canberra metric", it is probably a metric + // But *maybe* only for positive numbers only? + return true; + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedDistanceFunction.java index 7bd09e97..fc155970 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -52,21 +52,15 @@ public class WeightedDistanceFunction extends AbstractVectorDoubleDistanceFuncti assert (weightMatrix.getColumnDimensionality() == weightMatrix.getRowDimensionality()); } - /** - * Provides the Weighted distance for feature vectors. - * - * @return the Weighted distance between the given two vectors - */ @Override public double doubleDistance(NumberVector<?> o1, NumberVector<?> o2) { - assert (o1.getDimensionality() == o2.getDimensionality()) : "Different dimensionality of FeatureVectors" + "\n first argument: " + o1.toString() + "\n second argument: " + o2.toString(); - + dimensionality(o1, o2, weightMatrix.getColumnDimensionality()); Vector o1_minus_o2 = o1.getColumnVector().minusEquals(o2.getColumnVector()); return MathUtil.mahalanobisDistance(weightMatrix, o1_minus_o2); } @Override public VectorFieldTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { - return new VectorFieldTypeInformation<NumberVector<?>>(NumberVector.class, weightMatrix.getColumnDimensionality()); + return new VectorFieldTypeInformation<>(NumberVector.class, weightMatrix.getColumnDimensionality()); } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/AbstractSimilarityAdapter.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/AbstractSimilarityAdapter.java index 74606083..890a3ece 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/AbstractSimilarityAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/AbstractSimilarityAdapter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.adapter; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -175,7 +175,7 @@ public abstract class AbstractSimilarityAdapter<O> extends AbstractDatabaseDista @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); - final ObjectParameter<NormalizedSimilarityFunction<? super O, ? extends NumberDistance<?, ?>>> param = new ObjectParameter<NormalizedSimilarityFunction<? super O, ? extends NumberDistance<?, ?>>>(SIMILARITY_FUNCTION_ID, NormalizedSimilarityFunction.class, FractionalSharedNearestNeighborSimilarityFunction.class); + final ObjectParameter<NormalizedSimilarityFunction<? super O, ? extends NumberDistance<?, ?>>> param = new ObjectParameter<>(SIMILARITY_FUNCTION_ID, NormalizedSimilarityFunction.class, FractionalSharedNearestNeighborSimilarityFunction.class); if(config.grab(param)) { similarityFunction = param.instantiateClass(config); } diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/SimilarityAdapterArccos.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/ArccosSimilarityAdapter.java index b77e4a7d..a808e2a5 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/SimilarityAdapterArccos.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/ArccosSimilarityAdapter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.adapter; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -41,20 +41,20 @@ import de.lmu.ifi.dbs.elki.distance.similarityfunction.NormalizedSimilarityFunct * * @param <O> Object class to process. */ -public class SimilarityAdapterArccos<O> extends AbstractSimilarityAdapter<O> { +public class ArccosSimilarityAdapter<O> extends AbstractSimilarityAdapter<O> { /** * Constructor. * * @param similarityFunction Similarity function */ - public SimilarityAdapterArccos(NormalizedSimilarityFunction<? super O, ? extends NumberDistance<?, ?>> similarityFunction) { + public ArccosSimilarityAdapter(NormalizedSimilarityFunction<? super O, ? extends NumberDistance<?, ?>> similarityFunction) { super(similarityFunction); } @Override public <T extends O> DistanceQuery<T, DoubleDistance> instantiate(Relation<T> database) { SimilarityQuery<T, ? extends NumberDistance<?, ?>> similarityQuery = similarityFunction.instantiate(database); - return new Instance<T>(database, this, similarityQuery); + return new Instance<>(database, this, similarityQuery); } /** @@ -91,8 +91,8 @@ public class SimilarityAdapterArccos<O> extends AbstractSimilarityAdapter<O> { */ public static class Parameterizer<O> extends AbstractSimilarityAdapter.Parameterizer<O> { @Override - protected SimilarityAdapterArccos<O> makeInstance() { - return new SimilarityAdapterArccos<O>(similarityFunction); + protected ArccosSimilarityAdapter<O> makeInstance() { + return new ArccosSimilarityAdapter<>(similarityFunction); } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/SimilarityAdapterLinear.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/LinearAdapterLinear.java index ab7204ce..c78ff112 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/SimilarityAdapterLinear.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/LinearAdapterLinear.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.adapter; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -41,20 +41,20 @@ import de.lmu.ifi.dbs.elki.distance.similarityfunction.NormalizedSimilarityFunct * * @param <O> Object class to process. */ -public class SimilarityAdapterLinear<O> extends AbstractSimilarityAdapter<O> { +public class LinearAdapterLinear<O> extends AbstractSimilarityAdapter<O> { /** * Constructor. * * @param similarityFunction Similarity function */ - public SimilarityAdapterLinear(NormalizedSimilarityFunction<? super O, ? extends NumberDistance<?, ?>> similarityFunction) { + public LinearAdapterLinear(NormalizedSimilarityFunction<? super O, ? extends NumberDistance<?, ?>> similarityFunction) { super(similarityFunction); } @Override public <T extends O> DistanceQuery<T, DoubleDistance> instantiate(Relation<T> database) { SimilarityQuery<T, ? extends NumberDistance<?, ?>> similarityQuery = similarityFunction.instantiate(database); - return new Instance<T>(database, this, similarityQuery); + return new Instance<>(database, this, similarityQuery); } /** @@ -91,8 +91,8 @@ public class SimilarityAdapterLinear<O> extends AbstractSimilarityAdapter<O> { */ public static class Parameterizer<O> extends AbstractSimilarityAdapter.Parameterizer<O> { @Override - protected SimilarityAdapterLinear<O> makeInstance() { - return new SimilarityAdapterLinear<O>(similarityFunction); + protected LinearAdapterLinear<O> makeInstance() { + return new LinearAdapterLinear<>(similarityFunction); } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/SimilarityAdapterLn.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/LnSimilarityAdapter.java index b1b63486..2a9b49f9 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/SimilarityAdapterLn.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/LnSimilarityAdapter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.adapter; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -41,20 +41,20 @@ import de.lmu.ifi.dbs.elki.distance.similarityfunction.NormalizedSimilarityFunct * * @param <O> object class to process. */ -public class SimilarityAdapterLn<O> extends AbstractSimilarityAdapter<O> { +public class LnSimilarityAdapter<O> extends AbstractSimilarityAdapter<O> { /** * Constructor. * * @param similarityFunction Similarity function */ - public SimilarityAdapterLn(NormalizedSimilarityFunction<? super O, ? extends NumberDistance<?, ?>> similarityFunction) { + public LnSimilarityAdapter(NormalizedSimilarityFunction<? super O, ? extends NumberDistance<?, ?>> similarityFunction) { super(similarityFunction); } @Override public <T extends O> DistanceQuery<T, DoubleDistance> instantiate(Relation<T> database) { SimilarityQuery<T, ? extends NumberDistance<?, ?>> similarityQuery = similarityFunction.instantiate(database); - return new Instance<T>(database, this, similarityQuery); + return new Instance<>(database, this, similarityQuery); } /** @@ -91,8 +91,8 @@ public class SimilarityAdapterLn<O> extends AbstractSimilarityAdapter<O> { */ public static class Parameterizer<O> extends AbstractSimilarityAdapter.Parameterizer<O> { @Override - protected SimilarityAdapterLn<O> makeInstance() { - return new SimilarityAdapterLn<O>(similarityFunction); + protected LnSimilarityAdapter<O> makeInstance() { + return new LnSimilarityAdapter<>(similarityFunction); } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/package-info.java index 303d3500..14346688 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HSBHistogramQuadraticDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HSBHistogramQuadraticDistanceFunction.java index 771e32f2..414a4787 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HSBHistogramQuadraticDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HSBHistogramQuadraticDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -89,8 +89,14 @@ public class HSBHistogramQuadraticDistanceFunction extends WeightedDistanceFunct final int sy = (y / quantb) % quants; final int by = y % quantb; - final double cos = Math.cos((hx + .5) / quanth * MathUtil.TWOPI) * (sx + .5) / quants - Math.cos((hy + .5) / quanth * MathUtil.TWOPI) * (sy + .5) / quants; - final double sin = Math.sin((hx + .5) / quanth * MathUtil.TWOPI) * (sx + .5) / quants - Math.sin((hy + .5) / quanth * MathUtil.TWOPI) * (sy + .5) / quants; + final double chx = Math.cos((hx + .5) / quanth * MathUtil.TWOPI); + final double chy = Math.cos((hy + .5) / quanth * MathUtil.TWOPI); + // final double shx = Math.sin((hx + .5) / quanth * MathUtil.TWOPI); + final double shx = MathUtil.cosToSin((hx + .5) / quanth * MathUtil.TWOPI, chx); + // final double shy = Math.sin((hy + .5) / quanth * MathUtil.TWOPI); + final double shy = MathUtil.cosToSin((hy + .5) / quanth * MathUtil.TWOPI, chy); + final double cos = chx * (sx + .5) / quants - chy * (sy + .5) / quants; + final double sin = shx * (sx + .5) / quants - shy * (sy + .5) / quants; final double db = (bx - by) / (double) quantb; final double val = 1. - Math.sqrt((db * db + sin * sin + cos * cos) / 5); m.set(x, y, val); diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HistogramIntersectionDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HistogramIntersectionDistanceFunction.java index 2f38f68b..ffced03f 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HistogramIntersectionDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HistogramIntersectionDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,12 +25,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialDistanceQuery; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDoubleDistanceFunction; import de.lmu.ifi.dbs.elki.utilities.documentation.Description; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; import de.lmu.ifi.dbs.elki.utilities.documentation.Title; @@ -48,7 +43,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; @Title("Color histogram intersection distance") @Description("Distance function for color histograms that emphasizes 'strong' bins.") @Reference(authors = "M. J. Swain, D. H. Ballard", title = "Color Indexing", booktitle = "International Journal of Computer Vision, 7(1), 32, 1991") -public class HistogramIntersectionDistanceFunction extends AbstractVectorDoubleDistanceFunction implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { +public class HistogramIntersectionDistanceFunction extends AbstractSpatialDoubleDistanceFunction { /** * Static instance */ @@ -65,55 +60,33 @@ public class HistogramIntersectionDistanceFunction extends AbstractVectorDoubleD } @Override - public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) { - return new DoubleDistance(doubleMinDist(mbr1, mbr2)); - } - - @Override public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { - final int dim1 = v1.getDimensionality(); - if(dim1 != v2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of FeatureVectors" + "\n first argument: " + v1.toString() + "\n second argument: " + v2.toString() + "\n" + v1.getDimensionality() + "!=" + v2.getDimensionality()); - } - double dist = 0; - double norm1 = 0; - double norm2 = 0; - for(int i = 0; i < dim1; i++) { + final int dim = dimensionality(v1, v2); + double agg = 0., norm1 = 0., norm2 = 0.; + for (int i = 0; i < dim; i++) { final double val1 = v1.doubleValue(i); final double val2 = v2.doubleValue(i); - dist += Math.min(val1, val2); + agg += Math.min(val1, val2); norm1 += val1; norm2 += val2; } - dist = 1 - dist / Math.min(norm1, norm2); - return dist; + return 1. - agg / Math.min(norm1, norm2); } @Override public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { - final int dim1 = mbr1.getDimensionality(); - if(dim1 != mbr2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of FeatureVectors" + "\n first argument: " + mbr1.toString() + "\n second argument: " + mbr2.toString() + "\n" + mbr1.getDimensionality() + "!=" + mbr2.getDimensionality()); - } - double dist = 0; - double norm1 = 0; - double norm2 = 0; - for(int i = 0; i < dim1; i++) { + final int dim = dimensionality(mbr1, mbr2); + double agg = 0., norm1 = 0, norm2 = 0.; + for (int i = 0; i < dim; i++) { final double min1 = mbr1.getMin(i); final double max1 = mbr1.getMax(i); final double min2 = mbr2.getMin(i); final double max2 = mbr2.getMax(i); - dist += Math.min(max1, max2); + agg += Math.min(max1, max2); norm1 += min1; norm2 += min2; } - dist = 1 - dist / Math.min(norm1, norm2); - return dist; - } - - @Override - public <T extends NumberVector<?>> SpatialDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) { - return new SpatialPrimitiveDistanceQuery<T, DoubleDistance>(relation, this); + return 1 - agg / Math.min(norm1, norm2); } @Override @@ -123,7 +96,7 @@ public class HistogramIntersectionDistanceFunction extends AbstractVectorDoubleD @Override public boolean equals(Object obj) { - if(obj == null) { + if (obj == null) { return false; } return this.getClass().equals(obj.getClass()); @@ -142,4 +115,4 @@ public class HistogramIntersectionDistanceFunction extends AbstractVectorDoubleD return HistogramIntersectionDistanceFunction.STATIC; } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/RGBHistogramQuadraticDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/RGBHistogramQuadraticDistanceFunction.java index 09dfa124..8cf0339e 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/RGBHistogramQuadraticDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/RGBHistogramQuadraticDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/package-info.java index 43e90206..a61c1e49 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/ERiCDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/ERiCDistanceFunction.java index 55fd0e72..bece8279 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/ERiCDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/ERiCDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -113,7 +113,7 @@ public class ERiCDistanceFunction extends AbstractIndexBasedDistanceFunction<Num // Generics (AFAICT) @SuppressWarnings("unchecked") FilteredLocalPCAIndex<T> indexinst = (FilteredLocalPCAIndex<T>) indexFactory.instantiate((Relation<NumberVector<?>>) database); - return new Instance<T>(database, indexinst, this, delta, tau); + return new Instance<>(database, indexinst, this, delta, tau); } /** diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PCABasedCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PCABasedCorrelationDistanceFunction.java index 20f96a29..4d5553a3 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PCABasedCorrelationDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PCABasedCorrelationDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -88,7 +88,7 @@ public class PCABasedCorrelationDistanceFunction extends AbstractIndexBasedDista // Generics (AFAICT) @SuppressWarnings("unchecked") FilteredLocalPCAIndex<T> indexinst = (FilteredLocalPCAIndex<T>) indexFactory.instantiate((Relation<NumberVector<?>>) database); - return new Instance<T>(database, indexinst, delta, this); + return new Instance<>(database, indexinst, delta, this); } @Override diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PearsonCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PearsonCorrelationDistanceFunction.java index 1ba14af2..8716ad6e 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PearsonCorrelationDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PearsonCorrelationDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/SquaredPearsonCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/SquaredPearsonCorrelationDistanceFunction.java index b4f8a3bd..8ddb0de6 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/SquaredPearsonCorrelationDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/SquaredPearsonCorrelationDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedPearsonCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedPearsonCorrelationDistanceFunction.java index fa1196fe..67b1dc27 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedPearsonCorrelationDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedPearsonCorrelationDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -93,4 +93,9 @@ public class WeightedPearsonCorrelationDistanceFunction extends AbstractVectorDo } return Arrays.equals(this.weights, ((WeightedPearsonCorrelationDistanceFunction)obj).weights); } + + @Override + public String toString() { + return "WeightedPearsonCorrelationDistanceFunction"; + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedSquaredPearsonCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedSquaredPearsonCorrelationDistanceFunction.java index 141229f6..0c1848fc 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedSquaredPearsonCorrelationDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedSquaredPearsonCorrelationDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/package-info.java index 2033dab1..c422a3da 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedDoubleDistanceFunction.java index a7ddb1ad..e84f18b8 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedDoubleDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedDoubleDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedFloatDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedFloatDistanceFunction.java index 23da36b2..cd84853b 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedFloatDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedFloatDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParser.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParser.java index c332670a..08c3c312 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParser.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParser.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParsingResult.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParsingResult.java index 916451c0..3f43cb97 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParsingResult.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParsingResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java index 5489a241..29546401 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -170,7 +170,7 @@ public class FileBasedDoubleDistanceFunction extends AbstractDBIDDistanceFunctio matrixfile = MATRIX_PARAM.getValue(); } - final ObjectParameter<DistanceParser<DoubleDistance>> PARSER_PARAM = new ObjectParameter<DistanceParser<DoubleDistance>>(PARSER_ID, DistanceParser.class, NumberDistanceParser.class); + final ObjectParameter<DistanceParser<DoubleDistance>> PARSER_PARAM = new ObjectParameter<>(PARSER_ID, DistanceParser.class, NumberDistanceParser.class); if(config.grab(PARSER_PARAM)) { ListParameterization parserConfig = new ListParameterization(); parserConfig.addParameter(DistanceParser.DISTANCE_ID, DoubleDistance.class); diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedFloatDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedFloatDistanceFunction.java index 520c1f76..994d854d 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedFloatDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedFloatDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -168,13 +168,13 @@ public class FileBasedFloatDistanceFunction extends AbstractDBIDDistanceFunction if(config.grab(MATRIX_PARAM)) { matrixfile = MATRIX_PARAM.getValue(); } - final ObjectParameter<DistanceParser<FloatDistance>> PARSER_PARAM = new ObjectParameter<DistanceParser<FloatDistance>>(PARSER_ID, DistanceParser.class, NumberDistanceParser.class); + final ObjectParameter<DistanceParser<FloatDistance>> PARSER_PARAM = new ObjectParameter<>(PARSER_ID, DistanceParser.class, NumberDistanceParser.class); if(config.grab(PARSER_PARAM)) { ListParameterization parserConfig = new ListParameterization(); parserConfig.addParameter(DistanceParser.DISTANCE_ID, FloatDistance.class); ChainedParameterization combinedConfig = new ChainedParameterization(parserConfig, config); combinedConfig.errorsTo(config); - parser = PARSER_PARAM.instantiateClass(config); + parser = PARSER_PARAM.instantiateClass(combinedConfig); } } diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/NumberDistanceParser.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/NumberDistanceParser.java index 82cc5b27..9a7315b3 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/NumberDistanceParser.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/NumberDistanceParser.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -79,10 +79,11 @@ public class NumberDistanceParser<D extends NumberDistance<D, ?>> extends Abstra * * @param colSep Column separator pattern * @param quoteChar Quote character + * @param comment Comment pattern * @param distanceFactory Distance factory to use */ - public NumberDistanceParser(Pattern colSep, char quoteChar, D distanceFactory) { - super(colSep, quoteChar); + public NumberDistanceParser(Pattern colSep, char quoteChar, Pattern comment, D distanceFactory) { + super(colSep, quoteChar, comment); this.distanceFactory = distanceFactory; } @@ -93,39 +94,41 @@ public class NumberDistanceParser<D extends NumberDistance<D, ?>> extends Abstra IndefiniteProgress prog = LOG.isVerbose() ? new IndefiniteProgress("Parsing distance matrix", LOG) : null; ModifiableDBIDs ids = DBIDUtil.newHashSet(); - Map<DBIDPair, D> distanceCache = new HashMap<DBIDPair, D>(); + Map<DBIDPair, D> distanceCache = new HashMap<>(); try { for (String line; (line = reader.readLine()) != null; lineNumber++) { if (prog != null) { prog.incrementProcessed(LOG); } - if (!line.startsWith(COMMENT) && line.length() > 0) { - List<String> entries = tokenize(line); - if (entries.size() != 3) { - throw new IllegalArgumentException("Line " + lineNumber + " does not have the " + "required input format: id1 id2 distanceValue! " + line); - } - - DBID id1, id2; - try { - id1 = DBIDUtil.importInteger(Integer.parseInt(entries.get(0))); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Error in line " + lineNumber + ": id1 is no integer!"); - } - - try { - id2 = DBIDUtil.importInteger(Integer.parseInt(entries.get(1))); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Error in line " + lineNumber + ": id2 is no integer!"); - } - - try { - D distance = distanceFactory.parseString(entries.get(2)); - put(id1, id2, distance, distanceCache); - ids.add(id1); - ids.add(id2); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Error in line " + lineNumber + ":" + e.getMessage(), e); - } + // Skip empty lines and comments + if (line.length() <= 0 || (comment != null && comment.matcher(line).matches())) { + continue; + } + List<String> entries = tokenize(line); + if (entries.size() != 3) { + throw new IllegalArgumentException("Line " + lineNumber + " does not have the " + "required input format: id1 id2 distanceValue! " + line); + } + + DBID id1, id2; + try { + id1 = DBIDUtil.importInteger(Integer.parseInt(entries.get(0))); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Error in line " + lineNumber + ": id1 is no integer!"); + } + + try { + id2 = DBIDUtil.importInteger(Integer.parseInt(entries.get(1))); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Error in line " + lineNumber + ": id2 is no integer!"); + } + + try { + D distance = distanceFactory.parseString(entries.get(2)); + put(id1, id2, distance, distanceCache); + ids.add(id1); + ids.add(id2); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Error in line " + lineNumber + ":" + e.getMessage(), e); } } } catch (IOException e) { @@ -147,7 +150,7 @@ public class NumberDistanceParser<D extends NumberDistance<D, ?>> extends Abstra } } } - return new DistanceParsingResult<D>(distanceCache); + return new DistanceParsingResult<>(distanceCache); } /** @@ -211,7 +214,7 @@ public class NumberDistanceParser<D extends NumberDistance<D, ?>> extends Abstra @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); - ObjectParameter<D> distFuncP = new ObjectParameter<D>(DISTANCE_ID, Distance.class); + ObjectParameter<D> distFuncP = new ObjectParameter<>(DISTANCE_ID, Distance.class); if (config.grab(distFuncP)) { distanceFactory = distFuncP.instantiateClass(config); } @@ -219,7 +222,7 @@ public class NumberDistanceParser<D extends NumberDistance<D, ?>> extends Abstra @Override protected NumberDistanceParser<D> makeInstance() { - return new NumberDistanceParser<D>(colSep, quoteChar, distanceFactory); + return new NumberDistanceParser<>(colSep, quoteChar, comment, distanceFactory); } } } diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/package-info.java index 3099122a..53b692fa 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/package-info.java @@ -6,7 +6,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/DimensionSelectingLatLngDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/DimensionSelectingLatLngDistanceFunction.java index 42fd869d..1974e533 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/DimensionSelectingLatLngDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/DimensionSelectingLatLngDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.geo; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,25 +27,25 @@ import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; -import de.lmu.ifi.dbs.elki.math.GeoUtil; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDoubleDistanceFunction; +import de.lmu.ifi.dbs.elki.math.geodesy.EarthModel; +import de.lmu.ifi.dbs.elki.math.geodesy.SphericalVincentyEarthModel; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterEqualConstraint; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.NoDuplicateValueGlobalConstraint; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; /** * Distance function for 2D vectors in Latitude, Longitude form. * * @author Erich Schubert */ -public class DimensionSelectingLatLngDistanceFunction extends AbstractVectorDoubleDistanceFunction implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { +public class DimensionSelectingLatLngDistanceFunction extends AbstractSpatialDoubleDistanceFunction { /** * Latitude dimension. */ @@ -57,54 +57,90 @@ public class DimensionSelectingLatLngDistanceFunction extends AbstractVectorDoub final int dimlng; /** + * Earth model used. + */ + final EarthModel model; + + /** * Constructor. * * @param dimlat Dimension storing the latitude * @param dimlng Dimension storing the longitude + * @param model Earth model */ - public DimensionSelectingLatLngDistanceFunction(int dimlat, int dimlng) { + public DimensionSelectingLatLngDistanceFunction(int dimlat, int dimlng, EarthModel model) { super(); this.dimlat = dimlat; this.dimlng = dimlng; + this.model = model; } @Override public double doubleDistance(NumberVector<?> o1, NumberVector<?> o2) { - return GeoUtil.haversineFormulaDeg(o1.doubleValue(dimlat), o1.doubleValue(dimlng), o2.doubleValue(dimlat), o2.doubleValue(dimlng)); + return model.distanceDeg(o1.doubleValue(dimlat), o1.doubleValue(dimlng), o2.doubleValue(dimlat), o2.doubleValue(dimlng)); } @Override + @Reference(authors = "Erich Schubert, Arthur Zimek and Hans-Peter Kriegel", title = "Geodetic Distance Queries on R-Trees for Indexing Geographic Data", booktitle = "Advances in Spatial and Temporal Databases - 13th International Symposium, SSTD 2013, Munich, Germany") public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { if (mbr1 instanceof NumberVector) { if (mbr2 instanceof NumberVector) { return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); } else { NumberVector<?> o1 = (NumberVector<?>) mbr1; - return GeoUtil.latlngMinDistDeg(o1.doubleValue(dimlat), o1.doubleValue(dimlng), mbr2.getMin(dimlat), mbr2.getMin(dimlng), mbr2.getMax(dimlat), mbr2.getMax(dimlng)); + return model.minDistDeg(o1.doubleValue(dimlat), o1.doubleValue(dimlng), mbr2.getMin(dimlat), mbr2.getMin(dimlng), mbr2.getMax(dimlat), mbr2.getMax(dimlng)); } } else { if (mbr2 instanceof NumberVector) { NumberVector<?> o2 = (NumberVector<?>) mbr2; - return GeoUtil.latlngMinDistDeg(o2.doubleValue(dimlat), o2.doubleValue(dimlng), mbr1.getMin(dimlat), mbr1.getMin(dimlng), mbr1.getMax(dimlat), mbr1.getMax(dimlng)); + return model.minDistDeg(o2.doubleValue(dimlat), o2.doubleValue(dimlng), mbr1.getMin(dimlat), mbr1.getMin(dimlng), mbr1.getMax(dimlat), mbr1.getMax(dimlng)); } else { - throw new UnsupportedOperationException("MBR to MBR mindist is not yet implemented."); + throw new NotImplementedException("This distance function cannot - yet - be used with this algorithm, as the lower bound rectangle to rectangle distances have not yet been formalized for geodetic data."); } } } @Override - public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) { - return new DoubleDistance(doubleMinDist(mbr1, mbr2)); + public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { + return new VectorFieldTypeInformation<>(NumberVector.class, Math.max(dimlat, dimlng), Integer.MAX_VALUE); } @Override - public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { - return new VectorFieldTypeInformation<NumberVector<?>>(NumberVector.class, Math.max(dimlat, dimlng), Integer.MAX_VALUE); + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + dimlat; + result = prime * result + dimlng; + result = prime * result + ((model == null) ? 0 : model.hashCode()); + return result; } @Override - public <T extends NumberVector<?>> SpatialPrimitiveDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) { - return new SpatialPrimitiveDistanceQuery<T, DoubleDistance>(relation, this); + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + DimensionSelectingLatLngDistanceFunction other = (DimensionSelectingLatLngDistanceFunction) obj; + if (dimlat != other.dimlat) { + return false; + } + if (dimlng != other.dimlng) { + return false; + } + if (model == null) { + if (other.model != null) { + return false; + } + } else if (!model.equals(other.model)) { + return false; + } + return true; } /** @@ -135,6 +171,11 @@ public class DimensionSelectingLatLngDistanceFunction extends AbstractVectorDoub */ int dimlng; + /** + * Earth model used. + */ + EarthModel model; + @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); @@ -149,11 +190,15 @@ public class DimensionSelectingLatLngDistanceFunction extends AbstractVectorDoub dimlng = dimlngP.getValue(); } config.checkConstraint(new NoDuplicateValueGlobalConstraint(dimlatP, dimlngP)); + ObjectParameter<EarthModel> modelP = new ObjectParameter<>(EarthModel.MODEL_ID, EarthModel.class, SphericalVincentyEarthModel.class); + if (config.grab(modelP)) { + model = modelP.instantiateClass(config); + } } @Override protected DimensionSelectingLatLngDistanceFunction makeInstance() { - return new DimensionSelectingLatLngDistanceFunction(dimlat, dimlng); + return new DimensionSelectingLatLngDistanceFunction(dimlat, dimlng, model); } } } diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LatLngDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LatLngDistanceFunction.java index 31bed1c5..221cfa2b 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LatLngDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LatLngDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.geo; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,86 +27,94 @@ import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; -import de.lmu.ifi.dbs.elki.math.GeoUtil; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDoubleDistanceFunction; +import de.lmu.ifi.dbs.elki.math.geodesy.EarthModel; +import de.lmu.ifi.dbs.elki.math.geodesy.SphericalVincentyEarthModel; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; /** * Distance function for 2D vectors in Latitude, Longitude form. * * @author Erich Schubert */ -public class LatLngDistanceFunction extends AbstractVectorDoubleDistanceFunction implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { +public class LatLngDistanceFunction extends AbstractSpatialDoubleDistanceFunction { /** - * Static instance. + * Earth model to use. */ - public static final LatLngDistanceFunction STATIC = new LatLngDistanceFunction(); + private EarthModel model; /** - * Constructor. Use static instance instead! + * Constructor. */ - @Deprecated - public LatLngDistanceFunction() { + public LatLngDistanceFunction(EarthModel model) { super(); + this.model = model; } @Override public double doubleDistance(NumberVector<?> o1, NumberVector<?> o2) { - return GeoUtil.haversineFormulaDeg(o1.doubleValue(0), o1.doubleValue(1), o2.doubleValue(0), o2.doubleValue(1)); + return model.distanceDeg(o1.doubleValue(0), o1.doubleValue(1), o2.doubleValue(0), o2.doubleValue(1)); } @Override + @Reference(authors = "Erich Schubert, Arthur Zimek and Hans-Peter Kriegel", title = "Geodetic Distance Queries on R-Trees for Indexing Geographic Data", booktitle = "Advances in Spatial and Temporal Databases - 13th International Symposium, SSTD 2013, Munich, Germany") public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { if (mbr1 instanceof NumberVector) { if (mbr2 instanceof NumberVector) { return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); } else { NumberVector<?> o1 = (NumberVector<?>) mbr1; - return GeoUtil.latlngMinDistDeg(o1.doubleValue(0), o1.doubleValue(1), mbr2.getMin(0), mbr2.getMin(1), mbr2.getMax(0), mbr2.getMax(1)); + return model.minDistDeg(o1.doubleValue(0), o1.doubleValue(1), mbr2.getMin(0), mbr2.getMin(1), mbr2.getMax(0), mbr2.getMax(1)); } } else { if (mbr2 instanceof NumberVector) { NumberVector<?> o2 = (NumberVector<?>) mbr2; - return GeoUtil.latlngMinDistDeg(o2.doubleValue(0), o2.doubleValue(1), mbr1.getMin(0), mbr1.getMin(1), mbr1.getMax(0), mbr1.getMax(1)); + return model.minDistDeg(o2.doubleValue(0), o2.doubleValue(1), mbr1.getMin(0), mbr1.getMin(1), mbr1.getMax(0), mbr1.getMax(1)); } else { - throw new UnsupportedOperationException("MBR to MBR mindist is not yet implemented."); + throw new NotImplementedException("This distance function cannot - yet - be used with this algorithm, as the lower bound rectangle to rectangle distances have not yet been formalized for geodetic data."); } } } @Override - public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) { - return new DoubleDistance(doubleMinDist(mbr1, mbr2)); + public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { + return new VectorFieldTypeInformation<>(NumberVector.class, 2); } @Override - public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { - return new VectorFieldTypeInformation<NumberVector<?>>(NumberVector.class, 2); + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((model == null) ? 0 : model.hashCode()); + return result; } @Override public boolean equals(Object obj) { + if (this == obj) { + return true; + } if (obj == null) { return false; } - if (obj == this) { - return true; + if (getClass() != obj.getClass()) { + return false; } - if (this.getClass().equals(obj.getClass())) { - return true; + LatLngDistanceFunction other = (LatLngDistanceFunction) obj; + if (model == null) { + if (other.model != null) { + return false; + } + } else if (!model.equals(other.model)) { + return false; } - return super.equals(obj); + return true; } - @Override - public <T extends NumberVector<?>> SpatialPrimitiveDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) { - return new SpatialPrimitiveDistanceQuery<T, DoubleDistance>(relation, this); - } - /** * Parameterization class. * @@ -115,9 +123,23 @@ public class LatLngDistanceFunction extends AbstractVectorDoubleDistanceFunction * @apiviz.exclude */ public static class Parameterizer extends AbstractParameterizer { + /** + * Earth model used. + */ + EarthModel model; + + @Override + protected void makeOptions(Parameterization config) { + super.makeOptions(config); + ObjectParameter<EarthModel> modelP = new ObjectParameter<>(EarthModel.MODEL_ID, EarthModel.class, SphericalVincentyEarthModel.class); + if (config.grab(modelP)) { + model = modelP.instantiateClass(config); + } + } + @Override protected LatLngDistanceFunction makeInstance() { - return LatLngDistanceFunction.STATIC; + return new LatLngDistanceFunction(model); } } } diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LngLatDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LngLatDistanceFunction.java index 7064224a..98a219dd 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LngLatDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LngLatDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.geo; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,86 +27,99 @@ import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; -import de.lmu.ifi.dbs.elki.math.GeoUtil; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDoubleDistanceFunction; +import de.lmu.ifi.dbs.elki.math.geodesy.EarthModel; +import de.lmu.ifi.dbs.elki.math.geodesy.SphericalVincentyEarthModel; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; /** * Distance function for 2D vectors in Longitude, Latitude form. * * @author Erich Schubert */ -public class LngLatDistanceFunction extends AbstractVectorDoubleDistanceFunction implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { +public class LngLatDistanceFunction extends AbstractSpatialDoubleDistanceFunction { /** - * Static instance. + * Earth model to use. */ - public static final LngLatDistanceFunction STATIC = new LngLatDistanceFunction(); + private EarthModel model; /** - * Constructor. Use static instance instead! + * Constructor. */ - @Deprecated - public LngLatDistanceFunction() { + public LngLatDistanceFunction(EarthModel model) { super(); + this.model = model; } @Override public double doubleDistance(NumberVector<?> o1, NumberVector<?> o2) { - return GeoUtil.haversineFormulaDeg(o1.doubleValue(1), o1.doubleValue(0), o2.doubleValue(1), o2.doubleValue(0)); + return model.distanceDeg(o1.doubleValue(1), o1.doubleValue(0), o2.doubleValue(1), o2.doubleValue(0)); } @Override + @Reference(authors = "Erich Schubert, Arthur Zimek and Hans-Peter Kriegel", title = "Geodetic Distance Queries on R-Trees for Indexing Geographic Data", booktitle = "Advances in Spatial and Temporal Databases - 13th International Symposium, SSTD 2013, Munich, Germany") public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { if (mbr1 instanceof NumberVector) { if (mbr2 instanceof NumberVector) { return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); } else { NumberVector<?> o1 = (NumberVector<?>) mbr1; - return GeoUtil.latlngMinDistDeg(o1.doubleValue(1), o1.doubleValue(0), mbr2.getMin(1), mbr2.getMin(0), mbr2.getMax(1), mbr2.getMax(0)); + return model.minDistDeg(o1.doubleValue(1), o1.doubleValue(0), mbr2.getMin(1), mbr2.getMin(0), mbr2.getMax(1), mbr2.getMax(0)); } } else { if (mbr2 instanceof NumberVector) { NumberVector<?> o2 = (NumberVector<?>) mbr2; - return GeoUtil.latlngMinDistDeg(o2.doubleValue(1), o2.doubleValue(0), mbr1.getMin(1), mbr1.getMin(0), mbr1.getMax(1), mbr1.getMax(0)); + return model.minDistDeg(o2.doubleValue(1), o2.doubleValue(0), mbr1.getMin(1), mbr1.getMin(0), mbr1.getMax(1), mbr1.getMax(0)); } else { - throw new UnsupportedOperationException("MBR to MBR mindist is not yet implemented."); + throw new NotImplementedException("This distance function cannot - yet - be used with this algorithm, as the lower bound rectangle to rectangle distances have not yet been formalized for geodetic data."); } } } @Override - public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) { - return new DoubleDistance(doubleMinDist(mbr1, mbr2)); + public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { + return new VectorFieldTypeInformation<>(NumberVector.class, 2); } @Override - public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { - return new VectorFieldTypeInformation<NumberVector<?>>(NumberVector.class, 2); + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((model == null) ? 0 : model.hashCode()); + return result; } @Override public boolean equals(Object obj) { + if (this == obj) { + return true; + } if (obj == null) { return false; } - if (obj == this) { - return true; + if (getClass() != obj.getClass()) { + return false; } - if (this.getClass().equals(obj.getClass())) { - return true; + LngLatDistanceFunction other = (LngLatDistanceFunction) obj; + if (model == null) { + if (other.model != null) { + return false; + } + } else if (!model.equals(other.model)) { + return false; } - return super.equals(obj); + return true; } @Override - public <T extends NumberVector<?>> SpatialPrimitiveDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) { - return new SpatialPrimitiveDistanceQuery<T, DoubleDistance>(relation, this); + public String toString() { + return "LngLatDistanceFunction [model=" + model + "]"; } - + /** * Parameterization class. * @@ -115,9 +128,23 @@ public class LngLatDistanceFunction extends AbstractVectorDoubleDistanceFunction * @apiviz.exclude */ public static class Parameterizer extends AbstractParameterizer { + /** + * Earth model used. + */ + EarthModel model; + + @Override + protected void makeOptions(Parameterization config) { + super.makeOptions(config); + ObjectParameter<EarthModel> modelP = new ObjectParameter<>(EarthModel.MODEL_ID, EarthModel.class, SphericalVincentyEarthModel.class); + if (config.grab(modelP)) { + model = modelP.instantiateClass(config); + } + } + @Override protected LngLatDistanceFunction makeInstance() { - return LngLatDistanceFunction.STATIC; + return new LngLatDistanceFunction(model); } } } diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/package-info.java index 913447fd..4c05cc5a 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/JeffreyDivergenceDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/HistogramMatchDistanceFunction.java index 1ac5f2a4..947c50fe 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/JeffreyDivergenceDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/HistogramMatchDistanceFunction.java @@ -1,4 +1,4 @@ -package de.lmu.ifi.dbs.elki.distance.distancefunction; +package de.lmu.ifi.dbs.elki.distance.distancefunction.histogram; /* This file is part of ELKI: @@ -24,50 +24,49 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; */ import de.lmu.ifi.dbs.elki.data.NumberVector; -import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** - * Provides the Jeffrey Divergence Distance for FeatureVectors. + * Distance function based on histogram matching, i.e. Manhattan distance on the + * cumulative density function. + * + * This distance function assumes there exist a natural order in the vectors, + * i.e. they should be some 1-dimensional histogram. * * @author Erich Schubert */ -@Reference(authors="J. Puzicha, J.M. Buhmann, Y. Rubner, C. Tomasi", title="Empirical evaluation of dissimilarity measures for color and texture", booktitle="Proc. 7th IEEE International Conference on Computer Vision", url="http://dx.doi.org/10.1109/ICCV.1999.790412") -public class JeffreyDivergenceDistanceFunction extends AbstractVectorDoubleDistanceFunction { +public class HistogramMatchDistanceFunction extends AbstractVectorDoubleDistanceFunction { /** * Static instance. Use this! */ - public static final JeffreyDivergenceDistanceFunction STATIC = new JeffreyDivergenceDistanceFunction(); + public static final HistogramMatchDistanceFunction STATIC = new HistogramMatchDistanceFunction(); /** - * Constructor for the Jeffrey divergence. + * Constructor for the Histogram match distance function. * * @deprecated Use static instance! */ @Deprecated - public JeffreyDivergenceDistanceFunction() { + public HistogramMatchDistanceFunction() { + super(); } @Override public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { - final int dim1 = v1.getDimensionality(); - if(dim1 != v2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of FeatureVectors" + "\n first argument: " + v1.toString() + "\n second argument: " + v2.toString() + "\n" + v1.getDimensionality() + "!=" + v2.getDimensionality()); - } - double dist = 0; - for(int i = 0; i < dim1; i++) { - final double xi = v1.doubleValue(i); - final double yi = v2.doubleValue(i); - final double mi = .5 * (xi + yi); - dist += xi * Math.log(xi / mi); - dist += yi * Math.log(yi / mi); + final int dim = dimensionality(v1, v2); + double xs = 0., ys = 0., agg = 0.; + for(int i = 0; i < dim; i++) { + xs += v1.doubleValue(i); + ys += v2.doubleValue(i); + agg += Math.abs(xs - ys); } - return dist; + return agg; } @Override public String toString() { - return "JeffreyDivergenceDistance"; + return "HistogramMatchDistanceFunction"; } @Override @@ -93,8 +92,8 @@ public class JeffreyDivergenceDistanceFunction extends AbstractVectorDoubleDista */ public static class Parameterizer extends AbstractParameterizer { @Override - protected JeffreyDivergenceDistanceFunction makeInstance() { - return JeffreyDivergenceDistanceFunction.STATIC; + protected HistogramMatchDistanceFunction makeInstance() { + return STATIC; } } } diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/KolmogorovSmirnovDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/KolmogorovSmirnovDistanceFunction.java new file mode 100644 index 00000000..fa2fff76 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/KolmogorovSmirnovDistanceFunction.java @@ -0,0 +1,101 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction.histogram; + +/* + 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 de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Distance function based on the Kolmogorov-Smirnov goodness of fit test. + * + * This distance function assumes there exist a natural order in the vectors, + * i.e. they should be some 1-dimensional histogram. + * + * @author Erich Schubert + */ +public class KolmogorovSmirnovDistanceFunction extends AbstractVectorDoubleDistanceFunction { + /** + * Static instance. Use this! + */ + public static final KolmogorovSmirnovDistanceFunction STATIC = new KolmogorovSmirnovDistanceFunction(); + + /** + * Constructor for the Kolmogorov-Smirnov distance function. + * + * @deprecated Use static instance! + */ + @Deprecated + public KolmogorovSmirnovDistanceFunction() { + super(); + } + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2); + double xs = 0., ys = 0., agg = 0.; + for (int i = 0; i < dim; i++) { + xs += v1.doubleValue(i); + ys += v2.doubleValue(i); + double diff = Math.abs(xs - ys); + if (diff > agg) { + agg = diff; + } + } + return agg; + } + + @Override + public String toString() { + return "KolmogorovSmirnovDistanceFunction"; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (this.getClass().equals(obj.getClass())) { + return true; + } + return super.equals(obj); + } + + /** + * Parameterization class, using the static instance. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected KolmogorovSmirnovDistanceFunction makeInstance() { + return STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/package-info.java new file mode 100644 index 00000000..e6a9a8be --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/package-info.java @@ -0,0 +1,4 @@ +/** + * Distance functions for <b>one-dimensional</b> histograms. + */ +package de.lmu.ifi.dbs.elki.distance.distancefunction.histogram;
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/EuclideanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/EuclideanDistanceFunction.java new file mode 100644 index 00000000..03116430 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/EuclideanDistanceFunction.java @@ -0,0 +1,167 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2013 + 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.spatial.SpatialComparable; +import de.lmu.ifi.dbs.elki.utilities.Alias; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Provides the Euclidean distance for FeatureVectors. + * + * @author Arthur Zimek + */ +@Alias({ "euclidean", "euclid", "l2", "EuclideanDistanceFunction", "de.lmu.ifi.dbs.elki.distance.distancefunction.EuclideanDistanceFunction" }) +public class EuclideanDistanceFunction extends LPNormDistanceFunction { + /** + * Static instance. Use this! + */ + public static final EuclideanDistanceFunction STATIC = new EuclideanDistanceFunction(); + + /** + * Provides a Euclidean distance function that can compute the Euclidean + * distance (that is a DoubleDistance) for FeatureVectors. + * + * @deprecated Use static instance! + */ + @Deprecated + public EuclideanDistanceFunction() { + super(2.); + } + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double delta = v1.doubleValue(d) - v2.doubleValue(d); + agg += delta * delta; + } + return Math.sqrt(agg); + } + + @Override + public double doubleNorm(NumberVector<?> v) { + final int dim = v.getDimensionality(); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double val = v.doubleValue(d); + agg += val * val; + } + return Math.sqrt(agg); + } + + protected double doubleMinDistObject(NumberVector<?> v, SpatialComparable mbr) { + final int dim = dimensionality(mbr, v); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double value = v.doubleValue(d), min = mbr.getMin(d); + final double diff; + if (value < min) { + diff = min - value; + } else { + final double max = mbr.getMax(d); + if (value > max) { + diff = value - max; + } else { + continue; + } + } + agg += diff * diff; + } + return Math.sqrt(agg); + } + + @Override + public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + // Some optimizations for simpler cases. + if (mbr1 instanceof NumberVector) { + if (mbr2 instanceof NumberVector) { + return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); + } else { + return doubleMinDistObject((NumberVector<?>) mbr1, mbr2); + } + } else if (mbr2 instanceof NumberVector) { + return doubleMinDistObject((NumberVector<?>) mbr2, mbr1); + } + final int dim = dimensionality(mbr1, mbr2); + + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double diff; + final double d1 = mbr2.getMin(d) - mbr1.getMax(d); + if (d1 > 0.) { + diff = d1; + } else { + final double d2 = mbr1.getMin(d) - mbr2.getMax(d); + if (d2 > 0.) { + diff = d2; + } else { + continue; + } + } + agg += diff * diff; + } + return Math.sqrt(agg); + } + + @Override + public boolean isMetric() { + return true; + } + + @Override + public String toString() { + return "EuclideanDistance"; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (this.getClass().equals(obj.getClass())) { + return true; + } + return super.equals(obj); + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected EuclideanDistanceFunction makeInstance() { + return EuclideanDistanceFunction.STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LPNormDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/LPNormDistanceFunction.java index 98b9929a..c25e04f1 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LPNormDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/LPNormDistanceFunction.java @@ -1,10 +1,10 @@ -package de.lmu.ifi.dbs.elki.distance.distancefunction; +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,9 +25,8 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDoubleDistanceNorm; +import de.lmu.ifi.dbs.elki.utilities.Alias; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterConstraint; @@ -41,16 +40,17 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; * * @apiviz.landmark */ -public class LPNormDistanceFunction extends AbstractVectorDoubleDistanceNorm implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { +@Alias({ "lp", "minkowski", "p", "de.lmu.ifi.dbs.elki.distance.distancefunction.LPNormDistanceFunction" }) +public class LPNormDistanceFunction extends AbstractSpatialDoubleDistanceNorm { /** * OptionID for the "p" parameter */ public static final OptionID P_ID = new OptionID("lpnorm.p", "the degree of the L-P-Norm (positive number)"); /** - * Keeps the currently set p. + * Keeps the currently set p and its inverse */ - private double p; + protected double p, invp; /** * Constructor, internal version. @@ -60,89 +60,60 @@ public class LPNormDistanceFunction extends AbstractVectorDoubleDistanceNorm imp public LPNormDistanceFunction(double p) { super(); this.p = p; + this.invp = 1. / p; } - /** - * Returns the distance between the specified FeatureVectors as a LP-Norm for - * the currently set p. - * - * @param v1 first FeatureVector - * @param v2 second FeatureVector - * @return the distance between the specified FeatureVectors as a LP-Norm for - * the currently set p - */ @Override public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { - final int dim1 = v1.getDimensionality(); - if(dim1 != v2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of FeatureVectors\n first argument: " + v1.toString() + "\n second argument: " + v2.toString()); - } - - double sqrDist = 0; - for(int i = 0; i < dim1; i++) { - final double delta = Math.abs(v1.doubleValue(i) - v2.doubleValue(i)); - sqrDist += Math.pow(delta, p); + final int dim = dimensionality(v1, v2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + final double delta = (xd >= yd) ? xd - yd : yd - xd; + agg += Math.pow(delta, p); } - return Math.pow(sqrDist, 1.0 / p); + return Math.pow(agg, invp); } @Override public double doubleNorm(NumberVector<?> v) { final int dim = v.getDimensionality(); - double sqrDist = 0; - for(int i = 0; i < dim; i++) { - final double delta = v.doubleValue(i); - sqrDist += Math.pow(delta, p); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v.doubleValue(d); + agg += Math.pow(xd >= 0. ? xd : -xd, p); } - return Math.pow(sqrDist, 1.0 / p); - } - - /** - * Get the functions p parameter. - * - * @return p - */ - public double getP() { - return p; + return Math.pow(agg, invp); } @Override public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { // Optimization for the simplest case - if(mbr1 instanceof NumberVector) { - if(mbr2 instanceof NumberVector) { + if (mbr1 instanceof NumberVector) { + if (mbr2 instanceof NumberVector) { return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); } } // TODO: optimize for more simpler cases: obj vs. rect? - final int dim1 = mbr1.getDimensionality(); - if(dim1 != mbr2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr1.toString() + "\n " + "second argument: " + mbr2.toString()); - } - - double sumDist = 0; - for(int d = 0; d < dim1; d++) { - final double m1, m2; - if(mbr1.getMax(d) < mbr2.getMin(d)) { - m1 = mbr2.getMin(d); - m2 = mbr1.getMax(d); - } - else if(mbr1.getMin(d) > mbr2.getMax(d)) { - m1 = mbr1.getMin(d); - m2 = mbr2.getMax(d); + final int dim = dimensionality(mbr1, mbr2); + + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double diff; + final double d1 = mbr2.getMin(d) - mbr1.getMax(d); + if (d1 > 0.) { + diff = d1; + } else { + final double d2 = mbr1.getMin(d) - mbr2.getMax(d); + if (d2 > 0.) { + diff = d2; + } else { // The mbrs intersect! + continue; + } } - else { // The mbrs intersect! - continue; - } - final double manhattanI = m1 - m2; - sumDist += Math.pow(manhattanI, p); + agg += Math.pow(diff, p); } - return Math.pow(sumDist, 1.0 / p); - } - - @Override - public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) { - return new DoubleDistance(doubleMinDist(mbr1, mbr2)); + return Math.pow(agg, invp); } @Override @@ -152,25 +123,29 @@ public class LPNormDistanceFunction extends AbstractVectorDoubleDistanceNorm imp @Override public String toString() { - return "L_" + p + " Norm"; + return "L_" + p + "Norm"; + } + + /** + * Get the functions p parameter. + * + * @return p + */ + public double getP() { + return p; } @Override public boolean equals(Object obj) { - if(obj == null) { + if (obj == null) { return false; } - if(obj instanceof LPNormDistanceFunction) { + if (obj instanceof LPNormDistanceFunction) { return this.p == ((LPNormDistanceFunction) obj).p; } return false; } - @Override - public <T extends NumberVector<?>> SpatialPrimitiveDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) { - return new SpatialPrimitiveDistanceQuery<T, DoubleDistance>(relation, this); - } - /** * Parameterization class. * @@ -182,30 +157,30 @@ public class LPNormDistanceFunction extends AbstractVectorDoubleDistanceNorm imp /** * The value of p. */ - protected double p = 0.0; + protected double p; @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); final DoubleParameter paramP = new DoubleParameter(P_ID); - paramP.addConstraint(new GreaterConstraint(0)); - if(config.grab(paramP)) { + paramP.addConstraint(new GreaterConstraint(0.)); + if (config.grab(paramP)) { p = paramP.getValue(); } } @Override protected LPNormDistanceFunction makeInstance() { - if(p == 1.0) { + if (p == 1.0) { return ManhattanDistanceFunction.STATIC; } - if(p == 2.0) { + if (p == 2.0) { return EuclideanDistanceFunction.STATIC; } - if(p == Double.POSITIVE_INFINITY) { + if (p == Double.POSITIVE_INFINITY) { return MaximumDistanceFunction.STATIC; } return new LPNormDistanceFunction(p); } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ManhattanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/ManhattanDistanceFunction.java index a97ef086..9b8f80a7 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ManhattanDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/ManhattanDistanceFunction.java @@ -1,10 +1,10 @@ -package de.lmu.ifi.dbs.elki.distance.distancefunction; +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 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.distance.distancefunction; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; +import de.lmu.ifi.dbs.elki.utilities.Alias; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** @@ -33,8 +34,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; * * @author Arthur Zimek */ -// TODO: add spatial! -public class ManhattanDistanceFunction extends LPNormDistanceFunction implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { +@Alias({ "taxicab", "cityblock", "l1", "ManhattanDistanceFunction", "de.lmu.ifi.dbs.elki.distance.distancefunction.ManhattanDistanceFunction" }) +public class ManhattanDistanceFunction extends LPNormDistanceFunction { /** * The static instance to use. */ @@ -48,67 +49,47 @@ public class ManhattanDistanceFunction extends LPNormDistanceFunction implements */ @Deprecated public ManhattanDistanceFunction() { - super(1.0); + super(1.); } - /** - * Compute the Manhattan distance. - * - * @param v1 first vector - * @param v2 second vector - * @return Manhattan distance value - */ @Override public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { - final int dim = v1.getDimensionality(); - if (dim != v2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of FeatureVectors" + "\n first argument: " + v1.toString() + "\n second argument: " + v2.toString()); - } - double sum = 0; - for (int i = 0; i < dim; i++) { - sum += Math.abs(v1.doubleValue(i) - v2.doubleValue(i)); + final int dim = dimensionality(v1, v2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + final double val = (xd >= yd) ? xd - yd : yd - xd; + agg += val; } - return sum; + return agg; } - /** - * Returns the Manhattan norm of the given vector. - * - * @param v the vector to compute the norm of - * @return the Manhattan norm of the given vector - */ @Override public double doubleNorm(NumberVector<?> v) { final int dim = v.getDimensionality(); - double sum = 0; - for (int i = 0; i < dim; i++) { - sum += Math.abs(v.doubleValue(i)); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v.doubleValue(d); + agg += (xd >= 0.) ? xd : -xd; } - return sum; + return agg; } - private double doubleMinDistObject(SpatialComparable mbr, NumberVector<?> v) { - final int dim = mbr.getDimensionality(); - if (dim != v.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr.toString() + "\n " + "second argument: " + v.toString() + "\n" + dim + "!=" + v.getDimensionality()); - } - - double sumDist = 0; + protected double doubleMinDistObject(NumberVector<?> v, SpatialComparable mbr) { + final int dim = dimensionality(mbr, v); + double agg = 0.; for (int d = 0; d < dim; d++) { - final double value = v.doubleValue(d); - final double r; - if (value < mbr.getMin(d)) { - r = mbr.getMin(d); - } else if (value > mbr.getMax(d)) { - r = mbr.getMax(d); + final double value = v.doubleValue(d), min = mbr.getMin(d); + if (value < min) { + agg += min - value; } else { - r = value; + final double max = mbr.getMax(d); + if (value > max) { + agg += value - max; + } } - - final double manhattanI = Math.abs(value - r); - sumDist += manhattanI; } - return sumDist; + return agg; } @Override @@ -118,32 +99,26 @@ public class ManhattanDistanceFunction extends LPNormDistanceFunction implements if (mbr2 instanceof NumberVector) { return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); } else { - return doubleMinDistObject(mbr2, (NumberVector<?>) mbr1); + return doubleMinDistObject((NumberVector<?>) mbr1, mbr2); } } else if (mbr2 instanceof NumberVector) { - return doubleMinDistObject(mbr1, (NumberVector<?>) mbr2); - } - final int dim1 = mbr1.getDimensionality(); - if (dim1 != mbr2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr1.toString() + "\n " + "second argument: " + mbr2.toString()); + return doubleMinDistObject((NumberVector<?>) mbr2, mbr1); } + final int dim = dimensionality(mbr1, mbr2); - double sumDist = 0; - for (int d = 0; d < dim1; d++) { - final double m1, m2; - if (mbr1.getMax(d) < mbr2.getMin(d)) { - m1 = mbr2.getMin(d); - m2 = mbr1.getMax(d); - } else if (mbr1.getMin(d) > mbr2.getMax(d)) { - m1 = mbr1.getMin(d); - m2 = mbr2.getMax(d); - } else { // The mbrs intersect! - continue; + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double d1 = mbr2.getMin(d) - mbr1.getMax(d); + if (d1 > 0.) { + agg += d1; + } else { + final double d2 = mbr1.getMin(d) - mbr2.getMax(d); + if (d2 > 0.) { + agg += d2; + } } - final double manhattanI = m1 - m2; - sumDist += manhattanI; } - return sumDist; + return agg; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MaximumDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/MaximumDistanceFunction.java index 30b47c9d..1b54e278 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MaximumDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/MaximumDistanceFunction.java @@ -1,10 +1,10 @@ -package de.lmu.ifi.dbs.elki.distance.distancefunction; +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 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.distance.distancefunction; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; +import de.lmu.ifi.dbs.elki.utilities.Alias; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** @@ -33,7 +34,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; * * @author Erich Schubert */ -public class MaximumDistanceFunction extends LPNormDistanceFunction implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { +@Alias({ "maximum", "max", "chebyshev", "de.lmu.ifi.dbs.elki.distance.distancefunction.MaximumDistanceFunction" }) +public class MaximumDistanceFunction extends LPNormDistanceFunction { /** * Static instance. */ @@ -52,50 +54,62 @@ public class MaximumDistanceFunction extends LPNormDistanceFunction implements S @Override public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { - final int dim1 = v1.getDimensionality(); - if(dim1 != v2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of FeatureVectors" + "\n first argument: " + v1.toString() + "\n second argument: " + v2.toString()); - } - double max = 0; - for(int i = 0; i < dim1; i++) { - final double d = Math.abs(v1.doubleValue(i) - v2.doubleValue(i)); - max = Math.max(d, max); + final int dim = dimensionality(v1, v2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + final double val = (xd >= yd) ? xd - yd : yd - xd; + if (val > agg) { + agg = val; + } } - return max; + return agg; } @Override public double doubleNorm(NumberVector<?> v) { final int dim = v.getDimensionality(); - double max = 0; - for(int i = 0; i < dim; i++) { - max = Math.max(v.doubleValue(i), max); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v.doubleValue(d); + final double val = (xd >= 0.) ? xd : -xd; + if (val > agg) { + agg = val; + } } - return max; + return agg; } @Override public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { - final int dim1 = mbr1.getDimensionality(); - if(dim1 != mbr2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of objects."); - } - double max = 0; - for(int i = 0; i < dim1; i++) { - final double d; - if(mbr1.getMax(i) < mbr2.getMin(i)) { - d = mbr2.getMin(i) - mbr1.getMin(i); + // Some optimizations for simpler cases. + if (mbr1 instanceof NumberVector) { + if (mbr2 instanceof NumberVector) { + return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); } - else if(mbr1.getMin(i) > mbr2.getMax(i)) { - d = mbr1.getMin(i) - mbr2.getMax(i); + } + // TODO: add optimization for point to MBR? + final int dim = dimensionality(mbr1, mbr2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double diff; + final double d1 = mbr2.getMin(d) - mbr1.getMax(d); + if (d1 > 0.) { + diff = d1; + } else { + final double d2 = mbr1.getMin(d) - mbr2.getMax(d); + if (d2 > 0.) { + diff = d2; + } else { + // The objects overlap in this dimension. + continue; + } } - else { - // The object overlap in this dimension. - continue; + if (diff > agg) { + agg = diff; } - max = Math.max(d, max); } - return max; + return agg; } @Override @@ -110,13 +124,13 @@ public class MaximumDistanceFunction extends LPNormDistanceFunction implements S @Override public boolean equals(Object obj) { - if(obj == null) { + if (obj == null) { return false; } - if(obj == this) { + if (obj == this) { return true; } - if(this.getClass().equals(obj.getClass())) { + if (this.getClass().equals(obj.getClass())) { return true; } return super.equals(obj); @@ -135,4 +149,4 @@ public class MaximumDistanceFunction extends LPNormDistanceFunction implements S return MaximumDistanceFunction.STATIC; } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinimumDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/MinimumDistanceFunction.java index a336c126..552e3139 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinimumDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/MinimumDistanceFunction.java @@ -1,10 +1,10 @@ -package de.lmu.ifi.dbs.elki.distance.distancefunction; +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,9 +25,8 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDoubleDistanceNorm; +import de.lmu.ifi.dbs.elki.utilities.Alias; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** @@ -36,8 +35,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; * * @author Erich Schubert */ -// TODO: add spatial? -public class MinimumDistanceFunction extends AbstractVectorDoubleDistanceNorm implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { +@Alias({ "minimum", "min", "de.lmu.ifi.dbs.elki.distance.distancefunction.MinimumDistanceFunction" }) +public class MinimumDistanceFunction extends AbstractSpatialDoubleDistanceNorm { /** * Static instance. Use this. */ @@ -56,60 +55,67 @@ public class MinimumDistanceFunction extends AbstractVectorDoubleDistanceNorm im @Override public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { - final int dim = v1.getDimensionality(); - if(dim != v2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of FeatureVectors" + "\n first argument: " + v1.toString() + "\n second argument: " + v2.toString()); - } - double min = Double.MAX_VALUE; - for(int i = 0; i < dim; i++) { - final double d = Math.abs(v1.doubleValue(i) - v2.doubleValue(i)); - min = Math.min(d, min); + final int dim = dimensionality(v1, v2); + double agg = Double.POSITIVE_INFINITY; + for (int d = 0; d < dim; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + final double val = (xd >= yd) ? xd - yd : yd - xd; + if (val < agg) { + agg = val; + } } - return min; + return agg; } @Override public double doubleNorm(NumberVector<?> v) { final int dim = v.getDimensionality(); - double min = Double.POSITIVE_INFINITY; - for(int i = 0; i < dim; i++) { - min = Math.min(v.doubleValue(i), min); + double agg = Double.POSITIVE_INFINITY; + for (int d = 0; d < dim; d++) { + final double xd = v.doubleValue(d); + final double val = (xd >= 0.) ? xd : -xd; + if (val < agg) { + agg = val; + } } - return min; + return agg; } - + @Override public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { - final int dim = mbr1.getDimensionality(); - if(dim != mbr2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of FeatureVectors" + "\n first argument: " + mbr1.toString() + "\n second argument: " + mbr2.toString()); - } - double min = Double.MAX_VALUE; - for(int i = 0; i < dim; i++) { - final double min1 = mbr1.getMin(i); - final double max1 = mbr1.getMax(i); - final double min2 = mbr2.getMin(i); - final double max2 = mbr2.getMax(i); - final double d; - if(max1 <= min2) { - d = min2 - max1; + // Some optimizations for simpler cases. + if (mbr1 instanceof NumberVector) { + if (mbr2 instanceof NumberVector) { + return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); } - else if(max2 <= min1) { - d = min1 - max2; + } + // TODO: add optimization for point to MBR? + final int dim = dimensionality(mbr1, mbr2); + double agg = Double.POSITIVE_INFINITY; + for (int d = 0; d < dim; d++) { + final double diff; + final double d1 = mbr2.getMin(d) - mbr1.getMax(d); + if (d1 > 0.) { + diff = d1; + } else { + final double d2 = mbr1.getMin(d) - mbr2.getMax(d); + if (d2 > 0.) { + diff = d2; + } else { + // The objects overlap in this dimension. + return 0.; + } } - else { - // Overlap in this dimension - min = 0.0; - break; + if (diff < agg) { + agg = diff; } - min = Math.min(d, min); } - return min; + return agg; } @Override - public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) { - return new DoubleDistance(doubleMinDist(mbr1, mbr2)); + public boolean isMetric() { + return false; } @Override @@ -118,19 +124,17 @@ public class MinimumDistanceFunction extends AbstractVectorDoubleDistanceNorm im } @Override - public <T extends NumberVector<?>> SpatialPrimitiveDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) { - return new SpatialPrimitiveDistanceQuery<T, DoubleDistance>(relation, this); - } - - @Override public boolean equals(Object obj) { - if(obj == null) { + if (obj == null) { return false; } - if(obj == this) { + if (obj == this) { + return true; + } + if (this.getClass().equals(obj.getClass())) { return true; } - return this.getClass().equals(obj.getClass()); + return super.equals(obj); } /** @@ -146,4 +150,4 @@ public class MinimumDistanceFunction extends AbstractVectorDoubleDistanceNorm im return MinimumDistanceFunction.STATIC; } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SparseEuclideanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseEuclideanDistanceFunction.java index 8d68eb1d..bf621103 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SparseEuclideanDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseEuclideanDistanceFunction.java @@ -1,9 +1,10 @@ -package de.lmu.ifi.dbs.elki.distance.distancefunction; +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; + /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -37,7 +38,7 @@ public class SparseEuclideanDistanceFunction extends SparseLPNormDistanceFunctio * Static instance */ public static final SparseEuclideanDistanceFunction STATIC = new SparseEuclideanDistanceFunction(); - + /** * Constructor. * @@ -53,44 +54,45 @@ public class SparseEuclideanDistanceFunction extends SparseLPNormDistanceFunctio // Get the bit masks BitSet b1 = v1.getNotNullMask(); BitSet b2 = v2.getNotNullMask(); - double sqrDist = 0; + double accu = 0; int i1 = b1.nextSetBit(0); int i2 = b2.nextSetBit(0); - while(i1 >= 0 && i2 >= 0) { - if(i1 == i2) { - // Set in both - double manhattanI = v1.doubleValue(i1) - v2.doubleValue(i2); - sqrDist += manhattanI * manhattanI; + while (true) { + if (i1 == i2) { + if (i1 < 0) { + break; + } + // Both vectors have a value. + double val = v1.doubleValue(i1) - v2.doubleValue(i2); + accu += val * val; i1 = b1.nextSetBit(i1 + 1); i2 = b2.nextSetBit(i2 + 1); - } - else if(i1 < i2 && i1 >= 0) { + } else if (i2 < 0 || (i1 < i2 && i1 >= 0)) { // In first only - double manhattanI = v1.doubleValue(i1); - sqrDist += manhattanI * manhattanI; + double val = v1.doubleValue(i1); + accu += val * val; i1 = b1.nextSetBit(i1 + 1); - } - else { + } else { // In second only - double manhattanI = v2.doubleValue(i2); - sqrDist += manhattanI * manhattanI; - i2 = b1.nextSetBit(i2 + 1); + double val = v2.doubleValue(i2); + accu += val * val; + i2 = b2.nextSetBit(i2 + 1); } } - return Math.sqrt(sqrDist); + return Math.sqrt(accu); } @Override public double doubleNorm(SparseNumberVector<?> v1) { - double sqrDist = 0; + double accu = 0; // Get the bit masks BitSet b1 = v1.getNotNullMask(); // Set in first only - for(int i = b1.nextSetBit(0); i >= 0; i = b1.nextSetBit(i + 1)) { - double manhattanI = v1.doubleValue(i); - sqrDist += manhattanI * manhattanI; + for (int i = b1.nextSetBit(0); i >= 0; i = b1.nextSetBit(i + 1)) { + double val = v1.doubleValue(i); + accu += val * val; } - return Math.sqrt(sqrDist); + return Math.sqrt(accu); } /** @@ -106,4 +108,4 @@ public class SparseEuclideanDistanceFunction extends SparseLPNormDistanceFunctio return SparseEuclideanDistanceFunction.STATIC; } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SparseLPNormDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseLPNormDistanceFunction.java index b0cbc0dc..53d63ff8 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SparseLPNormDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseLPNormDistanceFunction.java @@ -1,10 +1,10 @@ -package de.lmu.ifi.dbs.elki.distance.distancefunction; +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -28,6 +28,8 @@ import java.util.BitSet; import de.lmu.ifi.dbs.elki.data.SparseNumberVector; import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; import de.lmu.ifi.dbs.elki.data.type.TypeUtil; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractPrimitiveDistanceFunction; +import de.lmu.ifi.dbs.elki.distance.distancefunction.DoubleNorm; import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterConstraint; @@ -58,31 +60,32 @@ public class SparseLPNormDistanceFunction extends AbstractPrimitiveDistanceFunct // Get the bit masks BitSet b1 = v1.getNotNullMask(); BitSet b2 = v2.getNotNullMask(); - double sqrDist = 0; + double accu = 0; int i1 = b1.nextSetBit(0); int i2 = b2.nextSetBit(0); - while(i1 >= 0 && i2 >= 0) { - if(i1 == i2) { - // Set in both - double manhattanI = Math.abs(v1.doubleValue(i1) - v2.doubleValue(i2)); - sqrDist += Math.pow(manhattanI, p); + while (true) { + if (i1 == i2) { + if (i1 < 0) { + break; + } + // Both vectors have a value. + double val = Math.abs(v1.doubleValue(i1) - v2.doubleValue(i2)); + accu += Math.pow(val, p); i1 = b1.nextSetBit(i1 + 1); i2 = b2.nextSetBit(i2 + 1); - } - else if(i1 < i2 && i1 >= 0) { + } else if (i2 < 0 || (i1 < i2 && i1 >= 0)) { // In first only - double manhattanI = Math.abs(v1.doubleValue(i1)); - sqrDist += Math.pow(manhattanI, p); + double val = Math.abs(v1.doubleValue(i1)); + accu += Math.pow(val, p); i1 = b1.nextSetBit(i1 + 1); - } - else { + } else { // In second only - double manhattanI = Math.abs(v2.doubleValue(i2)); - sqrDist += Math.pow(manhattanI, p); - i2 = b1.nextSetBit(i2 + 1); + double val = Math.abs(v2.doubleValue(i2)); + accu += Math.pow(val, p); + i2 = b2.nextSetBit(i2 + 1); } } - return Math.pow(sqrDist, 1.0 / p); + return Math.pow(accu, 1.0 / p); } @Override diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SparseManhattanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseManhattanDistanceFunction.java index 597dd6ca..4e397e0c 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SparseManhattanDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseManhattanDistanceFunction.java @@ -1,9 +1,9 @@ -package de.lmu.ifi.dbs.elki.distance.distancefunction; +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -53,29 +53,32 @@ public class SparseManhattanDistanceFunction extends SparseLPNormDistanceFunctio // Get the bit masks BitSet b1 = v1.getNotNullMask(); BitSet b2 = v2.getNotNullMask(); - double sqrDist = 0; + double accu = 0; int i1 = b1.nextSetBit(0); int i2 = b2.nextSetBit(0); - while(i1 >= 0 && i2 >= 0) { - if(i1 == i2) { - // Set in both - sqrDist += Math.abs(v1.doubleValue(i1) - v2.doubleValue(i2)); + while (true) { + if (i1 == i2) { + if (i1 < 0) { + break; + } + // Both vectors have a value. + double val = Math.abs(v1.doubleValue(i1) - v2.doubleValue(i2)); + accu += val; i1 = b1.nextSetBit(i1 + 1); i2 = b2.nextSetBit(i2 + 1); - } - else if(i1 < i2 && i1 >= 0) { + } else if (i2 < 0 || (i1 < i2 && i1 >= 0)) { // In first only - sqrDist += Math.abs(v1.doubleValue(i1)); + double val = Math.abs(v1.doubleValue(i1)); + accu += val; i1 = b1.nextSetBit(i1 + 1); - } - else { + } else { // In second only - double manhattanI = Math.abs(v2.doubleValue(i2)); - sqrDist += manhattanI; - i2 = b1.nextSetBit(i2 + 1); + double val = Math.abs(v2.doubleValue(i2)); + accu += val; + i2 = b2.nextSetBit(i2 + 1); } } - return sqrDist; + return accu; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SparseMaximumDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseMaximumDistanceFunction.java index 720b8017..f01ae32b 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SparseMaximumDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseMaximumDistanceFunction.java @@ -1,4 +1,4 @@ -package de.lmu.ifi.dbs.elki.distance.distancefunction; +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; import java.util.BitSet; @@ -8,7 +8,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -53,29 +53,32 @@ public class SparseMaximumDistanceFunction extends SparseLPNormDistanceFunction // Get the bit masks BitSet b1 = v1.getNotNullMask(); BitSet b2 = v2.getNotNullMask(); - double sqrDist = 0; + double accu = 0; int i1 = b1.nextSetBit(0); int i2 = b2.nextSetBit(0); - while(i1 >= 0 && i2 >= 0) { - if(i1 == i2) { - // Set in both - sqrDist = Math.max(sqrDist, Math.abs(v1.doubleValue(i1) - v2.doubleValue(i2))); + while (true) { + if (i1 == i2) { + if (i1 < 0) { + break; + } + // Both vectors have a value. + double val = Math.abs(v1.doubleValue(i1) - v2.doubleValue(i2)); + accu = Math.max(accu, val); i1 = b1.nextSetBit(i1 + 1); i2 = b2.nextSetBit(i2 + 1); - } - else if(i1 < i2 && i1 >= 0) { + } else if (i2 < 0 || (i1 < i2 && i1 >= 0)) { // In first only - sqrDist = Math.max(sqrDist, Math.abs(v1.doubleValue(i1))); + double val = Math.abs(v1.doubleValue(i1)); + accu = Math.max(accu, val); i1 = b1.nextSetBit(i1 + 1); - } - else { + } else { // In second only - double manhattanI = Math.abs(v2.doubleValue(i2)); - sqrDist = Math.max(sqrDist, manhattanI); - i2 = b1.nextSetBit(i2 + 1); + double val = Math.abs(v2.doubleValue(i2)); + accu = Math.max(accu, val); + i2 = b2.nextSetBit(i2 + 1); } } - return sqrDist; + return accu; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SquaredEuclideanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SquaredEuclideanDistanceFunction.java new file mode 100644 index 00000000..8f02e40b --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SquaredEuclideanDistanceFunction.java @@ -0,0 +1,166 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2013 + 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.spatial.SpatialComparable; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDoubleDistanceNorm; +import de.lmu.ifi.dbs.elki.utilities.Alias; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Provides the squared Euclidean distance for FeatureVectors. This results in + * the same rankings, but saves computing the square root as often. + * + * @author Arthur Zimek + */ +@Alias({ "squaredeuclidean", "de.lmu.ifi.dbs.elki.distance.distancefunction.SquaredEuclideanDistanceFunction" }) +public class SquaredEuclideanDistanceFunction extends AbstractSpatialDoubleDistanceNorm { + /** + * Static instance. Use this! + */ + public static final SquaredEuclideanDistanceFunction STATIC = new SquaredEuclideanDistanceFunction(); + + /** + * Provides a Euclidean distance function that can compute the Euclidean + * distance (that is a DoubleDistance) for FeatureVectors. + * + * @deprecated Use static instance! + */ + @Deprecated + public SquaredEuclideanDistanceFunction() { + super(); + } + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double delta = v1.doubleValue(d) - v2.doubleValue(d); + agg += delta * delta; + } + return agg; + } + + @Override + public double doubleNorm(NumberVector<?> v) { + final int dim = v.getDimensionality(); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double val = v.doubleValue(d); + agg += val * val; + } + return agg; + } + + protected double doubleMinDistObject(NumberVector<?> v, SpatialComparable mbr) { + final int dim = dimensionality(mbr, v); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double value = v.doubleValue(d), min = mbr.getMin(d); + final double diff; + if (value < min) { + diff = min - value; + } else { + final double max = mbr.getMax(d); + if (value > max) { + diff = value - max; + } else { + continue; + } + } + agg += diff * diff; + } + return agg; + } + + @Override + public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + // Some optimizations for simpler cases. + if (mbr1 instanceof NumberVector) { + if (mbr2 instanceof NumberVector) { + return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); + } else { + return doubleMinDistObject((NumberVector<?>) mbr1, mbr2); + } + } else if (mbr2 instanceof NumberVector) { + return doubleMinDistObject((NumberVector<?>) mbr2, mbr1); + } + final int dim = dimensionality(mbr1, mbr2); + + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double diff; + final double d1 = mbr2.getMin(d) - mbr1.getMax(d); + if (d1 > 0.) { + diff = d1; + } else { + final double d2 = mbr1.getMin(d) - mbr2.getMax(d); + if (d2 > 0.) { + diff = d2; + } else { + continue; + } + } + agg += diff * diff; + } + return agg; + } + + @Override + public boolean isMetric() { + return false; + } + + @Override + public String toString() { + return "SquaredEuclideanDistance"; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + return this.getClass().equals(obj.getClass()); + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected SquaredEuclideanDistanceFunction makeInstance() { + return SquaredEuclideanDistanceFunction.STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedEuclideanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedEuclideanDistanceFunction.java new file mode 100644 index 00000000..2bc85aae --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedEuclideanDistanceFunction.java @@ -0,0 +1,124 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2013 + 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.Arrays; + +import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; + +/** + * Provides the Euclidean distance for FeatureVectors. + * + * @author Erich Schubert + */ +public class WeightedEuclideanDistanceFunction extends WeightedLPNormDistanceFunction { + /** + * Constructor. + * + * @param weights + */ + public WeightedEuclideanDistanceFunction(double[] weights) { + super(2.0, weights); + } + + /** + * Provides the Euclidean distance between the given two vectors. + * + * @return the Euclidean distance between the given two vectors as raw double + * value + */ + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2, weights.length); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double delta = (v1.doubleValue(d) - v2.doubleValue(d)); + agg += delta * delta * weights[d]; + } + return Math.sqrt(agg); + } + + @Override + public double doubleNorm(NumberVector<?> obj) { + final int dim = obj.getDimensionality(); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double delta = obj.doubleValue(dim); + agg += delta * delta * weights[d]; + } + return Math.sqrt(agg); + } + + @Override + public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + // Optimization for the simplest case + if (mbr1 instanceof NumberVector) { + if (mbr2 instanceof NumberVector) { + return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); + } + } + // TODO: optimize for more simpler cases: obj vs. rect? + final int dim = dimensionality(mbr1, mbr2, weights.length); + double agg = 0; + for (int d = 0; d < dim; d++) { + final double diff; + if (mbr1.getMax(d) < mbr2.getMin(d)) { + diff = mbr2.getMin(d) - mbr1.getMax(d); + } else if (mbr1.getMin(d) > mbr2.getMax(d)) { + diff = mbr1.getMin(d) - mbr2.getMax(d); + } else { // The mbrs intersect! + continue; + } + agg += diff * diff * weights[d]; + } + return Math.sqrt(agg); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof WeightedEuclideanDistanceFunction)) { + if (obj.getClass().equals(WeightedLPNormDistanceFunction.class)) { + return super.equals(obj); + } + if (obj.getClass().equals(EuclideanDistanceFunction.class)) { + for (double d : weights) { + if (d != 1.0) { + return false; + } + } + return true; + } + return false; + } + WeightedEuclideanDistanceFunction other = (WeightedEuclideanDistanceFunction) obj; + return Arrays.equals(this.weights, other.weights); + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedLPNormDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedLPNormDistanceFunction.java index 6a76366f..3d49c95a 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedLPNormDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedLPNormDistanceFunction.java @@ -1,10 +1,10 @@ -package de.lmu.ifi.dbs.elki.distance.distancefunction; +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,7 +29,7 @@ import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; /** - * Weighted version of the Euclidean distance function. + * Weighted version of the Minkowski L_p metrics distance function. * * @author Erich Schubert */ @@ -53,70 +53,63 @@ public class WeightedLPNormDistanceFunction extends LPNormDistanceFunction { @Override public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { - final int dim = weights.length; - if(dim != v1.getDimensionality()) { - throw new IllegalArgumentException("Dimensionality of FeatureVector doesn't match weights!"); - } - if(dim != v2.getDimensionality()) { - throw new IllegalArgumentException("Dimensionality of FeatureVector doesn't match weights!"); + final int dim = dimensionality(v1, v2, weights.length); + double agg = 0; + for (int d = 0; d < dim; d++) { + final double delta = Math.abs(v1.doubleValue(d) - v2.doubleValue(d)); + agg += Math.pow(delta, p) * weights[d]; } + return Math.pow(agg, invp); + } - final double p = getP(); - double sqrDist = 0; - for(int i = 0; i < dim; i++) { - final double delta = Math.abs(v1.doubleValue(i) - v2.doubleValue(i)); - sqrDist += Math.pow(delta, p) * weights[i - 1]; + @Override + public double doubleNorm(NumberVector<?> v) { + final int dim = v.getDimensionality(); + double agg = 0; + for (int d = 0; d < dim; d++) { + final double delta = Math.abs(v.doubleValue(d)); + agg += Math.pow(delta, p) * weights[d]; } - return Math.pow(sqrDist, 1.0 / p); + return Math.pow(agg, invp); } - + @Override public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { // Optimization for the simplest case - if(mbr1 instanceof NumberVector) { - if(mbr2 instanceof NumberVector) { + if (mbr1 instanceof NumberVector) { + if (mbr2 instanceof NumberVector) { return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); } } // TODO: optimize for more simpler cases: obj vs. rect? - final int dim1 = mbr1.getDimensionality(); - if(dim1 != mbr2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr1.toString() + "\n " + "second argument: " + mbr2.toString()); - } - - final double p = getP(); - double sumDist = 0; - for(int d = 0; d < dim1; d++) { - final double m1, m2; - if(mbr1.getMax(d) < mbr2.getMin(d)) { - m1 = mbr2.getMin(d); - m2 = mbr1.getMax(d); - } - else if(mbr1.getMin(d) > mbr2.getMax(d)) { - m1 = mbr1.getMin(d); - m2 = mbr2.getMax(d); - } - else { // The mbrs intersect! + final int dim = dimensionality(mbr1, mbr2, weights.length); + double agg = 0; + for (int d = 0; d < dim; d++) { + final double diff; + if (mbr1.getMax(d) < mbr2.getMin(d)) { + diff = mbr2.getMin(d) - mbr1.getMax(d); + } else if (mbr1.getMin(d) > mbr2.getMax(d)) { + diff = mbr1.getMin(d) - mbr2.getMax(d); + } else { // The mbrs intersect! continue; } - final double manhattanI = m1 - m2; - sumDist += Math.pow(manhattanI, p) * weights[d - 1]; + agg += Math.pow(diff, p) * weights[d]; } - return Math.pow(sumDist, 1.0 / p); + return Math.pow(agg, invp); } @Override public boolean equals(Object obj) { - if(this == obj) { + if (this == obj) { return true; } - if(obj == null) { + if (obj == null) { return false; } - if(!(obj instanceof WeightedLPNormDistanceFunction)) { - if(obj instanceof LPNormDistanceFunction && super.equals(obj)) { - for(double d : weights) { - if(d != 1.0) { + if (!(obj instanceof WeightedLPNormDistanceFunction)) { + if (obj instanceof LPNormDistanceFunction && super.equals(obj)) { + for (double d : weights) { + if (d != 1.0) { return false; } } @@ -127,4 +120,4 @@ public class WeightedLPNormDistanceFunction extends LPNormDistanceFunction { WeightedLPNormDistanceFunction other = (WeightedLPNormDistanceFunction) obj; return Arrays.equals(this.weights, other.weights); } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedManhattanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedManhattanDistanceFunction.java new file mode 100644 index 00000000..186f0435 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedManhattanDistanceFunction.java @@ -0,0 +1,110 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2013 + 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.Arrays; + +import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; + +/** + * Weighted version of the Minkowski L_p metrics distance function. + * + * @author Erich Schubert + */ +public class WeightedManhattanDistanceFunction extends WeightedLPNormDistanceFunction { + /** + * Constructor. + * + * @param weights Weight vector + */ + public WeightedManhattanDistanceFunction(double[] weights) { + super(1.0, weights); + } + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2, weights.length); + double agg = 0; + for (int d = 0; d < dim; d++) { + final double delta = Math.abs(v1.doubleValue(d) - v2.doubleValue(d)); + agg += delta * weights[d]; + } + return agg; + } + + @Override + public double doubleNorm(NumberVector<?> v) { + final int dim = v.getDimensionality(); + double agg = 0; + for (int d = 0; d < dim; d++) { + final double delta = Math.abs(v.doubleValue(d)); + agg += delta * weights[d]; + } + return agg; + } + + @Override + public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + // Optimization for the simplest case + if (mbr1 instanceof NumberVector) { + if (mbr2 instanceof NumberVector) { + return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); + } + } + // TODO: optimize for more simpler cases: obj vs. rect? + final int dim = dimensionality(mbr1, mbr2, weights.length); + double agg = 0; + for (int d = 0; d < dim; d++) { + final double diff; + if (mbr1.getMax(d) < mbr2.getMin(d)) { + diff = mbr2.getMin(d) - mbr1.getMax(d); + } else if (mbr1.getMin(d) > mbr2.getMax(d)) { + diff = mbr1.getMin(d) - mbr2.getMax(d); + } else { // The mbrs intersect! + continue; + } + agg += diff * weights[d]; + } + return agg; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof WeightedManhattanDistanceFunction)) { + if (obj instanceof WeightedLPNormDistanceFunction) { + return super.equals(obj); + } + return false; + } + WeightedManhattanDistanceFunction other = (WeightedManhattanDistanceFunction) obj; + return Arrays.equals(this.weights, other.weights); + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedSquaredEuclideanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedSquaredEuclideanDistanceFunction.java index e00f8e07..4e361c10 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedSquaredEuclideanDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedSquaredEuclideanDistanceFunction.java @@ -1,10 +1,10 @@ -package de.lmu.ifi.dbs.elki.distance.distancefunction; +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,6 +26,8 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction; import java.util.Arrays; import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDoubleDistanceNorm; /** * Provides the squared Euclidean distance for FeatureVectors. This results in @@ -33,7 +35,7 @@ import de.lmu.ifi.dbs.elki.data.NumberVector; * * @author Arthur Zimek */ -public class WeightedSquaredEuclideanDistanceFunction extends AbstractVectorDoubleDistanceFunction { +public class WeightedSquaredEuclideanDistanceFunction extends AbstractSpatialDoubleDistanceNorm { /** * Weight array */ @@ -57,16 +59,49 @@ public class WeightedSquaredEuclideanDistanceFunction extends AbstractVectorDoub */ @Override public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { - final int dim1 = v1.getDimensionality(); - if(dim1 != v2.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of FeatureVectors" + "\n first argument: " + v1.toString() + "\n second argument: " + v2.toString() + "\n" + v1.getDimensionality() + "!=" + v2.getDimensionality()); + final int dim = dimensionality(v1, v2, weights.length); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double delta = (v1.doubleValue(d) - v2.doubleValue(d)); + agg += delta * delta * weights[d]; } - double sqrDist = 0; - for(int i = 0; i < dim1; i++) { - final double delta = v1.doubleValue(i) - v2.doubleValue(i); - sqrDist += delta * delta * weights[i - 1]; + return agg; + } + + @Override + public double doubleNorm(NumberVector<?> obj) { + final int dim = obj.getDimensionality(); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double delta = obj.doubleValue(dim); + agg += delta * delta * weights[d]; + } + return agg; + } + + @Override + public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + // Optimization for the simplest case + if (mbr1 instanceof NumberVector) { + if (mbr2 instanceof NumberVector) { + return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); + } + } + // TODO: optimize for more simpler cases: obj vs. rect? + final int dim = dimensionality(mbr1, mbr2, weights.length); + double agg = 0; + for (int d = 0; d < dim; d++) { + final double diff; + if (mbr1.getMax(d) < mbr2.getMin(d)) { + diff = mbr2.getMin(d) - mbr1.getMax(d); + } else if (mbr1.getMin(d) > mbr2.getMax(d)) { + diff = mbr1.getMin(d) - mbr2.getMax(d); + } else { // The mbrs intersect! + continue; + } + agg += diff * diff * weights[d]; } - return sqrDist; + return agg; } @Override @@ -76,16 +111,16 @@ public class WeightedSquaredEuclideanDistanceFunction extends AbstractVectorDoub @Override public boolean equals(Object obj) { - if(this == obj) { + if (this == obj) { return true; } - if(obj == null) { + if (obj == null) { return false; } - if(!(obj instanceof WeightedSquaredEuclideanDistanceFunction)) { - if(obj.getClass().equals(SquaredEuclideanDistanceFunction.class)) { - for(double d : weights) { - if(d != 1.0) { + if (!(obj instanceof WeightedSquaredEuclideanDistanceFunction)) { + if (obj.getClass().equals(SquaredEuclideanDistanceFunction.class)) { + for (double d : weights) { + if (d != 1.0) { return false; } } @@ -96,4 +131,4 @@ public class WeightedSquaredEuclideanDistanceFunction extends AbstractVectorDoub WeightedSquaredEuclideanDistanceFunction other = (WeightedSquaredEuclideanDistanceFunction) obj; return Arrays.equals(this.weights, other.weights); } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/package-info.java new file mode 100644 index 00000000..c52167f3 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/package-info.java @@ -0,0 +1,26 @@ +/** + * <p>Minkowski space L_p norms such as the popular Euclidean and Manhattan distances.</p> + */ +/* +This file is part of ELKI: +Environment for Developing KDD-Applications Supported by Index-Structures + +Copyright (C) 2013 +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/>. +*/ +package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski;
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/package-info.java index f71ae4a2..19d72baf 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/package-info.java @@ -42,7 +42,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/ChiSquaredDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/ChiSquaredDistanceFunction.java new file mode 100644 index 00000000..3fb44680 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/ChiSquaredDistanceFunction.java @@ -0,0 +1,135 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic; + +/* + 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 de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDoubleDistanceFunction; +import de.lmu.ifi.dbs.elki.utilities.Alias; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Chi-Squared distance function, symmetric version. + * + * Reference: + * <p> + * J. Puzicha, J.M. Buhmann, Y. Rubner, C. Tomasi<br /> + * Empirical evaluation of dissimilarity measures for color and texture<br /> + * Proc. 7th IEEE International Conference on Computer Vision + * </p> + * + * @author Erich Schubert + */ +@Alias("chisq") +@Reference(authors = "J. Puzicha, J.M. Buhmann, Y. Rubner, C. Tomasi", title = "Empirical evaluation of dissimilarity measures for color and texture", booktitle = "Proc. 7th IEEE International Conference on Computer Vision", url = "http://dx.doi.org/10.1109/ICCV.1999.790412") +public class ChiSquaredDistanceFunction extends AbstractSpatialDoubleDistanceFunction { + /** + * Static instance. Use this! + */ + public static final ChiSquaredDistanceFunction STATIC = new ChiSquaredDistanceFunction(); + + /** + * Constructor for the Chi-Squared distance function. + * + * @deprecated Use static instance! + */ + @Deprecated + public ChiSquaredDistanceFunction() { + super(); + } + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + final double di = xd - yd; + final double si = xd + yd; + if (!(si > 0. || si < 0.) || !(di > 0. || di < 0.)) { + continue; + } + agg += di * di / si; + } + return 2. * agg; + } + + @Override + public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + final int dim = dimensionality(mbr1, mbr2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double min1 = mbr1.getMin(d), max1 = mbr1.getMax(d); + final double min2 = mbr2.getMin(d), max2 = mbr2.getMax(d); + final double diff; // Minimum difference + if (max1 < min2) { + diff = min2 - max1; + } else if (max2 < min1) { + diff = max2 - min1; + } else { + continue; // 0. + } + final double si = max1 + max2; // Maximum sum + if (!(si > 0. || si < 0.) || !(diff > 0. || diff < 0.)) { + continue; + } + agg += diff * diff / si; + } + return 2. * agg; + } + + @Override + public String toString() { + return "ChiSquaredDistance"; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (this.getClass().equals(obj.getClass())) { + return true; + } + return super.equals(obj); + } + + /** + * Parameterization class, using the static instance. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected ChiSquaredDistanceFunction makeInstance() { + return STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JeffreyDivergenceDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JeffreyDivergenceDistanceFunction.java new file mode 100644 index 00000000..73b944cf --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JeffreyDivergenceDistanceFunction.java @@ -0,0 +1,137 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic; + +/* + 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 de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDoubleDistanceFunction; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Provides the Jeffrey Divergence Distance for FeatureVectors. + * + * Reference: + * <p> + * J. Puzicha, J.M. Buhmann, Y. Rubner, C. Tomasi<br /> + * Empirical evaluation of dissimilarity measures for color and texture<br /> + * Proc. 7th IEEE International Conference on Computer Vision + * </p> + * + * @author Erich Schubert + */ +@Reference(authors = "J. Puzicha, J.M. Buhmann, Y. Rubner, C. Tomasi", title = "Empirical evaluation of dissimilarity measures for color and texture", booktitle = "Proc. 7th IEEE International Conference on Computer Vision", url = "http://dx.doi.org/10.1109/ICCV.1999.790412") +public class JeffreyDivergenceDistanceFunction extends AbstractSpatialDoubleDistanceFunction { + /** + * Static instance. Use this! + */ + public static final JeffreyDivergenceDistanceFunction STATIC = new JeffreyDivergenceDistanceFunction(); + + /** + * Constructor for the Jeffrey divergence. + * + * @deprecated Use static instance! + */ + @Deprecated + public JeffreyDivergenceDistanceFunction() { + super(); + } + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + if (xd == yd) { + continue; + } + final double md = .5 * (xd + yd); + if (!(md > 0. || md < 0.)) { + continue; + } + if (xd > 0.) { + agg += xd * Math.log(xd / md); + } + if (yd > 0.) { + agg += yd * Math.log(yd / md); + } + } + return agg; + } + + @Override + public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + final int dim = dimensionality(mbr1, mbr2); + double agg = 0; + for (int d = 0; d < dim; d++) { + final double min1 = mbr1.getMin(d), max1 = mbr1.getMax(d); + final double min2 = mbr2.getMin(d), max2 = mbr2.getMax(d); + final double md = .5 * (max1 + max2); + if (!(md > 0. || md < 0.)) { + continue; + } + if (min1 > 0.) { + agg += min1 * Math.log(min1 / md); + } + if (min2 > 0.) { + agg += min2 * Math.log(min2 / md); + } + } + return agg; + } + + @Override + public String toString() { + return "JeffreyDivergenceDistance"; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (this.getClass().equals(obj.getClass())) { + return true; + } + return super.equals(obj); + } + + /** + * Parameterization class, using the static instance. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected JeffreyDivergenceDistanceFunction makeInstance() { + return STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JensenShannonDivergenceDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JensenShannonDivergenceDistanceFunction.java new file mode 100644 index 00000000..d7692dcc --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JensenShannonDivergenceDistanceFunction.java @@ -0,0 +1,74 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic; + +/* + 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 de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Jensen-Shannon Divergence is essentially the same as Jeffrey divergence, only + * scaled by half. + * + * @author Erich Schubert + */ +public class JensenShannonDivergenceDistanceFunction extends JeffreyDivergenceDistanceFunction { + /** + * Static instance. Use this! + */ + public static final JensenShannonDivergenceDistanceFunction STATIC = new JensenShannonDivergenceDistanceFunction(); + + /** + * Constructor for the Jensen-Shannon divergence. + * + * @deprecated Use static instance! + */ + @Deprecated + public JensenShannonDivergenceDistanceFunction() { + super(); + } + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + return .5 * super.doubleDistance(v1, v2); + } + + @Override + public String toString() { + return "JensenShannonDivergenceDistance"; + } + + /** + * Parameterization class, using the static instance. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected JensenShannonDivergenceDistanceFunction makeInstance() { + return STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceAsymmetricDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceAsymmetricDistanceFunction.java new file mode 100644 index 00000000..c0f61d43 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceAsymmetricDistanceFunction.java @@ -0,0 +1,121 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic; + +/* + 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 de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction; +import de.lmu.ifi.dbs.elki.utilities.Alias; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Kullback-Leibler (asymmetric!) Distance, also known as relative entropy, + * information deviation or just KL-distance + * + * For a version with the arguments reversed, see + * {@link KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction}. + * + * For a symmetric version, see {@link JeffreyDivergenceDistanceFunction}. + * + * Reference: + * <p> + * S. Kullback<br /> + * Information theory and statistics<br /> + * Courier Dover Publications, 1997. + * </p> + * + * @author Erich Schubert + */ +@Reference(authors = "S. Kullback", title = "Information theory and statistics", booktitle = "Information theory and statistics, Courier Dover Publications, 1997.") +@Alias("kl") +public class KullbackLeiblerDivergenceAsymmetricDistanceFunction extends AbstractVectorDoubleDistanceFunction { + /** + * Static instance. Use this! + */ + public static final KullbackLeiblerDivergenceAsymmetricDistanceFunction STATIC = new KullbackLeiblerDivergenceAsymmetricDistanceFunction(); + + /** + * Constructor for the Kullback-Leibler divergence. + * + * @deprecated Use static instance! + */ + @Deprecated + public KullbackLeiblerDivergenceAsymmetricDistanceFunction() { + super(); + } + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + if (yd <= 0.) { + return Double.POSITIVE_INFINITY; + } + if (xd > 0.) { + agg += xd * Math.log(xd / yd); + } + } + return agg; + } + + @Override + public boolean isSymmetric() { + return false; + } + + @Override + public String toString() { + return "KullbackLeiblerDivergenceDistance"; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (this.getClass().equals(obj.getClass())) { + return true; + } + return super.equals(obj); + } + + /** + * Parameterization class, using the static instance. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected KullbackLeiblerDivergenceAsymmetricDistanceFunction makeInstance() { + return STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction.java new file mode 100644 index 00000000..08bddc1b --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction.java @@ -0,0 +1,122 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic; + +/* + 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 de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction; +import de.lmu.ifi.dbs.elki.utilities.Alias; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Kullback-Leibler (asymmetric!) Distance, also known as relative entropy, + * information deviation or just KL-distance. + * + * This version has the arguments reversed, see + * {@link KullbackLeiblerDivergenceAsymmetricDistanceFunction} for the "forward" + * version. + * + * For a symmetric version, see {@link JeffreyDivergenceDistanceFunction}. + * + * Reference: + * <p> + * S. Kullback<br /> + * Information theory and statistics<br /> + * Courier Dover Publications, 1997. + * </p> + * + * @author Erich Schubert + */ +@Reference(authors = "S. Kullback", title = "Information theory and statistics", booktitle = "Information theory and statistics, Courier Dover Publications, 1997.") +@Alias("kli") +public class KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction extends AbstractVectorDoubleDistanceFunction { + /** + * Static instance. Use this! + */ + public static final KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction STATIC = new KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction(); + + /** + * Constructor for the Kullback-Leibler divergence. + * + * @deprecated Use static instance! + */ + @Deprecated + public KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction() { + super(); + } + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2); + double agg = 0.; + for (int d = 0; d < dim; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + if (xd <= 0.) { + return Double.POSITIVE_INFINITY; + } + if (yd > 0.) { + agg += yd * Math.log(yd / xd); + } + } + return agg; + } + + @Override + public boolean isSymmetric() { + return false; + } + + @Override + public String toString() { + return "KullbackLeiblerDivergenceDistance"; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (this.getClass().equals(obj.getClass())) { + return true; + } + return super.equals(obj); + } + + /** + * Parameterization class, using the static instance. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction makeInstance() { + return STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/SqrtJensenShannonDivergenceDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/SqrtJensenShannonDivergenceDistanceFunction.java new file mode 100644 index 00000000..af0590fc --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/SqrtJensenShannonDivergenceDistanceFunction.java @@ -0,0 +1,120 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic; + +/* + 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 de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * The square root of Jensen-Shannon divergence is metric. + * + * Reference (proof of triangle inequality, distance called D_PQ): + * <p> + * D. M. Endres, J. E. Schindelin<br /> + * A new metric for probability distributions<br /> + * IEEE Transactions on Information Theory, 49(7). + * </p> + * + * @author Erich Schubert + */ +@Reference(authors = "D. M. Endres, J. E. Schindelin", title = "A new metric for probability distributions", booktitle = "IEEE Transactions on Information Theory, 49(7)", url = "http://dx.doi.org/10.1109/TIT.2003.813506") +public class SqrtJensenShannonDivergenceDistanceFunction extends AbstractVectorDoubleDistanceFunction { + /** + * Static instance. Use this! + */ + public static final SqrtJensenShannonDivergenceDistanceFunction STATIC = new SqrtJensenShannonDivergenceDistanceFunction(); + + /** + * Constructor for sqrt Jensen Shannon divergence. + * + * @deprecated Use static instance! + */ + @Deprecated + public SqrtJensenShannonDivergenceDistanceFunction() { + super(); + } + + @Override + public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + final int dim = dimensionality(v1, v2); + double agg = 0.; + for(int d = 0; d < dim; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + if(xd == yd) { + continue; + } + final double md = .5 * (xd + yd); + if(!(md > 0. || md < 0.)) { + continue; + } + if(xd > 0.) { + agg += xd * Math.log(xd / md); + } + if(yd > 0.) { + agg += yd * Math.log(yd / md); + } + } + return Math.sqrt(agg); + } + + @Override + public boolean isMetric() { + return true; + } + + @Override + public String toString() { + return "SqrtJensenShannonDivergenceDistance"; + } + + @Override + public boolean equals(Object obj) { + if(obj == null) { + return false; + } + if(obj == this) { + return true; + } + if(this.getClass().equals(obj.getClass())) { + return true; + } + return super.equals(obj); + } + + /** + * Parameterization class, using the static instance. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected SqrtJensenShannonDivergenceDistanceFunction makeInstance() { + return STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/package-info.java new file mode 100644 index 00000000..335c6ae0 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/package-info.java @@ -0,0 +1,6 @@ +/** + * Distance from probability theory, mostly divergences such as K-L-divergence, J-divergence. + * + * @author Erich Schubert + */ +package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic;
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/LevenshteinDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/LevenshteinDistanceFunction.java new file mode 100644 index 00000000..fbc75a22 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/LevenshteinDistanceFunction.java @@ -0,0 +1,135 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction.strings;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2013
+ 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.TypeUtil;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractPrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancevalue.IntegerDistance;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Classic Levenshtein distance on strings.
+ *
+ * Reference:
+ * <p>
+ * V. I. Levenshtein<br>
+ * Binary codes capable of correcting deletions, insertions and reversals.<br>
+ * Soviet physics doklady. Vol. 10. 1966.
+ * </p>
+ *
+ * TODO: add case insensitive flag.
+ *
+ * @author Felix Stahlberg
+ * @author Erich Schubert
+ *
+ * @apiviz.uses String
+ */
+@Description("Levenshtein distance.")
+@Reference(authors = "V. I. Levenshtein", title = "Binary codes capable of correcting deletions, insertions and reversals.", booktitle = "Soviet physics doklady. Vol. 10. 1966.")
+public class LevenshteinDistanceFunction extends AbstractPrimitiveDistanceFunction<String, IntegerDistance> {
+ /**
+ * Static instance, case sensitive.
+ */
+ public static final LevenshteinDistanceFunction STATIC_SENSITIVE = new LevenshteinDistanceFunction();
+
+ /**
+ * Constructor. Use static instance instead.
+ */
+ @Deprecated
+ public LevenshteinDistanceFunction() {
+ super();
+ }
+
+ @Override
+ public IntegerDistance distance(String o1, String o2) {
+ if (o1.equals(o2)) {
+ return new IntegerDistance(0);
+ }
+ final int cost = levenshteinDistance(o1, o2);
+ return new IntegerDistance(cost);
+ }
+
+ /**
+ * Levenshtein distance for two strings.
+ *
+ * @param o1 First string
+ * @param o2 Second string
+ * @return Levenshtein distance
+ */
+ public static int levenshteinDistance(String o1, String o2) {
+ // Let o2 be the shorter one:
+ if (o1.length() < o2.length()) {
+ return levenshteinDistance(o2, o1);
+ }
+ final int l1 = o1.length(), l2 = o2.length();
+ // Use two buffers:
+ int[] curr = new int[l2 + 1], prev = new int[l2 + 1];
+ // Initial row
+ for (int j = 0; j <= l2; j++) {
+ curr[j] = j;
+ }
+ for (int i = 0; i < l1; i++) {
+ // Swap curr and prev:
+ int[] tmp = curr;
+ curr = prev;
+ prev = tmp;
+ // Compute next row:
+ curr[0] = i + 1;
+ for (int j = 0; j < l2; j++) {
+ // TODO: allow case insensitive comparisons?
+ final int cost = (o1.charAt(i) == o2.charAt(j)) ? 0 : 1;
+ curr[j + 1] = Math.min(prev[j + 1] + 1, Math.min(curr[j] + 1, prev[j] + cost));
+ }
+ }
+ final int cost = curr[o2.length()];
+ return cost;
+ }
+
+ @Override
+ public IntegerDistance getDistanceFactory() {
+ return IntegerDistance.FACTORY;
+ }
+
+ @Override
+ public SimpleTypeInformation<? super String> getInputTypeRestriction() {
+ return TypeUtil.STRING;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected LevenshteinDistanceFunction makeInstance() {
+ return STATIC_SENSITIVE;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/NormalizedLevenshteinDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/NormalizedLevenshteinDistanceFunction.java new file mode 100644 index 00000000..0861c6af --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/NormalizedLevenshteinDistanceFunction.java @@ -0,0 +1,96 @@ +package de.lmu.ifi.dbs.elki.distance.distancefunction.strings;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2013
+ 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.TypeUtil;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractPrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Levenshtein distance on strings, normalized by string length.
+ *
+ * Reference:
+ * <p>
+ * V. I. Levenshtein<br>
+ * Binary codes capable of correcting deletions, insertions and reversals.<br>
+ * Soviet physics doklady. Vol. 10. 1966.
+ * </p>
+ *
+ * TODO: add case insensitive flag.
+ *
+ * @author Felix Stahlberg
+ * @author Erich Schubert
+ *
+ * @apiviz.uses String
+ */
+@Description("Levenshtein distance, normalized by average string length.")
+@Reference(authors = "V. I. Levenshtein", title = "Binary codes capable of correcting deletions, insertions and reversals.", booktitle = "Soviet physics doklady. Vol. 10. 1966.")
+public class NormalizedLevenshteinDistanceFunction extends AbstractPrimitiveDistanceFunction<String, DoubleDistance> {
+ /**
+ * Static instance, case sensitive.
+ */
+ public static final NormalizedLevenshteinDistanceFunction STATIC_SENSITIVE = new NormalizedLevenshteinDistanceFunction();
+
+ /**
+ * Constructor. Use static instance instead.
+ */
+ @Deprecated
+ public NormalizedLevenshteinDistanceFunction() {
+ super();
+ }
+
+ @Override
+ public DoubleDistance distance(String o1, String o2) {
+ int cost = LevenshteinDistanceFunction.levenshteinDistance(o1, o2);
+ return new DoubleDistance(cost * 2.0 / (o1.length() + o2.length()));
+ }
+
+ @Override
+ public DoubleDistance getDistanceFactory() {
+ return DoubleDistance.FACTORY;
+ }
+
+ @Override
+ public SimpleTypeInformation<? super String> getInputTypeRestriction() {
+ return TypeUtil.STRING;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected NormalizedLevenshteinDistanceFunction makeInstance() {
+ return STATIC_SENSITIVE;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/ModifiableDistanceDBIDResult.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/package-info.java index 52889652..a2f3fd2d 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/ModifiableDistanceDBIDResult.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/package-info.java @@ -1,10 +1,11 @@ -package de.lmu.ifi.dbs.elki.distance.distanceresultlist; - +/** + * <p>Distance functions for strings.</p> + */ /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -22,27 +23,5 @@ package de.lmu.ifi.dbs.elki.distance.distanceresultlist; 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.distance.distancefunction.strings; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -/** - * Modifiable API for Distance-DBID results - * - * @author Erich Schubert - * - * @param <D> Distance type - */ -public interface ModifiableDistanceDBIDResult<D extends Distance<D>> extends DistanceDBIDResult<D> { - /** - * Add an object to this result. - * - * @param distance Distance to add - * @param id DBID to add - */ - public void add(D distance, DBIDRef id); - - /** - * Sort the result in ascending order - */ - public void sort(); -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractDimensionsSelectingDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractDimensionsSelectingDoubleDistanceFunction.java index 6bedd394..25cb6407 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractDimensionsSelectingDoubleDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractDimensionsSelectingDoubleDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractPreferenceVectorBasedCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractPreferenceVectorBasedCorrelationDistanceFunction.java index e662bef1..f3a07639 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractPreferenceVectorBasedCorrelationDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractPreferenceVectorBasedCorrelationDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DiSHDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DiSHDistanceFunction.java index 77633578..7303797d 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DiSHDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DiSHDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -64,7 +64,7 @@ public class DiSHDistanceFunction extends AbstractPreferenceVectorBasedCorrelati // Generics (AFAICT) @SuppressWarnings("unchecked") DiSHPreferenceVectorIndex<T> indexinst = (DiSHPreferenceVectorIndex<T>) indexFactory.instantiate((Relation<NumberVector<?>>) database); - return new Instance<T>(database, indexinst, getEpsilon(), this); + return new Instance<>(database, indexinst, getEpsilon(), this); } /** diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingDistanceFunction.java index e1d52710..fe593f0a 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,14 +23,13 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import java.util.BitSet; + import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation; import de.lmu.ifi.dbs.elki.data.type.VectorTypeInformation; -import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractPrimitiveDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDoubleDistanceNorm; import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; @@ -44,7 +43,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter; * * @author Elke Achtert */ -public class DimensionSelectingDistanceFunction extends AbstractPrimitiveDistanceFunction<NumberVector<?>, DoubleDistance> implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> { +public class DimensionSelectingDistanceFunction extends AbstractSpatialDoubleDistanceNorm implements DimensionSelectingSubspaceDistanceFunction<NumberVector<?>, DoubleDistance> { /** * Parameter for dimensionality. */ @@ -76,7 +75,7 @@ public class DimensionSelectingDistanceFunction extends AbstractPrimitiveDistanc */ @Override public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { - if(dim >= v1.getDimensionality() || dim >= v2.getDimensionality() || dim < 0) { + if (dim >= v1.getDimensionality() || dim >= v2.getDimensionality() || dim < 0) { throw new IllegalArgumentException("Specified dimension to be considered " + "is larger that dimensionality of FeatureVectors:" + "\n first argument: " + v1.toString() + "\n second argument: " + v2.toString() + "\n dimension: " + dim); } @@ -86,20 +85,18 @@ public class DimensionSelectingDistanceFunction extends AbstractPrimitiveDistanc @Override public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { - if(dim >= mbr1.getDimensionality() || dim >= mbr2.getDimensionality() || dim < 0) { + if (dim >= mbr1.getDimensionality() || dim >= mbr2.getDimensionality() || dim < 0) { throw new IllegalArgumentException("Specified dimension to be considered " + "is larger that dimensionality of FeatureVectors:" + "\n first argument: " + mbr1.toString() + "\n second argument: " + mbr2.toString() + "\n dimension: " + dim); } double m1, m2; - if(mbr1.getMax(dim) < mbr2.getMin(dim)) { + if (mbr1.getMax(dim) < mbr2.getMin(dim)) { m1 = mbr1.getMax(dim); m2 = mbr2.getMin(dim); - } - else if(mbr1.getMin(dim) > mbr2.getMax(dim)) { + } else if (mbr1.getMin(dim) > mbr2.getMax(dim)) { m1 = mbr1.getMin(dim); m2 = mbr2.getMax(dim); - } - else { // The mbrs intersect! + } else { // The mbrs intersect! m1 = 0; m2 = 0; } @@ -109,13 +106,8 @@ public class DimensionSelectingDistanceFunction extends AbstractPrimitiveDistanc } @Override - public DoubleDistance distance(NumberVector<?> o1, NumberVector<?> o2) { - return new DoubleDistance(doubleDistance(o1, o2)); - } - - @Override - public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) { - return new DoubleDistance(doubleMinDist(mbr1, mbr2)); + public double doubleNorm(NumberVector<?> obj) { + return Math.abs(obj.doubleValue(dim)); } /** @@ -128,31 +120,45 @@ public class DimensionSelectingDistanceFunction extends AbstractPrimitiveDistanc } @Override - public VectorTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { - return new VectorFieldTypeInformation<NumberVector<?>>(NumberVector.class, dim, Integer.MAX_VALUE); + @Deprecated + public BitSet getSelectedDimensions() { + BitSet bs = new BitSet(dim + 1); + bs.set(dim); + return bs; } @Override - public DoubleDistance getDistanceFactory() { - return DoubleDistance.FACTORY; + public void setSelectedDimensions(BitSet dimensions) { + dim = dimensions.nextSetBit(0); + if (dim == -1) { + throw new IllegalStateException("No dimension was set."); + } + if (dimensions.nextSetBit(dim + 1) > 0) { + throw new IllegalStateException("More than one dimension was set."); + } } @Override - public <T extends NumberVector<?>> SpatialPrimitiveDistanceQuery<T, DoubleDistance> instantiate(Relation<T> database) { - return new SpatialPrimitiveDistanceQuery<T, DoubleDistance>(database, this); + public VectorTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { + return new VectorFieldTypeInformation<>(NumberVector.class, dim, Integer.MAX_VALUE); + } + + @Override + public DoubleDistance getDistanceFactory() { + return DoubleDistance.FACTORY; } @Override public boolean equals(Object obj) { - if(obj == null) { + if (obj == null) { return false; } - if(!this.getClass().equals(obj.getClass())) { + if (!this.getClass().equals(obj.getClass())) { return false; } return this.dim == ((DimensionSelectingDistanceFunction) obj).dim; } - + /** * Parameterization class. * @@ -168,7 +174,7 @@ public class DimensionSelectingDistanceFunction extends AbstractPrimitiveDistanc super.makeOptions(config); final IntParameter dimP = new IntParameter(DIM_ID); dimP.addConstraint(new GreaterEqualConstraint(0)); - if(config.grab(dimP)) { + if (config.grab(dimP)) { dim = dimP.getValue(); } } @@ -178,4 +184,4 @@ public class DimensionSelectingDistanceFunction extends AbstractPrimitiveDistanc return new DimensionSelectingDistanceFunction(dim); } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingSubspaceDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingSubspaceDistanceFunction.java index acc24bf7..f60e2fdc 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingSubspaceDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingSubspaceDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,8 +24,8 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace; */ import java.util.BitSet; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction; +import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * Interface for dimension selecting subspace distance functions. diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/HiSCDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/HiSCDistanceFunction.java index 0703ab2d..a339c389 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/HiSCDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/HiSCDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -66,7 +66,7 @@ public class HiSCDistanceFunction<V extends NumberVector<?>> extends AbstractPre // Generics (AFAICT) @SuppressWarnings("unchecked") HiSCPreferenceVectorIndex<T> indexinst = (HiSCPreferenceVectorIndex<T>) indexFactory.instantiate((Relation<V>) database); - return new Instance<T>(database, indexinst, getEpsilon(), this); + return new Instance<>(database, indexinst, getEpsilon(), this); } /** @@ -152,7 +152,7 @@ public class HiSCDistanceFunction<V extends NumberVector<?>> extends AbstractPre @Override protected HiSCDistanceFunction<V> makeInstance() { - return new HiSCDistanceFunction<V>(factory, epsilon); + return new HiSCDistanceFunction<>(factory, epsilon); } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/LocalSubspaceDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/LocalSubspaceDistanceFunction.java index ff38d3d9..efcf6a3c 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/LocalSubspaceDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/LocalSubspaceDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -68,7 +68,7 @@ public class LocalSubspaceDistanceFunction extends AbstractIndexBasedDistanceFun // We can't really avoid these warnings, due to a limitation in Java Generics (AFAICT) @SuppressWarnings("unchecked") FilteredLocalPCAIndex<V> indexinst = (FilteredLocalPCAIndex<V>) indexFactory.instantiate((Relation<NumberVector<?>>)database); - return new Instance<V>(database, indexinst, this); + return new Instance<>(database, indexinst, this); } /** diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceEuclideanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceEuclideanDistanceFunction.java index 48518afd..d24fc62e 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceEuclideanDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceEuclideanDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceLPNormDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceLPNormDistanceFunction.java index ccfc51d9..2fbdf876 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceLPNormDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceLPNormDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -32,8 +32,8 @@ import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation; import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.distance.distancefunction.DoubleNorm; -import de.lmu.ifi.dbs.elki.distance.distancefunction.LPNormDistanceFunction; import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction; +import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction; import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterConstraint; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; @@ -171,7 +171,7 @@ public class SubspaceLPNormDistanceFunction extends AbstractDimensionsSelectingD @Override public <T extends NumberVector<?>> SpatialPrimitiveDistanceQuery<T, DoubleDistance> instantiate(Relation<T> database) { - return new SpatialPrimitiveDistanceQuery<T, DoubleDistance>(database, this); + return new SpatialPrimitiveDistanceQuery<>(database, this); } @Override diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceManhattanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceManhattanDistanceFunction.java index fb777d81..ccca76da 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceManhattanDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceManhattanDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/package-info.java index 85035eec..2b5db4c5 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/AbstractEditDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/AbstractEditDistanceFunction.java index a88dbded..76630586 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/AbstractEditDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/AbstractEditDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/DTWDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/DTWDistanceFunction.java index d3fab3c0..eedd3a7c 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/DTWDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/DTWDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/EDRDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/EDRDistanceFunction.java index 4c177b03..0e38d8bd 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/EDRDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/EDRDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/ERPDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/ERPDistanceFunction.java index a4525a6b..fd5bb61c 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/ERPDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/ERPDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/LCSSDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/LCSSDistanceFunction.java index 192f8d6f..2998248d 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/LCSSDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/LCSSDistanceFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/package-info.java index cad7fba9..4edbe89f 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/package-info.java @@ -8,7 +8,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/AbstractKNNHeap.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/AbstractKNNHeap.java deleted file mode 100644 index 30df7c16..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/AbstractKNNHeap.java +++ /dev/null @@ -1,113 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distanceresultlist; - -/* - 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 java.util.Comparator; - -import de.lmu.ifi.dbs.elki.database.ids.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; -import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.TiedTopBoundedHeap; - -/** - * Heap used for KNN management. - * - * @author Erich Schubert - * - * @param <P> pair type - * @param <D> distance type - */ -abstract public class AbstractKNNHeap<P extends DistanceDBIDPair<D>, D extends Distance<D>> implements KNNHeap<D> { - /** - * Static comparator. - */ - public static final Comparator<? super DistanceDBIDPair<?>> COMPARATOR = new Comp(); - - /** - * The actual heap. - */ - protected final TiedTopBoundedHeap<P> heap; - - /** - * Constructor. - * - * @param k Maximum heap size (unless tied) - */ - public AbstractKNNHeap(int k) { - super(); - heap = new TiedTopBoundedHeap<P>(k, COMPARATOR); - } - - /** - * Add a pair to the heap. - * - * @param pair Pair to add. - */ - public abstract void add(P pair); - - @Override - public final int getK() { - return heap.getMaxSize(); - } - - @Override - public int size() { - return heap.size(); - } - - @Override - public P peek() { - return heap.peek(); - } - - @Override - public boolean isEmpty() { - return heap.isEmpty(); - } - - @Override - public void clear() { - heap.clear(); - } - - @Override - public P poll() { - return heap.poll(); - } - - /** - * Comparator to use. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - protected static class Comp implements Comparator<DistanceDBIDPair<?>> { - @SuppressWarnings("unchecked") - @Override - public int compare(DistanceDBIDPair<?> o1, DistanceDBIDPair<?> o2) { - return -((DistanceDBIDPair<DoubleDistance>)o1).compareByDistance((DistanceDBIDPair<DoubleDistance>)o2); - } - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DistanceDBIDResult.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DistanceDBIDResult.java deleted file mode 100644 index 2d7d68de..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DistanceDBIDResult.java +++ /dev/null @@ -1,88 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distanceresultlist; - -/* - 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.database.ids.DBIDs; -import de.lmu.ifi.dbs.elki.database.ids.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; - -/** - * Collection of objects and their distances. - * - * To iterate over the results, use the following code: - * - * <pre> - * {@code - * for (DistanceDBIDResultIter<D> iter = result.iter(); iter.valid(); iter.advance()) { - * // You can get the distance via: iter.getDistance(); - * // Or use iter just like any other DBIDRef - * } - * } - * </pre> - * - * If you are only interested in the IDs of the objects, the following is also - * sufficient: - * - * <pre> - * {@code - * for (DBIDIter<D> iter = result.iter(); iter.valid(); iter.advance()) { - * // Use iter just like any other DBIDRef - * } - * } - * </pre> - * - * @author Erich Schubert - * - * @apiviz.landmark - * - * @apiviz.composedOf DistanceDBIDPair - * @apiviz.has DistanceDBIDResultIter - * - * @param <D> Distance type - */ -public interface DistanceDBIDResult<D extends Distance<D>> extends DBIDs { - /** - * Size of list. - * - * @return Size - */ - @Override - public int size(); - - /** - * Access a single pair. - * - * @param off Offset - * @return Pair - */ - public DistanceDBIDPair<D> get(int off); - - /** - * Get an iterator - * - * @return New iterator - */ - @Override - public DistanceDBIDResultIter<D> iter(); -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DistanceDBIDResultIter.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DistanceDBIDResultIter.java deleted file mode 100644 index d84e5d18..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DistanceDBIDResultIter.java +++ /dev/null @@ -1,57 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distanceresultlist; - -/* - 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.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; - -/** - * Iterator over distance-based query results. - * - * There is no getter for the DBID, as this implements - * {@link de.lmu.ifi.dbs.elki.database.ids.DBIDRef}. - * - * @author Erich Schubert - * - * @apiviz.landmark - * - * @apiviz.has DistanceDBIDPair - - iterator for - * @apiviz.has de.lmu.ifi.dbs.elki.database.ids.DBID - - iterator for - */ -public interface DistanceDBIDResultIter<D extends Distance<D>> extends DBIDIter { - /** - * Get the distance - * - * @return distance - */ - public D getDistance(); - - /** - * Get an object pair. - * - * @return object pair - */ - public DistanceDBIDPair<D> getDistancePair(); -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DistanceDBIDResultUtil.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DistanceDBIDResultUtil.java index aea23be6..d1564fd8 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DistanceDBIDResultUtil.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DistanceDBIDResultUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distanceresultlist; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,7 +27,9 @@ import java.util.Comparator; import java.util.List; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.DistanceDBIDPair; +import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair; +import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter; import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; /** @@ -44,7 +46,7 @@ public final class DistanceDBIDResultUtil { * @return comparator */ @SuppressWarnings("unchecked") - public static <D extends DistanceDBIDPair<?>> Comparator<D> distanceComparator() { + public static <D extends DistanceDBIDPair<?>> Comparator<? super D> distanceComparator() { return (Comparator<D>) BY_DISTANCE_THEN_DBID; } @@ -70,13 +72,24 @@ public final class DistanceDBIDResultUtil { } }; - public static String toString(DistanceDBIDResult<?> res) { + /** + * Static comparator for heaps. + */ + public static final Comparator<DistanceDBIDPair<?>> BY_REVERSE_DISTANCE = new Comparator<DistanceDBIDPair<?>>() { + @SuppressWarnings("unchecked") + @Override + public int compare(DistanceDBIDPair<?> o1, DistanceDBIDPair<?> o2) { + return -((DistanceDBIDPair<DoubleDistance>)o1).compareByDistance((DistanceDBIDPair<DoubleDistance>)o2); + } + }; + + public static String toString(DistanceDBIDList<?> res) { StringBuilder buf = new StringBuilder(); buf.append('['); - DistanceDBIDResultIter<?> iter = res.iter(); + DistanceDBIDListIter<?> iter = res.iter(); for(; iter.valid(); iter.advance()) { if(buf.length() > 1) { - buf.append(", "); + buf.append(',').append(' '); } buf.append(iter.getDistancePair().toString()); } diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DoubleDistanceDBIDList.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DoubleDistanceDBIDList.java deleted file mode 100644 index 9ff22b74..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DoubleDistanceDBIDList.java +++ /dev/null @@ -1,190 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distanceresultlist; - -/* - 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 java.util.ArrayList; -import java.util.Collections; - -import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory; -import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Default class to keep a list of distance-object pairs. - * - * @author Erich Schubert - * - * @apiviz.composedOf DoubleDistanceDBIDPair - * @apiviz.has DoubleDistanceDBIDResultIter - */ -public class DoubleDistanceDBIDList implements ModifiableDistanceDBIDResult<DoubleDistance> { - /** - * Actual storage. - */ - final ArrayList<DoubleDistanceDBIDPair> storage; - - /** - * Constructor. - */ - public DoubleDistanceDBIDList() { - super(); - storage = new ArrayList<DoubleDistanceDBIDPair>(); - } - - /** - * Constructor. - * - * @param initialCapacity Capacity - */ - public DoubleDistanceDBIDList(int initialCapacity) { - super(); - storage = new ArrayList<DoubleDistanceDBIDPair>(initialCapacity); - } - - /** - * Add an element. - * - * @deprecated Pass a double value instead. - * - * @param dist Distance - * @param id ID - */ - @Override - @Deprecated - public void add(DoubleDistance dist, DBIDRef id) { - storage.add(DBIDFactory.FACTORY.newDistancePair(dist.doubleValue(), id)); - } - - /** - * Add an element. - * - * @param dist Distance - * @param id ID - */ - public void add(double dist, DBIDRef id) { - storage.add(DBIDFactory.FACTORY.newDistancePair(dist, id)); - } - - /** - * Add an element. - * - * @param pair Pair to add - */ - public void add(DoubleDistanceDBIDPair pair) { - storage.add(pair); - } - - @Override - public void sort() { - Collections.sort(storage, DistanceDBIDResultUtil.distanceComparator()); - } - - @Override - public int size() { - return storage.size(); - } - - @Override - public DoubleDistanceDBIDPair get(int off) { - return storage.get(off); - } - - @Override - public DoubleDistanceDBIDResultIter iter() { - return new Iter(); - } - - @Override - public boolean contains(DBIDRef o) { - for(DBIDIter iter = iter(); iter.valid(); iter.advance()) { - if(DBIDUtil.equal(iter, o)) { - return true; - } - } - return false; - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public String toString() { - return DistanceDBIDResultUtil.toString(this); - } - - /** - * Iterator class. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - protected class Iter implements DoubleDistanceDBIDResultIter { - /** - * Iterator position. - */ - int pos = 0; - - @Override - public int internalGetIndex() { - return get(pos).internalGetIndex(); - } - - @Override - public boolean valid() { - return pos < size(); - } - - @Override - public void advance() { - pos++; - } - - @Override - @Deprecated - public DoubleDistance getDistance() { - return get(pos).getDistance(); - } - - @Override - public double doubleDistance() { - return get(pos).doubleDistance(); - } - - @Override - public DoubleDistanceDBIDPair getDistancePair() { - return get(pos); - } - - @Override - public String toString() { - return valid() ? getDistancePair().toString() : "null"; - } - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DoubleDistanceDBIDResultIter.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DoubleDistanceDBIDResultIter.java deleted file mode 100644 index d022fe4c..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DoubleDistanceDBIDResultIter.java +++ /dev/null @@ -1,61 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distanceresultlist; - -/* - 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.database.ids.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Iterator for double valued distance-based query results. - * - * @author Erich Schubert - */ -public interface DoubleDistanceDBIDResultIter extends DistanceDBIDResultIter<DoubleDistance> { - /** - * Get the distance - * - * @return distance - */ - public double doubleDistance(); - - /** - * Get an object pair. - * - * @return object pair - */ - @Override - public DoubleDistanceDBIDPair getDistancePair(); - - /** - * Get the distance - * - * @deprecated Use {@link #doubleDistance} to avoid creating unnecessary - * objects. - * - * @return distance - */ - @Deprecated - @Override - public DoubleDistance getDistance(); -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DoubleDistanceKNNHeap.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DoubleDistanceKNNHeap.java deleted file mode 100644 index 7faa407d..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DoubleDistanceKNNHeap.java +++ /dev/null @@ -1,191 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distanceresultlist; - -/* - 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 java.util.Comparator; - -import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Heap for collecting double-valued KNN instances. - * - * See also: {@link KNNUtil#newHeap}! - * - * Experiments have shown that it can be much more performant to track the - * knndistance <em>outside</em> of the heap, and do comparisons on the stack: - * <blockquote> - * - * <pre> - * {@code - * double knndist = Double.POSITIVE_INFINITY; - * DoubleDistanceKNNHeap heap = new DoubleDistanceKNNHeap(k); - * for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) { - * double dist = computeDistance(iditer, ...); - * if (dist < knndist) { - * heap.add(dist, iditer); - * if (heap.size() >= k) { - * max = heap.doubleKNNDistance(); - * } - * } - * } - * } - * </pre> - * - * </blockquote> - * - * The reason probably is that {@code knndist} resides on the stack and can be - * better optimized by the hotspot compiler. - * - * @author Erich Schubert - */ -public class DoubleDistanceKNNHeap extends AbstractKNNHeap<DoubleDistanceDBIDPair, DoubleDistance> { - /** - * Comparator class. - */ - public static final Comparator<DoubleDistanceDBIDPair> COMPARATOR = new Comp(); - - /** - * Cached distance to k nearest neighbor (to avoid going through {@link #peek} - * too often). - */ - protected double knndistance = Double.POSITIVE_INFINITY; - - /** - * Constructor. - * - * See also: {@link KNNUtil#newHeap}! - * - * @param k Heap size - */ - public DoubleDistanceKNNHeap(int k) { - super(k); - } - - /** - * Serialize to a {@link DoubleDistanceKNNList}. This empties the heap! - * - * @return KNNList with the heaps contents. - */ - @Override - public DoubleDistanceKNNList toKNNList() { - return new DoubleDistanceKNNList(this); - } - - /** - * Add a distance-id pair to the heap unless the distance is too large. - * - * Compared to the super.add() method, this often saves the pair construction. - * - * @param distance Distance value - * @param id ID number - */ - public final void add(final double distance, final DBIDRef id) { - if (size() < getK() || knndistance >= distance) { - heap.add(DBIDFactory.FACTORY.newDistancePair(distance, id)); - heapModified(); - } - } - - /** - * Add a distance-id pair to the heap unless the distance is too large. - * - * Compared to the super.add() method, this often saves the pair construction. - * - * @param distance Distance value - * @param id ID number - */ - public final void add(final Double distance, final DBIDRef id) { - if (size() < getK() || knndistance >= distance) { - heap.add(DBIDFactory.FACTORY.newDistancePair(distance, id)); - heapModified(); - } - } - - // @Override - protected void heapModified() { - // super.heapModified(); - if (size() >= getK()) { - knndistance = heap.peek().doubleDistance(); - } - } - - // @Override - public void add(final DoubleDistanceDBIDPair e) { - if (size() < getK() || knndistance >= e.doubleDistance()) { - heap.add(e); - heapModified(); - } - } - - /** - * {@inheritDoc} - * - * @deprecated if you know your distances are double-valued, you should be - * using the primitive type. - * - */ - @Override - @Deprecated - public void add(DoubleDistance dist, DBIDRef id) { - add(dist.doubleValue(), id); - } - - /** - * Get the distance to the k nearest neighbor, or maxdist otherwise. - * - * @return Maximum distance - */ - public double doubleKNNDistance() { - return knndistance; - } - - /** - * {@inheritDoc} - * - * @deprecated if you know your distances are double-valued, you should be - * using the primitive type. - */ - @Override - @Deprecated - public DoubleDistance getKNNDistance() { - return new DoubleDistance(knndistance); - } - - /** - * Comparator to use. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - protected static class Comp implements Comparator<DoubleDistanceDBIDPair> { - @Override - public int compare(DoubleDistanceDBIDPair o1, DoubleDistanceDBIDPair o2) { - return -Double.compare(o1.doubleDistance(), o2.doubleDistance()); - } - } -} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DoubleDistanceKNNList.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DoubleDistanceKNNList.java deleted file mode 100644 index 656377c6..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DoubleDistanceKNNList.java +++ /dev/null @@ -1,238 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distanceresultlist; - -/* - 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 java.util.Collection; -import java.util.Iterator; - -import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; -import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap; - -/** - * Finalized KNN List. - * - * @author Erich Schubert - * - * @apiviz.composedOf DoubleDistanceDBIDPair - * @apiviz.has DoubleDistanceDBIDResultIter - */ -public class DoubleDistanceKNNList implements KNNResult<DoubleDistance> { - /** - * The value of k this was materialized for. - */ - private final int k; - - /** - * The actual data array. - */ - private final DoubleDistanceDBIDPair[] data; - - /** - * Constructor. This will <em>clone</em> the given collection! - * - * @param col Existing collection - * @param k K parameter - */ - public DoubleDistanceKNNList(Collection<DoubleDistanceDBIDPair> col, int k) { - super(); - this.data = new DoubleDistanceDBIDPair[col.size()]; - this.k = k; - assert (col.size() >= this.k) : "Collection doesn't contain enough objects!"; - // Get sorted data from heap; but in reverse. - Iterator<DoubleDistanceDBIDPair> it = col.iterator(); - for(int i = 0; it.hasNext(); i++) { - data[i] = it.next(); - } - assert (data.length == 0 || data[0] != null); - } - - /** - * Constructor, to be called from KNNHeap only. Use {@link KNNHeap#toKNNList} - * instead! - * - * @param heap Calling heap - */ - protected DoubleDistanceKNNList(DoubleDistanceKNNHeap heap) { - super(); - this.data = new DoubleDistanceDBIDPair[heap.size()]; - this.k = heap.getK(); - assert (heap.size() >= this.k) : "Heap doesn't contain enough objects!"; - // Get sorted data from heap; but in reverse. - int i = heap.size(); - while(heap.size() > 0) { - i--; - assert (i >= 0); - data[i] = heap.poll(); - } - assert (data.length == 0 || data[0] != null); - assert (heap.size() == 0); - } - - /** - * Constructor, to be called from KNNHeap only. Use {@link KNNHeap#toKNNList} - * instead! - * - * @param heap Calling heap - * @param k Target number of neighbors (before ties) - */ - public DoubleDistanceKNNList(Heap<DoubleDistanceDBIDPair> heap, int k) { - super(); - this.data = new DoubleDistanceDBIDPair[heap.size()]; - this.k = k; - assert (heap.size() >= this.k) : "Heap doesn't contain enough objects!"; - // Get sorted data from heap; but in reverse. - int i = heap.size(); - while(heap.size() > 0) { - i--; - assert (i >= 0); - data[i] = heap.poll(); - } - assert (data.length == 0 || data[0] != null); - assert (heap.size() == 0); - } - - @Override - public int getK() { - return k; - } - - /** - * {@inheritDoc} - * - * @deprecated use doubleKNNDistance()! - */ - @Override - @Deprecated - public DoubleDistance getKNNDistance() { - return get(getK() - 1).getDistance(); - } - - /** - * Get the kNN distance as double value. - * - * @return Distance - */ - public double doubleKNNDistance() { - return get(getK() - 1).doubleDistance(); - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append("kNNList["); - for(DoubleDistanceDBIDResultIter iter = this.iter(); iter.valid();) { - buf.append(iter.doubleDistance()).append(':').append(DBIDUtil.toString(iter)); - iter.advance(); - if(iter.valid()) { - buf.append(','); - } - } - buf.append(']'); - return buf.toString(); - } - - @Override - public DoubleDistanceDBIDPair get(int index) { - return data[index]; - } - - @Override - public DoubleDistanceDBIDResultIter iter() { - return new Itr(); - } - - @Override - public int size() { - return data.length; - } - - @Override - public boolean contains(DBIDRef o) { - for(DBIDIter iter = iter(); iter.valid(); iter.advance()) { - if(DBIDUtil.equal(iter, o)) { - return true; - } - } - return false; - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - /** - * Iterator. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - private class Itr implements DoubleDistanceDBIDResultIter { - /** - * Cursor position. - */ - private int pos = 0; - - @Override - public int internalGetIndex() { - return get(pos).internalGetIndex(); - } - - @Override - public boolean valid() { - return pos < data.length; - } - - @Override - public void advance() { - pos++; - } - - /** - * {@inheritDoc} - * - * @deprecated use {@link #doubleDistance}! - */ - @Override - @Deprecated - public DoubleDistance getDistance() { - return get(pos).getDistance(); - } - - @Override - public double doubleDistance() { - return get(pos).doubleDistance(); - } - - @Override - public DoubleDistanceDBIDPair getDistancePair() { - return get(pos); - } - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/GenericDistanceDBIDList.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/GenericDistanceDBIDList.java deleted file mode 100644 index 05e4e687..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/GenericDistanceDBIDList.java +++ /dev/null @@ -1,163 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distanceresultlist; - -/* - 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 java.util.ArrayList; - -import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory; -import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; - -/** - * Default class to keep a list of distance-object pairs. - * - * @author Erich Schubert - * - * @param <D> Distance type - */ -public class GenericDistanceDBIDList<D extends Distance<D>> implements ModifiableDistanceDBIDResult<D> { - /** - * Actual storage. - */ - final ArrayList<DistanceDBIDPair<D>> storage; - - /** - * Constructor. - */ - public GenericDistanceDBIDList() { - super(); - storage = new ArrayList<DistanceDBIDPair<D>>(); - } - - /** - * Constructor. - * - * @param initialCapacity Capacity - */ - public GenericDistanceDBIDList(int initialCapacity) { - super(); - storage = new ArrayList<DistanceDBIDPair<D>>(initialCapacity); - } - - @Override - public void add(D dist, DBIDRef id) { - storage.add(DBIDFactory.FACTORY.newDistancePair(dist, id)); - } - - /** - * Add a prepared pair. - * - * @param pair Pair to add - */ - public void add(DistanceDBIDPair<D> pair) { - storage.add(pair); - } - - @Override - public void sort() { - DistanceDBIDResultUtil.sortByDistance(storage); - } - - @Override - public int size() { - return storage.size(); - } - - @Override - public DistanceDBIDPair<D> get(int off) { - return storage.get(off); - } - - @Override - public DistanceDBIDResultIter<D> iter() { - return new Iter(); - } - - @Override - public boolean contains(DBIDRef o) { - for(DBIDIter iter = iter(); iter.valid(); iter.advance()) { - if(DBIDUtil.equal(iter, o)) { - return true; - } - } - return false; - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public String toString() { - return DistanceDBIDResultUtil.toString(this); - } - - /** - * Iterator class. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - protected class Iter implements DistanceDBIDResultIter<D> { - /** - * Iterator position. - */ - int pos = 0; - - @Override - public int internalGetIndex() { - return get(pos).internalGetIndex(); - } - - @Override - public boolean valid() { - return pos < size(); - } - - @Override - public void advance() { - pos++; - } - - @Override - public D getDistance() { - return get(pos).getDistance(); - } - - @Override - public DistanceDBIDPair<D> getDistancePair() { - return get(pos); - } - - @Override - public String toString() { - return valid() ? getDistancePair().toString() : "null"; - } - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/GenericKNNHeap.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/GenericKNNHeap.java deleted file mode 100644 index c13887be..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/GenericKNNHeap.java +++ /dev/null @@ -1,106 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distanceresultlist; - -/* - 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.database.ids.DBIDFactory; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; - -/** - * Heap for collecting kNN candiates with arbitrary distance types. - * - * For double distances, see {@link DoubleDistanceKNNHeap} - * - * <b>To instantiate, use {@link KNNUtil#newHeap} instead!</b> - * - * @author Erich Schubert - * - * @param <D> Distance type - */ -class GenericKNNHeap<D extends Distance<D>> extends AbstractKNNHeap<DistanceDBIDPair<D>, D> { - /** - * Cached distance to k nearest neighbor (to avoid going through {@link #peek} - * each time). - */ - protected D knndistance = null; - - /** - * Constructor. - * - * <b>To instantiate, use {@link KNNUtil#newHeap} instead!</b> - * - * @param k Heap size - */ - protected GenericKNNHeap(int k) { - super(k); - } - - /** - * Serialize to a {@link GenericKNNList}. This empties the heap! - * - * @return KNNList with the heaps contents. - */ - @Override - public GenericKNNList<D> toKNNList() { - return new GenericKNNList<D>(this); - } - - @Override - public void add(D distance, DBIDRef id) { - if (size() < getK()) { - heap.add(DBIDFactory.FACTORY.newDistancePair(distance, id)); - heapModified(); - return; - } - // size >= maxsize. Insert only when necessary. - if (knndistance.compareTo(distance) >= 0) { - // Replace worst element. - heap.add(DBIDFactory.FACTORY.newDistancePair(distance, id)); - heapModified(); - } - } - - @Override - public void add(DistanceDBIDPair<D> pair) { - if (size() < getK() || knndistance.compareTo(pair.getDistance()) >= 0) { - heap.add(pair); - heapModified(); - } - } - - // @Override - protected void heapModified() { - // super.heapModified(); - // Update threshold. - if (size() >= getK()) { - knndistance = heap.peek().getDistance(); - } - } - - @Override - public D getKNNDistance() { - return knndistance; - } -} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/GenericKNNList.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/GenericKNNList.java deleted file mode 100644 index 71217b23..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/GenericKNNList.java +++ /dev/null @@ -1,189 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distanceresultlist; - -/* - 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.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap; - -/** - * Finalized KNN List. - * - * @author Erich Schubert - * - * @param <D> Distance type - */ -public class GenericKNNList<D extends Distance<D>> implements KNNResult<D> { - /** - * The value of k this was materialized for. - */ - private final int k; - - /** - * The actual data array. - */ - private final Object[] data; - - /** - * Constructor, to be called from KNNHeap only. Use {@link KNNHeap#toKNNList} - * instead! - * - * @param heap Calling heap - */ - protected GenericKNNList(KNNHeap<D> heap) { - super(); - this.data = new Object[heap.size()]; - this.k = heap.getK(); - assert (heap.size() >= this.k) : "Heap doesn't contain enough objects!"; - // Get sorted data from heap; but in reverse. - int i = heap.size(); - while(heap.size() > 0) { - i--; - assert (i >= 0); - data[i] = heap.poll(); - } - assert (data.length == 0 || data[0] != null); - assert (heap.size() == 0); - } - - /** - * Constructor. With a KNNHeap, use {@link KNNHeap#toKNNList} instead! - * - * @param heap Calling heap - * @param k K value - */ - public GenericKNNList(Heap<? extends DistanceDBIDPair<D>> heap, int k) { - super(); - this.data = new Object[heap.size()]; - this.k = k; - assert (heap.size() >= this.k) : "Heap doesn't contain enough objects!"; - // Get sorted data from heap; but in reverse. - int i = heap.size(); - while(!heap.isEmpty()) { - i--; - assert (i >= 0); - data[i] = heap.poll(); - } - assert (data.length == 0 || data[0] != null); - assert (heap.size() == 0); - } - - @Override - public int getK() { - return k; - } - - @Override - public D getKNNDistance() { - return get(getK() - 1).getDistance(); - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append("kNNList["); - for(DistanceDBIDResultIter<D> iter = this.iter(); iter.valid();) { - buf.append(iter.getDistance()).append(':').append(DBIDUtil.toString(iter)); - iter.advance(); - if(iter.valid()) { - buf.append(','); - } - } - buf.append(']'); - return buf.toString(); - } - - @SuppressWarnings("unchecked") - @Override - public DistanceDBIDPair<D> get(int index) { - return (DistanceDBIDPair<D>) data[index]; - } - - @Override - public DistanceDBIDResultIter<D> iter() { - return new Itr(); - } - - @Override - public int size() { - return data.length; - } - - @Override - public boolean contains(DBIDRef o) { - for(DBIDIter iter = iter(); iter.valid(); iter.advance()) { - if(DBIDUtil.equal(iter, o)) { - return true; - } - } - return false; - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - /** - * Iterator. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - private class Itr implements DistanceDBIDResultIter<D> { - /** - * Cursor position. - */ - private int pos = 0; - - @Override - public int internalGetIndex() { - return get(pos).internalGetIndex(); - } - - @Override - public boolean valid() { - return pos < data.length; - } - - @Override - public void advance() { - pos++; - } - - @Override - public D getDistance() { - return get(pos).getDistance(); - } - - @Override - public DistanceDBIDPair<D> getDistancePair() { - return get(pos); - } - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/KNNHeap.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/KNNHeap.java deleted file mode 100644 index cdcb7d98..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/KNNHeap.java +++ /dev/null @@ -1,113 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distanceresultlist; - -/* - 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.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; - -/** - * Interface for kNN heaps. - * - * To instantiate, use: {@link KNNUtil#newHeap}! - * - * @author Erich Schubert - * - * @apiviz.landmark - * - * @apiviz.uses GenericKNNList - - «serializes to» - * @apiviz.uses DoubleDistanceKNNList - - «serializes to» - * @apiviz.composedOf DistanceDBIDPair - * - * @param <D> Distance function - */ -public interface KNNHeap<D extends Distance<D>> { - /** - * Serialize to a {@link GenericKNNList}. This empties the heap! - * - * @return KNNList with the heaps contents. - */ - KNNResult<D> toKNNList(); - - /** - * Get the K parameter ("maxsize" internally). - * - * @return K - */ - int getK(); - - /** - * Get the distance to the k nearest neighbor, or maxdist otherwise. - * - * @return Maximum distance - */ - D getKNNDistance(); - - /** - * Add a distance-id pair to the heap unless the distance is too large. - * - * Compared to the super.add() method, this often saves the pair construction. - * - * @param distance Distance value - * @param id ID number - */ - void add(D distance, DBIDRef id); - - /** - * Current size of heap. - * - * @return Heap size - */ - int size(); - - /** - * Test if the heap is empty. - * - * @return true when empty. - */ - boolean isEmpty(); - - /** - * Clear the heap. - */ - void clear(); - - /** - * Poll the <em>largest</em> element from the heap. - * - * This is in descending order because of the heap structure. For a convenient - * way to serialize the heap into a list that you can iterate in ascending - * order, see {@link #toKNNList()}. - * - * @return largest element - */ - DistanceDBIDPair<D> poll(); - - /** - * Peek at the <em>largest</em> element in the heap. - * - * @return The current largest element. - */ - DistanceDBIDPair<D> peek(); -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/KNNResult.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/KNNResult.java deleted file mode 100644 index 785e5b8a..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/KNNResult.java +++ /dev/null @@ -1,91 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distanceresultlist; - -/* - 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.database.ids.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; - -/** - * Interface for kNN results. - * - * To iterate over the results, use the following code: - * - * <pre> - * {@code - * for (DistanceDBIDResultIter<D> iter = result.iter(); iter.valid(); iter.advance()) { - * // You can get the distance via: iter.getDistance(); - * // Or use iter just like any other DBIDRef - * } - * } - * </pre> - * - * If you are only interested in the IDs of the objects, the following is also - * sufficient: - * - * <pre> - * {@code - * for (DBIDIter<D> iter = result.iter(); iter.valid(); iter.advance()) { - * // Use iter just like any other DBIDRef - * } - * } - * </pre> - * - * @author Erich Schubert - * - * @apiviz.landmark - * - * @apiviz.composedOf DistanceDBIDPair - * @apiviz.has DistanceDBIDResultIter - * - * @param <D> Distance type - */ -public interface KNNResult<D extends Distance<D>> extends DistanceDBIDResult<D> { - /** - * Size - */ - @Override - public int size(); - - /** - * Get the K parameter (note: this may be less than the size of the list!) - * - * @return K - */ - public int getK(); - - /** - * Direct object access. - * - * @param index - */ - @Override - public DistanceDBIDPair<D> get(int index); - - /** - * Get the distance to the k nearest neighbor, or maxdist otherwise. - * - * @return Maximum distance - */ - public D getKNNDistance(); -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/KNNUtil.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/KNNUtil.java deleted file mode 100644 index fa658941..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/KNNUtil.java +++ /dev/null @@ -1,372 +0,0 @@ -package de.lmu.ifi.dbs.elki.distance.distanceresultlist; - -/* - 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 java.util.AbstractList; -import java.util.Iterator; -import java.util.List; - -import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; -import de.lmu.ifi.dbs.elki.distance.DistanceUtil; -import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Helper classes for kNN results. - * - * @author Erich Schubert - * - * @apiviz.landmark - * - * @apiviz.has KNNResult oneway - - «processes» - * @apiviz.has KNNHeap oneway - - «creates» - * @apiviz.has DistanceView - * @apiviz.has KNNSubList - */ -public final class KNNUtil { - /** - * Fake constructor: do not instantiate. - */ - private KNNUtil() { - // Empty. - } - - /** - * Create an appropriate heap for the distance function. - * - * This will use a double heap if appropriate. - * - * @param df Distance function - * @param k K value - * @param <D> distance type - * @return New heap of size k, appropriate for this distance function. - */ - @SuppressWarnings("unchecked") - public static <D extends Distance<D>> KNNHeap<D> newHeap(DistanceFunction<?, D> df, int k) { - if (DistanceUtil.isDoubleDistanceFunction(df)) { - return (KNNHeap<D>) new DoubleDistanceKNNHeap(k); - } - return new GenericKNNHeap<D>(k); - } - - /** - * Create an appropriate heap for the distance function. - * - * This will use a double heap if appropriate. - * - * @param df Distance function - * @param k K value - * @param <D> distance type - * @return New heap of size k, appropriate for this distance function. - */ - @SuppressWarnings("unchecked") - public static <D extends Distance<D>> KNNHeap<D> newHeap(DistanceQuery<?, D> df, int k) { - if (DistanceUtil.isDoubleDistanceFunction(df)) { - return (KNNHeap<D>) new DoubleDistanceKNNHeap(k); - } - return new GenericKNNHeap<D>(k); - } - - /** - * Create an appropriate heap for the distance function. - * - * This will use a double heap if appropriate. - * - * @param factory distance prototype - * @param k K value - * @param <D> distance type - * @return New heap of size k, appropriate for this distance type. - */ - @SuppressWarnings("unchecked") - public static <D extends Distance<D>> KNNHeap<D> newHeap(D factory, int k) { - if (factory instanceof DoubleDistance) { - return (KNNHeap<D>) new DoubleDistanceKNNHeap(k); - } - return new GenericKNNHeap<D>(k); - } - - /** - * Build a new heap from a given list. - * - * @param exist Existing result - * @param <D> Distance type - * @return New heap - */ - @SuppressWarnings("unchecked") - public static <D extends Distance<D>> KNNHeap<D> newHeap(KNNResult<D> exist) { - if (exist instanceof DoubleDistanceKNNList) { - DoubleDistanceKNNHeap heap = new DoubleDistanceKNNHeap(exist.getK()); - // Insert backwards, as this will produce a proper heap - for (int i = exist.size() - 1; i >= 0; i--) { - heap.add((DoubleDistanceDBIDPair) exist.get(i)); - } - return (KNNHeap<D>) heap; - } else { - GenericKNNHeap<D> heap = new GenericKNNHeap<D>(exist.getK()); - // Insert backwards, as this will produce a proper heap - for (int i = exist.size() - 1; i >= 0; i--) { - heap.add(exist.get(i)); - } - return heap; - } - } - - /** - * Sublist of an existing result to contain only the first k elements. - * - * @author Erich Schubert - * - * @param <D> Distance - */ - protected static class KNNSubList<D extends Distance<D>> implements KNNResult<D> { - /** - * Parameter k. - */ - private final int k; - - /** - * Actual size, including ties. - */ - private final int size; - - /** - * Wrapped inner result. - */ - private final KNNResult<D> inner; - - /** - * Constructor. - * - * @param inner Inner instance - * @param k k value - */ - public KNNSubList(KNNResult<D> inner, int k) { - this.inner = inner; - this.k = k; - // Compute list size - // TODO: optimize for double distances. - { - DistanceDBIDPair<D> dist = inner.get(k); - int i = k; - while (i + 1 < inner.size()) { - if (dist.compareByDistance(inner.get(i + 1)) < 0) { - break; - } - i++; - } - size = i; - } - } - - @Override - public int getK() { - return k; - } - - @Override - public DistanceDBIDPair<D> get(int index) { - assert (index < size) : "Access beyond design size of list."; - return inner.get(index); - } - - @Override - public D getKNNDistance() { - return inner.get(k).getDistance(); - } - - @Override - public DistanceDBIDResultIter<D> iter() { - return new Itr(); - } - - @Override - public boolean contains(DBIDRef o) { - for (DBIDIter iter = iter(); iter.valid(); iter.advance()) { - if (DBIDUtil.equal(iter, o)) { - return true; - } - } - return false; - } - - @Override - public boolean isEmpty() { - return size == 0; - } - - @Override - public int size() { - return size; - } - - /** - * Iterator for the sublist. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - private class Itr implements DistanceDBIDResultIter<D> { - /** - * Current position. - */ - private int pos = 0; - - @Override - public boolean valid() { - return pos < size; - } - - @Override - public void advance() { - pos++; - } - - @Override - public D getDistance() { - return inner.get(pos).getDistance(); - } - - @Override - public DistanceDBIDPair<D> getDistancePair() { - return inner.get(pos); - } - - @Override - public int internalGetIndex() { - return inner.get(pos).internalGetIndex(); - } - } - } - - /** - * Proxy iterator for accessing DBIDs. - * - * @author Erich Schubert - */ - protected static class DistanceItr<D extends Distance<D>> implements Iterator<D> { - /** - * The real iterator. - */ - DistanceDBIDResultIter<D> itr; - - /** - * Constructor. - * - * @param distanceDBIDResultIter Iterator - */ - protected DistanceItr(DistanceDBIDResultIter<D> distanceDBIDResultIter) { - super(); - this.itr = distanceDBIDResultIter; - } - - @Override - public boolean hasNext() { - return itr.valid(); - } - - @Override - public D next() { - D dist = itr.getDistance(); - itr.advance(); - return dist; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - } - - /** - * A view on the Distances of the result. - * - * @author Erich Schubert - * - * @apiviz.composedOf DistanceItr - */ - protected static class DistanceView<D extends Distance<D>> extends AbstractList<D> implements List<D> { - /** - * The true list. - */ - final KNNResult<D> parent; - - /** - * Constructor. - * - * @param parent Owner - */ - public DistanceView(KNNResult<D> parent) { - super(); - this.parent = parent; - } - - @Override - public D get(int i) { - return parent.get(i).getDistance(); - } - - @Override - public Iterator<D> iterator() { - return new DistanceItr<D>(parent.iter()); - } - - @Override - public int size() { - return parent.size(); - } - } - - /** - * View as list of distances. - * - * @param list Result to proxy - * @param <D> distance type - * @return List of distances view - */ - public static <D extends Distance<D>> List<D> asDistanceList(KNNResult<D> list) { - return new DistanceView<D>(list); - } - - /** - * Get a subset of the KNN result. - * - * @param list Existing list - * @param k k - * @param <D> distance type - * @return Subset - */ - public static <D extends Distance<D>> KNNResult<D> subList(KNNResult<D> list, int k) { - if (k >= list.size()) { - return list; - } - return new KNNSubList<D>(list, k); - } -} diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/package-info.java index 3d2a4b3b..e96621b5 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/package-info.java @@ -1,38 +1,11 @@ /** * <p>Classes for building and storing the results of distance-based queries</p> - * - * <p>The classes in this package essentially form three groups: - * <ol> - * <li>{@link de.lmu.ifi.dbs.elki.distance.distanceresultlist.KNNHeap} for <b>building kNN results</b>. - * It allows adding new candidates (and loses old candidates automatically), but it is not iterable.<br /> - * To get an instance, use {@link de.lmu.ifi.dbs.elki.distance.distanceresultlist.KNNUtil#newHeap}! - * </li> - * <li>{@link de.lmu.ifi.dbs.elki.distance.distanceresultlist.KNNResult} is the <b>final kNN result</b> - * obtained by serializing a heap via {@link de.lmu.ifi.dbs.elki.distance.distanceresultlist.KNNHeap#toKNNList}. - * It is iterable and totally ordered, but can no longer be modified (unless you call - * {@link de.lmu.ifi.dbs.elki.distance.distanceresultlist.KNNUtil#newHeap}!</li> - * <li>{@link de.lmu.ifi.dbs.elki.distance.distanceresultlist.GenericDistanceDBIDList} and the optimized - * counterpart {@link de.lmu.ifi.dbs.elki.distance.distanceresultlist.DoubleDistanceDBIDList}, are - * <b>modifiable, but not necessarily sorted</b> lists of neighbors, useful for example for range queries.</li> - * </ol> - * </p> - * - * <p>Try to choose the most appropriate one! Heaps are optimized for updates but bad for reading, - * KNNResult is optimized for reading but unmodifiable, and the lists are easy to modify, - * but less efficient than heaps.</p> - * - * @apiviz.exclude java.util.* - * @apiviz.exclude elki.database.query.* - * @apiviz.exclude elki.database.ids.DBIDIter - * @apiviz.exclude elki.database.ids.DBIDs - * @apiviz.exclude KNNUtil.DistanceItr - * @apiviz.exclude DoubleDistance */ /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/AbstractDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/AbstractDistance.java index 3e5e86af..c0573ae5 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/AbstractDistance.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/AbstractDistance.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancevalue; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/BitDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/BitDistance.java index 9c81188f..026e90aa 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/BitDistance.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/BitDistance.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancevalue; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -84,16 +84,6 @@ public class BitDistance extends NumberDistance<BitDistance, Bit> { return new BitDistance(val > 0); } - @Override - public BitDistance plus(BitDistance distance) { - return new BitDistance(this.bitValue() || distance.bitValue()); - } - - @Override - public BitDistance minus(BitDistance distance) { - return new BitDistance(this.bitValue() ^ distance.bitValue()); - } - /** * Returns the value of this BitDistance as a boolean. * diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/CorrelationDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/CorrelationDistance.java index 080f13c9..fc288809 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/CorrelationDistance.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/CorrelationDistance.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancevalue; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/Distance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/Distance.java index 73e11fa6..40dff25d 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/Distance.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/Distance.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancevalue; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -41,23 +41,6 @@ import java.io.Externalizable; */ public interface Distance<D extends Distance<D>> extends Comparable<D>, Externalizable { /** - * Returns a new distance as sum of this distance and the given distance. - * - * @param distance the distance to be added to this distance - * @return a new distance as sum of this distance and the given distance - */ - D plus(D distance); - - /** - * Returns a new Distance by subtracting the given distance from this - * distance. - * - * @param distance the distance to be subtracted from this distance - * @return a new Distance by subtracting the given distance from this distance - */ - D minus(D distance); - - /** * Any implementing class should implement a proper toString-method for * printing the result-values. * diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/DoubleDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/DoubleDistance.java index acf72c8d..4126374d 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/DoubleDistance.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/DoubleDistance.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancevalue; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -88,40 +88,6 @@ public class DoubleDistance extends NumberDistance<DoubleDistance, Double> { return new DoubleDistance(val); } - @Override - public DoubleDistance plus(DoubleDistance distance) { - return new DoubleDistance(this.value + distance.value); - } - - @Override - public DoubleDistance minus(DoubleDistance distance) { - return new DoubleDistance(this.value - distance.value); - } - - /** - * Returns a new distance as the product of this distance and the given - * distance. - * - * @param distance the distance to be multiplied with this distance - * @return a new distance as the product of this distance and the given - * distance - */ - public DoubleDistance times(DoubleDistance distance) { - return new DoubleDistance(this.value * distance.value); - } - - /** - * Returns a new distance as the product of this distance and the given double - * value. - * - * @param lambda the double value this distance should be multiplied with - * @return a new distance as the product of this distance and the given double - * value - */ - public DoubleDistance times(double lambda) { - return new DoubleDistance(this.value * lambda); - } - /** * Writes the double value of this DoubleDistance to the specified stream. */ @@ -226,7 +192,7 @@ public class DoubleDistance extends NumberDistance<DoubleDistance, Double> { @Override public String toString() { - return FormatUtil.NF8.format(value); + return FormatUtil.NF.format(value); } @Override diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/FloatDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/FloatDistance.java index 2e88b147..f72d5c1b 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/FloatDistance.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/FloatDistance.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancevalue; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -88,40 +88,6 @@ public class FloatDistance extends NumberDistance<FloatDistance, Float> { return new FloatDistance((float) val); } - @Override - public FloatDistance plus(FloatDistance distance) { - return new FloatDistance(value + distance.value); - } - - @Override - public FloatDistance minus(FloatDistance distance) { - return new FloatDistance(value - distance.value); - } - - /** - * Returns a new distance as the product of this distance and the given - * distance. - * - * @param distance the distance to be multiplied with this distance - * @return a new distance as the product of this distance and the given - * distance - */ - public FloatDistance times(FloatDistance distance) { - return new FloatDistance(value * distance.value); - } - - /** - * Returns a new distance as the product of this distance and the given float - * value. - * - * @param lambda the float value this distance should be multiplied with - * @return a new distance as the product of this distance and the given double - * value - */ - public FloatDistance times(float lambda) { - return new FloatDistance(value * lambda); - } - /** * Writes the float value of this FloatDistance to the specified stream. */ @@ -232,7 +198,7 @@ public class FloatDistance extends NumberDistance<FloatDistance, Float> { @Override public String toString() { - return FormatUtil.NF8.format(value); + return FormatUtil.NF.format(value); } @Override diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/IntegerDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/IntegerDistance.java index d776b3ae..0e206f88 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/IntegerDistance.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/IntegerDistance.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancevalue; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -73,16 +73,6 @@ public class IntegerDistance extends NumberDistance<IntegerDistance, Integer> { return new IntegerDistance((int) val); } - @Override - public IntegerDistance minus(IntegerDistance distance) { - return new IntegerDistance(this.value - distance.value); - } - - @Override - public IntegerDistance plus(IntegerDistance distance) { - return new IntegerDistance(this.value + distance.value); - } - /** * Writes the integer value of this IntegerDistance to the specified stream. */ diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/NumberDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/NumberDistance.java index 9a915c2b..92d2f4ec 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/NumberDistance.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/NumberDistance.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancevalue; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/PCACorrelationDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/PCACorrelationDistance.java index 79f27055..69087d59 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/PCACorrelationDistance.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/PCACorrelationDistance.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancevalue; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -126,16 +126,6 @@ public class PCACorrelationDistance extends CorrelationDistance<PCACorrelationDi } @Override - public PCACorrelationDistance plus(PCACorrelationDistance distance) { - return new PCACorrelationDistance(this.correlationValue + distance.getCorrelationValue(), this.euclideanValue + distance.getEuclideanValue()); - } - - @Override - public PCACorrelationDistance minus(PCACorrelationDistance distance) { - return new PCACorrelationDistance(this.correlationValue - distance.getCorrelationValue(), this.euclideanValue - distance.getEuclideanValue()); - } - - @Override public boolean isInfiniteDistance() { return correlationValue == Integer.MAX_VALUE || euclideanValue == Double.POSITIVE_INFINITY; } diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/PreferenceVectorBasedCorrelationDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/PreferenceVectorBasedCorrelationDistance.java index a5617372..0c82e6b5 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/PreferenceVectorBasedCorrelationDistance.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/PreferenceVectorBasedCorrelationDistance.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancevalue; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -105,42 +105,6 @@ public class PreferenceVectorBasedCorrelationDistance extends CorrelationDistanc } /** - * @throws IllegalArgumentException if the dimensionality values and common - * preference vectors of this distance and the specified distance are - * not equal - */ - @Override - public PreferenceVectorBasedCorrelationDistance plus(PreferenceVectorBasedCorrelationDistance distance) { - if(this.dimensionality != distance.dimensionality) { - throw new IllegalArgumentException("The dimensionality values of this distance " + "and the specified distance need to be equal.\n" + "this.dimensionality " + this.dimensionality + "\n" + "distance.dimensionality " + distance.dimensionality + "\n"); - } - - if(!this.commonPreferenceVector.equals(distance.commonPreferenceVector)) { - throw new IllegalArgumentException("The common preference vectors of this distance " + "and the specified distance need to be equal.\n" + "this.commonPreferenceVector " + this.commonPreferenceVector + "\n" + "distance.commonPreferenceVector " + distance.commonPreferenceVector + "\n"); - } - - return new PreferenceVectorBasedCorrelationDistance(dimensionality, getCorrelationValue() + distance.getCorrelationValue(), getEuclideanValue() + distance.getEuclideanValue(), (BitSet) commonPreferenceVector.clone()); - } - - /** - * @throws IllegalArgumentException if the dimensionality values and common - * preference vectors of this distance and the specified distance are - * not equal - */ - @Override - public PreferenceVectorBasedCorrelationDistance minus(PreferenceVectorBasedCorrelationDistance distance) { - if(this.dimensionality != distance.dimensionality) { - throw new IllegalArgumentException("The dimensionality values of this distance " + "and the specified distance need to be equal.\n" + "this.dimensionality " + this.dimensionality + "\n" + "distance.dimensionality " + distance.dimensionality + "\n"); - } - - if(!this.commonPreferenceVector.equals(distance.commonPreferenceVector)) { - throw new IllegalArgumentException("The common preference vectors of this distance " + "and the specified distance need to be equal.\n" + "this.commonPreferenceVector " + this.commonPreferenceVector + "\n" + "distance.commonPreferenceVector " + distance.commonPreferenceVector + "\n"); - } - - return new PreferenceVectorBasedCorrelationDistance(dimensionality, getCorrelationValue() - distance.getCorrelationValue(), getEuclideanValue() - distance.getEuclideanValue(), (BitSet) commonPreferenceVector.clone()); - } - - /** * Checks if the dimensionality values of this distance and the specified * distance are equal. If the check fails an IllegalArgumentException is * thrown, otherwise diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/SubspaceDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/SubspaceDistance.java index 094961b4..bc29b382 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/SubspaceDistance.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/SubspaceDistance.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancevalue; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -88,16 +88,6 @@ public class SubspaceDistance extends AbstractDistance<SubspaceDistance> { this.affineDistance = affineDistance; } - @Override - public SubspaceDistance plus(SubspaceDistance distance) { - return new SubspaceDistance(this.subspaceDistance + distance.subspaceDistance, this.affineDistance + distance.affineDistance); - } - - @Override - public SubspaceDistance minus(SubspaceDistance distance) { - return new SubspaceDistance(this.subspaceDistance - distance.subspaceDistance, this.affineDistance - distance.affineDistance); - } - /** * Returns a string representation of this SubspaceDistance. * diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/package-info.java index f302b854..ab0fdd9f 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/package-info.java @@ -13,7 +13,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/package-info.java index 801d4314..744c74e1 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/distance/package-info.java @@ -7,7 +7,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractDBIDSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractDBIDSimilarityFunction.java index 163438ce..22790a01 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractDBIDSimilarityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractDBIDSimilarityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractIndexBasedSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractIndexBasedSimilarityFunction.java index 039f7f2b..2147bbff 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractIndexBasedSimilarityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractIndexBasedSimilarityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -141,7 +141,7 @@ public abstract class AbstractIndexBasedSimilarityFunction<O, I extends Index, R * @param defaultClass Default class */ protected void configIndexFactory(Parameterization config, final Class<?> restrictionClass, final Class<?> defaultClass) { - final ObjectParameter<F> param = new ObjectParameter<F>(INDEX_ID, restrictionClass, defaultClass); + final ObjectParameter<F> param = new ObjectParameter<>(INDEX_ID, restrictionClass, defaultClass); if(config.grab(param)) { factory = param.instantiateClass(config); } diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractPrimitiveSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractPrimitiveSimilarityFunction.java index c408d1bb..2a9c2f88 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractPrimitiveSimilarityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractPrimitiveSimilarityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -34,6 +34,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * * @author Arthur Zimek * + * @apiviz.excludeSubtypes + * * @param <O> object type * @param <D> distance type */ @@ -59,6 +61,6 @@ public abstract class AbstractPrimitiveSimilarityFunction<O, D extends Distance< @Override public <T extends O> SimilarityQuery<T, D> instantiate(Relation<T> relation) { - return new PrimitiveSimilarityQuery<T, D>(relation, this); + return new PrimitiveSimilarityQuery<>(relation, this); } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/DBIDSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/DBIDSimilarityFunction.java index e7316115..7b6eef34 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/DBIDSimilarityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/DBIDSimilarityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/FractionalSharedNearestNeighborSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/FractionalSharedNearestNeighborSimilarityFunction.java index a28790b9..2e0dd52d 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/FractionalSharedNearestNeighborSimilarityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/FractionalSharedNearestNeighborSimilarityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -40,14 +40,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz * * @author Arthur Zimek * - * @apiviz.has - * de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborIndex - * .Factory - * @apiviz.uses Instance oneway - - «create» + * @apiviz.has de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborIndex.Factory + * @apiviz.has Instance oneway - - «create» * * @param <O> object type */ -// todo arthur comment class public class FractionalSharedNearestNeighborSimilarityFunction<O> extends AbstractIndexBasedSimilarityFunction<O, SharedNearestNeighborIndex<O>, ArrayDBIDs, DoubleDistance> implements NormalizedSimilarityFunction<O, DoubleDistance> { /** * Constructor. @@ -62,7 +59,7 @@ public class FractionalSharedNearestNeighborSimilarityFunction<O> extends Abstra @Override public <T extends O> Instance<T> instantiate(Relation<T> database) { SharedNearestNeighborIndex<O> indexi = indexFactory.instantiate((Relation<O>) database); - return (Instance<T>) new Instance<O>((Relation<O>) database, indexi); + return (Instance<T>) new Instance<>((Relation<O>) database, indexi); } /** @@ -96,17 +93,15 @@ public class FractionalSharedNearestNeighborSimilarityFunction<O> extends Abstra int intersection = 0; DBIDIter iter1 = neighbors1.iter(); DBIDIter iter2 = neighbors2.iter(); - while(iter1.valid() && iter2.valid()) { + while (iter1.valid() && iter2.valid()) { final int comp = DBIDUtil.compare(iter1, iter2); - if(comp == 0) { + if (comp == 0) { intersection++; iter1.advance(); iter2.advance(); - } - else if(comp < 0) { + } else if (comp < 0) { iter1.advance(); - } - else // iter2 < iter1 + } else // iter2 < iter1 { iter2.advance(); } @@ -151,7 +146,7 @@ public class FractionalSharedNearestNeighborSimilarityFunction<O> extends Abstra @Override protected FractionalSharedNearestNeighborSimilarityFunction<O> makeInstance() { - return new FractionalSharedNearestNeighborSimilarityFunction<O>(factory); + return new FractionalSharedNearestNeighborSimilarityFunction<>(factory); } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/IndexBasedSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/IndexBasedSimilarityFunction.java index 29ae9ce3..33192e38 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/IndexBasedSimilarityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/IndexBasedSimilarityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -33,6 +33,7 @@ import de.lmu.ifi.dbs.elki.index.Index; * * @author Erich Schubert * + * @apiviz.has Instance oneway - - «create» * @apiviz.landmark * * @param <O> Object type diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/InvertedDistanceSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/InvertedDistanceSimilarityFunction.java index 2a97a5a3..9c974f17 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/InvertedDistanceSimilarityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/InvertedDistanceSimilarityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -46,7 +46,7 @@ public class InvertedDistanceSimilarityFunction<O> extends AbstractPrimitiveSimi * </p> * <p> * Default value: - * {@link de.lmu.ifi.dbs.elki.distance.distancefunction.EuclideanDistanceFunction} + * {@link de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction} * </p> */ public static final OptionID DISTANCE_FUNCTION_ID = new OptionID("adapter.distancefunction", "Distance function to derive the similarity between database objects from."); diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski1SimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski1SimilarityFunction.java new file mode 100644 index 00000000..462279d5 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski1SimilarityFunction.java @@ -0,0 +1,110 @@ +package de.lmu.ifi.dbs.elki.distance.similarityfunction; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2013 + 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.TypeUtil; +import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Kulczynski similarity 1. + * + * Reference: + * <p> + * M.-M. Deza and E. Deza<br /> + * Dictionary of distances + * </p> + * + * @author Erich Schubert + */ +@Reference(authors = "M.-M. Deza and E. Deza", title = "Dictionary of distances", booktitle = "Dictionary of distances") +public class Kulczynski1SimilarityFunction extends AbstractPrimitiveSimilarityFunction<NumberVector<?>, DoubleDistance> { + /** + * Static instance. + */ + public static final Kulczynski1SimilarityFunction STATIC = new Kulczynski1SimilarityFunction(); + + /** + * Constructor. + * + * @deprecated Use {@link #STATIC} instance instead. + */ + @Deprecated + public Kulczynski1SimilarityFunction() { + super(); + } + + @Override + public DoubleDistance getDistanceFactory() { + return DoubleDistance.FACTORY; + } + + @Override + public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { + return TypeUtil.NUMBER_VECTOR_FIELD; + } + + @Override + public DoubleDistance similarity(NumberVector<?> o1, NumberVector<?> o2) { + return new DoubleDistance(doubleSimilarity(o1, o2)); + } + + /** + * Compute the similarity. + * + * @param v1 First vector + * @param v2 Second vector + * @return Similarity + */ + public double doubleSimilarity(NumberVector<?> v1, NumberVector<?> v2) { + final int dim1 = v1.getDimensionality(); + if (dim1 != v2.getDimensionality()) { + throw new IllegalArgumentException("Different dimensionality of FeatureVectors" + "\n first argument: " + v1.toString() + "\n second argument: " + v2.toString() + "\n" + v1.getDimensionality() + "!=" + v2.getDimensionality()); + } + double sumdiff = 0., summin = 0.; + for (int i = 0; i < dim1; i++) { + double xi = v1.doubleValue(i), yi = v2.doubleValue(i); + sumdiff += Math.abs(xi - yi); + summin += Math.min(xi, yi); + } + return summin / sumdiff; + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected Kulczynski1SimilarityFunction makeInstance() { + return Kulczynski1SimilarityFunction.STATIC; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski2SimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski2SimilarityFunction.java new file mode 100644 index 00000000..a59010b8 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski2SimilarityFunction.java @@ -0,0 +1,113 @@ +package de.lmu.ifi.dbs.elki.distance.similarityfunction; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2013 + 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.TypeUtil; +import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; + +/** + * Kulczynski similarity 2. + * + * Reference: + * <p> + * M.-M. Deza and E. Deza<br /> + * Dictionary of distances + * </p> + * + * TODO: add an optimized version for binary data. + * + * @author Erich Schubert + */ +@Reference(authors = "M.-M. Deza and E. Deza", title = "Dictionary of distances", booktitle = "Dictionary of distances") +public class Kulczynski2SimilarityFunction extends AbstractPrimitiveSimilarityFunction<NumberVector<?>, DoubleDistance> { + /** + * Static instance. + */ + public static final Kulczynski2SimilarityFunction STATIC_CONTINUOUS = new Kulczynski2SimilarityFunction(); + + /** + * Constructor. + * + * @deprecated Use {@link #STATIC_CONTINUOUS} instance instead. + */ + @Deprecated + public Kulczynski2SimilarityFunction() { + super(); + } + + @Override + public DoubleDistance getDistanceFactory() { + return DoubleDistance.FACTORY; + } + + @Override + public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { + return TypeUtil.NUMBER_VECTOR_FIELD; + } + + @Override + public DoubleDistance similarity(NumberVector<?> o1, NumberVector<?> o2) { + return new DoubleDistance(doubleSimilarity(o1, o2)); + } + + /** + * Compute the similarity. + * + * @param v1 First vector + * @param v2 Second vector + * @return Similarity + */ + public double doubleSimilarity(NumberVector<?> v1, NumberVector<?> v2) { + final int dim1 = v1.getDimensionality(); + if (dim1 != v2.getDimensionality()) { + throw new IllegalArgumentException("Different dimensionality of FeatureVectors" + "\n first argument: " + v1.toString() + "\n second argument: " + v2.toString() + "\n" + v1.getDimensionality() + "!=" + v2.getDimensionality()); + } + double sumx = 0., sumy = 0., summin = 0.; + for (int i = 0; i < dim1; i++) { + double xi = v1.doubleValue(i), yi = v2.doubleValue(i); + sumx += xi; + sumy += yi; + summin += Math.min(xi, yi); + } + return dim1 * .5 * (dim1 / sumx + dim1 / sumy) * summin; + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected Kulczynski2SimilarityFunction makeInstance() { + return Kulczynski2SimilarityFunction.STATIC_CONTINUOUS; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedPrimitiveSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedPrimitiveSimilarityFunction.java index fc86a3bc..6e8bd76a 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedPrimitiveSimilarityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedPrimitiveSimilarityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedSimilarityFunction.java index b2be1a56..dcfd8e74 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedSimilarityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedSimilarityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveSimilarityFunction.java index b5642d0c..d4d84734 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveSimilarityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveSimilarityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -33,6 +33,7 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @author Elke Achtert * * @apiviz.landmark + * @apiviz.excludeSubtypes * * @param <O> object type * @param <D> distance type diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SharedNearestNeighborSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SharedNearestNeighborSimilarityFunction.java index 3e757778..5faba431 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SharedNearestNeighborSimilarityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SharedNearestNeighborSimilarityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -41,7 +41,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz * @author Arthur Zimek * * @apiviz.has de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborIndex.Factory - * @apiviz.uses Instance oneway - - «create» + * @apiviz.has Instance oneway - - «create» * * @param <O> object type */ @@ -94,7 +94,7 @@ public class SharedNearestNeighborSimilarityFunction<O> extends AbstractIndexBas @Override public <T extends O> Instance<T> instantiate(Relation<T> database) { SharedNearestNeighborIndex<O> indexi = indexFactory.instantiate((Relation<O>) database); - return (Instance<T>) new Instance<O>((Relation<O>) database, indexi); + return (Instance<T>) new Instance<>((Relation<O>) database, indexi); } /** @@ -148,7 +148,7 @@ public class SharedNearestNeighborSimilarityFunction<O> extends AbstractIndexBas @Override protected SharedNearestNeighborSimilarityFunction<O> makeInstance() { - return new SharedNearestNeighborSimilarityFunction<O>(factory); + return new SharedNearestNeighborSimilarityFunction<>(factory); } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SimilarityFunction.java index d8324a80..0e3f4ce6 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SimilarityFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SimilarityFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/FooKernelFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/FooKernelFunction.java index be9ba959..d56b3f04 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/FooKernelFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/FooKernelFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -107,7 +107,7 @@ public class FooKernelFunction extends AbstractPrimitiveDistanceFunction<NumberV @Override public <T extends NumberVector<?>> DistanceSimilarityQuery<T, DoubleDistance> instantiate(Relation<T> database) { - return new PrimitiveDistanceSimilarityQuery<T, DoubleDistance>(database, this, this); + return new PrimitiveDistanceSimilarityQuery<>(database, this, this); } /** diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/KernelMatrix.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/KernelMatrix.java index 50dd0b4f..ed3731ba 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/KernelMatrix.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/KernelMatrix.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/LinearKernelFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/LinearKernelFunction.java index ffd2d0e3..0ae44b29 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/LinearKernelFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/LinearKernelFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -92,6 +92,6 @@ public class LinearKernelFunction<O extends NumberVector<?>> extends AbstractPri @Override public <T extends O> DistanceSimilarityQuery<T, DoubleDistance> instantiate(Relation<T> database) { - return new PrimitiveDistanceSimilarityQuery<T, DoubleDistance>(database, this, this); + return new PrimitiveDistanceSimilarityQuery<>(database, this, this); } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/PolynomialKernelFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/PolynomialKernelFunction.java index 1a7f97f5..07963962 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/PolynomialKernelFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/PolynomialKernelFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -107,7 +107,7 @@ public class PolynomialKernelFunction extends AbstractPrimitiveDistanceFunction< @Override public <T extends NumberVector<?>> DistanceSimilarityQuery<T, DoubleDistance> instantiate(Relation<T> database) { - return new PrimitiveDistanceSimilarityQuery<T, DoubleDistance>(database, this, this); + return new PrimitiveDistanceSimilarityQuery<>(database, this, this); } /** diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/package-info.java index 6d2e46fc..ec847f80 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/package-info.java @@ -7,7 +7,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/package-info.java index ba53fba3..6e5ad0e0 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/package-info.java @@ -7,7 +7,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team |