summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/distance
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/distance')
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/DistanceUtil.java117
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDBIDRangeDistanceFunction.java (renamed from src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDBIDDistanceFunction.java)48
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDatabaseDistanceFunction.java21
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractIndexBasedDistanceFunction.java9
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractNumberVectorDistanceFunction.java (renamed from src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceFunction.java)24
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractNumberVectorNorm.java (renamed from src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceNorm.java)10
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractPrimitiveDistanceFunction.java15
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDistanceFunction.java (renamed from src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDoubleDistanceFunction.java)13
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialNorm.java (renamed from src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDoubleDistanceNorm.java)13
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/ArcCosineDistanceFunction.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/BrayCurtisDistanceFunction.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/CanberraDistanceFunction.java62
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/ClarkDistanceFunction.java49
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/CosineDistanceFunction.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/DBIDDistanceFunction.java9
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/DBIDRangeDistanceFunction.java (renamed from src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDoubleDistanceFunction.java)31
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/DistanceFunction.java21
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/FilteredLocalPCABasedDistanceFunction.java64
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/IndexBasedDistanceFunction.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/Kulczynski1DistanceFunction.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/LocallyWeightedDistanceFunction.java260
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/LorentzianDistanceFunction.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/MatrixWeightedDistanceFunction.java (renamed from src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedDistanceFunction.java)16
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinKDistance.java258
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/Norm.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/NumberVectorDistanceFunction.java23
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDistanceFunction.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/ProxyDistanceFunction.java126
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/RandomStableDistanceFunction.java35
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/SharedNearestNeighborJaccardDistanceFunction.java21
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDistanceFunction.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDoubleDistanceFunction.java52
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedCanberraDistanceFunction.java56
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedNumberVectorDistanceFunction.java (renamed from src/de/lmu/ifi/dbs/elki/distance/distancefunction/DoubleNorm.java)19
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/AbstractSimilarityAdapter.java94
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/ArccosSimilarityAdapter.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/LinearAdapterLinear.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/LnSimilarityAdapter.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HSBHistogramQuadraticDistanceFunction.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HistogramIntersectionDistanceFunction.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/RGBHistogramQuadraticDistanceFunction.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/AbsolutePearsonCorrelationDistanceFunction.java104
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/AbsoluteUncenteredCorrelationDistanceFunction.java85
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/ERiCDistanceFunction.java289
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PCABasedCorrelationDistanceFunction.java291
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PearsonCorrelationDistanceFunction.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/SquaredPearsonCorrelationDistanceFunction.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/SquaredUncenteredCorrelationDistanceFunction.java86
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/UncenteredCorrelationDistanceFunction.java124
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedPearsonCorrelationDistanceFunction.java47
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedSquaredPearsonCorrelationDistanceFunction.java43
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/AsciiDistanceParser.java174
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedDoubleDistanceFunction.java79
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedFloatDistanceFunction.java71
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceCacheWriter.java (renamed from src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveDoubleSimilarityFunction.java)40
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParser.java32
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParsingResult.java65
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java137
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedFloatDistanceFunction.java119
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/NumberDistanceParser.java252
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/DimensionSelectingLatLngDistanceFunction.java34
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LatLngDistanceFunction.java66
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LngLatDistanceFunction.java66
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/HistogramMatchDistanceFunction.java46
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/KolmogorovSmirnovDistanceFunction.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/EuclideanDistanceFunction.java51
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/LPIntegerNormDistanceFunction.java53
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/LPNormDistanceFunction.java65
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/ManhattanDistanceFunction.java114
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/MaximumDistanceFunction.java120
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/MinimumDistanceFunction.java52
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseEuclideanDistanceFunction.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseLPNormDistanceFunction.java36
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseManhattanDistanceFunction.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SparseMaximumDistanceFunction.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/SquaredEuclideanDistanceFunction.java178
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedEuclideanDistanceFunction.java80
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedLPNormDistanceFunction.java163
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedManhattanDistanceFunction.java145
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedMaximumDistanceFunction.java81
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/WeightedSquaredEuclideanDistanceFunction.java89
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/minkowski/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/package-info.java9
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/ChiSquaredDistanceFunction.java88
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/HellingerDistanceFunction.java136
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JeffreyDivergenceDistanceFunction.java43
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JensenShannonDivergenceDistanceFunction.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceAsymmetricDistanceFunction.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/SqrtJensenShannonDivergenceDistanceFunction.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/AbstractSetDistanceFunction.java63
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/HammingDistanceFunction.java175
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/JaccardSimilarityDistanceFunction.java (renamed from src/de/lmu/ifi/dbs/elki/distance/similarityfunction/JaccardPrimitiveSimilarityFunction.java)101
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/package-info.java (renamed from src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/package-info.java)7
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/LevenshteinDistanceFunction.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/NormalizedLevenshteinDistanceFunction.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractDimensionsSelectingDistanceFunction.java (renamed from src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractDimensionsSelectingDoubleDistanceFunction.java)71
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractPreferenceVectorBasedCorrelationDistanceFunction.java231
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DiSHDistanceFunction.java163
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingSubspaceDistanceFunction.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/HiSCDistanceFunction.java158
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/LocalSubspaceDistanceFunction.java152
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/OnedimensionalDistanceFunction.java (renamed from src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingDistanceFunction.java)92
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceEuclideanDistanceFunction.java32
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceLPNormDistanceFunction.java61
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceManhattanDistanceFunction.java38
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceMaximumDistanceFunction.java66
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/package-info.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/AbstractEditDistanceFunction.java57
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/DTWDistanceFunction.java171
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/DerivativeDTWDistanceFunction.java154
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/EDRDistanceFunction.java175
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/ERPDistanceFunction.java184
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/LCSSDistanceFunction.java179
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DistanceDBIDResultUtil.java99
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancevalue/AbstractDistance.java116
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancevalue/BitDistance.java224
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancevalue/CorrelationDistance.java198
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancevalue/Distance.java122
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancevalue/DoubleDistance.java221
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancevalue/FloatDistance.java226
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancevalue/IntegerDistance.java194
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancevalue/NumberDistance.java102
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancevalue/PCACorrelationDistance.java144
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancevalue/PreferenceVectorBasedCorrelationDistance.java207
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancevalue/SubspaceDistance.java240
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancevalue/package-info.java34
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/package-info.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractDBIDSimilarityFunction.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractIndexBasedSimilarityFunction.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractPrimitiveSimilarityFunction.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractVectorSimilarityFunction.java (renamed from src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractVectorDoubleSimilarityFunction.java)17
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/DBIDSimilarityFunction.java9
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/FractionalSharedNearestNeighborSimilarityFunction.java24
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/IndexBasedSimilarityFunction.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/InvertedDistanceSimilarityFunction.java19
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski1SimilarityFunction.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski2SimilarityFunction.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedPrimitiveSimilarityFunction.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedSimilarityFunction.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveSimilarityFunction.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SharedNearestNeighborSimilarityFunction.java35
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SimilarityFunction.java19
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/ClusterIntersectionSimilarityFunction.java93
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/ClusterJaccardSimilarityFunction.java107
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/ClusteringAdjustedRandIndexSimilarityFunction.java96
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/package-info.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/KernelMatrix.java15
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/LaplaceKernelFunction.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/LinearKernelFunction.java18
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/PolynomialKernelFunction.java30
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/RadialBasisFunctionKernelFunction.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/RationalQuadraticKernelFunction.java16
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/SigmoidKernelFunction.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/similarityfunction/package-info.java2
165 files changed, 3865 insertions, 6795 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/distance/DistanceUtil.java b/src/de/lmu/ifi/dbs/elki/distance/DistanceUtil.java
deleted file mode 100644
index 8c1b2035..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/DistanceUtil.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-
-/**
- * Class with distance related utility functions.
- *
- * @apiviz.uses de.lmu.ifi.dbs.elki.distance.distancevalue.Distance oneway - -
- * handles
- *
- * @author Erich Schubert
- */
-public final class DistanceUtil {
- /**
- * Returns the maximum of the given Distances or the first, if none is greater
- * than the other one.
- *
- * @param <D> distance type
- * @param d1 first Distance
- * @param d2 second Distance
- * @return Distance the maximum of the given Distances or the first, if
- * neither is greater than the other one
- */
- public static <D extends Distance<D>> D max(D d1, D d2) {
- if(d1 == null) {
- return d2;
- }
- if(d2 == null) {
- return d1;
- }
- if(d1.compareTo(d2) > 0) {
- return d1;
- }
- else if(d2.compareTo(d1) > 0) {
- return d2;
- }
- else {
- return d1;
- }
- }
-
- /**
- * Returns the minimum of the given Distances or the first, if none is less
- * than the other one.
- *
- * @param <D> distance type
- * @param d1 first Distance
- * @param d2 second Distance
- * @return Distance the minimum of the given Distances or the first, if
- * neither is less than the other one
- */
- public static <D extends Distance<D>> D min(D d1, D d2) {
- if(d1 == null) {
- return d2;
- }
- if(d2 == null) {
- return d1;
- }
- if(d1.compareTo(d2) < 0) {
- return d1;
- }
- else if(d2.compareTo(d1) < 0) {
- return d2;
- }
- else {
- return d1;
- }
- }
-
- /**
- * Test whether a distance function is double-valued.
- *
- * @param df Distance function
- * @return True when the distance function returns double values
- */
- public static boolean isDoubleDistanceFunction(DistanceFunction<?, ?> df) {
- Object factory = df.getDistanceFactory();
- return (factory == DoubleDistance.FACTORY) || (factory instanceof DoubleDistance);
- }
-
- /**
- * Test whether a distance query is double-valued.
- *
- * @param df Distance function
- * @return True when the distance function returns double values
- */
- public static boolean isDoubleDistanceFunction(DistanceQuery<?, ?> df) {
- Object factory = df.getDistanceFactory();
- return (factory == DoubleDistance.FACTORY) || (factory instanceof DoubleDistance);
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDBIDDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDBIDRangeDistanceFunction.java
index 84fa0fbe..e754ef1a 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDBIDDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDBIDRangeDistanceFunction.java
@@ -1,10 +1,9 @@
package de.lmu.ifi.dbs.elki.distance.distancefunction;
-
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -27,44 +26,21 @@ import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.query.distance.DBIDDistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.distance.DBIDRangeDistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
/**
- * AbstractDistanceFunction provides some methods valid for any extending class.
- *
- * @author Arthur Zimek
- *
- * @apiviz.excludeSubtypes
+ * Abstract base class for distance functions that rely on integer offsets
+ * within a consecutive range. This is beneficial for external distances.
*
- * @param <D> the type of Distance used
+ * @author Erich Schubert
*/
-public abstract class AbstractDBIDDistanceFunction<D extends Distance<D>> implements DBIDDistanceFunction<D> {
- /**
- * Provides an abstract DistanceFunction.
- */
- protected AbstractDBIDDistanceFunction() {
- // Empty
- }
-
- @Override
- abstract public D distance(DBIDRef o1, DBIDRef o2);
-
- @Override
- abstract public D getDistanceFactory();
-
- @Override
- public boolean isSymmetric() {
- // Assume symmetric by default!
- return true;
- }
-
+public abstract class AbstractDBIDRangeDistanceFunction extends AbstractDatabaseDistanceFunction<DBID> implements DBIDRangeDistanceFunction {
@Override
- public boolean isMetric() {
- // Do NOT assume triangle equation by default!
- return false;
+ public double distance(DBIDRef o1, DBIDRef o2) {
+ throw new AbortException("This must be called via a distance query to determine the DBID offset, not directly.");
}
@Override
@@ -74,7 +50,7 @@ public abstract class AbstractDBIDDistanceFunction<D extends Distance<D>> implem
@SuppressWarnings("unchecked")
@Override
- final public <O extends DBID> DistanceQuery<O, D> instantiate(Relation<O> database) {
- return (DistanceQuery<O, D>) new DBIDDistanceQuery<>((Relation<DBID>) database, this);
+ public final <O extends DBID> DistanceQuery<O> instantiate(Relation<O> database) {
+ return (DistanceQuery<O>) new DBIDRangeDistanceQuery((Relation<DBID>) database, this);
}
-} \ No newline at end of file
+}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDatabaseDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDatabaseDistanceFunction.java
index 3bad6528..0c04bdd0 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDatabaseDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDatabaseDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -25,7 +25,6 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
import de.lmu.ifi.dbs.elki.database.query.distance.AbstractDatabaseDistanceQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Abstract super class for distance functions needing a database context.
@@ -36,22 +35,16 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @apiviz.excludeSubtypes
*
* @param <O> the type of DatabaseObject to compute the distances in between
- * @param <D> the type of Distance used
*/
-public abstract class AbstractDatabaseDistanceFunction<O, D extends Distance<D>> implements DistanceFunction<O, D> {
+public abstract class AbstractDatabaseDistanceFunction<O> implements DistanceFunction<O> {
/**
- * Constructor, supporting
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable} style
- * classes.
+ * Constructor.
*/
public AbstractDatabaseDistanceFunction() {
super();
}
@Override
- abstract public D getDistanceFactory();
-
- @Override
public boolean isMetric() {
return false;
}
@@ -66,11 +59,11 @@ public abstract class AbstractDatabaseDistanceFunction<O, D extends Distance<D>>
*
* @author Erich Schubert
*/
- abstract public static class Instance<O, D extends Distance<D>> extends AbstractDatabaseDistanceQuery<O, D> {
+ abstract public static class Instance<O> extends AbstractDatabaseDistanceQuery<O> {
/**
* Parent distance
*/
- DistanceFunction<? super O, D> parent;
+ DistanceFunction<? super O> parent;
/**
* Constructor.
@@ -78,13 +71,13 @@ public abstract class AbstractDatabaseDistanceFunction<O, D extends Distance<D>>
* @param database Database
* @param parent Parent distance
*/
- public Instance(Relation<O> database, DistanceFunction<? super O, D> parent) {
+ public Instance(Relation<O> database, DistanceFunction<? super O> parent) {
super(database);
this.parent = parent;
}
@Override
- public DistanceFunction<? super O, D> getDistanceFunction() {
+ public DistanceFunction<? super O> getDistanceFunction() {
return parent;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractIndexBasedDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractIndexBasedDistanceFunction.java
index 618a238d..ccb71435 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractIndexBasedDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractIndexBasedDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -26,7 +26,6 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.database.query.distance.AbstractDatabaseDistanceQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.index.Index;
import de.lmu.ifi.dbs.elki.index.IndexFactory;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -44,9 +43,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @param <O> the type of object to compute the distances in between
* @param <I> the type of Index used
- * @param <D> the type of Distance used
*/
-public abstract class AbstractIndexBasedDistanceFunction<O, I extends Index, D extends Distance<D>> extends AbstractDatabaseDistanceFunction<O, D> implements IndexBasedDistanceFunction<O, D> {
+public abstract class AbstractIndexBasedDistanceFunction<O, I extends Index> extends AbstractDatabaseDistanceFunction<O> implements IndexBasedDistanceFunction<O> {
/**
* Parameter to specify the preprocessor to be used.
* <p>
@@ -87,10 +85,9 @@ public abstract class AbstractIndexBasedDistanceFunction<O, I extends Index, D e
*
* @param <O> Object type
* @param <I> Index type
- * @param <D> Distance type
* @param <F> Distance function type
*/
- abstract public static class Instance<O, I extends Index, D extends Distance<D>, F extends DistanceFunction<? super O, D>> extends AbstractDatabaseDistanceQuery<O, D> implements IndexBasedDistanceFunction.Instance<O, I, D> {
+ abstract public static class Instance<O, I extends Index, F extends DistanceFunction<? super O>> extends AbstractDatabaseDistanceQuery<O> implements IndexBasedDistanceFunction.Instance<O, I> {
/**
* Index we use
*/
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractNumberVectorDistanceFunction.java
index e29d9237..21ade27f 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractNumberVectorDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -27,7 +27,6 @@ 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.distancevalue.DoubleDistance;
/**
* Abstract base class for the most common family of distance functions: defined
@@ -38,31 +37,20 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
* @apiviz.landmark
* @apiviz.excludeSubtypes
* @apiviz.uses NumberVector
- * @apiviz.has DoubleDistance
*/
-public abstract class AbstractVectorDoubleDistanceFunction extends AbstractPrimitiveDistanceFunction<NumberVector<?>, DoubleDistance> implements PrimitiveDoubleDistanceFunction<NumberVector<?>>, NumberVectorDistanceFunction<DoubleDistance> {
+public abstract class AbstractNumberVectorDistanceFunction extends AbstractPrimitiveDistanceFunction<NumberVector> implements NumberVectorDistanceFunction<NumberVector> {
/**
* Constructor.
*/
- public AbstractVectorDoubleDistanceFunction() {
+ public AbstractNumberVectorDistanceFunction() {
super();
}
@Override
- public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() {
+ public SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() {
return TypeUtil.NUMBER_VECTOR_FIELD;
}
- @Override
- public final DoubleDistance distance(NumberVector<?> o1, NumberVector<?> o2) {
- return new DoubleDistance(doubleDistance(o1, o2));
- }
-
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
- }
-
/**
* Get the common dimensionality of the two objects. Throw an
* {@link IllegalArgumentException} otherwise.
@@ -107,7 +95,7 @@ public abstract class AbstractVectorDoubleDistanceFunction extends AbstractPrimi
* @return Common dimensionality
* @throws IllegalArgumentException when dimensionalities are not the same.
*/
- public static final int dimensionality(NumberVector<?> o1, NumberVector<?> o2) {
+ public static final int dimensionality(NumberVector o1, NumberVector o2) {
final int dim1 = o1.getDimensionality(), dim2 = o2.getDimensionality();
if (dim1 != dim2) {
throw new IllegalArgumentException("Objects do not have the same dimensionality.");
@@ -125,7 +113,7 @@ public abstract class AbstractVectorDoubleDistanceFunction extends AbstractPrimi
* @return Common dimensionality
* @throws IllegalArgumentException when dimensionalities are not the same.
*/
- public static final int dimensionality(NumberVector<?> o1, NumberVector<?> o2, int expect) {
+ public static final int dimensionality(NumberVector o1, NumberVector o2, int expect) {
final int dim1 = o1.getDimensionality(), dim2 = o2.getDimensionality();
if (dim1 != dim2 || dim1 != expect) {
throw new IllegalArgumentException("Objects do not have the expected dimensionality of " + expect);
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceNorm.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractNumberVectorNorm.java
index 7555bb3a..e5e06716 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceNorm.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractNumberVectorNorm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,7 +24,6 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
/**
* Abstract base class for double-valued number-vector-based distances based on
@@ -34,9 +33,6 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
*
* @apiviz.landmark
*/
-public abstract class AbstractVectorDoubleDistanceNorm extends AbstractVectorDoubleDistanceFunction implements DoubleNorm<NumberVector<?>> {
- @Override
- public DoubleDistance norm(NumberVector<?> obj) {
- return new DoubleDistance(doubleNorm(obj));
- }
+public abstract class AbstractNumberVectorNorm extends AbstractNumberVectorDistanceFunction implements Norm<NumberVector> {
+ // Empty, but adds in the norm interface.
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractPrimitiveDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractPrimitiveDistanceFunction.java
index 7aefd19c..f28b54fa 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractPrimitiveDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractPrimitiveDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -26,7 +26,6 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* AbstractDistanceFunction provides some methods valid for any extending class.
@@ -36,21 +35,17 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @apiviz.excludeSubtypes
*
* @param <O> the type of objects to compute the distances in between
- * @param <D> the type of Distance used
*/
-public abstract class AbstractPrimitiveDistanceFunction<O, D extends Distance<D>> implements PrimitiveDistanceFunction<O, D> {
+public abstract class AbstractPrimitiveDistanceFunction<O> implements PrimitiveDistanceFunction<O> {
/**
- * Provides an abstract DistanceFunction.
+ * Constructor.
*/
public AbstractPrimitiveDistanceFunction() {
// EMPTY
}
@Override
- abstract public D distance(O o1, O o2);
-
- @Override
- abstract public D getDistanceFactory();
+ abstract public double distance(O o1, O o2);
@Override
public boolean isSymmetric() {
@@ -71,7 +66,7 @@ public abstract class AbstractPrimitiveDistanceFunction<O, D extends Distance<D>
* @return Actual distance query.
*/
@Override
- public <T extends O> DistanceQuery<T, D> instantiate(Relation<T> relation) {
+ public <T extends O> DistanceQuery<T> instantiate(Relation<T> relation) {
return new PrimitiveDistanceQuery<>(relation, this);
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDistanceFunction.java
index ef1b28b9..7eb5b28d 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDoubleDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,10 +24,8 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
/**
* Abstract base class for typical distance functions that allow
@@ -39,14 +37,9 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
*
* @author Erich Schubert
*/
-public abstract class AbstractSpatialDoubleDistanceFunction extends AbstractVectorDoubleDistanceFunction implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> {
+public abstract class AbstractSpatialDistanceFunction extends AbstractNumberVectorDistanceFunction implements SpatialPrimitiveDistanceFunction<NumberVector> {
@Override
- final public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
- return new DoubleDistance(doubleMinDist(mbr1, mbr2));
- }
-
- @Override
- public <T extends NumberVector<?>> SpatialPrimitiveDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) {
+ public <T extends NumberVector> SpatialPrimitiveDistanceQuery<T> instantiate(Relation<T> relation) {
return new SpatialPrimitiveDistanceQuery<>(relation, this);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDoubleDistanceNorm.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialNorm.java
index e350f880..5abd7793 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialDoubleDistanceNorm.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractSpatialNorm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,10 +24,8 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
/**
* Abstract base class for typical distance functions that allow
@@ -41,14 +39,9 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
*
* @apiviz.landmark
*/
-public abstract class AbstractSpatialDoubleDistanceNorm extends AbstractVectorDoubleDistanceNorm implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>> {
+public abstract class AbstractSpatialNorm extends AbstractNumberVectorNorm implements SpatialPrimitiveDistanceFunction<NumberVector> {
@Override
- final public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
- return new DoubleDistance(doubleMinDist(mbr1, mbr2));
- }
-
- @Override
- public <T extends NumberVector<?>> SpatialPrimitiveDistanceQuery<T, DoubleDistance> instantiate(Relation<T> relation) {
+ public <T extends NumberVector> SpatialPrimitiveDistanceQuery<T> instantiate(Relation<T> relation) {
return new SpatialPrimitiveDistanceQuery<>(relation, this);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ArcCosineDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ArcCosineDistanceFunction.java
index c95038cc..d186c83c 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ArcCosineDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ArcCosineDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -40,14 +40,14 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
* @author Arthur Zimek
*/
@Alias({ "arccos" })
-public class ArcCosineDistanceFunction extends AbstractSpatialDoubleDistanceFunction {
+public class ArcCosineDistanceFunction extends AbstractSpatialDistanceFunction {
/**
* Static instance
*/
public static final ArcCosineDistanceFunction STATIC = new ArcCosineDistanceFunction();
/**
- * Provides a CosineDistanceFunction.
+ * Constructor - use {@link #STATIC} instead.
*
* @deprecated Use static instance!
*/
@@ -67,18 +67,18 @@ public class ArcCosineDistanceFunction extends AbstractSpatialDoubleDistanceFunc
* @return the cosine distance for two given feature vectors v1 and v2
*/
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
double d = Math.acos(VectorUtil.cosAngle(v1, v2));
- if (d < 0) {
+ if(d < 0) {
d = 0;
}
return d;
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
double d = Math.acos(VectorUtil.minCosAngle(mbr1, mbr2));
- if (d < 0) {
+ if(d < 0) {
d = 0;
}
return d;
@@ -91,17 +91,17 @@ public class ArcCosineDistanceFunction extends AbstractSpatialDoubleDistanceFunc
@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() {
+ public SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() {
return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH;
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/BrayCurtisDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/BrayCurtisDistanceFunction.java
index 20a989fc..a3345fc3 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/BrayCurtisDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/BrayCurtisDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -70,7 +70,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*/
@Alias({ "bray-curtis", "braycurtis", "sorensen", "dice", "sorensen-dice" })
@Reference(authors = "J. R. Bray and J. T. Curtis", title = "An ordination of the upland forest communities of southern Wisconsin", booktitle = "Ecological monographs 27.4", url = "http://dx.doi.org/10.2307/1942268")
-public class BrayCurtisDistanceFunction extends AbstractSpatialDoubleDistanceFunction {
+public class BrayCurtisDistanceFunction extends AbstractSpatialDistanceFunction {
/**
* Static instance.
*/
@@ -103,7 +103,7 @@ public class BrayCurtisDistanceFunction extends AbstractSpatialDoubleDistanceFun
};
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
final int dim = dimensionality(v1, v2);
double sumdiff = 0., sumsum = 0.;
for (int d = 0; d < dim; d++) {
@@ -115,7 +115,7 @@ public class BrayCurtisDistanceFunction extends AbstractSpatialDoubleDistanceFun
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
final int dim = dimensionality(mbr1, mbr2);
double sumdiff = 0., sumsum = 0.;
for (int d = 0; d < dim; d++) {
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CanberraDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CanberraDistanceFunction.java
index 97ef19ce..0efe3c3e 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CanberraDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CanberraDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,6 +24,8 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -35,15 +37,18 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
* Reference:<br />
* G. N. Lance, W. T. Williams<br />
* Computer programs for hierarchical polythetic classification ("similarity
- * analysis")<br />
+ * analyses")<br />
* In: Computer Journal, Volume 9, Issue 1
* </p>
*
* @author Erich Schubert
*/
-@Reference(authors = "G. N. Lance, W. T. Williams", title = "Computer programs for hierarchical polythetic classification (similarity analysis).", booktitle = "Computer Journal, Volume 9, Issue 1", url = "http://comjnl.oxfordjournals.org/content/9/1/60.short")
+@Reference(authors = "G. N. Lance, W. T. Williams", //
+title = "Computer programs for hierarchical polythetic classification (similarity analyses)", //
+booktitle = "Computer Journal, Volume 9, Issue 1", //
+url = "http://comjnl.oxfordjournals.org/content/9/1/60.short")
@Alias({ "canberra" })
-public class CanberraDistanceFunction extends AbstractSpatialDoubleDistanceFunction {
+public class CanberraDistanceFunction extends AbstractSpatialDistanceFunction {
/**
* Static instance. Use this!
*/
@@ -57,30 +62,44 @@ public class CanberraDistanceFunction extends AbstractSpatialDoubleDistanceFunct
}
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
- final int dim = dimensionality(v1, 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 = 0.;
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < mindim; d++) {
final double xd = v1.doubleValue(d), yd = v2.doubleValue(d);
final double div = Math.abs(xd) + Math.abs(yd);
- if (div > 0) {
+ if(div > 0) {
agg += Math.abs(xd - yd) / div;
}
}
+ for(int d = mindim; d < dim1; d++) {
+ if(v1.doubleValue(d) != 0) {
+ agg += 1;
+ }
+ }
+ for(int d = mindim; d < dim2; d++) {
+ if(v2.doubleValue(d) != 0) {
+ agg += 1;
+ }
+ }
return agg;
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
- final int dim = dimensionality(mbr1, mbr2);
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ final int dim1 = mbr1.getDimensionality(), dim2 = mbr2.getDimensionality();
+ final int mindim = (dim1 < dim2) ? dim1 : dim2;
double agg = 0.;
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < mindim; 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;
}
final double a1 = Math.max(-mbr1.getMin(d), mbr1.getMax(d));
@@ -89,6 +108,16 @@ public class CanberraDistanceFunction extends AbstractSpatialDoubleDistanceFunct
// Cannot be 0, because then diff = 0 and we continued above.
agg += diff / div;
}
+ for(int d = mindim; d < dim1; d++) {
+ if(mbr1.getMin(d) > 0. || mbr1.getMax(d) < 0.) {
+ agg += 1;
+ }
+ }
+ for(int d = mindim; d < dim2; d++) {
+ if(mbr2.getMin(d) > 0. || mbr2.getMax(d) < 0.) {
+ agg += 1;
+ }
+ }
return agg;
}
@@ -99,6 +128,11 @@ public class CanberraDistanceFunction extends AbstractSpatialDoubleDistanceFunct
return true;
}
+ @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/ClarkDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ClarkDistanceFunction.java
index 221a7db1..b856729e 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ClarkDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ClarkDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -25,6 +25,8 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -40,7 +42,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
* @author Erich Schubert
*/
@Reference(authors = "M.-M. Deza and E. Deza", title = "Dictionary of distances", booktitle = "Dictionary of distances")
-public class ClarkDistanceFunction extends AbstractSpatialDoubleDistanceFunction {
+public class ClarkDistanceFunction extends AbstractSpatialDistanceFunction {
/**
* Static instance.
*/
@@ -57,10 +59,11 @@ public class ClarkDistanceFunction extends AbstractSpatialDoubleDistanceFunction
}
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
- final int dim = dimensionality(v1, 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 = 0.;
- for (int d = 0; d < dim; d++) {
+ for (int d = 0; d < mindim; d++) {
final double xd = v1.doubleValue(d), yd = v2.doubleValue(d);
final double div = Math.abs(xd) + Math.abs(yd);
if (div > 0.) {
@@ -68,14 +71,25 @@ public class ClarkDistanceFunction extends AbstractSpatialDoubleDistanceFunction
agg += v * v;
}
}
- return Math.sqrt(agg / dim);
+ for(int d = mindim; d < dim1; d++) {
+ if(v1.doubleValue(d) != 0) {
+ agg += 1;
+ }
+ }
+ for(int d = mindim; d < dim2; d++) {
+ if(v2.doubleValue(d) != 0) {
+ agg += 1;
+ }
+ }
+ return Math.sqrt(agg / Math.max(dim1, dim2));
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
- final int dim = dimensionality(mbr1, mbr2);
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ final int dim1 = mbr1.getDimensionality(), dim2 = mbr2.getDimensionality();
+ final int mindim = (dim1 < dim2) ? dim1 : dim2;
double agg = 0.;
- for (int d = 0; d < dim; d++) {
+ for (int d = 0; d < mindim; d++) {
final double min1 = mbr1.getMin(d), max1 = mbr1.getMax(d);
final double min2 = mbr2.getMin(d), max2 = mbr2.getMax(d);
final double diff;
@@ -93,7 +107,22 @@ public class ClarkDistanceFunction extends AbstractSpatialDoubleDistanceFunction
final double v = diff / (absmax1 + absmax2);
agg += v * v;
}
- return Math.sqrt(agg / dim);
+ for(int d = mindim; d < dim1; d++) {
+ if(mbr1.getMin(d) > 0. || mbr1.getMax(d) < 0.) {
+ agg += 1;
+ }
+ }
+ for(int d = mindim; d < dim2; d++) {
+ if(mbr2.getMin(d) > 0. || mbr2.getMax(d) < 0.) {
+ agg += 1;
+ }
+ }
+ return Math.sqrt(agg / Math.max(dim1, dim2));
+ }
+
+ @Override
+ public SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH;
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CosineDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CosineDistanceFunction.java
index bc86b6cf..b345aa47 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CosineDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/CosineDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -40,14 +40,14 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
* @author Arthur Zimek
*/
@Alias({ "cosine" })
-public class CosineDistanceFunction extends AbstractSpatialDoubleDistanceFunction {
+public class CosineDistanceFunction extends AbstractSpatialDistanceFunction {
/**
* Static instance
*/
public static final CosineDistanceFunction STATIC = new CosineDistanceFunction();
/**
- * Provides a CosineDistanceFunction.
+ * Constructor - use {@link #STATIC} instead.
*
* @deprecated Use static instance
*/
@@ -67,7 +67,7 @@ public class CosineDistanceFunction extends AbstractSpatialDoubleDistanceFunctio
* @return the cosine distance for two given feature vectors v1 and v2
*/
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
double d = 1 - VectorUtil.cosAngle(v1, v2);
if (d < 0) {
d = 0;
@@ -76,7 +76,7 @@ public class CosineDistanceFunction extends AbstractSpatialDoubleDistanceFunctio
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
double d = 1 - VectorUtil.minCosAngle(mbr1, mbr2);
if (d < 0) {
d = 0;
@@ -101,7 +101,7 @@ public class CosineDistanceFunction extends AbstractSpatialDoubleDistanceFunctio
}
@Override
- public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() {
+ public SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() {
return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH;
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DBIDDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DBIDDistanceFunction.java
index aea91f40..6553cc39 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DBIDDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DBIDDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -25,7 +25,6 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Distance functions valid in a database context only (i.e. for DBIDs)
@@ -39,10 +38,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
*
* @apiviz.landmark
* @apiviz.uses DBID oneway - - defined on
- *
- * @param <D> Distance type
*/
-public interface DBIDDistanceFunction<D extends Distance<?>> extends DistanceFunction<DBID, D> {
+public interface DBIDDistanceFunction extends DistanceFunction<DBID> {
/**
* Returns the distance between the two objects specified by their object ids.
*
@@ -50,5 +47,5 @@ public interface DBIDDistanceFunction<D extends Distance<?>> extends DistanceFun
* @param id2 second object id
* @return the distance between the two objects specified by their object ids
*/
- D distance(DBIDRef id1, DBIDRef id2);
+ double distance(DBIDRef id1, DBIDRef id2);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DBIDRangeDistanceFunction.java
index 321885b9..8fe7115d 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDoubleDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DBIDRangeDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,27 +23,28 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-
/**
- * Interface for distance functions that can provide a raw double value.
+ * Distance functions valid in a <em>static</em> database context only (i.e. for
+ * DBIDRanges)
+ *
+ * For any "distance" that cannot be computed for arbitrary objects, only those
+ * that exist in the database and referenced by their ID. Furthermore, the IDs
+ * must be contiguous.
*
- * This is for use in performance-critical situations that need to avoid the
- * boxing/unboxing cost of regular distance API.
+ * Example: external precomputed distances
*
* @author Erich Schubert
*
- * @param <O> Object type
+ * @apiviz.landmark
+ * @apiviz.uses de.lmu.ifi.dbs.elki.database.ids.DBIDRange oneway - - defined on
*/
-public interface PrimitiveDoubleDistanceFunction<O> extends PrimitiveDistanceFunction<O, DoubleDistance> {
+public interface DBIDRangeDistanceFunction extends DBIDDistanceFunction {
/**
- * Computes the distance between two given Objects according to this distance
- * function.
+ * Compute the distance for two integer offsets.
*
- * @param o1 first Object
- * @param o2 second Object
- * @return the distance between two given Objects according to this distance
- * function
+ * @param i1 First offset
+ * @param i2 Second offset
+ * @return Distance
*/
- double doubleDistance(O o1, O o2);
+ double distance(int i1, int i2);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DistanceFunction.java
index ae5d2780..8563bd0a 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -26,28 +26,19 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Base interface for any kind of distances.
*
* @author Erich Schubert
- *
+ *
* @param <O> Object type
- * @param <D> Distance result type
*
* @apiviz.landmark
- * @apiviz.has Distance
+ *
+ * @apiviz.has TypeInformation
*/
-public interface DistanceFunction<O, D extends Distance<?>> extends Parameterizable {
- /**
- * Method to get the distance functions factory.
- *
- * @return Factory for distance objects
- */
- D getDistanceFactory();
-
+public interface DistanceFunction<O> {
/**
* Is this function symmetric?
*
@@ -76,5 +67,5 @@ public interface DistanceFunction<O, D extends Distance<?>> extends Parameteriza
* @param relation The representation to use
* @return Actual distance query.
*/
- public <T extends O> DistanceQuery<T, D> instantiate(Relation<T> relation);
+ public <T extends O> DistanceQuery<T> instantiate(Relation<T> relation);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/FilteredLocalPCABasedDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/FilteredLocalPCABasedDistanceFunction.java
deleted file mode 100644
index da2bb2ec..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/FilteredLocalPCABasedDistanceFunction.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancefunction;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.index.Index;
-import de.lmu.ifi.dbs.elki.index.preprocessed.localpca.FilteredLocalPCAIndex;
-
-/**
- * Interface for local PCA based preprocessors.
- *
- * @author Erich Schubert
- *
- * @apiviz.has Instance
- *
- * @param <O> Database object type
- * @param <D> Distance type
- */
-public interface FilteredLocalPCABasedDistanceFunction<O extends NumberVector<?>, P extends FilteredLocalPCAIndex<? super O>, D extends Distance<D>> extends IndexBasedDistanceFunction<O, D> {
- /**
- * Instantiate with a database to get the actual distance query.
- *
- * @param database
- * @return Actual distance query.
- */
- @Override
- public <T extends O> Instance<T, ?, D> instantiate(Relation<T> database);
-
- /**
- * Instance produced by the distance function.
- *
- * @author Erich Schubert
- *
- * @param <T> Database object type
- * @param <I> Index type
- * @param <D> Distance type
- */
- public static interface Instance<T extends NumberVector<?>, I extends Index, D extends Distance<D>> extends IndexBasedDistanceFunction.Instance<T, I, D> {
- // No additional restrictions
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/IndexBasedDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/IndexBasedDistanceFunction.java
index b8f02e94..50d3d9fb 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/IndexBasedDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/IndexBasedDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,7 +24,6 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
*/
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.index.Index;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -36,8 +35,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
* @apiviz.landmark
* @apiviz.stereotype factory
* @apiviz.has Instance oneway - - «create»
+ *
+ * @param <O> Object type
*/
-public interface IndexBasedDistanceFunction<O, D extends Distance<D>> extends DistanceFunction<O, D> {
+public interface IndexBasedDistanceFunction<O> extends DistanceFunction<O> {
/**
* OptionID for the index parameter
*/
@@ -49,9 +50,8 @@ public interface IndexBasedDistanceFunction<O, D extends Distance<D>> extends Di
* @author Erich Schubert
*
* @param <T> Object type
- * @param <D> Distance type
*/
- public static interface Instance<T, I extends Index, D extends Distance<D>> extends DistanceQuery<T, D> {
+ public static interface Instance<T, I extends Index> extends DistanceQuery<T> {
/**
* Get the index used.
*
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Kulczynski1DistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Kulczynski1DistanceFunction.java
index 59b9a29d..eedafa2d 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Kulczynski1DistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Kulczynski1DistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -40,7 +40,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
* @author Erich Schubert
*/
@Reference(authors = "M.-M. Deza and E. Deza", title = "Dictionary of distances", booktitle = "Dictionary of distances")
-public class Kulczynski1DistanceFunction extends AbstractSpatialDoubleDistanceFunction {
+public class Kulczynski1DistanceFunction extends AbstractSpatialDistanceFunction {
/**
* Static instance.
*/
@@ -57,7 +57,7 @@ public class Kulczynski1DistanceFunction extends AbstractSpatialDoubleDistanceFu
}
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
final int dim = dimensionality(v1, v2);
double sumdiff = 0., summin = 0.;
for (int d = 0; d < dim; d++) {
@@ -69,7 +69,7 @@ public class Kulczynski1DistanceFunction extends AbstractSpatialDoubleDistanceFu
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
final int dim = dimensionality(mbr1, mbr2);
double sumdiff = 0., summin = 0.;
for (int d = 0; d < dim; d++) {
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LocallyWeightedDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LocallyWeightedDistanceFunction.java
deleted file mode 100644
index 024240b6..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LocallyWeightedDistanceFunction.java
+++ /dev/null
@@ -1,260 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancefunction;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.LocalProjectionIndex;
-import de.lmu.ifi.dbs.elki.index.preprocessed.localpca.FilteredLocalPCAIndex;
-import de.lmu.ifi.dbs.elki.index.preprocessed.localpca.KNNQueryFilteredPCAIndex;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-
-/**
- * Provides a locally weighted distance function. Computes the quadratic form
- * distance between two vectors P and Q as follows:
- *
- * result = max{dist<sub>P</sub>(P,Q), dist<sub>Q</sub>(Q,P)} where
- * dist<sub>X</sub>(X,Y) = (X-Y)*<b>M<sub>X</sub></b>*(X-Y)<b><sup>T</sup></b>
- * and <b>M<sub>X</sub></b> is the weight matrix of vector X.
- *
- * @author Arthur Zimek
- * @param <V> the type of NumberVector to compute the distances in between
- */
-// FIXME: implements SpatialPrimitiveDistanceFunction<V, DoubleDistance>
-public class LocallyWeightedDistanceFunction<V extends NumberVector<?>> extends AbstractIndexBasedDistanceFunction<V, FilteredLocalPCAIndex<V>, DoubleDistance> implements FilteredLocalPCABasedDistanceFunction<V, FilteredLocalPCAIndex<V>, DoubleDistance> {
- /**
- * Constructor
- *
- * @param indexFactory Index factory
- */
- public LocallyWeightedDistanceFunction(LocalProjectionIndex.Factory<V, FilteredLocalPCAIndex<V>> indexFactory) {
- super(indexFactory);
- }
-
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
- }
-
- @Override
- public boolean isMetric() {
- return false;
- }
-
- @Override
- public boolean isSymmetric() {
- return true;
- }
-
- @Override
- public <T extends V> Instance<T> instantiate(Relation<T> database) {
- // We can't really avoid these warnings, due to a limitation in Java
- // Generics (AFAICT)
- @SuppressWarnings("unchecked")
- LocalProjectionIndex<T, ?> indexinst = (LocalProjectionIndex<T, ?>) indexFactory.instantiate((Relation<V>) database);
- return new Instance<>(database, indexinst, this);
- }
-
- @Override
- public boolean equals(Object obj) {
- if(obj == null) {
- return false;
- }
- if(!this.getClass().equals(obj.getClass())) {
- return false;
- }
- if(this.indexFactory.equals(((LocallyWeightedDistanceFunction<?>) obj).indexFactory)) {
- return false;
- }
- return true;
- }
-
- /**
- * Instance of this distance for a particular database.
- *
- * @author Erich Schubert
- */
- public static class Instance<V extends NumberVector<?>> extends AbstractIndexBasedDistanceFunction.Instance<V, LocalProjectionIndex<V, ?>, DoubleDistance, LocallyWeightedDistanceFunction<? super V>> implements FilteredLocalPCABasedDistanceFunction.Instance<V, LocalProjectionIndex<V, ?>, DoubleDistance> {
- /**
- * Constructor.
- *
- * @param database Database
- * @param index Index
- * @param distanceFunction Distance Function
- */
- public Instance(Relation<V> database, LocalProjectionIndex<V, ?> index, LocallyWeightedDistanceFunction<? super V> distanceFunction) {
- super(database, index, distanceFunction);
- }
-
- /**
- * Computes the distance between two given real vectors according to this
- * distance function.
- *
- * @param id1 first object id
- * @param id2 second object id
- * @return the distance between two given real vectors according to this
- * distance function
- */
- @Override
- public DoubleDistance distance(DBIDRef id1, DBIDRef id2) {
- Matrix m1 = index.getLocalProjection(id1).similarityMatrix();
- Matrix m2 = index.getLocalProjection(id2).similarityMatrix();
-
- if(m1 == null || m2 == null) {
- return new DoubleDistance(Double.POSITIVE_INFINITY);
- }
-
- V v1 = relation.get(id1);
- V v2 = relation.get(id2);
- Vector v1Mv2 = v1.getColumnVector().minusEquals(v2.getColumnVector());
- Vector v2Mv1 = v2.getColumnVector().minusEquals(v1.getColumnVector());
-
- double dist1 = v1Mv2.transposeTimesTimes(m1, v1Mv2);
- double dist2 = v2Mv1.transposeTimesTimes(m2, v2Mv1);
-
- if(dist1 < 0) {
- if(-dist1 < 0.000000000001) {
- dist1 = 0;
- }
- else {
- throw new IllegalArgumentException("dist1 " + dist1 + " < 0!");
- }
- }
- if(dist2 < 0) {
- if(-dist2 < 0.000000000001) {
- dist2 = 0;
- }
- else {
- throw new IllegalArgumentException("dist2 " + dist2 + " < 0!");
- }
- }
-
- return new DoubleDistance(Math.max(Math.sqrt(dist1), Math.sqrt(dist2)));
- }
-
- // @Override
- // TODO: re-enable spatial interfaces
- public DoubleDistance minDistBROKEN(SpatialComparable mbr, V v) {
- if(mbr.getDimensionality() != v.getDimensionality()) {
- throw new IllegalArgumentException("Different dimensionality of objects\n first argument: " + mbr.toString() + "\n second argument: " + v.toString());
- }
-
- double[] r = new double[v.getDimensionality()];
- for(int d = 0; d < v.getDimensionality(); d++) {
- double value = v.doubleValue(d);
- if(value < mbr.getMin(d)) {
- r[d] = mbr.getMin(d);
- }
- else if(value > mbr.getMax(d)) {
- r[d] = mbr.getMax(d);
- }
- else {
- r[d] = value;
- }
- }
-
- Matrix m = null; // index.getLocalProjection(v.getID()).similarityMatrix();
- Vector rv1Mrv2 = v.getColumnVector().minusEquals(new Vector(r));
- double dist = rv1Mrv2.transposeTimesTimes(m, rv1Mrv2);
-
- return new DoubleDistance(Math.sqrt(dist));
- }
-
- // TODO: Remove?
- // @Override
- // public DoubleDistance minDist(SpatialComparable mbr, DBID id) {
- // return minDist(mbr, database.get(id));
- // }
-
- // @Override
- // TODO: re-enable spatial interface
- public DoubleDistance distance(SpatialComparable mbr1, SpatialComparable mbr2) {
- if(mbr1.getDimensionality() != mbr2.getDimensionality()) {
- throw new IllegalArgumentException("Different dimensionality of objects\n first argument: " + mbr1.toString() + "\n second argument: " + mbr2.toString());
- }
-
- double sqrDist = 0;
- for(int d = 0; d < mbr1.getDimensionality(); d++) {
- double m1, m2;
- if(mbr1.getMax(d) < mbr2.getMin(d)) {
- m1 = mbr2.getMin(d);
- m2 = mbr1.getMax(d);
- }
- else if(mbr1.getMin(d) > mbr2.getMax(d)) {
- m1 = mbr1.getMin(d);
- m2 = mbr2.getMax(d);
- }
- else { // The mbrs intersect!
- m1 = 0;
- m2 = 0;
- }
- double manhattanI = m1 - m2;
- sqrDist += manhattanI * manhattanI;
- }
- return new DoubleDistance(Math.sqrt(sqrDist));
- }
-
- // @Override
- // TODO: re-enable spatial interface
- public DoubleDistance centerDistance(SpatialComparable mbr1, SpatialComparable mbr2) {
- if(mbr1.getDimensionality() != mbr2.getDimensionality()) {
- throw new IllegalArgumentException("Different dimensionality of objects\n first argument: " + mbr1.toString() + "\n second argument: " + mbr2.toString());
- }
-
- double sqrDist = 0;
- for(int d = 0; d < mbr1.getDimensionality(); d++) {
- final double c1 = .5 * (mbr1.getMin(d) + mbr1.getMax(d));
- final double c2 = .5 * (mbr2.getMin(d) + mbr2.getMax(d));
- final double manhattanI = c1 - c2;
- sqrDist += manhattanI * manhattanI;
- }
- return new DoubleDistance(Math.sqrt(sqrDist));
- }
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractIndexBasedDistanceFunction.Parameterizer<LocalProjectionIndex.Factory<V, FilteredLocalPCAIndex<V>>> {
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- configIndexFactory(config, LocalProjectionIndex.Factory.class, KNNQueryFilteredPCAIndex.Factory.class);
- }
-
- @Override
- protected LocallyWeightedDistanceFunction<V> makeInstance() {
- return new LocallyWeightedDistanceFunction<>(factory);
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LorentzianDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LorentzianDistanceFunction.java
index 51140f36..b42f4865 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LorentzianDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/LorentzianDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -40,7 +40,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
* @author Erich Schubert
*/
@Reference(authors = "M.-M. Deza and E. Deza", title = "Dictionary of distances", booktitle = "Dictionary of distances")
-public class LorentzianDistanceFunction extends AbstractSpatialDoubleDistanceNorm {
+public class LorentzianDistanceFunction extends AbstractSpatialNorm {
/**
* Static instance.
*/
@@ -57,7 +57,7 @@ public class LorentzianDistanceFunction extends AbstractSpatialDoubleDistanceNor
}
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
final int dim = dimensionality(v1, v2);
double agg = 0.;
for (int d = 0; d < dim; d++) {
@@ -68,7 +68,7 @@ public class LorentzianDistanceFunction extends AbstractSpatialDoubleDistanceNor
}
@Override
- public double doubleNorm(NumberVector<?> v1) {
+ public double norm(NumberVector v1) {
final int dim = v1.getDimensionality();
double agg = 0.;
for (int i = 0; i < dim; i++) {
@@ -79,7 +79,7 @@ public class LorentzianDistanceFunction extends AbstractSpatialDoubleDistanceNor
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
final int dim = dimensionality(mbr1, mbr2);
double agg = 0.;
for (int d = 0; d < dim; d++) {
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MatrixWeightedDistanceFunction.java
index fc155970..dd0390bf 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MatrixWeightedDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -30,37 +30,37 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
/**
- * Provides the Weighted distance for feature vectors.
+ * Weighted distance for feature vectors.
*
* @author Elke Achtert
*/
// TODO: Factory with parameterizable weight matrix?
-public class WeightedDistanceFunction extends AbstractVectorDoubleDistanceFunction {
+public class MatrixWeightedDistanceFunction extends AbstractNumberVectorDistanceFunction {
/**
* The weight matrix.
*/
protected Matrix weightMatrix;
/**
- * Provides the Weighted distance for feature vectors.
+ * Constructor.
*
* @param weightMatrix weight matrix
*/
- public WeightedDistanceFunction(Matrix weightMatrix) {
+ public MatrixWeightedDistanceFunction(Matrix weightMatrix) {
super();
this.weightMatrix = weightMatrix;
assert (weightMatrix.getColumnDimensionality() == weightMatrix.getRowDimensionality());
}
@Override
- public double doubleDistance(NumberVector<?> o1, NumberVector<?> o2) {
+ public double distance(NumberVector o1, NumberVector o2) {
dimensionality(o1, o2, weightMatrix.getColumnDimensionality());
Vector o1_minus_o2 = o1.getColumnVector().minusEquals(o2.getColumnVector());
return MathUtil.mahalanobisDistance(weightMatrix, o1_minus_o2);
}
@Override
- public VectorFieldTypeInformation<? super NumberVector<?>> getInputTypeRestriction() {
- return new VectorFieldTypeInformation<>(NumberVector.class, weightMatrix.getColumnDimensionality());
+ public VectorFieldTypeInformation<? super NumberVector> getInputTypeRestriction() {
+ return VectorFieldTypeInformation.typeRequest(NumberVector.class, weightMatrix.getColumnDimensionality(), weightMatrix.getColumnDimensionality());
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinKDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinKDistance.java
deleted file mode 100644
index 4da3a5dd..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinKDistance.java
+++ /dev/null
@@ -1,258 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancefunction;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
-import de.lmu.ifi.dbs.elki.database.QueryUtil;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
-import de.lmu.ifi.dbs.elki.database.query.distance.AbstractDatabaseDistanceQuery;
-import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.DistanceUtil;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
-
-/**
- * A distance that is at least the distance to the kth nearest neighbor.
- *
- * This is essentially the "reachability distance" of LOF, but with arguments
- * reversed!
- *
- * Reachability of B <em>from</em> A, i.e.
- *
- * <pre>
- * reachability-distance(A,B) = max( k-distance(A), distance(A,B) )
- * </pre>
- *
- * Where <tt>k-distance(A)</tt> is the distance to the k nearest neighbor of A,
- * and <tt>distance</tt> is the actual distance of A and B.
- *
- * This distance is NOT symmetric. You need to pay attention to the order of
- * arguments!
- *
- * @author Erich Schubert
- *
- * @apiviz.uses DistanceFunction
- * @apiviz.has MinKDistance.Instance
- *
- * @param <O> Database object type
- * @param <D> Distance type
- */
-public class MinKDistance<O, D extends Distance<D>> extends AbstractDatabaseDistanceFunction<O, D> {
- /**
- * OptionID for the base distance used to compute reachability
- */
- public static final OptionID DISTANCE_FUNCTION_ID = new OptionID("reachdist.basedistance", "Base distance function to use.");
-
- /**
- * OptionID for the KNN query class to use (preprocessor, approximation, ...)
- */
- public static final OptionID KNNQUERY_ID = new OptionID("reachdist.knnquery", "kNN query to use");
-
- /**
- * OptionID for the "k" parameter.
- */
- public static final OptionID K_ID = new OptionID("reachdist.k", "The number of nearest neighbors of an object to be considered for computing its reachability distance.");
-
- /**
- * The distance function to determine the exact distance.
- */
- protected DistanceFunction<? super O, D> parentDistance;
-
- /**
- * The value of k
- */
- private int k;
-
- /**
- * Include object itself in kNN neighborhood.
- *
- * In the official LOF publication, the point itself is not considered to be
- * part of its k nearest neighbors.
- */
- static boolean objectIsInKNN = false;
-
- /**
- * Full constructor. See {@link Parameterizer} for factory.
- *
- * @param parentDistance distance function to use
- * @param k K parameter
- */
- public MinKDistance(DistanceFunction<? super O, D> parentDistance, int k) {
- super();
- this.parentDistance = parentDistance;
- this.k = k;
- }
-
- @Override
- public <T extends O> DistanceQuery<T, D> instantiate(Relation<T> relation) {
- return new Instance<>(relation, k, parentDistance);
- }
-
- /**
- * Instance for an actual database.
- *
- * @author Erich Schubert
- *
- * @apiviz.uses KNNQuery
- * @apiviz.exclude
- */
- public class Instance<T extends O> extends AbstractDatabaseDistanceQuery<T, D> {
- /**
- * KNN query instance
- */
- private KNNQuery<T, D> knnQuery;
-
- /**
- * Value for k
- */
- private int k;
-
- /**
- * Distance query for parent distance.
- */
- private DistanceQuery<T, D> parentDistanceQuery;
-
- /**
- * Constructor.
- *
- * @param relation Database
- * @param k Value of k
- */
- public Instance(Relation<T> relation, int k, DistanceFunction<? super O, D> parentDistance) {
- super(relation);
- this.k = k;
- this.parentDistanceQuery = parentDistance.instantiate(relation);
- this.knnQuery = QueryUtil.getKNNQuery(relation, parentDistance, k, DatabaseQuery.HINT_HEAVY_USE);
- }
-
- @Override
- public D distance(DBIDRef id1, DBIDRef id2) {
- KNNList<D> neighborhood = knnQuery.getKNNForDBID(id1, k);
- D truedist = parentDistanceQuery.distance(id1, id2);
- return computeReachdist(neighborhood, truedist);
- }
-
- @Override
- public DistanceFunction<? super T, D> getDistanceFunction() {
- return MinKDistance.this;
- }
- }
-
- /**
- * Actually compute the distance, whichever way we obtained the neighborhood
- * above.
- *
- * @param neighborhood Neighborhood
- * @param truedist True distance
- * @return Reachability distance
- */
- protected D computeReachdist(KNNList<D> neighborhood, D truedist) {
- // TODO: need to check neighborhood size?
- // TODO: Do we need to check we actually got the object itself in the
- // neighborhood?
- D kdist = neighborhood.get(neighborhood.size() - 1).getDistance();
- return DistanceUtil.max(kdist, truedist);
- }
-
- @Override
- public boolean isMetric() {
- return false;
- }
-
- @Override
- public boolean isSymmetric() {
- return false;
- }
-
- @Override
- public D getDistanceFactory() {
- return parentDistance.getDistanceFactory();
- }
-
- @Override
- public TypeInformation getInputTypeRestriction() {
- return parentDistance.getInputTypeRestriction();
- }
-
- @Override
- public boolean equals(Object obj) {
- if(obj == null) {
- return false;
- }
- if(!this.getClass().equals(obj.getClass())) {
- return false;
- }
- MinKDistance<?, ?> other = (MinKDistance<?, ?>) obj;
- return this.parentDistance.equals(other.parentDistance) && this.k == other.k;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractParameterizer {
- /**
- * The distance function to determine the exact distance.
- */
- protected DistanceFunction<? super O, D> parentDistance = null;
-
- /**
- * The value of k
- */
- private int k = 0;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- final IntParameter kP = new IntParameter(K_ID);
- kP.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
- if(config.grab(kP)) {
- k = kP.getValue();
- }
-
- final ObjectParameter<DistanceFunction<? super O, D>> parentDistanceP = new ObjectParameter<>(DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
- if(config.grab(parentDistanceP)) {
- parentDistance = parentDistanceP.instantiateClass(config);
- }
- }
-
- @Override
- protected MinKDistance<O, D> makeInstance() {
- return new MinKDistance<>(parentDistance, k + (objectIsInKNN ? 0 : 1));
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Norm.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Norm.java
index ae6605f2..afa338f5 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Norm.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/Norm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,7 +23,6 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Abstract interface for a mathematical norm.
@@ -31,14 +30,13 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public interface Norm<O, D extends Distance<D>> extends DistanceFunction<O, D> {
+public interface Norm<O> extends PrimitiveDistanceFunction<O> {
/**
* Compute the norm of object obj.
*
* @param obj Object
* @return Norm
*/
- public D norm(O obj);
+ public double norm(O obj);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/NumberVectorDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/NumberVectorDistanceFunction.java
index f548c271..f031b7f1 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/NumberVectorDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/NumberVectorDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,17 +24,26 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
- * Base interface for the common case of distance functions defined on numerical vectors.
+ * Base interface for the common case of distance functions defined on numerical
+ * vectors.
*
* @author Erich Schubert
*
* @apiviz.landmark
- *
- * @param <D> Distance type
+ *
+ * @param <O> vector type, usually NumberVector or a parent type
*/
-public interface NumberVectorDistanceFunction<D extends Distance<D>> extends PrimitiveDistanceFunction<NumberVector<?>, D> {
- // Empty - marker interface
+public interface NumberVectorDistanceFunction<O> extends PrimitiveDistanceFunction<O> {
+ /**
+ * Computes the distance between two given vectors according to this distance
+ * function.
+ *
+ * @param o1 first DatabaseObject
+ * @param o2 second DatabaseObject
+ * @return the distance between two given vectors according to this distance
+ * function
+ */
+ double distance(NumberVector o1, NumberVector o2);
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDistanceFunction.java
index 8d293e9a..09951177 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/PrimitiveDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,7 +24,6 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
*/
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Primitive distance function that is defined on some kind of object.
@@ -34,9 +33,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @apiviz.landmark
*
* @param <O> input object type
- * @param <D> distance result type
*/
-public interface PrimitiveDistanceFunction<O, D extends Distance<?>> extends DistanceFunction<O, D> {
+public interface PrimitiveDistanceFunction<O> extends DistanceFunction<O> {
/**
* Computes the distance between two given DatabaseObjects according to this
* distance function.
@@ -46,8 +44,8 @@ public interface PrimitiveDistanceFunction<O, D extends Distance<?>> extends Dis
* @return the distance between two given DatabaseObjects according to this
* distance function
*/
- D distance(O o1, O o2);
-
+ double distance(O o1, O o2);
+
@Override
- SimpleTypeInformation<? super O> getInputTypeRestriction();
+ SimpleTypeInformation<? super O> getInputTypeRestriction();
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ProxyDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ProxyDistanceFunction.java
deleted file mode 100644
index 58dd512a..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/ProxyDistanceFunction.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancefunction;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-
-/**
- * Distance function to proxy computations to another distance (that probably
- * was run before).
- *
- * @author Erich Schubert
- *
- * @param <O> object type
- * @param <D> distance type
- */
-public class ProxyDistanceFunction<O, D extends Distance<D>> extends AbstractDBIDDistanceFunction<D> {
- /**
- * Distance query
- */
- DistanceQuery<O, D> inner;
-
- /**
- * Constructor
- *
- * @param inner Inner distance
- */
- public ProxyDistanceFunction(DistanceQuery<O, D> inner) {
- super();
- this.inner = inner;
- }
-
- /**
- * Static method version.
- *
- * @param <O> Object type
- * @param <D> Distance type
- * @param inner Inner distance query
- * @return Proxy object
- */
- public static <O, D extends Distance<D>> ProxyDistanceFunction<O, D> proxy(DistanceQuery<O, D> inner) {
- return new ProxyDistanceFunction<>(inner);
- }
-
- @Override
- public D distance(DBIDRef o1, DBIDRef o2) {
- return inner.distance(o1, o2);
- }
-
- @Override
- public D getDistanceFactory() {
- return inner.getDistanceFactory();
- }
-
- /**
- * Get the inner query
- *
- * @return query
- */
- public DistanceQuery<O, D> getDistanceQuery() {
- return inner;
- }
-
- /**
- * @param inner the inner distance query to set
- */
- public void setDistanceQuery(DistanceQuery<O, D> inner) {
- this.inner = inner;
- }
-
- /**
- * Helper function, to resolve any wrapped Proxy Distances
- *
- * @param <V> Object type
- * @param <D> Distance type
- * @param dfun Distance function to unwrap.
- * @return unwrapped distance function
- */
- @SuppressWarnings("unchecked")
- public static <V, T extends V, D extends Distance<D>> DistanceFunction<? super V, D> unwrapDistance(DistanceFunction<V, D> dfun) {
- if(ProxyDistanceFunction.class.isInstance(dfun)) {
- return unwrapDistance(((ProxyDistanceFunction<V, D>) dfun).getDistanceQuery().getDistanceFunction());
- }
- return dfun;
- }
-
-
- @Override
- public boolean equals(Object obj) {
- if(obj == null) {
- return false;
- }
- if (!this.getClass().equals(obj.getClass())) {
- return false;
- }
- ProxyDistanceFunction<?, ?> other = (ProxyDistanceFunction<?, ?>) obj;
- return this.inner.equals(other.inner);
- }
-
- @Override
- public int hashCode() {
- return this.inner.hashCode();
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/RandomStableDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/RandomStableDistanceFunction.java
index 3d6d1128..ce95a390 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/RandomStableDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/RandomStableDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -25,9 +25,14 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
import java.util.Random;
+import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.database.query.distance.DBIDDistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.utilities.Util;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -43,9 +48,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Erich Schubert
*/
-public class RandomStableDistanceFunction extends AbstractDBIDDistanceFunction<DoubleDistance> {
- // TODO: add seed parameter!
-
+public class RandomStableDistanceFunction extends AbstractDatabaseDistanceFunction<DBID> implements DBIDDistanceFunction {
/**
* Static instance
*/
@@ -65,16 +68,16 @@ public class RandomStableDistanceFunction extends AbstractDBIDDistanceFunction<D
}
@Override
- public DoubleDistance distance(DBIDRef o1, DBIDRef o2) {
+ public double distance(DBIDRef o1, DBIDRef o2) {
final int c = DBIDUtil.compare(o1, o2);
if(c == 0) {
- return DoubleDistance.FACTORY.nullDistance();
+ return 0.;
}
// Symmetry
if(c > 0) {
return distance(o2, o1);
}
- return new DoubleDistance(pseudoRandom(seed, Util.mixHashCodes(DBIDUtil.deref(o1).hashCode(), DBIDUtil.deref(o2).hashCode(), (int) seed)));
+ return pseudoRandom(seed, Util.mixHashCodes(DBIDUtil.deref(o1).hashCode(), DBIDUtil.deref(o2).hashCode(), (int) seed));
}
/**
@@ -105,11 +108,6 @@ public class RandomStableDistanceFunction extends AbstractDBIDDistanceFunction<D
}
@Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
- }
-
- @Override
public String toString() {
return "RandomDistance";
}
@@ -130,6 +128,17 @@ public class RandomStableDistanceFunction extends AbstractDBIDDistanceFunction<D
return (int) seed;
}
+ @Override
+ public TypeInformation getInputTypeRestriction() {
+ return TypeUtil.DBID;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T extends DBID> DistanceQuery<T> instantiate(Relation<T> relation) {
+ return (DistanceQuery<T>) new DBIDDistanceQuery((Relation<DBID>) relation, this);
+ }
+
/**
* Parameterization class.
*
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SharedNearestNeighborJaccardDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SharedNearestNeighborJaccardDistanceFunction.java
index 29732783..24170cf7 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SharedNearestNeighborJaccardDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SharedNearestNeighborJaccardDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -28,7 +28,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborIndex;
import de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborPreprocessor;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -47,7 +46,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
*
* @param <O> object type
*/
-public class SharedNearestNeighborJaccardDistanceFunction<O> extends AbstractIndexBasedDistanceFunction<O, SharedNearestNeighborIndex<O>, DoubleDistance> {
+public class SharedNearestNeighborJaccardDistanceFunction<O> extends AbstractIndexBasedDistanceFunction<O, SharedNearestNeighborIndex<O>> {
/**
* Constructor.
*
@@ -73,7 +72,7 @@ public class SharedNearestNeighborJaccardDistanceFunction<O> extends AbstractInd
*
* @param <T> Object type
*/
- public static class Instance<T> extends AbstractIndexBasedDistanceFunction.Instance<T, SharedNearestNeighborIndex<T>, DoubleDistance, SharedNearestNeighborJaccardDistanceFunction<T>> {
+ public static class Instance<T> extends AbstractIndexBasedDistanceFunction.Instance<T, SharedNearestNeighborIndex<T>, SharedNearestNeighborJaccardDistanceFunction<T>> {
/**
* Constructor.
*
@@ -124,21 +123,11 @@ public class SharedNearestNeighborJaccardDistanceFunction<O> extends AbstractInd
}
@Override
- public DoubleDistance distance(DBIDRef id1, DBIDRef id2) {
+ public double distance(DBIDRef id1, DBIDRef id2) {
DBIDs neighbors1 = index.getNearestNeighborSet(id1);
DBIDs neighbors2 = index.getNearestNeighborSet(id2);
- return new DoubleDistance(1.0 - jaccardCoefficient(neighbors1, neighbors2));
+ return 1.0 - jaccardCoefficient(neighbors1, neighbors2);
}
-
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
- }
- }
-
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDistanceFunction.java
index 0a2b7840..2baef009 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -26,7 +26,6 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.database.query.distance.SpatialDistanceQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* API for a spatial primitive distance function.
@@ -34,9 +33,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @author Erich Schubert
*
* @param <V> Vector type
- * @param <D> Distance type
*/
-public interface SpatialPrimitiveDistanceFunction<V extends SpatialComparable, D extends Distance<D>> extends PrimitiveDistanceFunction<V, D> {
+public interface SpatialPrimitiveDistanceFunction<V extends SpatialComparable> extends PrimitiveDistanceFunction<V> {
/**
* Computes the distance between the two given MBRs according to this distance
* function.
@@ -46,8 +44,8 @@ public interface SpatialPrimitiveDistanceFunction<V extends SpatialComparable, D
* @return the distance between the two given MBRs according to this distance
* function
*/
- D minDist(SpatialComparable mbr1, SpatialComparable mbr2);
+ double minDist(SpatialComparable mbr1, SpatialComparable mbr2);
@Override
- public <T extends V> SpatialDistanceQuery<T, D> instantiate(Relation<T> relation);
+ public <T extends V> SpatialDistanceQuery<T> instantiate(Relation<T> relation);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDoubleDistanceFunction.java
deleted file mode 100644
index 25a996c6..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDoubleDistanceFunction.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancefunction;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-
-/**
- * Interface combining spatial primitive distance functions with primitive
- * number distance functions. This allows for optimization in the most common
- * types, while not sacrificing generality to support the others.
- *
- * In essence, you should use this interface only in specialized optimized
- * codepaths.
- *
- * @author Erich Schubert
- *
- * @param <V> Vector type
- */
-public interface SpatialPrimitiveDoubleDistanceFunction<V extends SpatialComparable> extends SpatialPrimitiveDistanceFunction<V, DoubleDistance>, PrimitiveDoubleDistanceFunction<V> {
- /**
- * Computes the distance between the two given MBRs according to this
- * distance function.
- *
- * @param mbr1 the first MBR object
- * @param mbr2 the second MBR object
- * @return the distance between the two given MBRs according to this
- * distance function
- */
- double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2);
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedCanberraDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedCanberraDistanceFunction.java
index 66321b36..1fc2bb0b 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedCanberraDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedCanberraDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,15 +24,17 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.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 Canberra distance function, a variation of Manhattan distance.
*
- * TODO: add parameterizer. As of now, this can only be used from Java code.
- *
* @author Erich Schubert
*/
-public class WeightedCanberraDistanceFunction extends AbstractSpatialDoubleDistanceFunction {
+public class WeightedCanberraDistanceFunction extends AbstractSpatialDistanceFunction implements WeightedNumberVectorDistanceFunction<NumberVector> {
/**
* Weight array
*/
@@ -47,13 +49,13 @@ public class WeightedCanberraDistanceFunction extends AbstractSpatialDoubleDista
}
@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 xd = v1.doubleValue(d), yd = v2.doubleValue(d);
final double div = Math.abs(xd) + Math.abs(yd);
- if (div > 0.) {
+ if(div > 0.) {
agg += weights[d] * Math.abs(xd - yd) / div;
}
}
@@ -61,16 +63,18 @@ public class WeightedCanberraDistanceFunction extends AbstractSpatialDoubleDista
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
final int dim = dimensionality(mbr1, mbr2, weights.length);
double agg = 0.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;
}
final double a1 = Math.max(-mbr1.getMin(d), mbr1.getMax(d));
@@ -88,4 +92,32 @@ public class WeightedCanberraDistanceFunction extends AbstractSpatialDoubleDista
// But *maybe* only for positive numbers only?
return true;
}
+
+ /**
+ * 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 WeightedCanberraDistanceFunction makeInstance() {
+ return new WeightedCanberraDistanceFunction(weights);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DoubleNorm.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedNumberVectorDistanceFunction.java
index 6ba5246a..a3824a1a 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DoubleNorm.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedNumberVectorDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,21 +23,18 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
/**
- * Interface for norms in the double domain.
+ * Distance functions where each dimension is assigned a weight.
*
* @author Erich Schubert
*
- * @param <O> Object type
+ * @param <V> Vector type, usually NumberVector or above.
*/
-public interface DoubleNorm<O> extends Norm<O, DoubleDistance>, PrimitiveDoubleDistanceFunction<O> {
+public interface WeightedNumberVectorDistanceFunction<V> extends NumberVectorDistanceFunction<V> {
/**
- * Compute the norm of object obj as double value.
- *
- * @param obj Object
- * @return Double
+ * Parameter to set the weights of the weighted distance function.
*/
- public double doubleNorm(O obj);
-} \ No newline at end of file
+ public static final OptionID WEIGHTS_ID = new OptionID("distance.weights", "Weights to use for the distance function.");
+}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/AbstractSimilarityAdapter.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/AbstractSimilarityAdapter.java
index b2bd9a72..44398dff 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/AbstractSimilarityAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/AbstractSimilarityAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.adapter;
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
@@ -30,17 +30,16 @@ import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractDatabaseDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
-import de.lmu.ifi.dbs.elki.distance.similarityfunction.FractionalSharedNearestNeighborSimilarityFunction;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.NormalizedSimilarityFunction;
+import de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction;
+import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
- * Adapter from a normalized similarity function to a distance function.
+ * Adapter from a similarity function to a distance function.
*
* Note: The derived distance function will usually not satisfy the triangle
* equation.
@@ -51,33 +50,18 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @param <O> object class to process
*/
-public abstract class AbstractSimilarityAdapter<O> extends AbstractDatabaseDistanceFunction<O, DoubleDistance> {
- /**
- * Parameter to specify the similarity function to derive the distance between
- * database objects from. Must extend
- * {@link de.lmu.ifi.dbs.elki.distance.similarityfunction.NormalizedSimilarityFunction}
- * .
- * <p>
- * Key: {@code -adapter.similarityfunction}
- * </p>
- * <p>
- * Default value:
- * {@link de.lmu.ifi.dbs.elki.distance.similarityfunction.FractionalSharedNearestNeighborSimilarityFunction}
- * </p>
- */
- public static final OptionID SIMILARITY_FUNCTION_ID = new OptionID("adapter.similarityfunction", "Similarity function to derive the distance between database objects from.");
-
+public abstract class AbstractSimilarityAdapter<O> extends AbstractDatabaseDistanceFunction<O> {
/**
* Holds the similarity function.
*/
- protected NormalizedSimilarityFunction<? super O> similarityFunction;
+ protected SimilarityFunction<? super O> similarityFunction;
/**
* Constructor.
*
* @param similarityFunction Similarity function to use.
*/
- public AbstractSimilarityAdapter(NormalizedSimilarityFunction<? super O> similarityFunction) {
+ public AbstractSimilarityAdapter(SimilarityFunction<? super O> similarityFunction) {
super();
this.similarityFunction = similarityFunction;
}
@@ -93,20 +77,15 @@ public abstract class AbstractSimilarityAdapter<O> extends AbstractDatabaseDista
}
@Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
- }
-
- @Override
- abstract public <T extends O> DistanceQuery<T, DoubleDistance> instantiate(Relation<T> database);
+ abstract public <T extends O> DistanceQuery<T> instantiate(Relation<T> database);
@Override
public boolean equals(Object obj) {
- if (obj == null) {
+ if(obj == null) {
return false;
}
// Same subclass
- if (!this.getClass().equals(obj.getClass())) {
+ if(!this.getClass().equals(obj.getClass())) {
return false;
}
// Same similarity function
@@ -121,11 +100,11 @@ public abstract class AbstractSimilarityAdapter<O> extends AbstractDatabaseDista
*
* @param <O> Object type
*/
- public abstract static class Instance<O> extends AbstractDatabaseDistanceFunction.Instance<O, DoubleDistance> {
+ public abstract static class Instance<O> extends AbstractDatabaseDistanceFunction.Instance<O> {
/**
* The similarity query we use.
*/
- private SimilarityQuery<? super O, ? extends NumberDistance<?, ?>> similarityQuery;
+ private SimilarityQuery<? super O> similarityQuery;
/**
* Constructor.
@@ -134,7 +113,7 @@ public abstract class AbstractSimilarityAdapter<O> extends AbstractDatabaseDista
* @param parent Parent distance function
* @param similarityQuery Similarity query
*/
- public Instance(Relation<O> database, DistanceFunction<? super O, DoubleDistance> parent, SimilarityQuery<? super O, ? extends NumberDistance<?, ?>> similarityQuery) {
+ public Instance(Relation<O> database, DistanceFunction<? super O> parent, SimilarityQuery<? super O> similarityQuery) {
super(database, parent);
this.similarityQuery = similarityQuery;
}
@@ -148,14 +127,8 @@ public abstract class AbstractSimilarityAdapter<O> extends AbstractDatabaseDista
public abstract double transform(double similarity);
@Override
- public DoubleDistance distance(DBIDRef id1, DBIDRef id2) {
- final NumberDistance<?, ?> sim = similarityQuery.similarity(id1, id2);
- return new DoubleDistance(transform(sim.doubleValue()));
- }
-
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
+ public double distance(DBIDRef id1, DBIDRef id2) {
+ return transform(similarityQuery.similarity(id1, id2));
}
}
@@ -166,19 +139,48 @@ public abstract class AbstractSimilarityAdapter<O> extends AbstractDatabaseDista
*
* @apiviz.exclude
*/
- public abstract static class Parameterizer<O> extends AbstractParameterizer {
+ public abstract static class Parameterizer<O, S extends SimilarityFunction<? super O>> extends AbstractParameterizer {
+ /**
+ * Parameter to specify the similarity function to derive the distance
+ * between database objects from. Must extend
+ * {@link de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction}
+ * .
+ * <p>
+ * Key: {@code -adapter.similarityfunction}
+ * </p>
+ */
+ public static final OptionID SIMILARITY_FUNCTION_ID = new OptionID("adapter.similarityfunction", //
+ "Similarity function to derive the distance between database objects from.");
+
/**
* Holds the similarity function.
*/
- protected NormalizedSimilarityFunction<? super O> similarityFunction = null;
+ protected S similarityFunction = null;
+
+ /**
+ * Arbitrary Similarity functions
+ */
+ protected Class<SimilarityFunction<? super O>> ARBITRARY_SIMILARITY = ClassGenericsUtil.uglyCastIntoSubclass(SimilarityFunction.class);
+
+ /**
+ * Normalized similarity functions
+ */
+ protected Class<NormalizedSimilarityFunction<? super O>> NORMALIZED_SIMILARITY = ClassGenericsUtil.uglyCastIntoSubclass(NormalizedSimilarityFunction.class);
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final ObjectParameter<NormalizedSimilarityFunction<? super O>> param = new ObjectParameter<>(SIMILARITY_FUNCTION_ID, NormalizedSimilarityFunction.class, FractionalSharedNearestNeighborSimilarityFunction.class);
- if (config.grab(param)) {
+ final ObjectParameter<S> param = new ObjectParameter<>(SIMILARITY_FUNCTION_ID, getSimilarityRestriction());
+ if(config.grab(param)) {
similarityFunction = param.instantiateClass(config);
}
}
+
+ /**
+ * Get the similarity function restriction.
+ *
+ * @return Distance function supported.
+ */
+ protected abstract Class<? extends S> getSimilarityRestriction();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/ArccosSimilarityAdapter.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/ArccosSimilarityAdapter.java
index 4bb2b99d..992a42df 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/ArccosSimilarityAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/ArccosSimilarityAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.adapter;
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,8 +27,6 @@ import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.NormalizedSimilarityFunction;
/**
@@ -52,8 +50,8 @@ public class ArccosSimilarityAdapter<O> extends AbstractSimilarityAdapter<O> {
}
@Override
- public <T extends O> DistanceQuery<T, DoubleDistance> instantiate(Relation<T> database) {
- SimilarityQuery<T, ? extends NumberDistance<?, ?>> similarityQuery = similarityFunction.instantiate(database);
+ public <T extends O> DistanceQuery<T> instantiate(Relation<T> database) {
+ SimilarityQuery<T> similarityQuery = similarityFunction.instantiate(database);
return new Instance<>(database, this, similarityQuery);
}
@@ -72,7 +70,7 @@ public class ArccosSimilarityAdapter<O> extends AbstractSimilarityAdapter<O> {
* @param parent Parent distance
* @param similarityQuery similarity Query to use
*/
- public Instance(Relation<O> database, DistanceFunction<? super O, DoubleDistance> parent, SimilarityQuery<O, ? extends NumberDistance<?, ?>> similarityQuery) {
+ public Instance(Relation<O> database, DistanceFunction<? super O> parent, SimilarityQuery<O> similarityQuery) {
super(database, parent, similarityQuery);
}
@@ -89,10 +87,15 @@ public class ArccosSimilarityAdapter<O> extends AbstractSimilarityAdapter<O> {
*
* @apiviz.exclude
*/
- public static class Parameterizer<O> extends AbstractSimilarityAdapter.Parameterizer<O> {
+ public static class Parameterizer<O> extends AbstractSimilarityAdapter.Parameterizer<O, NormalizedSimilarityFunction<? super O>> {
@Override
protected ArccosSimilarityAdapter<O> makeInstance() {
return new ArccosSimilarityAdapter<>(similarityFunction);
}
+
+ @Override
+ protected Class<? extends NormalizedSimilarityFunction<? super O>> getSimilarityRestriction() {
+ return NORMALIZED_SIMILARITY;
+ }
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/LinearAdapterLinear.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/LinearAdapterLinear.java
index 428b2c41..c5d2d5b0 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/LinearAdapterLinear.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/LinearAdapterLinear.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.adapter;
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,8 +27,6 @@ import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.NormalizedSimilarityFunction;
/**
@@ -52,8 +50,8 @@ public class LinearAdapterLinear<O> extends AbstractSimilarityAdapter<O> {
}
@Override
- public <T extends O> DistanceQuery<T, DoubleDistance> instantiate(Relation<T> database) {
- SimilarityQuery<T, ? extends NumberDistance<?, ?>> similarityQuery = similarityFunction.instantiate(database);
+ public <T extends O> DistanceQuery<T> instantiate(Relation<T> database) {
+ SimilarityQuery<T> similarityQuery = similarityFunction.instantiate(database);
return new Instance<>(database, this, similarityQuery);
}
@@ -72,7 +70,7 @@ public class LinearAdapterLinear<O> extends AbstractSimilarityAdapter<O> {
* @param parent Parent distance
* @param similarityQuery similarity Query to use
*/
- public Instance(Relation<O> database, DistanceFunction<? super O, DoubleDistance> parent, SimilarityQuery<? super O, ? extends NumberDistance<?, ?>> similarityQuery) {
+ public Instance(Relation<O> database, DistanceFunction<? super O> parent, SimilarityQuery<? super O> similarityQuery) {
super(database, parent, similarityQuery);
}
@@ -89,10 +87,15 @@ public class LinearAdapterLinear<O> extends AbstractSimilarityAdapter<O> {
*
* @apiviz.exclude
*/
- public static class Parameterizer<O> extends AbstractSimilarityAdapter.Parameterizer<O> {
+ public static class Parameterizer<O> extends AbstractSimilarityAdapter.Parameterizer<O, NormalizedSimilarityFunction<? super O>> {
@Override
protected LinearAdapterLinear<O> makeInstance() {
return new LinearAdapterLinear<>(similarityFunction);
}
+
+ @Override
+ protected Class<? extends NormalizedSimilarityFunction<? super O>> getSimilarityRestriction() {
+ return NORMALIZED_SIMILARITY;
+ }
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/LnSimilarityAdapter.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/LnSimilarityAdapter.java
index cffd9e2a..4bf2b7af 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/LnSimilarityAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/LnSimilarityAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.adapter;
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,8 +27,6 @@ import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.NormalizedSimilarityFunction;
/**
@@ -52,8 +50,8 @@ public class LnSimilarityAdapter<O> extends AbstractSimilarityAdapter<O> {
}
@Override
- public <T extends O> DistanceQuery<T, DoubleDistance> instantiate(Relation<T> database) {
- SimilarityQuery<T, ? extends NumberDistance<?, ?>> similarityQuery = similarityFunction.instantiate(database);
+ public <T extends O> DistanceQuery<T> instantiate(Relation<T> database) {
+ SimilarityQuery<T> similarityQuery = similarityFunction.instantiate(database);
return new Instance<>(database, this, similarityQuery);
}
@@ -72,7 +70,7 @@ public class LnSimilarityAdapter<O> extends AbstractSimilarityAdapter<O> {
* @param parent Parent distance
* @param similarityQuery similarity Query to use
*/
- public Instance(Relation<O> database, DistanceFunction<? super O, DoubleDistance> parent, SimilarityQuery<O, ? extends NumberDistance<?, ?>> similarityQuery) {
+ public Instance(Relation<O> database, DistanceFunction<? super O> parent, SimilarityQuery<O> similarityQuery) {
super(database, parent, similarityQuery);
}
@@ -89,10 +87,15 @@ public class LnSimilarityAdapter<O> extends AbstractSimilarityAdapter<O> {
*
* @apiviz.exclude
*/
- public static class Parameterizer<O> extends AbstractSimilarityAdapter.Parameterizer<O> {
+ public static class Parameterizer<O> extends AbstractSimilarityAdapter.Parameterizer<O, NormalizedSimilarityFunction<? super O>> {
@Override
protected LnSimilarityAdapter<O> makeInstance() {
return new LnSimilarityAdapter<>(similarityFunction);
}
+
+ @Override
+ protected Class<? extends NormalizedSimilarityFunction<? super O>> getSimilarityRestriction() {
+ return NORMALIZED_SIMILARITY;
+ }
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/package-info.java
index 14346688..4cddcf14 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/adapter/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
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HSBHistogramQuadraticDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HSBHistogramQuadraticDistanceFunction.java
index 3dae70e8..dfe9d500 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HSBHistogramQuadraticDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HSBHistogramQuadraticDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram;
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,7 +25,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram;
import java.util.List;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.MatrixWeightedDistanceFunction;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
@@ -50,7 +50,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntListParameter;
* @author Erich Schubert
*/
@Reference(authors = "J. R. Smith, S. F. Chang", title = "VisualSEEk: a fully automated content-based image query system", booktitle = "Proceedings of the fourth ACM international conference on Multimedia 1997", url = "http://dx.doi.org/10.1145/244130.244151")
-public class HSBHistogramQuadraticDistanceFunction extends WeightedDistanceFunction {
+public class HSBHistogramQuadraticDistanceFunction extends MatrixWeightedDistanceFunction {
/**
* Parameter for the kernel dimensionality.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HistogramIntersectionDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HistogramIntersectionDistanceFunction.java
index ffced03f..fbea23ef 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HistogramIntersectionDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/HistogramIntersectionDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram;
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,7 +25,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram;
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.AbstractSpatialDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
@@ -43,7 +43,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@Title("Color histogram intersection distance")
@Description("Distance function for color histograms that emphasizes 'strong' bins.")
@Reference(authors = "M. J. Swain, D. H. Ballard", title = "Color Indexing", booktitle = "International Journal of Computer Vision, 7(1), 32, 1991")
-public class HistogramIntersectionDistanceFunction extends AbstractSpatialDoubleDistanceFunction {
+public class HistogramIntersectionDistanceFunction extends AbstractSpatialDistanceFunction {
/**
* Static instance
*/
@@ -60,7 +60,7 @@ public class HistogramIntersectionDistanceFunction extends AbstractSpatialDouble
}
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
final int dim = dimensionality(v1, v2);
double agg = 0., norm1 = 0., norm2 = 0.;
for (int i = 0; i < dim; i++) {
@@ -74,7 +74,7 @@ public class HistogramIntersectionDistanceFunction extends AbstractSpatialDouble
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
final int dim = dimensionality(mbr1, mbr2);
double agg = 0., norm1 = 0, norm2 = 0.;
for (int i = 0; i < dim; i++) {
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/RGBHistogramQuadraticDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/RGBHistogramQuadraticDistanceFunction.java
index 8cf0339e..3e09a363 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/RGBHistogramQuadraticDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/RGBHistogramQuadraticDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram;
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
@@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.MatrixWeightedDistanceFunction;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -47,7 +47,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* @author Erich Schubert
*/
@Reference(authors = "J. Hafner, H. S.Sawhney, W. Equits, M. Flickner, W. Niblack", title = "Efficient Color Histogram Indexing for Quadratic Form Distance Functions", booktitle = "IEEE Trans. on Pattern Analysis and Machine Intelligence, Vol. 17, No. 7, July 1995", url = "http://dx.doi.org/10.1109/34.391417")
-public class RGBHistogramQuadraticDistanceFunction extends WeightedDistanceFunction {
+public class RGBHistogramQuadraticDistanceFunction extends MatrixWeightedDistanceFunction {
/**
* Parameter for the kernel dimensionality.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/package-info.java
index a61c1e49..33e81a1a 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/colorhistogram/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
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/AbsolutePearsonCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/AbsolutePearsonCorrelationDistanceFunction.java
new file mode 100644
index 00000000..b7d208df
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/AbsolutePearsonCorrelationDistanceFunction.java
@@ -0,0 +1,104 @@
+package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Absolute Pearson correlation distance function for feature vectors.
+ *
+ * The absolute Pearson correlation distance is computed from the Pearson
+ * correlation coefficient <code>r</code> as: <code>1-abs(r)</code>.
+ *
+ * The distance between two vectors will be low (near 0), if their attribute
+ * values are dimension-wise strictly positively or negatively correlated, it
+ * will be high (near 1), if their attribute values are dimension-wise
+ * uncorrelated.
+ *
+ * @author Erich Schubert
+ */
+public class AbsolutePearsonCorrelationDistanceFunction extends AbstractNumberVectorDistanceFunction {
+ /**
+ * Static instance.
+ */
+ public static final AbsolutePearsonCorrelationDistanceFunction STATIC = new AbsolutePearsonCorrelationDistanceFunction();
+
+ /**
+ * Constructor - use {@link #STATIC} instead.
+ *
+ * @deprecated Use static instance!
+ */
+ @Deprecated
+ public AbsolutePearsonCorrelationDistanceFunction() {
+ super();
+ }
+
+ /**
+ * Computes the absolute Pearson correlation distance for two given feature
+ * vectors.
+ *
+ * The absolute Pearson correlation distance is computed from the Pearson
+ * correlation coefficient <code>r</code> as: <code>1-abs(r)</code>. Hence,
+ * possible values of this distance are between 0 and 1.
+ *
+ * @param v1 first feature vector
+ * @param v2 second feature vector
+ * @return the absolute Pearson correlation distance for two given feature
+ * vectors v1 and v2
+ */
+ @Override
+ public double distance(NumberVector v1, NumberVector v2) {
+ return 1 - Math.abs(MathUtil.pearsonCorrelationCoefficient(v1, v2));
+ }
+
+ @Override
+ public String toString() {
+ return "AbsolutePearsonCorrelationDistance";
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == null) {
+ return false;
+ }
+ return this.getClass().equals(obj.getClass());
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected AbsolutePearsonCorrelationDistanceFunction makeInstance() {
+ return AbsolutePearsonCorrelationDistanceFunction.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/AbsoluteUncenteredCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/AbsoluteUncenteredCorrelationDistanceFunction.java
new file mode 100644
index 00000000..d2d7a6ba
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/AbsoluteUncenteredCorrelationDistanceFunction.java
@@ -0,0 +1,85 @@
+package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Absolute uncentered correlation distance function for feature vectors.
+ *
+ * This is highly similar to {@link AbsolutePearsonCorrelationDistanceFunction},
+ * but uses a fixed mean of 0 instead of the sample mean.
+ *
+ * @author Erich Schubert
+ */
+public class AbsoluteUncenteredCorrelationDistanceFunction extends AbstractNumberVectorDistanceFunction {
+ /**
+ * Static instance.
+ */
+ public static final AbsoluteUncenteredCorrelationDistanceFunction STATIC = new AbsoluteUncenteredCorrelationDistanceFunction();
+
+ /**
+ * Constructor - use {@link #STATIC} instead.
+ *
+ * @deprecated Use static instance!
+ */
+ @Deprecated
+ public AbsoluteUncenteredCorrelationDistanceFunction() {
+ super();
+ }
+
+ @Override
+ public double distance(NumberVector v1, NumberVector v2) {
+ return 1. - Math.abs(UncenteredCorrelationDistanceFunction.uncenteredCorrelation(v1, v2));
+ }
+
+ @Override
+ public String toString() {
+ return "AbsoluteUncenteredCorrelationDistance";
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == null) {
+ return false;
+ }
+ return this.getClass().equals(obj.getClass());
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected AbsoluteUncenteredCorrelationDistanceFunction makeInstance() {
+ return AbsoluteUncenteredCorrelationDistanceFunction.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/ERiCDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/ERiCDistanceFunction.java
deleted file mode 100644
index b8c18304..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/ERiCDistanceFunction.java
+++ /dev/null
@@ -1,289 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractIndexBasedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.FilteredLocalPCABasedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.BitDistance;
-import de.lmu.ifi.dbs.elki.index.IndexFactory;
-import de.lmu.ifi.dbs.elki.index.preprocessed.localpca.FilteredLocalPCAIndex;
-import de.lmu.ifi.dbs.elki.index.preprocessed.localpca.KNNQueryFilteredPCAIndex;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredResult;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-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 distance function for building the hierarchy in the ERiC
- * algorithm.
- *
- * @author Elke Achtert
- *
- * @apiviz.has Instance
- */
-public class ERiCDistanceFunction extends AbstractIndexBasedDistanceFunction<NumberVector<?>, FilteredLocalPCAIndex<NumberVector<?>>, BitDistance> implements FilteredLocalPCABasedDistanceFunction<NumberVector<?>, FilteredLocalPCAIndex<NumberVector<?>>, BitDistance> {
- /**
- * Parameter to specify the threshold for approximate linear dependency: the
- * strong eigenvectors of q are approximately linear dependent from the strong
- * eigenvectors p if the following condition holds for all strong eigenvectors
- * q_i of q (lambda_q < lambda_p): q_i' * M^check_p * q_i <= delta^2, must be
- * a double equal to or greater than 0.
- * <p>
- * Default value: {@code 0.1}
- * </p>
- * <p>
- * Key: {@code -ericdf.delta}
- * </p>
- */
- public static final OptionID DELTA_ID = new OptionID("ericdf.delta", "Threshold for approximate linear dependency: " + "the strong eigenvectors of q are approximately linear dependent " + "from the strong eigenvectors p if the following condition " + "holds for all stroneg eigenvectors q_i of q (lambda_q < lambda_p): " + "q_i' * M^check_p * q_i <= delta^2.");
-
- /**
- * Parameter to specify the threshold for the maximum distance between two
- * approximately linear dependent subspaces of two objects p and q (lambda_q <
- * lambda_p) before considering them as parallel, must be a double equal to or
- * greater than 0.
- * <p>
- * Default value: {@code 0.1}
- * </p>
- * <p>
- * Key: {@code -ericdf.tau}
- * </p>
- */
- public static final OptionID TAU_ID = new OptionID("ericdf.tau", "Threshold for the maximum distance between two approximately linear " + "dependent subspaces of two objects p and q " + "(lambda_q < lambda_p) before considering them as parallel.");
-
- /**
- * Holds the value of {@link #DELTA_ID}.
- */
- private double delta;
-
- /**
- * Holds the value of {@link #TAU_ID}.
- */
- private double tau;
-
- /**
- * Constructor.
- *
- * @param indexFactory Index factory.
- * @param delta Delta parameter
- * @param tau Tau parameter
- */
- public ERiCDistanceFunction(IndexFactory<NumberVector<?>, FilteredLocalPCAIndex<NumberVector<?>>> indexFactory, double delta, double tau) {
- super(indexFactory);
- this.delta = delta;
- this.tau = tau;
- }
-
- @Override
- public BitDistance getDistanceFactory() {
- return BitDistance.FACTORY;
- }
-
- @Override
- public <T extends NumberVector<?>> Instance<T> instantiate(Relation<T> database) {
- // We can't really avoid these warnings, due to a limitation in Java
- // Generics (AFAICT)
- @SuppressWarnings("unchecked")
- FilteredLocalPCAIndex<T> indexinst = (FilteredLocalPCAIndex<T>) indexFactory.instantiate((Relation<NumberVector<?>>) database);
- return new Instance<>(database, indexinst, this, delta, tau);
- }
-
- /**
- * Returns true, if the strong eigenvectors of the two specified pcas span up
- * the same space. Note, that the first pca must have equal ore more strong
- * eigenvectors than the second pca.
- *
- * @param pca1 first PCA
- * @param pca2 second PCA
- * @return true, if the strong eigenvectors of the two specified pcas span up
- * the same space
- */
- private boolean approximatelyLinearDependent(PCAFilteredResult pca1, PCAFilteredResult pca2) {
- Matrix m1_czech = pca1.dissimilarityMatrix();
- Matrix v2_strong = pca2.adapatedStrongEigenvectors();
- for(int i = 0; i < v2_strong.getColumnDimensionality(); i++) {
- Vector v2_i = v2_strong.getCol(i);
- // check, if distance of v2_i to the space of pca_1 > delta
- // (i.e., if v2_i spans up a new dimension)
- double dist = Math.sqrt(v2_i.transposeTimes(v2_i) - v2_i.transposeTimesTimes(m1_czech, v2_i));
-
- // if so, return false
- if(dist > delta) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Computes the distance between two given DatabaseObjects according to this
- * distance function. Note, that the first pca must have equal or more strong
- * eigenvectors than the second pca.
- *
- * @param v1 first DatabaseObject
- * @param v2 second DatabaseObject
- * @param pca1 first PCA
- * @param pca2 second PCA
- * @return the distance between two given DatabaseObjects according to this
- * distance function
- */
- public BitDistance distance(NumberVector<?> v1, NumberVector<?> v2, PCAFilteredResult pca1, PCAFilteredResult pca2) {
- if(pca1.getCorrelationDimension() < pca2.getCorrelationDimension()) {
- throw new IllegalStateException("pca1.getCorrelationDimension() < pca2.getCorrelationDimension(): " + pca1.getCorrelationDimension() + " < " + pca2.getCorrelationDimension());
- }
-
- boolean approximatelyLinearDependent;
- if(pca1.getCorrelationDimension() == pca2.getCorrelationDimension()) {
- approximatelyLinearDependent = approximatelyLinearDependent(pca1, pca2) && approximatelyLinearDependent(pca2, pca1);
- }
- else {
- approximatelyLinearDependent = approximatelyLinearDependent(pca1, pca2);
- }
-
- if(!approximatelyLinearDependent) {
- return new BitDistance(true);
- }
-
- else {
- double affineDistance;
-
- if(pca1.getCorrelationDimension() == pca2.getCorrelationDimension()) {
- WeightedDistanceFunction df1 = new WeightedDistanceFunction(pca1.similarityMatrix());
- WeightedDistanceFunction df2 = new WeightedDistanceFunction(pca2.similarityMatrix());
- affineDistance = Math.max(df1.distance(v1, v2).doubleValue(), df2.distance(v1, v2).doubleValue());
- }
- else {
- WeightedDistanceFunction df1 = new WeightedDistanceFunction(pca1.similarityMatrix());
- affineDistance = df1.distance(v1, v2).doubleValue();
- }
-
- if(affineDistance > tau) {
- return new BitDistance(true);
- }
-
- return new BitDistance(false);
- }
- }
-
- @Override
- public boolean equals(Object obj) {
- if(obj == null) {
- return false;
- }
- if(!this.getClass().equals(obj.getClass())) {
- return false;
- }
- ERiCDistanceFunction other = (ERiCDistanceFunction) obj;
- return (this.delta == other.delta) && (this.tau == other.tau);
- }
-
- /**
- * The actual instance bound to a particular database.
- *
- * @author Erich Schubert
- */
- public static class Instance<V extends NumberVector<?>> extends AbstractIndexBasedDistanceFunction.Instance<V, FilteredLocalPCAIndex<V>, BitDistance, ERiCDistanceFunction> implements FilteredLocalPCABasedDistanceFunction.Instance<V, FilteredLocalPCAIndex<V>, BitDistance> {
- /**
- * Holds the value of {@link #DELTA_ID}.
- */
- private final double delta;
-
- /**
- * Holds the value of {@link #TAU_ID}.
- */
- private final double tau;
-
- /**
- * Constructor.
- *
- * @param database Database
- * @param index Index
- * @param parent Parent distance
- * @param delta Delta parameter
- * @param tau Tau parameter
- */
- public Instance(Relation<V> database, FilteredLocalPCAIndex<V> index, ERiCDistanceFunction parent, double delta, double tau) {
- super(database, index, parent);
- this.delta = delta;
- this.tau = tau;
- }
-
- /**
- * Note, that the pca of o1 must have equal ore more strong eigenvectors
- * than the pca of o2.
- */
- @Override
- public BitDistance distance(DBIDRef id1, DBIDRef id2) {
- PCAFilteredResult pca1 = index.getLocalProjection(id1);
- PCAFilteredResult pca2 = index.getLocalProjection(id2);
- V v1 = relation.get(id1);
- V v2 = relation.get(id2);
- return parent.distance(v1, v2, pca1, pca2);
- }
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer extends AbstractIndexBasedDistanceFunction.Parameterizer<IndexFactory<NumberVector<?>, FilteredLocalPCAIndex<NumberVector<?>>>> {
- double delta = 0.0;
-
- double tau = 0.0;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- configIndexFactory(config, FilteredLocalPCAIndex.Factory.class, KNNQueryFilteredPCAIndex.Factory.class);
-
- final DoubleParameter deltaP = new DoubleParameter(DELTA_ID, 0.1);
- deltaP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
- if(config.grab(deltaP)) {
- delta = deltaP.doubleValue();
- }
-
- final DoubleParameter tauP = new DoubleParameter(TAU_ID, 0.1);
- tauP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
- if(config.grab(tauP)) {
- tau = tauP.doubleValue();
- }
- }
-
- @Override
- protected ERiCDistanceFunction makeInstance() {
- return new ERiCDistanceFunction(factory, delta, tau);
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PCABasedCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PCABasedCorrelationDistanceFunction.java
deleted file mode 100644
index b7a22b32..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PCABasedCorrelationDistanceFunction.java
+++ /dev/null
@@ -1,291 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractIndexBasedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.FilteredLocalPCABasedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.PCACorrelationDistance;
-import de.lmu.ifi.dbs.elki.index.IndexFactory;
-import de.lmu.ifi.dbs.elki.index.preprocessed.localpca.FilteredLocalPCAIndex;
-import de.lmu.ifi.dbs.elki.index.preprocessed.localpca.KNNQueryFilteredPCAIndex;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredResult;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-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 the correlation distance for real valued vectors.
- *
- * @author Elke Achtert
- *
- * @apiviz.has Instance
- */
-public class PCABasedCorrelationDistanceFunction extends AbstractIndexBasedDistanceFunction<NumberVector<?>, FilteredLocalPCAIndex<NumberVector<?>>, PCACorrelationDistance> implements FilteredLocalPCABasedDistanceFunction<NumberVector<?>, FilteredLocalPCAIndex<NumberVector<?>>, PCACorrelationDistance> {
- /**
- * Parameter to specify the threshold of a distance between a vector q and a
- * given space that indicates that q adds a new dimension to the space, must
- * be a double equal to or greater than 0.
- * <p>
- * Default value: {@code 0.25}
- * </p>
- * <p>
- * Key: {@code -pcabasedcorrelationdf.delta}
- * </p>
- */
- public static final OptionID DELTA_ID = new OptionID("pcabasedcorrelationdf.delta", "Threshold of a distance between a vector q and a given space that indicates that " + "q adds a new dimension to the space.");
-
- /**
- * Holds the value of {@link #DELTA_ID}.
- */
- private double delta;
-
- /**
- * Constructor
- *
- * @param indexFactory index factory
- * @param delta Delta parameter
- */
- public PCABasedCorrelationDistanceFunction(IndexFactory<NumberVector<?>, FilteredLocalPCAIndex<NumberVector<?>>> indexFactory, double delta) {
- super(indexFactory);
- this.delta = delta;
- }
-
- @Override
- public PCACorrelationDistance getDistanceFactory() {
- return PCACorrelationDistance.FACTORY;
- }
-
- @Override
- public <T extends NumberVector<?>> Instance<T> instantiate(Relation<T> database) {
- // We can't really avoid these warnings, due to a limitation in Java
- // Generics (AFAICT)
- @SuppressWarnings("unchecked")
- FilteredLocalPCAIndex<T> indexinst = (FilteredLocalPCAIndex<T>) indexFactory.instantiate((Relation<NumberVector<?>>) database);
- return new Instance<>(database, indexinst, delta, this);
- }
-
- @Override
- public boolean equals(Object obj) {
- if(obj == null) {
- return false;
- }
- if(!this.getClass().equals(obj.getClass())) {
- return false;
- }
- PCABasedCorrelationDistanceFunction other = (PCABasedCorrelationDistanceFunction) obj;
- return (this.delta == other.delta);
- }
-
- /**
- * The actual instance bound to a particular database.
- *
- * @author Erich Schubert
- */
- public static class Instance<V extends NumberVector<?>> extends AbstractIndexBasedDistanceFunction.Instance<V, FilteredLocalPCAIndex<V>, PCACorrelationDistance, PCABasedCorrelationDistanceFunction> implements FilteredLocalPCABasedDistanceFunction.Instance<V, FilteredLocalPCAIndex<V>, PCACorrelationDistance> {
- /**
- * Delta value
- */
- final double delta;
-
- /**
- * Constructor.
- *
- * @param database Database
- * @param index Index to use
- * @param delta Delta
- * @param distanceFunction Distance function
- */
- public Instance(Relation<V> database, FilteredLocalPCAIndex<V> index, double delta, PCABasedCorrelationDistanceFunction distanceFunction) {
- super(database, index, distanceFunction);
- this.delta = delta;
- }
-
- @Override
- public PCACorrelationDistance distance(DBIDRef id1, DBIDRef id2) {
- PCAFilteredResult pca1 = index.getLocalProjection(id1);
- PCAFilteredResult pca2 = index.getLocalProjection(id2);
- V dv1 = relation.get(id1);
- V dv2 = relation.get(id2);
-
- int correlationDistance = correlationDistance(pca1, pca2, dv1.getDimensionality());
- double euclideanDistance = euclideanDistance(dv1, dv2);
-
- return new PCACorrelationDistance(correlationDistance, euclideanDistance);
- }
-
- /**
- * Computes the correlation distance between the two subspaces defined by
- * the specified PCAs.
- *
- * @param pca1 first PCA
- * @param pca2 second PCA
- * @param dimensionality the dimensionality of the data space
- * @return the correlation distance between the two subspaces defined by the
- * specified PCAs
- */
- public int correlationDistance(PCAFilteredResult pca1, PCAFilteredResult pca2, int dimensionality) {
- // TODO nur in eine Richtung?
- // pca of rv1
- Matrix v1 = pca1.getEigenvectors().copy();
- Matrix v1_strong = pca1.adapatedStrongEigenvectors().copy();
- Matrix e1_czech = pca1.selectionMatrixOfStrongEigenvectors().copy();
- int lambda1 = pca1.getCorrelationDimension();
-
- // pca of rv2
- Matrix v2 = pca2.getEigenvectors().copy();
- Matrix v2_strong = pca2.adapatedStrongEigenvectors().copy();
- Matrix e2_czech = pca2.selectionMatrixOfStrongEigenvectors().copy();
- int lambda2 = pca2.getCorrelationDimension();
-
- // for all strong eigenvectors of rv2
- Matrix m1_czech = pca1.dissimilarityMatrix();
- for(int i = 0; i < v2_strong.getColumnDimensionality(); i++) {
- Vector v2_i = v2_strong.getCol(i);
- // check, if distance of v2_i to the space of rv1 > delta
- // (i.e., if v2_i spans up a new dimension)
- double dist = Math.sqrt(v2_i.transposeTimes(v2_i) - v2_i.transposeTimesTimes(m1_czech, v2_i));
-
- // if so, insert v2_i into v1 and adjust v1
- // and compute m1_czech new, increase lambda1
- if(lambda1 < dimensionality && dist > delta) {
- adjust(v1, e1_czech, v2_i, lambda1++);
- m1_czech = v1.times(e1_czech).timesTranspose(v1);
- }
- }
-
- // for all strong eigenvectors of rv1
- Matrix m2_czech = pca2.dissimilarityMatrix();
- for(int i = 0; i < v1_strong.getColumnDimensionality(); i++) {
- Vector v1_i = v1_strong.getCol(i);
- // check, if distance of v1_i to the space of rv2 > delta
- // (i.e., if v1_i spans up a new dimension)
- double dist = Math.sqrt(v1_i.transposeTimes(v1_i) - v1_i.transposeTimes(m2_czech).times(v1_i).get(0));
-
- // if so, insert v1_i into v2 and adjust v2
- // and compute m2_czech new , increase lambda2
- if(lambda2 < dimensionality && dist > delta) {
- adjust(v2, e2_czech, v1_i, lambda2++);
- m2_czech = v2.times(e2_czech).timesTranspose(v2);
- }
- }
-
- int correlationDistance = Math.max(lambda1, lambda2);
-
- // TODO delta einbauen
- // Matrix m_1_czech = pca1.dissimilarityMatrix();
- // double dist_1 = normalizedDistance(dv1, dv2, m1_czech);
- // Matrix m_2_czech = pca2.dissimilarityMatrix();
- // double dist_2 = normalizedDistance(dv1, dv2, m2_czech);
- // if (dist_1 > delta || dist_2 > delta) {
- // correlationDistance++;
- // }
-
- return correlationDistance;
- }
-
- /**
- * Inserts the specified vector into the given orthonormal matrix
- * <code>v</code> at column <code>corrDim</code>. After insertion the matrix
- * <code>v</code> is orthonormalized and column <code>corrDim</code> of
- * matrix <code>e_czech</code> is set to the <code>corrDim</code>-th unit
- * vector.
- *
- * @param v the orthonormal matrix of the eigenvectors
- * @param e_czech the selection matrix of the strong eigenvectors
- * @param vector the vector to be inserted
- * @param corrDim the column at which the vector should be inserted
- */
- private void adjust(Matrix v, Matrix e_czech, Vector vector, int corrDim) {
- int dim = v.getRowDimensionality();
-
- // set e_czech[corrDim][corrDim] := 1
- e_czech.set(corrDim, corrDim, 1);
-
- // normalize v
- Vector v_i = vector.copy();
- Vector sum = new Vector(dim);
- for(int k = 0; k < corrDim; k++) {
- Vector v_k = v.getCol(k);
- sum.plusTimesEquals(v_k, v_i.transposeTimes(v_k));
- }
- v_i.minusEquals(sum);
- v_i.normalize();
- v.setCol(corrDim, v_i);
- }
-
- /**
- * Computes the Euclidean distance between the given two vectors.
- *
- * @param dv1 first FeatureVector
- * @param dv2 second FeatureVector
- * @return the Euclidean distance between the given two vectors
- */
- private double euclideanDistance(V dv1, V dv2) {
- if(dv1.getDimensionality() != dv2.getDimensionality()) {
- throw new IllegalArgumentException("Different dimensionality of FeatureVectors\n first argument: " + dv1.toString() + "\n second argument: " + dv2.toString());
- }
-
- double sqrDist = 0;
- for(int i = 0; i < dv1.getDimensionality(); i++) {
- double manhattanI = dv1.doubleValue(i) - dv2.doubleValue(i);
- sqrDist += manhattanI * manhattanI;
- }
- return Math.sqrt(sqrDist);
- }
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer extends AbstractIndexBasedDistanceFunction.Parameterizer<FilteredLocalPCAIndex.Factory<NumberVector<?>, FilteredLocalPCAIndex<NumberVector<?>>>> {
- protected double delta = 0.0;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- configIndexFactory(config, FilteredLocalPCAIndex.Factory.class, KNNQueryFilteredPCAIndex.Factory.class);
-
- final DoubleParameter param = new DoubleParameter(DELTA_ID, 0.25);
- param.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
- if(config.grab(param)) {
- delta = param.doubleValue();
- }
- }
-
- @Override
- protected PCABasedCorrelationDistanceFunction makeInstance() {
- return new PCABasedCorrelationDistanceFunction(factory, delta);
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PearsonCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PearsonCorrelationDistanceFunction.java
index 8716ad6e..c8f9d487 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PearsonCorrelationDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/PearsonCorrelationDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation;
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,7 +24,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -43,14 +43,14 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Arthur Zimek
*/
-public class PearsonCorrelationDistanceFunction extends AbstractVectorDoubleDistanceFunction {
+public class PearsonCorrelationDistanceFunction extends AbstractNumberVectorDistanceFunction {
/**
* Static instance.
*/
public static final PearsonCorrelationDistanceFunction STATIC = new PearsonCorrelationDistanceFunction();
/**
- * Provides a PearsonCorrelationDistanceFunction.
+ * Constructor - use {@link #STATIC} instead.
*
* @deprecated Use static instance!
*/
@@ -72,7 +72,7 @@ public class PearsonCorrelationDistanceFunction extends AbstractVectorDoubleDist
* and v2
*/
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
return 1 - MathUtil.pearsonCorrelationCoefficient(v1, v2);
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/SquaredPearsonCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/SquaredPearsonCorrelationDistanceFunction.java
index 8ddb0de6..f44151fc 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/SquaredPearsonCorrelationDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/SquaredPearsonCorrelationDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation;
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,7 +24,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -43,14 +43,14 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Arthur Zimek
*/
-public class SquaredPearsonCorrelationDistanceFunction extends AbstractVectorDoubleDistanceFunction {
+public class SquaredPearsonCorrelationDistanceFunction extends AbstractNumberVectorDistanceFunction {
/**
* Static instance.
*/
public static final SquaredPearsonCorrelationDistanceFunction STATIC = new SquaredPearsonCorrelationDistanceFunction();
/**
- * Provides a SquaredPearsonCorrelationDistanceFunction.
+ * Constructor - use {@link #STATIC} instead.
*
* @deprecated use static instance!
*/
@@ -74,7 +74,7 @@ public class SquaredPearsonCorrelationDistanceFunction extends AbstractVectorDou
* vectors v1 and v2
*/
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
final double pcc = MathUtil.pearsonCorrelationCoefficient(v1, v2);
return 1 - pcc * pcc;
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/SquaredUncenteredCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/SquaredUncenteredCorrelationDistanceFunction.java
new file mode 100644
index 00000000..ff333824
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/SquaredUncenteredCorrelationDistanceFunction.java
@@ -0,0 +1,86 @@
+package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Squared uncentered correlation distance function for feature vectors.
+ *
+ * This is highly similar to {@link SquaredPearsonCorrelationDistanceFunction},
+ * but uses a fixed mean of 0 instead of the sample mean.
+ *
+ * @author Erich Schubert
+ */
+public class SquaredUncenteredCorrelationDistanceFunction extends AbstractNumberVectorDistanceFunction {
+ /**
+ * Static instance.
+ */
+ public static final SquaredUncenteredCorrelationDistanceFunction STATIC = new SquaredUncenteredCorrelationDistanceFunction();
+
+ /**
+ * Constructor - use {@link #STATIC} instead.
+ *
+ * @deprecated Use static instance!
+ */
+ @Deprecated
+ public SquaredUncenteredCorrelationDistanceFunction() {
+ super();
+ }
+
+ @Override
+ public double distance(NumberVector v1, NumberVector v2) {
+ final double pcc = UncenteredCorrelationDistanceFunction.uncenteredCorrelation(v1, v2);
+ return 1. - pcc * pcc;
+ }
+
+ @Override
+ public String toString() {
+ return "SquaredUncenteredCorrelationDistanceFunction";
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == null) {
+ return false;
+ }
+ return this.getClass().equals(obj.getClass());
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected SquaredUncenteredCorrelationDistanceFunction makeInstance() {
+ return SquaredUncenteredCorrelationDistanceFunction.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/UncenteredCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/UncenteredCorrelationDistanceFunction.java
new file mode 100644
index 00000000..96bb4692
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/UncenteredCorrelationDistanceFunction.java
@@ -0,0 +1,124 @@
+package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Uncentered correlation distance.
+ *
+ * This is highly similar to {@link PearsonCorrelationDistanceFunction}, but
+ * uses a fixed mean of 0 instead of the sample mean.
+ *
+ * @author Erich Schubert
+ */
+public class UncenteredCorrelationDistanceFunction extends AbstractNumberVectorDistanceFunction {
+ /**
+ * Static instance.
+ */
+ public static final UncenteredCorrelationDistanceFunction STATIC = new UncenteredCorrelationDistanceFunction();
+
+ /**
+ * Constructor - use {@link #STATIC} instead.
+ *
+ * @deprecated Use static instance!
+ */
+ @Deprecated
+ public UncenteredCorrelationDistanceFunction() {
+ super();
+ }
+
+ /**
+ * Compute the uncentered correlation of two vectors.
+ *
+ * @param x first NumberVector
+ * @param y second NumberVector
+ * @return the uncentered correlation coefficient for x and y
+ */
+ public static double uncenteredCorrelation(NumberVector x, NumberVector y) {
+ final int xdim = x.getDimensionality();
+ final int ydim = y.getDimensionality();
+ if(xdim != ydim) {
+ throw new IllegalArgumentException("Invalid arguments: number vectors differ in dimensionality.");
+ }
+ double sumXX = 0., sumYY = 0., sumXY = 0.;
+ for(int i = 0; i < xdim; i++) {
+ final double xv = x.doubleValue(i), yv = y.doubleValue(i);
+ sumXX += xv * xv;
+ sumYY += yv * yv;
+ sumXY += xv * yv;
+ }
+ // One or both series were constant:
+ if(!(sumXX > 0. && sumYY > 0.)) {
+ return (sumXX == sumYY) ? 1. : 0.;
+ }
+ return sumXY / Math.sqrt(sumXX * sumYY);
+ }
+
+ /**
+ * Computes the Pearson correlation distance for two given feature vectors.
+ *
+ * The Pearson correlation distance is computed from the Pearson correlation
+ * coefficient <code>r</code> as: <code>1-r</code>. Hence, possible values of
+ * this distance are between 0 and 2.
+ *
+ * @param v1 first feature vector
+ * @param v2 second feature vector
+ * @return the Pearson correlation distance for two given feature vectors v1
+ * and v2
+ */
+ @Override
+ public double distance(NumberVector v1, NumberVector v2) {
+ return 1. - uncenteredCorrelation(v1, v2);
+ }
+
+ @Override
+ public String toString() {
+ return "UncenteredCorrelationDistance";
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == null) {
+ return false;
+ }
+ return this.getClass().equals(obj.getClass());
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected UncenteredCorrelationDistanceFunction makeInstance() {
+ return UncenteredCorrelationDistanceFunction.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedPearsonCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedPearsonCorrelationDistanceFunction.java
index 67b1dc27..82d85b30 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedPearsonCorrelationDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedPearsonCorrelationDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation;
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,8 +26,13 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedNumberVectorDistanceFunction;
import de.lmu.ifi.dbs.elki.math.MathUtil;
+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;
/**
* Pearson correlation distance function for feature vectors.
@@ -47,14 +52,14 @@ import de.lmu.ifi.dbs.elki.math.MathUtil;
* @author Arthur Zimek
* @author Erich Schubert
*/
-public class WeightedPearsonCorrelationDistanceFunction extends AbstractVectorDoubleDistanceFunction {
+public class WeightedPearsonCorrelationDistanceFunction extends AbstractNumberVectorDistanceFunction implements WeightedNumberVectorDistanceFunction<NumberVector> {
/**
* Weights
*/
private double[] weights;
/**
- * Provides a PearsonCorrelationDistanceFunction.
+ * Constructor.
*
* @param weights Weights
*/
@@ -76,7 +81,7 @@ public class WeightedPearsonCorrelationDistanceFunction extends AbstractVectorDo
* and v2
*/
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
return 1 - MathUtil.weightedPearsonCorrelationCoefficient(v1, v2, weights);
}
@@ -88,14 +93,42 @@ public class WeightedPearsonCorrelationDistanceFunction extends AbstractVectorDo
if(obj == null) {
return false;
}
- if (!this.getClass().equals(obj.getClass())) {
+ if(!this.getClass().equals(obj.getClass())) {
return false;
}
- return Arrays.equals(this.weights, ((WeightedPearsonCorrelationDistanceFunction)obj).weights);
+ return Arrays.equals(this.weights, ((WeightedPearsonCorrelationDistanceFunction) obj).weights);
}
@Override
public String toString() {
return "WeightedPearsonCorrelationDistanceFunction";
}
+
+ /**
+ * 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 WeightedPearsonCorrelationDistanceFunction makeInstance() {
+ return new WeightedPearsonCorrelationDistanceFunction(weights);
+ }
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedSquaredPearsonCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedSquaredPearsonCorrelationDistanceFunction.java
index 0c1848fc..fd0e3fc1 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedSquaredPearsonCorrelationDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/WeightedSquaredPearsonCorrelationDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation;
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,8 +26,13 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.correlation;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedNumberVectorDistanceFunction;
import de.lmu.ifi.dbs.elki.math.MathUtil;
+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;
/**
* Squared Pearson correlation distance function for feature vectors.
@@ -47,14 +52,14 @@ import de.lmu.ifi.dbs.elki.math.MathUtil;
* @author Arthur Zimek
* @author Erich Schubert
*/
-public class WeightedSquaredPearsonCorrelationDistanceFunction extends AbstractVectorDoubleDistanceFunction {
+public class WeightedSquaredPearsonCorrelationDistanceFunction extends AbstractNumberVectorDistanceFunction implements WeightedNumberVectorDistanceFunction<NumberVector> {
/**
* Weights
*/
private double[] weights;
/**
- * Provides a SquaredPearsonCorrelationDistanceFunction.
+ * Constructor.
*
* @param weights Weights
*/
@@ -78,7 +83,7 @@ public class WeightedSquaredPearsonCorrelationDistanceFunction extends AbstractV
* vectors v1 and v2
*/
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
final double pcc = MathUtil.weightedPearsonCorrelationCoefficient(v1, v2, weights);
return 1 - pcc * pcc;
}
@@ -96,4 +101,32 @@ public class WeightedSquaredPearsonCorrelationDistanceFunction extends AbstractV
}
return Arrays.equals(this.weights, ((WeightedSquaredPearsonCorrelationDistanceFunction)obj).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 WeightedSquaredPearsonCorrelationDistanceFunction makeInstance() {
+ return new WeightedSquaredPearsonCorrelationDistanceFunction(weights);
+ }
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/package-info.java
index c422a3da..61dab3a1 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/correlation/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
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/AsciiDistanceParser.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/AsciiDistanceParser.java
new file mode 100644
index 00000000..4eaeca2e
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/AsciiDistanceParser.java
@@ -0,0 +1,174 @@
+package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.regex.Pattern;
+
+import de.lmu.ifi.dbs.elki.datasource.parser.AbstractParser;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+
+/**
+ * Parser for parsing one distance value per line.
+ *
+ * A line must have the following format: {@code id1 id2 distanceValue}, where
+ * id1 and id2 are integers representing the two ids belonging to the distance
+ * value. Lines starting with &quot;#&quot; will be ignored.
+ *
+ * @author Elke Achtert
+ * @author Erich Schubert
+ */
+@Title("Number Distance Parser")
+@Description("Parser for the following line format:\n" //
+ + "id1 id2 distanceValue, where id1 and is2 are integers representing the two ids belonging to the distance value.\n" //
+ + "The ids and the distance value are separated by whitespace. Empty lines and lines beginning with \"#\" will be ignored.")
+public class AsciiDistanceParser extends AbstractParser implements DistanceParser {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(AsciiDistanceParser.class);
+
+ /**
+ * Constructor.
+ *
+ * @param colSep Column separator pattern
+ * @param quoteChars Quote characters
+ * @param comment Comment pattern
+ */
+ public AsciiDistanceParser(Pattern colSep, String quoteChars, Pattern comment) {
+ super(colSep, quoteChars, comment);
+ }
+
+ @Override
+ public void parse(InputStream in, DistanceCacheWriter cache) {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ int lineNumber = 1;
+
+ int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
+ IndefiniteProgress prog = LOG.isVerbose() ? new IndefiniteProgress("Parsing distance matrix", LOG) : null;
+ try {
+ for(String line; (line = reader.readLine()) != null; lineNumber++) {
+ LOG.incrementProcessed(prog);
+ // Skip empty lines and comments
+ if(line.length() <= 0 || isComment(line)) {
+ continue;
+ }
+ tokenizer.initialize(line, 0, lengthWithoutLinefeed(line));
+
+ if(!tokenizer.valid()) {
+ throw new IllegalArgumentException("Less than three values in line " + lineNumber);
+ }
+ int id1, id2;
+ try {
+ id1 = (int) tokenizer.getLongBase10();
+ tokenizer.advance();
+ }
+ catch(NumberFormatException e) {
+ throw new IllegalArgumentException("Error in line " + lineNumber + ": id1 is not an integer!");
+ }
+ if(!tokenizer.valid()) {
+ throw new IllegalArgumentException("Less than three values in line " + lineNumber);
+ }
+
+ try {
+ id2 = (int) tokenizer.getLongBase10();
+ tokenizer.advance();
+ }
+ catch(NumberFormatException e) {
+ throw new IllegalArgumentException("Error in line " + lineNumber + ": id2 is not an integer!");
+ }
+ if(!tokenizer.valid()) {
+ throw new IllegalArgumentException("Less than three values in line " + lineNumber);
+ }
+
+ // Track minimum and maximum
+ if(id1 < id2) {
+ min = (id1 < min) ? id1 : min;
+ max = (id2 > min) ? id2 : max;
+ }
+ else {
+ min = (id2 < min) ? id2 : min;
+ max = (id1 > min) ? id1 : max;
+ }
+
+ try {
+ double distance = tokenizer.getDouble();
+ cache.put(id1, id2, distance);
+ }
+ catch(IllegalArgumentException e) {
+ throw new IllegalArgumentException("Error in line " + lineNumber + ":" + e.getMessage(), e);
+ }
+ tokenizer.advance();
+ if(tokenizer.valid()) {
+ throw new IllegalArgumentException("More than three values in line " + lineNumber);
+ }
+ }
+ }
+ catch(IOException e) {
+ throw new IllegalArgumentException("Error while parsing line " + lineNumber + ".");
+ }
+
+ LOG.setCompleted(prog);
+
+ // check if all distance values are specified
+ for(int i1 = min; i1 <= max; i1++) {
+ for(int i2 = i1 + 1; i2 <= max; i2++) {
+ if(!cache.containsKey(i1, i2)) {
+ throw new IllegalArgumentException("Distance value for " + i1 + " to " + i2 + " is missing!");
+ }
+ }
+ }
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParser.Parameterizer {
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ }
+
+ @Override
+ protected AsciiDistanceParser makeInstance() {
+ return new AsciiDistanceParser(colSep, quoteChars, comment);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedDoubleDistanceFunction.java
index e84f18b8..0199ec2e 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedDoubleDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedDoubleDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
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,14 +26,11 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
import java.io.File;
import java.io.IOException;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractDBIDDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractDBIDRangeDistanceFunction;
import de.lmu.ifi.dbs.elki.persistent.OnDiskUpperTriangleMatrix;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException;
@@ -41,35 +38,22 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
/**
- * Provides a DistanceFunction that is based on double distances given by a
- * distance matrix of an external file.
+ * Distance function that is based on double distances given by a distance
+ * matrix of an external binary matrix file.
*
* @author Erich Schubert
*/
@Title("File based double distance for database objects.")
@Description("Loads double distance values from an external matrix.")
-public class DiskCacheBasedDoubleDistanceFunction extends AbstractDBIDDistanceFunction<DoubleDistance> {
+public class DiskCacheBasedDoubleDistanceFunction extends AbstractDBIDRangeDistanceFunction {
// TODO: constructor with file.
/**
- * Parameter that specifies the name of the distance matrix file.
- * <p>
- * Key: {@code -distance.matrix}
- * </p>
- */
- public static final OptionID MATRIX_ID = new OptionID("distance.matrix", "The name of the file containing the distance matrix.");
-
- /**
* Magic to identify double cache matrices
*/
public static final int DOUBLE_CACHE_MAGIC = 50902811;
/**
- * Storage required for a double value.
- */
- private static final int DOUBLE_SIZE = 8;
-
- /**
* The distance matrix
*/
private OnDiskUpperTriangleMatrix cache;
@@ -84,47 +68,19 @@ public class DiskCacheBasedDoubleDistanceFunction extends AbstractDBIDDistanceFu
this.cache = cache;
}
- /**
- * Returns the distance between the two objects specified by their objects
- * ids. If a cache is used, the distance value is looked up in the cache. If
- * the distance does not yet exists in cache, it will be computed an put to
- * cache. If no cache is used, the distance is computed.
- *
- * @param id1 first object id
- * @param id2 second object id
- * @return the distance between the two objects specified by their objects ids
- */
@Override
- public DoubleDistance distance(DBIDRef id1, DBIDRef id2) {
- if(id1 == null) {
- return getDistanceFactory().undefinedDistance();
- }
- if(id2 == null) {
- return getDistanceFactory().undefinedDistance();
- }
- final int intid1 = DBIDUtil.asInteger(id1);
- final int intid2 = DBIDUtil.asInteger(id2);
- if(intid1 < 0 || intid2 < 0) {
- throw new AbortException("Negative DBIDs not supported in OnDiskCache");
- }
+ public double distance(int i1, int i2) {
// the smaller id is the first key
- if(intid1 > intid2) {
- return distance(id2, id1);
+ if(i1 > i2) {
+ return distance(i2, i1);
}
- double distance;
try {
- distance = cache.getRecordBuffer(intid1, intid2).getDouble();
+ return cache.getRecordBuffer(i1, i2).getDouble();
}
catch(IOException e) {
- throw new RuntimeException("Read error when loading distance " + id1 + "," + id2 + " from cache file.", e);
+ throw new RuntimeException("Read error when loading distance " + i1 + "," + i2 + " from cache file.", e);
}
- return new DoubleDistance(distance);
- }
-
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
}
@Override
@@ -147,6 +103,17 @@ public class DiskCacheBasedDoubleDistanceFunction extends AbstractDBIDDistanceFu
* @apiviz.exclude
*/
public static class Parameterizer extends AbstractParameterizer {
+ // TODO: constructor with file.
+
+ /**
+ * Parameter that specifies the name of the distance matrix file.
+ * <p>
+ * Key: {@code -distance.matrix}
+ * </p>
+ */
+ public static final OptionID MATRIX_ID = new OptionID("distance.matrix", //
+ "The name of the file containing the distance matrix.");
+
protected OnDiskUpperTriangleMatrix cache = null;
@Override
@@ -156,7 +123,7 @@ public class DiskCacheBasedDoubleDistanceFunction extends AbstractDBIDDistanceFu
if(config.grab(param)) {
File matrixfile = param.getValue();
try {
- cache = new OnDiskUpperTriangleMatrix(matrixfile, DOUBLE_CACHE_MAGIC, 0, DOUBLE_SIZE, false);
+ cache = new OnDiskUpperTriangleMatrix(matrixfile, DOUBLE_CACHE_MAGIC, 0, ByteArrayUtil.SIZE_DOUBLE, false);
}
catch(IOException e) {
config.reportError(new WrongParameterValueException(param, matrixfile.toString(), e));
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedFloatDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedFloatDistanceFunction.java
index cd84853b..8b823056 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedFloatDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DiskCacheBasedFloatDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
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,38 +26,26 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
import java.io.File;
import java.io.IOException;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractDBIDDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.FloatDistance;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractDBIDRangeDistanceFunction;
import de.lmu.ifi.dbs.elki.persistent.OnDiskUpperTriangleMatrix;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
/**
- * Provides a DistanceFunction that is based on float distances given by a
- * distance matrix of an external file.
+ * Distance function that is based on float distances given by a distance matrix
+ * of an external binary matrix file.
*
* @author Erich Schubert
*/
@Title("File based float distance for database objects.")
@Description("Loads float distance values from an external matrix.")
-public class DiskCacheBasedFloatDistanceFunction extends AbstractDBIDDistanceFunction<FloatDistance> {
+public class DiskCacheBasedFloatDistanceFunction extends AbstractDBIDRangeDistanceFunction {
// TODO: constructor with file.
-
- /**
- * Parameter that specifies the name of the distance matrix file.
- * <p>
- * Key: {@code -distance.matrix}
- * </p>
- */
- public static final OptionID MATRIX_ID = new OptionID("distance.matrix", "The name of the file containing the distance matrix.");
/**
* Magic to identify double cache matrices
@@ -65,11 +53,6 @@ public class DiskCacheBasedFloatDistanceFunction extends AbstractDBIDDistanceFun
public static final int FLOAT_CACHE_MAGIC = 23423411;
/**
- * Storage required for a float value.
- */
- private static final int FLOAT_SIZE = 4;
-
- /**
* The distance cache
*/
private OnDiskUpperTriangleMatrix cache;
@@ -84,47 +67,19 @@ public class DiskCacheBasedFloatDistanceFunction extends AbstractDBIDDistanceFun
this.cache = cache;
}
- /**
- * Returns the distance between the two objects specified by their objects
- * ids. If a cache is used, the distance value is looked up in the cache. If
- * the distance does not yet exists in cache, it will be computed an put to
- * cache. If no cache is used, the distance is computed.
- *
- * @param id1 first object id
- * @param id2 second object id
- * @return the distance between the two objects specified by their objects ids
- */
@Override
- public FloatDistance distance(DBIDRef id1, DBIDRef id2) {
- if(id1 == null) {
- return getDistanceFactory().undefinedDistance();
- }
- if(id2 == null) {
- return getDistanceFactory().undefinedDistance();
- }
- final int intid1 = DBIDUtil.asInteger(id1);
- final int intid2 = DBIDUtil.asInteger(id2);
- if(intid1 < 0 || intid2 < 0) {
- throw new AbortException("Negative DBIDs not supported in OnDiskCache");
- }
+ public double distance(int i1, int i2) {
// the smaller id is the first key
- if(intid1 > intid2) {
- return distance(id2, id1);
+ if(i1 > i2) {
+ return distance(i2, i1);
}
- float distance;
try {
- distance = cache.getRecordBuffer(intid1, intid2).getFloat();
+ return cache.getRecordBuffer(i1, i2).getFloat();
}
catch(IOException e) {
- throw new RuntimeException("Read error when loading distance " + id1 + "," + id2 + " from cache file.", e);
+ throw new RuntimeException("Read error when loading distance " + i1 + "," + i2 + " from cache file.", e);
}
- return new FloatDistance(distance);
- }
-
- @Override
- public FloatDistance getDistanceFactory() {
- return FloatDistance.FACTORY;
}
@Override
@@ -152,11 +107,11 @@ public class DiskCacheBasedFloatDistanceFunction extends AbstractDBIDDistanceFun
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final FileParameter param = new FileParameter(MATRIX_ID, FileParameter.FileType.INPUT_FILE);
+ final FileParameter param = new FileParameter(DiskCacheBasedDoubleDistanceFunction.Parameterizer.MATRIX_ID, FileParameter.FileType.INPUT_FILE);
if(config.grab(param)) {
File matrixfile = param.getValue();
try {
- cache = new OnDiskUpperTriangleMatrix(matrixfile, FLOAT_CACHE_MAGIC, 0, FLOAT_SIZE, false);
+ cache = new OnDiskUpperTriangleMatrix(matrixfile, FLOAT_CACHE_MAGIC, 0, ByteArrayUtil.SIZE_FLOAT, false);
}
catch(IOException e) {
config.reportError(new WrongParameterValueException(param, matrixfile.toString(), e));
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveDoubleSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceCacheWriter.java
index 2d886706..3457d335 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveDoubleSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceCacheWriter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.distance.similarityfunction;
+package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
/*
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
@@ -23,27 +23,29 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-
/**
- * Interface for similarity functions that can provide a raw double value.
- *
- * This is for use in performance-critical situations that need to avoid the
- * boxing/unboxing cost of regular distance API.
+ * Interface to plug in the cache storage into the parser.
*
* @author Erich Schubert
- *
- * @param <O> Object type
*/
-public interface PrimitiveDoubleSimilarityFunction<O> extends PrimitiveSimilarityFunction<O, DoubleDistance> {
+public interface DistanceCacheWriter {
+ /**
+ * Puts the specified distance value for the given ids to the distance cache.
+ *
+ * @param id1 the first id offset
+ * @param id2 the second id offset
+ * @param distance the distance value
+ */
+ void put(int id1, int id2, double distance);
+
/**
- * Computes the similarity between two given Objects according to this
- * similarity function.
+ * Returns <tt>true</tt> if the specified distance cache contains a distance
+ * value for the specified ids.
*
- * @param o1 first Object
- * @param o2 second Object
- * @return the similarity between two given Objects according to this
- * similarity function
+ * @param id1 the first id offset
+ * @param id2 the second id offset
+ * @return <tt>true</tt> if this cache contains a distance value for the
+ * specified ids, false otherwise
*/
- double doubleSimilarity(O o1, O o2);
-}
+ boolean containsKey(int id1, int id2);
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParser.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParser.java
index 08c3c312..a1d80ae2 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParser.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParser.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
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,31 +25,21 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
import java.io.InputStream;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-
/**
- * A DistanceParser shall provide a DistanceParsingResult by parsing an InputStream.
- *
- * @author Arthur Zimek
+ * A DistanceParser shall provide a DistanceParsingResult by parsing an
+ * InputStream.
*
- * @apiviz.uses DistanceParsingResult oneway - - «create»
+ * @author Arthur Zimek
*
- * @param <D> distance type
+ * @apiviz.uses DistanceCacheWriter oneway - - «create»
*/
-public interface DistanceParser<D extends Distance<D>> {
- /**
- * Parameter for distance function.
- */
- public static final OptionID DISTANCE_ID = new OptionID("parser.distance", "Distance type used for parsing values.");
-
+public interface DistanceParser {
/**
- * Returns a list of the objects parsed from the specified input stream
- * and a list of the labels associated with the objects.
- *
+ * Returns a list of the objects parsed from the specified input stream and a
+ * list of the labels associated with the objects.
+ *
* @param in the stream to parse objects from
- * @return a list containing those objects parsed
- * from the input stream and their associated labels.
+ * @param cache Cache writer
*/
- DistanceParsingResult<D> parse(InputStream in);
+ void parse(InputStream in, DistanceCacheWriter cache);
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParsingResult.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParsingResult.java
deleted file mode 100644
index 3f43cb97..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceParsingResult.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.util.Map;
-
-import de.lmu.ifi.dbs.elki.database.ids.DBIDPair;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-
-/**
- * Provides a cache of precomputed distances between the database objects.
- *
- * TODO: this class needs to reworked.
- *
- * @author Elke Achtert
- *
- * @param <D> distance type
- */
-public class DistanceParsingResult<D extends Distance<D>> {
- /**
- * The cache of precomputed distances between the database objects.
- */
- private final Map<DBIDPair, D> distanceCache;
-
- /**
- * Provides a list of database objects, a list of label objects associated
- * with these objects and cached distances between these objects.
- *
- * @param distanceCache the cache of precomputed distances between the
- * database objects
- */
- public DistanceParsingResult(Map<DBIDPair, D> distanceCache) {
- this.distanceCache = distanceCache;
- }
-
- /**
- * Returns the cache of precomputed distances between the database objects.
- *
- * @return the cache of precomputed distances between the database objects
- */
- public Map<DBIDPair, D> getDistanceCache() {
- return distanceCache;
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java
index 29546401..055d5d75 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
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
@@ -23,63 +23,44 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import gnu.trove.map.TLongDoubleMap;
+import gnu.trove.map.hash.TLongDoubleHashMap;
+
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.Map;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractDBIDDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractDBIDRangeDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.FileUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ChainedParameterization;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
- * Provides a DistanceFunction that is based on double distances given by a
- * distance matrix of an external file.
+ * Distance function that is based on double distances given by a distance
+ * matrix of an external ascii file.
+ *
+ * See {@link AsciiDistanceParser} for the default input format.
*
- * See {@link NumberDistanceParser} for the default input format.
+ * TODO: use a {@code double[]} instead of the hash map.
*
* @author Elke Achtert
+ * @author Erich Schubert
*/
@Title("File based double distance for database objects.")
@Description("Loads double distance values from an external text file.")
-public class FileBasedDoubleDistanceFunction extends AbstractDBIDDistanceFunction<DoubleDistance> {
- /**
- * Parameter that specifies the name of the distance matrix file.
- * <p>
- * Key: {@code -distance.matrix}
- * </p>
- */
- public static final OptionID MATRIX_ID = new OptionID("distance.matrix", "The name of the file containing the distance matrix.");
-
- /**
- * Optional parameter to specify the parsers to provide a database, must
- * extend {@link DistanceParser}. If this parameter is not set,
- * {@link NumberDistanceParser} is used as parser for all input files.
- * <p>
- * Key: {@code -distance.parser}
- * </p>
- */
- public static final OptionID PARSER_ID = new OptionID("distance.parser", "Parser used to load the distance matrix.");
-
+public class FileBasedDoubleDistanceFunction extends AbstractDBIDRangeDistanceFunction {
/**
* The distance cache
*/
- private Map<DBIDPair, DoubleDistance> cache;
+ private TLongDoubleMap cache;
/**
* Constructor.
@@ -87,7 +68,7 @@ public class FileBasedDoubleDistanceFunction extends AbstractDBIDDistanceFunctio
* @param parser Parser
* @param matrixfile input file
*/
- public FileBasedDoubleDistanceFunction(DistanceParser<DoubleDistance> parser, File matrixfile) {
+ public FileBasedDoubleDistanceFunction(DistanceParser parser, File matrixfile) {
super();
try {
loadCache(parser, matrixfile);
@@ -97,45 +78,41 @@ public class FileBasedDoubleDistanceFunction extends AbstractDBIDDistanceFunctio
}
}
- /**
- * Returns the distance between the two objects specified by their objects
- * ids. If a cache is used, the distance value is looked up in the cache. If
- * the distance does not yet exists in cache, it will be computed an put to
- * cache. If no cache is used, the distance is computed.
- *
- * @param id1 first object id
- * @param id2 second object id
- * @return the distance between the two objects specified by their objects ids
- */
@Override
- public DoubleDistance distance(DBIDRef id1, DBIDRef id2) {
- if(id1 == null) {
- return getDistanceFactory().undefinedDistance();
- }
- if(id2 == null) {
- return getDistanceFactory().undefinedDistance();
+ public double distance(int i1, int i2) {
+ if(i1 == i2) {
+ return 0.;
}
- // the smaller id is the first key
- if(DBIDUtil.compare(id1, id2) > 0) {
- return distance(id2, id1);
- }
-
- DoubleDistance ret = cache.get(DBIDUtil.newPair(id1, id2));
- if (ret == null && DBIDUtil.equal(id1, id2)) {
- return DoubleDistance.ZERO_DISTANCE;
- }
- return ret;
+ return cache.get(makeKey(i1, i2));
}
- private void loadCache(DistanceParser<DoubleDistance> parser, File matrixfile) throws IOException {
+ private void loadCache(DistanceParser parser, File matrixfile) throws IOException {
InputStream in = new BufferedInputStream(FileUtil.tryGzipInput(new FileInputStream(matrixfile)));
- DistanceParsingResult<DoubleDistance> res = parser.parse(in);
- cache = res.getDistanceCache();
+ cache = new TLongDoubleHashMap();
+ parser.parse(in, new DistanceCacheWriter() {
+ @Override
+ public void put(int id1, int id2, double distance) {
+ cache.put(makeKey(id1, id2), distance);
+ }
+
+ @Override
+ public boolean containsKey(int id1, int id2) {
+ return cache.containsKey(makeKey(id1, id2));
+ }
+ });
}
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
+ /**
+ * Combine two integer ids into a long value.
+ *
+ * @param i1 First id
+ * @param i2 Second id
+ * @return Combined value
+ */
+ protected static final long makeKey(int i1, int i2) {
+ return (i1 < i2) //
+ ? ((((long) i1) << 32) | i2)//
+ : ((((long) i2) << 32) | i1);
}
@Override
@@ -158,9 +135,29 @@ public class FileBasedDoubleDistanceFunction extends AbstractDBIDDistanceFunctio
* @apiviz.exclude
*/
public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Parameter that specifies the name of the distance matrix file.
+ * <p>
+ * Key: {@code -distance.matrix}
+ * </p>
+ */
+ public static final OptionID MATRIX_ID = new OptionID("distance.matrix", //
+ "The name of the file containing the distance matrix.");
+
+ /**
+ * Optional parameter to specify the parsers to provide a database, must
+ * extend {@link DistanceParser}. If this parameter is not set,
+ * {@link AsciiDistanceParser} is used as parser for all input files.
+ * <p>
+ * Key: {@code -distance.parser}
+ * </p>
+ */
+ public static final OptionID PARSER_ID = new OptionID("distance.parser", //
+ "Parser used to load the distance matrix.");
+
protected File matrixfile = null;
- protected DistanceParser<DoubleDistance> parser = null;
+ protected DistanceParser parser = null;
@Override
protected void makeOptions(Parameterization config) {
@@ -170,13 +167,9 @@ public class FileBasedDoubleDistanceFunction extends AbstractDBIDDistanceFunctio
matrixfile = MATRIX_PARAM.getValue();
}
- final ObjectParameter<DistanceParser<DoubleDistance>> PARSER_PARAM = new ObjectParameter<>(PARSER_ID, DistanceParser.class, NumberDistanceParser.class);
+ final ObjectParameter<DistanceParser> PARSER_PARAM = new ObjectParameter<>(PARSER_ID, DistanceParser.class, AsciiDistanceParser.class);
if(config.grab(PARSER_PARAM)) {
- ListParameterization parserConfig = new ListParameterization();
- parserConfig.addParameter(DistanceParser.DISTANCE_ID, DoubleDistance.class);
- ChainedParameterization combinedConfig = new ChainedParameterization(parserConfig, config);
- combinedConfig.errorsTo(config);
- parser = PARSER_PARAM.instantiateClass(combinedConfig);
+ parser = PARSER_PARAM.instantiateClass(config);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedFloatDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedFloatDistanceFunction.java
index 994d854d..f39e1fdc 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedFloatDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedFloatDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
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
@@ -23,63 +23,43 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import gnu.trove.map.TLongFloatMap;
+import gnu.trove.map.hash.TLongFloatHashMap;
+
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.Map;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractDBIDDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.FloatDistance;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractDBIDRangeDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.FileUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ChainedParameterization;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
- * Provides a DistanceFunction that is based on float distances given by a
- * distance matrix of an external file.
+ * Distance function that is based on float distances given by a
+ * distance matrix of an external ascii file.
+ *
+ * See {@link AsciiDistanceParser} for the default input format.
*
- * See {@link NumberDistanceParser} for the default input format.
+ * TODO: use a {@code float[]} instead of the hash map.
*
* @author Elke Achtert
+ * @author Erich Schubert
*/
@Title("File based float distance for database objects.")
@Description("Loads float distance values from an external text file.")
-public class FileBasedFloatDistanceFunction extends AbstractDBIDDistanceFunction<FloatDistance> {
- /**
- * Parameter that specifies the name of the distance matrix file.
- * <p>
- * Key: {@code -distance.matrix}
- * </p>
- */
- public static final OptionID MATRIX_ID = new OptionID("distance.matrix", "The name of the file containing the distance matrix.");
-
- /**
- * Optional parameter to specify the parsers to provide a database, must
- * extend {@link DistanceParser}. If this parameter is not set,
- * {@link NumberDistanceParser} is used as parser for all input files.
- * <p>
- * Key: {@code -distance.parser}
- * </p>
- */
- public static final OptionID PARSER_ID = new OptionID("distance.parser", "Parser used to load the distance matrix.");
-
+public class FileBasedFloatDistanceFunction extends AbstractDBIDRangeDistanceFunction {
/**
* The distance cache
*/
- private Map<DBIDPair, FloatDistance> cache;
+ private TLongFloatMap cache;
/**
* Constructor.
@@ -87,7 +67,7 @@ public class FileBasedFloatDistanceFunction extends AbstractDBIDDistanceFunction
* @param parser Parser
* @param matrixfile input file
*/
- public FileBasedFloatDistanceFunction(DistanceParser<FloatDistance> parser, File matrixfile) {
+ public FileBasedFloatDistanceFunction(DistanceParser parser, File matrixfile) {
super();
try {
loadCache(parser, matrixfile);
@@ -97,44 +77,38 @@ public class FileBasedFloatDistanceFunction extends AbstractDBIDDistanceFunction
}
}
- /**
- * Returns the distance between the two objects specified by their objects
- * ids. If a cache is used, the distance value is looked up in the cache. If
- * the distance does not yet exists in cache, it will be computed an put to
- * cache. If no cache is used, the distance is computed.
- *
- * @param id1 first object id
- * @param id2 second object id
- * @return the distance between the two objects specified by their objects ids
- */
@Override
- public FloatDistance distance(DBIDRef id1, DBIDRef id2) {
- if(id1 == null) {
- return getDistanceFactory().undefinedDistance();
- }
- if(id2 == null) {
- return getDistanceFactory().undefinedDistance();
- }
- // the smaller id is the first key
- if(DBIDUtil.compare(id1, id2) > 0) {
- return distance(id2, id1);
- }
- FloatDistance ret = cache.get(DBIDUtil.newPair(id1, id2));
- if (ret == null && DBIDUtil.equal(id1, id2)) {
- return FloatDistance.ZERO_DISTANCE;
- }
- return ret;
+ public double distance(int i1, int i2) {
+ return (i1 == i2) ? 0. : cache.get(makeKey(i1, i2));
}
- private void loadCache(DistanceParser<FloatDistance> parser, File matrixfile) throws IOException {
+ private void loadCache(DistanceParser parser, File matrixfile) throws IOException {
InputStream in = new BufferedInputStream(FileUtil.tryGzipInput(new FileInputStream(matrixfile)));
- DistanceParsingResult<FloatDistance> res = parser.parse(in);
- cache = res.getDistanceCache();
+ cache = new TLongFloatHashMap();
+ parser.parse(in, new DistanceCacheWriter() {
+ @Override
+ public void put(int id1, int id2, double distance) {
+ cache.put(makeKey(id1, id2), (float) distance);
+ }
+
+ @Override
+ public boolean containsKey(int id1, int id2) {
+ return cache.containsKey(makeKey(id1, id2));
+ }
+ });
}
- @Override
- public FloatDistance getDistanceFactory() {
- return FloatDistance.FACTORY;
+ /**
+ * Combine two integer ids into a long value.
+ *
+ * @param i1 First id
+ * @param i2 Second id
+ * @return Combined value
+ */
+ protected static final long makeKey(int i1, int i2) {
+ return (i1 < i2) //
+ ? ((((long) i1) << 32) | i2)//
+ : ((((long) i2) << 32) | i1);
}
@Override
@@ -159,22 +133,19 @@ public class FileBasedFloatDistanceFunction extends AbstractDBIDDistanceFunction
public static class Parameterizer extends AbstractParameterizer {
protected File matrixfile = null;
- protected DistanceParser<FloatDistance> parser = null;
+ protected DistanceParser parser = null;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final FileParameter MATRIX_PARAM = new FileParameter(MATRIX_ID, FileParameter.FileType.INPUT_FILE);
+ final FileParameter MATRIX_PARAM = new FileParameter(FileBasedDoubleDistanceFunction.Parameterizer.MATRIX_ID, FileParameter.FileType.INPUT_FILE);
if(config.grab(MATRIX_PARAM)) {
matrixfile = MATRIX_PARAM.getValue();
}
- final ObjectParameter<DistanceParser<FloatDistance>> PARSER_PARAM = new ObjectParameter<>(PARSER_ID, DistanceParser.class, NumberDistanceParser.class);
+
+ final ObjectParameter<DistanceParser> PARSER_PARAM = new ObjectParameter<>(FileBasedDoubleDistanceFunction.Parameterizer.PARSER_ID, DistanceParser.class, AsciiDistanceParser.class);
if(config.grab(PARSER_PARAM)) {
- ListParameterization parserConfig = new ListParameterization();
- parserConfig.addParameter(DistanceParser.DISTANCE_ID, FloatDistance.class);
- ChainedParameterization combinedConfig = new ChainedParameterization(parserConfig, config);
- combinedConfig.errorsTo(config);
- parser = PARSER_PARAM.instantiateClass(combinedConfig);
+ parser = PARSER_PARAM.instantiateClass(config);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/NumberDistanceParser.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/NumberDistanceParser.java
deleted file mode 100644
index b8e720ab..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/NumberDistanceParser.java
+++ /dev/null
@@ -1,252 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.datasource.parser.AbstractParser;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
-import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
-import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
-
-/**
- * Provides a parser for parsing one distance value per line.
- * <p/>
- * A line must have the following format: id1 id2 distanceValue, where id1 and
- * id2 are integers representing the two ids belonging to the distance value.
- * Lines starting with &quot;#&quot; will be ignored.
- *
- * @author Elke Achtert
- *
- * @apiviz.has NumberDistance
- *
- * @param <D> distance type
- */
-@Title("Number Distance Parser")
-@Description("Parser for the following line format:\n" + "id1 id2 distanceValue, where id1 and is2 are integers representing the two ids belonging to the distance value.\n" + " The ids and the distance value are separated by whitespace. Empty lines and lines beginning with \"#\" will be ignored.")
-public class NumberDistanceParser<D extends NumberDistance<D, ?>> extends AbstractParser implements DistanceParser<D> {
- /**
- * The logger for this class.
- */
- private static final Logging LOG = Logging.getLogger(NumberDistanceParser.class);
-
- /**
- * The distance function.
- */
- private final D distanceFactory;
-
- /**
- * Constructor.
- *
- * @param colSep Column separator pattern
- * @param quoteChars Quote characters
- * @param comment Comment pattern
- * @param distanceFactory Distance factory to use
- */
- public NumberDistanceParser(Pattern colSep, String quoteChars, Pattern comment, D distanceFactory) {
- super(colSep, quoteChars, comment);
- this.distanceFactory = distanceFactory;
- }
-
- @Override
- public DistanceParsingResult<D> parse(InputStream in) {
- BufferedReader reader = new BufferedReader(new InputStreamReader(in));
- int lineNumber = 0;
-
- IndefiniteProgress prog = LOG.isVerbose() ? new IndefiniteProgress("Parsing distance matrix", LOG) : null;
- ModifiableDBIDs ids = DBIDUtil.newHashSet();
- Map<DBIDPair, D> distanceCache = new HashMap<>();
- try {
- for(String line; (line = reader.readLine()) != null; lineNumber++) {
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
- // Skip empty lines and comments
- if(line.length() <= 0 || (comment != null && comment.matcher(line).matches())) {
- continue;
- }
- tokenizer.initialize(line, 0, lengthWithoutLinefeed(line));
-
- if(!tokenizer.valid()) {
- throw new IllegalArgumentException("Less than three values in line " + lineNumber);
- }
- DBID id1, id2;
- try {
- id1 = DBIDUtil.importInteger((int) tokenizer.getLongBase10());
- tokenizer.advance();
- }
- catch(NumberFormatException e) {
- throw new IllegalArgumentException("Error in line " + lineNumber + ": id1 is no integer!");
- }
- if(!tokenizer.valid()) {
- throw new IllegalArgumentException("Less than three values in line " + lineNumber);
- }
-
- try {
- id2 = DBIDUtil.importInteger((int) tokenizer.getLongBase10());
- tokenizer.advance();
- }
- catch(NumberFormatException e) {
- throw new IllegalArgumentException("Error in line " + lineNumber + ": id2 is no integer!");
- }
- if(!tokenizer.valid()) {
- throw new IllegalArgumentException("Less than three values in line " + lineNumber);
- }
-
- try {
- final D distance;
- if(distanceFactory == DoubleDistance.FACTORY) {
- @SuppressWarnings("unchecked")
- D dist = (D) DoubleDistance.FACTORY.fromDouble(tokenizer.getDouble());
- distance = dist;
- }
- else {
- distance = distanceFactory.parseString(tokenizer.getSubstring());
- }
- tokenizer.advance();
- put(id1, id2, distance, distanceCache);
- ids.add(id1);
- ids.add(id2);
- }
- catch(IllegalArgumentException e) {
- throw new IllegalArgumentException("Error in line " + lineNumber + ":" + e.getMessage(), e);
- }
- if(tokenizer.valid()) {
- throw new IllegalArgumentException("More than three values in line " + lineNumber);
- }
- }
- }
- catch(IOException e) {
- throw new IllegalArgumentException("Error while parsing line " + lineNumber + ".");
- }
-
- if(prog != null) {
- prog.setCompleted(LOG);
- }
-
- // check if all distance values are specified
- for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- for(DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) {
- if(DBIDUtil.compare(iter2, iter) <= 0) {
- continue;
- }
- if(!containsKey(iter, iter2, distanceCache)) {
- throw new IllegalArgumentException("Distance value for " + DBIDUtil.toString(iter) + " - " + DBIDUtil.toString(iter2) + " is missing!");
- }
- }
- }
- return new DistanceParsingResult<>(distanceCache);
- }
-
- /**
- * Puts the specified distance value for the given ids to the distance cache.
- *
- * @param id1 the first id
- * @param id2 the second id
- * @param distance the distance value
- * @param cache the distance cache
- */
- private void put(DBID id1, DBID id2, D distance, Map<DBIDPair, D> cache) {
- // the smaller id is the first key
- if(DBIDUtil.compare(id1, id2) > 0) {
- put(id2, id1, distance, cache);
- return;
- }
-
- D oldDistance = cache.put(DBIDUtil.newPair(id1, id2), distance);
-
- if(oldDistance != null) {
- throw new IllegalArgumentException("Distance value for specified ids is already assigned!");
- }
- }
-
- /**
- * Returns <tt>true</tt> if the specified distance cache contains a distance
- * value for the specified ids.
- *
- * @param id1 the first id
- * @param id2 the second id
- * @param cache the distance cache
- * @return <tt>true</tt> if this cache contains a distance value for the
- * specified ids, false otherwise
- */
- public boolean containsKey(DBIDRef id1, DBIDRef id2, Map<DBIDPair, D> cache) {
- if(DBIDUtil.compare(id1, id2) > 0) {
- return containsKey(id2, id1, cache);
- }
-
- return cache.containsKey(DBIDUtil.newPair(id1, id2));
- }
-
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<D extends NumberDistance<D, ?>> extends AbstractParser.Parameterizer {
- /**
- * The distance function.
- */
- protected D distanceFactory;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- ObjectParameter<D> distFuncP = new ObjectParameter<>(DISTANCE_ID, Distance.class);
- if(config.grab(distFuncP)) {
- distanceFactory = distFuncP.instantiateClass(config);
- }
- }
-
- @Override
- protected NumberDistanceParser<D> makeInstance() {
- return new NumberDistanceParser<>(colSep, quoteChars, comment, distanceFactory);
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/package-info.java
index 53b692fa..42e27b92 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/package-info.java
@@ -6,7 +6,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
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/DimensionSelectingLatLngDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/DimensionSelectingLatLngDistanceFunction.java
index 8eea1f15..b821f019 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/DimensionSelectingLatLngDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/DimensionSelectingLatLngDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.geo;
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.VectorFieldTypeInformation;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDistanceFunction;
import de.lmu.ifi.dbs.elki.math.geodesy.EarthModel;
import de.lmu.ifi.dbs.elki.math.geodesy.SphericalVincentyEarthModel;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
@@ -43,9 +43,23 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
* Distance function for 2D vectors in Latitude, Longitude form.
*
+ * The input data must be in degrees (not radians), and the output distance will
+ * be in meters (see {@link EarthModel#distanceDeg}).
+ *
+ * This implementation allows index accelerated queries using R*-trees (by
+ * providing a point-to-rectangle minimum distance), as published in:
+ * <p>
+ * Erich Schubert, Arthur Zimek and Hans-Peter Kriegel<br />
+ * Geodetic Distance Queries on R-Trees for Indexing Geographic Data<br />
+ * Advances in Spatial and Temporal Databases - 13th International Symposium,
+ * SSTD 2013, Munich, Germany
+ * </p>
+ *
* @author Erich Schubert
+ *
+ * @apiviz.composedOf EarthModel
*/
-public class DimensionSelectingLatLngDistanceFunction extends AbstractSpatialDoubleDistanceFunction {
+public class DimensionSelectingLatLngDistanceFunction extends AbstractSpatialDistanceFunction {
/**
* Latitude dimension.
*/
@@ -76,25 +90,25 @@ public class DimensionSelectingLatLngDistanceFunction extends AbstractSpatialDou
}
@Override
- public double doubleDistance(NumberVector<?> o1, NumberVector<?> o2) {
+ public double distance(NumberVector o1, NumberVector o2) {
return model.distanceDeg(o1.doubleValue(dimlat), o1.doubleValue(dimlng), o2.doubleValue(dimlat), o2.doubleValue(dimlng));
}
@Override
@Reference(authors = "Erich Schubert, Arthur Zimek and Hans-Peter Kriegel", title = "Geodetic Distance Queries on R-Trees for Indexing Geographic Data", booktitle = "Advances in Spatial and Temporal Databases - 13th International Symposium, SSTD 2013, Munich, Germany")
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
if(mbr1 instanceof NumberVector) {
if(mbr2 instanceof NumberVector) {
- return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2);
+ return distance((NumberVector) mbr1, (NumberVector) mbr2);
}
else {
- NumberVector<?> o1 = (NumberVector<?>) mbr1;
+ NumberVector o1 = (NumberVector) mbr1;
return model.minDistDeg(o1.doubleValue(dimlat), o1.doubleValue(dimlng), mbr2.getMin(dimlat), mbr2.getMin(dimlng), mbr2.getMax(dimlat), mbr2.getMax(dimlng));
}
}
else {
if(mbr2 instanceof NumberVector) {
- NumberVector<?> o2 = (NumberVector<?>) mbr2;
+ NumberVector o2 = (NumberVector) mbr2;
return model.minDistDeg(o2.doubleValue(dimlat), o2.doubleValue(dimlng), mbr1.getMin(dimlat), mbr1.getMin(dimlng), mbr1.getMax(dimlat), mbr1.getMax(dimlng));
}
else {
@@ -104,8 +118,8 @@ public class DimensionSelectingLatLngDistanceFunction extends AbstractSpatialDou
}
@Override
- public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() {
- return new VectorFieldTypeInformation<>(NumberVector.class, Math.max(dimlat, dimlng), Integer.MAX_VALUE);
+ public SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() {
+ return VectorFieldTypeInformation.typeRequest(NumberVector.class, Math.max(dimlat, dimlng), Integer.MAX_VALUE);
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LatLngDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LatLngDistanceFunction.java
index 221cfa2b..b0e3be68 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LatLngDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LatLngDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.geo;
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,8 +26,8 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.geo;
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.AbstractSpatialDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDistanceFunction;
import de.lmu.ifi.dbs.elki.math.geodesy.EarthModel;
import de.lmu.ifi.dbs.elki.math.geodesy.SphericalVincentyEarthModel;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
@@ -39,9 +39,23 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
* Distance function for 2D vectors in Latitude, Longitude form.
*
+ * The input data must be in degrees (not radians), and the output distance will
+ * be in meters (see {@link EarthModel#distanceDeg}).
+ *
+ * This implementation allows index accelerated queries using R*-trees (by
+ * providing a point-to-rectangle minimum distance), as published in:
+ * <p>
+ * Erich Schubert, Arthur Zimek and Hans-Peter Kriegel<br />
+ * Geodetic Distance Queries on R-Trees for Indexing Geographic Data<br />
+ * Advances in Spatial and Temporal Databases - 13th International Symposium,
+ * SSTD 2013, Munich, Germany
+ * </p>
+ *
* @author Erich Schubert
+ *
+ * @apiviz.composedOf EarthModel
*/
-public class LatLngDistanceFunction extends AbstractSpatialDoubleDistanceFunction {
+public class LatLngDistanceFunction extends AbstractSpatialDistanceFunction {
/**
* Earth model to use.
*/
@@ -56,33 +70,36 @@ public class LatLngDistanceFunction extends AbstractSpatialDoubleDistanceFunctio
}
@Override
- public double doubleDistance(NumberVector<?> o1, NumberVector<?> o2) {
+ public double distance(NumberVector o1, NumberVector o2) {
return model.distanceDeg(o1.doubleValue(0), o1.doubleValue(1), o2.doubleValue(0), o2.doubleValue(1));
}
@Override
@Reference(authors = "Erich Schubert, Arthur Zimek and Hans-Peter Kriegel", title = "Geodetic Distance Queries on R-Trees for Indexing Geographic Data", booktitle = "Advances in Spatial and Temporal Databases - 13th International Symposium, SSTD 2013, Munich, Germany")
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
- if (mbr1 instanceof NumberVector) {
- if (mbr2 instanceof NumberVector) {
- return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2);
- } else {
- NumberVector<?> o1 = (NumberVector<?>) mbr1;
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ if(mbr1 instanceof NumberVector) {
+ if(mbr2 instanceof NumberVector) {
+ return distance((NumberVector) mbr1, (NumberVector) mbr2);
+ }
+ else {
+ NumberVector o1 = (NumberVector) mbr1;
return model.minDistDeg(o1.doubleValue(0), o1.doubleValue(1), mbr2.getMin(0), mbr2.getMin(1), mbr2.getMax(0), mbr2.getMax(1));
}
- } else {
- if (mbr2 instanceof NumberVector) {
- NumberVector<?> o2 = (NumberVector<?>) mbr2;
+ }
+ else {
+ if(mbr2 instanceof NumberVector) {
+ NumberVector o2 = (NumberVector) mbr2;
return model.minDistDeg(o2.doubleValue(0), o2.doubleValue(1), mbr1.getMin(0), mbr1.getMin(1), mbr1.getMax(0), mbr1.getMax(1));
- } else {
+ }
+ else {
throw new NotImplementedException("This distance function cannot - yet - be used with this algorithm, as the lower bound rectangle to rectangle distances have not yet been formalized for geodetic data.");
}
}
}
@Override
- public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() {
- return new VectorFieldTypeInformation<>(NumberVector.class, 2);
+ public SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_FIELD_2D;
}
@Override
@@ -95,21 +112,22 @@ public class LatLngDistanceFunction extends AbstractSpatialDoubleDistanceFunctio
@Override
public boolean equals(Object obj) {
- if (this == obj) {
+ if(this == obj) {
return true;
}
- if (obj == null) {
+ if(obj == null) {
return false;
}
- if (getClass() != obj.getClass()) {
+ if(getClass() != obj.getClass()) {
return false;
}
LatLngDistanceFunction other = (LatLngDistanceFunction) obj;
- if (model == null) {
- if (other.model != null) {
+ if(model == null) {
+ if(other.model != null) {
return false;
}
- } else if (!model.equals(other.model)) {
+ }
+ else if(!model.equals(other.model)) {
return false;
}
return true;
@@ -132,7 +150,7 @@ public class LatLngDistanceFunction extends AbstractSpatialDoubleDistanceFunctio
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
ObjectParameter<EarthModel> modelP = new ObjectParameter<>(EarthModel.MODEL_ID, EarthModel.class, SphericalVincentyEarthModel.class);
- if (config.grab(modelP)) {
+ if(config.grab(modelP)) {
model = modelP.instantiateClass(config);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LngLatDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LngLatDistanceFunction.java
index 98a219dd..e8d2623d 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LngLatDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/LngLatDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.geo;
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,8 +26,8 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.geo;
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.AbstractSpatialDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDistanceFunction;
import de.lmu.ifi.dbs.elki.math.geodesy.EarthModel;
import de.lmu.ifi.dbs.elki.math.geodesy.SphericalVincentyEarthModel;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
@@ -39,9 +39,23 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
* Distance function for 2D vectors in Longitude, Latitude form.
*
+ * The input data must be in degrees (not radians), and the output distance will
+ * be in meters (see {@link EarthModel#distanceDeg}).
+ *
+ * This implementation allows index accelerated queries using R*-trees (by
+ * providing a point-to-rectangle minimum distance), as published in:
+ * <p>
+ * Erich Schubert, Arthur Zimek and Hans-Peter Kriegel<br />
+ * Geodetic Distance Queries on R-Trees for Indexing Geographic Data<br />
+ * Advances in Spatial and Temporal Databases - 13th International Symposium,
+ * SSTD 2013, Munich, Germany
+ * </p>
+ *
* @author Erich Schubert
+ *
+ * @apiviz.composedOf EarthModel
*/
-public class LngLatDistanceFunction extends AbstractSpatialDoubleDistanceFunction {
+public class LngLatDistanceFunction extends AbstractSpatialDistanceFunction {
/**
* Earth model to use.
*/
@@ -56,33 +70,36 @@ public class LngLatDistanceFunction extends AbstractSpatialDoubleDistanceFunctio
}
@Override
- public double doubleDistance(NumberVector<?> o1, NumberVector<?> o2) {
+ public double distance(NumberVector o1, NumberVector o2) {
return model.distanceDeg(o1.doubleValue(1), o1.doubleValue(0), o2.doubleValue(1), o2.doubleValue(0));
}
@Override
@Reference(authors = "Erich Schubert, Arthur Zimek and Hans-Peter Kriegel", title = "Geodetic Distance Queries on R-Trees for Indexing Geographic Data", booktitle = "Advances in Spatial and Temporal Databases - 13th International Symposium, SSTD 2013, Munich, Germany")
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
- if (mbr1 instanceof NumberVector) {
- if (mbr2 instanceof NumberVector) {
- return doubleDistance((NumberVector<?>) mbr1, (NumberVector<?>) mbr2);
- } else {
- NumberVector<?> o1 = (NumberVector<?>) mbr1;
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ if(mbr1 instanceof NumberVector) {
+ if(mbr2 instanceof NumberVector) {
+ return distance((NumberVector) mbr1, (NumberVector) mbr2);
+ }
+ else {
+ NumberVector o1 = (NumberVector) mbr1;
return model.minDistDeg(o1.doubleValue(1), o1.doubleValue(0), mbr2.getMin(1), mbr2.getMin(0), mbr2.getMax(1), mbr2.getMax(0));
}
- } else {
- if (mbr2 instanceof NumberVector) {
- NumberVector<?> o2 = (NumberVector<?>) mbr2;
+ }
+ else {
+ if(mbr2 instanceof NumberVector) {
+ NumberVector o2 = (NumberVector) mbr2;
return model.minDistDeg(o2.doubleValue(1), o2.doubleValue(0), mbr1.getMin(1), mbr1.getMin(0), mbr1.getMax(1), mbr1.getMax(0));
- } else {
+ }
+ else {
throw new NotImplementedException("This distance function cannot - yet - be used with this algorithm, as the lower bound rectangle to rectangle distances have not yet been formalized for geodetic data.");
}
}
}
@Override
- public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() {
- return new VectorFieldTypeInformation<>(NumberVector.class, 2);
+ public SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_FIELD_2D;
}
@Override
@@ -95,21 +112,22 @@ public class LngLatDistanceFunction extends AbstractSpatialDoubleDistanceFunctio
@Override
public boolean equals(Object obj) {
- if (this == obj) {
+ if(this == obj) {
return true;
}
- if (obj == null) {
+ if(obj == null) {
return false;
}
- if (getClass() != obj.getClass()) {
+ if(getClass() != obj.getClass()) {
return false;
}
LngLatDistanceFunction other = (LngLatDistanceFunction) obj;
- if (model == null) {
- if (other.model != null) {
+ if(model == null) {
+ if(other.model != null) {
return false;
}
- } else if (!model.equals(other.model)) {
+ }
+ else if(!model.equals(other.model)) {
return false;
}
return true;
@@ -137,7 +155,7 @@ public class LngLatDistanceFunction extends AbstractSpatialDoubleDistanceFunctio
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
ObjectParameter<EarthModel> modelP = new ObjectParameter<>(EarthModel.MODEL_ID, EarthModel.class, SphericalVincentyEarthModel.class);
- if (config.grab(modelP)) {
+ if(config.grab(modelP)) {
model = modelP.instantiateClass(config);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/package-info.java
index 4c05cc5a..5242c6d1 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/geo/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
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/HistogramMatchDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/HistogramMatchDistanceFunction.java
index 947c50fe..f3bf61f7 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/HistogramMatchDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/HistogramMatchDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.histogram;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,7 +24,9 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.histogram;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDistanceFunction;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
@@ -34,9 +36,26 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
* This distance function assumes there exist a natural order in the vectors,
* i.e. they should be some 1-dimensional histogram.
*
+ * This is also known as Earth Movers Distance (EMD), 1st Mallows distance or
+ * 1st Wasserstein metric (also Vasershtein metric), for the special case of a
+ * one-dimensional histogram, where the cost is linear in the number of bins to
+ * transport.
+ *
+ * Reference:
+ * <p>
+ * L.N. Vaserstein<br />
+ * Markov processes over denumerable products of spaces describing large systems
+ * of automata <br />
+ * Problemy Peredachi Informatsii 5.3 / Problems of Information Transmission 5:3
+ * </p>
+ *
* @author Erich Schubert
*/
-public class HistogramMatchDistanceFunction extends AbstractVectorDoubleDistanceFunction {
+@Reference(authors = "L.N. Vaserstein", //
+title = "Markov processes over denumerable products of spaces describing large systems of automata", //
+booktitle = "Problemy Peredachi Informatsii 5.3 / Problems of Information Transmission, 5:3", //
+url = "http://mi.mathnet.ru/eng/ppi1811")
+public class HistogramMatchDistanceFunction extends AbstractSpatialDistanceFunction {
/**
* Static instance. Use this!
*/
@@ -53,7 +72,7 @@ public class HistogramMatchDistanceFunction extends AbstractVectorDoubleDistance
}
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
final int dim = dimensionality(v1, v2);
double xs = 0., ys = 0., agg = 0.;
for(int i = 0; i < dim; i++) {
@@ -65,6 +84,25 @@ public class HistogramMatchDistanceFunction extends AbstractVectorDoubleDistance
}
@Override
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ final int dim = dimensionality(mbr1, mbr2);
+ double xmin = 0., xmax = 0., ymin = 0., ymax = 0., agg = 0.;
+ for(int i = 0; i < dim; i++) {
+ xmin += mbr1.getMin(i);
+ xmax += mbr1.getMax(i);
+ ymin += mbr2.getMin(i);
+ ymax += mbr2.getMax(i);
+ agg += (ymin > xmax) ? (ymin - xmax) : (xmin > ymax) ? (xmin - ymax) : 0.;
+ }
+ return agg;
+ }
+
+ @Override
+ public boolean isMetric() {
+ return true;
+ }
+
+ @Override
public String toString() {
return "HistogramMatchDistanceFunction";
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/KolmogorovSmirnovDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/KolmogorovSmirnovDistanceFunction.java
index fa2fff76..fb11074f 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/KolmogorovSmirnovDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/KolmogorovSmirnovDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.histogram;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.histogram;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
@@ -35,7 +35,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Erich Schubert
*/
-public class KolmogorovSmirnovDistanceFunction extends AbstractVectorDoubleDistanceFunction {
+public class KolmogorovSmirnovDistanceFunction extends AbstractNumberVectorDistanceFunction {
/**
* Static instance. Use this!
*/
@@ -52,7 +52,7 @@ public class KolmogorovSmirnovDistanceFunction extends AbstractVectorDoubleDista
}
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
final int dim = dimensionality(v1, v2);
double xs = 0., ys = 0., agg = 0.;
for (int i = 0; i < dim; i++) {
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/package-info.java
index 770dcf52..7f251d73 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/histogram/package-info.java
@@ -6,7 +6,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
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
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/package-info.java
index 19d72baf..aa2558f5 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/package-info.java
@@ -25,16 +25,13 @@
*
* <h2>Code example</h2>
* <pre>{@code
- * DistanceQuery<V, DoubleDistance> distanceQuery = database.getDistanceQuery(EuclideanDistanceFunction.STATIC);
+ * DistanceQuery<V> distanceQuery = database.getDistanceQuery(EuclideanDistanceFunction.STATIC);
* }</pre>
*
* @apiviz.exclude de.lmu.ifi.dbs.elki.application.*
* @apiviz.exclude de.lmu.ifi.dbs.elki.algorithm.*
* @apiviz.exclude de.lmu.ifi.dbs.elki.database.*
- * @apiviz.exclude de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.*
- * @apiviz.exclude de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.*
- * @apiviz.exclude de.lmu.ifi.dbs.elki.distance.distancefunction.geo.*
- * @apiviz.exclude de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.*
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.distance.(distance|similarity)function\..*\.
* @apiviz.exclude de.lmu.ifi.dbs.elki.index.*
* @apiviz.exclude de.lmu.ifi.dbs.elki.*Instance
*/
@@ -42,7 +39,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
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/ChiSquaredDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/ChiSquaredDistanceFunction.java
index 3fb44680..cee290f1 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/ChiSquaredDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/ChiSquaredDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -25,7 +25,9 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic;
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.AbstractSpatialDoubleDistanceFunction;
+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.AbstractSpatialDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -43,8 +45,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
* @author Erich Schubert
*/
@Alias("chisq")
-@Reference(authors = "J. Puzicha, J.M. Buhmann, Y. Rubner, C. Tomasi", title = "Empirical evaluation of dissimilarity measures for color and texture", booktitle = "Proc. 7th IEEE International Conference on Computer Vision", url = "http://dx.doi.org/10.1109/ICCV.1999.790412")
-public class ChiSquaredDistanceFunction extends AbstractSpatialDoubleDistanceFunction {
+@Reference(authors = "J. Puzicha, J.M. Buhmann, Y. Rubner, C. Tomasi", //
+title = "Empirical evaluation of dissimilarity measures for color and texture", //
+booktitle = "Proc. 7th IEEE International Conference on Computer Vision", //
+url = "http://dx.doi.org/10.1109/ICCV.1999.790412")
+public class ChiSquaredDistanceFunction extends AbstractSpatialDistanceFunction {
/**
* Static instance. Use this!
*/
@@ -61,42 +66,84 @@ public class ChiSquaredDistanceFunction extends AbstractSpatialDoubleDistanceFun
}
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
- final int dim = dimensionality(v1, 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 = 0.;
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < mindim; d++) {
final double xd = v1.doubleValue(d), yd = v2.doubleValue(d);
final double di = xd - yd;
final double si = xd + yd;
- if (!(si > 0. || si < 0.) || !(di > 0. || di < 0.)) {
+ if(!(si > 0. || si < 0.) || !(di > 0. || di < 0.)) {
continue;
}
agg += di * di / si;
}
+ for(int d = mindim; d < dim1; d++) {
+ final double xd = v1.doubleValue(d);
+ if(xd != xd) { /* avoid NaNs */
+ continue;
+ }
+ agg += xd;
+ }
+ for(int d = mindim; d < dim2; d++) {
+ final double xd = v2.doubleValue(d);
+ if(xd != xd) { /* avoid NaNs */
+ continue;
+ }
+ agg += xd;
+ }
return 2. * agg;
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
- final int dim = dimensionality(mbr1, mbr2);
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ final int dim1 = mbr1.getDimensionality(), dim2 = mbr2.getDimensionality();
+ final int mindim = (dim1 < dim2) ? dim1 : dim2;
double agg = 0.;
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < mindim; d++) {
final double min1 = mbr1.getMin(d), max1 = mbr1.getMax(d);
final double min2 = mbr2.getMin(d), max2 = mbr2.getMax(d);
final double diff; // Minimum difference
- if (max1 < min2) {
+ if(max1 < min2) {
diff = min2 - max1;
- } else if (max2 < min1) {
+ }
+ else if(max2 < min1) {
diff = max2 - min1;
- } else {
+ }
+ else {
continue; // 0.
}
final double si = max1 + max2; // Maximum sum
- if (!(si > 0. || si < 0.) || !(diff > 0. || diff < 0.)) {
+ if(!(si > 0. || si < 0.) || !(diff > 0. || diff < 0.)) {
continue;
}
agg += diff * diff / si;
}
+ for(int d = mindim; d < dim1; d++) {
+ final double min1 = mbr1.getMin(d);
+ if(min1 > 0.) {
+ agg += min1;
+ }
+ else {
+ final double max1 = mbr1.getMax(d);
+ if(max1 < 0.) { // Should never happen.
+ agg += max1;
+ }
+ }
+ }
+ for(int d = mindim; d < dim2; d++) {
+ final double min2 = mbr2.getMin(d);
+ if(min2 > 0.) {
+ agg += min2;
+ }
+ else {
+ final double max2 = mbr2.getMax(d);
+ if(max2 < 0.) { // Should never happen.
+ agg += max2;
+ }
+ }
+ }
return 2. * agg;
}
@@ -107,18 +154,23 @@ public class ChiSquaredDistanceFunction extends AbstractSpatialDoubleDistanceFun
@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);
}
+ @Override
+ public SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH;
+ }
+
/**
* Parameterization class, using the static instance.
*
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/HellingerDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/HellingerDistanceFunction.java
new file mode 100644
index 00000000..4bd3de73
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/HellingerDistanceFunction.java
@@ -0,0 +1,136 @@
+package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.database.query.DistanceSimilarityQuery;
+import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceSimilarityQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFunction;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Hellinger kernel / Hellinger distance are used with SIFT vectors, and also
+ * known as Bhattacharyya distance / coefficient.
+ *
+ * This distance is appropriate for histograms, and is equal to A) L1
+ * normalizing the vectors and then B) using Euclidean distance. As this is
+ * usually much faster, this is the recommended way of handling such data.
+ *
+ * Reference:
+ * <p>
+ * E. Hellinger<br />
+ * Neue Begründung der Theorie quadratischer Formen von unendlichvielen
+ * Veränderlichen<br />
+ * Journal für die reine und angewandte Mathematik
+ * </p>
+ *
+ * TODO: support acceleration for sparse vectors
+ *
+ * @author Erich Schubert
+ */
+@Reference(authors = "E. Hellinger", //
+title = "Neue Begründung der Theorie quadratischer Formen von unendlichvielen Veränderlichen", //
+booktitle = "Journal für die reine und angewandte Mathematik ", //
+url = "http://resolver.sub.uni-goettingen.de/purl?GDZPPN002166941")
+@Alias({ "hellinger", "bhattacharyya" })
+public class HellingerDistanceFunction extends AbstractNumberVectorDistanceFunction implements PrimitiveSimilarityFunction<NumberVector> {
+ /**
+ * Static instance.
+ */
+ public static final HellingerDistanceFunction STATIC = new HellingerDistanceFunction();
+
+ /**
+ * Hellinger kernel. Use static instance {@link #STATIC}!
+ */
+ @Deprecated
+ public HellingerDistanceFunction() {
+ super();
+ }
+
+ @Override
+ public double distance(final NumberVector fv1, final NumberVector fv2) {
+ final int dim1 = fv1.getDimensionality(), dim2 = fv2.getDimensionality();
+ final int mindim = (dim1 < dim2) ? dim1 : dim2;
+ double agg = 0.;
+ for(int d = 0; d < mindim; d++) {
+ final double v = Math.sqrt(fv1.doubleValue(d)) - Math.sqrt(fv2.doubleValue(d));
+ agg += v * v;
+ }
+ for(int d = mindim; d < dim1; d++) {
+ agg += Math.abs(fv1.doubleValue(d));
+ }
+ for(int d = mindim; d < dim2; d++) {
+ agg += Math.abs(fv2.doubleValue(d));
+ }
+ return MathUtil.SQRTHALF * Math.sqrt(agg);
+ }
+
+ @Override
+ public double similarity(final NumberVector o1, final NumberVector o2) {
+ // TODO: accelerate sparse!
+ final int dim1 = o1.getDimensionality(), dim2 = o2.getDimensionality();
+ final int mindim = (dim1 < dim2) ? dim1 : dim2;
+ double agg = 0.;
+ for(int d = 0; d < mindim; d++) {
+ agg += Math.sqrt(o1.doubleValue(d) * o2.doubleValue(d));
+ }
+ return agg;
+ }
+
+ @Override
+ public boolean isMetric() {
+ return true; // as this equals Euclidean in sqrt space
+ }
+
+ @Override
+ public <T extends NumberVector> DistanceSimilarityQuery<T> instantiate(Relation<T> database) {
+ return new PrimitiveDistanceSimilarityQuery<>(database, this, this);
+ }
+
+ @Override
+ public SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected HellingerDistanceFunction makeInstance() {
+ return HellingerDistanceFunction.STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JeffreyDivergenceDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JeffreyDivergenceDistanceFunction.java
index 73b944cf..173d2f0b 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JeffreyDivergenceDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JeffreyDivergenceDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -25,12 +25,12 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic;
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.AbstractSpatialDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
- * Provides the Jeffrey Divergence Distance for FeatureVectors.
+ * Jeffrey Divergence Distance for {@link NumberVector}s.
*
* Reference:
* <p>
@@ -41,15 +41,18 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Erich Schubert
*/
-@Reference(authors = "J. Puzicha, J.M. Buhmann, Y. Rubner, C. Tomasi", title = "Empirical evaluation of dissimilarity measures for color and texture", booktitle = "Proc. 7th IEEE International Conference on Computer Vision", url = "http://dx.doi.org/10.1109/ICCV.1999.790412")
-public class JeffreyDivergenceDistanceFunction extends AbstractSpatialDoubleDistanceFunction {
+@Reference(authors = "J. Puzicha, J.M. Buhmann, Y. Rubner, C. Tomasi", //
+title = "Empirical evaluation of dissimilarity measures for color and texture", //
+booktitle = "Proc. 7th IEEE International Conference on Computer Vision", //
+url = "http://dx.doi.org/10.1109/ICCV.1999.790412")
+public class JeffreyDivergenceDistanceFunction extends AbstractSpatialDistanceFunction {
/**
* Static instance. Use this!
*/
public static final JeffreyDivergenceDistanceFunction STATIC = new JeffreyDivergenceDistanceFunction();
/**
- * Constructor for the Jeffrey divergence.
+ * Constructor for the Jeffrey divergence - use {@link #STATIC} instead.
*
* @deprecated Use static instance!
*/
@@ -59,22 +62,22 @@ public class JeffreyDivergenceDistanceFunction extends AbstractSpatialDoubleDist
}
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
final int dim = dimensionality(v1, v2);
double agg = 0.;
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
final double xd = v1.doubleValue(d), yd = v2.doubleValue(d);
- if (xd == yd) {
+ if(xd == yd) {
continue;
}
final double md = .5 * (xd + yd);
- if (!(md > 0. || md < 0.)) {
+ if(!(md > 0. || md < 0.)) {
continue;
}
- if (xd > 0.) {
+ if(xd > 0.) {
agg += xd * Math.log(xd / md);
}
- if (yd > 0.) {
+ if(yd > 0.) {
agg += yd * Math.log(yd / md);
}
}
@@ -82,20 +85,20 @@ public class JeffreyDivergenceDistanceFunction extends AbstractSpatialDoubleDist
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
final int dim = dimensionality(mbr1, mbr2);
double agg = 0;
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
final double min1 = mbr1.getMin(d), max1 = mbr1.getMax(d);
final double min2 = mbr2.getMin(d), max2 = mbr2.getMax(d);
final double md = .5 * (max1 + max2);
- if (!(md > 0. || md < 0.)) {
+ if(!(md > 0. || md < 0.)) {
continue;
}
- if (min1 > 0.) {
+ if(min1 > 0.) {
agg += min1 * Math.log(min1 / md);
}
- if (min2 > 0.) {
+ if(min2 > 0.) {
agg += min2 * Math.log(min2 / md);
}
}
@@ -109,13 +112,13 @@ public class JeffreyDivergenceDistanceFunction extends AbstractSpatialDoubleDist
@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/probabilistic/JensenShannonDivergenceDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JensenShannonDivergenceDistanceFunction.java
index d7692dcc..143506aa 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JensenShannonDivergenceDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/JensenShannonDivergenceDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,6 +24,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
@@ -49,11 +50,16 @@ public class JensenShannonDivergenceDistanceFunction extends JeffreyDivergenceDi
}
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
- return .5 * super.doubleDistance(v1, v2);
+ public double distance(NumberVector v1, NumberVector v2) {
+ return .5 * super.distance(v1, v2);
}
@Override
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ return .5 * super.minDist(mbr1, mbr2);
+ }
+
+ @Override
public String toString() {
return "JensenShannonDivergenceDistance";
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceAsymmetricDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceAsymmetricDistanceFunction.java
index c0f61d43..2f27f78a 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceAsymmetricDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceAsymmetricDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -49,7 +49,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*/
@Reference(authors = "S. Kullback", title = "Information theory and statistics", booktitle = "Information theory and statistics, Courier Dover Publications, 1997.")
@Alias("kl")
-public class KullbackLeiblerDivergenceAsymmetricDistanceFunction extends AbstractVectorDoubleDistanceFunction {
+public class KullbackLeiblerDivergenceAsymmetricDistanceFunction extends AbstractNumberVectorDistanceFunction {
/**
* Static instance. Use this!
*/
@@ -66,7 +66,7 @@ public class KullbackLeiblerDivergenceAsymmetricDistanceFunction extends Abstrac
}
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
final int dim = dimensionality(v1, v2);
double agg = 0.;
for (int d = 0; d < dim; d++) {
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction.java
index 08bddc1b..998348fd 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -50,7 +50,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*/
@Reference(authors = "S. Kullback", title = "Information theory and statistics", booktitle = "Information theory and statistics, Courier Dover Publications, 1997.")
@Alias("kli")
-public class KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction extends AbstractVectorDoubleDistanceFunction {
+public class KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction extends AbstractNumberVectorDistanceFunction {
/**
* Static instance. Use this!
*/
@@ -67,7 +67,7 @@ public class KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction extends
}
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
final int dim = dimensionality(v1, v2);
double agg = 0.;
for (int d = 0; d < dim; d++) {
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/SqrtJensenShannonDivergenceDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/SqrtJensenShannonDivergenceDistanceFunction.java
index af0590fc..a52463f0 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/SqrtJensenShannonDivergenceDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/SqrtJensenShannonDivergenceDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -41,7 +41,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
* @author Erich Schubert
*/
@Reference(authors = "D. M. Endres, J. E. Schindelin", title = "A new metric for probability distributions", booktitle = "IEEE Transactions on Information Theory, 49(7)", url = "http://dx.doi.org/10.1109/TIT.2003.813506")
-public class SqrtJensenShannonDivergenceDistanceFunction extends AbstractVectorDoubleDistanceFunction {
+public class SqrtJensenShannonDivergenceDistanceFunction extends AbstractNumberVectorDistanceFunction {
/**
* Static instance. Use this!
*/
@@ -58,7 +58,7 @@ public class SqrtJensenShannonDivergenceDistanceFunction extends AbstractVectorD
}
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
final int dim = dimensionality(v1, v2);
double agg = 0.;
for(int d = 0; d < dim; d++) {
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/package-info.java
index 7a6f705c..d0718b89 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/probabilistic/package-info.java
@@ -8,7 +8,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
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/AbstractSetDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/AbstractSetDistanceFunction.java
new file mode 100644
index 00000000..5f374c78
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/AbstractSetDistanceFunction.java
@@ -0,0 +1,63 @@
+package de.lmu.ifi.dbs.elki.distance.distancefunction.set;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.FeatureVector;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractPrimitiveDistanceFunction;
+
+/**
+ * Abstract base class for set distance functions.
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Vector type
+ */
+public abstract class AbstractSetDistanceFunction<O> extends AbstractPrimitiveDistanceFunction<O> {
+ /**
+ * Constants for checking null.
+ */
+ public static final Integer INTEGER_NULL = Integer.valueOf(0);
+
+ /**
+ * Constants for checking null.
+ */
+ public static final Double DOUBLE_NULL = Double.valueOf(0.);
+
+ /**
+ * Empty string.
+ */
+ public static final String STRING_NULL = "";
+
+ /**
+ * Test a value for null.
+ *
+ * TODO: delegate to {@link FeatureVector} instead?
+ *
+ * @param val Value
+ * @return true when null
+ */
+ protected static boolean isNull(Object val) {
+ return (val == null) || STRING_NULL.equals(val) || DOUBLE_NULL.equals(val) || INTEGER_NULL.equals(val);
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/HammingDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/HammingDistanceFunction.java
new file mode 100644
index 00000000..6c24eadf
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/HammingDistanceFunction.java
@@ -0,0 +1,175 @@
+package de.lmu.ifi.dbs.elki.distance.distancefunction.set;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.BitVector;
+import de.lmu.ifi.dbs.elki.data.FeatureVector;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+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.NumberVectorDistanceFunction;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Computes the Hamming distance of arbitrary vectors - i.e. counting, on how
+ * many places they differ.
+ *
+ * Reference:
+ * <p>
+ * R. W. Hamming<br />
+ * Error detecting and error correcting codes<br />
+ * Bell System technical journal, 29(2)
+ * </p>
+ *
+ * TODO: add a sparse (but not binary) optimized version?
+ *
+ * @author Erich Schubert
+ */
+@Reference(authors = "R. W. Hamming", //
+title = "Error detecting and error correcting codes", //
+booktitle = "Bell System technical journal, 29(2)", //
+url = "http://dx.doi.org/10.1002/j.1538-7305.1950.tb00463.x")
+public class HammingDistanceFunction extends AbstractSetDistanceFunction<FeatureVector<?>> implements NumberVectorDistanceFunction<FeatureVector<?>> {
+ /**
+ * Static instance.
+ */
+ public static final HammingDistanceFunction STATIC = new HammingDistanceFunction();
+
+ @Override
+ public boolean isMetric() {
+ return true;
+ }
+
+ @Override
+ public double distance(FeatureVector<?> o1, FeatureVector<?> o2) {
+ if(o1 instanceof BitVector && o2 instanceof BitVector) {
+ return ((BitVector) o1).hammingDistance((BitVector) o2);
+ }
+ if(o1 instanceof NumberVector && o2 instanceof NumberVector) {
+ return hammingDistanceNumberVector((NumberVector) o1, (NumberVector) o2);
+ }
+ final int d1 = o1.getDimensionality(), d2 = o2.getDimensionality();
+ int differences = 0;
+ int d = 0;
+ for(; d < d1 && d < d2; d++) {
+ Object v1 = o1.getValue(d), v2 = o2.getValue(d);
+ final boolean n1 = isNull(v1), n2 = isNull(v2);
+ if(n1 && n2) {
+ continue;
+ }
+ if(v1 instanceof Double && Double.isNaN((Double) v1)) {
+ continue;
+ }
+ if(v2 instanceof Double && Double.isNaN((Double) v2)) {
+ continue;
+ }
+ // One must be set.
+ if(n1 || n2 || !v1.equals(v2)) {
+ ++differences;
+ }
+ }
+ for(; d < d1; d++) {
+ Object v1 = o1.getValue(d);
+ if(!isNull(v1)) {
+ if(v1 instanceof Double && Double.isNaN((Double) v1)) {
+ continue;
+ }
+ ++differences;
+ }
+ }
+ for(; d < d2; d++) {
+ Object v2 = o2.getValue(d);
+ if(!isNull(v2)) {
+ if(v2 instanceof Double && Double.isNaN((Double) v2)) {
+ continue;
+ }
+ ++differences;
+ }
+ }
+ return differences;
+ }
+
+ @Override
+ public double distance(NumberVector o1, NumberVector o2) {
+ if(o1 instanceof BitVector && o2 instanceof BitVector) {
+ return ((BitVector) o1).hammingDistance((BitVector) o2);
+ }
+ return hammingDistanceNumberVector(o1, o2);
+ }
+
+ /**
+ * Version for number vectors.
+ *
+ * @param o1 First vector
+ * @param o2 Second vector
+ * @return hamming distance
+ */
+ private double hammingDistanceNumberVector(NumberVector o1, NumberVector o2) {
+ final int d1 = o1.getDimensionality(), d2 = o2.getDimensionality();
+ int differences = 0;
+ int d = 0;
+ for(; d < d1 && d < d2; d++) {
+ double v1 = o1.doubleValue(d), v2 = o2.doubleValue(d);
+ if(v1 != v1 || v2 != v2) { /* NaN */
+ continue;
+ }
+ if(v1 != v2) {
+ ++differences;
+ }
+ }
+ for(; d < d1; d++) {
+ double v1 = o1.doubleValue(d);
+ if(v1 != 0. && v1 == v1 /* not NaN */) {
+ ++differences;
+ }
+ }
+ for(; d < d2; d++) {
+ double v2 = o2.doubleValue(d);
+ if(v2 != 0. && v2 == v2 /* not NaN */) {
+ ++differences;
+ }
+ }
+ return differences;
+ }
+
+ @Override
+ public SimpleTypeInformation<? super FeatureVector<?>> getInputTypeRestriction() {
+ return TypeUtil.FEATURE_VECTORS;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected HammingDistanceFunction makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/JaccardPrimitiveSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/JaccardSimilarityDistanceFunction.java
index 99fa440e..02df9d1a 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/JaccardPrimitiveSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/JaccardSimilarityDistanceFunction.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.distance.similarityfunction;
+package de.lmu.ifi.dbs.elki.distance.distancefunction.set;
/*
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
@@ -22,6 +22,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import de.lmu.ifi.dbs.elki.data.BitVector;
import de.lmu.ifi.dbs.elki.data.FeatureVector;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
@@ -29,8 +30,9 @@ import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.query.DistanceSimilarityQuery;
import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceSimilarityQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.NumberVectorDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.similarityfunction.NormalizedPrimitiveSimilarityFunction;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
/**
@@ -48,45 +50,33 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* Reference:
* <p>
* P. Jaccard<br />
- * Étude comparative de la distribution florale dans une portion des Alpes et
- * des Jura<br />
+ * Distribution de la florine alpine dans la Bassin de Dranses et dans quelques
+ * regiones voisines<br />
* Bulletin del la Société Vaudoise des Sciences Naturelles
* </p>
*
- * TODO: add optimized implementations for binary vectors.
- *
* @author Erich Schubert
*
* @param <O> Vector type
*/
-@Reference(authors = "P. Jaccard", title = "Étude comparative de la distribution florale dans une portion des Alpes et des Jura", booktitle = "Bulletin del la Société Vaudoise des Sciences Naturelles")
-public class JaccardPrimitiveSimilarityFunction<O extends FeatureVector<?>> extends AbstractPrimitiveSimilarityFunction<O, DoubleDistance> implements NormalizedPrimitiveSimilarityFunction<O>, PrimitiveDoubleDistanceFunction<O> {
- /**
- * Constants for checking null.
- */
- private static final Integer INTEGER_NULL = Integer.valueOf(0);
-
- /**
- * Constants for checking null.
- */
- private static final Double DOUBLE_NULL = Double.valueOf(0.);
-
- /**
- * Empty string.
- */
- private static final String STRING_NULL = "";
-
+@Reference(authors = "P. Jaccard", //
+title = "Distribution de la florine alpine dans la Bassin de Dranses et dans quelques regiones voisines", //
+booktitle = "Bulletin del la Société Vaudoise des Sciences Naturelles")
+public class JaccardSimilarityDistanceFunction<O extends FeatureVector<?>> extends AbstractSetDistanceFunction<O> implements NormalizedPrimitiveSimilarityFunction<O>, NumberVectorDistanceFunction<O>, PrimitiveDistanceFunction<O> {
/**
* Constructor. No parameters.
*/
- public JaccardPrimitiveSimilarityFunction() {
+ public JaccardSimilarityDistanceFunction() {
super();
}
@Override
- public double doubleSimilarity(O o1, O o2) {
+ public double similarity(O o1, O o2) {
+ if(o1 instanceof BitVector && o2 instanceof BitVector) {
+ return ((BitVector) o1).jaccardSimilarity((BitVector) o2);
+ }
if(o1 instanceof NumberVector && o2 instanceof NumberVector) {
- return doubleSimilarityNumberVector((NumberVector<?>) o1, (NumberVector<?>) o2);
+ return similarityNumberVector((NumberVector) o1, (NumberVector) o2);
}
final int d1 = o1.getDimensionality(), d2 = o2.getDimensionality();
int intersection = 0, union = 0;
@@ -94,10 +84,8 @@ public class JaccardPrimitiveSimilarityFunction<O extends FeatureVector<?>> exte
for(; d < d1 && d < d2; d++) {
Object v1 = o1.getValue(d), v2 = o2.getValue(d);
final boolean n1 = isNull(v1), n2 = isNull(v2);
- if(v1 instanceof Double && Double.isNaN((Double) v1)) {
- continue;
- }
- if(v2 instanceof Double && Double.isNaN((Double) v2)) {
+ if(v1 instanceof Double && Double.isNaN((Double) v1) //
+ || v2 instanceof Double && Double.isNaN((Double) v2)) {
continue;
}
if(!n1 || !n2) {
@@ -108,12 +96,20 @@ public class JaccardPrimitiveSimilarityFunction<O extends FeatureVector<?>> exte
}
}
for(; d < d1; d++) {
- if(!isNull(o1.getValue(d))) {
+ Object v1 = o1.getValue(d);
+ if(!isNull(v1)) {
+ if(v1 instanceof Double && Double.isNaN((Double) v1)) {
+ continue;
+ }
++union;
}
}
for(; d < d2; d++) {
- if(!isNull(o2.getValue(d))) {
+ Object v2 = o2.getValue(d);
+ if(!isNull(v2)) {
+ if(v2 instanceof Double && Double.isNaN((Double) v2)) {
+ continue;
+ }
++union;
}
}
@@ -127,7 +123,7 @@ public class JaccardPrimitiveSimilarityFunction<O extends FeatureVector<?>> exte
* @param o2 Second vector
* @return Jaccard similarity
*/
- public static double doubleSimilarityNumberVector(NumberVector<?> o1, NumberVector<?> o2) {
+ public static double similarityNumberVector(NumberVector o1, NumberVector o2) {
final int d1 = o1.getDimensionality(), d2 = o2.getDimensionality();
int intersection = 0, union = 0;
int d = 0;
@@ -157,30 +153,16 @@ public class JaccardPrimitiveSimilarityFunction<O extends FeatureVector<?>> exte
}
@Override
- public DoubleDistance similarity(O o1, O o2) {
- return new DoubleDistance(doubleSimilarity(o1, o2));
- }
-
- /**
- * Test a value for null.
- *
- * TODO: delegate to {@link FeatureVector} instead?
- *
- * @param val Value
- * @return true when null
- */
- private static boolean isNull(Object val) {
- return (val == null) || STRING_NULL.equals(val) || DOUBLE_NULL.equals(val) || INTEGER_NULL.equals(val);
- }
-
- @Override
- public DoubleDistance distance(O o1, O o2) {
- return new DoubleDistance(1. - doubleSimilarity(o1, o2));
+ public double distance(O o1, O o2) {
+ return 1. - similarity(o1, o2);
}
@Override
- public double doubleDistance(O o1, O o2) {
- return 1. - doubleSimilarity(o1, o2);
+ public double distance(NumberVector o1, NumberVector o2) {
+ if(o1 instanceof BitVector && o2 instanceof BitVector) {
+ return 1. - ((BitVector) o1).jaccardSimilarity((BitVector) o2);
+ }
+ return 1. - similarityNumberVector(o1, o2);
}
@Override
@@ -189,17 +171,12 @@ public class JaccardPrimitiveSimilarityFunction<O extends FeatureVector<?>> exte
}
@Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
- }
-
- @Override
public SimpleTypeInformation<? super O> getInputTypeRestriction() {
return TypeUtil.FEATURE_VECTORS;
}
@Override
- public <T extends O> DistanceSimilarityQuery<T, DoubleDistance> instantiate(Relation<T> relation) {
+ public <T extends O> DistanceSimilarityQuery<T> instantiate(Relation<T> relation) {
return new PrimitiveDistanceSimilarityQuery<>(relation, this, this);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/package-info.java
index e96621b5..ddc606f4 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/package-info.java
@@ -1,11 +1,12 @@
/**
- * <p>Classes for building and storing the results of distance-based queries</p>
+ * Distance functions for binary and set type data.
*/
+
/*
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
@@ -23,4 +24,4 @@
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package de.lmu.ifi.dbs.elki.distance.distanceresultlist; \ No newline at end of file
+package de.lmu.ifi.dbs.elki.distance.distancefunction.set; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/LevenshteinDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/LevenshteinDistanceFunction.java
index fbc75a22..683177f4 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/LevenshteinDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/LevenshteinDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.strings;
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,6 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.strings;
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.distancevalue.IntegerDistance;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -50,7 +49,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*/
@Description("Levenshtein distance.")
@Reference(authors = "V. I. Levenshtein", title = "Binary codes capable of correcting deletions, insertions and reversals.", booktitle = "Soviet physics doklady. Vol. 10. 1966.")
-public class LevenshteinDistanceFunction extends AbstractPrimitiveDistanceFunction<String, IntegerDistance> {
+public class LevenshteinDistanceFunction extends AbstractPrimitiveDistanceFunction<String> {
/**
* Static instance, case sensitive.
*/
@@ -65,12 +64,11 @@ public class LevenshteinDistanceFunction extends AbstractPrimitiveDistanceFuncti
}
@Override
- public IntegerDistance distance(String o1, String o2) {
+ public double distance(String o1, String o2) {
if (o1.equals(o2)) {
- return new IntegerDistance(0);
+ return 0.;
}
- final int cost = levenshteinDistance(o1, o2);
- return new IntegerDistance(cost);
+ return levenshteinDistance(o1, o2);
}
/**
@@ -110,11 +108,6 @@ public class LevenshteinDistanceFunction extends AbstractPrimitiveDistanceFuncti
}
@Override
- public IntegerDistance getDistanceFactory() {
- return IntegerDistance.FACTORY;
- }
-
- @Override
public SimpleTypeInformation<? super String> getInputTypeRestriction() {
return TypeUtil.STRING;
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/NormalizedLevenshteinDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/NormalizedLevenshteinDistanceFunction.java
index 0861c6af..3b5ad7f9 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/NormalizedLevenshteinDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/NormalizedLevenshteinDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.strings;
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,6 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.strings;
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.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -50,7 +49,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*/
@Description("Levenshtein distance, normalized by average string length.")
@Reference(authors = "V. I. Levenshtein", title = "Binary codes capable of correcting deletions, insertions and reversals.", booktitle = "Soviet physics doklady. Vol. 10. 1966.")
-public class NormalizedLevenshteinDistanceFunction extends AbstractPrimitiveDistanceFunction<String, DoubleDistance> {
+public class NormalizedLevenshteinDistanceFunction extends AbstractPrimitiveDistanceFunction<String> {
/**
* Static instance, case sensitive.
*/
@@ -65,14 +64,9 @@ public class NormalizedLevenshteinDistanceFunction extends AbstractPrimitiveDist
}
@Override
- public DoubleDistance distance(String o1, String o2) {
+ public double distance(String o1, String o2) {
int cost = LevenshteinDistanceFunction.levenshteinDistance(o1, o2);
- return new DoubleDistance(cost * 2.0 / (o1.length() + o2.length()));
- }
-
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
+ return cost * 2.0 / (o1.length() + o2.length());
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/package-info.java
index a2f3fd2d..e4ac22fb 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/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
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractDimensionsSelectingDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractDimensionsSelectingDistanceFunction.java
index 052e089c..caf45d9d 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractDimensionsSelectingDoubleDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractDimensionsSelectingDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
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
@@ -23,12 +23,12 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.BitSet;
+import java.util.List;
import de.lmu.ifi.dbs.elki.data.FeatureVector;
import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractPrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -36,52 +36,47 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntListParameter;
/**
- * Provides a distance function that computes the distance (which is a double
- * distance) between feature vectors only in specified dimensions.
+ * Abstract base class for distances computed only in subspaces.
+ *
+ * Selected dimensions are encuded as bits in a {@code long[]}.
*
* @author Elke Achtert
* @param <V> the type of FeatureVector to compute the distances in between
*/
-public abstract class AbstractDimensionsSelectingDoubleDistanceFunction<V extends FeatureVector<?>> extends AbstractPrimitiveDistanceFunction<V, DoubleDistance> implements PrimitiveDoubleDistanceFunction<V>, DimensionSelectingSubspaceDistanceFunction<V, DoubleDistance> {
- /**
- * Dimensions parameter.
- */
- public static final OptionID DIMS_ID = new OptionID("distance.dims", "a comma separated array of integer values, where 0 <= d_i < the dimensionality of the feature space specifying the dimensions to be considered for distance computation. If this parameter is not set, no dimensions will be considered, i.e. the distance between two objects is always 0.");
-
+public abstract class AbstractDimensionsSelectingDistanceFunction<V extends FeatureVector<?>> extends AbstractPrimitiveDistanceFunction<V> implements PrimitiveDistanceFunction<V>, DimensionSelectingSubspaceDistanceFunction<V> {
/**
* The dimensions to be considered for distance computation.
*/
- protected BitSet dimensions;
+ protected long[] dimensions;
/**
* Constructor.
*
* @param dimensions
*/
- public AbstractDimensionsSelectingDoubleDistanceFunction(BitSet dimensions) {
+ public AbstractDimensionsSelectingDistanceFunction(long[] dimensions) {
super();
this.dimensions = dimensions;
}
@Override
- public DoubleDistance distance(V o1, V o2) {
- return new DoubleDistance(doubleDistance(o1, o2));
+ public double distance(V o1, V o2) {
+ return distance(o1, o2);
}
@Override
- public BitSet getSelectedDimensions() {
+ public long[] getSelectedDimensions() {
return dimensions;
}
@Override
- public void setSelectedDimensions(BitSet dimensions) {
- this.dimensions.clear();
- this.dimensions.or(dimensions);
- }
-
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
+ public void setSelectedDimensions(long[] dimensions) {
+ if(this.dimensions == null || this.dimensions.length < dimensions.length) {
+ this.dimensions = dimensions.clone();
+ return;
+ }
+ BitsUtil.zeroI(this.dimensions);
+ BitsUtil.orI(this.dimensions, dimensions);
}
@Override
@@ -92,7 +87,7 @@ public abstract class AbstractDimensionsSelectingDoubleDistanceFunction<V extend
if(!this.getClass().equals(obj.getClass())) {
return false;
}
- return this.dimensions.equals(((AbstractDimensionsSelectingDoubleDistanceFunction<?>) obj).dimensions);
+ return this.dimensions.equals(((AbstractDimensionsSelectingDistanceFunction<?>) obj).dimensions);
}
/**
@@ -103,18 +98,28 @@ public abstract class AbstractDimensionsSelectingDoubleDistanceFunction<V extend
* @apiviz.exclude
*/
public abstract static class Parameterizer extends AbstractParameterizer {
- protected BitSet dimensions = null;
+ /**
+ * Dimensions parameter.
+ */
+ public static final OptionID DIMS_ID = new OptionID("distance.dims", "a comma separated array of integer values, where 0 <= d_i < the dimensionality of the feature space specifying the dimensions to be considered for distance computation. If this parameter is not set, no dimensions will be considered, i.e. the distance between two objects is always 0.");
+
+ protected long[] dimensions = null;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- dimensions = new BitSet();
- final IntListParameter dimsP = new IntListParameter(DIMS_ID);
- dimsP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_INT_LIST);
- dimsP.setOptional(true);
+ final IntListParameter dimsP = new IntListParameter(DIMS_ID)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_INT_LIST) //
+ .setOptional(true);
if(config.grab(dimsP)) {
- for(int d : dimsP.getValue()) {
- dimensions.set(d);
+ final List<Integer> value = dimsP.getValue();
+ int maxd = 0;
+ for(int d : value) {
+ maxd = (d > maxd) ? d : maxd;
+ }
+ dimensions = BitsUtil.zero(maxd);
+ for(int d : value) {
+ BitsUtil.setI(dimensions, d);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractPreferenceVectorBasedCorrelationDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractPreferenceVectorBasedCorrelationDistanceFunction.java
deleted file mode 100644
index 20ee637e..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/AbstractPreferenceVectorBasedCorrelationDistanceFunction.java
+++ /dev/null
@@ -1,231 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.util.BitSet;
-
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractIndexBasedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.PreferenceVectorBasedCorrelationDistance;
-import de.lmu.ifi.dbs.elki.index.IndexFactory;
-import de.lmu.ifi.dbs.elki.index.preprocessed.preference.PreferenceVectorIndex;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-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;
-
-/**
- * Abstract super class for all preference vector based correlation distance
- * functions.
- *
- * @author Arthur Zimek
- * @param <V> the type of NumberVector to compute the distances in between
- * @param <P> the type of Preprocessor used
- */
-public abstract class AbstractPreferenceVectorBasedCorrelationDistanceFunction<V extends NumberVector<?>, P extends PreferenceVectorIndex<V>> extends AbstractIndexBasedDistanceFunction<V, P, PreferenceVectorBasedCorrelationDistance> {
- /**
- * Parameter to specify the maximum distance between two vectors with equal
- * preference vectors before considering them as parallel, must be a double
- * equal to or greater than 0.
- * <p>
- * Default value: {@code 0.001}
- * </p>
- * <p>
- * Key: {@code -pvbasedcorrelationdf.epsilon}
- * </p>
- */
- public static final OptionID EPSILON_ID = new OptionID("distancefunction.epsilon", "The maximum distance between two vectors with equal preference vectors before considering them as parallel.");
-
- /**
- * Holds the value of {@link #EPSILON_ID}.
- */
- private double epsilon;
-
- /**
- * Constructor.
- *
- * @param indexFactory Index factory
- * @param epsilon Epsilon value
- */
- public AbstractPreferenceVectorBasedCorrelationDistanceFunction(IndexFactory<V, P> indexFactory, double epsilon) {
- super(indexFactory);
- this.epsilon = epsilon;
- }
-
- @Override
- public PreferenceVectorBasedCorrelationDistance getDistanceFactory() {
- return PreferenceVectorBasedCorrelationDistance.FACTORY;
- }
-
- /**
- * Returns epsilon.
- *
- * @return epsilon
- */
- public double getEpsilon() {
- return epsilon;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (!this.getClass().equals(obj.getClass())) {
- return false;
- }
- AbstractPreferenceVectorBasedCorrelationDistanceFunction<?, ?> other = (AbstractPreferenceVectorBasedCorrelationDistanceFunction<?, ?>) obj;
- return (this.indexFactory.equals(other.indexFactory)) && this.epsilon == other.epsilon;
- }
-
- /**
- * Instance to compute the distances on an actual database.
- *
- * @author Erich Schubert
- */
- abstract public static class Instance<V extends NumberVector<?>, P extends PreferenceVectorIndex<V>> extends AbstractIndexBasedDistanceFunction.Instance<V, P, PreferenceVectorBasedCorrelationDistance, AbstractPreferenceVectorBasedCorrelationDistanceFunction<? super V, ?>> {
- /**
- * The epsilon value
- */
- final double epsilon;
-
- /**
- * Constructor.
- *
- * @param database Database
- * @param preprocessor Preprocessor
- * @param epsilon Epsilon
- * @param distanceFunction parent distance function
- */
- public Instance(Relation<V> database, P preprocessor, double epsilon, AbstractPreferenceVectorBasedCorrelationDistanceFunction<? super V, ?> distanceFunction) {
- super(database, preprocessor, distanceFunction);
- this.epsilon = epsilon;
- }
-
- @Override
- public PreferenceVectorBasedCorrelationDistance distance(DBIDRef id1, DBIDRef id2) {
- BitSet preferenceVector1 = index.getPreferenceVector(id1);
- BitSet preferenceVector2 = index.getPreferenceVector(id2);
- V v1 = relation.get(id1);
- V v2 = relation.get(id2);
- return correlationDistance(v1, v2, preferenceVector1, preferenceVector2);
- }
-
- /**
- * Computes the correlation distance between the two specified vectors
- * according to the specified preference vectors.
- *
- * @param v1 first vector
- * @param v2 second vector
- * @param pv1 the first preference vector
- * @param pv2 the second preference vector
- * @return the correlation distance between the two specified vectors
- */
- public abstract PreferenceVectorBasedCorrelationDistance correlationDistance(V v1, V v2, BitSet pv1, BitSet pv2);
-
- /**
- * Computes the weighted distance between the two specified vectors
- * according to the given preference vector.
- *
- * @param v1 the first vector
- * @param v2 the second vector
- * @param weightVector the preference vector
- * @return the weighted distance between the two specified vectors according
- * to the given preference vector
- */
- public double weightedDistance(V v1, V v2, BitSet weightVector) {
- if (v1.getDimensionality() != v2.getDimensionality()) {
- throw new IllegalArgumentException("Different dimensionality of FeatureVectors\n first argument: " + v1.toString() + "\n second argument: " + v2.toString());
- }
-
- double sqrDist = 0;
- for (int i = 0; i < v1.getDimensionality(); i++) {
- if (weightVector.get(i)) {
- double manhattanI = v1.doubleValue(i) - v2.doubleValue(i);
- sqrDist += manhattanI * manhattanI;
- }
- }
- return Math.sqrt(sqrDist);
- }
-
- /**
- * Computes the weighted distance between the two specified vectors
- * according to the given preference vector.
- *
- * @param id1 the id of the first vector
- * @param id2 the id of the second vector
- * @param weightVector the preference vector
- * @return the weighted distance between the two specified vectors according
- * to the given preference vector
- */
- public double weightedDistance(DBID id1, DBID id2, BitSet weightVector) {
- return weightedDistance(relation.get(id1), relation.get(id2), weightVector);
- }
-
- /**
- * Computes the weighted distance between the two specified data vectors
- * according to their preference vectors.
- *
- * @param id1 the id of the first vector
- * @param id2 the id of the second vector
- * @return the weighted distance between the two specified vectors according
- * to the preference vector of the first data vector
- */
- public double weightedPrefereneceVectorDistance(DBID id1, DBID id2) {
- final V v1 = relation.get(id1);
- final V v2 = relation.get(id2);
- double d1 = weightedDistance(v1, v2, index.getPreferenceVector(id1));
- double d2 = weightedDistance(v2, v1, index.getPreferenceVector(id2));
- return Math.max(d1, d2);
- }
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public abstract static class Parameterizer<F extends IndexFactory<?, ?>> extends AbstractIndexBasedDistanceFunction.Parameterizer<F> {
- protected double epsilon = 0.0;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- configEpsilon(config);
- }
-
- protected void configEpsilon(Parameterization config) {
- final DoubleParameter epsilonP = new DoubleParameter(EPSILON_ID, 0.001);
- epsilonP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
- if (config.grab(epsilonP)) {
- epsilon = epsilonP.doubleValue();
- }
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DiSHDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DiSHDistanceFunction.java
deleted file mode 100644
index 7303797d..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DiSHDistanceFunction.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.util.BitSet;
-
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.PreferenceVectorBasedCorrelationDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.preference.DiSHPreferenceVectorIndex;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-
-/**
- * Distance function used in the DiSH algorithm.
- *
- * @author Elke Achtert
- *
- * @apiviz.has Instance
- */
-public class DiSHDistanceFunction extends AbstractPreferenceVectorBasedCorrelationDistanceFunction<NumberVector<?>, DiSHPreferenceVectorIndex<NumberVector<?>>> {
- /**
- * Logger for debug.
- */
- private static final Logging LOG = Logging.getLogger(DiSHDistanceFunction.class);
-
- /**
- * Constructor.
- *
- * @param indexFactory DiSH index factory
- * @param epsilon Epsilon value
- */
- public DiSHDistanceFunction(DiSHPreferenceVectorIndex.Factory<NumberVector<?>> indexFactory, double epsilon) {
- super(indexFactory, epsilon);
- }
-
- @Override
- public <T extends NumberVector<?>> Instance<T> instantiate(Relation<T> database) {
- // We can't really avoid these warnings, due to a limitation in Java
- // Generics (AFAICT)
- @SuppressWarnings("unchecked")
- DiSHPreferenceVectorIndex<T> indexinst = (DiSHPreferenceVectorIndex<T>) indexFactory.instantiate((Relation<NumberVector<?>>) database);
- return new Instance<>(database, indexinst, getEpsilon(), this);
- }
-
- /**
- * Get the minpts value.
- *
- * @return the minpts parameter
- */
- public int getMinpts() {
- // TODO: get rid of this cast?
- return ((DiSHPreferenceVectorIndex.Factory<NumberVector<?>>) indexFactory).getMinpts();
- }
-
- /**
- * The actual instance bound to a particular database.
- *
- * @author Erich Schubert
- */
- public static class Instance<V extends NumberVector<?>> extends AbstractPreferenceVectorBasedCorrelationDistanceFunction.Instance<V, DiSHPreferenceVectorIndex<V>> {
- /**
- * Constructor.
- *
- * @param database Database
- * @param index Preprocessed index
- * @param epsilon Epsilon
- * @param distanceFunction parent distance function
- */
- public Instance(Relation<V> database, DiSHPreferenceVectorIndex<V> index, double epsilon, DiSHDistanceFunction distanceFunction) {
- super(database, index, epsilon, distanceFunction);
- }
-
- /**
- * Computes the correlation distance between the two specified vectors
- * according to the specified preference vectors.
- *
- * @param v1 first vector
- * @param v2 second vector
- * @param pv1 the first preference vector
- * @param pv2 the second preference vector
- * @return the correlation distance between the two specified vectors
- */
- @Override
- public PreferenceVectorBasedCorrelationDistance correlationDistance(V v1, V v2, BitSet pv1, BitSet pv2) {
- BitSet commonPreferenceVector = (BitSet) pv1.clone();
- commonPreferenceVector.and(pv2);
- int dim = v1.getDimensionality();
-
- // number of zero values in commonPreferenceVector
- Integer subspaceDim = dim - commonPreferenceVector.cardinality();
-
- // special case: v1 and v2 are in parallel subspaces
- if(commonPreferenceVector.equals(pv1) || commonPreferenceVector.equals(pv2)) {
- double d = weightedDistance(v1, v2, commonPreferenceVector);
- if(d > 2 * epsilon) {
- subspaceDim++;
- if(LOG.isDebugging()) {
- //Representation<String> rep = database.getObjectLabelQuery();
- StringBuilder msg = new StringBuilder();
- msg.append("d ").append(d);
- //msg.append("\nv1 ").append(rep.get(v1.getID()));
- //msg.append("\nv2 ").append(rep.get(v2.getID()));
- msg.append("\nsubspaceDim ").append(subspaceDim);
- msg.append("\ncommon pv ").append(FormatUtil.format(dim, commonPreferenceVector));
- LOG.debugFine(msg.toString());
- }
- }
- }
-
- // flip commonPreferenceVector for distance computation in common subspace
- BitSet inverseCommonPreferenceVector = (BitSet) commonPreferenceVector.clone();
- inverseCommonPreferenceVector.flip(0, dim);
-
- return new PreferenceVectorBasedCorrelationDistance(RelationUtil.dimensionality(relation), subspaceDim, weightedDistance(v1, v2, inverseCommonPreferenceVector), commonPreferenceVector);
- }
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer extends AbstractPreferenceVectorBasedCorrelationDistanceFunction.Parameterizer<DiSHPreferenceVectorIndex.Factory<NumberVector<?>>> {
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- Class<DiSHPreferenceVectorIndex.Factory<NumberVector<?>>> cls = ClassGenericsUtil.uglyCastIntoSubclass(DiSHPreferenceVectorIndex.Factory.class);
- factory = config.tryInstantiate(cls);
- }
-
- @Override
- protected DiSHDistanceFunction makeInstance() {
- return new DiSHDistanceFunction(factory, epsilon);
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingSubspaceDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingSubspaceDistanceFunction.java
index f60e2fdc..dcab8e26 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingSubspaceDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingSubspaceDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
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
@@ -22,10 +22,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.BitSet;
-
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Interface for dimension selecting subspace distance functions.
@@ -33,20 +30,19 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance value
*/
-public interface DimensionSelectingSubspaceDistanceFunction<O, D extends Distance<D>> extends DistanceFunction<O, D> {
+public interface DimensionSelectingSubspaceDistanceFunction<O> extends DistanceFunction<O> {
/**
* Returns a bit set representing the selected dimensions.
*
* @return a bit set representing the selected dimensions
*/
- public BitSet getSelectedDimensions();
+ public long[] getSelectedDimensions();
/**
* Sets the selected dimensions according to the set bits in the given BitSet.
*
- * @param dimensions a BitSet designating the new selected dimensions
+ * @param dimensions a bit set designating the new selected dimensions
*/
- public void setSelectedDimensions(BitSet dimensions);
+ public void setSelectedDimensions(long[] dimensions);
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/HiSCDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/HiSCDistanceFunction.java
deleted file mode 100644
index a339c389..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/HiSCDistanceFunction.java
+++ /dev/null
@@ -1,158 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.util.BitSet;
-
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.PreferenceVectorBasedCorrelationDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.preference.HiSCPreferenceVectorIndex;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-
-/**
- * Distance function used in the HiSC algorithm.
- *
- * @author Elke Achtert
- *
- * @apiviz.has Instance
- *
- * @param <V> the type of NumberVector to compute the distances in between
- */
-public class HiSCDistanceFunction<V extends NumberVector<?>> extends AbstractPreferenceVectorBasedCorrelationDistanceFunction<V, HiSCPreferenceVectorIndex<V>> {
- /**
- * Logger for debug.
- */
- private static final Logging LOG = Logging.getLogger(HiSCDistanceFunction.class);
-
- /**
- * Constructor.
- *
- * @param indexFactory HiSC index factory
- * @param epsilon Epsilon value
- */
- public HiSCDistanceFunction(HiSCPreferenceVectorIndex.Factory<V> indexFactory, double epsilon) {
- super(indexFactory, epsilon);
- }
-
- @Override
- public <T extends V> Instance<T> instantiate(Relation<T> database) {
- // We can't really avoid these warnings, due to a limitation in Java
- // Generics (AFAICT)
- @SuppressWarnings("unchecked")
- HiSCPreferenceVectorIndex<T> indexinst = (HiSCPreferenceVectorIndex<T>) indexFactory.instantiate((Relation<V>) database);
- return new Instance<>(database, indexinst, getEpsilon(), this);
- }
-
- /**
- * The actual instance bound to a particular database.
- *
- * @author Erich Schubert
- *
- * @param <V> the type of NumberVector to compute the distances in between
- */
- public static class Instance<V extends NumberVector<?>> extends AbstractPreferenceVectorBasedCorrelationDistanceFunction.Instance<V, HiSCPreferenceVectorIndex<V>> {
- /**
- * Constructor.
- *
- * @param database Database
- * @param index Preprocessed index
- * @param epsilon Epsilon
- * @param distanceFunction parent distance function
- */
- public Instance(Relation<V> database, HiSCPreferenceVectorIndex<V> index, double epsilon, HiSCDistanceFunction<? super V> distanceFunction) {
- super(database, index, epsilon, distanceFunction);
- }
-
- /**
- * Computes the correlation distance between the two specified vectors
- * according to the specified preference vectors.
- *
- * @param v1 first vector
- * @param v2 second vector
- * @param pv1 the first preference vector
- * @param pv2 the second preference vector
- * @return the correlation distance between the two specified vectors
- */
- @Override
- public PreferenceVectorBasedCorrelationDistance correlationDistance(V v1, V v2, BitSet pv1, BitSet pv2) {
- BitSet commonPreferenceVector = (BitSet) pv1.clone();
- commonPreferenceVector.and(pv2);
- int dim = v1.getDimensionality();
-
- // number of zero values in commonPreferenceVector
- Integer subspaceDim = dim - commonPreferenceVector.cardinality();
-
- // special case: v1 and v2 are in parallel subspaces
- double dist1 = weightedDistance(v1, v2, pv1);
- double dist2 = weightedDistance(v1, v2, pv2);
-
- if(Math.max(dist1, dist2) > epsilon) {
- subspaceDim++;
- if(LOG.isDebugging()) {
- //Representation<String> rep = rep.getObjectLabelQuery();
- StringBuilder msg = new StringBuilder();
- msg.append("\ndist1 ").append(dist1);
- msg.append("\ndist2 ").append(dist2);
- // msg.append("\nv1 ").append(rep.get(v1.getID()));
- // msg.append("\nv2 ").append(rep.get(v2.getID()));
- msg.append("\nsubspaceDim ").append(subspaceDim);
- msg.append("\ncommon pv ").append(FormatUtil.format(dim, commonPreferenceVector));
- LOG.debugFine(msg.toString());
- }
- }
-
- // flip commonPreferenceVector for distance computation in common subspace
- BitSet inverseCommonPreferenceVector = (BitSet) commonPreferenceVector.clone();
- inverseCommonPreferenceVector.flip(0, dim);
-
- return new PreferenceVectorBasedCorrelationDistance(RelationUtil.dimensionality(relation), subspaceDim, weightedDistance(v1, v2, inverseCommonPreferenceVector), commonPreferenceVector);
- }
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractPreferenceVectorBasedCorrelationDistanceFunction.Parameterizer<HiSCPreferenceVectorIndex.Factory<V>> {
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- Class<HiSCPreferenceVectorIndex.Factory<V>> cls = ClassGenericsUtil.uglyCastIntoSubclass(HiSCPreferenceVectorIndex.Factory.class);
- factory = config.tryInstantiate(cls);
- }
-
- @Override
- protected HiSCDistanceFunction<V> makeInstance() {
- return new HiSCDistanceFunction<>(factory, epsilon);
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/LocalSubspaceDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/LocalSubspaceDistanceFunction.java
deleted file mode 100644
index efcf6a3c..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/LocalSubspaceDistanceFunction.java
+++ /dev/null
@@ -1,152 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractIndexBasedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.FilteredLocalPCABasedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.SubspaceDistance;
-import de.lmu.ifi.dbs.elki.index.IndexFactory;
-import de.lmu.ifi.dbs.elki.index.preprocessed.LocalProjectionIndex;
-import de.lmu.ifi.dbs.elki.index.preprocessed.localpca.FilteredLocalPCAIndex;
-import de.lmu.ifi.dbs.elki.index.preprocessed.localpca.KNNQueryFilteredPCAIndex;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredResult;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-
-/**
- * Provides a distance function to determine a kind of correlation distance
- * between two points, which is a pair consisting of the distance between the
- * two subspaces spanned by the strong eigenvectors of the two points and the
- * affine distance between the two subspaces.
- *
- * @author Elke Achtert
- *
- * @apiviz.has Instance
- */
-public class LocalSubspaceDistanceFunction extends AbstractIndexBasedDistanceFunction<NumberVector<?>, FilteredLocalPCAIndex<NumberVector<?>>, SubspaceDistance> implements FilteredLocalPCABasedDistanceFunction<NumberVector<?>, FilteredLocalPCAIndex<NumberVector<?>>, SubspaceDistance> {
- /**
- * Constructor
- *
- * @param indexFactory Index factory
- */
- public LocalSubspaceDistanceFunction(IndexFactory<NumberVector<?>, FilteredLocalPCAIndex<NumberVector<?>>> indexFactory) {
- super(indexFactory);
- }
-
- @Override
- public SubspaceDistance getDistanceFactory() {
- return SubspaceDistance.FACTORY;
- }
-
- @Override
- public <V extends NumberVector<?>> Instance<V> instantiate(Relation<V> database) {
- // We can't really avoid these warnings, due to a limitation in Java Generics (AFAICT)
- @SuppressWarnings("unchecked")
- FilteredLocalPCAIndex<V> indexinst = (FilteredLocalPCAIndex<V>) indexFactory.instantiate((Relation<NumberVector<?>>)database);
- return new Instance<>(database, indexinst, this);
- }
-
- /**
- * The actual instance bound to a particular database.
- *
- * @author Erich Schubert
- */
- public static class Instance<V extends NumberVector<?>> extends AbstractIndexBasedDistanceFunction.Instance<V, FilteredLocalPCAIndex<V>, SubspaceDistance, LocalSubspaceDistanceFunction> implements FilteredLocalPCABasedDistanceFunction.Instance<V, FilteredLocalPCAIndex<V>, SubspaceDistance> {
- /**
- * @param database Database
- * @param index Index
- */
- public Instance(Relation<V> database, FilteredLocalPCAIndex<V> index, LocalSubspaceDistanceFunction distanceFunction) {
- super(database, index, distanceFunction);
- }
-
- /**
- * Note, that the pca of o1 must have equal ore more strong eigenvectors
- * than the pca of o2.
- *
- */
- @Override
- public SubspaceDistance distance(DBIDRef id1, DBIDRef id2) {
- PCAFilteredResult pca1 = index.getLocalProjection(id1);
- PCAFilteredResult pca2 = index.getLocalProjection(id2);
- V o1 = relation.get(id1);
- V o2 = relation.get(id2);
- return distance(o1, o2, pca1, pca2);
- }
-
- /**
- * Computes the distance between two given DatabaseObjects according to this
- * distance function. Note, that the first pca must have an equal number of
- * strong eigenvectors than the second pca.
- *
- * @param o1 first DatabaseObject
- * @param o2 second DatabaseObject
- * @param pca1 first PCA
- * @param pca2 second PCA
- * @return the distance between two given DatabaseObjects according to this
- * distance function
- */
- public SubspaceDistance distance(V o1, V o2, PCAFilteredResult pca1, PCAFilteredResult pca2) {
- if(pca1.getCorrelationDimension() != pca2.getCorrelationDimension()) {
- throw new IllegalStateException("pca1.getCorrelationDimension() != pca2.getCorrelationDimension()");
- }
-
- Matrix strong_ev1 = pca1.getStrongEigenvectors();
- Matrix weak_ev2 = pca2.getWeakEigenvectors();
- Matrix m1 = weak_ev2.getColumnDimensionality() == 0 ? strong_ev1.transpose() : strong_ev1.transposeTimes(weak_ev2);
- double d1 = m1.norm2();
-
- WeightedDistanceFunction df1 = new WeightedDistanceFunction(pca1.similarityMatrix());
- WeightedDistanceFunction df2 = new WeightedDistanceFunction(pca2.similarityMatrix());
-
- double affineDistance = Math.max(df1.distance(o1, o2).doubleValue(), df2.distance(o1, o2).doubleValue());
-
- return new SubspaceDistance(d1, affineDistance);
- }
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer extends AbstractIndexBasedDistanceFunction.Parameterizer<LocalProjectionIndex.Factory<NumberVector<?>, FilteredLocalPCAIndex<NumberVector<?>>>> {
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- configIndexFactory(config, LocalProjectionIndex.Factory.class, KNNQueryFilteredPCAIndex.Factory.class);
- }
-
- @Override
- protected LocalSubspaceDistanceFunction makeInstance() {
- return new LocalSubspaceDistanceFunction(factory);
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/OnedimensionalDistanceFunction.java
index 5fbe1c73..581e9ebc 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/DimensionSelectingDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/OnedimensionalDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
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
@@ -23,14 +23,12 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.BitSet;
-
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.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.VectorTypeInformation;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialDoubleDistanceNorm;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractSpatialNorm;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -38,17 +36,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
/**
- * Provides a distance function that computes the distance between feature
- * vectors as the absolute difference of their values in a specified dimension.
+ * Distance function that computes the distance between feature vectors as the
+ * absolute difference of their values in a specified dimension only.
*
* @author Elke Achtert
*/
-public class DimensionSelectingDistanceFunction extends AbstractSpatialDoubleDistanceNorm implements DimensionSelectingSubspaceDistanceFunction<NumberVector<?>, DoubleDistance> {
- /**
- * Parameter for dimensionality.
- */
- public static final OptionID DIM_ID = new OptionID("dim", "an integer between 1 and the dimensionality of the " + "feature space 1 specifying the dimension to be considered " + "for distance computation.");
-
+public class OnedimensionalDistanceFunction extends AbstractSpatialNorm implements DimensionSelectingSubspaceDistanceFunction<NumberVector> {
/**
* The dimension to be considered for distance computation.
*/
@@ -59,7 +52,7 @@ public class DimensionSelectingDistanceFunction extends AbstractSpatialDoubleDis
*
* @param dim Dimension
*/
- public DimensionSelectingDistanceFunction(int dim) {
+ public OnedimensionalDistanceFunction(int dim) {
super();
this.dim = dim;
}
@@ -74,41 +67,34 @@ public class DimensionSelectingDistanceFunction extends AbstractSpatialDoubleDis
* distance function
*/
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
if(dim >= v1.getDimensionality() || dim >= v2.getDimensionality() || dim < 0) {
throw new IllegalArgumentException("Specified dimension to be considered " + "is larger that dimensionality of FeatureVectors:" + "\n first argument: " + v1.toString() + "\n second argument: " + v2.toString() + "\n dimension: " + dim);
}
- double manhattan = v1.doubleValue(dim) - v2.doubleValue(dim);
- return Math.abs(manhattan);
+ double delta = v1.doubleValue(dim) - v2.doubleValue(dim);
+ return delta >= 0 ? delta : -delta;
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
if(dim >= mbr1.getDimensionality() || dim >= mbr2.getDimensionality() || dim < 0) {
throw new IllegalArgumentException("Specified dimension to be considered " + "is larger that dimensionality of FeatureVectors:" + "\n first argument: " + mbr1.toString() + "\n second argument: " + mbr2.toString() + "\n dimension: " + dim);
}
- double m1, m2;
- if(mbr1.getMax(dim) < mbr2.getMin(dim)) {
- m1 = mbr1.getMax(dim);
- m2 = mbr2.getMin(dim);
- }
- else if(mbr1.getMin(dim) > mbr2.getMax(dim)) {
- m1 = mbr1.getMin(dim);
- m2 = mbr2.getMax(dim);
+ final double max1 = mbr1.getMax(dim), min2 = mbr2.getMin(dim);
+ if(max1 < min2) {
+ return min2 - max1;
}
- else { // The mbrs intersect!
- m1 = 0;
- m2 = 0;
+ final double min1 = mbr1.getMin(dim), max2 = mbr2.getMax(dim);
+ if(min1 > max2) {
+ return min1 - max2;
}
- double manhattan = m1 - m2;
-
- return Math.abs(manhattan);
+ return 0;
}
@Override
- public double doubleNorm(NumberVector<?> obj) {
+ public double norm(NumberVector obj) {
return Math.abs(obj.doubleValue(dim));
}
@@ -123,31 +109,27 @@ public class DimensionSelectingDistanceFunction extends AbstractSpatialDoubleDis
@Override
@Deprecated
- public BitSet getSelectedDimensions() {
- BitSet bs = new BitSet(dim + 1);
- bs.set(dim);
+ public long[] getSelectedDimensions() {
+ long[] bs = BitsUtil.zero(dim);
+ BitsUtil.setI(bs, dim);
return bs;
}
@Override
- public void setSelectedDimensions(BitSet dimensions) {
- dim = dimensions.nextSetBit(0);
+ @Deprecated
+ public void setSelectedDimensions(long[] dimensions) {
+ dim = BitsUtil.nextSetBit(dimensions, 0);
if(dim == -1) {
throw new IllegalStateException("No dimension was set.");
}
- if(dimensions.nextSetBit(dim + 1) > 0) {
+ if(BitsUtil.nextSetBit(dimensions, dim + 1) > 0) {
throw new IllegalStateException("More than one dimension was set.");
}
}
@Override
- public VectorTypeInformation<? super NumberVector<?>> getInputTypeRestriction() {
- return new VectorFieldTypeInformation<>(NumberVector.class, dim, Integer.MAX_VALUE);
- }
-
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
+ public VectorTypeInformation<? super NumberVector> getInputTypeRestriction() {
+ return VectorFieldTypeInformation.typeRequest(NumberVector.class, dim, Integer.MAX_VALUE);
}
@Override
@@ -158,7 +140,7 @@ public class DimensionSelectingDistanceFunction extends AbstractSpatialDoubleDis
if(!this.getClass().equals(obj.getClass())) {
return false;
}
- return this.dim == ((DimensionSelectingDistanceFunction) obj).dim;
+ return this.dim == ((OnedimensionalDistanceFunction) obj).dim;
}
/**
@@ -169,21 +151,29 @@ public class DimensionSelectingDistanceFunction extends AbstractSpatialDoubleDis
* @apiviz.exclude
*/
public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Parameter for dimensionality.
+ */
+ public static final OptionID DIM_ID = new OptionID("dim", "an integer between 1 and the dimensionality of the " + "feature space 1 specifying the dimension to be considered " + "for distance computation.");
+
+ /**
+ * Selected dimension.
+ */
protected int dim = 0;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final IntParameter dimP = new IntParameter(DIM_ID);
- dimP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_INT);
+ final IntParameter dimP = new IntParameter(DIM_ID)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_INT);
if(config.grab(dimP)) {
dim = dimP.getValue();
}
}
@Override
- protected DimensionSelectingDistanceFunction makeInstance() {
- return new DimensionSelectingDistanceFunction(dim);
+ protected OnedimensionalDistanceFunction makeInstance() {
+ return new OnedimensionalDistanceFunction(dim);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceEuclideanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceEuclideanDistanceFunction.java
index d24fc62e..a48de183 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceEuclideanDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceEuclideanDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
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
@@ -23,14 +23,13 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.BitSet;
-
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
/**
- * Provides a distance function that computes the Euclidean distance between
- * feature vectors only in specified dimensions.
+ * Euclidean distance function between {@link NumberVector}s only in specified
+ * dimensions.
*
* @author Elke Achtert
*/
@@ -40,13 +39,12 @@ public class SubspaceEuclideanDistanceFunction extends SubspaceLPNormDistanceFun
*
* @param dimensions Selected dimensions
*/
- public SubspaceEuclideanDistanceFunction(BitSet dimensions) {
+ public SubspaceEuclideanDistanceFunction(long[] dimensions) {
super(2.0, dimensions);
}
/**
- * Provides the Euclidean distance between two given feature vectors in the
- * selected dimensions.
+ * Constructor.
*
* @param v1 first feature vector
* @param v2 second feature vector
@@ -54,13 +52,13 @@ public class SubspaceEuclideanDistanceFunction extends SubspaceLPNormDistanceFun
* selected dimensions
*/
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
if(v1.getDimensionality() != v2.getDimensionality()) {
throw new IllegalArgumentException("Different dimensionality of FeatureVectors\n " + "first argument: " + v1 + "\n " + "second argument: " + v2);
}
double sqrDist = 0;
- for(int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
final double delta = v1.doubleValue(d) - v2.doubleValue(d);
sqrDist += delta * delta;
}
@@ -68,13 +66,13 @@ public class SubspaceEuclideanDistanceFunction extends SubspaceLPNormDistanceFun
}
@Override
- protected double doubleMinDistObject(SpatialComparable mbr, NumberVector<?> v) {
+ protected double minDistObject(SpatialComparable mbr, NumberVector v) {
if(mbr.getDimensionality() != v.getDimensionality()) {
throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr.toString() + "\n " + "second argument: " + v.toString());
}
double sqrDist = 0;
- for(int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
final double delta;
final double value = v.doubleValue(d);
final double omin = mbr.getMin(d);
@@ -96,12 +94,12 @@ public class SubspaceEuclideanDistanceFunction extends SubspaceLPNormDistanceFun
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
if(mbr1.getDimensionality() != mbr2.getDimensionality()) {
throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr1.toString() + "\n " + "second argument: " + mbr2.toString());
}
double sqrDist = 0;
- for(int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
final double delta;
final double max1 = mbr1.getMax(d);
final double min2 = mbr2.getMin(d);
@@ -124,9 +122,9 @@ public class SubspaceEuclideanDistanceFunction extends SubspaceLPNormDistanceFun
}
@Override
- public double doubleNorm(NumberVector<?> obj) {
+ public double norm(NumberVector obj) {
double sqrDist = 0;
- for(int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
final double delta = obj.doubleValue(d);
sqrDist += delta * delta;
}
@@ -140,7 +138,7 @@ public class SubspaceEuclideanDistanceFunction extends SubspaceLPNormDistanceFun
*
* @apiviz.exclude
*/
- public static class Parameterizer extends AbstractDimensionsSelectingDoubleDistanceFunction.Parameterizer {
+ public static class Parameterizer extends AbstractDimensionsSelectingDistanceFunction.Parameterizer {
@Override
protected SubspaceEuclideanDistanceFunction makeInstance() {
return new SubspaceEuclideanDistanceFunction(dimensions);
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceLPNormDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceLPNormDistanceFunction.java
index 6c9579ad..34ea7eac 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceLPNormDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceLPNormDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
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
@@ -23,30 +23,28 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.BitSet;
-
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.TypeUtil;
import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.database.query.distance.SpatialPrimitiveDistanceQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.DoubleNorm;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.Norm;
import de.lmu.ifi.dbs.elki.distance.distancefunction.NumberVectorDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
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 distance function that computes the Euclidean distance between
- * feature vectors only in specified dimensions.
+ * LP-Norm distance function between {@link NumberVector}s only in specified
+ * dimensions.
*
* @author Elke Achtert
*/
-public class SubspaceLPNormDistanceFunction extends AbstractDimensionsSelectingDoubleDistanceFunction<NumberVector<?>> implements SpatialPrimitiveDoubleDistanceFunction<NumberVector<?>>, DoubleNorm<NumberVector<?>>, NumberVectorDistanceFunction<DoubleDistance> {
+public class SubspaceLPNormDistanceFunction extends AbstractDimensionsSelectingDistanceFunction<NumberVector> implements SpatialPrimitiveDistanceFunction<NumberVector>, Norm<NumberVector>, NumberVectorDistanceFunction<NumberVector> {
/**
* Value of p
*/
@@ -58,7 +56,7 @@ public class SubspaceLPNormDistanceFunction extends AbstractDimensionsSelectingD
* @param dimensions Selected dimensions
* @param p p value
*/
- public SubspaceLPNormDistanceFunction(double p, BitSet dimensions) {
+ public SubspaceLPNormDistanceFunction(double p, long[] dimensions) {
super(dimensions);
this.p = p;
}
@@ -72,36 +70,27 @@ public class SubspaceLPNormDistanceFunction extends AbstractDimensionsSelectingD
return p;
}
- /**
- * Provides the Euclidean distance between two given feature vectors in the
- * selected dimensions.
- *
- * @param v1 first feature vector
- * @param v2 second feature vector
- * @return the Euclidean distance between two given feature vectors in the
- * selected dimensions
- */
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
if(v1.getDimensionality() != v2.getDimensionality()) {
throw new IllegalArgumentException("Different dimensionality of FeatureVectors\n " + "first argument: " + v1 + "\n " + "second argument: " + v2);
}
double sqrDist = 0;
- for(int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
double delta = Math.abs(v1.doubleValue(d) - v2.doubleValue(d));
sqrDist += Math.pow(delta, p);
}
return Math.pow(sqrDist, 1. / p);
}
- protected double doubleMinDistObject(SpatialComparable mbr, NumberVector<?> v) {
+ protected double minDistObject(SpatialComparable mbr, NumberVector v) {
if(mbr.getDimensionality() != v.getDimensionality()) {
throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr.toString() + "\n " + "second argument: " + v.toString());
}
double sqrDist = 0;
- for(int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
final double delta;
final double value = v.doubleValue(d);
final double omin = mbr.getMin(d);
@@ -123,12 +112,12 @@ public class SubspaceLPNormDistanceFunction extends AbstractDimensionsSelectingD
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
if(mbr1.getDimensionality() != mbr2.getDimensionality()) {
throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr1.toString() + "\n " + "second argument: " + mbr2.toString());
}
double sqrDist = 0;
- for(int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
final double delta;
final double max1 = mbr1.getMax(d);
final double min2 = mbr2.getMin(d);
@@ -151,19 +140,9 @@ public class SubspaceLPNormDistanceFunction extends AbstractDimensionsSelectingD
}
@Override
- public DoubleDistance minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
- return new DoubleDistance(doubleMinDist(mbr1, mbr2));
- }
-
- @Override
- public DoubleDistance norm(NumberVector<?> obj) {
- return new DoubleDistance(doubleNorm(obj));
- }
-
- @Override
- public double doubleNorm(NumberVector<?> obj) {
+ public double norm(NumberVector obj) {
double sqrDist = 0;
- for(int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
double delta = Math.abs(obj.doubleValue(d));
sqrDist += Math.pow(delta, p);
}
@@ -171,12 +150,12 @@ public class SubspaceLPNormDistanceFunction extends AbstractDimensionsSelectingD
}
@Override
- public <T extends NumberVector<?>> SpatialPrimitiveDistanceQuery<T, DoubleDistance> instantiate(Relation<T> database) {
+ public <T extends NumberVector> SpatialPrimitiveDistanceQuery<T> instantiate(Relation<T> database) {
return new SpatialPrimitiveDistanceQuery<>(database, this);
}
@Override
- public VectorFieldTypeInformation<? super NumberVector<?>> getInputTypeRestriction() {
+ public VectorFieldTypeInformation<? super NumberVector> getInputTypeRestriction() {
return TypeUtil.NUMBER_VECTOR_FIELD;
}
@@ -192,7 +171,7 @@ public class SubspaceLPNormDistanceFunction extends AbstractDimensionsSelectingD
*
* @apiviz.exclude
*/
- public static class Parameterizer extends AbstractDimensionsSelectingDoubleDistanceFunction.Parameterizer {
+ public static class Parameterizer extends AbstractDimensionsSelectingDistanceFunction.Parameterizer {
/**
* Value of p.
*/
@@ -200,7 +179,7 @@ public class SubspaceLPNormDistanceFunction extends AbstractDimensionsSelectingD
@Override
protected void makeOptions(Parameterization config) {
- final DoubleParameter paramP = new DoubleParameter(LPNormDistanceFunction.P_ID);
+ final DoubleParameter paramP = new DoubleParameter(LPNormDistanceFunction.Parameterizer.P_ID);
paramP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
if(config.grab(paramP)) {
p = paramP.getValue();
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceManhattanDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceManhattanDistanceFunction.java
index ccca76da..ab54b88f 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceManhattanDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceManhattanDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
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
@@ -23,14 +23,13 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.BitSet;
-
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
/**
- * Provides a distance function that computes the Euclidean distance between
- * feature vectors only in specified dimensions.
+ * Manhattan distance function between {@link NumberVector}s only in specified
+ * dimensions.
*
* @author Elke Achtert
*/
@@ -40,40 +39,31 @@ public class SubspaceManhattanDistanceFunction extends SubspaceLPNormDistanceFun
*
* @param dimensions Selected dimensions
*/
- public SubspaceManhattanDistanceFunction(BitSet dimensions) {
+ public SubspaceManhattanDistanceFunction(long[] dimensions) {
super(1.0, dimensions);
}
- /**
- * Provides the Euclidean distance between two given feature vectors in the
- * selected dimensions.
- *
- * @param v1 first feature vector
- * @param v2 second feature vector
- * @return the Euclidean distance between two given feature vectors in the
- * selected dimensions
- */
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
+ public double distance(NumberVector v1, NumberVector v2) {
if(v1.getDimensionality() != v2.getDimensionality()) {
throw new IllegalArgumentException("Different dimensionality of FeatureVectors\n " + "first argument: " + v1 + "\n " + "second argument: " + v2);
}
double sum = 0;
- for(int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
sum += Math.abs(v1.doubleValue(d) - v2.doubleValue(d));
}
return sum;
}
@Override
- protected double doubleMinDistObject(SpatialComparable mbr, NumberVector<?> v) {
+ protected double minDistObject(SpatialComparable mbr, NumberVector v) {
if(mbr.getDimensionality() != v.getDimensionality()) {
throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr.toString() + "\n " + "second argument: " + v.toString());
}
double sum = 0;
- for(int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
final double value = v.doubleValue(d);
final double omin = mbr.getMin(d);
if(value < omin) {
@@ -93,12 +83,12 @@ public class SubspaceManhattanDistanceFunction extends SubspaceLPNormDistanceFun
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
if(mbr1.getDimensionality() != mbr2.getDimensionality()) {
throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr1.toString() + "\n " + "second argument: " + mbr2.toString());
}
double sum = 0;
- for(int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
final double max1 = mbr1.getMax(d);
final double min2 = mbr2.getMin(d);
if(max1 < min2) {
@@ -119,9 +109,9 @@ public class SubspaceManhattanDistanceFunction extends SubspaceLPNormDistanceFun
}
@Override
- public double doubleNorm(NumberVector<?> obj) {
+ public double norm(NumberVector obj) {
double sum = 0;
- for(int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
sum += Math.abs(obj.doubleValue(d));
}
return sum;
@@ -134,7 +124,7 @@ public class SubspaceManhattanDistanceFunction extends SubspaceLPNormDistanceFun
*
* @apiviz.exclude
*/
- public static class Parameterizer extends AbstractDimensionsSelectingDoubleDistanceFunction.Parameterizer {
+ public static class Parameterizer extends AbstractDimensionsSelectingDistanceFunction.Parameterizer {
@Override
protected SubspaceManhattanDistanceFunction makeInstance() {
return new SubspaceManhattanDistanceFunction(dimensions);
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceMaximumDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceMaximumDistanceFunction.java
index 60791159..d1f0485c 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceMaximumDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/SubspaceMaximumDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
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
@@ -23,14 +23,13 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.subspace;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.BitSet;
-
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
/**
- * Provides a distance function that computes the Euclidean distance between
- * feature vectors only in specified dimensions.
+ * Maximum distance function between {@link NumberVector}s only in specified
+ * dimensions.
*
* @author Elke Achtert
*/
@@ -40,29 +39,20 @@ public class SubspaceMaximumDistanceFunction extends SubspaceLPNormDistanceFunct
*
* @param dimensions Selected dimensions
*/
- public SubspaceMaximumDistanceFunction(BitSet dimensions) {
+ public SubspaceMaximumDistanceFunction(long[] dimensions) {
super(1.0, dimensions);
}
- /**
- * Provides the Euclidean distance between two given feature vectors in the
- * selected dimensions.
- *
- * @param v1 first feature vector
- * @param v2 second feature vector
- * @return the Euclidean distance between two given feature vectors in the
- * selected dimensions
- */
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
- if (v1.getDimensionality() != v2.getDimensionality()) {
+ public double distance(NumberVector v1, NumberVector v2) {
+ if(v1.getDimensionality() != v2.getDimensionality()) {
throw new IllegalArgumentException("Different dimensionality of FeatureVectors\n " + "first argument: " + v1 + "\n " + "second argument: " + v2);
}
double agg = 0.;
- for (int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
double v = Math.abs(v1.doubleValue(d) - v2.doubleValue(d));
- if (v > agg) {
+ if(v > agg) {
agg = v;
}
}
@@ -70,24 +60,25 @@ public class SubspaceMaximumDistanceFunction extends SubspaceLPNormDistanceFunct
}
@Override
- protected double doubleMinDistObject(SpatialComparable mbr, NumberVector<?> v) {
- if (mbr.getDimensionality() != v.getDimensionality()) {
+ protected double minDistObject(SpatialComparable mbr, NumberVector v) {
+ if(mbr.getDimensionality() != v.getDimensionality()) {
throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr.toString() + "\n " + "second argument: " + v.toString());
}
double agg = 0.;
- for (int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
final double value = v.doubleValue(d);
final double omin = mbr.getMin(d);
final double diff1 = omin - value;
- if (diff1 > 0.) {
- if (diff1 > agg) {
+ if(diff1 > 0.) {
+ if(diff1 > agg) {
agg = diff1;
}
- } else {
+ }
+ else {
final double omax = mbr.getMax(d);
final double diff2 = value - omax;
- if (diff2 > agg) {
+ if(diff2 > agg) {
agg = diff2;
}
}
@@ -96,24 +87,25 @@ public class SubspaceMaximumDistanceFunction extends SubspaceLPNormDistanceFunct
}
@Override
- public double doubleMinDist(SpatialComparable mbr1, SpatialComparable mbr2) {
- if (mbr1.getDimensionality() != mbr2.getDimensionality()) {
+ public double minDist(SpatialComparable mbr1, SpatialComparable mbr2) {
+ if(mbr1.getDimensionality() != mbr2.getDimensionality()) {
throw new IllegalArgumentException("Different dimensionality of objects\n " + "first argument: " + mbr1.toString() + "\n " + "second argument: " + mbr2.toString());
}
double agg = 0.;
- for (int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
final double max1 = mbr1.getMax(d);
final double min2 = mbr2.getMin(d);
- if (max1 < min2) {
+ if(max1 < min2) {
double v = min2 - max1;
- if (v > agg) {
+ if(v > agg) {
agg = v;
}
- } else {
+ }
+ else {
final double min1 = mbr1.getMin(d);
final double max2 = mbr2.getMax(d);
double v = min1 - max2;
- if (v > agg) {
+ if(v > agg) {
agg = v;
}
}
@@ -122,11 +114,11 @@ public class SubspaceMaximumDistanceFunction extends SubspaceLPNormDistanceFunct
}
@Override
- public double doubleNorm(NumberVector<?> obj) {
+ public double norm(NumberVector obj) {
double agg = 0.;
- for (int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
double v = Math.abs(obj.doubleValue(d));
- if (v > agg) {
+ if(v > agg) {
agg = v;
}
}
@@ -140,7 +132,7 @@ public class SubspaceMaximumDistanceFunction extends SubspaceLPNormDistanceFunct
*
* @apiviz.exclude
*/
- public static class Parameterizer extends AbstractDimensionsSelectingDoubleDistanceFunction.Parameterizer {
+ public static class Parameterizer extends AbstractDimensionsSelectingDistanceFunction.Parameterizer {
@Override
protected SubspaceMaximumDistanceFunction makeInstance() {
return new SubspaceMaximumDistanceFunction(dimensions);
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/package-info.java
index 2b5db4c5..34f1bd33 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/subspace/package-info.java
@@ -1,11 +1,13 @@
/**
* <p>Distance functions based on subspaces.</p>
+ *
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.math.dimensionsimilarity
*/
/*
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
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/AbstractEditDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/AbstractEditDistanceFunction.java
index c6a35985..f7d95525 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/AbstractEditDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/AbstractEditDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries;
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,8 +25,8 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
-import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.data.type.VectorTypeInformation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -34,16 +34,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
- * Provides the Edit Distance for FeatureVectors.
+ * Edit Distance for FeatureVectors.
*
* @author Thomas Bernecker
*/
-public abstract class AbstractEditDistanceFunction extends AbstractVectorDoubleDistanceFunction {
- /**
- * BANDSIZE parameter
- */
- public static final OptionID BANDSIZE_ID = new OptionID("edit.bandSize", "the band size for Edit Distance alignment (positive double value, 0 <= bandSize <= 1)");
-
+public abstract class AbstractEditDistanceFunction extends AbstractNumberVectorDistanceFunction {
/**
* Keeps the currently set bandSize.
*/
@@ -59,10 +54,27 @@ public abstract class AbstractEditDistanceFunction extends AbstractVectorDoubleD
this.bandSize = bandSize;
}
- // TODO: relax this to VectorTypeInformation!
+ /**
+ * Compute the effective band size.
+ *
+ * @param dim1 First dimensionality
+ * @param dim2 Second dimensionality
+ * @return Effective bandsize
+ */
+ protected int effectiveBandSize(final int dim1, final int dim2) {
+ if(bandSize == Double.POSITIVE_INFINITY) {
+ return (dim1 > dim2) ? dim1 : dim2;
+ }
+ if(bandSize >= 1.) {
+ return (int) bandSize;
+ }
+ // Max * bandSize:
+ return (int) Math.ceil((dim1 >= dim2 ? dim1 : dim2) * bandSize);
+ }
+
@Override
- public VectorFieldTypeInformation<? super NumberVector<?>> getInputTypeRestriction() {
- return TypeUtil.NUMBER_VECTOR_FIELD;
+ public VectorTypeInformation<? super NumberVector> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH;
}
@Override
@@ -84,14 +96,25 @@ public abstract class AbstractEditDistanceFunction extends AbstractVectorDoubleD
* @apiviz.exclude
*/
public abstract static class Parameterizer extends AbstractParameterizer {
- protected double bandSize = 0.0;
+ /**
+ * Bandsize parameter.
+ */
+ public static final OptionID BANDSIZE_ID = new OptionID("edit.bandsize", //
+ "The band size for time series alignment. By default, no constraint is used. "//
+ + "If the value is larger than 0, it will be considered absolute, otherwise relative to the longer sequence. " //
+ + "Note that 0 does not make sense: use Euclidean distance then instead.");
+
+ /**
+ * Keeps the currently set bandSize.
+ */
+ protected double bandSize = Double.POSITIVE_INFINITY;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final DoubleParameter bandSizeP = new DoubleParameter(BANDSIZE_ID, 0.1);
- bandSizeP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
- bandSizeP.addConstraint(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
+ final DoubleParameter bandSizeP = new DoubleParameter(BANDSIZE_ID) //
+ .setOptional(true) //
+ .addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
if(config.grab(bandSizeP)) {
bandSize = bandSizeP.doubleValue();
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/DTWDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/DTWDistanceFunction.java
index eedd3a7c..f7981c93 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/DTWDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/DTWDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries;
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
@@ -23,21 +23,44 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.Arrays;
+
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
/**
- * Provides the Dynamic Time Warping distance for FeatureVectors.
+ * Dynamic Time Warping distance (DTW) for numerical vectors.
+ *
+ * Reference:
+ * <p>
+ * Berndt, D. and Clifford, J.<br />
+ * Using dynamic time warping to find patterns in time series<br />
+ * AAAI-94 Workshop on Knowledge Discovery in Databases, 1994
+ * </p>
+ *
+ * This implementation uses a buffer storing two rows.
+ *
+ * TODO: allow different one-dimensional distances
*
* @author Thomas Bernecker
+ * @author Erich Schubert
*/
@Title("Dynamic Time Warping Distance Function")
-@Reference(authors = "Berndt, D. and Clifford, J.", title = "Using dynamic time warping to find patterns in time series", booktitle = "AAAI-94 Workshop on Knowledge Discovery in Databases, 1994", url = "http://www.aaai.org/Papers/Workshops/1994/WS-94-03/WS94-03-031.pdf")
+@Reference(authors = "Berndt, D. and Clifford, J.", //
+title = "Using dynamic time warping to find patterns in time series", //
+booktitle = "AAAI-94 Workshop on Knowledge Discovery in Databases, 1994", //
+url = "http://www.aaai.org/Papers/Workshops/1994/WS-94-03/WS94-03-031.pdf")
public class DTWDistanceFunction extends AbstractEditDistanceFunction {
/**
* Constructor.
+ */
+ public DTWDistanceFunction() {
+ this(Double.POSITIVE_INFINITY);
+ }
+
+ /**
+ * Constructor.
*
* @param bandSize Band size
*/
@@ -45,74 +68,98 @@ public class DTWDistanceFunction extends AbstractEditDistanceFunction {
super(bandSize);
}
- /**
- * Provides the Dynamic Time Warping distance between the given two vectors.
- *
- * @return the Dynamic Time Warping distance between the given two vectors as
- * an instance of {@link DoubleDistance DoubleDistance}.
- */
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
- // Current and previous columns of the matrix
- double[] curr = new double[v2.getDimensionality()];
- double[] prev = new double[v2.getDimensionality()];
+ public double distance(NumberVector v1, NumberVector v2) {
+ // Dimensionality, and last valid value in second vector:
+ final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality();
+ final int m2 = dim2 - 1;
- // size of edit distance band
- int band = (int) Math.ceil(v2.getDimensionality() * bandSize);
// bandsize is the maximum allowed distance to the diagonal
-
- // System.out.println("len1: " + features1.length + ", len2: " +
- // features2.length + ", band: " + band);
-
- for(int i = 0; i < v1.getDimensionality(); i++) {
- // Swap current and prev arrays. We'll just overwrite the new curr.
- {
- double[] temp = prev;
- prev = curr;
- curr = temp;
+ final int band = effectiveBandSize(dim1, dim2);
+ // unsatisfiable - lengths too different!
+ if(Math.abs(dim1 - dim2) > band) {
+ return Double.POSITIVE_INFINITY;
+ }
+ // Current and previous columns of the matrix
+ double[] buf = new double[dim2 << 1];
+ Arrays.fill(buf, Double.POSITIVE_INFINITY);
+
+ // Fill first row:
+ firstRow(buf, band, v1, v2, dim2);
+
+ // Active buffer offsets (cur = read, nxt = write)
+ int cur = 0, nxt = dim2;
+ // Fill remaining rows:
+ int i = 1, l = 0, r = Math.min(m2, i + band);
+ while(i < dim1) {
+ final double val1 = v1.doubleValue(i);
+ for(int j = l; j <= r; j++) {
+ // Value in previous row (must exist, may be infinite):
+ double min = buf[cur + j];
+ // Diagonal:
+ if(j > 0) {
+ final double pij = buf[cur + j - 1];
+ min = (pij < min) ? pij : min;
+ // Previous in same row:
+ if(j > l) {
+ final double pj = buf[nxt + j - 1];
+ min = (pj < min) ? pj : min;
+ }
+ }
+ // Write:
+ buf[nxt + j] = min + delta(val1, v2.doubleValue(j));
}
- int l = i - (band + 1);
- if(l < 0) {
- l = 0;
+ // Swap buffer positions:
+ cur = dim2 - cur;
+ nxt = dim2 - nxt;
+ // Update positions:
+ ++i;
+ if(i > band) {
+ ++l;
}
- int r = i + (band + 1);
- if(r > (v2.getDimensionality() - 1)) {
- r = (v2.getDimensionality() - 1);
+ if(r < m2) {
+ ++r;
}
+ }
- for(int j = l; j <= r; j++) {
- if(Math.abs(i - j) <= band) {
- double val1 = v1.doubleValue(i);
- double val2 = v2.doubleValue(j);
- double diff = (val1 - val2);
- // Formally: diff = Math.sqrt(diff * diff);
-
- double cost = diff * diff;
-
- if((i + j) != 0) {
- if((i == 0) || ((j != 0) && ((prev[j - 1] > curr[j - 1]) && (curr[j - 1] < prev[j])))) {
- // del
- cost += curr[j - 1];
- }
- else if((j == 0) || ((i != 0) && ((prev[j - 1] > prev[j]) && (prev[j] < curr[j - 1])))) {
- // ins
- cost += prev[j];
- }
- else {
- // match
- cost += prev[j - 1];
- }
- }
+ // TODO: support Euclidean, Manhattan here:
+ return Math.sqrt(buf[cur + dim2 - 1]);
+ }
- curr[j] = cost;
- }
- else {
- curr[j] = Double.POSITIVE_INFINITY; // outside band
- }
- }
+ /**
+ * Fill the first row.
+ *
+ * @param buf Buffer
+ * @param band Bandwidth
+ * @param v1 First vector
+ * @param v2 Second vector
+ * @param dim2 Dimensionality of second
+ */
+ protected void firstRow(double[] buf, int band, NumberVector v1, NumberVector v2, int dim2) {
+ // First cell:
+ final double val1 = v1.doubleValue(0);
+ buf[0] = delta(val1, v2.doubleValue(0));
+
+ // Width of valid area:
+ final int w = (band >= dim2) ? dim2 - 1 : band;
+ // Fill remaining part of buffer:
+ for(int j = 1; j <= w; j++) {
+ buf[j] = buf[j - 1] + delta(val1, v2.doubleValue(j));
}
+ }
- return Math.sqrt(curr[v2.getDimensionality() - 1]);
+ /**
+ * Compute the delta of two values.
+ *
+ * TODO: support Euclidean, Manhattan, others?
+ *
+ * @param val1 First value
+ * @param val2 Second value
+ * @return Difference
+ */
+ protected double delta(double val1, double val2) {
+ double diff = val1 - val2;
+ return diff * diff;
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/DerivativeDTWDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/DerivativeDTWDistanceFunction.java
new file mode 100644
index 00000000..7330466b
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/DerivativeDTWDistanceFunction.java
@@ -0,0 +1,154 @@
+package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.util.Arrays;
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
+
+/**
+ * Derivative Dynamic Time Warping distance for numerical vectors.
+ *
+ * Reference:
+ * <p>
+ * E. J. Keogh and M. J. Pazzani<br />
+ * Derivative dynamic time warping<br />
+ * In the 1st SIAM International Conference on Data Mining (SDM-2001), Chicago,
+ * IL, USA.
+ * </p>
+ *
+ * @author Lara Hirschbeck, Daniel Kolb
+ */
+@Title("Derivative dynamic time warping")
+@Reference(authors = "E. J. Keogh and M. J. Pazzani", //
+title = "Derivative dynamic time warping", //
+booktitle = "1st SIAM International Conference on Data Mining (SDM-2001)", //
+url = "https://siam.org/proceedings/datamining/2001/dm01_01KeoghE.pdf")
+public class DerivativeDTWDistanceFunction extends DTWDistanceFunction {
+ /**
+ * Constructor.
+ */
+ public DerivativeDTWDistanceFunction() {
+ this(Double.POSITIVE_INFINITY);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param bandSize Band size
+ */
+ public DerivativeDTWDistanceFunction(double bandSize) {
+ super(bandSize);
+ }
+
+ @Override
+ public double distance(NumberVector v1, NumberVector v2) {
+ // Dimensionality, and last valid value in second vector:
+ final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality();
+ final int m2 = dim2 - 1;
+
+ // bandsize is the maximum allowed distance to the diagonal
+ final int band = effectiveBandSize(dim1, dim2);
+ // unsatisfiable - lengths too different!
+ if(Math.abs(dim1 - dim2) > band) {
+ return Double.POSITIVE_INFINITY;
+ }
+ // Current and previous columns of the matrix
+ double[] buf = new double[dim2 << 1];
+ Arrays.fill(buf, Double.POSITIVE_INFINITY);
+
+ // Fill first row:
+ firstRow(buf, band, v1, v2, dim2);
+
+ // Active buffer offsets (cur = read, nxt = write)
+ int cur = 0, nxt = dim2;
+ // Fill remaining rows:
+ int i = 1, l = 0, r = Math.min(m2, i + band);
+ while(i < dim1) {
+ final double val1 = derivative(i, v1);
+ for(int j = l; j <= r; j++) {
+ // Value in previous row (must exist, may be infinite):
+ double min = buf[cur + j];
+ // Diagonal:
+ if(j > 0) {
+ final double pij = buf[cur + j - 1];
+ min = (pij < min) ? pij : min;
+ // Previous in same row:
+ if(j > l) {
+ final double pj = buf[nxt + j - 1];
+ min = (pj < min) ? pj : min;
+ }
+ }
+ // Write:
+ buf[nxt + j] = min + delta(val1, derivative(j, v2));
+ }
+ // Swap buffer positions:
+ cur = dim2 - cur;
+ nxt = dim2 - nxt;
+ // Update positions:
+ ++i;
+ if(i > band) {
+ ++l;
+ }
+ if(r < m2) {
+ ++r;
+ }
+ }
+
+ // TODO: support Euclidean, Manhattan here:
+ return Math.sqrt(buf[cur + dim2 - 1]);
+ }
+
+ @Override
+ protected void firstRow(double[] buf, int band, NumberVector v1, NumberVector v2, int dim2) {
+ // First cell:
+ final double val1 = derivative(0, v1);
+ buf[0] = delta(val1, derivative(0, v2));
+
+ // Width of valid area:
+ final int w = (band >= dim2) ? dim2 - 1 : band;
+ // Fill remaining part of buffer:
+ for(int j = 1; j <= w; j++) {
+ buf[j] = buf[j - 1] + delta(val1, derivative(j, v2));
+ }
+ }
+
+ /**
+ * Given a NumberVector and the position of an element, approximates the
+ * gradient of given element.
+ *
+ * @return Derivative as double
+ */
+ public double derivative(int i, NumberVector v) {
+ final int dim = v.getDimensionality();
+ if(dim == 1) {
+ return 0.;
+ }
+ // Adjust for boundary conditions, as per the article:
+ i = (i == 0) ? 1 : (i == dim - 1) ? dim - 2 : i;
+ return (v.doubleValue(i) - v.doubleValue(i - 1) + (v.doubleValue(i + 1) - v.doubleValue(i - 1)) * .5) * .5;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/EDRDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/EDRDistanceFunction.java
index d48a21f0..5c11302f 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/EDRDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/EDRDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries;
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
@@ -23,8 +23,9 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.Arrays;
+
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -33,22 +34,28 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
- * Provides the Edit Distance on Real Sequence distance for FeatureVectors.
+ * Edit Distance on Real Sequence distance for numerical vectors.
+ *
+ * Reference:
+ * <p>
+ * L. Chen and M. T. Özsu and V. Oria<br />
+ * Robust and fast similarity search for moving object trajectories<br />
+ * SIGMOD '05: Proceedings of the 2005 ACM SIGMOD international conference on
+ * Management of data
+ * </p>
*
* @author Thomas Bernecker
*/
@Title("Edit Distance on Real Sequence")
-@Reference(authors = "L. Chen and M. T. Özsu and V. Oria", title = "Robust and fast similarity search for moving object trajectories", booktitle = "SIGMOD '05: Proceedings of the 2005 ACM SIGMOD international conference on Management of data", url = "http://dx.doi.org/10.1145/1066157.1066213")
-public class EDRDistanceFunction extends AbstractEditDistanceFunction {
- /**
- * DELTA parameter
- */
- public static final OptionID DELTA_ID = new OptionID("edr.delta", "the delta parameter (similarity threshold) for EDR (positive number)");
-
+@Reference(authors = "L. Chen and M. T. Özsu and V. Oria", //
+title = "Robust and fast similarity search for moving object trajectories", //
+booktitle = "SIGMOD '05: Proceedings of the 2005 ACM SIGMOD international conference on Management of data", //
+url = "http://dx.doi.org/10.1145/1066157.1066213")
+public class EDRDistanceFunction extends DTWDistanceFunction {
/**
- * Keeps the currently set delta.
+ * Delta parameter, similarity threshold for attributes.
*/
- private double delta;
+ private final double delta;
/**
* Constructor.
@@ -61,82 +68,80 @@ public class EDRDistanceFunction extends AbstractEditDistanceFunction {
this.delta = delta;
}
- /**
- * Provides the Edit Distance on Real Sequence distance between the given two
- * vectors.
- *
- * @return the Edit Distance on Real Sequence distance between the given two
- * vectors as an instance of {@link DoubleDistance DoubleDistance}.
- */
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
- // Current and previous columns of the matrix
- double[] curr = new double[v2.getDimensionality()];
- double[] prev = new double[v2.getDimensionality()];
+ public double distance(NumberVector v1, NumberVector v2) {
+ // Dimensionality, and last valid value in second vector:
+ final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality();
+ final int m2 = dim2 - 1;
- // size of edit distance band
// bandsize is the maximum allowed distance to the diagonal
- int band = (int) Math.ceil(v2.getDimensionality() * bandSize);
-
- // System.out.println("len1: " + features1.length + ", len2: " +
- // features2.length + ", band: " + band);
- final double deltaValue = delta;
-
- for(int i = 0; i < v1.getDimensionality(); i++) {
- // Swap current and prev arrays. We'll just overwrite the new curr.
- {
- double[] temp = prev;
- prev = curr;
- curr = temp;
+ final int band = effectiveBandSize(dim1, dim2);
+ // unsatisfiable - lengths too different!
+ if(Math.abs(dim1 - dim2) > band) {
+ return Double.POSITIVE_INFINITY;
+ }
+ // Current and previous columns of the matrix
+ double[] buf = new double[dim2 << 1];
+ Arrays.fill(buf, Double.POSITIVE_INFINITY);
+
+ // Fill first row:
+ firstRow(buf, band, v1, v2, dim2);
+
+ // Active buffer offsets (cur = read, nxt = write)
+ int cur = 0, nxt = dim2;
+ // Fill remaining rows:
+ int i = 1, l = 0, r = Math.min(m2, i + band);
+ while(i < dim1) {
+ final double val1 = v1.doubleValue(i);
+ for(int j = l; j <= r; j++) {
+ // Value in previous row (must exist, may be infinite):
+ double min = buf[cur + j];
+ // Diagonal:
+ if(j > 0) {
+ final double pij = buf[cur + j - 1];
+ min = (pij < min) ? pij : min;
+ // Previous in same row:
+ if(j > l) {
+ final double pj = buf[nxt + j - 1];
+ min = (pj < min) ? pj : min;
+ }
+ }
+ // Write:
+ buf[nxt + j] = min + delta(val1, v2.doubleValue(j));
}
- int l = i - (band + 1);
- if(l < 0) {
- l = 0;
+ // Swap buffer positions:
+ cur = dim2 - cur;
+ nxt = dim2 - nxt;
+ // Update positions:
+ ++i;
+ if(i > band) {
+ ++l;
}
- int r = i + (band + 1);
- if(r > (v2.getDimensionality() - 1)) {
- r = (v2.getDimensionality() - 1);
+ if(r < m2) {
+ ++r;
}
+ }
- for(int j = l; j <= r; j++) {
- if(Math.abs(i - j) <= band) {
- // compute squared distance
- double val1 = v1.doubleValue(i);
- double val2 = v2.doubleValue(j);
- double diff = (val1 - val2);
- final double d = Math.sqrt(diff * diff);
-
- final double cost;
-
- final double subcost = (d <= deltaValue) ? 0 : 1;
-
- if((i + j) != 0) {
- if((i == 0) || ((j != 0) && (((prev[j - 1] + subcost) > (curr[j - 1] + 1)) && ((curr[j - 1] + 1) < (prev[j] + 1))))) {
- // del
- cost = curr[j - 1] + 1;
- }
- else if((j == 0) || ((i != 0) && (((prev[j - 1] + subcost) > (prev[j] + 1)) && ((prev[j] + 1) < (curr[j - 1] + 1))))) {
- // ins
- cost = prev[j] + 1;
- }
- else {
- // match
- cost = prev[j - 1] + subcost;
- }
- }
- else {
- cost = 0;
- }
+ return buf[cur + dim2 - 1];
+ }
- curr[j] = cost;
- }
- else {
- curr[j] = Double.POSITIVE_INFINITY; // outside band
- }
- }
+ @Override
+ protected void firstRow(double[] buf, int band, NumberVector v1, NumberVector v2, int dim2) {
+ // First cell:
+ final double val1 = v1.doubleValue(0);
+ buf[0] = delta(val1, v2.doubleValue(0));
+
+ // Width of valid area:
+ final int w = (band >= dim2) ? dim2 - 1 : band;
+ // Fill remaining part of buffer:
+ for(int j = 1; j <= w; j++) {
+ buf[j] = buf[j - 1] + delta(val1, v2.doubleValue(j));
}
+ }
- return curr[v2.getDimensionality() - 1];
+ @Override
+ protected double delta(double val1, double val2) {
+ return (Math.abs(val1 - val2) < delta) ? 0. : 1.;
}
@Override
@@ -155,13 +160,21 @@ public class EDRDistanceFunction extends AbstractEditDistanceFunction {
* @apiviz.exclude
*/
public static class Parameterizer extends AbstractEditDistanceFunction.Parameterizer {
- protected double delta = 0.0;
+ /**
+ * DELTA parameter
+ */
+ public static final OptionID DELTA_ID = new OptionID("edr.delta", "the delta parameter (similarity threshold) for EDR (positive number)");
+
+ /**
+ * Delta parameter, similarity threshold for attributes.
+ */
+ protected double delta = 0.;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final DoubleParameter deltaP = new DoubleParameter(DELTA_ID, 1.0);
- deltaP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ final DoubleParameter deltaP = new DoubleParameter(DELTA_ID, 1.0) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
if(config.grab(deltaP)) {
delta = deltaP.doubleValue();
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/ERPDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/ERPDistanceFunction.java
index e7d7dd7e..de8d7d3c 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/ERPDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/ERPDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries;
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
@@ -23,30 +23,36 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.Arrays;
+
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-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 the Edit Distance With Real Penalty distance for FeatureVectors.
+ * Edit Distance With Real Penalty distance for numerical vectors.
+ *
+ * Reference:
+ * <p>
+ * L. Chen and R. Ng<br />
+ * On the marriage of Lp-norms and edit distance<br />
+ * VLDB '04: Proceedings of the Thirtieth international conference on Very large
+ * data bases
+ * </p>
*
* @author Thomas Bernecker
*/
@Title("Edit Distance with Real Penalty")
-@Reference(authors = "L. Chen and R. Ng", title = "On the marriage of Lp-norms and edit distance", booktitle = "VLDB '04: Proceedings of the Thirtieth international conference on Very large data bases", url = "http://www.vldb.org/conf/2004/RS21P2.PDF")
-public class ERPDistanceFunction extends AbstractEditDistanceFunction {
+@Reference(authors = "L. Chen and R. Ng", //
+title = "On the marriage of Lp-norms and edit distance", //
+booktitle = "VLDB '04: Proceedings of the Thirtieth international conference on Very large data bases", //
+url = "http://www.vldb.org/conf/2004/RS21P2.PDF")
+public class ERPDistanceFunction extends DTWDistanceFunction {
/**
- * G parameter
- */
- public static final OptionID G_ID = new OptionID("erp.g", "the g parameter ERP (positive number)");
-
- /**
- * Keeps the currently set g.
+ * Gap value.
*/
private final double g;
@@ -61,91 +67,82 @@ public class ERPDistanceFunction extends AbstractEditDistanceFunction {
this.g = g;
}
- /**
- * Provides the Edit Distance With Real Penalty distance between the given two
- * vectors.
- *
- * @return the Edit Distance With Real Penalty distance between the given two
- * vectors as an instance of {@link DoubleDistance DoubleDistance}.
- */
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
- // Current and previous columns of the matrix
- double[] curr = new double[v2.getDimensionality()];
- double[] prev = new double[v2.getDimensionality()];
+ public double distance(NumberVector v1, NumberVector v2) {
+ // Dimensionality, and last valid value in second vector:
+ final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality();
+ final int m2 = dim2 - 1;
- // size of edit distance band
// bandsize is the maximum allowed distance to the diagonal
- final int band = (int) Math.ceil(v2.getDimensionality() * bandSize);
-
- for(int i = 0; i < v1.getDimensionality(); i++) {
- // Swap current and prev arrays. We'll just overwrite the new curr.
- {
- double[] temp = prev;
- prev = curr;
- curr = temp;
+ final int band = effectiveBandSize(dim1, dim2);
+ // unsatisfiable - lengths too different!
+ if(Math.abs(dim1 - dim2) > band) {
+ return Double.POSITIVE_INFINITY;
+ }
+ // Current and previous columns of the matrix
+ double[] buf = new double[dim2 << 1];
+ Arrays.fill(buf, Double.POSITIVE_INFINITY);
+
+ // Fill first row:
+ firstRow(buf, band, v1, v2, dim2);
+
+ // Active buffer offsets (cur = read, nxt = write)
+ int cur = 0, nxt = dim2;
+ // Fill remaining rows:
+ int i = 1, l = 0, r = Math.min(m2, i + band);
+ while(i < dim1) {
+ final double val1 = v1.doubleValue(i);
+ for(int j = l; j <= r; j++) {
+ // Value in previous row (must exist, may be infinite):
+ double min = buf[cur + j] + delta(val1, g);
+ // Diagonal:
+ if(j > 0) {
+ final double pij = buf[cur + j - 1] + delta(val1, v2.doubleValue(j));
+ min = (pij < min) ? pij : min;
+ // Previous in same row:
+ if(j > l) {
+ final double pj = buf[nxt + j - 1] + delta(g, v2.doubleValue(j));
+ min = (pj < min) ? pj : min;
+ }
+ }
+ // Write:
+ buf[nxt + j] = min;
}
- int l = i - (band + 1);
- if(l < 0) {
- l = 0;
+ // Swap buffer positions:
+ cur = dim2 - cur;
+ nxt = dim2 - nxt;
+ // Update positions:
+ ++i;
+ if(i > band) {
+ ++l;
}
- int r = i + (band + 1);
- if(r > (v2.getDimensionality() - 1)) {
- r = (v2.getDimensionality() - 1);
+ if(r < m2) {
+ ++r;
}
+ }
- for(int j = l; j <= r; j++) {
- if(Math.abs(i - j) <= band) {
- // compute squared distance of feature vectors
- double val1 = v1.doubleValue(i);
- double val2 = g;
- double diff = (val1 - val2);
- final double d1 = Math.sqrt(diff * diff);
-
- val1 = g;
- val2 = v2.doubleValue(j);
- diff = (val1 - val2);
- final double d2 = Math.sqrt(diff * diff);
-
- val1 = v1.doubleValue(i);
- val2 = v2.doubleValue(j);
- diff = (val1 - val2);
- final double d12 = Math.sqrt(diff * diff);
-
- final double dist1 = d1 * d1;
- final double dist2 = d2 * d2;
- final double dist12 = d12 * d12;
-
- final double cost;
-
- if((i + j) != 0) {
- if((i == 0) || ((j != 0) && (((prev[j - 1] + dist12) > (curr[j - 1] + dist2)) && ((curr[j - 1] + dist2) < (prev[j] + dist1))))) {
- // del
- cost = curr[j - 1] + dist2;
- }
- else if((j == 0) || ((i != 0) && (((prev[j - 1] + dist12) > (prev[j] + dist1)) && ((prev[j] + dist1) < (curr[j - 1] + dist2))))) {
- // ins
- cost = prev[j] + dist1;
- }
- else {
- // match
- cost = prev[j - 1] + dist12;
- }
- }
- else {
- cost = 0;
- }
+ // TODO: support Euclidean, Manhattan here:
+ return Math.sqrt(buf[cur + dim2 - 1]);
+ }
- curr[j] = cost;
- // steps[i][j] = step;
- }
- else {
- curr[j] = Double.POSITIVE_INFINITY; // outside band
- }
- }
+ @Override
+ protected void firstRow(double[] buf, int band, NumberVector v1, NumberVector v2, int dim2) {
+ // First cell:
+ final double val1 = v1.doubleValue(0);
+ buf[0] = Math.min(delta(val1, g), delta(val1, v2.doubleValue(0)));
+
+ // Width of valid area:
+ final int w = (band >= dim2) ? dim2 - 1 : band;
+ // Fill remaining part of buffer:
+ for(int j = 1; j <= w; j++) {
+ buf[j] = Math.min(delta(val1, g), buf[j - 1]) + delta(val1, v2.doubleValue(j));
}
+ }
- return Math.sqrt(curr[v2.getDimensionality() - 1]);
+ @Override
+ protected double delta(double val1, double val2) {
+ double diff = val1 - val2;
+ return diff * diff;
}
@Override
@@ -164,13 +161,20 @@ public class ERPDistanceFunction extends AbstractEditDistanceFunction {
* @apiviz.exclude
*/
public static class Parameterizer extends AbstractEditDistanceFunction.Parameterizer {
- protected double g = 0.0;
+ /**
+ * G parameter
+ */
+ public static final OptionID G_ID = new OptionID("erp.g", "The g parameter of ERP - comparison value to use in gaps.");
+
+ /**
+ * Gap value.
+ */
+ protected double g = 0.;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final DoubleParameter gP = new DoubleParameter(G_ID, 0.0);
- gP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ final DoubleParameter gP = new DoubleParameter(G_ID, 0.);
if(config.grab(gP)) {
g = gP.doubleValue();
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/LCSSDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/LCSSDistanceFunction.java
index 4f1c0850..34e11993 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/LCSSDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/LCSSDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries;
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,12 +24,9 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.VectorUtil;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
-import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.data.type.VectorTypeInformation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -39,8 +36,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
- * Provides the Longest Common Subsequence distance for FeatureVectors.
- *
+ * Longest Common Subsequence distance for numerical vectors.
*
* Adapted for Java, based on Matlab Code by Michalis Vlachos. Original
* Copyright Notice:
@@ -74,18 +70,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
* @author Thomas Bernecker
*/
@Title("Longest Common Subsequence distance function")
-@Reference(authors = "M. Vlachos, M. Hadjieleftheriou, D. Gunopulos, E. Keogh", title = "Indexing Multi-Dimensional Time-Series with Support for Multiple Distance Measures", booktitle = "Proceedings of the ninth ACM SIGKDD international conference on Knowledge discovery and data mining", url = "http://dx.doi.org/10.1145/956750.956777")
-public class LCSSDistanceFunction extends AbstractVectorDoubleDistanceFunction {
- /**
- * PDELTA parameter
- */
- public static final OptionID PDELTA_ID = new OptionID("lcss.pDelta", "the allowed deviation in x direction for LCSS alignment (positive double value, 0 <= pDelta <= 1)");
-
- /**
- * PEPSILON parameter
- */
- public static final OptionID PEPSILON_ID = new OptionID("lcss.pEpsilon", "the allowed deviation in y directionfor LCSS alignment (positive double value, 0 <= pEpsilon <= 1)");
-
+@Reference(authors = "M. Vlachos, M. Hadjieleftheriou, D. Gunopulos, E. Keogh", //
+title = "Indexing Multi-Dimensional Time-Series with Support for Multiple Distance Measures", //
+booktitle = "Proceedings of the ninth ACM SIGKDD international conference on Knowledge discovery and data mining", //
+url = "http://dx.doi.org/10.1145/956750.956777")
+public class LCSSDistanceFunction extends AbstractNumberVectorDistanceFunction {
/**
* Keeps the currently set pDelta.
*/
@@ -108,95 +97,79 @@ public class LCSSDistanceFunction extends AbstractVectorDoubleDistanceFunction {
this.pEpsilon = pEpsilon;
}
- /**
- * Provides the Longest Common Subsequence distance between the given two
- * vectors.
- *
- * @return the Longest Common Subsequence distance between the given two
- * vectors as an instance of {@link DoubleDistance DoubleDistance}.
- */
@Override
- public double doubleDistance(NumberVector<?> v1, NumberVector<?> v2) {
- final int delta = (int) Math.ceil(v2.getDimensionality() * pDelta);
-
- DoubleMinMax extrema1 = VectorUtil.getRangeDouble(v1);
- DoubleMinMax extrema2 = VectorUtil.getRangeDouble(v2);
- double range = Math.max(extrema1.getMax(), extrema2.getMax()) - Math.min(extrema1.getMin(), extrema2.getMin());
- final double epsilon = range * pEpsilon;
-
- int m = -1;
- int n = -1;
- double[] a, b;
-
- // put shorter vector first
- if (v1.getDimensionality() < v2.getDimensionality()) {
- m = v1.getDimensionality();
- n = v2.getDimensionality();
- a = new double[m];
- b = new double[n];
-
- for (int i = 0; i < v1.getDimensionality(); i++) {
- a[i] = v1.doubleValue(i);
- }
- for (int j = 0; j < v2.getDimensionality(); j++) {
- b[j] = v2.doubleValue(j);
- }
- } else {
- m = v2.getDimensionality();
- n = v1.getDimensionality();
- a = new double[m];
- b = new double[n];
-
- for (int i = 0; i < v2.getDimensionality(); i++) {
- a[i] = v2.doubleValue(i);
- }
- for (int j = 0; j < v1.getDimensionality(); j++) {
- b[j] = v1.doubleValue(j);
- }
+ public double distance(NumberVector v1, NumberVector v2) {
+ final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality();
+ if(dim1 > dim2) {
+ return distance(v2, v1);
}
+ final int delta = (int) Math.ceil(dim2 * pDelta);
+
+ // Compute value range, for scaling epsilon:
+ final double epsilon = getRange(v1, dim1, v2, dim2) * pEpsilon;
- double[] curr = new double[n + 1];
+ double[] curr = new double[dim2 + 1];
+ double[] next = new double[dim2 + 1];
- for (int i = 0; i < m; i++) {
- double[] next = new double[n + 1];
- for (int j = Math.max(0, i - delta); j <= Math.min(n - 1, i + delta); j++) {
- if ((b[j] + epsilon) >= a[i] && (b[j] - epsilon) <= a[i]) { // match
+ for(int i = 0; i < dim1; i++) {
+ final double ai = v1.doubleValue(i);
+ for(int j = Math.max(0, i - delta); j <= Math.min(dim2 - 1, i + delta); j++) {
+ final double bj = v2.doubleValue(j);
+ if((bj + epsilon) >= ai && (bj - epsilon) <= ai) { // match
next[j + 1] = curr[j] + 1;
- } else if (curr[j + 1] > next[j]) { // ins
+ }
+ else if(curr[j + 1] > next[j]) { // ins
next[j + 1] = curr[j + 1];
- } else { // del
+ }
+ else { // del
next[j + 1] = next[j];
}
}
+ // Swap
+ double[] tmp = curr;
curr = next;
+ next = tmp;
}
// search for maximum in the last line
- double maxEntry = -1;
- for (int i = 1; i < n + 1; i++) {
- if (curr[i] > maxEntry) {
- maxEntry = curr[i];
- }
+ double maxEntry = curr[1];
+ for(int i = 2; i < dim2 + 1; i++) {
+ maxEntry = (curr[i] > maxEntry) ? curr[i] : maxEntry;
}
- double sim = maxEntry / Math.min(m, n);
- return 1 - sim;
+ final double sim = maxEntry / Math.min(dim1, dim2);
+ return 1. - sim;
+ }
+
+ public double getRange(NumberVector v1, final int dim1, NumberVector v2, final int dim2) {
+ double min = v1.doubleValue(0), max = min;
+ for(int i = 1; i < dim1; i++) {
+ final double v = v1.doubleValue(i);
+ min = (v < min) ? v : min;
+ max = (v > max) ? v : max;
+ }
+ for(int i = 0; i < dim2; i++) {
+ final double v = v2.doubleValue(i);
+ min = (v < min) ? v : min;
+ max = (v > max) ? v : max;
+ }
+ final double range = max - min;
+ return range;
}
- // TODO: relax this to VectorTypeInformation!
@Override
- public VectorFieldTypeInformation<? super NumberVector<?>> getInputTypeRestriction() {
- return TypeUtil.NUMBER_VECTOR_FIELD;
+ public VectorTypeInformation<? super NumberVector> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH;
}
@Override
public boolean equals(Object obj) {
- if (obj == this) {
+ if(obj == this) {
return true;
}
- if (obj == null) {
+ if(obj == null) {
return false;
}
- if (!this.getClass().equals(obj.getClass())) {
+ if(!this.getClass().equals(obj.getClass())) {
return false;
}
return (this.pDelta == ((LCSSDistanceFunction) obj).pDelta) && (this.pEpsilon == ((LCSSDistanceFunction) obj).pEpsilon);
@@ -210,24 +183,40 @@ public class LCSSDistanceFunction extends AbstractVectorDoubleDistanceFunction {
* @apiviz.exclude
*/
public static class Parameterizer extends AbstractParameterizer {
- protected double pDelta = 0.0;
-
- protected double pEpsilon = 0.0;
+ /**
+ * PDELTA parameter
+ */
+ public static final OptionID PDELTA_ID = new OptionID("lcss.pDelta", "the allowed deviation in x direction for LCSS alignment (positive double value, 0 <= pDelta <= 1)");
+
+ /**
+ * PEPSILON parameter
+ */
+ public static final OptionID PEPSILON_ID = new OptionID("lcss.pEpsilon", "the allowed deviation in y direction for LCSS alignment (positive double value, 0 <= pEpsilon <= 1)");
+
+ /**
+ * Keeps the currently set pDelta.
+ */
+ private double pDelta;
+
+ /**
+ * Keeps the currently set pEpsilon.
+ */
+ private double pEpsilon;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final DoubleParameter pDeltaP = new DoubleParameter(PDELTA_ID, 0.1);
- pDeltaP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
- pDeltaP.addConstraint(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
- if (config.grab(pDeltaP)) {
+ final DoubleParameter pDeltaP = new DoubleParameter(PDELTA_ID, 0.1)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE)//
+ .addConstraint(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
+ if(config.grab(pDeltaP)) {
pDelta = pDeltaP.doubleValue();
}
- final DoubleParameter pEpsilonP = new DoubleParameter(PEPSILON_ID, 0.05);
- pEpsilonP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
- pEpsilonP.addConstraint(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
- if (config.grab(pEpsilonP)) {
+ final DoubleParameter pEpsilonP = new DoubleParameter(PEPSILON_ID, 0.05)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE) //
+ .addConstraint(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
+ if(config.grab(pEpsilonP)) {
pEpsilon = pEpsilonP.doubleValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/package-info.java
index 4edbe89f..0d7fcebf 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/timeseries/package-info.java
@@ -8,7 +8,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
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DistanceDBIDResultUtil.java b/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DistanceDBIDResultUtil.java
deleted file mode 100644
index d1564fd8..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/DistanceDBIDResultUtil.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distanceresultlist;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-
-/**
- * Utility classes for distance DBID results.
- *
- * @author Erich Schubert
- *
- * @apiviz.uses DistanceDBIDPair oneway - -
- */
-public final class DistanceDBIDResultUtil {
- /**
- * Get a comparator to sort by distance, then DBID
- *
- * @return comparator
- */
- @SuppressWarnings("unchecked")
- public static <D extends DistanceDBIDPair<?>> Comparator<? super D> distanceComparator() {
- return (Comparator<D>) BY_DISTANCE_THEN_DBID;
- }
-
- /**
- * Sort a Java list by distance.
- *
- * @param list List to sort
- */
- @SuppressWarnings("unchecked")
- public static <D extends DistanceDBIDPair<?>> void sortByDistance(List<? extends D> list) {
- Collections.sort(list, (Comparator<D>) BY_DISTANCE_THEN_DBID);
- }
-
- /**
- * Static comparator.
- */
- private static final Comparator<DistanceDBIDPair<?>> BY_DISTANCE_THEN_DBID = new Comparator<DistanceDBIDPair<?>>() {
- @SuppressWarnings("unchecked")
- @Override
- public int compare(DistanceDBIDPair<?> o1, DistanceDBIDPair<?> o2) {
- final int d = ((DistanceDBIDPair<DoubleDistance>)o1).compareByDistance((DistanceDBIDPair<DoubleDistance>)o2);
- return (d == 0) ? DBIDUtil.compare(o1, o2) : d;
- }
- };
-
- /**
- * Static comparator for heaps.
- */
- public static final Comparator<DistanceDBIDPair<?>> BY_REVERSE_DISTANCE = new Comparator<DistanceDBIDPair<?>>() {
- @SuppressWarnings("unchecked")
- @Override
- public int compare(DistanceDBIDPair<?> o1, DistanceDBIDPair<?> o2) {
- return -((DistanceDBIDPair<DoubleDistance>)o1).compareByDistance((DistanceDBIDPair<DoubleDistance>)o2);
- }
- };
-
- public static String toString(DistanceDBIDList<?> res) {
- StringBuilder buf = new StringBuilder();
- buf.append('[');
- DistanceDBIDListIter<?> iter = res.iter();
- for(; iter.valid(); iter.advance()) {
- if(buf.length() > 1) {
- buf.append(',').append(' ');
- }
- buf.append(iter.getDistancePair().toString());
- }
- buf.append(']');
- return buf.toString();
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/AbstractDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/AbstractDistance.java
deleted file mode 100644
index c0573ae5..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/AbstractDistance.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancevalue;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.util.regex.Pattern;
-
-/**
- * An abstract distance implements equals conveniently for any extending class.
- * At the same time any extending class is to implement hashCode properly.
- *
- * See {@link de.lmu.ifi.dbs.elki.distance.DistanceUtil} for related utility
- * functions such as <code>min</code>, <code>max</code>.
- *
- * @author Arthur Zimek
- * @see de.lmu.ifi.dbs.elki.distance.DistanceUtil
- * @param <D> the (final) type of Distance used
- */
-public abstract class AbstractDistance<D extends AbstractDistance<D>> implements Distance<D> {
- /**
- * Indicates an infinity pattern.
- */
- public static final String INFINITY_PATTERN = "inf";
-
- /**
- * Pattern for parsing and validating double values
- */
- public static final Pattern DOUBLE_PATTERN = Pattern.compile("(\\d+|\\d*\\.\\d+)?([eE][-]?\\d+)?");
-
- /**
- * Pattern for parsing and validating integer values
- */
- public static final Pattern INTEGER_PATTERN = Pattern.compile("\\d+");
-
- /**
- * Any extending class should implement a proper hashCode method.
- */
- @Override
- public abstract int hashCode();
-
- /**
- * Returns true if <code>this == o</code> has the value <code>true</code> or o
- * is not null and o is of the same class as this instance and
- * <code>this.compareTo(o)</code> is 0, false otherwise.
- */
- @SuppressWarnings("unchecked")
- @Override
- public boolean equals(Object o) {
- if(this == o) {
- return true;
- }
-
- if(o == null || getClass() != o.getClass()) {
- return false;
- }
-
- return this.compareTo((D) o) == 0;
- }
-
- /**
- * Get the pattern accepted by this distance
- *
- * @return Pattern
- */
- abstract public Pattern getPattern();
-
- @Override
- public final String requiredInputPattern() {
- return getPattern().pattern();
- }
-
- /**
- * Test a string value against the input pattern.
- *
- * @param value String value to test
- * @return Match result
- */
- public final boolean testInputPattern(String value) {
- return getPattern().matcher(value).matches();
- }
-
- @Override
- public boolean isInfiniteDistance() {
- return this.equals(infiniteDistance());
- }
-
- @Override
- public boolean isNullDistance() {
- return this.equals(nullDistance());
- }
-
- @Override
- public boolean isUndefinedDistance() {
- return this.equals(undefinedDistance());
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/BitDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/BitDistance.java
deleted file mode 100644
index 7c257bb5..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/BitDistance.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancevalue;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import de.lmu.ifi.dbs.elki.data.Bit;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.regex.Pattern;
-
-/**
- * Provides a Distance for a bit-valued distance.
- *
- * @author Arthur Zimek
- */
-public class BitDistance extends NumberDistance<BitDistance, Bit> {
- /**
- * The static factory instance
- */
- public static final BitDistance FACTORY = new BitDistance();
-
- /**
- * The distance value
- */
- private boolean value;
-
- /**
- * Distance 0.
- */
- public static final BitDistance ZERO = new BitDistance(false);
-
- /**
- * Distance 1.
- */
- public static final BitDistance ONE = new BitDistance(true);
-
- /**
- * Generated serial version UID
- */
- private static final long serialVersionUID = 6514853467081717551L;
-
- /**
- * Empty constructor for serialization purposes.
- */
- public BitDistance() {
- super();
- }
-
- /**
- * Constructs a new BitDistance object that represents the bit argument.
- *
- * @param bit the value to be represented by the BitDistance.
- */
- public BitDistance(boolean bit) {
- super();
- this.value = bit;
- }
-
- /**
- * Constructs a new BitDistance object that represents the bit argument.
- *
- * @param bit the value to be represented by the BitDistance.
- */
- public BitDistance(Bit bit) {
- super();
- this.value = bit.bitValue();
- }
-
- @Override
- public BitDistance fromDouble(double val) {
- return (val > 0) ? ONE : ZERO;
- }
-
- /**
- * Returns the value of this BitDistance as a boolean.
- *
- * @return the value as a boolean
- */
- public boolean bitValue() {
- return this.value;
- }
-
- /**
- * Writes the bit value of this BitDistance to the specified stream.
- */
- @Override
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeBoolean(value);
- }
-
- /**
- * Reads the bit value of this BitDistance from the specified stream.
- */
- @Override
- public void readExternal(ObjectInput in) throws IOException {
- value = in.readBoolean();
- }
-
- /**
- * Returns the number of Bytes this distance uses if it is written to an
- * external file.
- *
- * @return 1 (1 Byte for a boolean value)
- */
- @Override
- public int externalizableSize() {
- return 1;
- }
-
- @Override
- public double doubleValue() {
- return value ? 1. : 0.;
- }
-
- @Override
- public long longValue() {
- return value ? 1 : 0;
- }
-
- @Override
- public int intValue() {
- return value ? 1 : 0;
- }
-
- @Override
- public int compareTo(BitDistance other) {
- return this.intValue() - other.intValue();
- }
-
- @Override
- public BitDistance parseString(String val) throws IllegalArgumentException {
- int i = Integer.parseInt(val);
- if(i == 0) {
- return ZERO;
- }
- if(i == 1) {
- return ONE;
- }
- throw new IllegalArgumentException("Given pattern \"" + val + "\" does not match required pattern \"" + requiredInputPattern() + "\"");
- }
-
- @Override
- public BitDistance infiniteDistance() {
- return ONE;
- }
-
- @Override
- public BitDistance nullDistance() {
- return ZERO;
- }
-
- @Override
- public BitDistance undefinedDistance() {
- throw new UnsupportedOperationException(ExceptionMessages.UNSUPPORTED_UNDEFINED_DISTANCE);
- }
-
- @Override
- public Pattern getPattern() {
- return Bit.BIT_PATTERN;
- }
-
- @Override
- public boolean isInfiniteDistance() {
- return false;
- }
-
- @Override
- public boolean isNullDistance() {
- return !value;
- }
-
- @Override
- public boolean isUndefinedDistance() {
- return false;
- }
-
- @Override
- public String toString() {
- return Boolean.toString(value);
- }
-
- @Override
- public int hashCode() {
- return (value ? 1231 : 1237);
- }
-
- @Override
- public boolean equals(Object obj) {
- if(this == obj) {
- return true;
- }
- if(!super.equals(obj)) {
- return false;
- }
- if(getClass() != obj.getClass()) {
- return false;
- }
- BitDistance other = (BitDistance) obj;
- return (value == other.value);
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/CorrelationDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/CorrelationDistance.java
deleted file mode 100644
index fc288809..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/CorrelationDistance.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancevalue;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.regex.Pattern;
-
-/**
- * The correlation distance is a special Distance that indicates the
- * dissimilarity between correlation connected objects. The correlation distance
- * between two points is a pair consisting of the correlation dimension of two
- * points and the euclidean distance between the two points.
- *
- * @author Elke Achtert
- * @param <D> distance type
- */
-public abstract class CorrelationDistance<D extends CorrelationDistance<D>> extends AbstractDistance<D> {
- /**
- * The component separator used by correlation distances.
- *
- * Note: Do NOT use regular expression syntax characters!
- */
- public static final String SEPARATOR = "x";
-
- /**
- * The pattern used for correlation distances
- */
- public static final Pattern CORRELATION_DISTANCE_PATTERN = Pattern.compile("\\d+" + Pattern.quote(SEPARATOR) + "\\d+(\\.\\d+)?([eE][-]?\\d+)?");
-
- /**
- * Generated SerialVersionUID.
- */
- private static final long serialVersionUID = 2829135841596857929L;
-
- /**
- * The correlation dimension.
- */
- protected int correlationValue;
-
- /**
- * The euclidean distance.
- */
- protected double euclideanValue;
-
- /**
- * Empty constructor for serialization purposes.
- */
- public CorrelationDistance() {
- // for serialization
- }
-
- /**
- * Constructs a new CorrelationDistance object consisting of the specified
- * correlation value and euclidean value.
- *
- * @param correlationValue the correlation dimension to be represented by the
- * CorrelationDistance
- * @param euclideanValue the euclidean distance to be represented by the
- * CorrelationDistance
- */
- public CorrelationDistance(int correlationValue, double euclideanValue) {
- this.correlationValue = correlationValue;
- this.euclideanValue = euclideanValue;
- }
-
- /**
- * Returns a string representation of this CorrelationDistance.
- *
- * @return the correlation value and the euclidean value separated by blank
- */
- @Override
- public String toString() {
- return Integer.toString(correlationValue) + SEPARATOR + Double.toString(euclideanValue);
- }
-
- /**
- * Compares this CorrelationDistance with the given CorrelationDistance wrt
- * the represented correlation values. If both values are considered to be
- * equal, the euclidean values are compared. Subclasses may need to overwrite
- * this method if necessary.
- *
- * @return the value of {@link Integer#compareTo(Integer)}
- * this.correlationValue.compareTo(other.correlationValue)} if it is a
- * non zero value, the value of {@link Double#compare(double,double)
- * Double.compare(this.euclideanValue, other.euclideanValue)}
- * otherwise
- */
- @Override
- public int compareTo(D other) {
- int compare = (this.correlationValue < other.getCorrelationValue()) ? -1 : (this.correlationValue > other.getCorrelationValue()) ? +1 : 0;
- if (compare != 0) {
- return compare;
- } else {
- return Double.compare(this.euclideanValue, other.getEuclideanValue());
- }
- }
-
- @Override
- public int hashCode() {
- int result;
- long temp;
- result = correlationValue;
- temp = euclideanValue >= Double.MIN_NORMAL ? Double.doubleToLongBits(euclideanValue) : 0L;
- result = 29 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final CorrelationDistance<D> other = (CorrelationDistance<D>) obj;
- if (this.correlationValue != other.correlationValue) {
- return false;
- }
- if (this.euclideanValue != other.euclideanValue) {
- return false;
- }
- return true;
- }
-
- /**
- * Returns the correlation dimension between the objects.
- *
- * @return the correlation dimension
- */
- public int getCorrelationValue() {
- return correlationValue;
- }
-
- /**
- * Returns the euclidean distance between the objects.
- *
- * @return the euclidean distance
- */
- public double getEuclideanValue() {
- return euclideanValue;
- }
-
- /**
- * Writes the correlation value and the euclidean value of this
- * CorrelationDistance to the specified stream.
- */
- @Override
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeInt(correlationValue);
- out.writeDouble(euclideanValue);
- }
-
- /**
- * Reads the correlation value and the euclidean value of this
- * CorrelationDistance from the specified stream.
- */
- @Override
- public void readExternal(ObjectInput in) throws IOException {
- correlationValue = in.readInt();
- euclideanValue = in.readDouble();
- }
-
- /**
- * Returns the number of Bytes this distance uses if it is written to an
- * external file.
- *
- * @return 12 (4 Byte for an integer, 8 Byte for a double value)
- */
- @Override
- public int externalizableSize() {
- return 12;
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/Distance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/Distance.java
deleted file mode 100644
index 40dff25d..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/Distance.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancevalue;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.Externalizable;
-
-/**
- * The interface Distance defines the requirements of any instance class.
- *
- * See {@link de.lmu.ifi.dbs.elki.distance.DistanceUtil} for related utility
- * functions such as <code>min</code>, <code>max</code>.
- *
- * @author Arthur Zimek
- *
- * @see de.lmu.ifi.dbs.elki.distance.DistanceUtil
- *
- * @apiviz.landmark
- *
- * @param <D> the type of Distance used
- */
-public interface Distance<D extends Distance<D>> extends Comparable<D>, Externalizable {
- /**
- * Any implementing class should implement a proper toString-method for
- * printing the result-values.
- *
- * @return String a human-readable representation of the Distance
- */
- @Override
- String toString();
-
- /**
- * Provides a measurement suitable to this measurement function based on the
- * given pattern.
- *
- * @param pattern a pattern defining a similarity suitable to this measurement
- * function
- * @return a measurement suitable to this measurement function based on the
- * given pattern
- * @throws IllegalArgumentException if the given pattern is not compatible
- * with the requirements of this measurement function
- */
- D parseString(String pattern) throws IllegalArgumentException;
-
- /**
- * Returns a String as description of the required input format.
- *
- * @return a String as description of the required input format
- */
- String requiredInputPattern();
-
- /**
- * Returns the number of Bytes this distance uses if it is written to an
- * external file.
- *
- * @return the number of Bytes this distance uses if it is written to an
- * external file
- */
- int externalizableSize();
-
- /**
- * Provides an infinite distance.
- *
- * @return an infinite distance
- */
- D infiniteDistance();
-
- /**
- * Provides a null distance.
- *
- * @return a null distance
- */
- D nullDistance();
-
- /**
- * Provides an undefined distance.
- *
- * @return an undefined distance
- */
- D undefinedDistance();
-
- /**
- * Returns true, if the distance is an infinite distance, false otherwise.
- *
- * @return true, if the distance is an infinite distance, false otherwise
- */
- boolean isInfiniteDistance();
-
- /**
- * Returns true, if the distance is a null distance, false otherwise.
- *
- * @return true, if the distance is a null distance, false otherwise
- */
- boolean isNullDistance();
-
- /**
- * Returns true, if the distance is an undefined distance, false otherwise.
- *
- * @return true, if the distance is an undefined distance, false otherwise
- */
- boolean isUndefinedDistance();
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/DoubleDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/DoubleDistance.java
deleted file mode 100644
index c49ba6a3..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/DoubleDistance.java
+++ /dev/null
@@ -1,221 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancevalue;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.regex.Pattern;
-
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-
-/**
- * Provides a Distance for a double-valued distance.
- *
- * @author Elke Achtert
- */
-public class DoubleDistance extends NumberDistance<DoubleDistance, Double> {
- /**
- * Zero distance constant
- */
- public static final DoubleDistance ZERO_DISTANCE = new DoubleDistance(0.0);
-
- /**
- * Infinite distance constant
- */
- public static final DoubleDistance INFINITE_DISTANCE = new DoubleDistance(Double.POSITIVE_INFINITY);
-
- /**
- * Undefined distance constant
- */
- public static final DoubleDistance UNDEFINED_DISTANCE = new DoubleDistance(Double.NaN);
-
- /**
- * The static factory instance
- */
- public static final DoubleDistance FACTORY = UNDEFINED_DISTANCE;
-
- /**
- * The actual value.
- */
- double value;
-
- /**
- * Generated serialVersionUID.
- */
- private static final long serialVersionUID = 3711413449321214862L;
-
- /**
- * Empty constructor for serialization purposes.
- */
- public DoubleDistance() {
- super();
- }
-
- /**
- * Constructs a new DoubleDistance object that represents the double argument.
- *
- * @param value the value to be represented by the DoubleDistance.
- */
- public DoubleDistance(double value) {
- super();
- this.value = value;
- }
-
- @Override
- public DoubleDistance fromDouble(double val) {
- return new DoubleDistance(val);
- }
-
- /**
- * Writes the double value of this DoubleDistance to the specified stream.
- */
- @Override
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeDouble(this.value);
- }
-
- /**
- * Reads the double value of this DoubleDistance from the specified stream.
- */
- @Override
- public void readExternal(ObjectInput in) throws IOException {
- this.value = in.readDouble();
- }
-
- /**
- * Returns the number of Bytes this distance uses if it is written to an
- * external file.
- *
- * @return 8 (8 Byte for a double value)
- */
- @Override
- public int externalizableSize() {
- return 8;
- }
-
- @Override
- public double doubleValue() {
- return value;
- }
-
- @Override
- public long longValue() {
- return (long) value;
- }
-
- @Override
- public int compareTo(DoubleDistance other) {
- return Double.compare(this.value, other.value);
- }
-
- /**
- * An infinite DoubleDistance is based on {@link Double#POSITIVE_INFINITY
- * Double.POSITIVE_INFINITY}.
- */
- @Override
- public DoubleDistance infiniteDistance() {
- return INFINITE_DISTANCE;
- }
-
- /**
- * A null DoubleDistance is based on 0.
- */
- @Override
- public DoubleDistance nullDistance() {
- return ZERO_DISTANCE;
- }
-
- /**
- * An undefined DoubleDistance is based on {@link Double#NaN Double.NaN}.
- */
- @Override
- public DoubleDistance undefinedDistance() {
- return UNDEFINED_DISTANCE;
- }
-
- /**
- * As pattern is required a String defining a Double.
- */
- @Override
- public DoubleDistance parseString(String val) throws IllegalArgumentException {
- if (val.equals(INFINITY_PATTERN)) {
- return infiniteDistance();
- }
- if (testInputPattern(val)) {
- return new DoubleDistance(FormatUtil.parseDouble(val));
- } else {
- throw new IllegalArgumentException("Given pattern \"" + val + "\" does not match required pattern \"" + requiredInputPattern() + "\"");
- }
- }
-
- @Override
- public boolean isInfiniteDistance() {
- return Double.isInfinite(value);
- }
-
- @Override
- public boolean isNullDistance() {
- return (value <= 0.0);
- }
-
- @Override
- public boolean isUndefinedDistance() {
- return Double.isNaN(value);
- }
-
- @Override
- public Pattern getPattern() {
- return DOUBLE_PATTERN;
- }
-
- @Override
- public String toString() {
- return FormatUtil.NF.format(value);
- }
-
- @Override
- public int hashCode() {
- final long bits = Double.doubleToLongBits(value);
- return (int) (bits ^ (bits >>> 32));
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- DoubleDistance other = (DoubleDistance) obj;
- if (Double.doubleToLongBits(value) != Double.doubleToLongBits(other.value)) {
- return false;
- }
- return true;
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/FloatDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/FloatDistance.java
deleted file mode 100644
index f72d5c1b..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/FloatDistance.java
+++ /dev/null
@@ -1,226 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancevalue;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.regex.Pattern;
-
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-
-/**
- * Provides a Distance for a float-valued distance.
- *
- * @author Elke Achtert
- */
-public class FloatDistance extends NumberDistance<FloatDistance, Float> {
- /**
- * The static factory instance
- */
- public static final FloatDistance FACTORY = new FloatDistance();
-
- /**
- * The distance value.
- */
- private float value;
-
- /**
- * Generated serialVersionUID.
- */
- private static final long serialVersionUID = -5702250266358369075L;
-
- /**
- * Infinite distance.
- */
- public static final FloatDistance INFINITE_DISTANCE = new FloatDistance(Float.POSITIVE_INFINITY);
-
- /**
- * Zero distance.
- */
- public static final FloatDistance ZERO_DISTANCE = new FloatDistance(0.0F);
-
- /**
- * Undefined distance.
- */
- public static final FloatDistance UNDEFINED_DISTANCE = new FloatDistance(Float.NaN);
-
- /**
- * Empty constructor for serialization purposes.
- */
- public FloatDistance() {
- super();
- }
-
- /**
- * Constructs a new FloatDistance object that represents the float argument.
- *
- * @param value the value to be represented by the FloatDistance.
- */
- public FloatDistance(float value) {
- super();
- this.value = value;
- }
-
- @Override
- public FloatDistance fromDouble(double val) {
- return new FloatDistance((float) val);
- }
-
- /**
- * Writes the float value of this FloatDistance to the specified stream.
- */
- @Override
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeFloat(value);
- }
-
- /**
- * Reads the float value of this FloatDistance from the specified stream.
- */
- @Override
- public void readExternal(ObjectInput in) throws IOException {
- value = in.readFloat();
- }
-
- /**
- * Returns the number of Bytes this distance uses if it is written to an
- * external file.
- *
- * @return 4 (4 Byte for a float value)
- */
- @Override
- public int externalizableSize() {
- return 4;
- }
-
- @Override
- public double doubleValue() {
- return value;
- }
-
- @Override
- public float floatValue() {
- return value;
- }
-
- @Override
- public long longValue() {
- return (long) value;
- }
-
- @Override
- public int compareTo(FloatDistance other) {
- return Float.compare(this.value, other.value);
- }
-
- /**
- * An infinite FloatDistance is based on {@link Float#POSITIVE_INFINITY
- * Float.POSITIVE_INFINITY}.
- */
- @Override
- public FloatDistance infiniteDistance() {
- return INFINITE_DISTANCE;
- }
-
- /**
- * A null FloatDistance is based on 0.
- */
- @Override
- public FloatDistance nullDistance() {
- return ZERO_DISTANCE;
- }
-
- /**
- * An undefined FloatDistance is based on {@link Float#NaN Float.NaN}.
- */
- @Override
- public FloatDistance undefinedDistance() {
- return UNDEFINED_DISTANCE;
- }
-
- /**
- * As pattern is required a String defining a Float.
- */
- @Override
- public FloatDistance parseString(String val) throws IllegalArgumentException {
- if (val.equals(INFINITY_PATTERN)) {
- return infiniteDistance();
- }
-
- if (DoubleDistance.DOUBLE_PATTERN.matcher(val).matches()) {
- return new FloatDistance(Float.parseFloat(val));
- } else {
- throw new IllegalArgumentException("Given pattern \"" + val + "\" does not match required pattern \"" + requiredInputPattern() + "\"");
- }
- }
-
- @Override
- public boolean isInfiniteDistance() {
- return Float.isInfinite(value);
- }
-
- @Override
- public boolean isNullDistance() {
- return (value <= 0.0);
- }
-
- @Override
- public boolean isUndefinedDistance() {
- return Float.isNaN(value);
- }
-
- @Override
- public Pattern getPattern() {
- return DOUBLE_PATTERN;
- }
-
- @Override
- public String toString() {
- return FormatUtil.NF.format(value);
- }
-
- @Override
- public int hashCode() {
- return Float.floatToIntBits(value);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- FloatDistance other = (FloatDistance) obj;
- if (Float.floatToIntBits(value) != Float.floatToIntBits(other.value)) {
- return false;
- }
- return true;
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/IntegerDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/IntegerDistance.java
deleted file mode 100644
index 0e206f88..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/IntegerDistance.java
+++ /dev/null
@@ -1,194 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancevalue;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.regex.Pattern;
-
-import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
-
-/**
- * Provides an integer distance value.
- *
- * @author Arthur Zimek
- */
-public class IntegerDistance extends NumberDistance<IntegerDistance, Integer> {
- /**
- * The static factory instance
- */
- public static final IntegerDistance FACTORY = new IntegerDistance();
-
- /**
- * The distance value
- */
- int value;
-
- /**
- * Created serial version UID.
- */
- private static final long serialVersionUID = 5583821082931825810L;
-
- /**
- * Empty constructor for serialization purposes.
- */
- public IntegerDistance() {
- super();
- }
-
- /**
- * Constructor
- *
- * @param value distance value
- */
- public IntegerDistance(int value) {
- super();
- this.value = value;
- }
-
- @Override
- public IntegerDistance fromDouble(double val) {
- return new IntegerDistance((int) val);
- }
-
- /**
- * Writes the integer value of this IntegerDistance to the specified stream.
- */
- @Override
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeInt(value);
- }
-
- /**
- * Reads the integer value of this IntegerDistance from the specified stream.
- */
- @Override
- public void readExternal(ObjectInput in) throws IOException {
- value = in.readInt();
- }
-
- /**
- * Returns the number of Bytes this distance uses if it is written to an
- * external file.
- *
- * @return 4 (4 Byte for an integer value)
- */
- @Override
- public int externalizableSize() {
- return 4;
- }
-
- @Override
- public double doubleValue() {
- return value;
- }
-
- @Override
- public long longValue() {
- return value;
- }
-
- @Override
- public int intValue() {
- return value;
- }
-
- @Override
- public int compareTo(IntegerDistance other) {
- return (this.value < other.value ? -1 : (this.value == other.value ? 0 : 1));
- }
-
- @Override
- public IntegerDistance nullDistance() {
- return new IntegerDistance(0);
- }
-
- @Override
- public IntegerDistance undefinedDistance() {
- throw new UnsupportedOperationException(ExceptionMessages.UNSUPPORTED_UNDEFINED_DISTANCE);
- }
-
- @Override
- public IntegerDistance infiniteDistance() {
- return new IntegerDistance(Integer.MAX_VALUE);
- }
-
- @Override
- public boolean isInfiniteDistance() {
- return value == Integer.MAX_VALUE;
- }
-
- @Override
- public boolean isNullDistance() {
- return value == 0;
- }
-
- @Override
- public boolean isUndefinedDistance() {
- return false;
- }
-
- @Override
- public IntegerDistance parseString(String val) throws IllegalArgumentException {
- if (testInputPattern(val)) {
- return new IntegerDistance(Integer.parseInt(val));
- } else {
- throw new IllegalArgumentException("Given pattern \"" + val + "\" does not match required pattern \"" + requiredInputPattern() + "\"");
- }
- }
-
- @Override
- public String toString() {
- return Integer.toString(value);
- }
-
- @Override
- public int hashCode() {
- return value;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- IntegerDistance other = (IntegerDistance) obj;
- if (value != other.value) {
- return false;
- }
- return true;
- }
-
- @Override
- public Pattern getPattern() {
- return INTEGER_PATTERN;
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/NumberDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/NumberDistance.java
deleted file mode 100644
index 92d2f4ec..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/NumberDistance.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancevalue;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * Provides a Distance for a number-valued distance.
- *
- * @author Elke Achtert
- *
- * @apiviz.landmark
- * @apiviz.composedOf Number
- *
- * @param <D> the (final) type of NumberDistance used
- * @param <N> the type of Number used (e.g. Double, Integer, Float, etc.)
- */
-public abstract class NumberDistance<D extends NumberDistance<D, N>, N extends Number> extends AbstractDistance<D> {
- /**
- * Constructs a new NumberDistance object that represents the value argument.
- */
- public NumberDistance() {
- super();
- }
-
- /**
- * Build a new instance from a double value.
- *
- * @param val Value
- * @return Distance
- */
- public abstract D fromDouble(double val);
-
- /**
- * Get the value as double.
- *
- * @return same result as getValue().doubleValue() but may be more efficient.
- */
- public abstract double doubleValue();
-
- /**
- * Get the value as float.
- *
- * @return same result as getValue().floatValue() but may be more efficient.
- */
- public float floatValue() {
- return (float) doubleValue();
- }
-
- /**
- * Get the value as int.
- *
- * @return same result as getValue().intValue() but may be more efficient.
- */
- public int intValue() {
- return (int) longValue();
- }
-
- /**
- * Get the value as long.
- *
- * @return same result as getValue().longValue() but may be more efficient.
- */
- public abstract long longValue();
-
- /**
- * Get the value as short.
- *
- * @return same result as getValue().shortValue() but may be more efficient.
- */
- public short shortValue() {
- return (short) longValue();
- }
-
- /**
- * Get the value as byte.
- *
- * @return same result as getValue().byteValue() but may be more efficient.
- */
- public byte byteValue() {
- return (byte) longValue();
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/PCACorrelationDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/PCACorrelationDistance.java
deleted file mode 100644
index 30026285..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/PCACorrelationDistance.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancevalue;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.util.regex.Pattern;
-
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-
-
-/**
- * The correlation distance is a special Distance that indicates the
- * dissimilarity between correlation connected objects. The correlation distance
- * between two points is a pair consisting of the correlation dimension of two
- * points and the euclidean distance between the two points.
- *
- * @author Elke Achtert
- */
-public class PCACorrelationDistance extends CorrelationDistance<PCACorrelationDistance> {
- /**
- * The static factory instance
- */
- public static final PCACorrelationDistance FACTORY = new PCACorrelationDistance();
-
- /**
- * Serial
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Empty constructor for serialization purposes.
- */
- public PCACorrelationDistance() {
- // for serialization
- }
-
- /**
- * Constructs a new CorrelationDistance object consisting of the specified
- * correlation value and euclidean value.
- *
- * @param correlationValue the correlation dimension to be represented by the
- * CorrelationDistance
- * @param euclideanValue the euclidean distance to be represented by the
- * CorrelationDistance
- */
- public PCACorrelationDistance(int correlationValue, double euclideanValue) {
- super(correlationValue, euclideanValue);
- }
-
- /**
- * Provides a distance suitable to this DistanceFunction based on the given
- * pattern.
- *
- * @param val A pattern defining a distance suitable to this
- * DistanceFunction
- * @return a distance suitable to this DistanceFunction based on the given
- * pattern
- * @throws IllegalArgumentException if the given pattern is not compatible
- * with the requirements of this DistanceFunction
- */
- @Override
- public PCACorrelationDistance parseString(String val) throws IllegalArgumentException {
- if(val.equals(INFINITY_PATTERN)) {
- return infiniteDistance();
- }
- if(testInputPattern(val)) {
- String[] values = SEPARATOR.split(val);
- return new PCACorrelationDistance(Integer.parseInt(values[0]), FormatUtil.parseDouble(values[1]));
- }
- else {
- throw new IllegalArgumentException("Given pattern \"" + val + "\" does not match required pattern \"" + requiredInputPattern() + "\"");
- }
- }
-
- @Override
- public Pattern getPattern() {
- return CORRELATION_DISTANCE_PATTERN;
- }
-
- /**
- * Provides an infinite distance.
- *
- * @return an infinite distance
- */
- @Override
- public PCACorrelationDistance infiniteDistance() {
- return new PCACorrelationDistance(Integer.MAX_VALUE, Double.POSITIVE_INFINITY);
- }
-
- /**
- * Provides a null distance.
- *
- * @return a null distance
- */
- @Override
- public PCACorrelationDistance nullDistance() {
- return new PCACorrelationDistance(0, 0.0);
- }
-
- /**
- * Provides an undefined distance.
- *
- * @return an undefined distance
- */
- @Override
- public PCACorrelationDistance undefinedDistance() {
- return new PCACorrelationDistance(-1, Double.NaN);
- }
-
- @Override
- public boolean isInfiniteDistance() {
- return correlationValue == Integer.MAX_VALUE || euclideanValue == Double.POSITIVE_INFINITY;
- }
-
- @Override
- public boolean isNullDistance() {
- return correlationValue == 0 || euclideanValue == 0.0;
- }
-
- @Override
- public boolean isUndefinedDistance() {
- return correlationValue == -1 && Double.isNaN(euclideanValue);
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/PreferenceVectorBasedCorrelationDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/PreferenceVectorBasedCorrelationDistance.java
deleted file mode 100644
index cc15eb24..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/PreferenceVectorBasedCorrelationDistance.java
+++ /dev/null
@@ -1,207 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancevalue;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.BitSet;
-import java.util.regex.Pattern;
-
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-
-/**
- * A PreferenceVectorBasedCorrelationDistance holds additionally to the
- * CorrelationDistance the common preference vector of the two objects defining
- * the distance.
- *
- * @author Elke Achtert
- */
-public class PreferenceVectorBasedCorrelationDistance extends CorrelationDistance<PreferenceVectorBasedCorrelationDistance> {
- /**
- * The static factory instance
- */
- public static final PreferenceVectorBasedCorrelationDistance FACTORY = new PreferenceVectorBasedCorrelationDistance();
-
- /**
- * Serial version
- */
- private static final long serialVersionUID = 1;
-
- /**
- * The dimensionality of the feature space (needed for serialization).
- */
- private int dimensionality;
-
- /**
- * The common preference vector of the two objects defining this distance.
- */
- private BitSet commonPreferenceVector;
-
- /**
- * Empty constructor for serialization purposes.
- */
- public PreferenceVectorBasedCorrelationDistance() {
- super();
- }
-
- /**
- * Constructs a new CorrelationDistance object.
- *
- * @param dimensionality the dimensionality of the feature space (needed for
- * serialization)
- * @param correlationValue the correlation dimension to be represented by the
- * CorrelationDistance
- * @param euclideanValue the euclidean distance to be represented by the
- * CorrelationDistance
- * @param commonPreferenceVector the common preference vector of the two
- * objects defining this distance
- */
- public PreferenceVectorBasedCorrelationDistance(int dimensionality, int correlationValue, double euclideanValue, BitSet commonPreferenceVector) {
- super(correlationValue, euclideanValue);
- this.dimensionality = dimensionality;
- this.commonPreferenceVector = commonPreferenceVector;
- }
-
- /**
- * Returns the common preference vector of the two objects defining this
- * distance.
- *
- * @return the common preference vector
- */
- public BitSet getCommonPreferenceVector() {
- return commonPreferenceVector;
- }
-
- /**
- * Returns a string representation of this
- * PreferenceVectorBasedCorrelationDistance.
- *
- * @return the correlation value, the euclidean value and the common
- * preference vector separated by blanks
- */
- @Override
- public String toString() {
- return super.toString() + SEPARATOR + commonPreferenceVector.toString();
- }
-
- /**
- * Checks if the dimensionality values of this distance and the specified
- * distance are equal. If the check fails an IllegalArgumentException is
- * thrown, otherwise
- * {@link CorrelationDistance#compareTo(CorrelationDistance)
- * CorrelationDistance#compareTo(distance)} is returned.
- *
- * @return the value of
- * {@link CorrelationDistance#compareTo(CorrelationDistance)
- * CorrelationDistance#compareTo(distance)}
- * @throws IllegalArgumentException if the dimensionality values of this
- * distance and the specified distance are not equal
- */
- @Override
- public int compareTo(PreferenceVectorBasedCorrelationDistance distance) {
- if(this.dimensionality >= 0 && distance.dimensionality >= 0 && this.dimensionality != distance.dimensionality) {
- throw new IllegalArgumentException("The dimensionality values of this distance " + "and the specified distance need to be equal.\n" + "this.dimensionality " + this.dimensionality + "\n" + "distance.dimensionality " + distance.dimensionality + "\n");
- }
-
- return super.compareTo(distance);
- }
-
- /**
- * Calls
- * {@link de.lmu.ifi.dbs.elki.distance.distancevalue.CorrelationDistance#writeExternal(java.io.ObjectOutput)}
- * and writes additionally the dimensionality and each Byte of the common
- * preference vector to the specified stream.
- */
- @Override
- public void writeExternal(ObjectOutput out) throws IOException {
- super.writeExternal(out);
- out.writeInt(dimensionality);
- for(int d = 0; d < dimensionality; d++) {
- out.writeBoolean(commonPreferenceVector.get(d));
- }
- }
-
- /**
- * Calls
- * {@link de.lmu.ifi.dbs.elki.distance.distancevalue.CorrelationDistance#readExternal(java.io.ObjectInput)}
- * and reads additionally the dimensionality and each Byte of the common
- * preference vector from the specified stream..
- */
- @Override
- public void readExternal(ObjectInput in) throws IOException {
- super.readExternal(in);
- dimensionality = in.readInt();
- commonPreferenceVector = new BitSet();
- for(int d = 0; d < dimensionality; d++) {
- commonPreferenceVector.set(d, in.readBoolean());
- }
- }
-
- /**
- * Returns the number of Bytes this distance uses if it is written to an
- * external file.
- *
- * @return 16 + 4 * dimensionality (8 Byte for two integer, 8 Byte for a
- * double value, and 4 * dimensionality for the bit set)
- */
- @Override
- public int externalizableSize() {
- return super.externalizableSize() + 4 + dimensionality << 2;
- }
-
- @Override
- public Pattern getPattern() {
- return CORRELATION_DISTANCE_PATTERN;
- }
-
- @Override
- public PreferenceVectorBasedCorrelationDistance parseString(String pattern) throws IllegalArgumentException {
- if(pattern.equals(INFINITY_PATTERN)) {
- return infiniteDistance();
- }
- if(testInputPattern(pattern)) {
- String[] values = SEPARATOR.split(pattern);
- return new PreferenceVectorBasedCorrelationDistance(-1, Integer.parseInt(values[0]), FormatUtil.parseDouble(values[1]), new BitSet());
- }
- else {
- throw new IllegalArgumentException("Given pattern \"" + pattern + "\" does not match required pattern \"" + requiredInputPattern() + "\"");
- }
- }
-
- @Override
- public PreferenceVectorBasedCorrelationDistance infiniteDistance() {
- return new PreferenceVectorBasedCorrelationDistance(-1, Integer.MAX_VALUE, Double.POSITIVE_INFINITY, new BitSet());
- }
-
- @Override
- public PreferenceVectorBasedCorrelationDistance nullDistance() {
- return new PreferenceVectorBasedCorrelationDistance(-1, 0, 0, new BitSet());
- }
-
- @Override
- public PreferenceVectorBasedCorrelationDistance undefinedDistance() {
- return new PreferenceVectorBasedCorrelationDistance(-1, -1, Double.NaN, new BitSet());
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/SubspaceDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/SubspaceDistance.java
deleted file mode 100644
index 6376c040..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/SubspaceDistance.java
+++ /dev/null
@@ -1,240 +0,0 @@
-package de.lmu.ifi.dbs.elki.distance.distancevalue;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.regex.Pattern;
-
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-
-/**
- * The subspace distance is a special distance that indicates the dissimilarity
- * between subspaces of equal dimensionality. The subspace distance between two
- * points is a pair consisting of the distance between the two subspaces spanned
- * by the strong eigenvectors of the two points and the affine distance between
- * the two subspaces.
- *
- * @author Elke Achtert
- */
-public class SubspaceDistance extends AbstractDistance<SubspaceDistance> {
- /**
- * The static factory instance
- */
- public static final SubspaceDistance FACTORY = new SubspaceDistance();
-
- /**
- * Serial version number.
- */
- private static final long serialVersionUID = 1;
-
- /**
- * Indicates a separator.
- */
- public static final String SEPARATOR = "x";
-
- /**
- * The pattern for parsing subspace values
- */
- public static final Pattern SUBSPACE_PATTERN = Pattern.compile("\\d+(\\.\\d+)?([eE][-]?\\d+)?" + Pattern.quote(SEPARATOR) + "\\d+(\\.\\d+)?([eE][-]?\\d+)?");
-
- /**
- * The subspace distance.
- */
- private double subspaceDistance;
-
- /**
- * The affine distance.
- */
- private double affineDistance;
-
- /**
- * Empty constructor for serialization purposes.
- */
- public SubspaceDistance() {
- // for serialization
- }
-
- /**
- * Constructs a new SubspaceDistance object consisting of the specified
- * subspace distance and affine distance.
- *
- * @param subspaceDistance the distance between the two subspaces spanned by
- * the strong eigenvectors of the two points
- * @param affineDistance the affine distance between the two subspaces
- */
- public SubspaceDistance(double subspaceDistance, double affineDistance) {
- this.subspaceDistance = subspaceDistance;
- this.affineDistance = affineDistance;
- }
-
- /**
- * Returns a string representation of this SubspaceDistance.
- *
- * @return the values of the subspace distance and the affine distance
- * separated by blank
- */
- @Override
- public String toString() {
- return Double.toString(subspaceDistance) + SEPARATOR + Double.toString(affineDistance);
- }
-
- /**
- * Compares this SubspaceDistance with the given SubspaceDistance wrt the
- * represented subspace distance values. If both values are considered to be
- * equal, the values of the affine distances are compared.
- *
- * @return the value of {@link Double#compare(double,double)
- * Double.compare(this.subspaceDistance, other.subspaceDistance)} if
- * it is a non zero value, the value of
- * {@link Double#compare(double,double)
- * Double.compare(this.affineDistance, other.affineDistance)}
- * otherwise
- */
- @Override
- public int compareTo(SubspaceDistance other) {
- int compare = Double.compare(this.subspaceDistance, other.subspaceDistance);
- if (compare != 0) {
- return compare;
- } else {
- return Double.compare(this.affineDistance, other.affineDistance);
- }
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- long temp;
- temp = Double.doubleToLongBits(subspaceDistance);
- result = prime * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(affineDistance);
- result = prime * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- SubspaceDistance other = (SubspaceDistance) obj;
- if (Double.doubleToLongBits(affineDistance) != Double.doubleToLongBits(other.affineDistance)) {
- return false;
- }
- if (Double.doubleToLongBits(subspaceDistance) != Double.doubleToLongBits(other.subspaceDistance)) {
- return false;
- }
- return true;
- }
-
- /**
- * Returns the value of the subspace distance.
- *
- * @return the value of the subspace distance
- */
- public double getSubspaceDistance() {
- return subspaceDistance;
- }
-
- /**
- * Returns the value of the affine distance.
- *
- * @return the value of the affine distance
- */
- public double getAffineDistance() {
- return affineDistance;
- }
-
- /**
- * Writes the subspace distance value and the affine distance value of this
- * SubspaceDistance to the specified stream.
- */
- @Override
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeDouble(subspaceDistance);
- out.writeDouble(affineDistance);
- }
-
- /**
- * Reads the subspace distance value and the affine distance value of this
- * SubspaceDistance from the specified stream.
- */
- @Override
- public void readExternal(ObjectInput in) throws IOException {
- subspaceDistance = in.readDouble();
- affineDistance = in.readDouble();
- }
-
- /**
- * Returns the number of Bytes this distance uses if it is written to an
- * external file.
- *
- * @return 16 (2 * 8 Byte for two double values)
- */
- @Override
- public int externalizableSize() {
- return 16;
- }
-
- @Override
- public Pattern getPattern() {
- return SUBSPACE_PATTERN;
- }
-
- @Override
- public SubspaceDistance parseString(String val) throws IllegalArgumentException {
- if (val.equals(INFINITY_PATTERN)) {
- return infiniteDistance();
- }
- if (testInputPattern(val)) {
- String[] values = SEPARATOR.split(val);
- return new SubspaceDistance(FormatUtil.parseDouble(values[0]), FormatUtil.parseDouble(values[1]));
- } else {
- throw new IllegalArgumentException("Given pattern \"" + val + "\" does not match required pattern \"" + requiredInputPattern() + "\"");
- }
- }
-
- @Override
- public SubspaceDistance infiniteDistance() {
- return new SubspaceDistance(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
- }
-
- @Override
- public SubspaceDistance nullDistance() {
- return new SubspaceDistance(0, 0);
- }
-
- @Override
- public SubspaceDistance undefinedDistance() {
- return new SubspaceDistance(Double.NaN, Double.NaN);
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancevalue/package-info.java
deleted file mode 100644
index ab0fdd9f..00000000
--- a/src/de/lmu/ifi/dbs/elki/distance/distancevalue/package-info.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * <p>Distance values, i.e. object storing an actual <em>distance</em> value along with
- * comparison functions and value parsers.</p>
- *
- * <p>Distances follow a factory pattern. Usually, a class will have a static instance
- * called <code>FACTORY</code> that can be used to obtain e.g. infinity or zero distances
- * as well as parse a string value into a new distance value.</p>
- *
- * @apiviz.exclude java.io.*
- * @apiviz.exclude java.lang.*
- */
-/*
-This file is part of ELKI:
-Environment for Developing KDD-Applications Supported by Index-Structures
-
-Copyright (C) 2013
-Ludwig-Maximilians-Universität München
-Lehr- und Forschungseinheit für Datenbanksysteme
-ELKI Development Team
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-package de.lmu.ifi.dbs.elki.distance.distancevalue;
diff --git a/src/de/lmu/ifi/dbs/elki/distance/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/package-info.java
index 744c74e1..f1ebd45f 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/package-info.java
@@ -1,13 +1,12 @@
/**
- * <p>{@link de.lmu.ifi.dbs.elki.distance.distancevalue Distance values},
- * {@link de.lmu.ifi.dbs.elki.distance.distancefunction distance functions} and
+ * <p>{@link de.lmu.ifi.dbs.elki.distance.distancefunction distance functions} and
* {@link de.lmu.ifi.dbs.elki.distance.similarityfunction similarity functions}.</p>
*/
/*
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
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractDBIDSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractDBIDSimilarityFunction.java
index 746f719a..b063c3bc 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractDBIDSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractDBIDSimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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,16 +25,13 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Abstract super class for distance functions needing a preprocessor.
*
* @author Elke Achtert
- *
- * @param <D> distance type
*/
-public abstract class AbstractDBIDSimilarityFunction<D extends Distance<D>> extends AbstractPrimitiveSimilarityFunction<DBID, D> implements DBIDSimilarityFunction<D> {
+public abstract class AbstractDBIDSimilarityFunction extends AbstractPrimitiveSimilarityFunction<DBID> implements DBIDSimilarityFunction {
/**
* The database we work on
*/
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractIndexBasedSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractIndexBasedSimilarityFunction.java
index 2147bbff..059e5bc4 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractIndexBasedSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractIndexBasedSimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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,6 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.database.query.similarity.AbstractDBIDSimilarityQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.index.Index;
import de.lmu.ifi.dbs.elki.index.IndexFactory;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -44,9 +43,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @param <O> object type
* @param <I> index type
- * @param <D> distance type
*/
-public abstract class AbstractIndexBasedSimilarityFunction<O, I extends Index, R, D extends Distance<D>> implements IndexBasedSimilarityFunction<O, D> {
+public abstract class AbstractIndexBasedSimilarityFunction<O, I extends Index> implements IndexBasedSimilarityFunction<O> {
/**
* Parameter to specify the preprocessor to be used.
* <p>
@@ -74,7 +72,7 @@ public abstract class AbstractIndexBasedSimilarityFunction<O, I extends Index, R
}
@Override
- abstract public <T extends O> Instance<T, ?, R, D> instantiate(Relation<T> database);
+ abstract public <T extends O> Instance<T, ?> instantiate(Relation<T> database);
@Override
public boolean isSymmetric() {
@@ -95,9 +93,8 @@ public abstract class AbstractIndexBasedSimilarityFunction<O, I extends Index, R
*
* @param <O> Object type
* @param <I> Index type
- * @param <D> Distance result type
*/
- abstract public static class Instance<O, I extends Index, R, D extends Distance<D>> extends AbstractDBIDSimilarityQuery<O, D> implements IndexBasedSimilarityFunction.Instance<O, I, D> {
+ abstract public static class Instance<O, I extends Index> extends AbstractDBIDSimilarityQuery<O> implements IndexBasedSimilarityFunction.Instance<O, I> {
/**
* Parent index
*/
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractPrimitiveSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractPrimitiveSimilarityFunction.java
index 2360f66e..454ecae2 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractPrimitiveSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractPrimitiveSimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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,6 @@ import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.database.query.similarity.PrimitiveSimilarityQuery;
import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Base implementation of a similarity function.
@@ -37,9 +36,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @apiviz.excludeSubtypes
*
* @param <O> object type
- * @param <D> distance type
*/
-public abstract class AbstractPrimitiveSimilarityFunction<O, D extends Distance<D>> implements PrimitiveSimilarityFunction<O, D> {
+public abstract class AbstractPrimitiveSimilarityFunction<O> implements PrimitiveSimilarityFunction<O> {
/**
* Constructor.
*/
@@ -57,10 +55,10 @@ public abstract class AbstractPrimitiveSimilarityFunction<O, D extends Distance<
abstract public SimpleTypeInformation<? super O> getInputTypeRestriction();
@Override
- abstract public D similarity(O o1, O o2);
+ abstract public double similarity(O o1, O o2);
@Override
- public <T extends O> SimilarityQuery<T, D> instantiate(Relation<T> relation) {
+ public <T extends O> SimilarityQuery<T> instantiate(Relation<T> relation) {
return new PrimitiveSimilarityQuery<>(relation, this);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractVectorDoubleSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractVectorSimilarityFunction.java
index 1f04cc98..bbb141b7 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractVectorDoubleSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/AbstractVectorSimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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,15 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
import de.lmu.ifi.dbs.elki.data.NumberVector;
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.distancevalue.DoubleDistance;
/**
* Abstract base class for double-valued primitive similarity functions.
*
* @author Erich Schubert
*/
-public abstract class AbstractVectorDoubleSimilarityFunction extends AbstractPrimitiveSimilarityFunction<NumberVector<?>, DoubleDistance> implements PrimitiveDoubleSimilarityFunction<NumberVector<?>> {
+public abstract class AbstractVectorSimilarityFunction extends AbstractPrimitiveSimilarityFunction<NumberVector> implements PrimitiveSimilarityFunction<NumberVector> {
@Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
- }
-
- @Override
- public DoubleDistance similarity(NumberVector<?> o1, NumberVector<?> o2) {
- return new DoubleDistance(doubleSimilarity(o1, o2));
- }
-
- @Override
- public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() {
+ public SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() {
return TypeUtil.NUMBER_VECTOR_FIELD;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/DBIDSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/DBIDSimilarityFunction.java
index 7b6eef34..da839bbe 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/DBIDSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/DBIDSimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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,7 +24,6 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Interface DBIDSimilarityFunction describes the requirements of any similarity
@@ -34,10 +33,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
*
* @apiviz.landmark
* @apiviz.uses DBID oneway - - defined on
- *
- * @param <D> distance type
*/
-public interface DBIDSimilarityFunction<D extends Distance<D>> extends SimilarityFunction<DBID, D> {
+public interface DBIDSimilarityFunction extends SimilarityFunction<DBID> {
/**
* Computes the similarity between two given DatabaseObjects according to this
* similarity function.
@@ -47,5 +44,5 @@ public interface DBIDSimilarityFunction<D extends Distance<D>> extends Similarit
* @return the similarity between two given DatabaseObjects according to this
* similarity function
*/
- D similarity(DBID id1, DBID id2);
+ double similarity(DBID id1, DBID id2);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/FractionalSharedNearestNeighborSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/FractionalSharedNearestNeighborSimilarityFunction.java
index 741ece82..af17ae93 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/FractionalSharedNearestNeighborSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/FractionalSharedNearestNeighborSimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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
@@ -23,13 +23,11 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborIndex;
import de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborPreprocessor;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -47,7 +45,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
*
* @param <O> object type
*/
-public class FractionalSharedNearestNeighborSimilarityFunction<O> extends AbstractIndexBasedSimilarityFunction<O, SharedNearestNeighborIndex<O>, ArrayDBIDs, DoubleDistance> implements NormalizedSimilarityFunction<O> {
+public class FractionalSharedNearestNeighborSimilarityFunction<O> extends AbstractIndexBasedSimilarityFunction<O, SharedNearestNeighborIndex<O>> implements NormalizedSimilarityFunction<O> {
/**
* Constructor.
*
@@ -73,7 +71,7 @@ public class FractionalSharedNearestNeighborSimilarityFunction<O> extends Abstra
*
* @param <T> Object type
*/
- public static class Instance<T> extends AbstractIndexBasedSimilarityFunction.Instance<T, SharedNearestNeighborIndex<T>, ArrayDBIDs, DoubleDistance> {
+ public static class Instance<T> extends AbstractIndexBasedSimilarityFunction.Instance<T, SharedNearestNeighborIndex<T>> {
/**
* Similarity function.
*/
@@ -118,27 +116,17 @@ public class FractionalSharedNearestNeighborSimilarityFunction<O> extends Abstra
}
@Override
- public DoubleDistance similarity(DBIDRef id1, DBIDRef id2) {
+ public double similarity(DBIDRef id1, DBIDRef id2) {
DBIDs neighbors1 = index.getNearestNeighborSet(id1);
DBIDs neighbors2 = index.getNearestNeighborSet(id2);
int intersection = countSharedNeighbors(neighbors1, neighbors2);
- return new DoubleDistance((double) intersection / index.getNumberOfNeighbors());
+ return (double) intersection / index.getNumberOfNeighbors();
}
@Override
- public SimilarityFunction<? super T, DoubleDistance> getSimilarityFunction() {
+ public SimilarityFunction<? super T> getSimilarityFunction() {
return similarityFunction;
}
-
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
- }
- }
-
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/IndexBasedSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/IndexBasedSimilarityFunction.java
index 33192e38..b5213baf 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/IndexBasedSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/IndexBasedSimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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,7 +25,6 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.index.Index;
/**
@@ -37,9 +36,8 @@ import de.lmu.ifi.dbs.elki.index.Index;
* @apiviz.landmark
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public interface IndexBasedSimilarityFunction<O, D extends Distance<D>> extends SimilarityFunction<O, D> {
+public interface IndexBasedSimilarityFunction<O> extends SimilarityFunction<O> {
/**
* Preprocess the database to get the actual distance function.
*
@@ -47,7 +45,7 @@ public interface IndexBasedSimilarityFunction<O, D extends Distance<D>> extends
* @return Actual distance query.
*/
@Override
- public abstract <T extends O> Instance<T, ?, D> instantiate(Relation<T> database);
+ public abstract <T extends O> Instance<T, ?> instantiate(Relation<T> database);
/**
* Instance interface for index/preprocessor based distance functions.
@@ -55,9 +53,8 @@ public interface IndexBasedSimilarityFunction<O, D extends Distance<D>> extends
* @author Erich Schubert
*
* @param <T> Object type
- * @param <D> Distance type
*/
- public static interface Instance<T, I extends Index, D extends Distance<D>> extends SimilarityQuery<T, D> {
+ public static interface Instance<T, I extends Index> extends SimilarityQuery<T> {
/**
* Get the index used.
*
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/InvertedDistanceSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/InvertedDistanceSimilarityFunction.java
index 9c974f17..f5ea8bad 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/InvertedDistanceSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/InvertedDistanceSimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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,8 +24,6 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
*/
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
/**
@@ -36,7 +34,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
*
* @param <O> Object type
*/
-public class InvertedDistanceSimilarityFunction<O> extends AbstractPrimitiveSimilarityFunction<O, DoubleDistance> {
+public class InvertedDistanceSimilarityFunction<O> extends AbstractPrimitiveSimilarityFunction<O> {
/**
* Parameter to specify the similarity function to derive the distance between
* database objects from. Must extend
@@ -54,12 +52,7 @@ public class InvertedDistanceSimilarityFunction<O> extends AbstractPrimitiveSimi
/**
* Holds the similarity function.
*/
- protected PrimitiveDistanceFunction<? super O, ? extends NumberDistance<?, ?>> distanceFunction;
-
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
- }
+ protected PrimitiveDistanceFunction<? super O> distanceFunction;
@Override
public SimpleTypeInformation<? super O> getInputTypeRestriction() {
@@ -67,8 +60,8 @@ public class InvertedDistanceSimilarityFunction<O> extends AbstractPrimitiveSimi
}
@Override
- public DoubleDistance similarity(O o1, O o2) {
- double dist = distanceFunction.distance(o1, o2).doubleValue();
- return new DoubleDistance(1. / dist);
+ public double similarity(O o1, O o2) {
+ double dist = distanceFunction.distance(o1, o2);
+ return dist > 0. ? 1. / dist : Double.POSITIVE_INFINITY;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski1SimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski1SimilarityFunction.java
index d307bec8..b1302e13 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski1SimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski1SimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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,7 +24,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -40,7 +40,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
* @author Erich Schubert
*/
@Reference(authors = "M.-M. Deza and E. Deza", title = "Dictionary of distances", booktitle = "Dictionary of distances")
-public class Kulczynski1SimilarityFunction extends AbstractVectorDoubleSimilarityFunction {
+public class Kulczynski1SimilarityFunction extends AbstractVectorSimilarityFunction {
/**
* Static instance.
*/
@@ -57,8 +57,8 @@ public class Kulczynski1SimilarityFunction extends AbstractVectorDoubleSimilarit
}
@Override
- public double doubleSimilarity(NumberVector<?> v1, NumberVector<?> v2) {
- final int dim = AbstractVectorDoubleDistanceFunction.dimensionality(v1, v2);
+ public double similarity(NumberVector v1, NumberVector v2) {
+ final int dim = AbstractNumberVectorDistanceFunction.dimensionality(v1, v2);
double sumdiff = 0., summin = 0.;
for (int i = 0; i < dim; i++) {
double xi = v1.doubleValue(i), yi = v2.doubleValue(i);
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski2SimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski2SimilarityFunction.java
index 8c678601..093dce00 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski2SimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/Kulczynski2SimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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,7 +24,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -42,7 +42,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
* @author Erich Schubert
*/
@Reference(authors = "M.-M. Deza and E. Deza", title = "Dictionary of distances", booktitle = "Dictionary of distances")
-public class Kulczynski2SimilarityFunction extends AbstractVectorDoubleSimilarityFunction {
+public class Kulczynski2SimilarityFunction extends AbstractVectorSimilarityFunction {
/**
* Static instance.
*/
@@ -59,8 +59,8 @@ public class Kulczynski2SimilarityFunction extends AbstractVectorDoubleSimilarit
}
@Override
- public double doubleSimilarity(NumberVector<?> v1, NumberVector<?> v2) {
- final int dim = AbstractVectorDoubleDistanceFunction.dimensionality(v1, v2);
+ public double similarity(NumberVector v1, NumberVector v2) {
+ final int dim = AbstractNumberVectorDistanceFunction.dimensionality(v1, v2);
double sumx = 0., sumy = 0., summin = 0.;
for (int i = 0; i < dim; i++) {
double xi = v1.doubleValue(i), yi = v2.doubleValue(i);
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedPrimitiveSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedPrimitiveSimilarityFunction.java
index 83a0edfa..ac0e360b 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedPrimitiveSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedPrimitiveSimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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
@@ -31,6 +31,6 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
*
* @param <O> Object type
*/
-public interface NormalizedPrimitiveSimilarityFunction<O> extends PrimitiveDoubleSimilarityFunction<O>, NormalizedSimilarityFunction<O> {
+public interface NormalizedPrimitiveSimilarityFunction<O> extends PrimitiveSimilarityFunction<O>, NormalizedSimilarityFunction<O> {
// empty marker interface
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedSimilarityFunction.java
index 91e94498..865168cd 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/NormalizedSimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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
@@ -23,7 +23,6 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
/**
* Marker interface to signal that the similarity function is normalized to
@@ -31,8 +30,7 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
*
* @author Erich Schubert
* @param <O> object type
- *
*/
-public interface NormalizedSimilarityFunction<O> extends SimilarityFunction<O, DoubleDistance> {
+public interface NormalizedSimilarityFunction<O> extends SimilarityFunction<O> {
// Empty - marker interface.
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveSimilarityFunction.java
index 5188e9d9..2550dbef 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveSimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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,7 +24,6 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
*/
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Interface SimilarityFunction describes the requirements of any similarity
@@ -36,9 +35,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @apiviz.excludeSubtypes
*
* @param <O> object type
- * @param <D> distance type
*/
-public interface PrimitiveSimilarityFunction<O, D extends Distance<?>> extends SimilarityFunction<O, D> {
+public interface PrimitiveSimilarityFunction<O> extends SimilarityFunction<O> {
/**
* Computes the similarity between two given DatabaseObjects according to this
* similarity function.
@@ -48,7 +46,7 @@ public interface PrimitiveSimilarityFunction<O, D extends Distance<?>> extends S
* @return the similarity between two given DatabaseObjects according to this
* similarity function
*/
- D similarity(O o1, O o2);
+ double similarity(O o1, O o2);
@Override
abstract public SimpleTypeInformation<? super O> getInputTypeRestriction();
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SharedNearestNeighborSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SharedNearestNeighborSimilarityFunction.java
index 89661f13..38b43b09 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SharedNearestNeighborSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SharedNearestNeighborSimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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,7 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.SetDBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.IntegerDistance;
import de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborIndex;
import de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborPreprocessor;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -47,8 +45,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
*
* @param <O> object type
*/
-// todo arthur comment class
-public class SharedNearestNeighborSimilarityFunction<O> extends AbstractIndexBasedSimilarityFunction<O, SharedNearestNeighborIndex<O>, SetDBIDs, IntegerDistance> {
+public class SharedNearestNeighborSimilarityFunction<O> extends AbstractIndexBasedSimilarityFunction<O, SharedNearestNeighborIndex<O>> {
/**
* Constructor.
*
@@ -58,11 +55,6 @@ public class SharedNearestNeighborSimilarityFunction<O> extends AbstractIndexBas
super(indexFactory);
}
- @Override
- public IntegerDistance getDistanceFactory() {
- return IntegerDistance.FACTORY;
- }
-
/**
* Compute the intersection size
*
@@ -74,15 +66,17 @@ public class SharedNearestNeighborSimilarityFunction<O> extends AbstractIndexBas
int intersection = 0;
DBIDIter iter1 = neighbors1.iter();
DBIDIter iter2 = neighbors2.iter();
- while (iter1.valid() && iter2.valid()) {
+ while(iter1.valid() && iter2.valid()) {
final int comp = DBIDUtil.compare(iter1, iter2);
- if (comp == 0) {
+ if(comp == 0) {
intersection++;
iter1.advance();
iter2.advance();
- } else if (comp < 0) {
+ }
+ else if(comp < 0) {
iter1.advance();
- } else // iter2 < iter1
+ }
+ else // iter2 < iter1
{
iter2.advance();
}
@@ -106,7 +100,7 @@ public class SharedNearestNeighborSimilarityFunction<O> extends AbstractIndexBas
*
* @param <O> Object type
*/
- public static class Instance<O> extends AbstractIndexBasedSimilarityFunction.Instance<O, SharedNearestNeighborIndex<O>, SetDBIDs, IntegerDistance> {
+ public static class Instance<O> extends AbstractIndexBasedSimilarityFunction.Instance<O, SharedNearestNeighborIndex<O>> {
/**
* Similarity function.
*/
@@ -124,19 +118,14 @@ public class SharedNearestNeighborSimilarityFunction<O> extends AbstractIndexBas
}
@Override
- public IntegerDistance similarity(DBIDRef id1, DBIDRef id2) {
+ public double similarity(DBIDRef id1, DBIDRef id2) {
DBIDs neighbors1 = index.getNearestNeighborSet(id1);
DBIDs neighbors2 = index.getNearestNeighborSet(id2);
- return new IntegerDistance(countSharedNeighbors(neighbors1, neighbors2));
- }
-
- @Override
- public IntegerDistance getDistanceFactory() {
- return IntegerDistance.FACTORY;
+ return countSharedNeighbors(neighbors1, neighbors2);
}
@Override
- public SimilarityFunction<? super O, IntegerDistance> getSimilarityFunction() {
+ public SimilarityFunction<? super O> getSimilarityFunction() {
return similarityFunction;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SimilarityFunction.java
index 0e3f4ce6..2dc28ff0 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/SimilarityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
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,22 +26,18 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Interface SimilarityFunction describes the requirements of any similarity
* function.
*
- * @author Elke Achtert
+ * @author Erich Schubert
*
* @apiviz.landmark
- * @apiviz.has Distance
*
* @param <O> object type
- * @param <D> distance type
*/
-public interface SimilarityFunction<O, D extends Distance<?>> extends Parameterizable {
+public interface SimilarityFunction<O> {
/**
* Is this function symmetric?
*
@@ -55,17 +51,10 @@ public interface SimilarityFunction<O, D extends Distance<?>> extends Parameteri
TypeInformation getInputTypeRestriction();
/**
- * Get a distance factory.
- *
- * @return distance factory
- */
- D getDistanceFactory();
-
- /**
* Instantiate with a representation to get the actual similarity query.
*
* @param relation Representation to use
* @return Actual distance query.
*/
- public <T extends O> SimilarityQuery<T, D> instantiate(Relation<T> relation);
+ public <T extends O> SimilarityQuery<T> instantiate(Relation<T> relation);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/ClusterIntersectionSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/ClusterIntersectionSimilarityFunction.java
new file mode 100644
index 00000000..078c7934
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/ClusterIntersectionSimilarityFunction.java
@@ -0,0 +1,93 @@
+package de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.query.DistanceSimilarityQuery;
+import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceSimilarityQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.similarityfunction.AbstractPrimitiveSimilarityFunction;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Measure the similarity of clusters via the intersection size.
+ *
+ * @author Erich Schubert
+ */
+public class ClusterIntersectionSimilarityFunction extends AbstractPrimitiveSimilarityFunction<Cluster<?>> implements PrimitiveDistanceFunction<Cluster<?>> {
+ /**
+ * Static instance.
+ */
+ public static final ClusterIntersectionSimilarityFunction STATIC = new ClusterIntersectionSimilarityFunction();
+
+ /**
+ * Constructor - use the static instance {@link #STATIC}!
+ */
+ public ClusterIntersectionSimilarityFunction() {
+ super();
+ }
+
+ @Override
+ public double similarity(Cluster<?> o1, Cluster<?> o2) {
+ return DBIDUtil.intersectionSize(o1.getIDs(), o2.getIDs());
+ }
+
+ @Override
+ public double distance(Cluster<?> o1, Cluster<?> o2) {
+ int i = DBIDUtil.intersectionSize(o1.getIDs(), o2.getIDs());
+ return Math.max(o1.size(), o2.size()) - i;
+ }
+
+ @Override
+ public boolean isMetric() {
+ return false;
+ }
+
+ @Override
+ public <T extends Cluster<?>> DistanceSimilarityQuery<T> instantiate(Relation<T> relation) {
+ return new PrimitiveDistanceSimilarityQuery<>(relation, this, this);
+ }
+
+ @Override
+ public SimpleTypeInformation<? super Cluster<?>> getInputTypeRestriction() {
+ return new SimpleTypeInformation<>(Cluster.class);
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected ClusterIntersectionSimilarityFunction makeInstance() {
+ return STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/ClusterJaccardSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/ClusterJaccardSimilarityFunction.java
new file mode 100644
index 00000000..7b25306e
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/ClusterJaccardSimilarityFunction.java
@@ -0,0 +1,107 @@
+package de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.query.DistanceSimilarityQuery;
+import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceSimilarityQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.similarityfunction.AbstractPrimitiveSimilarityFunction;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Measure the similarity of clusters via the Jaccard coefficient.
+ *
+ * <p>
+ * P. Jaccard<br />
+ * Distribution de la florine alpine dans la Bassin de Dranses et dans quelques
+ * regiones voisines<br />
+ * Bulletin del la Société Vaudoise des Sciences Naturelles
+ * </p>
+ *
+ * @author Erich Schubert
+ */
+@Reference(authors = "P. Jaccard", //
+title = "Distribution de la florine alpine dans la Bassin de Dranses et dans quelques regiones voisines", //
+booktitle = "Bulletin del la Société Vaudoise des Sciences Naturelles")
+public class ClusterJaccardSimilarityFunction extends AbstractPrimitiveSimilarityFunction<Cluster<?>> implements PrimitiveDistanceFunction<Cluster<?>> {
+ /**
+ * Static instance.
+ */
+ public static final ClusterJaccardSimilarityFunction STATIC = new ClusterJaccardSimilarityFunction();
+
+ /**
+ * Constructor - use the static instance {@link #STATIC}!
+ */
+ public ClusterJaccardSimilarityFunction() {
+ super();
+ }
+
+ @Override
+ public double similarity(Cluster<?> o1, Cluster<?> o2) {
+ int i = DBIDUtil.intersectionSize(o1.getIDs(), o2.getIDs());
+ int union = o1.size() + o2.size() - i;
+ return i / (double) union;
+ }
+
+ @Override
+ public double distance(Cluster<?> o1, Cluster<?> o2) {
+ int i = DBIDUtil.intersectionSize(o1.getIDs(), o2.getIDs());
+ int union = o1.size() + o2.size() - i;
+ return 1. - i / (double) union;
+ }
+
+ @Override
+ public boolean isMetric() {
+ return true;
+ }
+
+ @Override
+ public <T extends Cluster<?>> DistanceSimilarityQuery<T> instantiate(Relation<T> relation) {
+ return new PrimitiveDistanceSimilarityQuery<>(relation, this, this);
+ }
+
+ @Override
+ public SimpleTypeInformation<? super Cluster<?>> getInputTypeRestriction() {
+ return new SimpleTypeInformation<>(Cluster.class);
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected ClusterJaccardSimilarityFunction makeInstance() {
+ return STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/ClusteringAdjustedRandIndexSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/ClusteringAdjustedRandIndexSimilarityFunction.java
new file mode 100644
index 00000000..2b9d19d4
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/ClusteringAdjustedRandIndexSimilarityFunction.java
@@ -0,0 +1,96 @@
+package de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.database.query.DistanceSimilarityQuery;
+import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceSimilarityQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.similarityfunction.AbstractPrimitiveSimilarityFunction;
+import de.lmu.ifi.dbs.elki.evaluation.clustering.ClusterContingencyTable;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Measure the similarity of clusters via the Adjusted Rand Index.
+ *
+ * @author Erich Schubert
+ */
+public class ClusteringAdjustedRandIndexSimilarityFunction extends AbstractPrimitiveSimilarityFunction<Clustering<?>> implements PrimitiveDistanceFunction<Clustering<?>> {
+ /**
+ * Static instance.
+ */
+ public static final ClusteringAdjustedRandIndexSimilarityFunction STATIC = new ClusteringAdjustedRandIndexSimilarityFunction();
+
+ /**
+ * Constructor - use the static instance {@link #STATIC}!
+ */
+ public ClusteringAdjustedRandIndexSimilarityFunction() {
+ super();
+ }
+
+ @Override
+ public double similarity(Clustering<?> o1, Clustering<?> o2) {
+ ClusterContingencyTable ct = new ClusterContingencyTable(false, true);
+ ct.process(o1, o2);
+ return ct.getPaircount().adjustedRandIndex();
+ }
+
+ @Override
+ public double distance(Clustering<?> o1, Clustering<?> o2) {
+ ClusterContingencyTable ct = new ClusterContingencyTable(false, true);
+ ct.process(o1, o2);
+ return 1. - ct.getPaircount().adjustedRandIndex();
+ }
+
+ @Override
+ public boolean isMetric() {
+ return false;
+ }
+
+ @Override
+ public <T extends Clustering<?>> DistanceSimilarityQuery<T> instantiate(Relation<T> relation) {
+ return new PrimitiveDistanceSimilarityQuery<>(relation, this, this);
+ }
+
+ @Override
+ public SimpleTypeInformation<? super Clustering<?>> getInputTypeRestriction() {
+ return new SimpleTypeInformation<>(Clustering.class);
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected ClusteringAdjustedRandIndexSimilarityFunction makeInstance() {
+ return STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/package-info.java
new file mode 100644
index 00000000..5f6d5e6e
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/cluster/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * Similarity measures for comparing clusters.
+ */
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2014
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/KernelMatrix.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/KernelMatrix.java
index 39fb97a5..7acd784b 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/KernelMatrix.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/KernelMatrix.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel;
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
@@ -34,14 +34,12 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFunction;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
/**
- * Provides a class for storing the kernel matrix and several extraction methods
- * for convenience.
+ * Kernel matrix representation.
*
* @author Simon Paradies
*
@@ -141,8 +139,7 @@ public class KernelMatrix {
* @param relation the database that holds the objects
* @param ids the IDs of those objects for which the kernel matrix is computed
*/
- public <O, D extends NumberDistance<?, ?>> KernelMatrix(PrimitiveSimilarityFunction<? super O, D> kernelFunction, final Relation<? extends O> relation, final DBIDs ids) {
- LoggingUtil.logExpensive(Level.FINER, "Computing kernel matrix");
+ public <O> KernelMatrix(PrimitiveSimilarityFunction<? super O> kernelFunction, final Relation<? extends O> relation, final DBIDs ids) {
this.kernel = new Matrix(ids.size(), ids.size());
if(ids instanceof DBIDRange) {
this.idmap = new RangeMap((DBIDRange) ids);
@@ -155,7 +152,7 @@ public class KernelMatrix {
for(i1.seek(0); i1.valid(); i1.advance()) {
O o1 = relation.get(i1);
for(i2.seek(i1.getOffset()); i2.valid(); i2.advance()) {
- double value = kernelFunction.similarity(o1, relation.get(i2)).doubleValue();
+ double value = kernelFunction.similarity(o1, relation.get(i2));
kernel.set(i1.getOffset(), i2.getOffset(), value);
kernel.set(i2.getOffset(), i1.getOffset(), value);
}
@@ -169,7 +166,7 @@ public class KernelMatrix {
* @param relation the database that holds the objects
* @param ids the IDs of those objects for which the kernel matrix is computed
*/
- public <O, D extends NumberDistance<?, ?>> KernelMatrix(SimilarityQuery<? super O, D> kernelFunction, final Relation<? extends O> relation, final DBIDs ids) {
+ public <O> KernelMatrix(SimilarityQuery<? super O> kernelFunction, final Relation<? extends O> relation, final DBIDs ids) {
LoggingUtil.logExpensive(Level.FINER, "Computing kernel matrix");
kernel = new Matrix(ids.size(), ids.size());
if(ids instanceof DBIDRange) {
@@ -182,7 +179,7 @@ public class KernelMatrix {
for(i1.seek(0); i1.valid(); i1.advance()) {
O o1 = relation.get(i1);
for(i2.seek(i1.getOffset()); i2.valid(); i2.advance()) {
- double value = kernelFunction.similarity(o1, i2).doubleValue();
+ double value = kernelFunction.similarity(o1, i2);
kernel.set(i1.getOffset(), i2.getOffset(), value);
kernel.set(i2.getOffset(), i1.getOffset(), value);
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/LaplaceKernelFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/LaplaceKernelFunction.java
index 2a5f6028..a2297409 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/LaplaceKernelFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/LaplaceKernelFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel;
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,8 +24,8 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.similarityfunction.AbstractVectorDoubleSimilarityFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.similarityfunction.AbstractVectorSimilarityFunction;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -33,11 +33,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
- * Provides the laplace / exponential radial basis function kernel.
+ * Laplace / exponential radial basis function kernel.
*
* @author Erich Schubert
*/
-public class LaplaceKernelFunction extends AbstractVectorDoubleSimilarityFunction {
+public class LaplaceKernelFunction extends AbstractVectorSimilarityFunction {
/**
* Scaling factor mgamma. (= - 1/sigma)
*/
@@ -54,8 +54,8 @@ public class LaplaceKernelFunction extends AbstractVectorDoubleSimilarityFunctio
}
@Override
- public double doubleSimilarity(NumberVector<?> o1, NumberVector<?> o2) {
- final int dim = AbstractVectorDoubleDistanceFunction.dimensionality(o1, o2);
+ public double similarity(NumberVector o1, NumberVector o2) {
+ final int dim = AbstractNumberVectorDistanceFunction.dimensionality(o1, o2);
double sim = 0.;
for(int i = 0; i < dim; i++) {
final double v = o1.doubleValue(i) - o2.doubleValue(i);
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/LinearKernelFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/LinearKernelFunction.java
index a86ad55d..6a5b0a79 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/LinearKernelFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/LinearKernelFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel;
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,12 +24,12 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
- * Provides a linear Kernel function that computes a similarity between the two
- * feature vectors V1 and V2 defined by V1^T*V2.
+ * Linear Kernel function that computes a similarity between the two feature
+ * vectors V1 and V2 defined by V1^T*V2.
*
* Note: this is effectively equivalent to using
* {@link de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction}
@@ -51,18 +51,18 @@ public class LinearKernelFunction extends PolynomialKernelFunction {
}
@Override
- public double doubleSimilarity(final NumberVector<?> o1, final NumberVector<?> o2) {
- final int dim = AbstractVectorDoubleDistanceFunction.dimensionality(o1, o2);
+ public double similarity(final NumberVector o1, final NumberVector o2) {
+ final int dim = AbstractNumberVectorDistanceFunction.dimensionality(o1, o2);
double sim = 0.;
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
sim += o1.doubleValue(i) * o2.doubleValue(i);
}
return sim;
}
@Override
- public double doubleDistance(final NumberVector<?> fv1, final NumberVector<?> fv2) {
- return Math.sqrt(doubleSimilarity(fv1, fv1) + doubleSimilarity(fv2, fv2) - 2 * doubleSimilarity(fv1, fv2));
+ public double distance(final NumberVector fv1, final NumberVector fv2) {
+ return Math.sqrt(similarity(fv1, fv1) + similarity(fv2, fv2) - 2 * similarity(fv1, fv2));
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/PolynomialKernelFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/PolynomialKernelFunction.java
index 2b25ba19..a726003c 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/PolynomialKernelFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/PolynomialKernelFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel;
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,10 +27,9 @@ import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.query.DistanceSimilarityQuery;
import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceSimilarityQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.distance.similarityfunction.AbstractVectorDoubleSimilarityFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.similarityfunction.AbstractVectorSimilarityFunction;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -40,12 +39,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
/**
- * Provides a polynomial Kernel function that computes a similarity between the
- * two feature vectors V1 and V2 defined by (V1^T*V2)^degree.
+ * Polynomial Kernel function that computes a similarity between the two feature
+ * vectors V1 and V2 defined by (V1^T*V2)^degree.
*
* @author Simon Paradies
*/
-public class PolynomialKernelFunction extends AbstractVectorDoubleSimilarityFunction implements PrimitiveDoubleDistanceFunction<NumberVector<?>> {
+public class PolynomialKernelFunction extends AbstractVectorSimilarityFunction implements PrimitiveDistanceFunction<NumberVector> {
/**
* The default degree.
*/
@@ -83,8 +82,8 @@ public class PolynomialKernelFunction extends AbstractVectorDoubleSimilarityFunc
}
@Override
- public double doubleSimilarity(NumberVector<?> o1, NumberVector<?> o2) {
- final int dim = AbstractVectorDoubleDistanceFunction.dimensionality(o1, o2);
+ public double similarity(NumberVector o1, NumberVector o2) {
+ final int dim = AbstractNumberVectorDistanceFunction.dimensionality(o1, o2);
double sim = 0.;
for(int i = 0; i < dim; i++) {
sim += o1.doubleValue(i) * o2.doubleValue(i);
@@ -93,22 +92,17 @@ public class PolynomialKernelFunction extends AbstractVectorDoubleSimilarityFunc
}
@Override
- public DoubleDistance distance(final NumberVector<?> fv1, final NumberVector<?> fv2) {
- return new DoubleDistance(doubleDistance(fv1, fv2));
- }
-
- @Override
public boolean isMetric() {
return true;
}
@Override
- public double doubleDistance(NumberVector<?> fv1, NumberVector<?> fv2) {
- return Math.sqrt(doubleSimilarity(fv1, fv1) + doubleSimilarity(fv2, fv2) - 2 * doubleSimilarity(fv1, fv2));
+ public double distance(NumberVector fv1, NumberVector fv2) {
+ return Math.sqrt(similarity(fv1, fv1) + similarity(fv2, fv2) - 2 * similarity(fv1, fv2));
}
@Override
- public <T extends NumberVector<?>> DistanceSimilarityQuery<T, DoubleDistance> instantiate(Relation<T> database) {
+ public <T extends NumberVector> DistanceSimilarityQuery<T> instantiate(Relation<T> database) {
return new PrimitiveDistanceSimilarityQuery<>(database, this, this);
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/RadialBasisFunctionKernelFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/RadialBasisFunctionKernelFunction.java
index a7613a78..a0287b36 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/RadialBasisFunctionKernelFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/RadialBasisFunctionKernelFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel;
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,8 +24,8 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.similarityfunction.AbstractVectorDoubleSimilarityFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.similarityfunction.AbstractVectorSimilarityFunction;
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;
@@ -34,12 +34,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
- * Provides the Gaussian radial basis function kernel (RBF Kernel).
+ * Gaussian radial basis function kernel (RBF Kernel).
*
* @author Erich Schubert
*/
@Alias({ "rbf" })
-public class RadialBasisFunctionKernelFunction extends AbstractVectorDoubleSimilarityFunction {
+public class RadialBasisFunctionKernelFunction extends AbstractVectorSimilarityFunction {
/**
* Scaling factor gamma. (= - 1/(2sigma^2))
*/
@@ -56,8 +56,8 @@ public class RadialBasisFunctionKernelFunction extends AbstractVectorDoubleSimil
}
@Override
- public double doubleSimilarity(NumberVector<?> o1, NumberVector<?> o2) {
- final int dim = AbstractVectorDoubleDistanceFunction.dimensionality(o1, o2);
+ public double similarity(NumberVector o1, NumberVector o2) {
+ final int dim = AbstractNumberVectorDistanceFunction.dimensionality(o1, o2);
double sim = 0.;
for(int i = 0; i < dim; i++) {
final double v = o1.doubleValue(i) - o2.doubleValue(i);
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/RationalQuadraticKernelFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/RationalQuadraticKernelFunction.java
index 0a3dc45c..54398fd3 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/RationalQuadraticKernelFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/RationalQuadraticKernelFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel;
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,8 +24,8 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.similarityfunction.AbstractVectorDoubleSimilarityFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.similarityfunction.AbstractVectorSimilarityFunction;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -33,12 +33,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
- * Provides the rational quadratic kernel, a less computational approximation of
- * the Gaussian RBF kerne ({@link RadialBasisFunctionKernelFunction}).
+ * Rational quadratic kernel, a less computational approximation of the Gaussian
+ * RBF kernel ({@link RadialBasisFunctionKernelFunction}).
*
* @author Erich Schubert
*/
-public class RationalQuadraticKernelFunction extends AbstractVectorDoubleSimilarityFunction {
+public class RationalQuadraticKernelFunction extends AbstractVectorSimilarityFunction {
/**
* Constant term c.
*/
@@ -55,8 +55,8 @@ public class RationalQuadraticKernelFunction extends AbstractVectorDoubleSimilar
}
@Override
- public double doubleSimilarity(NumberVector<?> o1, NumberVector<?> o2) {
- final int dim = AbstractVectorDoubleDistanceFunction.dimensionality(o1, o2);
+ public double similarity(NumberVector o1, NumberVector o2) {
+ final int dim = AbstractNumberVectorDistanceFunction.dimensionality(o1, o2);
double sim = 0.;
for(int i = 0; i < dim; i++) {
final double v = o1.doubleValue(i) - o2.doubleValue(i);
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/SigmoidKernelFunction.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/SigmoidKernelFunction.java
index a88225f9..11f33f16 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/SigmoidKernelFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/SigmoidKernelFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel;
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,8 +24,8 @@ package de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel;
*/
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.similarityfunction.AbstractVectorDoubleSimilarityFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.similarityfunction.AbstractVectorSimilarityFunction;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -37,7 +37,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
*
* @author Erich Schubert
*/
-public class SigmoidKernelFunction extends AbstractVectorDoubleSimilarityFunction {
+public class SigmoidKernelFunction extends AbstractVectorSimilarityFunction {
/**
* Scaling factor c, bias theta
*/
@@ -56,8 +56,8 @@ public class SigmoidKernelFunction extends AbstractVectorDoubleSimilarityFunctio
}
@Override
- public double doubleSimilarity(NumberVector<?> o1, NumberVector<?> o2) {
- final int dim = AbstractVectorDoubleDistanceFunction.dimensionality(o1, o2);
+ public double similarity(NumberVector o1, NumberVector o2) {
+ final int dim = AbstractNumberVectorDistanceFunction.dimensionality(o1, o2);
double sim = 0.;
for (int i = 0; i < dim; i++) {
final double v = o1.doubleValue(i) * o2.doubleValue(i);
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/package-info.java
index ec847f80..6d0d3da2 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/kernel/package-info.java
@@ -7,7 +7,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
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/package-info.java
index 6e5ad0e0..025c3792 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/package-info.java
@@ -7,7 +7,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