summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LocallyWeightedDistanceFunction.java
diff options
context:
space:
mode:
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.java260
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