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