diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/distance/distancefunction/LPNormDistanceFunction.java')
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/distance/distancefunction/LPNormDistanceFunction.java | 65 |
1 files changed, 61 insertions, 4 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LPNormDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LPNormDistanceFunction.java index d17825e9..134b587f 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LPNormDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LPNormDistanceFunction.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) 2011 + Copyright (C) 2012 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,6 +24,10 @@ 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.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterConstraint; @@ -37,9 +41,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; * * @apiviz.landmark */ -public class LPNormDistanceFunction extends AbstractVectorDoubleDistanceFunction { - // TODO: implement SpatialPrimitiveDoubleDistanceFunction? - +public class LPNormDistanceFunction extends AbstractVectorDoubleDistanceNorm implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?, ?>> { /** * OptionID for the "p" parameter */ @@ -84,6 +86,17 @@ public class LPNormDistanceFunction extends AbstractVectorDoubleDistanceFunction return Math.pow(sqrDist, 1.0 / p); } + @Override + public double doubleNorm(NumberVector<?, ?> v) { + final int dim = v.getDimensionality(); + double sqrDist = 0; + for(int i = 1; i <= dim; i++) { + final double delta = v.doubleValue(i); + sqrDist += Math.pow(delta, p); + } + return Math.pow(sqrDist, 1.0 / p); + } + /** * Get the functions p parameter. * @@ -94,6 +107,45 @@ public class LPNormDistanceFunction extends AbstractVectorDoubleDistanceFunction } @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 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 = 1; 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; + sumDist += Math.pow(manhattanI, p); + } + return Math.pow(sumDist, 1.0 / p); + } + + @Override + public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) { + return new DoubleDistance(doubleMinDist(mbr1, mbr2)); + } + + @Override public boolean isMetric() { return (p >= 1); } @@ -114,6 +166,11 @@ public class LPNormDistanceFunction extends AbstractVectorDoubleDistanceFunction return false; } + @Override + public <T extends NumberVector<?, ?>> SpatialPrimitiveDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) { + return new SpatialPrimitiveDistanceQuery<T, DoubleDistance>(relation, this); + } + /** * Parameterization class. * |