diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/distance/distancefunction/LocallyWeightedDistanceFunction.java')
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/distance/distancefunction/LocallyWeightedDistanceFunction.java | 260 |
1 files changed, 0 insertions, 260 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LocallyWeightedDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LocallyWeightedDistanceFunction.java deleted file mode 100644 index 024240b6..00000000 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LocallyWeightedDistanceFunction.java +++ /dev/null @@ -1,260 +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) 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.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; -import de.lmu.ifi.dbs.elki.index.preprocessed.LocalProjectionIndex; -import de.lmu.ifi.dbs.elki.index.preprocessed.localpca.FilteredLocalPCAIndex; -import de.lmu.ifi.dbs.elki.index.preprocessed.localpca.KNNQueryFilteredPCAIndex; -import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix; -import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; - -/** - * Provides a locally weighted distance function. Computes the quadratic form - * distance between two vectors P and Q as follows: - * - * result = max{dist<sub>P</sub>(P,Q), dist<sub>Q</sub>(Q,P)} where - * dist<sub>X</sub>(X,Y) = (X-Y)*<b>M<sub>X</sub></b>*(X-Y)<b><sup>T</sup></b> - * and <b>M<sub>X</sub></b> is the weight matrix of vector X. - * - * @author Arthur Zimek - * @param <V> the type of NumberVector to compute the distances in between - */ -// FIXME: implements SpatialPrimitiveDistanceFunction<V, DoubleDistance> -public class LocallyWeightedDistanceFunction<V extends NumberVector<?>> extends AbstractIndexBasedDistanceFunction<V, FilteredLocalPCAIndex<V>, DoubleDistance> implements FilteredLocalPCABasedDistanceFunction<V, FilteredLocalPCAIndex<V>, DoubleDistance> { - /** - * Constructor - * - * @param indexFactory Index factory - */ - public LocallyWeightedDistanceFunction(LocalProjectionIndex.Factory<V, FilteredLocalPCAIndex<V>> indexFactory) { - super(indexFactory); - } - - @Override - public DoubleDistance getDistanceFactory() { - return DoubleDistance.FACTORY; - } - - @Override - public boolean isMetric() { - return false; - } - - @Override - public boolean isSymmetric() { - return true; - } - - @Override - public <T extends V> Instance<T> instantiate(Relation<T> database) { - // We can't really avoid these warnings, due to a limitation in Java - // Generics (AFAICT) - @SuppressWarnings("unchecked") - LocalProjectionIndex<T, ?> indexinst = (LocalProjectionIndex<T, ?>) indexFactory.instantiate((Relation<V>) database); - return new Instance<>(database, indexinst, this); - } - - @Override - public boolean equals(Object obj) { - if(obj == null) { - return false; - } - if(!this.getClass().equals(obj.getClass())) { - return false; - } - if(this.indexFactory.equals(((LocallyWeightedDistanceFunction<?>) obj).indexFactory)) { - return false; - } - return true; - } - - /** - * Instance of this distance for a particular database. - * - * @author Erich Schubert - */ - public static class Instance<V extends NumberVector<?>> extends AbstractIndexBasedDistanceFunction.Instance<V, LocalProjectionIndex<V, ?>, DoubleDistance, LocallyWeightedDistanceFunction<? super V>> implements FilteredLocalPCABasedDistanceFunction.Instance<V, LocalProjectionIndex<V, ?>, DoubleDistance> { - /** - * Constructor. - * - * @param database Database - * @param index Index - * @param distanceFunction Distance Function - */ - public Instance(Relation<V> database, LocalProjectionIndex<V, ?> index, LocallyWeightedDistanceFunction<? super V> distanceFunction) { - super(database, index, distanceFunction); - } - - /** - * Computes the distance between two given real vectors according to this - * distance function. - * - * @param id1 first object id - * @param id2 second object id - * @return the distance between two given real vectors according to this - * distance function - */ - @Override - public DoubleDistance distance(DBIDRef id1, DBIDRef id2) { - Matrix m1 = index.getLocalProjection(id1).similarityMatrix(); - Matrix m2 = index.getLocalProjection(id2).similarityMatrix(); - - if(m1 == null || m2 == null) { - return new DoubleDistance(Double.POSITIVE_INFINITY); - } - - V v1 = relation.get(id1); - V v2 = relation.get(id2); - Vector v1Mv2 = v1.getColumnVector().minusEquals(v2.getColumnVector()); - Vector v2Mv1 = v2.getColumnVector().minusEquals(v1.getColumnVector()); - - double dist1 = v1Mv2.transposeTimesTimes(m1, v1Mv2); - double dist2 = v2Mv1.transposeTimesTimes(m2, v2Mv1); - - if(dist1 < 0) { - if(-dist1 < 0.000000000001) { - dist1 = 0; - } - else { - throw new IllegalArgumentException("dist1 " + dist1 + " < 0!"); - } - } - if(dist2 < 0) { - if(-dist2 < 0.000000000001) { - dist2 = 0; - } - else { - throw new IllegalArgumentException("dist2 " + dist2 + " < 0!"); - } - } - - return new DoubleDistance(Math.max(Math.sqrt(dist1), Math.sqrt(dist2))); - } - - // @Override - // TODO: re-enable spatial interfaces - public DoubleDistance minDistBROKEN(SpatialComparable mbr, V v) { - if(mbr.getDimensionality() != v.getDimensionality()) { - throw new IllegalArgumentException("Different dimensionality of objects\n first argument: " + mbr.toString() + "\n second argument: " + v.toString()); - } - - double[] r = new double[v.getDimensionality()]; - for(int d = 0; d < v.getDimensionality(); d++) { - double value = v.doubleValue(d); - if(value < mbr.getMin(d)) { - r[d] = mbr.getMin(d); - } - else if(value > mbr.getMax(d)) { - r[d] = mbr.getMax(d); - } - else { - r[d] = value; - } - } - - Matrix m = null; // index.getLocalProjection(v.getID()).similarityMatrix(); - Vector rv1Mrv2 = v.getColumnVector().minusEquals(new Vector(r)); - double dist = rv1Mrv2.transposeTimesTimes(m, rv1Mrv2); - - return new DoubleDistance(Math.sqrt(dist)); - } - - // TODO: Remove? - // @Override - // public DoubleDistance minDist(SpatialComparable mbr, DBID id) { - // return minDist(mbr, database.get(id)); - // } - - // @Override - // TODO: re-enable spatial interface - public DoubleDistance distance(SpatialComparable mbr1, SpatialComparable mbr2) { - if(mbr1.getDimensionality() != 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 < mbr1.getDimensionality(); d++) { - 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! - m1 = 0; - m2 = 0; - } - double manhattanI = m1 - m2; - sqrDist += manhattanI * manhattanI; - } - return new DoubleDistance(Math.sqrt(sqrDist)); - } - - // @Override - // TODO: re-enable spatial interface - public DoubleDistance centerDistance(SpatialComparable mbr1, SpatialComparable mbr2) { - if(mbr1.getDimensionality() != 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 < mbr1.getDimensionality(); d++) { - final double c1 = .5 * (mbr1.getMin(d) + mbr1.getMax(d)); - final double c2 = .5 * (mbr2.getMin(d) + mbr2.getMax(d)); - final double manhattanI = c1 - c2; - sqrDist += manhattanI * manhattanI; - } - return new DoubleDistance(Math.sqrt(sqrDist)); - } - } - - /** - * Parameterization class. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - public static class Parameterizer<V extends NumberVector<?>> extends AbstractIndexBasedDistanceFunction.Parameterizer<LocalProjectionIndex.Factory<V, FilteredLocalPCAIndex<V>>> { - @Override - protected void makeOptions(Parameterization config) { - super.makeOptions(config); - configIndexFactory(config, LocalProjectionIndex.Factory.class, KNNQueryFilteredPCAIndex.Factory.class); - } - - @Override - protected LocallyWeightedDistanceFunction<V> makeInstance() { - return new LocallyWeightedDistanceFunction<>(factory); - } - } -}
\ No newline at end of file |