diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski')
17 files changed, 742 insertions, 517 deletions
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 index 24dfdc16..a652133c 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/EuclideanDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/EuclideanDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 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.utilities.Alias; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** - * Provides the Euclidean distance for FeatureVectors. + * Euclidean distance for {@link NumberVector}s. * * @author Arthur Zimek */ @@ -41,8 +41,7 @@ public class EuclideanDistanceFunction extends LPIntegerNormDistanceFunction { public static final EuclideanDistanceFunction STATIC = new EuclideanDistanceFunction(); /** - * Provides a Euclidean distance function that can compute the Euclidean - * distance (that is a DoubleDistance) for FeatureVectors. + * Constructor - use {@link #STATIC} instead. * * @deprecated Use static instance! */ @@ -51,7 +50,7 @@ public class EuclideanDistanceFunction extends LPIntegerNormDistanceFunction { super(2); } - private final double doublePreDistance(NumberVector<?> v1, NumberVector<?> v2, int start, int end, double agg) { + private final double preDistance(NumberVector v1, NumberVector v2, int start, int end, double agg) { for(int d = start; d < end; d++) { final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); final double delta = xd - yd; @@ -60,7 +59,7 @@ public class EuclideanDistanceFunction extends LPIntegerNormDistanceFunction { return agg; } - private final double doublePreDistanceVM(NumberVector<?> v, SpatialComparable mbr, int start, int end, double agg) { + private final double preDistanceVM(NumberVector v, SpatialComparable mbr, int start, int end, double agg) { for(int d = start; d < end; d++) { final double value = v.doubleValue(d), min = mbr.getMin(d); double delta = min - value; @@ -74,7 +73,7 @@ public class EuclideanDistanceFunction extends LPIntegerNormDistanceFunction { return agg; } - private final double doublePreDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, int start, int end, double agg) { + private final double preDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, int start, int end, double agg) { for(int d = start; d < end; d++) { double delta = mbr2.getMin(d) - mbr1.getMax(d); if(delta < 0.) { @@ -87,7 +86,7 @@ public class EuclideanDistanceFunction extends LPIntegerNormDistanceFunction { return agg; } - private final double doublePreNorm(NumberVector<?> v, int start, int end, double agg) { + private final double preNorm(NumberVector v, int start, int end, double agg) { for(int d = start; d < end; d++) { final double xd = v.doubleValue(d); agg += xd * xd; @@ -95,7 +94,7 @@ public class EuclideanDistanceFunction extends LPIntegerNormDistanceFunction { return agg; } - private final double doublePreNormMBR(SpatialComparable mbr, int start, int end, double agg) { + private final double preNormMBR(SpatialComparable mbr, int start, int end, double agg) { for(int d = start; d < end; d++) { double delta = mbr.getMin(d); if(delta < 0.) { @@ -109,65 +108,65 @@ public class EuclideanDistanceFunction extends LPIntegerNormDistanceFunction { } @Override - public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + public double distance(NumberVector v1, NumberVector v2) { final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - double agg = doublePreDistance(v1, v2, 0, mindim, 0.); + double agg = preDistance(v1, v2, 0, mindim, 0.); if(dim1 > mindim) { - agg = doublePreNorm(v1, mindim, dim1, agg); + agg = preNorm(v1, mindim, dim1, agg); } else if(dim2 > mindim) { - agg = doublePreNorm(v2, mindim, dim2, agg); + agg = preNorm(v2, mindim, dim2, agg); } return Math.sqrt(agg); } @Override - public double doubleNorm(NumberVector<?> v) { - return Math.sqrt(doublePreNorm(v, 0, v.getDimensionality(), 0.)); + public double norm(NumberVector v) { + return Math.sqrt(preNorm(v, 0, v.getDimensionality(), 0.)); } @Override - public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) { final int dim1 = mbr1.getDimensionality(), dim2 = mbr2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - final NumberVector<?> v1 = (mbr1 instanceof NumberVector) ? (NumberVector<?>) mbr1 : null; - final NumberVector<?> v2 = (mbr2 instanceof NumberVector) ? (NumberVector<?>) mbr2 : null; + final NumberVector v1 = (mbr1 instanceof NumberVector) ? (NumberVector) mbr1 : null; + final NumberVector v2 = (mbr2 instanceof NumberVector) ? (NumberVector) mbr2 : null; double agg = 0.; if(v1 != null) { if(v2 != null) { - agg = doublePreDistance(v1, v2, 0, mindim, agg); + agg = preDistance(v1, v2, 0, mindim, agg); } else { - agg = doublePreDistanceVM(v1, mbr2, 0, mindim, agg); + agg = preDistanceVM(v1, mbr2, 0, mindim, agg); } } else { if(v2 != null) { - agg = doublePreDistanceVM(v2, mbr1, 0, mindim, agg); + agg = preDistanceVM(v2, mbr1, 0, mindim, agg); } else { - agg = doublePreDistanceMBR(mbr1, mbr2, 0, mindim, agg); + agg = preDistanceMBR(mbr1, mbr2, 0, mindim, agg); } } // first object has more dimensions. if(dim1 > mindim) { if(v1 != null) { - agg = doublePreNorm(v1, mindim, dim1, agg); + agg = preNorm(v1, mindim, dim1, agg); } else { - agg = doublePreNormMBR(v1, mindim, dim1, agg); + agg = preNormMBR(v1, mindim, dim1, agg); } } // second object has more dimensions. if(dim2 > mindim) { if(v2 != null) { - agg = doublePreNorm(v2, mindim, dim2, agg); + agg = preNorm(v2, mindim, dim2, agg); } else { - agg = doublePreNormMBR(mbr2, mindim, dim2, agg); + agg = preNormMBR(mbr2, mindim, dim2, agg); } } return Math.sqrt(agg); diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/LPIntegerNormDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/LPIntegerNormDistanceFunction.java index 22ae45b3..b94374ed 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/LPIntegerNormDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/LPIntegerNormDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -32,8 +32,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter; /** - * Provides a LP-Norm for number vectors. Optimized version for integer values - * of p. This will likely not have huge impact, but YMMV. + * LP-Norm for {@link NumberVector}s, optimized version for integer values of p. + * This will likely not have huge impact, but may vary from CPU and virtual + * machine version. * * @author Erich Schubert * @@ -55,7 +56,7 @@ public class LPIntegerNormDistanceFunction extends LPNormDistanceFunction { this.intp = p; } - private final double doublePreDistance(NumberVector<?> v1, NumberVector<?> v2, final int start, final int end, double agg) { + private final double preDistance(NumberVector v1, NumberVector v2, final int start, final int end, double agg) { for(int d = start; d < end; d++) { final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); final double delta = (xd >= yd) ? xd - yd : yd - xd; @@ -64,7 +65,7 @@ public class LPIntegerNormDistanceFunction extends LPNormDistanceFunction { return agg; } - private final double doublePreDistanceVM(NumberVector<?> v, SpatialComparable mbr, final int start, final int end, double agg) { + private final double preDistanceVM(NumberVector v, SpatialComparable mbr, final int start, final int end, double agg) { for(int d = start; d < end; d++) { final double value = v.doubleValue(d), min = mbr.getMin(d); double delta = min - value; @@ -78,7 +79,7 @@ public class LPIntegerNormDistanceFunction extends LPNormDistanceFunction { return agg; } - private final double doublePreDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, final int start, final int end, double agg) { + private final double preDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, final int start, final int end, double agg) { for(int d = start; d < end; d++) { double delta = mbr2.getMin(d) - mbr1.getMax(d); if(delta < 0.) { @@ -91,7 +92,7 @@ public class LPIntegerNormDistanceFunction extends LPNormDistanceFunction { return agg; } - private final double doublePreNorm(NumberVector<?> v, final int start, final int end, double agg) { + private final double preNorm(NumberVector v, final int start, final int end, double agg) { for(int d = start; d < end; d++) { final double xd = v.doubleValue(d); final double delta = xd >= 0. ? xd : -xd; @@ -100,7 +101,7 @@ public class LPIntegerNormDistanceFunction extends LPNormDistanceFunction { return agg; } - private final double doublePreNormMBR(SpatialComparable mbr, final int start, final int end, double agg) { + private final double preNormMBR(SpatialComparable mbr, final int start, final int end, double agg) { for(int d = start; d < end; d++) { double delta = mbr.getMin(d); if(delta < 0.) { @@ -114,65 +115,65 @@ public class LPIntegerNormDistanceFunction extends LPNormDistanceFunction { } @Override - public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + public double distance(NumberVector v1, NumberVector v2) { final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - double agg = doublePreDistance(v1, v2, 0, mindim, 0.); + double agg = preDistance(v1, v2, 0, mindim, 0.); if(dim1 > mindim) { - agg = doublePreNorm(v1, mindim, dim1, agg); + agg = preNorm(v1, mindim, dim1, agg); } else if(dim2 > mindim) { - agg = doublePreNorm(v2, mindim, dim2, agg); + agg = preNorm(v2, mindim, dim2, agg); } return Math.pow(agg, invp); } @Override - public double doubleNorm(NumberVector<?> v) { - return Math.pow(doublePreNorm(v, 0, v.getDimensionality(), 0.), invp); + public double norm(NumberVector v) { + return Math.pow(preNorm(v, 0, v.getDimensionality(), 0.), invp); } @Override - public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) { final int dim1 = mbr1.getDimensionality(), dim2 = mbr2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - final NumberVector<?> v1 = (mbr1 instanceof NumberVector) ? (NumberVector<?>) mbr1 : null; - final NumberVector<?> v2 = (mbr2 instanceof NumberVector) ? (NumberVector<?>) mbr2 : null; + final NumberVector v1 = (mbr1 instanceof NumberVector) ? (NumberVector) mbr1 : null; + final NumberVector v2 = (mbr2 instanceof NumberVector) ? (NumberVector) mbr2 : null; double agg = 0.; if(v1 != null) { if(v2 != null) { - agg = doublePreDistance(v1, v2, 0, mindim, agg); + agg = preDistance(v1, v2, 0, mindim, agg); } else { - agg = doublePreDistanceVM(v1, mbr2, 0, mindim, agg); + agg = preDistanceVM(v1, mbr2, 0, mindim, agg); } } else { if(v2 != null) { - agg = doublePreDistanceVM(v2, mbr1, 0, mindim, agg); + agg = preDistanceVM(v2, mbr1, 0, mindim, agg); } else { - agg = doublePreDistanceMBR(mbr1, mbr2, 0, mindim, agg); + agg = preDistanceMBR(mbr1, mbr2, 0, mindim, agg); } } // first object has more dimensions. if(dim1 > mindim) { if(v1 != null) { - agg = doublePreNorm(v1, mindim, dim1, agg); + agg = preNorm(v1, mindim, dim1, agg); } else { - agg = doublePreNormMBR(v1, mindim, dim1, agg); + agg = preNormMBR(v1, mindim, dim1, agg); } } // second object has more dimensions. if(dim2 > mindim) { if(v2 != null) { - agg = doublePreNorm(v2, mindim, dim2, agg); + agg = preNorm(v2, mindim, dim2, agg); } else { - agg = doublePreNormMBR(mbr2, mindim, dim2, agg); + agg = preNormMBR(mbr2, mindim, dim2, agg); } } return Math.pow(agg, invp); @@ -194,7 +195,7 @@ public class LPIntegerNormDistanceFunction extends LPNormDistanceFunction { @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); - final IntParameter paramP = new IntParameter(P_ID); + final IntParameter paramP = new IntParameter(LPNormDistanceFunction.Parameterizer.P_ID); paramP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT); if(config.grab(paramP)) { p = paramP.getValue(); diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/LPNormDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/LPNormDistanceFunction.java index 42753ac1..e9a79115 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/LPNormDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/LPNormDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,7 +27,7 @@ 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.distancefunction.AbstractSpatialDoubleDistanceNorm; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialNorm; 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; @@ -36,21 +36,16 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; /** - * Provides a LP-Norm for FeatureVectors. + * LP-Norm for {@link NumberVector}s. * * @author Arthur Zimek * * @apiviz.landmark */ @Alias({ "lp", "minkowski", "p", "de.lmu.ifi.dbs.elki.distance.distancefunction.LPNormDistanceFunction" }) -public class LPNormDistanceFunction extends AbstractSpatialDoubleDistanceNorm { +public class LPNormDistanceFunction extends AbstractSpatialNorm { /** - * 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 and its inverse + * p parameter and its inverse. */ protected double p, invp; @@ -75,7 +70,7 @@ public class LPNormDistanceFunction extends AbstractSpatialDoubleDistanceNorm { * @param agg Current aggregate value * @return Aggregated values. */ - private final double doublePreDistance(NumberVector<?> v1, NumberVector<?> v2, final int start, final int end, double agg) { + private final double preDistance(NumberVector v1, NumberVector v2, final int start, final int end, double agg) { for(int d = start; d < end; d++) { final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); final double delta = (xd >= yd) ? xd - yd : yd - xd; @@ -94,7 +89,7 @@ public class LPNormDistanceFunction extends AbstractSpatialDoubleDistanceNorm { * @param agg Current aggregate value * @return Aggregated values. */ - private final double doublePreDistanceVM(NumberVector<?> v, SpatialComparable mbr, final int start, final int end, double agg) { + private final double preDistanceVM(NumberVector v, SpatialComparable mbr, final int start, final int end, double agg) { for(int d = start; d < end; d++) { final double value = v.doubleValue(d), min = mbr.getMin(d); double delta = min - value; @@ -118,7 +113,7 @@ public class LPNormDistanceFunction extends AbstractSpatialDoubleDistanceNorm { * @param agg Current aggregate value * @return Aggregated values. */ - private final double doublePreDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, final int start, final int end, double agg) { + private final double preDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, final int start, final int end, double agg) { for(int d = start; d < end; d++) { double delta = mbr2.getMin(d) - mbr1.getMax(d); if(delta < 0.) { @@ -140,7 +135,7 @@ public class LPNormDistanceFunction extends AbstractSpatialDoubleDistanceNorm { * @param agg Current aggregate value * @return Aggregated values. */ - private final double doublePreNorm(NumberVector<?> v, final int start, final int end, double agg) { + private final double preNorm(NumberVector v, final int start, final int end, double agg) { for(int d = start; d < end; d++) { final double xd = v.doubleValue(d); final double delta = xd >= 0. ? xd : -xd; @@ -158,7 +153,7 @@ public class LPNormDistanceFunction extends AbstractSpatialDoubleDistanceNorm { * @param agg Current aggregate value * @return Aggregated values. */ - private final double doublePreNormMBR(SpatialComparable mbr, final int start, final int end, double agg) { + private final double preNormMBR(SpatialComparable mbr, final int start, final int end, double agg) { for(int d = start; d < end; d++) { double delta = mbr.getMin(d); if(delta < 0.) { @@ -172,65 +167,65 @@ public class LPNormDistanceFunction extends AbstractSpatialDoubleDistanceNorm { } @Override - public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + public double distance(NumberVector v1, NumberVector v2) { final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - double agg = doublePreDistance(v1, v2, 0, mindim, 0.); + double agg = preDistance(v1, v2, 0, mindim, 0.); if(dim1 > mindim) { - agg = doublePreNorm(v1, mindim, dim1, agg); + agg = preNorm(v1, mindim, dim1, agg); } else if(dim2 > mindim) { - agg = doublePreNorm(v2, mindim, dim2, agg); + agg = preNorm(v2, mindim, dim2, agg); } return Math.pow(agg, invp); } @Override - public double doubleNorm(NumberVector<?> v) { - return Math.pow(doublePreNorm(v, 0, v.getDimensionality(), 0.), invp); + public double norm(NumberVector v) { + return Math.pow(preNorm(v, 0, v.getDimensionality(), 0.), invp); } @Override - public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) { final int dim1 = mbr1.getDimensionality(), dim2 = mbr2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - final NumberVector<?> v1 = (mbr1 instanceof NumberVector) ? (NumberVector<?>) mbr1 : null; - final NumberVector<?> v2 = (mbr2 instanceof NumberVector) ? (NumberVector<?>) mbr2 : null; + final NumberVector v1 = (mbr1 instanceof NumberVector) ? (NumberVector) mbr1 : null; + final NumberVector v2 = (mbr2 instanceof NumberVector) ? (NumberVector) mbr2 : null; double agg = 0.; if(v1 != null) { if(v2 != null) { - agg = doublePreDistance(v1, v2, 0, mindim, agg); + agg = preDistance(v1, v2, 0, mindim, agg); } else { - agg = doublePreDistanceVM(v1, mbr2, 0, mindim, agg); + agg = preDistanceVM(v1, mbr2, 0, mindim, agg); } } else { if(v2 != null) { - agg = doublePreDistanceVM(v2, mbr1, 0, mindim, agg); + agg = preDistanceVM(v2, mbr1, 0, mindim, agg); } else { - agg = doublePreDistanceMBR(mbr1, mbr2, 0, mindim, agg); + agg = preDistanceMBR(mbr1, mbr2, 0, mindim, agg); } } // first object has more dimensions. if(dim1 > mindim) { if(v1 != null) { - agg = doublePreNorm(v1, mindim, dim1, agg); + agg = preNorm(v1, mindim, dim1, agg); } else { - agg = doublePreNormMBR(v1, mindim, dim1, agg); + agg = preNormMBR(v1, mindim, dim1, agg); } } // second object has more dimensions. if(dim2 > mindim) { if(v2 != null) { - agg = doublePreNorm(v2, mindim, dim2, agg); + agg = preNorm(v2, mindim, dim2, agg); } else { - agg = doublePreNormMBR(mbr2, mindim, dim2, agg); + agg = preNormMBR(mbr2, mindim, dim2, agg); } } return Math.pow(agg, invp); @@ -267,7 +262,7 @@ public class LPNormDistanceFunction extends AbstractSpatialDoubleDistanceNorm { } @Override - public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { + public SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() { return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH; } @@ -280,6 +275,10 @@ public class LPNormDistanceFunction extends AbstractSpatialDoubleDistanceNorm { */ public static class Parameterizer extends AbstractParameterizer { /** + * OptionID for the "p" parameter + */ + public static final OptionID P_ID = new OptionID("lpnorm.p", "the degree of the L-P-Norm (positive number)"); + /** * The value of p. */ protected double p; diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/ManhattanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/ManhattanDistanceFunction.java index 3d5d061c..01991324 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/ManhattanDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/ManhattanDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,8 +29,7 @@ import de.lmu.ifi.dbs.elki.utilities.Alias; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** - * Manhattan distance function to compute the Manhattan distance for a pair of - * FeatureVectors. + * Manhattan distance for {@link NumberVector}s. * * @author Arthur Zimek */ @@ -42,8 +41,7 @@ public class ManhattanDistanceFunction extends LPIntegerNormDistanceFunction { public static final ManhattanDistanceFunction STATIC = new ManhattanDistanceFunction(); /** - * Provides a Manhattan distance function that can compute the Manhattan - * distance (that is a DoubleDistance) for FeatureVectors. + * Constructor - use {@link #STATIC} instead. * * @deprecated Use static instance! */ @@ -52,8 +50,8 @@ public class ManhattanDistanceFunction extends LPIntegerNormDistanceFunction { super(1); } - private final double doublePreDistance(NumberVector<?> v1, NumberVector<?> v2, int start, int end, double agg) { - for (int d = start; d < end; d++) { + private final double preDistance(NumberVector v1, NumberVector v2, int start, int end, double agg) { + for(int d = start; d < end; d++) { final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); final double delta = (xd >= yd) ? xd - yd : yd - xd; agg += delta; @@ -61,35 +59,35 @@ public class ManhattanDistanceFunction extends LPIntegerNormDistanceFunction { return agg; } - private final double doublePreDistanceVM(NumberVector<?> v, SpatialComparable mbr, int start, int end, double agg) { - for (int d = start; d < end; d++) { + private final double preDistanceVM(NumberVector v, SpatialComparable mbr, int start, int end, double agg) { + for(int d = start; d < end; d++) { final double value = v.doubleValue(d), min = mbr.getMin(d); double delta = min - value; - if (delta < 0.) { + if(delta < 0.) { delta = value - mbr.getMax(d); } - if (delta > 0.) { + if(delta > 0.) { agg += delta; } } return agg; } - private final double doublePreDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, int start, int end, double agg) { - for (int d = start; d < end; d++) { + private final double preDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, int start, int end, double agg) { + for(int d = start; d < end; d++) { double delta = mbr2.getMin(d) - mbr1.getMax(d); - if (delta < 0.) { + if(delta < 0.) { delta = mbr1.getMin(d) - mbr2.getMax(d); } - if (delta > 0.) { + if(delta > 0.) { agg += delta; } } return agg; } - private final double doublePreNorm(NumberVector<?> v, int start, int end, double agg) { - for (int d = start; d < end; d++) { + private final double preNorm(NumberVector v, int start, int end, double agg) { + for(int d = start; d < end; d++) { final double xd = v.doubleValue(d); final double delta = (xd >= 0.) ? xd : -xd; agg += delta; @@ -97,13 +95,13 @@ public class ManhattanDistanceFunction extends LPIntegerNormDistanceFunction { return agg; } - private final double doublePreNormMBR(SpatialComparable mbr, int start, int end, double agg) { - for (int d = start; d < end; d++) { + private final double preNormMBR(SpatialComparable mbr, int start, int end, double agg) { + for(int d = start; d < end; d++) { double delta = mbr.getMin(d); - if (delta < 0.) { + if(delta < 0.) { delta = -mbr.getMax(d); } - if (delta > 0.) { + if(delta > 0.) { agg += delta; } } @@ -111,59 +109,65 @@ public class ManhattanDistanceFunction extends LPIntegerNormDistanceFunction { } @Override - public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + public double distance(NumberVector v1, NumberVector v2) { final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - double agg = doublePreDistance(v1, v2, 0, mindim, 0.); - if (dim1 > mindim) { - agg = doublePreNorm(v1, mindim, dim1, agg); - } else if (dim2 > mindim) { - agg = doublePreNorm(v2, mindim, dim2, agg); + double agg = preDistance(v1, v2, 0, mindim, 0.); + if(dim1 > mindim) { + agg = preNorm(v1, mindim, dim1, agg); + } + else if(dim2 > mindim) { + agg = preNorm(v2, mindim, dim2, agg); } return agg; } @Override - public double doubleNorm(NumberVector<?> v) { - return doublePreNorm(v, 0, v.getDimensionality(), 0.); + public double norm(NumberVector v) { + return preNorm(v, 0, v.getDimensionality(), 0.); } @Override - public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) { final int dim1 = mbr1.getDimensionality(), dim2 = mbr2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - final NumberVector<?> v1 = (mbr1 instanceof NumberVector) ? (NumberVector<?>) mbr1 : null; - final NumberVector<?> v2 = (mbr2 instanceof NumberVector) ? (NumberVector<?>) mbr2 : null; + final NumberVector v1 = (mbr1 instanceof NumberVector) ? (NumberVector) mbr1 : null; + final NumberVector v2 = (mbr2 instanceof NumberVector) ? (NumberVector) mbr2 : null; double agg = 0.; - if (v1 != null) { - if (v2 != null) { - agg = doublePreDistance(v1, v2, 0, mindim, agg); - } else { - agg = doublePreDistanceVM(v1, mbr2, 0, mindim, agg); + if(v1 != null) { + if(v2 != null) { + agg = preDistance(v1, v2, 0, mindim, agg); + } + else { + agg = preDistanceVM(v1, mbr2, 0, mindim, agg); + } + } + else { + if(v2 != null) { + agg = preDistanceVM(v2, mbr1, 0, mindim, agg); } - } else { - if (v2 != null) { - agg = doublePreDistanceVM(v2, mbr1, 0, mindim, agg); - } else { - agg = doublePreDistanceMBR(mbr1, mbr2, 0, mindim, agg); + else { + agg = preDistanceMBR(mbr1, mbr2, 0, mindim, agg); } } // first object has more dimensions. - if (dim1 > mindim) { - if (v1 != null) { - agg = doublePreNorm(v1, mindim, dim1, agg); - } else { - agg = doublePreNormMBR(v1, mindim, dim1, agg); + if(dim1 > mindim) { + if(v1 != null) { + agg = preNorm(v1, mindim, dim1, agg); + } + else { + agg = preNormMBR(v1, mindim, dim1, agg); } } // second object has more dimensions. - if (dim2 > mindim) { - if (v2 != null) { - agg = doublePreNorm(v2, mindim, dim2, agg); - } else { - agg = doublePreNormMBR(mbr2, mindim, dim2, agg); + if(dim2 > mindim) { + if(v2 != null) { + agg = preNorm(v2, mindim, dim2, agg); + } + else { + agg = preNormMBR(mbr2, mindim, dim2, agg); } } return agg; @@ -181,13 +185,13 @@ public class ManhattanDistanceFunction extends LPIntegerNormDistanceFunction { @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); diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/MaximumDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/MaximumDistanceFunction.java index 2cc1b10c..da972b49 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/MaximumDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/MaximumDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,8 +29,7 @@ import de.lmu.ifi.dbs.elki.utilities.Alias; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** - * Maximum distance function to compute the Maximum distance for a pair of - * FeatureVectors. + * Maximum distance for {@link NumberVector}s. * * @author Erich Schubert */ @@ -42,8 +41,7 @@ public class MaximumDistanceFunction extends LPNormDistanceFunction { public static final MaximumDistanceFunction STATIC = new MaximumDistanceFunction(); /** - * Provides a Maximum distance function that can compute the Manhattan - * distance (that is a DoubleDistance) for FeatureVectors. + * Constructor - use {@link #STATIC} instead. * * @deprecated Use static instance! */ @@ -52,62 +50,62 @@ public class MaximumDistanceFunction extends LPNormDistanceFunction { super(Double.POSITIVE_INFINITY); } - private final double doublePreDistance(NumberVector<?> v1, NumberVector<?> v2, int start, int end, double agg) { - for (int d = start; d < end; d++) { + private final double preDistance(NumberVector v1, NumberVector v2, int start, int end, double agg) { + for(int d = start; d < end; d++) { final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); final double delta = (xd >= yd) ? xd - yd : yd - xd; - if (delta > agg) { + if(delta > agg) { agg = delta; } } return agg; } - private final double doublePreDistanceVM(NumberVector<?> v, SpatialComparable mbr, int start, int end, double agg) { - for (int d = start; d < end; d++) { + private final double preDistanceVM(NumberVector v, SpatialComparable mbr, int start, int end, double agg) { + for(int d = start; d < end; d++) { final double value = v.doubleValue(d), min = mbr.getMin(d); double delta = min - value; - if (delta < 0.) { + if(delta < 0.) { delta = value - mbr.getMax(d); } - if (delta > agg) { + if(delta > agg) { agg = delta; } } return agg; } - private final double doublePreDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, int start, int end, double agg) { - for (int d = start; d < end; d++) { + private final double preDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, int start, int end, double agg) { + for(int d = start; d < end; d++) { double delta = mbr2.getMin(d) - mbr1.getMax(d); - if (delta < 0.) { + if(delta < 0.) { delta = mbr1.getMin(d) - mbr2.getMax(d); } - if (delta > agg) { + if(delta > agg) { agg = delta; } } return agg; } - private final double doublePreNorm(NumberVector<?> v, int start, int end, double agg) { - for (int d = start; d < end; d++) { + private final double preNorm(NumberVector v, int start, int end, double agg) { + for(int d = start; d < end; d++) { final double xd = v.doubleValue(d); final double delta = (xd >= 0.) ? xd : -xd; - if (delta > agg) { + if(delta > agg) { agg = delta; } } return agg; } - private final double doublePreNormMBR(SpatialComparable mbr, int start, int end, double agg) { - for (int d = start; d < end; d++) { + private final double preNormMBR(SpatialComparable mbr, int start, int end, double agg) { + for(int d = start; d < end; d++) { double delta = mbr.getMin(d); - if (delta < 0.) { + if(delta < 0.) { delta = -mbr.getMax(d); } - if (delta > agg) { + if(delta > agg) { agg = delta; } } @@ -115,59 +113,65 @@ public class MaximumDistanceFunction extends LPNormDistanceFunction { } @Override - public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + public double distance(NumberVector v1, NumberVector v2) { final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - double agg = doublePreDistance(v1, v2, 0, mindim, 0.); - if (dim1 > mindim) { - agg = doublePreNorm(v1, mindim, dim1, agg); - } else if (dim2 > mindim) { - agg = doublePreNorm(v2, mindim, dim2, agg); + double agg = preDistance(v1, v2, 0, mindim, 0.); + if(dim1 > mindim) { + agg = preNorm(v1, mindim, dim1, agg); + } + else if(dim2 > mindim) { + agg = preNorm(v2, mindim, dim2, agg); } return agg; } @Override - public double doubleNorm(NumberVector<?> v) { - return doublePreNorm(v, 0, v.getDimensionality(), 0.); + public double norm(NumberVector v) { + return preNorm(v, 0, v.getDimensionality(), 0.); } @Override - public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) { final int dim1 = mbr1.getDimensionality(), dim2 = mbr2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - final NumberVector<?> v1 = (mbr1 instanceof NumberVector) ? (NumberVector<?>) mbr1 : null; - final NumberVector<?> v2 = (mbr2 instanceof NumberVector) ? (NumberVector<?>) mbr2 : null; + final NumberVector v1 = (mbr1 instanceof NumberVector) ? (NumberVector) mbr1 : null; + final NumberVector v2 = (mbr2 instanceof NumberVector) ? (NumberVector) mbr2 : null; double agg = 0.; - if (v1 != null) { - if (v2 != null) { - agg = doublePreDistance(v1, v2, 0, mindim, agg); - } else { - agg = doublePreDistanceVM(v1, mbr2, 0, mindim, agg); - } - } else { - if (v2 != null) { - agg = doublePreDistanceVM(v2, mbr1, 0, mindim, agg); - } else { - agg = doublePreDistanceMBR(mbr1, mbr2, 0, mindim, agg); + if(v1 != null) { + if(v2 != null) { + agg = preDistance(v1, v2, 0, mindim, agg); + } + else { + agg = preDistanceVM(v1, mbr2, 0, mindim, agg); + } + } + else { + if(v2 != null) { + agg = preDistanceVM(v2, mbr1, 0, mindim, agg); + } + else { + agg = preDistanceMBR(mbr1, mbr2, 0, mindim, agg); } } // first object has more dimensions. - if (dim1 > mindim) { - if (v1 != null) { - agg = doublePreNorm(v1, mindim, dim1, agg); - } else { - agg = doublePreNormMBR(v1, mindim, dim1, agg); + if(dim1 > mindim) { + if(v1 != null) { + agg = preNorm(v1, mindim, dim1, agg); + } + else { + agg = preNormMBR(v1, mindim, dim1, agg); } } // second object has more dimensions. - if (dim2 > mindim) { - if (v2 != null) { - agg = doublePreNorm(v2, mindim, dim2, agg); - } else { - agg = doublePreNormMBR(mbr2, mindim, dim2, agg); + if(dim2 > mindim) { + if(v2 != null) { + agg = preNorm(v2, mindim, dim2, agg); + } + else { + agg = preNormMBR(mbr2, mindim, dim2, agg); } } return agg; @@ -185,13 +189,13 @@ public class MaximumDistanceFunction extends LPNormDistanceFunction { @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); diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/MinimumDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/MinimumDistanceFunction.java index 552e3139..ef3a3d9e 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/MinimumDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/MinimumDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,26 +25,24 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; 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.distance.distancefunction.AbstractSpatialNorm; import de.lmu.ifi.dbs.elki.utilities.Alias; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** - * Maximum distance function to compute the Minimum distance for a pair of - * FeatureVectors. + * Maximum distance for {@link NumberVector}s. * * @author Erich Schubert */ @Alias({ "minimum", "min", "de.lmu.ifi.dbs.elki.distance.distancefunction.MinimumDistanceFunction" }) -public class MinimumDistanceFunction extends AbstractSpatialDoubleDistanceNorm { +public class MinimumDistanceFunction extends AbstractSpatialNorm { /** * Static instance. Use this. */ public static final MinimumDistanceFunction STATIC = new MinimumDistanceFunction(); /** - * Provides a Minimum distance function that can compute the Minimum distance - * (that is a DoubleDistance) for FeatureVectors. + * Constructor - use {@link #STATIC} instead. * * @deprecated Use static instance! */ @@ -54,13 +52,13 @@ public class MinimumDistanceFunction extends AbstractSpatialDoubleDistanceNorm { } @Override - public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + public double distance(NumberVector v1, NumberVector v2) { final int dim = dimensionality(v1, v2); double agg = Double.POSITIVE_INFINITY; - for (int d = 0; d < dim; d++) { + 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) { + if(val < agg) { agg = val; } } @@ -68,13 +66,13 @@ public class MinimumDistanceFunction extends AbstractSpatialDoubleDistanceNorm { } @Override - public double doubleNorm(NumberVector<?> v) { + public double norm(NumberVector v) { final int dim = v.getDimensionality(); double agg = Double.POSITIVE_INFINITY; - for (int d = 0; d < dim; d++) { + for(int d = 0; d < dim; d++) { final double xd = v.doubleValue(d); final double val = (xd >= 0.) ? xd : -xd; - if (val < agg) { + if(val < agg) { agg = val; } } @@ -82,31 +80,33 @@ public class MinimumDistanceFunction extends AbstractSpatialDoubleDistanceNorm { } @Override - public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) { // Some optimizations for simpler cases. - if (mbr1 instanceof NumberVector) { - if (mbr2 instanceof NumberVector) { - return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); + if(mbr1 instanceof NumberVector) { + if(mbr2 instanceof NumberVector) { + return distance((NumberVector) mbr1, (NumberVector) mbr2); } } // 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++) { + for(int d = 0; d < dim; d++) { final double diff; final double d1 = mbr2.getMin(d) - mbr1.getMax(d); - if (d1 > 0.) { + if(d1 > 0.) { diff = d1; - } else { + } + else { final double d2 = mbr1.getMin(d) - mbr2.getMax(d); - if (d2 > 0.) { + if(d2 > 0.) { diff = d2; - } else { + } + else { // The objects overlap in this dimension. return 0.; } } - if (diff < agg) { + if(diff < agg) { agg = diff; } } @@ -125,13 +125,13 @@ public class MinimumDistanceFunction extends AbstractSpatialDoubleDistanceNorm { @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); diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseEuclideanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseEuclideanDistanceFunction.java index 8fcf0c84..204c5c4a 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseEuclideanDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseEuclideanDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,7 +27,7 @@ import de.lmu.ifi.dbs.elki.data.SparseNumberVector; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** - * Euclidean distance function. Optimized for sparse vectors. + * Euclidean distance function, optimized for {@link SparseNumberVector}s. * * @author Erich Schubert */ @@ -38,7 +38,7 @@ public class SparseEuclideanDistanceFunction extends SparseLPNormDistanceFunctio public static final SparseEuclideanDistanceFunction STATIC = new SparseEuclideanDistanceFunction(); /** - * Constructor. + * Constructor - use {@link #STATIC} instead. * * @deprecated Use static instance instead. */ @@ -48,7 +48,7 @@ public class SparseEuclideanDistanceFunction extends SparseLPNormDistanceFunctio } @Override - public double doubleDistance(SparseNumberVector<?> v1, SparseNumberVector<?> v2) { + public double distance(SparseNumberVector v1, SparseNumberVector v2) { // Get the bit masks double accu = 0.; int i1 = v1.iter(), i2 = v2.iter(); @@ -90,7 +90,7 @@ public class SparseEuclideanDistanceFunction extends SparseLPNormDistanceFunctio } @Override - public double doubleNorm(SparseNumberVector<?> v1) { + public double norm(SparseNumberVector v1) { double accu = 0.; for(int it = v1.iter(); v1.iterValid(it); it = v1.iterAdvance(it)) { final double val = v1.iterDoubleValue(it); diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseLPNormDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseLPNormDistanceFunction.java index 9fbd9f7f..2fa7770e 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseLPNormDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseLPNormDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,27 +27,26 @@ 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.distance.distancefunction.Norm; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter; /** - * Provides a LP-Norm for FeatureVectors. + * LP-Norm, optimized for {@link SparseNumberVector}s. * * @author Erich Schubert */ // TODO: implement SpatialDistanceFunction -public class SparseLPNormDistanceFunction extends AbstractPrimitiveDistanceFunction<SparseNumberVector<?>, DoubleDistance> implements DoubleNorm<SparseNumberVector<?>> { +public class SparseLPNormDistanceFunction extends AbstractPrimitiveDistanceFunction<SparseNumberVector> implements Norm<SparseNumberVector> { /** - * Keeps the currently set p. + * P parameter and its inverse. */ private double p, invp; /** - * Provides a LP-Norm for FeatureVectors. + * Constructor. */ public SparseLPNormDistanceFunction(double p) { super(); @@ -56,7 +55,7 @@ public class SparseLPNormDistanceFunction extends AbstractPrimitiveDistanceFunct } @Override - public double doubleDistance(SparseNumberVector<?> v1, SparseNumberVector<?> v2) { + public double distance(SparseNumberVector v1, SparseNumberVector v2) { // Get the bit masks double accu = 0.; int i1 = v1.iter(), i2 = v2.iter(); @@ -98,7 +97,7 @@ public class SparseLPNormDistanceFunction extends AbstractPrimitiveDistanceFunct } @Override - public double doubleNorm(SparseNumberVector<?> v1) { + public double norm(SparseNumberVector v1) { double accu = 0.; for(int it = v1.iter(); v1.iterValid(it); it = v1.iterAdvance(it)) { final double val = Math.abs(v1.iterDoubleValue(it)); @@ -108,22 +107,7 @@ public class SparseLPNormDistanceFunction extends AbstractPrimitiveDistanceFunct } @Override - public DoubleDistance norm(SparseNumberVector<?> obj) { - return new DoubleDistance(doubleNorm(obj)); - } - - @Override - public DoubleDistance distance(SparseNumberVector<?> v1, SparseNumberVector<?> v2) { - return new DoubleDistance(doubleDistance(v1, v2)); - } - - @Override - public DoubleDistance getDistanceFactory() { - return DoubleDistance.FACTORY; - } - - @Override - public SimpleTypeInformation<? super SparseNumberVector<?>> getInputTypeRestriction() { + public SimpleTypeInformation<? super SparseNumberVector> getInputTypeRestriction() { return TypeUtil.SPARSE_VECTOR_VARIABLE_LENGTH; } @@ -148,7 +132,7 @@ public class SparseLPNormDistanceFunction extends AbstractPrimitiveDistanceFunct @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); - DoubleParameter pP = new DoubleParameter(LPNormDistanceFunction.P_ID); + DoubleParameter pP = new DoubleParameter(LPNormDistanceFunction.Parameterizer.P_ID); pP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE); if(config.grab(pP)) { p = pP.getValue(); diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseManhattanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseManhattanDistanceFunction.java index b22aaad7..9ea4d8f6 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseManhattanDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseManhattanDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,7 +27,7 @@ import de.lmu.ifi.dbs.elki.data.SparseNumberVector; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** - * Manhattan distance function. Optimized for sparse vectors. + * Manhattan distance, optimized for {@link SparseNumberVector}s. * * @author Erich Schubert */ @@ -38,7 +38,7 @@ public class SparseManhattanDistanceFunction extends SparseLPNormDistanceFunctio public static final SparseManhattanDistanceFunction STATIC = new SparseManhattanDistanceFunction(); /** - * Constructor. + * Constructor - use {@link #STATIC} instead. * * @deprecated Use static instance instead. */ @@ -48,7 +48,7 @@ public class SparseManhattanDistanceFunction extends SparseLPNormDistanceFunctio } @Override - public double doubleDistance(SparseNumberVector<?> v1, SparseNumberVector<?> v2) { + public double distance(SparseNumberVector v1, SparseNumberVector v2) { // Get the bit masks double accu = 0.; int i1 = v1.iter(), i2 = v2.iter(); @@ -90,7 +90,7 @@ public class SparseManhattanDistanceFunction extends SparseLPNormDistanceFunctio } @Override - public double doubleNorm(SparseNumberVector<?> v1) { + public double norm(SparseNumberVector v1) { double accu = 0.; for(int it = v1.iter(); v1.iterValid(it); it = v1.iterAdvance(it)) { final double val = Math.abs(v1.iterDoubleValue(it)); diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseMaximumDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseMaximumDistanceFunction.java index 4a516f7a..78c7f8e1 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseMaximumDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseMaximumDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,7 +26,7 @@ import de.lmu.ifi.dbs.elki.data.SparseNumberVector; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; /** - * Maximum distance function. Optimized for sparse vectors. + * Maximum distance, optimized for {@link SparseNumberVector}s. * * @author Erich Schubert */ @@ -37,7 +37,7 @@ public class SparseMaximumDistanceFunction extends SparseLPNormDistanceFunction public static final SparseMaximumDistanceFunction STATIC = new SparseMaximumDistanceFunction(); /** - * Constructor. + * Constructor - use {@link #STATIC} instead. * * @deprecated Use static instance */ @@ -47,7 +47,7 @@ public class SparseMaximumDistanceFunction extends SparseLPNormDistanceFunction } @Override - public double doubleDistance(SparseNumberVector<?> v1, SparseNumberVector<?> v2) { + public double distance(SparseNumberVector v1, SparseNumberVector v2) { // Get the bit masks double accu = 0.; int i1 = v1.iter(), i2 = v2.iter(); @@ -99,7 +99,7 @@ public class SparseMaximumDistanceFunction extends SparseLPNormDistanceFunction } @Override - public double doubleNorm(SparseNumberVector<?> v1) { + public double norm(SparseNumberVector v1) { double accu = 0.; for(int it = v1.iter(); v1.iterValid(it); it = v1.iterAdvance(it)) { final double val = Math.abs(v1.iterDoubleValue(it)); 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 index 8f02e40b..6ade9a3b 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SquaredEuclideanDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SquaredEuclideanDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,27 +24,30 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski; */ import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.data.SparseNumberVector; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; -import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDoubleDistanceNorm; +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.AbstractSpatialNorm; 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. + * Squared Euclidean distance, optimized for {@link SparseNumberVector}s. This + * results in the same rankings as regular Euclidean distance, but saves + * computing the square root. * * @author Arthur Zimek */ @Alias({ "squaredeuclidean", "de.lmu.ifi.dbs.elki.distance.distancefunction.SquaredEuclideanDistanceFunction" }) -public class SquaredEuclideanDistanceFunction extends AbstractSpatialDoubleDistanceNorm { +public class SquaredEuclideanDistanceFunction extends AbstractSpatialNorm { /** * 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. + * Constructor - use {@link #STATIC} instead. * * @deprecated Use static instance! */ @@ -53,78 +56,124 @@ public class SquaredEuclideanDistanceFunction extends AbstractSpatialDoubleDista 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); + private final double preDistance(NumberVector v1, NumberVector v2, int start, int end, double agg) { + for(int d = start; d < end; d++) { + final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); + final double delta = xd - yd; 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; + private final double preDistanceVM(NumberVector v, SpatialComparable mbr, int start, int end, double agg) { + for(int d = start; d < end; d++) { + final double value = v.doubleValue(d), min = mbr.getMin(d); + double delta = min - value; + if(delta < 0.) { + delta = value - mbr.getMax(d); + } + if(delta > 0.) { + agg += delta * delta; + } } 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; - } + private final double preDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, int start, int end, double agg) { + for(int d = start; d < end; d++) { + double delta = mbr2.getMin(d) - mbr1.getMax(d); + if(delta < 0.) { + delta = mbr1.getMin(d) - mbr2.getMax(d); + } + if(delta > 0.) { + agg += delta * delta; } - 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); + private final double preNorm(NumberVector v, int start, int end, double agg) { + for(int d = start; d < end; d++) { + final double xd = v.doubleValue(d); + agg += xd * xd; + } + return agg; + } + + private final double preNormMBR(SpatialComparable mbr, int start, int end, double agg) { + for(int d = start; d < end; d++) { + double delta = mbr.getMin(d); + if(delta < 0.) { + delta = -mbr.getMax(d); + } + if(delta > 0.) { + agg += delta * delta; } - } else if (mbr2 instanceof NumberVector) { - return doubleMinDistObject((NumberVector<?>) mbr2, mbr1); } - final int dim = dimensionality(mbr1, mbr2); + return agg; + } + + @Override + public double distance(NumberVector v1, NumberVector v2) { + final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality(); + final int mindim = (dim1 < dim2) ? dim1 : dim2; + double agg = preDistance(v1, v2, 0, mindim, 0.); + if(dim1 > mindim) { + agg = preNorm(v1, mindim, dim1, agg); + } + else if(dim2 > mindim) { + agg = preNorm(v2, mindim, dim2, agg); + } + return agg; + } + + @Override + public double norm(NumberVector v) { + return preNorm(v, 0, v.getDimensionality(), 0.); + } + + @Override + public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) { + final int dim1 = mbr1.getDimensionality(), dim2 = mbr2.getDimensionality(); + final int mindim = (dim1 < dim2) ? dim1 : dim2; + + final NumberVector v1 = (mbr1 instanceof NumberVector) ? (NumberVector) mbr1 : null; + final NumberVector v2 = (mbr2 instanceof NumberVector) ? (NumberVector) mbr2 : null; 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; - } + if(v1 != null) { + if(v2 != null) { + agg = preDistance(v1, v2, 0, mindim, agg); + } + else { + agg = preDistanceVM(v1, mbr2, 0, mindim, agg); + } + } + else { + if(v2 != null) { + agg = preDistanceVM(v2, mbr1, 0, mindim, agg); + } + else { + agg = preDistanceMBR(mbr1, mbr2, 0, mindim, agg); + } + } + // first object has more dimensions. + if(dim1 > mindim) { + if(v1 != null) { + agg = preNorm(v1, mindim, dim1, agg); + } + else { + agg = preNormMBR(v1, mindim, dim1, agg); + } + } + // second object has more dimensions. + if(dim2 > mindim) { + if(v2 != null) { + agg = preNorm(v2, mindim, dim2, agg); + } + else { + agg = preNormMBR(mbr2, mindim, dim2, agg); } - agg += diff * diff; } return agg; } @@ -141,15 +190,20 @@ public class SquaredEuclideanDistanceFunction extends AbstractSpatialDoubleDista @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 SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() { + return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH; + } + /** * Parameterization class. * 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 index 4fb4e6a2..a8236663 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedEuclideanDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedEuclideanDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,9 +27,13 @@ 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.utilities.datastructures.arraylike.ArrayLikeUtil; +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.DoubleListParameter; /** - * Provides the Euclidean distance for FeatureVectors. + * Weighted Euclidean distance for {@link NumberVector}s. * * @author Erich Schubert */ @@ -43,7 +47,7 @@ public class WeightedEuclideanDistanceFunction extends WeightedLPNormDistanceFun super(2.0, weights); } - private final double doublePreDistance(NumberVector<?> v1, NumberVector<?> v2, final int start, final int end, double agg) { + private final double preDistance(NumberVector v1, NumberVector v2, final int start, final int end, double agg) { for(int d = start; d < end; d++) { final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); final double delta = xd - yd; @@ -52,7 +56,7 @@ public class WeightedEuclideanDistanceFunction extends WeightedLPNormDistanceFun return agg; } - private final double doublePreDistanceVM(NumberVector<?> v, SpatialComparable mbr, final int start, final int end, double agg) { + private final double preDistanceVM(NumberVector v, SpatialComparable mbr, final int start, final int end, double agg) { for(int d = start; d < end; d++) { final double value = v.doubleValue(d), min = mbr.getMin(d); double delta = min - value; @@ -66,7 +70,7 @@ public class WeightedEuclideanDistanceFunction extends WeightedLPNormDistanceFun return agg; } - private final double doublePreDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, final int start, final int end, double agg) { + private final double preDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, final int start, final int end, double agg) { for(int d = start; d < end; d++) { double delta = mbr2.getMin(d) - mbr1.getMax(d); if(delta < 0.) { @@ -79,7 +83,7 @@ public class WeightedEuclideanDistanceFunction extends WeightedLPNormDistanceFun return agg; } - private final double doublePreNorm(NumberVector<?> v, final int start, final int end, double agg) { + private final double preNorm(NumberVector v, final int start, final int end, double agg) { for(int d = start; d < end; d++) { final double xd = v.doubleValue(d); agg += xd * xd * weights[d]; @@ -87,7 +91,7 @@ public class WeightedEuclideanDistanceFunction extends WeightedLPNormDistanceFun return agg; } - private final double doublePreNormMBR(SpatialComparable mbr, final int start, final int end, double agg) { + private final double preNormMBR(SpatialComparable mbr, final int start, final int end, double agg) { for(int d = start; d < end; d++) { double delta = mbr.getMin(d); if(delta < 0.) { @@ -101,65 +105,65 @@ public class WeightedEuclideanDistanceFunction extends WeightedLPNormDistanceFun } @Override - public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + public double distance(NumberVector v1, NumberVector v2) { final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - double agg = doublePreDistance(v1, v2, 0, mindim, 0.); + double agg = preDistance(v1, v2, 0, mindim, 0.); if(dim1 > mindim) { - agg = doublePreNorm(v1, mindim, dim1, agg); + agg = preNorm(v1, mindim, dim1, agg); } else if(dim2 > mindim) { - agg = doublePreNorm(v2, mindim, dim2, agg); + agg = preNorm(v2, mindim, dim2, agg); } return Math.sqrt(agg); } @Override - public double doubleNorm(NumberVector<?> v) { - return Math.sqrt(doublePreNorm(v, 0, v.getDimensionality(), 0.)); + public double norm(NumberVector v) { + return Math.sqrt(preNorm(v, 0, v.getDimensionality(), 0.)); } @Override - public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) { final int dim1 = mbr1.getDimensionality(), dim2 = mbr2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - final NumberVector<?> v1 = (mbr1 instanceof NumberVector) ? (NumberVector<?>) mbr1 : null; - final NumberVector<?> v2 = (mbr2 instanceof NumberVector) ? (NumberVector<?>) mbr2 : null; + final NumberVector v1 = (mbr1 instanceof NumberVector) ? (NumberVector) mbr1 : null; + final NumberVector v2 = (mbr2 instanceof NumberVector) ? (NumberVector) mbr2 : null; double agg = 0.; if(v1 != null) { if(v2 != null) { - agg = doublePreDistance(v1, v2, 0, mindim, agg); + agg = preDistance(v1, v2, 0, mindim, agg); } else { - agg = doublePreDistanceVM(v1, mbr2, 0, mindim, agg); + agg = preDistanceVM(v1, mbr2, 0, mindim, agg); } } else { if(v2 != null) { - agg = doublePreDistanceVM(v2, mbr1, 0, mindim, agg); + agg = preDistanceVM(v2, mbr1, 0, mindim, agg); } else { - agg = doublePreDistanceMBR(mbr1, mbr2, 0, mindim, agg); + agg = preDistanceMBR(mbr1, mbr2, 0, mindim, agg); } } // first object has more dimensions. if(dim1 > mindim) { if(v1 != null) { - agg = doublePreNorm(v1, mindim, dim1, agg); + agg = preNorm(v1, mindim, dim1, agg); } else { - agg = doublePreNormMBR(v1, mindim, dim1, agg); + agg = preNormMBR(v1, mindim, dim1, agg); } } // second object has more dimensions. if(dim2 > mindim) { if(v2 != null) { - agg = doublePreNorm(v2, mindim, dim2, agg); + agg = preNorm(v2, mindim, dim2, agg); } else { - agg = doublePreNormMBR(mbr2, mindim, dim2, agg); + agg = preNormMBR(mbr2, mindim, dim2, agg); } } return Math.sqrt(agg); @@ -190,4 +194,32 @@ public class WeightedEuclideanDistanceFunction extends WeightedLPNormDistanceFun WeightedEuclideanDistanceFunction other = (WeightedEuclideanDistanceFunction) obj; return Arrays.equals(this.weights, other.weights); } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + /** + * Weight array + */ + protected double[] weights; + + @Override + protected void makeOptions(Parameterization config) { + super.makeOptions(config); + DoubleListParameter weightsP = new DoubleListParameter(WEIGHTS_ID); + if(config.grab(weightsP)) { + weights = ArrayLikeUtil.toPrimitiveDoubleArray(weightsP.getValue()); + } + } + + @Override + protected WeightedEuclideanDistanceFunction makeInstance() { + return new WeightedEuclideanDistanceFunction(weights); + } + } } diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedLPNormDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedLPNormDistanceFunction.java index 48a9c5a2..ff2b15f3 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedLPNormDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedLPNormDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,13 +29,17 @@ 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.distance.distancefunction.WeightedNumberVectorDistanceFunction; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleListParameter; /** - * Weighted version of the Minkowski L_p metrics distance function. + * Weighted version of the Minkowski L_p norm distance for {@link NumberVector}. * * @author Erich Schubert */ -public class WeightedLPNormDistanceFunction extends LPNormDistanceFunction { +public class WeightedLPNormDistanceFunction extends LPNormDistanceFunction implements WeightedNumberVectorDistanceFunction<NumberVector> { /** * Weight array */ @@ -52,8 +56,8 @@ public class WeightedLPNormDistanceFunction extends LPNormDistanceFunction { this.weights = weights; } - private final double doublePreDistance(NumberVector<?> v1, NumberVector<?> v2, final int start, final int end, double agg) { - for (int d = start; d < end; d++) { + private final double preDistance(NumberVector v1, NumberVector v2, final int start, final int end, double agg) { + for(int d = start; d < end; 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) * weights[d]; @@ -61,35 +65,35 @@ public class WeightedLPNormDistanceFunction extends LPNormDistanceFunction { return agg; } - private final double doublePreDistanceVM(NumberVector<?> v, SpatialComparable mbr, final int start, final int end, double agg) { - for (int d = start; d < end; d++) { + private final double preDistanceVM(NumberVector v, SpatialComparable mbr, final int start, final int end, double agg) { + for(int d = start; d < end; d++) { final double value = v.doubleValue(d), min = mbr.getMin(d); double delta = min - value; - if (delta < 0.) { + if(delta < 0.) { delta = value - mbr.getMax(d); } - if (delta > 0.) { + if(delta > 0.) { agg += Math.pow(delta, p) * weights[d]; } } return agg; } - private final double doublePreDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, final int start, final int end, double agg) { - for (int d = start; d < end; d++) { + private final double preDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, final int start, final int end, double agg) { + for(int d = start; d < end; d++) { double delta = mbr2.getMin(d) - mbr1.getMax(d); - if (delta < 0.) { + if(delta < 0.) { delta = mbr1.getMin(d) - mbr2.getMax(d); } - if (delta > 0.) { + if(delta > 0.) { agg += Math.pow(delta, p) * weights[d]; } } return agg; } - private final double doublePreNorm(NumberVector<?> v, final int start, final int end, double agg) { - for (int d = start; d < end; d++) { + private final double preNorm(NumberVector v, final int start, final int end, double agg) { + for(int d = start; d < end; d++) { final double xd = v.doubleValue(d); final double delta = xd >= 0. ? xd : -xd; agg += Math.pow(delta, p) * weights[d]; @@ -97,13 +101,13 @@ public class WeightedLPNormDistanceFunction extends LPNormDistanceFunction { return agg; } - private final double doublePreNormMBR(SpatialComparable mbr, final int start, final int end, double agg) { - for (int d = start; d < end; d++) { + private final double preNormMBR(SpatialComparable mbr, final int start, final int end, double agg) { + for(int d = start; d < end; d++) { double delta = mbr.getMin(d); - if (delta < 0.) { + if(delta < 0.) { delta = -mbr.getMax(d); } - if (delta > 0.) { + if(delta > 0.) { agg += Math.pow(delta, p) * weights[d]; } } @@ -111,59 +115,65 @@ public class WeightedLPNormDistanceFunction extends LPNormDistanceFunction { } @Override - public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + public double distance(NumberVector v1, NumberVector v2) { final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - double agg = doublePreDistance(v1, v2, 0, mindim, 0.); - if (dim1 > mindim) { - agg = doublePreNorm(v1, mindim, dim1, agg); - } else if (dim2 > mindim) { - agg = doublePreNorm(v2, mindim, dim2, agg); + double agg = preDistance(v1, v2, 0, mindim, 0.); + if(dim1 > mindim) { + agg = preNorm(v1, mindim, dim1, agg); + } + else if(dim2 > mindim) { + agg = preNorm(v2, mindim, dim2, agg); } return Math.pow(agg, invp); } @Override - public double doubleNorm(NumberVector<?> v) { - return Math.pow(doublePreNorm(v, 0, v.getDimensionality(), 0.), invp); + public double norm(NumberVector v) { + return Math.pow(preNorm(v, 0, v.getDimensionality(), 0.), invp); } @Override - public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) { final int dim1 = mbr1.getDimensionality(), dim2 = mbr2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - final NumberVector<?> v1 = (mbr1 instanceof NumberVector) ? (NumberVector<?>) mbr1 : null; - final NumberVector<?> v2 = (mbr2 instanceof NumberVector) ? (NumberVector<?>) mbr2 : null; + final NumberVector v1 = (mbr1 instanceof NumberVector) ? (NumberVector) mbr1 : null; + final NumberVector v2 = (mbr2 instanceof NumberVector) ? (NumberVector) mbr2 : null; double agg = 0.; - if (v1 != null) { - if (v2 != null) { - agg = doublePreDistance(v1, v2, 0, mindim, agg); - } else { - agg = doublePreDistanceVM(v1, mbr2, 0, mindim, agg); + if(v1 != null) { + if(v2 != null) { + agg = preDistance(v1, v2, 0, mindim, agg); } - } else { - if (v2 != null) { - agg = doublePreDistanceVM(v2, mbr1, 0, mindim, agg); - } else { - agg = doublePreDistanceMBR(mbr1, mbr2, 0, mindim, agg); + else { + agg = preDistanceVM(v1, mbr2, 0, mindim, agg); + } + } + else { + if(v2 != null) { + agg = preDistanceVM(v2, mbr1, 0, mindim, agg); + } + else { + agg = preDistanceMBR(mbr1, mbr2, 0, mindim, agg); } } // first object has more dimensions. - if (dim1 > mindim) { - if (v1 != null) { - agg = doublePreNorm(v1, mindim, dim1, agg); - } else { - agg = doublePreNormMBR(v1, mindim, dim1, agg); + if(dim1 > mindim) { + if(v1 != null) { + agg = preNorm(v1, mindim, dim1, agg); + } + else { + agg = preNormMBR(v1, mindim, dim1, agg); } } // second object has more dimensions. - if (dim2 > mindim) { - if (v2 != null) { - agg = doublePreNorm(v2, mindim, dim2, agg); - } else { - agg = doublePreNormMBR(mbr2, mindim, dim2, agg); + if(dim2 > mindim) { + if(v2 != null) { + agg = preNorm(v2, mindim, dim2, agg); + } + else { + agg = preNormMBR(mbr2, mindim, dim2, agg); } } return Math.pow(agg, invp); @@ -171,16 +181,16 @@ public class WeightedLPNormDistanceFunction extends LPNormDistanceFunction { @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.) { + if(!(obj instanceof WeightedLPNormDistanceFunction)) { + if(obj instanceof LPNormDistanceFunction && super.equals(obj)) { + for(double d : weights) { + if(d != 1.) { return false; } } @@ -193,7 +203,44 @@ public class WeightedLPNormDistanceFunction extends LPNormDistanceFunction { } @Override - public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() { - return new VectorFieldTypeInformation<>(NumberVector.class, 0, weights.length); + public SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() { + return VectorFieldTypeInformation.typeRequest(NumberVector.class, 0, weights.length); + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends LPNormDistanceFunction.Parameterizer { + /** + * Weight array + */ + protected double[] weights; + + @Override + protected void makeOptions(Parameterization config) { + super.makeOptions(config); + DoubleListParameter weightsP = new DoubleListParameter(WEIGHTS_ID); + if(config.grab(weightsP)) { + weights = ArrayLikeUtil.toPrimitiveDoubleArray(weightsP.getValue()); + } + } + + @Override + protected WeightedLPNormDistanceFunction makeInstance() { + if(p == 1.) { + return new WeightedManhattanDistanceFunction(weights); + } + if(p == 2.) { + return new WeightedEuclideanDistanceFunction(weights); + } + if(p == Double.POSITIVE_INFINITY) { + return new WeightedMaximumDistanceFunction(weights); + } + return new WeightedLPNormDistanceFunction(p, weights); + } } } 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 index b419f0df..f793b531 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedManhattanDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedManhattanDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,9 +27,14 @@ 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.utilities.datastructures.arraylike.ArrayLikeUtil; +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.DoubleListParameter; /** - * Weighted version of the Minkowski L_p metrics distance function. + * Weighted version of the Minkowski L_p metrics distance function for + * {@link NumberVector}s. * * @author Erich Schubert */ @@ -43,8 +48,8 @@ public class WeightedManhattanDistanceFunction extends WeightedLPNormDistanceFun super(1., weights); } - private final double doublePreDistance(NumberVector<?> v1, NumberVector<?> v2, final int start, final int end, double agg) { - for (int d = start; d < end; d++) { + private final double preDistance(NumberVector v1, NumberVector v2, final int start, final int end, double agg) { + for(int d = start; d < end; d++) { final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); final double delta = (xd >= yd) ? xd - yd : yd - xd; agg += delta * weights[d]; @@ -52,35 +57,35 @@ public class WeightedManhattanDistanceFunction extends WeightedLPNormDistanceFun return agg; } - private final double doublePreDistanceVM(NumberVector<?> v, SpatialComparable mbr, final int start, final int end, double agg) { - for (int d = start; d < end; d++) { + private final double preDistanceVM(NumberVector v, SpatialComparable mbr, final int start, final int end, double agg) { + for(int d = start; d < end; d++) { final double value = v.doubleValue(d), min = mbr.getMin(d); double delta = min - value; - if (delta < 0.) { + if(delta < 0.) { delta = value - mbr.getMax(d); } - if (delta > 0.) { + if(delta > 0.) { agg += delta * weights[d]; } } return agg; } - private final double doublePreDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, final int start, final int end, double agg) { - for (int d = start; d < end; d++) { + private final double preDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, final int start, final int end, double agg) { + for(int d = start; d < end; d++) { double delta = mbr2.getMin(d) - mbr1.getMax(d); - if (delta < 0.) { + if(delta < 0.) { delta = mbr1.getMin(d) - mbr2.getMax(d); } - if (delta > 0.) { + if(delta > 0.) { agg += delta * weights[d]; } } return agg; } - private final double doublePreNorm(NumberVector<?> v, final int start, final int end, double agg) { - for (int d = start; d < end; d++) { + private final double preNorm(NumberVector v, final int start, final int end, double agg) { + for(int d = start; d < end; d++) { final double xd = v.doubleValue(d); final double delta = xd >= 0. ? xd : -xd; agg += delta * weights[d]; @@ -88,13 +93,13 @@ public class WeightedManhattanDistanceFunction extends WeightedLPNormDistanceFun return agg; } - private final double doublePreNormMBR(SpatialComparable mbr, final int start, final int end, double agg) { - for (int d = start; d < end; d++) { + private final double preNormMBR(SpatialComparable mbr, final int start, final int end, double agg) { + for(int d = start; d < end; d++) { double delta = mbr.getMin(d); - if (delta < 0.) { + if(delta < 0.) { delta = -mbr.getMax(d); } - if (delta > 0.) { + if(delta > 0.) { agg += delta * weights[d]; } } @@ -102,59 +107,65 @@ public class WeightedManhattanDistanceFunction extends WeightedLPNormDistanceFun } @Override - public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + public double distance(NumberVector v1, NumberVector v2) { final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - double agg = doublePreDistance(v1, v2, 0, mindim, 0.); - if (dim1 > mindim) { - agg = doublePreNorm(v1, mindim, dim1, agg); - } else if (dim2 > mindim) { - agg = doublePreNorm(v2, mindim, dim2, agg); + double agg = preDistance(v1, v2, 0, mindim, 0.); + if(dim1 > mindim) { + agg = preNorm(v1, mindim, dim1, agg); + } + else if(dim2 > mindim) { + agg = preNorm(v2, mindim, dim2, agg); } return agg; } @Override - public double doubleNorm(NumberVector<?> v) { - return doublePreNorm(v, 0, v.getDimensionality(), 0.); + public double norm(NumberVector v) { + return preNorm(v, 0, v.getDimensionality(), 0.); } @Override - public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) { final int dim1 = mbr1.getDimensionality(), dim2 = mbr2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - final NumberVector<?> v1 = (mbr1 instanceof NumberVector) ? (NumberVector<?>) mbr1 : null; - final NumberVector<?> v2 = (mbr2 instanceof NumberVector) ? (NumberVector<?>) mbr2 : null; + final NumberVector v1 = (mbr1 instanceof NumberVector) ? (NumberVector) mbr1 : null; + final NumberVector v2 = (mbr2 instanceof NumberVector) ? (NumberVector) mbr2 : null; double agg = 0.; - if (v1 != null) { - if (v2 != null) { - agg = doublePreDistance(v1, v2, 0, mindim, agg); - } else { - agg = doublePreDistanceVM(v1, mbr2, 0, mindim, agg); + if(v1 != null) { + if(v2 != null) { + agg = preDistance(v1, v2, 0, mindim, agg); + } + else { + agg = preDistanceVM(v1, mbr2, 0, mindim, agg); + } + } + else { + if(v2 != null) { + agg = preDistanceVM(v2, mbr1, 0, mindim, agg); } - } else { - if (v2 != null) { - agg = doublePreDistanceVM(v2, mbr1, 0, mindim, agg); - } else { - agg = doublePreDistanceMBR(mbr1, mbr2, 0, mindim, agg); + else { + agg = preDistanceMBR(mbr1, mbr2, 0, mindim, agg); } } // first object has more dimensions. - if (dim1 > mindim) { - if (v1 != null) { - agg = doublePreNorm(v1, mindim, dim1, agg); - } else { - agg = doublePreNormMBR(v1, mindim, dim1, agg); + if(dim1 > mindim) { + if(v1 != null) { + agg = preNorm(v1, mindim, dim1, agg); + } + else { + agg = preNormMBR(v1, mindim, dim1, agg); } } // second object has more dimensions. - if (dim2 > mindim) { - if (v2 != null) { - agg = doublePreNorm(v2, mindim, dim2, agg); - } else { - agg = doublePreNormMBR(mbr2, mindim, dim2, agg); + if(dim2 > mindim) { + if(v2 != null) { + agg = preNorm(v2, mindim, dim2, agg); + } + else { + agg = preNormMBR(mbr2, mindim, dim2, agg); } } return agg; @@ -162,14 +173,14 @@ public class WeightedManhattanDistanceFunction extends WeightedLPNormDistanceFun @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 WeightedManhattanDistanceFunction)) { - if (obj instanceof WeightedLPNormDistanceFunction) { + if(!(obj instanceof WeightedManhattanDistanceFunction)) { + if(obj instanceof WeightedLPNormDistanceFunction) { return super.equals(obj); } return false; @@ -177,4 +188,32 @@ public class WeightedManhattanDistanceFunction extends WeightedLPNormDistanceFun WeightedManhattanDistanceFunction other = (WeightedManhattanDistanceFunction) obj; return Arrays.equals(this.weights, other.weights); } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + /** + * Weight array + */ + protected double[] weights; + + @Override + protected void makeOptions(Parameterization config) { + super.makeOptions(config); + DoubleListParameter weightsP = new DoubleListParameter(WEIGHTS_ID); + if(config.grab(weightsP)) { + weights = ArrayLikeUtil.toPrimitiveDoubleArray(weightsP.getValue()); + } + } + + @Override + protected WeightedManhattanDistanceFunction makeInstance() { + return new WeightedManhattanDistanceFunction(weights); + } + } } diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedMaximumDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedMaximumDistanceFunction.java index c97848dd..1def2415 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedMaximumDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedMaximumDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,9 +27,14 @@ 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.utilities.datastructures.arraylike.ArrayLikeUtil; +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.DoubleListParameter; /** - * Weighted version of the Minkowski L_p metrics distance function. + * Weighted version of the Minkowski L_p metrics distance function for + * {@link NumberVector}s. * * @author Erich Schubert */ @@ -43,7 +48,7 @@ public class WeightedMaximumDistanceFunction extends WeightedLPNormDistanceFunct super(Double.POSITIVE_INFINITY, weights); } - private final double doublePreDistance(NumberVector<?> v1, NumberVector<?> v2, final int start, final int end, double agg) { + private final double preDistance(NumberVector v1, NumberVector v2, final int start, final int end, double agg) { for(int d = start; d < end; d++) { final double xd = v1.doubleValue(d), yd = v2.doubleValue(d); final double delta = ((xd >= yd) ? xd - yd : yd - xd) * weights[d]; @@ -54,7 +59,7 @@ public class WeightedMaximumDistanceFunction extends WeightedLPNormDistanceFunct return agg; } - private final double doublePreDistanceVM(NumberVector<?> v, SpatialComparable mbr, final int start, final int end, double agg) { + private final double preDistanceVM(NumberVector v, SpatialComparable mbr, final int start, final int end, double agg) { for(int d = start; d < end; d++) { final double value = v.doubleValue(d), min = mbr.getMin(d); double delta = min - value; @@ -69,7 +74,7 @@ public class WeightedMaximumDistanceFunction extends WeightedLPNormDistanceFunct return agg; } - private final double doublePreDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, final int start, final int end, double agg) { + private final double preDistanceMBR(SpatialComparable mbr1, SpatialComparable mbr2, final int start, final int end, double agg) { for(int d = start; d < end; d++) { double delta = mbr2.getMin(d) - mbr1.getMax(d); if(delta < 0.) { @@ -83,7 +88,7 @@ public class WeightedMaximumDistanceFunction extends WeightedLPNormDistanceFunct return agg; } - private final double doublePreNorm(NumberVector<?> v, final int start, final int end, double agg) { + private final double preNorm(NumberVector v, final int start, final int end, double agg) { for(int d = start; d < end; d++) { final double xd = v.doubleValue(d); final double delta = (xd >= 0. ? xd : -xd) * weights[d]; @@ -94,7 +99,7 @@ public class WeightedMaximumDistanceFunction extends WeightedLPNormDistanceFunct return agg; } - private final double doublePreNormMBR(SpatialComparable mbr, final int start, final int end, double agg) { + private final double preNormMBR(SpatialComparable mbr, final int start, final int end, double agg) { for(int d = start; d < end; d++) { double delta = mbr.getMin(d); if(delta < 0.) { @@ -109,65 +114,65 @@ public class WeightedMaximumDistanceFunction extends WeightedLPNormDistanceFunct } @Override - public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) { + public double distance(NumberVector v1, NumberVector v2) { final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - double agg = doublePreDistance(v1, v2, 0, mindim, 0.); + double agg = preDistance(v1, v2, 0, mindim, 0.); if(dim1 > mindim) { - agg = doublePreNorm(v1, mindim, dim1, agg); + agg = preNorm(v1, mindim, dim1, agg); } else if(dim2 > mindim) { - agg = doublePreNorm(v2, mindim, dim2, agg); + agg = preNorm(v2, mindim, dim2, agg); } return agg; } @Override - public double doubleNorm(NumberVector<?> v) { - return doublePreNorm(v, 0, v.getDimensionality(), 0.); + public double norm(NumberVector v) { + return preNorm(v, 0, v.getDimensionality(), 0.); } @Override - public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) { final int dim1 = mbr1.getDimensionality(), dim2 = mbr2.getDimensionality(); final int mindim = (dim1 < dim2) ? dim1 : dim2; - final NumberVector<?> v1 = (mbr1 instanceof NumberVector) ? (NumberVector<?>) mbr1 : null; - final NumberVector<?> v2 = (mbr2 instanceof NumberVector) ? (NumberVector<?>) mbr2 : null; + final NumberVector v1 = (mbr1 instanceof NumberVector) ? (NumberVector) mbr1 : null; + final NumberVector v2 = (mbr2 instanceof NumberVector) ? (NumberVector) mbr2 : null; double agg = 0.; if(v1 != null) { if(v2 != null) { - agg = doublePreDistance(v1, v2, 0, mindim, agg); + agg = preDistance(v1, v2, 0, mindim, agg); } else { - agg = doublePreDistanceVM(v1, mbr2, 0, mindim, agg); + agg = preDistanceVM(v1, mbr2, 0, mindim, agg); } } else { if(v2 != null) { - agg = doublePreDistanceVM(v2, mbr1, 0, mindim, agg); + agg = preDistanceVM(v2, mbr1, 0, mindim, agg); } else { - agg = doublePreDistanceMBR(mbr1, mbr2, 0, mindim, agg); + agg = preDistanceMBR(mbr1, mbr2, 0, mindim, agg); } } // first object has more dimensions. if(dim1 > mindim) { if(v1 != null) { - agg = doublePreNorm(v1, mindim, dim1, agg); + agg = preNorm(v1, mindim, dim1, agg); } else { - agg = doublePreNormMBR(v1, mindim, dim1, agg); + agg = preNormMBR(v1, mindim, dim1, agg); } } // second object has more dimensions. if(dim2 > mindim) { if(v2 != null) { - agg = doublePreNorm(v2, mindim, dim2, agg); + agg = preNorm(v2, mindim, dim2, agg); } else { - agg = doublePreNormMBR(mbr2, mindim, dim2, agg); + agg = preNormMBR(mbr2, mindim, dim2, agg); } } return agg; @@ -190,4 +195,32 @@ public class WeightedMaximumDistanceFunction extends WeightedLPNormDistanceFunct WeightedMaximumDistanceFunction other = (WeightedMaximumDistanceFunction) obj; return Arrays.equals(this.weights, other.weights); } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + /** + * Weight array + */ + protected double[] weights; + + @Override + protected void makeOptions(Parameterization config) { + super.makeOptions(config); + DoubleListParameter weightsP = new DoubleListParameter(WEIGHTS_ID); + if(config.grab(weightsP)) { + weights = ArrayLikeUtil.toPrimitiveDoubleArray(weightsP.getValue()); + } + } + + @Override + protected WeightedMaximumDistanceFunction makeInstance() { + return new WeightedMaximumDistanceFunction(weights); + } + } } diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedSquaredEuclideanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedSquaredEuclideanDistanceFunction.java index 4e361c10..a238ba1d 100644 --- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedSquaredEuclideanDistanceFunction.java +++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedSquaredEuclideanDistanceFunction.java @@ -4,7 +4,7 @@ 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 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,15 +27,20 @@ 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; +import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialNorm; +import de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedNumberVectorDistanceFunction; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil; +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.DoubleListParameter; /** - * Provides the squared Euclidean distance for FeatureVectors. This results in - * the same rankings, but saves computing the square root as often. + * Squared Euclidean distance for {@link NumberVector}s. This results in the + * same rankings as Euclidean distance, but saves computing the square root. * * @author Arthur Zimek */ -public class WeightedSquaredEuclideanDistanceFunction extends AbstractSpatialDoubleDistanceNorm { +public class WeightedSquaredEuclideanDistanceFunction extends AbstractSpatialNorm implements WeightedNumberVectorDistanceFunction<NumberVector> { /** * Weight array */ @@ -44,24 +49,18 @@ public class WeightedSquaredEuclideanDistanceFunction extends AbstractSpatialDou /** * Constructor. * - * @param weights + * @param weights Weight vector */ public WeightedSquaredEuclideanDistanceFunction(double[] weights) { super(); this.weights = weights; } - /** - * 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) { + public double distance(NumberVector v1, NumberVector v2) { final int dim = dimensionality(v1, v2, weights.length); double agg = 0.; - for (int d = 0; d < dim; d++) { + for(int d = 0; d < dim; d++) { final double delta = (v1.doubleValue(d) - v2.doubleValue(d)); agg += delta * delta * weights[d]; } @@ -69,10 +68,10 @@ public class WeightedSquaredEuclideanDistanceFunction extends AbstractSpatialDou } @Override - public double doubleNorm(NumberVector<?> obj) { + public double norm(NumberVector obj) { final int dim = obj.getDimensionality(); double agg = 0.; - for (int d = 0; d < dim; d++) { + for(int d = 0; d < dim; d++) { final double delta = obj.doubleValue(dim); agg += delta * delta * weights[d]; } @@ -80,23 +79,25 @@ public class WeightedSquaredEuclideanDistanceFunction extends AbstractSpatialDou } @Override - public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) { + public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) { // Optimization for the simplest case - if (mbr1 instanceof NumberVector) { - if (mbr2 instanceof NumberVector) { - return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2); + if(mbr1 instanceof NumberVector) { + if(mbr2 instanceof NumberVector) { + return distance((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++) { + for(int d = 0; d < dim; d++) { final double diff; - if (mbr1.getMax(d) < mbr2.getMin(d)) { + if(mbr1.getMax(d) < mbr2.getMin(d)) { diff = mbr2.getMin(d) - mbr1.getMax(d); - } else if (mbr1.getMin(d) > mbr2.getMax(d)) { + } + else if(mbr1.getMin(d) > mbr2.getMax(d)) { diff = mbr1.getMin(d) - mbr2.getMax(d); - } else { // The mbrs intersect! + } + else { // The mbrs intersect! continue; } agg += diff * diff * weights[d]; @@ -111,16 +112,16 @@ public class WeightedSquaredEuclideanDistanceFunction extends AbstractSpatialDou @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; } } @@ -131,4 +132,32 @@ public class WeightedSquaredEuclideanDistanceFunction extends AbstractSpatialDou WeightedSquaredEuclideanDistanceFunction other = (WeightedSquaredEuclideanDistanceFunction) obj; return Arrays.equals(this.weights, other.weights); } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + /** + * Weight array + */ + protected double[] weights; + + @Override + protected void makeOptions(Parameterization config) { + super.makeOptions(config); + DoubleListParameter weightsP = new DoubleListParameter(WEIGHTS_ID); + if(config.grab(weightsP)) { + weights = ArrayLikeUtil.toPrimitiveDoubleArray(weightsP.getValue()); + } + } + + @Override + protected WeightedSquaredEuclideanDistanceFunction makeInstance() { + return new WeightedSquaredEuclideanDistanceFunction(weights); + } + } } 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 index c52167f3..0904c22b 100644 --- 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 @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team |