summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrej Shadura <andrewsh@debian.org>2019-03-09 22:30:40 +0000
committerAndrej Shadura <andrewsh@debian.org>2019-03-09 22:30:40 +0000
commit337087b668d3a54f3afee3a9adb597a32e9f7e94 (patch)
treed860094269622472f8079d497ac7af02dbb4e038
parent14a486343aef55f97f54082d6b542dedebf6f3ba (diff)
Import Upstream version 0.6.5~20141030
-rw-r--r--license/LICENSE (renamed from LICENSE.txt)2
-rw-r--r--license/LICENSE-libsvm30
-rw-r--r--license/LICENSE-trove4j504
-rw-r--r--src/META-INF/MANIFEST.MF180
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.AbstractPrimitiveDistanceBasedAlgorithm5
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.Algorithm59
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.DistanceBasedAlgorithm40
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.classification.Classifier2
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm11
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.em.EMClusterModelFactory3
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.CorePredicate4
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.NeighborPredicate6
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeans3
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansInitialization7
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMedoidsInitialization5
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization9
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMedoidsInitialization6
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.KMeansQualityMeasure3
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.optics.OPTICSTypeAlgorithm (renamed from src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICSTypeAlgorithm)4
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm40
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.application.AbstractApplication5
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.data.SparseNumberVector$Factory3
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.data.images.ComputeColorHistogram3
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.DatabaseConnection3
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter54
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.filter.StreamFilter23
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.parser.Parser7
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractIndexBasedDistanceFunction7
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction40
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.FilteredLocalPCABasedDistanceFunction4
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction1
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.Norm (renamed from src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.DoubleNorm)12
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.NumberVectorDistanceFunction28
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction32
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction57
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction15
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction32
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedNumberVectorDistanceFunction8
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.external.DistanceParser2
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction8
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingSubspaceDistanceFunction2
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.NormalizedSimilarityFunction2
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFunction8
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction8
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.evaluation.Evaluator2
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.evaluation.scores.ScoreEvaluation4
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.index.IndexFactory6
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.index.KNNIndex23
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.index.RKNNIndex9
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.index.RangeIndex15
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.index.preprocessed.LocalProjectionIndex$Factory4
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.index.preprocessed.localpca.FilteredLocalPCAIndex$Factory1
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj.SubspaceProjectionIndex$Factory2
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert.ReinsertStrategy2
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.math.statistics.dependence.DependenceMeasure12
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.result.ResultHandler3
-rw-r--r--src/META-INF/elki/de.lmu.ifi.dbs.elki.visualization.visualizers.VisFactory2
-rw-r--r--src/de/lmu/ifi/dbs/elki/KDDTask.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/APRIORI.java356
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/AbstractAlgorithm.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/AbstractDistanceBasedAlgorithm.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/AbstractPrimitiveDistanceBasedAlgorithm.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/Algorithm.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/DependencyDerivator.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/DistanceBasedAlgorithm.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/DummyAlgorithm.java9
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/KNNDistanceOrder.java184
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/KNNDistancesSampler.java268
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/KNNJoin.java187
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/MaterializeDistances.java66
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/NullAlgorithm.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/benchmark/KNNBenchmarkAlgorithm.java106
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/benchmark/RangeQueryBenchmarkAlgorithm.java121
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/benchmark/ValidateApproximativeKNNIndex.java81
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/benchmark/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/classification/AbstractClassifier.java75
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/classification/Classifier.java62
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/classification/KNNClassifier.java204
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/classification/PriorProbabilityClassifier.java135
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/classification/package-info.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/distance/package-info.java)6
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/AbstractProjectedClustering.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/AbstractProjectedDBSCAN.java445
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/CanopyPreClustering.java78
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/ClusteringAlgorithm.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/DBSCAN.java46
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/NaiveMeanShiftClustering.java93
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICS.java319
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/SNNClustering.java66
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/AffinityPropagationClusteringAlgorithm.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/AffinityPropagationInitialization.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/DistanceBasedInitializationWithMedian.java34
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/SimilarityBasedInitializationWithMedian.java25
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/biclustering/AbstractBiclustering.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/biclustering/ChengAndChurch.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/biclustering/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/CASH.java196
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/COPAC.java402
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/ERiC.java393
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/FourC.java239
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/HiCO.java353
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/LMCLUS.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/ORCLUS.java71
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/CASHInterval.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/CASHIntervalSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/ParameterizationFunction.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/package-info.java36
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/AbstractEMModelFactory.java89
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/DiagonalGaussianModel.java200
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/DiagonalGaussianModelFactory.java88
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/EM.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/clustering/EM.java)237
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/EMClusterModel.java81
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/EMClusterModelFactory.java (renamed from src/de/lmu/ifi/dbs/elki/database/query/AbstractDataBasedQuery.java)43
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/MultivariateGaussianModel.java212
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/MultivariateGaussianModelFactory.java89
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/SphericalGaussianModel.java190
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/SphericalGaussianModelFactory.java88
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/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/algorithm/clustering/gdbscan/AbstractRangeQueryNeighborPredicate.java217
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/COPACNeighborPredicate.java310
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/CorePredicate.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/ERiCNeighborPredicate.java314
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/EpsilonNeighborPredicate.java51
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/FourCCorePredicate.java133
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/FourCNeighborPredicate.java240
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/GeneralizedDBSCAN.java81
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/LSDBC.java351
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/MinPtsCorePredicate.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/NeighborPredicate.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/PreDeConCorePredicate.java132
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/PreDeConNeighborPredicate.java285
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/package-info.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/CentroidLinkageMethod.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/CompleteLinkageMethod.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/ExtractFlatClusteringFromHierarchy.java414
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/GroupAverageLinkageMethod.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/HierarchicalClusteringAlgorithm.java16
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/LinkageMethod.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/MedianLinkageMethod.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/NaiveAgglomerativeHierarchicalClustering.java96
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/PointerHierarchyRepresentationResult.java15
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/SLINK.java186
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/SingleLinkageMethod.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/WardLinkageMethod.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/WeightedAverageLinkageMethod.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/AbstractKMeans.java224
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/BestOfMultipleKMeans.java70
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/CLARA.java244
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeans.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansBatchedLloyd.java137
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansBisecting.java31
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansHybridLloydMacQueen.java71
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansLloyd.java64
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansMacQueen.java70
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMediansLloyd.java295
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMedoidsEM.java40
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMedoidsPAM.java163
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/SingleAssignmentKMeans.java130
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/XMeans.java393
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/AbstractKMeansInitialization.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/AbstractKMeansInitialization.java)12
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/FarthestPointsInitialMeans.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/FarthestPointsInitialMeans.java)382
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/FarthestSumPointsInitialMeans.java176
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/FirstKInitialMeans.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/FirstKInitialMeans.java)172
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/KMeansInitialization.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansInitialization.java)14
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/KMeansPlusPlusInitialMeans.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansPlusPlusInitialMeans.java)164
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/KMedoidsInitialization.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMedoidsInitialization.java)7
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/PAMInitialMeans.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/PAMInitialMeans.java)47
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/PredefinedInitialMeans.java161
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/RandomlyChosenInitialMeans.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/RandomlyChosenInitialMeans.java)166
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/RandomlyGeneratedInitialMeans.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/RandomlyGeneratedInitialMeans.java)29
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/SampleKMeansInitialization.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/SampleKMeansInitialization.java)63
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/parallel/KMeansProcessor.java272
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/parallel/ParallelLloydKMeans.java154
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/parallel/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/AbstractKMeansQualityMeasure.java239
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/AkaikeInformationCriterion.java74
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/BayesianInformationCriterion.java77
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/BayesianInformationCriterionZhao.java67
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/KMeansQualityMeasure.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/WithinClusterMeanDistanceQualityMeasure.java65
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/WithinClusterVarianceQualityMeasure.java61
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/onedimensional/KNNKernelDensityMinimaClustering.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/onedimensional/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/ClusterOrderEntry.java (renamed from src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderEntry.java)19
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/ClusterOrderResult.java229
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/CorrelationClusterOrderEntry.java170
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/DeLiClu.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/clustering/DeLiClu.java)120
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/DoubleDistanceClusterOrderEntry.java (renamed from src/de/lmu/ifi/dbs/elki/result/optics/DoubleDistanceClusterOrderEntry.java)39
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/GeneralizedOPTICS.java154
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/OPTICS.java238
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/OPTICSTypeAlgorithm.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICSTypeAlgorithm.java)20
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/OPTICSXi.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICSXi.java)118
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/package-info.java33
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/CLIQUE.java24
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/DOC.java151
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/DiSH.java681
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/HiSC.java280
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/P3C.java135
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/PROCLUS.java546
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/PreDeCon.java225
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/SUBCLU.java154
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/SubspaceClusteringAlgorithm.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/CLIQUEInterval.java (renamed from src/de/lmu/ifi/dbs/elki/data/Interval.java)12
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/CLIQUESubspace.java24
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/CLIQUEUnit.java46
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/package-info.java37
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelClustering.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelHierarchicalClustering.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelOrAllInOneClustering.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByModelClustering.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/TrivialAllInOne.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/TrivialAllNoise.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/APRIORI.java619
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/DenseItemset.java129
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/Itemset.java92
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/OneItemset.java126
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/SmallDenseItemset.java125
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/SparseItemset.java175
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/COP.java36
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/DWOF.java82
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/GaussianModel.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/GaussianUniformMixture.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/KNNWeightOutlier.java189
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/OPTICSOF.java51
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/OutlierAlgorithm.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/ReferenceBasedOutlierDetection.java337
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/SimpleCOP.java35
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/anglebased/ABOD.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/outlier/ABOD.java)58
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/anglebased/FastABOD.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/outlier/FastABOD.java)60
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/anglebased/LBABOD.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/outlier/LBABOD.java)35
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/anglebased/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/EMOutlier.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/outlier/EMOutlier.java)40
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/KMeansOutlierDetection.java178
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/SilhouetteOutlierDetection.java253
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/AbstractDBOutlier.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/outlier/AbstractDBOutlier.java)59
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/DBOutlierDetection.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/outlier/DBOutlierDetection.java)72
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/DBOutlierScore.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/outlier/DBOutlierScore.java)39
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/HilOut.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/outlier/HilOut.java)285
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/KNNOutlier.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/outlier/KNNOutlier.java)97
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/KNNWeightOutlier.java205
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/ODIN.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/outlier/ODIN.java)37
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/ReferenceBasedOutlierDetection.java325
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/package-info.java30
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/KNNWeightProcessor.java118
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/ParallelKNNOutlier.java181
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/ParallelKNNWeightOutlier.java187
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/ALOCI.java71
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/COF.java276
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/FlexibleLOF.java271
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/INFLO.java232
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/KDEOS.java445
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LDF.java129
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LDOF.java64
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LOCI.java331
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LOF.java147
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LoOP.java372
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/OnlineLOF.java192
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/SimpleKernelDensityLOF.java123
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/SimplifiedLOF.java198
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/LOFProcessor.java119
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/LRDProcessor.java103
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/ParallelLOF.java208
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/ParallelSimplifiedLOF.java197
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/SimplifiedLRDProcessor.java97
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/package-info.java44
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/ExternalDoubleOutlierScore.java9
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/FeatureBagging.java60
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/HiCS.java59
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/RescaleMetaOutlierAlgorithm.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/SimpleOutlierEnsemble.java28
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/AbstractDistanceBasedSpatialOutlier.java19
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/AbstractNeighborhoodOutlier.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuGLSBackwardSearchAlgorithm.java30
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMeanMultipleAttributes.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMedianAlgorithm.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMedianMultipleAttributes.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMoranScatterplotOutlier.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuRandomWalkEC.java36
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuScatterplotOutlier.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuZTestOutlier.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/SLOM.java22
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/SOF.java22
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/TrimmedMeanApproach.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/AbstractPrecomputedNeighborhood.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/ExtendedNeighborhood.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/ExternalNeighborhood.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/NeighborSetPredicate.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/PrecomputedKNearestNeighborNeighborhood.java80
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/LinearWeightedExtendedNeighborhood.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/UnweightedNeighborhoodAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/WeightedNeighborSetPredicate.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/AbstractAggarwalYuOutlier.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/outlier/AbstractAggarwalYuOutlier.java)92
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/AggarwalYuEvolutionary.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/outlier/AggarwalYuEvolutionary.java)247
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/AggarwalYuNaive.java (renamed from src/de/lmu/ifi/dbs/elki/algorithm/outlier/AggarwalYuNaive.java)28
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/OUTRES.java106
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/OutRankS1.java37
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/SOD.java109
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/svm/LibSVMOneClassOutlierDetection.java279
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/svm/package-info.java (renamed from test/de/lmu/ifi/dbs/elki/JUnit4Test.java)22
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/ByLabelOutlier.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialAllOutlier.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialAverageCoordinateOutlier.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialGeneratedOutlier.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialNoOutlier.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/statistics/AddSingleScale.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/statistics/AveragePrecisionAtK.java124
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/statistics/DistanceStatisticsWithClasses.java58
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/statistics/EvaluateRankingQuality.java34
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/statistics/HopkinsStatisticClusteringTendency.java416
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/statistics/MeanAveragePrecisionForDistance.java388
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/statistics/RankingQualityHistogram.java34
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/statistics/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/AbstractApplication.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/ClassifierHoldoutEvaluationTask.java253
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/ComputeSingleColorHistogram.java166
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/ConvertToBundleApplication.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/ELKILauncher.java40
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/GeneratorXMLSpec.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/KDDCLIApplication.java9
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceInOnDiskMatrix.java74
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceKNNLists.java54
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceRangeQueries.java68
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/cache/CacheFloatDistanceInOnDiskMatrix.java80
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/cache/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/geo/VisualizeGeodesicDistances.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/geo/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/greedyensemble/ComputeKNNOutlierScores.java58
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/greedyensemble/GreedyEnsembleExperiment.java210
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/greedyensemble/VisualizePairwiseGainMatrix.java69
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/greedyensemble/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/internal/CheckELKIServices.java176
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/internal/CheckParameterizables.java278
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java313
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/internal/DocumentReferences.java153
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/internal/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/jsmap/JSONBuffer.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/jsmap/JSONResultHandler.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/jsmap/JSONWebServer.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/jsmap/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/AbstractNumberVector.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/Arithmetic.java70
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/Bit.java31
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/BitVector.java309
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/ByteVector.java42
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/ClassLabel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/Cluster.java43
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/Clustering.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/DoubleVector.java32
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/ExternalID.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/FeatureVector.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/FloatVector.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/HierarchicalClassLabel.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/HyperBoundingBox.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/IntegerVector.java21
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/LabelList.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/ModifiableHyperBoundingBox.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/NumberVector.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/OneDimensionalDoubleVector.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/RationalNumber.java401
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/ShortVector.java46
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/SimpleClassLabel.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/SparseByteVector.java40
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/SparseDoubleVector.java35
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/SparseFeatureVector.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/SparseFloatVector.java35
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/SparseIntegerVector.java36
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/SparseNumberVector.java9
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/SparseShortVector.java35
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/Subspace.java68
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/VectorUtil.java183
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/images/AbstractComputeColorHistogram.java99
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/images/BlendComposite.java437
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/images/ComputeColorHistogram.java52
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/images/ComputeHSBColorHistogram.java149
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveRGBColorHistogram.java101
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/images/ImageUtil.java62
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/AbstractModel.java (renamed from src/de/lmu/ifi/dbs/elki/data/model/BaseModel.java)15
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/BiclusterModel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/BiclusterWithInversionsModel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/ClusterModel.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/CoreObjectsModel.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/CorrelationAnalysisSolution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/CorrelationModel.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/DendrogramModel.java60
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/DimensionModel.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/EMModel.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/KMeansModel.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/LinearEquationModel.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/MeanModel.java41
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/MedoidModel.java33
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/Model.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/ModelUtil.java113
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/OPTICSModel.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/PrototypeModel.java74
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/SubspaceModel.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/package-info.java35
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/package-info.java43
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/projection/FeatureSelection.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/projection/LatLngToECEFProjection.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/projection/LngLatToECEFProjection.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/projection/NumericalFeatureSelection.java15
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/projection/Projection.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/projection/RandomProjection.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/projection/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/spatial/Polygon.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/spatial/PolygonsObject.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/spatial/SpatialComparable.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/spatial/SpatialSingleMaxComparator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/spatial/SpatialSingleMeanComparator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/spatial/SpatialSingleMinComparator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/spatial/SpatialUtil.java106
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/spatial/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterface.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterfaceDynamic.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorSingleCluster.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorStatic.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/type/AlternativeTypeInformation.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/type/CombinedTypeInformation.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/type/MultivariateSeriesTypeInformation.java93
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/type/NoSupportedDataTypeException.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/type/SimpleTypeInformation.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/type/TypeInformation.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/type/TypeInformationSerializer.java28
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/type/TypeUtil.java50
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/type/VectorFieldTypeInformation.java76
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/type/VectorTypeInformation.java84
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/type/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/AbstractDatabase.java37
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/Database.java18
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/DatabaseEventManager.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/HashmapDatabase.java99
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ProxyDatabase.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/QueryUtil.java99
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/StaticArrayDatabase.java73
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/UpdatableDatabase.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/DBIDDataStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/DataStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreEvent.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreFactory.java9
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreIDMap.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreListener.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreUtil.java67
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/DoubleDataStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/IntegerDataStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/RecordStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/WritableDBIDDataStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/WritableDataStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDataStore.java16
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDistanceDataStore.java65
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/WritableIntegerDataStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/WritableRecordStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDBIDStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleDistanceStore.java133
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleStore.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayIntegerStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayRecordStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDBIDStore.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleDistanceStore.java111
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleStore.java24
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDIntegerStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDRecordStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapRecordStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/MemoryDataStoreFactory.java34
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/memory/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/datastore/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/ArrayDBIDs.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/ArrayModifiableDBIDs.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/ArrayStaticDBIDs.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DBID.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayIter.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayMIter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DBIDFactory.java76
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DBIDIter.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DBIDMIter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DBIDPair.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DBIDRange.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DBIDRef.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DBIDUtil.java210
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DBIDVar.java28
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DBIDs.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDList.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDList.java)30
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDListIter.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDListIter.java)41
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDPair.java35
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/EmptyDBIDs.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/HashSetDBIDs.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/HashSetModifiableDBIDs.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/KNNHeap.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/distance/KNNHeap.java)39
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/KNNList.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/distance/KNNList.java)16
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/ModifiableDBIDs.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/ModifiableDoubleDBIDList.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/distance/ModifiableDistanceDBIDList.java)27
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/SetDBIDs.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/StaticDBIDs.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDPairList.java217
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceKNNHeap.java101
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/generic/AbstractKNNHeap.java93
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/generic/DistanceDBIDPairKNNHeap.java106
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/generic/DistanceDBIDPairKNNList.java211
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNHeap.java218
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNList.java257
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNListHeap.java289
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/generic/GenericDistanceDBIDList.java206
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/generic/KNNSubList.java72
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/generic/MaskedDBIDs.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableArrayDBIDs.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableDBIDs.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/generic/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/AbstractIntegerDBIDFactory.java74
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayModifiableIntegerDBIDs.java28
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayStaticIntegerDBIDs.java30
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DistanceIntegerDBIDPair.java101
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPair.java110
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairKNNListHeap.java339
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDKNNHeap.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNHeap.java)111
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDKNNList.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNList.java)30
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDList.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDList.java)96
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDListIter.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDListIter.java)12
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDListKNNHeap.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDSortedKNNList.java)45
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPair.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDoubleDBIDPair.java)19
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPairKNNListHeap.java286
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPairList.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairList.java)117
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayDBIDs.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayStaticDBIDs.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBID.java24
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayIter.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayMIter.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayQuickSort.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDIter.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDKNNList.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDList.java)18
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDKNNSubList.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceKNNSubList.java)77
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDMIter.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDPair.java94
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRange.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRef.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDVar.java78
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDs.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/ReusingDBIDFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/SimpleDBIDFactory.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/TrivialDBIDFactory.java22
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveHashSetModifiableDBIDs.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerArrayDBIDs.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerDBIDs.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/package-info.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/DatabaseQuery.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/DistanceSimilarityQuery.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/LinearScanQuery.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDatabaseDistanceQuery.java25
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDistanceQuery.java57
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDDistanceQuery.java15
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDRangeDistanceQuery.java74
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/distance/DistanceQuery.java48
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceQuery.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceSimilarityQuery.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialDistanceQuery.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialPrimitiveDistanceQuery.java16
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/distance/package-info.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/knn/AbstractDistanceKNNQuery.java31
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/knn/DoubleOptimizedDistanceKNNQuery.java91
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/knn/KNNQuery.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanDistanceKNNQuery.java81
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanEuclideanDistanceKNNQuery.java141
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanPrimitiveDistanceKNNQuery.java103
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/knn/PreprocessorKNNQuery.java64
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/knn/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/range/AbstractDistanceRangeQuery.java31
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/range/DoubleOptimizedDistanceRangeQuery.java92
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanDistanceRangeQuery.java29
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanEuclideanDistanceRangeQuery.java104
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanPrimitiveDistanceRangeQuery.java62
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/range/RangeQuery.java21
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/range/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/rknn/AbstractRKNNQuery.java23
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/rknn/LinearScanRKNNQuery.java68
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/rknn/PreprocessorRKNNQuery.java38
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/rknn/RKNNQuery.java16
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/rknn/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractDBIDSimilarityQuery.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractSimilarityQuery.java30
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/similarity/PrimitiveSimilarityQuery.java43
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/similarity/SimilarityQuery.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/query/similarity/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/relation/ConvertToStringView.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/relation/DBIDView.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/relation/DoubleRelation.java (renamed from src/de/lmu/ifi/dbs/elki/database/datastore/DoubleDistanceDataStore.java)44
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/relation/MaterializedDoubleRelation.java209
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/relation/MaterializedRelation.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/relation/ProjectedView.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/relation/ProxyView.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/relation/Relation.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/relation/RelationUtil.java244
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/relation/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/AbstractDatabaseConnection.java102
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/ArrayAdapterDatabaseConnection.java19
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/BundleDatabaseConnection.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/ConcatenateFilesDatabaseConnection.java37
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/DBIDRangeDatabaseConnection.java21
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/DatabaseConnection.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/EmptyDatabaseConnection.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/ExternalIDJoinDatabaseConnection.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/FileBasedDatabaseConnection.java47
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/GeneratorXMLDatabaseConnection.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/InputStreamDatabaseConnection.java48
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/LabelJoinDatabaseConnection.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/MultipleObjectsBundleDatabaseConnection.java54
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/PresortedBlindJoinDatabaseConnection.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/RandomDoubleVectorDatabaseConnection.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleMeta.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleReader.java113
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleStreamSource.java29
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleWriter.java74
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/bundle/MultipleObjectsBundle.java102
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/bundle/ObjectBundle.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/bundle/SingleObjectBundle.java34
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/bundle/StreamFromBundle.java23
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/bundle/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractConversionFilter.java23
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractStreamConversionFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractStreamFilter.java31
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractVectorConversionFilter.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractVectorStreamConversionFilter.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/FilterUtil.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/FixedDBIDsFilter.java58
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/NoOpFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/ObjectFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/StreamFilter.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/DropNaNFilter.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/DropNaNFilter.java)56
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/NoMissingValuesFilter.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/NoMissingValuesFilter.java)9
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/ReplaceNaNWithRandomFilter.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/ReplaceNaNWithRandomFilter.java)65
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/VectorDimensionalityFilter.java219
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AbstractNormalization.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AbstractStreamNormalization.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/NonNumericFeaturesException.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/Normalization.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/TFIDFNormalization.java77
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseBetaNormalization.java326
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseCDFNormalization.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseCDFNormalization.java)171
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseErfNormalization.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseErfNormalization.java)28
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseMADNormalization.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseMADNormalization.java)81
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseMeanNormalization.java207
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseMinMaxNormalization.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseMinMaxNormalization.java)58
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseVarianceNormalization.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseVarianceNormalization.java)96
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/IntegerRankTieNormalization.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/RankTieNormalization.java)83
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/InverseDocumentFrequencyNormalization.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/InverseDocumentFrequencyNormalization.java)19
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/HellingerHistogramNormalization.java97
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/InstanceMeanVarianceNormalization.java159
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/InstanceMinMaxNormalization.java177
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/LengthNormalization.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/LengthNormalization.java)37
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/Log1PlusNormalization.java119
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/package-info.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/selection/ByLabelFilter.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/ByLabelFilter.java)26
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/selection/RandomSamplingStreamFilter.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/RandomSamplingStreamFilter.java)9
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/selection/ShuffleObjectsFilter.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/ShuffleObjectsFilter.java)23
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/selection/SortByLabelFilter.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/SortByLabelFilter.java)19
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/selection/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/transform/AbstractSupervisedProjectionVectorFilter.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/transform/ClassicMultidimensionalScalingTransform.java33
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/transform/GlobalPrincipalComponentAnalysisTransform.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/transform/HistogramJitterFilter.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/HistogramJitterFilter.java)13
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/transform/LatLngToECEFFilter.java22
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/transform/LinearDiscriminantAnalysisFilter.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/transform/LngLatToECEFFilter.java22
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/transform/NumberVectorFeatureSelectionFilter.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/transform/NumberVectorRandomFeatureSelectionFilter.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/transform/PerturbationFilter.java436
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/transform/ProjectionFilter.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/transform/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/ClassLabelFilter.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/ClassLabelFilter.java)9
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/ClassLabelFromPatternFilter.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/ClassLabelFromPatternFilter.java)44
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/ExternalIDFilter.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/ExternalIDFilter.java)10
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/MultivariateTimeSeriesFilter.java124
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/SparseVectorFieldFilter.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/SparseVectorFieldFilter.java)12
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/SplitNumberVectorFilter.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/filter/SplitNumberVectorFilter.java)17
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/AbstractParser.java38
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/AbstractStreamingParser.java88
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/ArffParser.java48
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/BitVectorLabelParser.java95
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/CategorialDataAsNumberVectorParser.java28
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/ClusteringVectorParser.java268
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/DoubleVectorLabelParser.java104
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/FloatVectorLabelParser.java99
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/LibSVMFormatParser.java151
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/NumberVectorLabelParser.java194
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/Parser.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/SimplePolygonParser.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/SimpleTransactionParser.java200
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/SparseBitVectorLabelParser.java143
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/SparseFloatVectorLabelParser.java97
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/SparseNumberVectorLabelParser.java37
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/StreamingParser.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/StringParser.java23
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/TermFrequencyParser.java70
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/package-info.java6
-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.java40
-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.java51
-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.java27
-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
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/AutomaticEvaluation.java43
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/Evaluator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/NoAutomaticEvaluation.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/classification/ConfusionMatrix.java359
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/classification/ConfusionMatrixEvaluationResult.java92
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/AbstractHoldout.java118
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/DisjointCrossValidation.java144
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/Holdout.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/distance/ModifiableDoubleDistanceDBIDList.java)49
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/LeaveOneOut.java82
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/RandomizedCrossValidation.java141
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/RandomizedHoldout.java (renamed from src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveHSBColorHistogram.java)55
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/StratifiedCrossValidation.java162
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/TrainingAndTestSet.java89
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/classification/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/clustering/BCubed.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/clustering/ClusterContingencyTable.java87
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/clustering/EditDistance.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/clustering/Entropy.java38
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/clustering/EvaluateClustering.java92
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/clustering/PairCounting.java70
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/clustering/SetMatchingPurity.java53
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/clustering/internal/EvaluateSilhouette.java265
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/clustering/internal/package-info.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/clustering/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/ClusterPairSegmentAnalysis.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/Segment.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/Segments.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/histogram/ComputeOutlierHistogram.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/histogram/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/index/IndexPurity.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/index/IndexStatistics.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/index/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/outlier/JudgeOutlierScores.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierPrecisionAtKCurve.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierPrecisionRecallCurve.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierROCCurve.java35
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierRankingEvaluation.java211
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierSmROCCurve.java23
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierThresholdClustering.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/outlier/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/roc/ROC.java656
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/roc/package-info.java28
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/AbstractScoreEvaluation.java55
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/AveragePrecisionEvaluation.java76
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/MaximumF1Evaluation.java76
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/PrecisionAtKEvaluation.java127
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/ROCEvaluation.java147
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/ScoreEvaluation.java114
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DBIDRefIter.java39
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DBIDsTest.java59
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DecreasingVectorIter.java116
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DistanceResultAdapter.java92
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/FilteredDistanceResultAdapter.java76
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/IncreasingVectorIter.java116
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/OutlierScoreAdapter.java103
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/SimpleAdapter.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/generic/MergedDBIDs.java)70
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/VectorNonZero.java (renamed from src/de/lmu/ifi/dbs/elki/distance/distancefunction/DoubleNorm.java)25
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/VectorOverThreshold.java79
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/VectorZero.java (renamed from src/de/lmu/ifi/dbs/elki/math/linearalgebra/SubspaceProjectionResult.java)53
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/package-info.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/scores/package-info.java28
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/similaritymatrix/ComputeSimilarityMatrixImage.java29
-rw-r--r--src/de/lmu/ifi/dbs/elki/evaluation/similaritymatrix/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/GUIUtil.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractParameterConfigurator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractSingleParameterConfigurator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java148
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java150
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/ConfiguratorPanel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/EnumParameterConfigurator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/FileParameterConfigurator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/FlagParameterConfigurator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/ParameterConfigurator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/TextParameterConfigurator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/icons/StockIcon.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/icons/copyright-tango-project.txt2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/icons/edit-find.pngbin0 -> 617 bytes
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/icons/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/icons/package.pngbin0 -> 540 bytes
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/icons/system-search.pngbin0 -> 935 bytes
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/minigui/MiniGUI.java96
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/minigui/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/multistep/MultiStepGUI.java23
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/multistep/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/multistep/panels/AlgorithmTabPanel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/multistep/panels/EvaluationTabPanel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/multistep/panels/InputTabPanel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/multistep/panels/LoggingTabPanel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/multistep/panels/OutputTabPanel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/multistep/panels/ParameterTabPanel.java9
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/multistep/panels/SavedSettingsTabPanel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/multistep/panels/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/util/ClassTree.java211
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/util/DynamicParameters.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/util/LogPane.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/util/LogPanel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/util/ParameterTable.java461
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/util/ParametersModel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/util/SavedSettingsFile.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/util/TreePopup.java412
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/util/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/AbstractIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/AbstractRefiningIndex.java19
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/DistanceIndex.java (renamed from src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveDoubleSimilarityFunction.java)35
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/DynamicIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/Index.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/IndexFactory.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/KNNIndex.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/PagedIndexFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/RKNNIndex.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/RangeIndex.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/distancematrix/PrecomputedDistanceMatrix.java293
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/distancematrix/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/idistance/InMemoryIDistanceIndex.java559
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/idistance/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/invertedlist/InMemoryInvertedIndex.java474
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/invertedlist/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/lsh/InMemoryLSHIndex.java68
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/AbstractProjectedHashFunctionFamily.java (renamed from src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/AbstractHashFunctionFamily.java)15
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/EuclideanHashFunctionFamily.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/LocalitySensitiveHashFunctionFamily.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/ManhattanHashFunctionFamily.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/lsh/hashfunctions/LocalitySensitiveHashFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/lsh/hashfunctions/MultipleProjectionsLocalitySensitiveHashFunction.java34
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/lsh/hashfunctions/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/lsh/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/AbstractPreprocessorIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/LocalProjectionIndex.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/AbstractMaterializeKNNPreprocessor.java66
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/CachedDoubleDistanceKNNPreprocessor.java43
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNChangeEvent.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNJoinMaterializeKNNPreprocessor.java38
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNListener.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNAndRKNNPreprocessor.java170
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNPreprocessor.java147
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MetricalIndexApproximationMaterializeKNNPreprocessor.java54
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/PartitionApproximationMaterializeKNNPreprocessor.java49
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/RandomSampleKNNPreprocessor.java40
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/SpatialApproximationMaterializeKNNPreprocessor.java47
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/AbstractFilteredPCAIndex.java42
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/FilteredLocalPCAIndex.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/KNNQueryFilteredPCAIndex.java66
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/RangeQueryFilteredPCAIndex.java178
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/AbstractPreferenceVectorIndex.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java125
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/HiSCPreferenceVectorIndex.java43
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/PreferenceVectorIndex.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborPreprocessor.java41
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/AbstractSubspaceProjectionIndex.java272
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/FourCSubspaceIndex.java260
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/PreDeConSubspaceIndex.java254
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/SubspaceProjectionIndex.java74
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/projected/LatLngAsECEFIndex.java91
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/projected/LngLatAsECEFIndex.java36
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/projected/PINN.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/projected/ProjectedIndex.java177
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/projected/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/AbstractDirectoryEntry.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/AbstractLeafEntry.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/AbstractNode.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/BreadthFirstEnumeration.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/DirectoryEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/Entry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/IndexTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/IndexTreePath.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/LeafEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/Node.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexHeader.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexPathComponent.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/MetricalIndexTree.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTree.java111
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeFactory.java16
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeNode.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeDirectoryEntry.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeLeafEntry.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeSettings.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTree.java28
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnified.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnifiedFactory.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/MkTreeHeader.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/MkTreeSettings.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppDirectoryEntry.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppLeafEntry.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTree.java144
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeFactory.java22
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeIndex.java33
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeNode.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeSettings.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/PolynomialApproximation.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ApproximationLine.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPDirectoryEntry.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPLeafEntry.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java211
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeIndex.java63
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeNode.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCopTreeFactory.java22
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxDirectoryEntry.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxLeafEntry.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTree.java79
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeFactory.java22
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeIndex.java39
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeNode.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabDirectoryEntry.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabLeafEntry.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTree.java82
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeFactory.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeIndex.java43
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeNode.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTree.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeFactory.java22
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeIndex.java35
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeNode.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/DoubleDistanceMetricalIndexKNNQuery.java143
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/DoubleDistanceMetricalIndexRangeQuery.java137
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MTreeQueryUtil.java32
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexKNNQuery.java51
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexRangeQuery.java53
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MkTreeRKNNQuery.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/insert/MTreeInsert.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/insert/MinimumEnlargementInsert.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/insert/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/Assignments.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/DistanceEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MLBDistSplit.java16
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MMRadSplit.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MRadSplit.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MTreeSplit.java59
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/RandomSplit.java19
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/query/DoubleDistanceSearchCandidate.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/query/DoubleMTreeDistanceSearchCandidate.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/query/GenericDistanceSearchCandidate.java68
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/query/GenericMTreeDistanceSearchCandidate.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/query/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialDirectoryEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialIndexTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialNode.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPair.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPointLeafEntry.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/kd/MinimalisticMemoryKDTree.java82
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/kd/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/package-info.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeFactory.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeNode.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRTreeSettings.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/NonFlatRStarTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluDirectoryEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluLeafEntry.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluNode.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeFactory.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeIndex.java44
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTree.java228
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTreeFactory.java84
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTreeIndex.java203
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTreeNode.java81
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/package-info.java (renamed from src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/package-info.java)6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/EuclideanRStarTreeKNNQuery.java167
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/EuclideanRStarTreeRangeQuery.java120
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeKNNQuery.java243
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeRangeQuery.java131
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeKNNQuery.java (renamed from src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeKNNQuery.java)84
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeRangeQuery.java (renamed from src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeRangeQuery.java)64
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeUtil.java45
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNDirectoryEntry.java129
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNEntry.java49
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNLeafEntry.java129
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNNode.java96
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNTree.java672
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNTreeFactory.java120
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNTreeHeader.java101
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdkNNSettings.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceKNNList.java)35
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/package-info.java (renamed from src/de/lmu/ifi/dbs/elki/data/images/package-info.java)8
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeFactory.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeIndex.java21
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeNode.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/AbstractBulkSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/AdaptiveSortTileRecursiveBulkSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/BulkSplit.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/FileOrderBulkSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/MaxExtensionBulkSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/MaxExtensionSortTileRecursiveBulkSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/OneDimSortBulkSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SortTileRecursiveBulkSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SpatialSortBulkSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/ApproximativeLeastOverlapInsertionStrategy.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/CombinedInsertionStrategy.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/InsertionStrategy.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementInsertionStrategy.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementWithAreaInsertionStrategy.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastOverlapInsertionStrategy.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/LimitedReinsertOverflowTreatment.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/OverflowTreatment.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/SplitOnlyOverflowTreatment.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/AbstractPartialReinsert.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/CloseReinsert.java21
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/FarReinsert.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/ReinsertStrategy.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/AngTanLinearSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/GreeneSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeLinearSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeQuadraticSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/SplitStrategy.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/TopologicalSplitter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/NodeArrayAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/vafile/DAFile.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/vafile/PartialVAFile.java132
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/vafile/VAFile.java71
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/vafile/VALPNormDistance.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/vafile/VectorApproximation.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/vafile/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/CLISmartHandler.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/ELKILogRecord.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/ErrorFormatter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/Logging.java82
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/LoggingConfiguration.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/LoggingUtil.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/MessageFormatter.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/OutputStreamLogger.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/progress/AbstractProgress.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/progress/FiniteProgress.java9
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/progress/IndefiniteProgress.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/progress/MutableProgress.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/progress/Progress.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/progress/ProgressLogRecord.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/progress/ProgressTracker.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/progress/StepProgress.java24
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/progress/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/statistics/AbstractStatistic.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/statistics/AtomicLongCounter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/statistics/Counter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/statistics/DoubleStatistic.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/statistics/Duration.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/statistics/LongStatistic.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/statistics/MillisTimeDuration.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/statistics/NanoDuration.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/statistics/Statistic.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/statistics/StringStatistic.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/statistics/UnsynchronizedLongCounter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/logging/statistics/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/DoubleMinMax.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/IntegerMinMax.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/MathUtil.java457
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/Mean.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/MeanVariance.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/MeanVarianceMinMax.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/MinMax.java185
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/PearsonCorrelation.java76
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/Primes.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/SinCosTable.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/StatisticalMoments.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/analysis/package-info.java (renamed from src/de/lmu/ifi/dbs/elki/result/optics/package-info.java)8
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/CovarianceDimensionSimilarity.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarity.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarityMatrix.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HSMDimensionSimilarity.java73
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HiCSDimensionSimilarity.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/MCEDimensionSimilarity.java191
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SURFINGDimensionSimilarity.java37
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeDimensionSimilarity.java32
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeInversionDimensionSimilarity.java54
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geodesy/AbstractEarthModel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1858SpheroidEarthModel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1880SpheroidEarthModel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geodesy/EarthModel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geodesy/GRS67SpheroidEarthModel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geodesy/GRS80SpheroidEarthModel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geodesy/SphereUtil.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalCosineEarthModel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalHaversineEarthModel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalVincentyEarthModel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geodesy/WGS72SpheroidEarthModel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geodesy/WGS84SpheroidEarthModel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geometry/AlphaShape.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geometry/GrahamScanConvexHull2D.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geometry/PrimsMinimumSpanningTree.java50
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geometry/SweepHullDelaunay2D.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geometry/XYCurve.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geometry/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/AffineTransformation.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/Centroid.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/CholeskyDecomposition.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/CovarianceMatrix.java120
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenPair.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenvalueDecomposition.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/LUDecomposition.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/LinearEquationSystem.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/Matrix.java526
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectedCentroid.java32
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectionResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/QRDecomposition.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/SingularValueDecomposition.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/SortedEigenPairs.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/VMath.java284
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/Vector.java258
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunctionResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/GaussianFittingFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/LevenbergMarquardtMethod.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/package-info.java38
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/AbstractCovarianceMatrixBuilder.java18
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CompositeEigenPairFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CovarianceMatrixBuilder.java19
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/DropEigenPairFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/EigenPairFilter.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FilteredEigenPairs.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FirstNEigenPairFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/LimitEigenPairFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/NormalizingEigenPairFilter.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredAutotuningRunner.java91
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredRunner.java100
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCARunner.java36
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PercentageEigenPairFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/ProgressiveEigenPairFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RANSACCovarianceMatrixBuilder.java22
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RelativeEigenPairFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/SignificantEigenPairFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/StandardCovarianceMatrixBuilder.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeakEigenPairFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeightedCovarianceMatrixBuilder.java73
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/package-info.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ConstantWeight.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcStddevWeight.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcWeight.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialStddevWeight.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialWeight.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussStddevWeight.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussWeight.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseLinearWeight.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalStddevWeight.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalWeight.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/LinearWeight.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticStddevWeight.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticWeight.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/WeightFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AbstractRandomProjectionFamily.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AchlioptasRandomProjectionFamily.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/CauchyRandomProjectionFamily.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/GaussianRandomProjectionFamily.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomProjectionFamily.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomSubsetProjectionFamily.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/random/FastNonThreadsafeRandom.java (renamed from src/de/lmu/ifi/dbs/elki/utilities/UnsafeRandom.java)17
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/random/RandomFactory.java (renamed from src/de/lmu/ifi/dbs/elki/utilities/RandomFactory.java)8
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/random/XorShift1024NonThreadsafeRandom.java110
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/random/XorShift64NonThreadsafeRandom.java95
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/random/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/scales/LinearScale.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/scales/Scales.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/scales/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/AbstractSpatialSorter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/BinarySplitSpatialSorter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/HilbertSpatialSorter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/PeanoSpatialSorter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/SpatialSorter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveSpatialSorter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveTransformer.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/KernelDensityEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/LinearRegression.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/MultipleLinearRegression.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/PolynomialRegression.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/ProbabilityWeightedMoments.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/AbstractDependenceMeasure.java262
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/CorrelationDependenceMeasure.java141
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/DependenceMeasure.java98
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/DistanceCorrelationDependenceMeasure.java206
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HSMDependenceMeasure.java245
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HiCSDependenceMeasure.java243
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HoeffdingsDDependenceMeasure.java207
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/JensenShannonEquiwidthDependenceMeasure.java143
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/MCEDependenceMeasure.java274
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/MutualInformationEquiwidthDependenceMeasure.java137
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SURFINGDependenceMeasure.java133
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SlopeDependenceMeasure.java153
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SlopeInversionDependenceMeasure.java157
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SpearmanCorrelationDependenceMeasure.java78
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/dependence/package-info.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/BetaDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/CauchyDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiSquaredDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ConstantDistribution.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/Distribution.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentialDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentiallyModifiedGaussianDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GammaDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedExtremeValueDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticAlternateDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GumbelDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/HaltonUniformDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/KappaDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LaplaceDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaAlternateDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogLogisticDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogNormalDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogisticDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/NormalDistribution.java44
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/PoissonDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/RayleighDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/SkewGeneralizedNormalDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/StudentsTDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/UniformDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WaldDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WeibullDistribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractExpMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLMMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMOMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMeanVarianceEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMOMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMeanVarianceEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/CauchyMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/DistributionEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/EMGOlivierNorbergEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExpMADDistributionEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialLMMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMOMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMedianEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaChoiWetteEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaLMMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMOMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedExtremeValueLMMEstimator.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedLogisticAlternateLMMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelLMMEstimator.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LMMDistributionEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceLMMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMLEEstimator.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaAlternateExpMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaChoiWetteEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMOMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogLogisticMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMADDistributionEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMOMDistributionEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalBilkovaLMMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLMMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLevenbergMarquardtKDEEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMOMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticLMMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MADDistributionEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MOMDistributionEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MeanVarianceDistributionEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLMMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLevenbergMarquardtKDEEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMOMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighLMMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMLEEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/SkewGNormalLMMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformEnhancedMinMaxEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformLMMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMinMaxEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMLEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMOMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLMMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMOMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/BestFitEstimator.java36
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/TrimmedEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/WinsorisingEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/BiweightKernelDensityFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/CosineKernelDensityFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/EpanechnikovKernelDensityFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/GaussianKernelDensityFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/KernelDensityFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriangularKernelDensityFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TricubeKernelDensityFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriweightKernelDensityFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/UniformKernelDensityFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/tests/GoodnessOfFitTest.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/tests/KolmogorovSmirnovTest.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/tests/WelchTTest.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/tests/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/package-info.java15
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/Executor.java45
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/ParallelCore.java134
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/ParallelExecutor.java173
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/SingleThreadedExecutor.java114
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/package-info.java32
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/processor/AbstractDoubleProcessor.java85
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/processor/DoubleMinMaxProcessor.java127
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/processor/KDistanceProcessor.java111
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/processor/KNNProcessor.java130
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/processor/Processor.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDPair.java)49
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/processor/WriteDataStoreProcessor.java108
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/processor/WriteDoubleDataStoreProcessor.java106
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/processor/WriteIntegerDataStoreProcessor.java106
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/processor/package-info.java47
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/variables/SharedDouble.java86
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/variables/SharedInteger.java86
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/variables/SharedObject.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDListIter.java)58
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/variables/SharedVariable.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDPair.java)49
-rw-r--r--src/de/lmu/ifi/dbs/elki/parallel/variables/package-info.java28
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/AbstractExternalizablePage.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/AbstractPageFile.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/AbstractPageFileFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/AbstractStoringPageFile.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/DefaultPageHeader.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/ExternalizablePage.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/LRUCache.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/LRUCachePageFileFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/MemoryPageFile.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/MemoryPageFileFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/OnDiskArray.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/OnDiskArrayPageFile.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/OnDiskArrayPageFileFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/OnDiskUpperTriangleMatrix.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/Page.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/PageFile.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/PageFileFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/PageHeader.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/PersistentPageFile.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/PersistentPageFileFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/AbstractHierarchicalResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/AprioriResult.java52
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/BasicResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/ClusteringVectorDumper.java269
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/CollectionResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/DBIDSelection.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/EvaluationResult.java305
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/HierarchicalResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/HistogramResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/IterableResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/KMLOutputHandler.java350
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/KNNDistanceOrderResult.java63
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/LogResultStructureResultHandler.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/OrderingFromDataStore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/OrderingResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/PixmapResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/RangeSelection.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/ReferencePointsResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/Result.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/ResultAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/ResultHandler.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/ResultListener.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/ResultProcessor.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/ResultUtil.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/ResultWriter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/SamplingResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/ScalesResult.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/SelectionResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/SettingsResult.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java384
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/optics/GenericClusterOrderEntry.java147
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/outlier/BasicOutlierScoreMeta.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/outlier/InvertedOutlierScoreMeta.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/outlier/OrderingFromRelation.java52
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/outlier/OutlierScoreMeta.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/outlier/ProbabilisticOutlierScore.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/outlier/QuotientOutlierScoreMeta.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/outlier/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/MultipleFilesOutput.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/SingleStreamOutput.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/StreamFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriteable.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java147
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterStream.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterWriterInterface.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/naming/NamingScheme.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/naming/SimpleEnumeratingScheme.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/naming/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterDoubleDoublePair.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectArray.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectComment.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectInline.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterPair.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTextWriteable.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTriple.java73
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterVector.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/writers/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/Alias.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/Base64.java122
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/BitsUtil.java775
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/ClassGenericsUtil.java104
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/DatabaseUtil.java382
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/ELKIServiceLoader.java41
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/FileUtil.java58
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/FormatUtil.java732
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/HandlerList.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/InspectionUtil.java216
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/Util.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/QuickSelect.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayDBIDsAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayLikeUtil.java15
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/DoubleArrayAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ExtendedArray.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FeatureVectorAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FlatMatrixAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FloatArrayAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/IdentityArrayAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ListArrayAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberArrayAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberListArrayAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberVectorAdapter.java22
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SingleSubsetArrayAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetArrayAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetNumberArrayAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/TDoubleListAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/VectorAdapter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/DoubleIntegerArrayQuickSort.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerArrayQuickSort.java)145
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerArrayQuickSort.java197
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerComparator.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/hash/Unique.java132
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/hash/package-info.java30
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMaxHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMinHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMaxHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMinHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleHeap.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerHeap.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMaxHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMinHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongHeap.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMaxHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMinHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMaxHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMinHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectHeap.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMaxHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMinHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoublePriorityObject.java16
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/Heap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerHeap.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMaxHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMinHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectHeap.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMaxHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMinHeap.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerPriorityObject.java16
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ObjectHeap.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedHeap.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedUpdatableHeap.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedHeap.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedUpdatableHeap.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/UpdatableHeap.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/HashMapHierarchy.java23
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/Hierarchy.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/ModifiableHierarchy.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjDynamicHistogram.java51
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjStaticHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractStaticHistogram.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleArrayStaticHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleDynamicHistogram.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleStaticHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatDynamicHistogram.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatStaticHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/Histogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntArrayStaticHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntDynamicHistogram.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntStaticHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongArrayStaticHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongDynamicHistogram.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongStaticHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/MeanVarianceStaticHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ObjHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortDynamicHistogram.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortStaticHistogram.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayIter.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayListIter.java16
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/Iter.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/MIter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/documentation/Description.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/documentation/DocumentationUtil.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/documentation/Reference.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/documentation/Restricted.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/documentation/Title.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/documentation/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVoting.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingInverseMultiplicative.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMax.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMean.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMedian.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMin.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMultiplicative.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/ensemble/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/exceptions/APIViolationException.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/exceptions/AbortException.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/exceptions/ExceptionMessages.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/exceptions/NotImplementedException.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/exceptions/ObjectNotFoundException.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/exceptions/UnableToComplyException.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/exceptions/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/io/ByteArrayUtil.java (renamed from src/de/lmu/ifi/dbs/elki/persistent/ByteArrayUtil.java)4
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferInputStream.java (renamed from src/de/lmu/ifi/dbs/elki/persistent/ByteBufferInputStream.java)4
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferOutputStream.java (renamed from src/de/lmu/ifi/dbs/elki/persistent/ByteBufferOutputStream.java)4
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferSerializer.java (renamed from src/de/lmu/ifi/dbs/elki/persistent/ByteBufferSerializer.java)4
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/io/FixedSizeByteBufferSerializer.java (renamed from src/de/lmu/ifi/dbs/elki/persistent/FixedSizeByteBufferSerializer.java)5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/io/LineReader.java122
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/io/Tokenizer.java (renamed from src/de/lmu/ifi/dbs/elki/datasource/parser/Tokenizer.java)88
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/io/package-info.java29
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/AbstractParameterizer.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/InternalParameterizationErrors.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/NoParameterValueException.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionID.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionUtil.java16
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/ParameterException.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizable.java100
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizer.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnspecifiedParameterException.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnusedParameterException.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/WrongParameterValueException.java23
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AbstractNumberConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AllOrNoneMustBeSetGlobalConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/CommonConstraints.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualSizeGlobalConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualStringConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalListSizeConstraint.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalParameterConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalVectorListElementSizeConstraint.java9
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterEqualConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/IntervalConstraint.java217
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualGlobalConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessGlobalConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListEachConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListParameterNoDuplicateValueConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListSizeConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/NoDuplicateValueGlobalConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OneMustBeSetGlobalConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OnlyOneIsAllowedToBeSetGlobalConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterFlagGlobalConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/StringLengthConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/package-info.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/AbstractParameterization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ChainedParameterization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/EmptyParameterization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ListParameterization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/MergedParameterization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/Parameterization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/SerializedParameterization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/TrackParameters.java66
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/TrackedParameter.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/generic/DBIDIterAdapter.java)69
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/UnParameterization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/AbstractParameter.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassListParameter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassParameter.java64
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DistanceParameter.java149
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleListParameter.java28
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleParameter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/EnumParameter.java38
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileListParameter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileParameter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Flag.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntListParameter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntParameter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ListParameter.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/LongParameter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/NumberParameter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectListParameter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectParameter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Parameter.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/PatternParameter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/RandomParameter.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/StringParameter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/VectorListParameter.java43
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/package-info.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/pairs/CPair.java96
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/pairs/CTriple.java104
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleDoublePair.java25
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleIntPair.java25
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleObjPair.java18
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/pairs/FCPair.java83
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/pairs/IntDoublePair.java25
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/pairs/IntIntPair.java34
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/pairs/Pair.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/pairs/PairInterface.java53
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/pairs/PairUtil.java478
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/pairs/SCPair.java83
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/pairs/Triple.java215
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/pairs/package-info.java62
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/referencepoints/AxisBasedReferencePoints.java61
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/referencepoints/FullDatabaseReferencePoints.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/referencepoints/GridBasedReferencePoints.java119
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomGeneratedReferencePoints.java109
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomSampleReferencePoints.java125
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/referencepoints/ReferencePointsHeuristic.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/referencepoints/StarBasedReferencePoints.java85
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/referencepoints/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/ClipScaling.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/GammaScaling.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/IdentityScaling.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/LinearScaling.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/MinusLogScaling.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/ScalingFunction.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/StaticScalingFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/COPOutlierScaling.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/HeDESNormalizationOutlierScaling.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogGammaScaling.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogStandardDeviationScaling.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MixtureModelOutlierScalingFunction.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MultiplicativeInverseScaling.java16
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierGammaScaling.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierLinearScaling.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierMinusLogScaling.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierScalingFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierSqrtScaling.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/RankingPseudoOutlierScaling.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SigmoidOutlierScalingFunction.java18
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SqrtStandardDeviationScaling.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/StandardDeviationScaling.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/TopKOutlierScaling.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/scaling/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/xml/DOMCloner.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/xml/HTMLUtil.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeIterator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeListIterator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/xml/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/ExportVisualizations.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/VisualizationTask.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/VisualizerContext.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/VisualizerParameterizer.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/AddCSSClass.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/AttributeModifier.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/BatikUtil.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/CSSHoverClass.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/CloneInlineImages.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/DragableArea.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/JSVGSynchronizedCanvas.java83
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/JSVGUpdateSynchronizer.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/LazyCanvasResizer.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeAppendChild.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeReplaceChild.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeReplacer.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/RemoveCSSClass.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailRegistryEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailTranscoder.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/colors/ColorLibrary.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/colors/ListBasedColorLibrary.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/css/CSSClass.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/css/CSSClassManager.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/gui/ResultVisualizer.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/gui/ResultWindow.java49
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/gui/SimpleSVGViewer.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/gui/detail/DetailView.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/gui/overview/DetailViewSelectedEvent.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/gui/overview/LayerMap.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/gui/overview/OverviewPlot.java323
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/gui/overview/PlotItem.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/gui/overview/RectangleArranger.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorAdapter.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorFromStylingPolicy.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorStatic.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSCorrelationDimensionalityDistanceAdapter.java (renamed from src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSCorrelationDimensionalityDistance.java)23
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSCut.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSDistanceAdapter.java18
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSNumberDistanceAdapter.java (renamed from src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSNumberDistance.java)20
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSPlot.java63
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projections/AbstractFullProjection.java18
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projections/AbstractProjection.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projections/AbstractSimpleProjection.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projections/AffineProjection.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projections/CanvasSize.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projections/FullProjection.java18
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projections/OPTICSProjection.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projections/Projection.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projections/Projection1D.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projections/Projection2D.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projections/ProjectionParallel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projections/Simple1D.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projections/Simple2D.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projections/SimpleParallel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramFactory.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjector.java22
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjectorFactory.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/ParallelPlotFactory.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/ParallelPlotProjector.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/Projector.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/ProjectorFactory.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotFactory.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/savedialog/SVGSaveDialog.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/savedialog/SaveOptionsPanel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/ClassStylingPolicy.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/ClusterStylingPolicy.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/PropertiesBasedStyleLibrary.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/SingleObjectsStylingPolicy.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/StyleLibrary.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/StyleResult.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/StylingPolicy.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/lines/DashedLineStyleLibrary.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/lines/LineStyleLibrary.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/lines/SolidLineStyleLibrary.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/lines/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/marker/CircleMarkers.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/marker/MarkerLibrary.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/marker/MinimalMarkers.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/style/marker/PrettyMarkers.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/SVGArrow.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/SVGButton.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/SVGCheckbox.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/SVGCloneVisible.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/SVGEffects.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/SVGHyperCube.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/SVGHyperSphere.java15
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/SVGPath.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/SVGPlot.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/SVGScoreBar.java31
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/SVGSimpleLinearAxis.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/SVGUtil.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/UpdateRunner.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/UpdateSynchronizer.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/svg/VoronoiDraw.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/StaticVisualizationInstance.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisFactory.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/Visualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisualizerUtil.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/AbstractHistogramVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/ColoredHistogramVisualizer.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/AbstractOPTICSVisualization.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSClusterVisualization.java40
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotCutVisualization.java53
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotSelectionVisualization.java25
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotVisualizer.java16
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSSteepAreaVisualization.java53
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/CircleSegmentsVisualizer.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/SegmentsStylingPolicy.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AbstractParallelVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AxisReorderVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AxisVisibilityVisualization.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/LineVisualization.java18
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/ParallelAxisVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterOutlineVisualization.java175
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterParallelMeanVisualization.java21
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/RTreeParallelVisualization.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionAxisRangeVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionLineVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolAxisRangeVisualization.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolLineVisualization.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractScatterplotVisualization.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractTooltipVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AxisVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/MarkerVisualization.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/PolygonVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/ReferencePointsVisualization.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipScoreVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipStringVisualization.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterHullVisualization.java69
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterMeanVisualization.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterOrderVisualization.java16
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/EMClusterVisualization.java33
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/VoronoiVisualization.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/density/DensityEstimationOverlay.java9
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeMBRVisualization.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeSphereVisualization.java65
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/BubbleVisualization.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/COPVectorVisualization.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/DistanceFunctionVisualization.java92
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/MoveObjectsToolVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolCubeVisualization.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolDotVisualization.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailThread.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/EvaluationVisualization.java (renamed from src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisualization.java)97
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisualization.java19
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/LabelVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/PixmapVisualizer.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisualization.java32
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SimilarityMatrixVisualizer.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/XYCurveVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/workflow/AlgorithmStep.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/workflow/EvaluationStep.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/workflow/InputStep.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/workflow/LoggingStep.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/workflow/OutputStep.java23
-rw-r--r--src/de/lmu/ifi/dbs/elki/workflow/WorkflowStep.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/workflow/package-info.java2
-rw-r--r--src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering1.java59
-rw-r--r--src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering2.java26
-rw-r--r--src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering3.java82
-rw-r--r--src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering4.java80
-rw-r--r--src/tutorial/clustering/SameSizeKMeansAlgorithm.java51
-rw-r--r--src/tutorial/clustering/package-info.java2
-rw-r--r--src/tutorial/distancefunction/MultiLPNorm.java12
-rw-r--r--src/tutorial/distancefunction/TutorialDistanceFunction.java14
-rw-r--r--src/tutorial/distancefunction/package-info.java2
-rw-r--r--src/tutorial/outlier/DistanceStddevOutlier.java50
-rw-r--r--src/tutorial/outlier/ODIN.java26
-rw-r--r--src/tutorial/outlier/SimpleScoreDumper.java8
-rw-r--r--src/tutorial/package-info.java2
-rw-r--r--test/de/lmu/ifi/dbs/elki/AllTests.java60
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/AbstractSimpleAlgorithmTest.java242
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/TestKNNJoin.java215
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestDBSCANResults.java144
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestDeLiCluResults.java90
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestEMResults.java70
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestOPTICSResults.java71
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestSNNClusteringResults.java72
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestCASHResults.java96
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestCOPACResults.java114
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestERiCResults.java130
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestFourCResults.java98
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestORCLUSResults.java98
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/TestNaiveAgglomerativeHierarchicalClustering.java140
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/TestSLINKResults.java75
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/TestKMeansBisecting.java90
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/TestKMeansQualityMeasure.java110
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/TestKMeansResults.java163
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestCLIQUEResults.java98
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestDiSHResults.java94
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestP3C.java84
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestPROCLUSResults.java99
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestPreDeConResults.java109
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestSUBCLUResults.java98
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestABOD.java60
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestAggarwalYuEvolutionary.java63
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestAggarwalYuNaive.java61
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestDBOutlierDetection.java62
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestDBOutlierScore.java61
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestFastABOD.java60
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestGaussianModel.java59
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestGaussianUniformMixture.java59
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestKNNOutlier.java61
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestKNNWeightOutlier.java61
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestLBABOD.java62
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestOPTICSOF.java62
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestReferenceBasedOutlierDetection.java63
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestINFLO.java62
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLDOF.java62
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLOCI.java62
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLOF.java62
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLoOP.java62
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestOnlineLOF.java168
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/TestFeatureBagging.java84
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/TestHiCS.java88
-rw-r--r--test/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/TestSOD.java63
-rw-r--r--test/de/lmu/ifi/dbs/elki/data/spatial/TestPolygon.java74
-rw-r--r--test/de/lmu/ifi/dbs/elki/database/TestRelationSorting.java91
-rw-r--r--test/de/lmu/ifi/dbs/elki/datasource/parser/TestTermFrequencyParser.java129
-rw-r--r--test/de/lmu/ifi/dbs/elki/datasource/parser/TestTokenizer.java133
-rw-r--r--test/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDistanceFunctionTest.java154
-rw-r--r--test/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/LevenshteinDistanceFunctionTest.java66
-rw-r--r--test/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/NormalizedLevenshteinDistanceFunctionTest.java66
-rw-r--r--test/de/lmu/ifi/dbs/elki/evaluation/paircounting/TestClusterContingencyTable.java107
-rw-r--r--test/de/lmu/ifi/dbs/elki/evaluation/roc/TestComputeROC.java73
-rw-r--r--test/de/lmu/ifi/dbs/elki/index/TestIndexStructures.java233
-rw-r--r--test/de/lmu/ifi/dbs/elki/index/preprocessed/TestMaterializedKNNAndRKNNPreprocessor.java213
-rw-r--r--test/de/lmu/ifi/dbs/elki/logging/TestOutputStreamLogger.java62
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/TestAffineTransformation.java242
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/TestKernelDensityFitting.java166
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/TestLevenbergMarquardtGaussianFitting.java99
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/TestMathUtil.java104
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/TestMatrix.java89
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/TestSinCosTable.java50
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/TestSlidingVariance.java68
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/TestStatisticalMoments.java120
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/TestWeightFunctions.java75
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/geodesy/TestEarthModels.java385
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/geometry/TestPrimsMinimumSpanningTree.java76
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/scales/TestLinearScale.java64
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistributionTest.java71
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestBetaDistribution.java3939
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestChiSquaredDistribution.java826
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestExponentialDistribution.java826
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestExponentiallyModifiedGaussianDistribution.java110
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGammaDistribution.java1317
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGeneralizedExtremeValueDistribution.java1294
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGeneralizedLogisticDistribution.java364
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGumbelDistribution.java672
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestLogGammaAlternateDistribution.java672
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestLogNormalDistribution.java518
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestLogisticDistribution.java210
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestNormalDistribution.java519
-rw-r--r--test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestWeibullDistribution.java1291
-rw-r--r--test/de/lmu/ifi/dbs/elki/persistent/TestByteArrayUtil.java110
-rw-r--r--test/de/lmu/ifi/dbs/elki/persistent/TestOnDiskArray.java120
-rw-r--r--test/de/lmu/ifi/dbs/elki/persistent/TestOnDiskUpperTriangleMatrix.java121
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/TestBitsUtil.java212
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/TestFormatUtil.java84
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/datastructures/TestQuickSelect.java112
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestDoubleHeap.java91
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestDoubleObjectHeaps.java91
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestHeap.java232
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestHeapPerformance.java127
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestIntegerHeap.java232
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestIntegerMinHeapPerformance.java124
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestTiedTopBoundedHeap.java95
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestTiedTopBoundedUpdatableHeap.java114
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestTopBoundedHeap.java64
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestUpdatableHeap.java88
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/TestHashMapHierarchy.java85
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/TestDoubleHistogram.java72
-rw-r--r--test/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/TestFlexiHistogram.java159
2182 files changed, 54735 insertions, 60252 deletions
diff --git a/LICENSE.txt b/license/LICENSE
index af4068b6..325fc642 100644
--- a/LICENSE.txt
+++ b/license/LICENSE
@@ -1,6 +1,6 @@
ELKI: Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2013 Lehr- und Forschungseinheit für Datenbanksysteme, Ludwig-Maximilians-Universität München
+Copyright (C) 2014 Lehr- und Forschungseinheit für Datenbanksysteme, Ludwig-Maximilians-Universität München
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
diff --git a/license/LICENSE-libsvm b/license/LICENSE-libsvm
new file mode 100644
index 00000000..a9a0b298
--- /dev/null
+++ b/license/LICENSE-libsvm
@@ -0,0 +1,30 @@
+Copyright (c) 2000-2012 Chih-Chung Chang and Chih-Jen Lin
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+3. Neither name of copyright holders nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/license/LICENSE-trove4j b/license/LICENSE-trove4j
new file mode 100644
index 00000000..c6f39202
--- /dev/null
+++ b/license/LICENSE-trove4j
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF
index 1746b30f..1408a47c 100644
--- a/src/META-INF/MANIFEST.MF
+++ b/src/META-INF/MANIFEST.MF
@@ -1,174 +1,6 @@
-Comment: ELKI: Environment for DeveLoping KDD-Applications Supported by Index-Structures
-
-Name: junit
-Comment: JUnit 4.5
-Implementation-Title: JUnit
-Implementation-Version: 4.5
-Implementation-Vendor: JUnit Contributors http://junit.sourceforge.net/
-Implementation-URL: http://junit.sourceforge.net/
-
-Name: org/junit
-Comment: JUnit 4.5
-Implementation-Title: JUnit
-Implementation-Version: 4.5
-Implementation-Vendor: JUnit Contributors http://junit.sourceforge.net/
-Implementation-URL: http://junit.sourceforge.net/
-
-Name: org/hamcrest
-Comment: JUnit 4.5
-Implementation-Title: JUnit
-Implementation-Version: 4.5
-Implementation-Vendor: JUnit Contributors http://junit.sourceforge.net/
-Implementation-URL: http://junit.sourceforge.net/
-
-Name: org/apache/batik
-Comment: Apache Batik http://xmlgraphics.apache.org/batik/
-Implementation-Title: Batik all-in-one JAR
-Implementation-Version: 1.7+r608262
-Implementation-Vendor: Apache Software Foundation
-Implementation-URL: http://xmlgraphics.apache.org/batik/
-
-Name: org/apache/xmlcommons/Version
-Comment: XmlCommonsExternal for http://xml.apache.org/ subproject's us
- e
-Implementation-Title: org.apache.xmlcommons.Version
-Implementation-Version: 1.4.01
-Implementation-Vendor: Apache Software Foundation
-Implementation-URL: http://xml.apache.org/commons/
-
-Name: org/xml/sax/
-Comment: xml-commons for http://xml.apache.org/ subproject's use
-Specification-Title: Simple API for XML
-Specification-Vendor: David Megginson
-Specification-Version: 2.0.2 (sax2r3)
-Implementation-Title: org.xml.sax
-Implementation-Version: 2.0.2
-Implementation-Vendor: David Megginson
-Implementation-URL: http://www.saxproject.org/
-
-Name: org/w3c/dom/
-Comment: xml-commons for http://xml.apache.org/ subproject's use
-Specification-Title: Document Object Model (DOM) Level 3 Core
-Specification-Vendor: World Wide Web Consortium
-Specification-Version: 1.0
-Implementation-Title: org.w3c.dom
-Implementation-Version: 1.0
-Implementation-Vendor: World Wide Web Consortium
-Implementation-URL: http://www.w3c.org/DOM/
-
-Name: org/w3c/dom/ls/
-Comment: xml-commons for http://xml.apache.org/ subproject's use
-Specification-Title: Document Object Model (DOM) Level 3 Load and Save
-Specification-Vendor: World Wide Web Consortium
-Specification-Version: 1.0
-Implementation-Title: org.w3c.dom.ls
-Implementation-Version: 1.0
-Implementation-Vendor: World Wide Web Consortium
-Implementation-URL: http://www.w3c.org/DOM/
-
-Name: javax/xml/stream/
-Comment: xml-commons for http://xml.apache.org/ subproject's use
-Specification-Title: Streaming API for XML (StAX) 1.0
-Specification-Vendor: BEA Systems, Inc.
-Specification-Version: 1.0
-Implementation-Title: javax.xml.stream
-Implementation-Version: 1.4.01
-Implementation-Vendor: Apache Software Foundation
-Implementation-URL: http://xml.apache.org/commons/
-
-Name: javax/xml/datatype/
-Comment: xml-commons for http://xml.apache.org/ subproject's use
-Specification-Title: Java API for XML Processing (JAXP) 1.4
-Specification-Vendor: Sun Microsystems Inc.
-Specification-Version: 1.4
-Implementation-Title: javax.xml.datatype
-Implementation-Version: 1.4.01
-Implementation-Vendor: Apache Software Foundation
-Implementation-URL: http://xml.apache.org/commons/
-
-Name: javax/xml/namespace/
-Comment: xml-commons for http://xml.apache.org/ subproject's use
-Specification-Title: Java API for XML Processing (JAXP) 1.4
-Specification-Vendor: Sun Microsystems Inc.
-Specification-Version: 1.4
-Implementation-Title: javax.xml.namespace
-Implementation-Version: 1.4.01
-Implementation-Vendor: Apache Software Foundation
-Implementation-URL: http://xml.apache.org/commons/
-
-Name: javax/xml/parsers/
-Comment: xml-commons for http://xml.apache.org/ subproject's use
-Specification-Title: Java API for XML Processing (JAXP) 1.4
-Specification-Vendor: Sun Microsystems Inc.
-Specification-Version: 1.4
-Implementation-Title: javax.xml.parsers
-Implementation-Version: 1.4.01
-Implementation-Vendor: Apache Software Foundation
-Implementation-URL: http://xml.apache.org/commons/
-
-Name: javax/xml/transform/
-Comment: xml-commons for http://xml.apache.org/ subproject's use
-Specification-Title: Java API for XML Processing (JAXP) 1.4
-Specification-Vendor: Sun Microsystems Inc.
-Specification-Version: 1.4
-Implementation-Title: javax.xml.transform
-Implementation-Version: 1.4.01
-Implementation-Vendor: Apache Software Foundation
-Implementation-URL: http://xml.apache.org/commons/
-
-Name: javax/xml/validation/
-Comment: xml-commons for http://xml.apache.org/ subproject's use
-Specification-Title: Java API for XML Processing (JAXP) 1.4
-Specification-Vendor: Sun Microsystems Inc.
-Specification-Version: 1.4
-Implementation-Title: javax.xml.validation
-Implementation-Version: 1.4.01
-Implementation-Vendor: Apache Software Foundation
-Implementation-URL: http://xml.apache.org/commons/
-
-Name: javax/xml/xpath/
-Comment: xml-commons for http://xml.apache.org/ subproject's use
-Specification-Title: Java API for XML Processing (JAXP) 1.4
-Specification-Vendor: Sun Microsystems Inc.
-Specification-Version: 1.4
-Implementation-Title: javax.xml.xpath
-Implementation-Version: 1.4.01
-Implementation-Vendor: Apache Software Foundation
-Implementation-URL: http://xml.apache.org/commons/
-
-Name: org/w3c/css/sac/
-Specification-Title: Simple API for CSS
-Specification-Version: 1.3
-Specification-Vendor: World Wide Web Consortium
-Specification-URL: http://www.w3.org/Style/CSS/SAC/
-Implementation-Title: org.w3c.css.sac
-Implementation-Version: 1.3
-Implementation-Vendor: World Wide Web Consortium
-Implementation-URL: http://www.w3.org/Style/CSS/SAC/
-
-Name: org/w3c/dom/smil/
-Specification-Title: Document Object Model (DOM) for Synchronized Mult
- imedia Integration Language (SMIL)
-Specification-Vendor: World Wide Web Consortium
-Specification-URL: http://www.w3.org/TR/SMIL2/
-Implementation-Title: org.w3c.dom.smil
-Implementation-Vendor: World Wide Web Consortium
-Implementation-URL: http://dev.w3.org/cvsweb/java/classes/org/w3c/dom/
- smil/
-
-Name: org/w3c/dom/svg/
-Specification-Title: Document Object Model (DOM) for Scalable Vector G
- raphics (SVG)
-Specification-Version: 1.1
-Specification-Vendor: World Wide Web Consortium
-Specification-URL: http://www.w3.org/TR/SVG11/
-Implementation-Title: org.w3c.dom.svg
-Implementation-Version: 1.1
-Implementation-Vendor: World Wide Web Consortium
-Implementation-URL: http://www.w3.org/TR/SVG11/java.html
-
-Name: gnu/trove
-Comment: GNU Trove
-Implementation-Title: Trove
-Implementation-Version: 3.0.1
-Implementation-URL: http://trove4j.sourceforge.net/
+Manifest-Version: 1.0
+Archiver-Version: Plexus Archiver
+Built-By: schube
+Created-By: Apache Maven 3.0.5
+Build-Jdk: 1.8.0_40-internal
+
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.AbstractPrimitiveDistanceBasedAlgorithm b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.AbstractPrimitiveDistanceBasedAlgorithm
index 8f43e0f7..8af2b257 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.AbstractPrimitiveDistanceBasedAlgorithm
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.AbstractPrimitiveDistanceBasedAlgorithm
@@ -1,7 +1,12 @@
de.lmu.ifi.dbs.elki.algorithm.DependencyDerivator
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansLloyd
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.parallel.ParallelLloydKMeans
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansMacQueen
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMediansLloyd
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansBatchedLloyd
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansHybridLloydMacQueen
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.SingleAssignmentKMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.XMeans
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.ReferenceBasedOutlierDetection
+de.lmu.ifi.dbs.elki.algorithm.statistics.HopkinsStatisticClusteringTendency
tutorial.clustering.SameSizeKMeansAlgorithm
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.Algorithm b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.Algorithm
index 5fc2ff24..6f64a557 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.Algorithm
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.Algorithm
@@ -1,25 +1,30 @@
de.lmu.ifi.dbs.elki.algorithm.NullAlgorithm
de.lmu.ifi.dbs.elki.algorithm.clustering.CanopyPreClustering
de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN
-de.lmu.ifi.dbs.elki.algorithm.clustering.DeLiClu
-de.lmu.ifi.dbs.elki.algorithm.clustering.EM
de.lmu.ifi.dbs.elki.algorithm.clustering.affinitypropagation.AffinityPropagationClusteringAlgorithm
+de.lmu.ifi.dbs.elki.algorithm.clustering.em.EM
de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.GeneralizedDBSCAN
+de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.LSDBC
de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical.ExtractFlatClusteringFromHierarchy
de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical.NaiveAgglomerativeHierarchicalClustering
de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical.SLINK
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansLloyd
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.parallel.ParallelLloydKMeans
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansMacQueen
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMediansLloyd
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMedoidsPAM
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMedoidsEM
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.CLARA
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.BestOfMultipleKMeans
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansBisecting
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansBatchedLloyd
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansHybridLloydMacQueen
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.SingleAssignmentKMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.XMeans
de.lmu.ifi.dbs.elki.algorithm.clustering.NaiveMeanShiftClustering
-de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICSXi
-de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICS
+de.lmu.ifi.dbs.elki.algorithm.clustering.optics.DeLiClu
+de.lmu.ifi.dbs.elki.algorithm.clustering.optics.OPTICSXi
+de.lmu.ifi.dbs.elki.algorithm.clustering.optics.OPTICS
de.lmu.ifi.dbs.elki.algorithm.clustering.SNNClustering
de.lmu.ifi.dbs.elki.algorithm.clustering.biclustering.ChengAndChurch
de.lmu.ifi.dbs.elki.algorithm.clustering.correlation.CASH
@@ -44,36 +49,45 @@ de.lmu.ifi.dbs.elki.algorithm.clustering.trivial.ByModelClustering
de.lmu.ifi.dbs.elki.algorithm.clustering.trivial.TrivialAllInOne
de.lmu.ifi.dbs.elki.algorithm.clustering.trivial.TrivialAllNoise
de.lmu.ifi.dbs.elki.algorithm.clustering.trivial.ByLabelOrAllInOneClustering
-de.lmu.ifi.dbs.elki.algorithm.outlier.ABOD
-de.lmu.ifi.dbs.elki.algorithm.outlier.FastABOD
-de.lmu.ifi.dbs.elki.algorithm.outlier.LBABOD
-de.lmu.ifi.dbs.elki.algorithm.outlier.AggarwalYuEvolutionary
-de.lmu.ifi.dbs.elki.algorithm.outlier.AggarwalYuNaive
+de.lmu.ifi.dbs.elki.algorithm.itemsetmining.APRIORI
+de.lmu.ifi.dbs.elki.algorithm.outlier.anglebased.ABOD
+de.lmu.ifi.dbs.elki.algorithm.outlier.anglebased.FastABOD
+de.lmu.ifi.dbs.elki.algorithm.outlier.anglebased.LBABOD
+de.lmu.ifi.dbs.elki.algorithm.outlier.clustering.EMOutlier
+de.lmu.ifi.dbs.elki.algorithm.outlier.clustering.KMeansOutlierDetection
+de.lmu.ifi.dbs.elki.algorithm.outlier.clustering.SilhouetteOutlierDetection
de.lmu.ifi.dbs.elki.algorithm.outlier.COP
-de.lmu.ifi.dbs.elki.algorithm.outlier.DBOutlierDetection
-de.lmu.ifi.dbs.elki.algorithm.outlier.DBOutlierScore
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.DBOutlierDetection
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.DBOutlierScore
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.HilOut
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.KNNOutlier
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.KNNWeightOutlier
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.ODIN
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.parallel.ParallelKNNOutlier
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.parallel.ParallelKNNWeightOutlier
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.ReferenceBasedOutlierDetection
de.lmu.ifi.dbs.elki.algorithm.outlier.DWOF
-de.lmu.ifi.dbs.elki.algorithm.outlier.EMOutlier
de.lmu.ifi.dbs.elki.algorithm.outlier.GaussianModel
de.lmu.ifi.dbs.elki.algorithm.outlier.GaussianUniformMixture
-de.lmu.ifi.dbs.elki.algorithm.outlier.HilOut
-de.lmu.ifi.dbs.elki.algorithm.outlier.KNNOutlier
-de.lmu.ifi.dbs.elki.algorithm.outlier.KNNWeightOutlier
-de.lmu.ifi.dbs.elki.algorithm.outlier.ODIN
de.lmu.ifi.dbs.elki.algorithm.outlier.OPTICSOF
-de.lmu.ifi.dbs.elki.algorithm.outlier.ReferenceBasedOutlierDetection
de.lmu.ifi.dbs.elki.algorithm.outlier.SimpleCOP
+de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOF
+de.lmu.ifi.dbs.elki.algorithm.outlier.lof.parallel.ParallelLOF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.ALOCI
+de.lmu.ifi.dbs.elki.algorithm.outlier.lof.COF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.FlexibleLOF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.INFLO
+de.lmu.ifi.dbs.elki.algorithm.outlier.lof.KDEOS
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LDF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LDOF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOCI
-de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LoOP
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.OnlineLOF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.SimplifiedLOF
+de.lmu.ifi.dbs.elki.algorithm.outlier.lof.parallel.ParallelSimplifiedLOF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.SimpleKernelDensityLOF
+de.lmu.ifi.dbs.elki.algorithm.outlier.subspace.AggarwalYuEvolutionary
+de.lmu.ifi.dbs.elki.algorithm.outlier.subspace.AggarwalYuNaive
de.lmu.ifi.dbs.elki.algorithm.outlier.subspace.OUTRES
de.lmu.ifi.dbs.elki.algorithm.outlier.subspace.OutRankS1
de.lmu.ifi.dbs.elki.algorithm.outlier.subspace.SOD
@@ -100,18 +114,21 @@ de.lmu.ifi.dbs.elki.algorithm.outlier.trivial.TrivialGeneratedOutlier
de.lmu.ifi.dbs.elki.algorithm.outlier.trivial.TrivialAverageCoordinateOutlier
de.lmu.ifi.dbs.elki.algorithm.statistics.AddSingleScale
de.lmu.ifi.dbs.elki.algorithm.statistics.AveragePrecisionAtK
+de.lmu.ifi.dbs.elki.algorithm.statistics.DistanceStatisticsWithClasses
de.lmu.ifi.dbs.elki.algorithm.statistics.EvaluateRankingQuality
+de.lmu.ifi.dbs.elki.algorithm.statistics.HopkinsStatisticClusteringTendency
+de.lmu.ifi.dbs.elki.algorithm.statistics.MeanAveragePrecisionForDistance
de.lmu.ifi.dbs.elki.algorithm.statistics.RankingQualityHistogram
-de.lmu.ifi.dbs.elki.algorithm.statistics.DistanceStatisticsWithClasses
# de.lmu.ifi.dbs.elki.algorithm.DummyAlgorithm
-de.lmu.ifi.dbs.elki.algorithm.APRIORI
de.lmu.ifi.dbs.elki.algorithm.DependencyDerivator
-de.lmu.ifi.dbs.elki.algorithm.KNNDistanceOrder
+de.lmu.ifi.dbs.elki.algorithm.KNNDistancesSampler
de.lmu.ifi.dbs.elki.algorithm.KNNJoin
de.lmu.ifi.dbs.elki.algorithm.MaterializeDistances
de.lmu.ifi.dbs.elki.algorithm.benchmark.KNNBenchmarkAlgorithm
de.lmu.ifi.dbs.elki.algorithm.benchmark.RangeQueryBenchmarkAlgorithm
de.lmu.ifi.dbs.elki.algorithm.benchmark.ValidateApproximativeKNNIndex
+# de.lmu.ifi.dbs.elki.algorithm.classification.KNNClassifier
+# de.lmu.ifi.dbs.elki.algorithm.classification.PriorProbabilityClassifier
tutorial.clustering.NaiveAgglomerativeHierarchicalClustering1
tutorial.clustering.NaiveAgglomerativeHierarchicalClustering2
tutorial.clustering.NaiveAgglomerativeHierarchicalClustering3
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.DistanceBasedAlgorithm b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.DistanceBasedAlgorithm
index fceac21e..ddb0d89a 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.DistanceBasedAlgorithm
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.DistanceBasedAlgorithm
@@ -1,50 +1,62 @@
-de.lmu.ifi.dbs.elki.algorithm.KNNDistanceOrder
-de.lmu.ifi.dbs.elki.algorithm.KNNJoin
-de.lmu.ifi.dbs.elki.algorithm.MaterializeDistances
de.lmu.ifi.dbs.elki.algorithm.clustering.CanopyPreClustering
de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN
de.lmu.ifi.dbs.elki.algorithm.clustering.NaiveMeanShiftClustering
-de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICS
-de.lmu.ifi.dbs.elki.algorithm.clustering.DeLiClu
+de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.LSDBC
de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical.NaiveAgglomerativeHierarchicalClustering
de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical.SLINK
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansLloyd
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.parallel.ParallelLloydKMeans
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansMacQueen
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMediansLloyd
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMedoidsPAM
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMedoidsEM
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.CLARA
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.BestOfMultipleKMeans
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansBisecting
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansBatchedLloyd
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansHybridLloydMacQueen
-de.lmu.ifi.dbs.elki.algorithm.clustering.correlation.HiCO
-de.lmu.ifi.dbs.elki.algorithm.clustering.subspace.HiSC
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.SingleAssignmentKMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.XMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.optics.OPTICS
+de.lmu.ifi.dbs.elki.algorithm.clustering.optics.DeLiClu
+de.lmu.ifi.dbs.elki.algorithm.outlier.clustering.SilhouetteOutlierDetection
de.lmu.ifi.dbs.elki.algorithm.outlier.COP
-de.lmu.ifi.dbs.elki.algorithm.outlier.DBOutlierDetection
-de.lmu.ifi.dbs.elki.algorithm.outlier.DBOutlierScore
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.DBOutlierDetection
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.DBOutlierScore
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.HilOut
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.KNNOutlier
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.KNNWeightOutlier
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.ODIN
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.parallel.ParallelKNNOutlier
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.parallel.ParallelKNNWeightOutlier
de.lmu.ifi.dbs.elki.algorithm.outlier.DWOF
-de.lmu.ifi.dbs.elki.algorithm.outlier.HilOut
-de.lmu.ifi.dbs.elki.algorithm.outlier.KNNOutlier
-de.lmu.ifi.dbs.elki.algorithm.outlier.KNNWeightOutlier
-de.lmu.ifi.dbs.elki.algorithm.outlier.ODIN
de.lmu.ifi.dbs.elki.algorithm.outlier.OPTICSOF
de.lmu.ifi.dbs.elki.algorithm.outlier.SimpleCOP
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOF
+de.lmu.ifi.dbs.elki.algorithm.outlier.lof.parallel.ParallelLOF
+de.lmu.ifi.dbs.elki.algorithm.outlier.lof.COF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.INFLO
+de.lmu.ifi.dbs.elki.algorithm.outlier.lof.KDEOS
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LDF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LDOF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOCI
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.SimplifiedLOF
+de.lmu.ifi.dbs.elki.algorithm.outlier.lof.parallel.ParallelSimplifiedLOF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.SimpleKernelDensityLOF
de.lmu.ifi.dbs.elki.algorithm.outlier.spatial.CTLuGLSBackwardSearchAlgorithm
de.lmu.ifi.dbs.elki.algorithm.outlier.spatial.CTLuRandomWalkEC
de.lmu.ifi.dbs.elki.algorithm.statistics.AveragePrecisionAtK
-de.lmu.ifi.dbs.elki.algorithm.statistics.RankingQualityHistogram
de.lmu.ifi.dbs.elki.algorithm.statistics.DistanceStatisticsWithClasses
de.lmu.ifi.dbs.elki.algorithm.statistics.EvaluateRankingQuality
+de.lmu.ifi.dbs.elki.algorithm.statistics.MeanAveragePrecisionForDistance
+de.lmu.ifi.dbs.elki.algorithm.statistics.RankingQualityHistogram
de.lmu.ifi.dbs.elki.algorithm.benchmark.KNNBenchmarkAlgorithm
de.lmu.ifi.dbs.elki.algorithm.benchmark.RangeQueryBenchmarkAlgorithm
de.lmu.ifi.dbs.elki.algorithm.benchmark.ValidateApproximativeKNNIndex
+de.lmu.ifi.dbs.elki.algorithm.classification.KNNClassifier
+de.lmu.ifi.dbs.elki.algorithm.KNNDistancesSampler
+de.lmu.ifi.dbs.elki.algorithm.KNNJoin
+de.lmu.ifi.dbs.elki.algorithm.MaterializeDistances
tutorial.clustering.NaiveAgglomerativeHierarchicalClustering1
tutorial.clustering.NaiveAgglomerativeHierarchicalClustering2
tutorial.clustering.NaiveAgglomerativeHierarchicalClustering3
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.classification.Classifier b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.classification.Classifier
new file mode 100644
index 00000000..28b88dc3
--- /dev/null
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.classification.Classifier
@@ -0,0 +1,2 @@
+de.lmu.ifi.dbs.elki.algorithm.classification.KNNClassifier
+de.lmu.ifi.dbs.elki.algorithm.classification.PriorProbabilityClassifier \ No newline at end of file
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm
index f0fc5b55..71107b34 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm
@@ -1,20 +1,25 @@
de.lmu.ifi.dbs.elki.algorithm.clustering.CanopyPreClustering
de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN
-de.lmu.ifi.dbs.elki.algorithm.clustering.EM
-de.lmu.ifi.dbs.elki.algorithm.clustering.affinitypropagation.AffinityPropagationClusteringAlgorithm
de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.GeneralizedDBSCAN
+de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.LSDBC
+de.lmu.ifi.dbs.elki.algorithm.clustering.affinitypropagation.AffinityPropagationClusteringAlgorithm
+de.lmu.ifi.dbs.elki.algorithm.clustering.em.EM
de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical.ExtractFlatClusteringFromHierarchy
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansLloyd
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.parallel.ParallelLloydKMeans
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansMacQueen
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMediansLloyd
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMedoidsPAM
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMedoidsEM
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.CLARA
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.BestOfMultipleKMeans
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansBisecting
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansBatchedLloyd
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansHybridLloydMacQueen
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.SingleAssignmentKMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.XMeans
de.lmu.ifi.dbs.elki.algorithm.clustering.NaiveMeanShiftClustering
-de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICSXi
+de.lmu.ifi.dbs.elki.algorithm.clustering.optics.OPTICSXi
de.lmu.ifi.dbs.elki.algorithm.clustering.SNNClustering
de.lmu.ifi.dbs.elki.algorithm.clustering.biclustering.ChengAndChurch
de.lmu.ifi.dbs.elki.algorithm.clustering.correlation.CASH
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.em.EMClusterModelFactory b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.em.EMClusterModelFactory
new file mode 100644
index 00000000..049bde23
--- /dev/null
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.em.EMClusterModelFactory
@@ -0,0 +1,3 @@
+de.lmu.ifi.dbs.elki.algorithm.clustering.em.MultivariateGaussianModelFactory
+de.lmu.ifi.dbs.elki.algorithm.clustering.em.DiagonalGaussianModelFactory
+de.lmu.ifi.dbs.elki.algorithm.clustering.em.SphericalGaussianModelFactory \ No newline at end of file
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.CorePredicate b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.CorePredicate
index df33be1c..9ec772b5 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.CorePredicate
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.CorePredicate
@@ -1 +1,3 @@
-de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.MinPtsCorePredicate \ No newline at end of file
+de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.MinPtsCorePredicate
+de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.PreDeConCorePredicate
+de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.FourCCorePredicate
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.NeighborPredicate b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.NeighborPredicate
index 08ed8efa..e4083e44 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.NeighborPredicate
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.NeighborPredicate
@@ -1 +1,5 @@
-de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.EpsilonNeighborPredicate \ No newline at end of file
+de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.EpsilonNeighborPredicate
+de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.COPACNeighborPredicate
+de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.ERiCNeighborPredicate
+de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.FourCNeighborPredicate
+de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.PreDeConNeighborPredicate
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeans b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeans
index 783a9264..89a006ca 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeans
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeans
@@ -1,8 +1,11 @@
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansLloyd
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.parallel.ParallelLloydKMeans
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansMacQueen
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMediansLloyd
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.BestOfMultipleKMeans
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansBisecting
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansBatchedLloyd
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansHybridLloydMacQueen
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.SingleAssignmentKMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.XMeans
tutorial.clustering.SameSizeKMeansAlgorithm \ No newline at end of file
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansInitialization b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansInitialization
deleted file mode 100644
index dd91455e..00000000
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansInitialization
+++ /dev/null
@@ -1,7 +0,0 @@
-de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.RandomlyChosenInitialMeans
-de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.FirstKInitialMeans
-de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansPlusPlusInitialMeans
-de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.SampleKMeansInitialization
-de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.FarthestPointsInitialMeans
-de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.RandomlyGeneratedInitialMeans
-de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.PAMInitialMeans
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMedoidsInitialization b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMedoidsInitialization
deleted file mode 100644
index dffb5448..00000000
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMedoidsInitialization
+++ /dev/null
@@ -1,5 +0,0 @@
-de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.PAMInitialMeans
-de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.RandomlyChosenInitialMeans
-de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.FirstKInitialMeans
-de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansPlusPlusInitialMeans
-de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.FarthestPointsInitialMeans \ No newline at end of file
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization
new file mode 100644
index 00000000..6a5305b4
--- /dev/null
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization
@@ -0,0 +1,9 @@
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.RandomlyChosenInitialMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.FirstKInitialMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansPlusPlusInitialMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.SampleKMeansInitialization
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.FarthestPointsInitialMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.FarthestSumPointsInitialMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.RandomlyGeneratedInitialMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.PredefinedInitialMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.PAMInitialMeans
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMedoidsInitialization b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMedoidsInitialization
new file mode 100644
index 00000000..29d84566
--- /dev/null
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMedoidsInitialization
@@ -0,0 +1,6 @@
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.PAMInitialMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.RandomlyChosenInitialMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.FirstKInitialMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansPlusPlusInitialMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.FarthestPointsInitialMeans
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.FarthestSumPointsInitialMeans \ No newline at end of file
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.KMeansQualityMeasure b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.KMeansQualityMeasure
index 4785c3f9..bf508d07 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.KMeansQualityMeasure
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.KMeansQualityMeasure
@@ -1,2 +1,5 @@
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.WithinClusterVarianceQualityMeasure
de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.WithinClusterMeanDistanceQualityMeasure
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.AkaikeInformationCriterion
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.BayesianInformationCriterion
+de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.BayesianInformationCriterionZhao \ No newline at end of file
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICSTypeAlgorithm b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.optics.OPTICSTypeAlgorithm
index 98ae4fdb..55ebbacd 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICSTypeAlgorithm
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.clustering.optics.OPTICSTypeAlgorithm
@@ -1,4 +1,4 @@
-de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICS
-de.lmu.ifi.dbs.elki.algorithm.clustering.DeLiClu
+de.lmu.ifi.dbs.elki.algorithm.clustering.optics.OPTICS
+de.lmu.ifi.dbs.elki.algorithm.clustering.optics.DeLiClu
de.lmu.ifi.dbs.elki.algorithm.clustering.correlation.HiCO
de.lmu.ifi.dbs.elki.algorithm.clustering.subspace.HiSC
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm
index fbb5c6b2..2e0406b5 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm
@@ -1,33 +1,41 @@
-de.lmu.ifi.dbs.elki.algorithm.outlier.ABOD
-de.lmu.ifi.dbs.elki.algorithm.outlier.FastABOD
-de.lmu.ifi.dbs.elki.algorithm.outlier.LBABOD
-de.lmu.ifi.dbs.elki.algorithm.outlier.AggarwalYuEvolutionary
-de.lmu.ifi.dbs.elki.algorithm.outlier.AggarwalYuNaive
+de.lmu.ifi.dbs.elki.algorithm.outlier.anglebased.ABOD
+de.lmu.ifi.dbs.elki.algorithm.outlier.anglebased.FastABOD
+de.lmu.ifi.dbs.elki.algorithm.outlier.anglebased.LBABOD
+de.lmu.ifi.dbs.elki.algorithm.outlier.clustering.EMOutlier
+de.lmu.ifi.dbs.elki.algorithm.outlier.clustering.KMeansOutlierDetection
+de.lmu.ifi.dbs.elki.algorithm.outlier.clustering.SilhouetteOutlierDetection
de.lmu.ifi.dbs.elki.algorithm.outlier.COP
-de.lmu.ifi.dbs.elki.algorithm.outlier.DBOutlierDetection
-de.lmu.ifi.dbs.elki.algorithm.outlier.DBOutlierScore
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.DBOutlierDetection
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.DBOutlierScore
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.HilOut
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.KNNOutlier
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.KNNWeightOutlier
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.ODIN
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.parallel.ParallelKNNOutlier
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.parallel.ParallelKNNWeightOutlier
+de.lmu.ifi.dbs.elki.algorithm.outlier.distance.ReferenceBasedOutlierDetection
de.lmu.ifi.dbs.elki.algorithm.outlier.DWOF
-de.lmu.ifi.dbs.elki.algorithm.outlier.EMOutlier
de.lmu.ifi.dbs.elki.algorithm.outlier.GaussianModel
de.lmu.ifi.dbs.elki.algorithm.outlier.GaussianUniformMixture
-de.lmu.ifi.dbs.elki.algorithm.outlier.HilOut
-de.lmu.ifi.dbs.elki.algorithm.outlier.KNNOutlier
-de.lmu.ifi.dbs.elki.algorithm.outlier.KNNWeightOutlier
+de.lmu.ifi.dbs.elki.algorithm.outlier.OPTICSOF
+de.lmu.ifi.dbs.elki.algorithm.outlier.SimpleCOP
+de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOF
+de.lmu.ifi.dbs.elki.algorithm.outlier.lof.parallel.ParallelLOF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.ALOCI
+de.lmu.ifi.dbs.elki.algorithm.outlier.lof.COF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.FlexibleLOF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.INFLO
+de.lmu.ifi.dbs.elki.algorithm.outlier.lof.KDEOS
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LDF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LDOF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOCI
-de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LoOP
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.OnlineLOF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.SimplifiedLOF
+de.lmu.ifi.dbs.elki.algorithm.outlier.lof.parallel.ParallelSimplifiedLOF
de.lmu.ifi.dbs.elki.algorithm.outlier.lof.SimpleKernelDensityLOF
-de.lmu.ifi.dbs.elki.algorithm.outlier.ODIN
-de.lmu.ifi.dbs.elki.algorithm.outlier.OPTICSOF
-de.lmu.ifi.dbs.elki.algorithm.outlier.ReferenceBasedOutlierDetection
-de.lmu.ifi.dbs.elki.algorithm.outlier.SimpleCOP
+de.lmu.ifi.dbs.elki.algorithm.outlier.subspace.AggarwalYuEvolutionary
+de.lmu.ifi.dbs.elki.algorithm.outlier.subspace.AggarwalYuNaive
de.lmu.ifi.dbs.elki.algorithm.outlier.subspace.OUTRES
de.lmu.ifi.dbs.elki.algorithm.outlier.subspace.OutRankS1
de.lmu.ifi.dbs.elki.algorithm.outlier.subspace.SOD
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.application.AbstractApplication b/src/META-INF/elki/de.lmu.ifi.dbs.elki.application.AbstractApplication
index 3ff2c408..7a5dcdea 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.application.AbstractApplication
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.application.AbstractApplication
@@ -1,8 +1,9 @@
de.lmu.ifi.dbs.elki.gui.minigui.MiniGUI
de.lmu.ifi.dbs.elki.application.KDDCLIApplication
de.lmu.ifi.dbs.elki.gui.multistep.MultiStepGUI
-de.lmu.ifi.dbs.elki.application.GeneratorXMLSpec
+de.lmu.ifi.dbs.elki.application.ClassifierHoldoutEvaluationTask
de.lmu.ifi.dbs.elki.application.ConvertToBundleApplication
+de.lmu.ifi.dbs.elki.application.GeneratorXMLSpec
de.lmu.ifi.dbs.elki.application.cache.CacheDoubleDistanceInOnDiskMatrix
de.lmu.ifi.dbs.elki.application.cache.CacheFloatDistanceInOnDiskMatrix
de.lmu.ifi.dbs.elki.application.cache.CacheDoubleDistanceKNNLists
@@ -10,5 +11,3 @@ de.lmu.ifi.dbs.elki.application.cache.CacheDoubleDistanceRangeQueries
de.lmu.ifi.dbs.elki.application.geo.VisualizeGeodesicDistances
de.lmu.ifi.dbs.elki.application.greedyensemble.ComputeKNNOutlierScores
de.lmu.ifi.dbs.elki.application.greedyensemble.GreedyEnsembleExperiment
-de.lmu.ifi.dbs.elki.application.greedyensemble.VisualizePairwiseGainMatrix
-de.lmu.ifi.dbs.elki.application.ComputeSingleColorHistogram
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.data.SparseNumberVector$Factory b/src/META-INF/elki/de.lmu.ifi.dbs.elki.data.SparseNumberVector$Factory
index 9d6b1ed0..95a79d8b 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.data.SparseNumberVector$Factory
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.data.SparseNumberVector$Factory
@@ -2,4 +2,5 @@ de.lmu.ifi.dbs.elki.data.SparseFloatVector$Factory
de.lmu.ifi.dbs.elki.data.SparseDoubleVector$Factory
de.lmu.ifi.dbs.elki.data.SparseByteVector$Factory
de.lmu.ifi.dbs.elki.data.SparseIntegerVector$Factory
-de.lmu.ifi.dbs.elki.data.SparseShortVector$Factory \ No newline at end of file
+de.lmu.ifi.dbs.elki.data.SparseShortVector$Factory
+de.lmu.ifi.dbs.elki.data.BitVector$Factory \ No newline at end of file
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.data.images.ComputeColorHistogram b/src/META-INF/elki/de.lmu.ifi.dbs.elki.data.images.ComputeColorHistogram
deleted file mode 100644
index 94c65a07..00000000
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.data.images.ComputeColorHistogram
+++ /dev/null
@@ -1,3 +0,0 @@
-de.lmu.ifi.dbs.elki.data.images.ComputeHSBColorHistogram
-de.lmu.ifi.dbs.elki.data.images.ComputeNaiveHSBColorHistogram
-de.lmu.ifi.dbs.elki.data.images.ComputeNaiveRGBColorHistogram
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.DatabaseConnection b/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.DatabaseConnection
index 1ec23984..6c4c8ebf 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.DatabaseConnection
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.DatabaseConnection
@@ -9,4 +9,5 @@ de.lmu.ifi.dbs.elki.datasource.ConcatenateFilesDatabaseConnection
de.lmu.ifi.dbs.elki.datasource.EmptyDatabaseConnection
de.lmu.ifi.dbs.elki.datasource.PresortedBlindJoinDatabaseConnection
# de.lmu.ifi.dbs.elki.datasource.InputStreamDatabaseConnection
-# de.lmu.ifi.dbs.elki.datasource.ArrayAdapterDatabaseConnection \ No newline at end of file
+# de.lmu.ifi.dbs.elki.datasource.ArrayAdapterDatabaseConnection
+# de.lmu.ifi.dbs.elki.datasource.MultipleObjectsBundleDatabaseConnection \ No newline at end of file
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter b/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter
index a5257291..3a89cdaa 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter
@@ -1,27 +1,33 @@
de.lmu.ifi.dbs.elki.datasource.filter.FixedDBIDsFilter
de.lmu.ifi.dbs.elki.datasource.filter.NoOpFilter
-de.lmu.ifi.dbs.elki.datasource.filter.ClassLabelFilter
-de.lmu.ifi.dbs.elki.datasource.filter.ClassLabelFromPatternFilter
-de.lmu.ifi.dbs.elki.datasource.filter.ExternalIDFilter
-de.lmu.ifi.dbs.elki.datasource.filter.SparseVectorFieldFilter
-de.lmu.ifi.dbs.elki.datasource.filter.ByLabelFilter
-de.lmu.ifi.dbs.elki.datasource.filter.RandomSamplingStreamFilter
-de.lmu.ifi.dbs.elki.datasource.filter.ShuffleObjectsFilter
-de.lmu.ifi.dbs.elki.datasource.filter.SortByLabelFilter
-de.lmu.ifi.dbs.elki.datasource.filter.DropNaNFilter
-de.lmu.ifi.dbs.elki.datasource.filter.ReplaceNaNWithRandomFilter
-de.lmu.ifi.dbs.elki.datasource.filter.NoMissingValuesFilter
-de.lmu.ifi.dbs.elki.datasource.filter.HistogramJitterFilter
-de.lmu.ifi.dbs.elki.datasource.filter.SplitNumberVectorFilter
-de.lmu.ifi.dbs.elki.datasource.filter.normalization.AttributeWiseMinMaxNormalization
-de.lmu.ifi.dbs.elki.datasource.filter.normalization.AttributeWiseVarianceNormalization
-de.lmu.ifi.dbs.elki.datasource.filter.normalization.AttributeWiseMADNormalization
-de.lmu.ifi.dbs.elki.datasource.filter.normalization.AttributeWiseErfNormalization
-de.lmu.ifi.dbs.elki.datasource.filter.normalization.AttributeWiseCDFNormalization
-de.lmu.ifi.dbs.elki.datasource.filter.normalization.LengthNormalization
-de.lmu.ifi.dbs.elki.datasource.filter.normalization.InverseDocumentFrequencyNormalization
-de.lmu.ifi.dbs.elki.datasource.filter.normalization.RankTieNormalization
-de.lmu.ifi.dbs.elki.datasource.filter.normalization.TFIDFNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.typeconversions.ClassLabelFilter
+de.lmu.ifi.dbs.elki.datasource.filter.typeconversions.ClassLabelFromPatternFilter
+de.lmu.ifi.dbs.elki.datasource.filter.typeconversions.ExternalIDFilter
+de.lmu.ifi.dbs.elki.datasource.filter.typeconversions.MultivariateTimeSeriesFilter
+de.lmu.ifi.dbs.elki.datasource.filter.typeconversions.SparseVectorFieldFilter
+de.lmu.ifi.dbs.elki.datasource.filter.typeconversions.SplitNumberVectorFilter
+de.lmu.ifi.dbs.elki.datasource.filter.selection.ByLabelFilter
+de.lmu.ifi.dbs.elki.datasource.filter.selection.RandomSamplingStreamFilter
+de.lmu.ifi.dbs.elki.datasource.filter.selection.ShuffleObjectsFilter
+de.lmu.ifi.dbs.elki.datasource.filter.selection.SortByLabelFilter
+de.lmu.ifi.dbs.elki.datasource.filter.cleaning.DropNaNFilter
+de.lmu.ifi.dbs.elki.datasource.filter.cleaning.ReplaceNaNWithRandomFilter
+de.lmu.ifi.dbs.elki.datasource.filter.cleaning.NoMissingValuesFilter
+de.lmu.ifi.dbs.elki.datasource.filter.cleaning.VectorDimensionalityFilter
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise.AttributeWiseMinMaxNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise.AttributeWiseVarianceNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise.AttributeWiseMeanNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise.AttributeWiseMADNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise.AttributeWiseErfNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise.AttributeWiseCDFNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise.AttributeWiseBetaNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise.InverseDocumentFrequencyNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise.IntegerRankTieNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise.LengthNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise.HellingerHistogramNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise.InstanceMeanVarianceNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise.InstanceMinMaxNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise.Log1PlusNormalization
de.lmu.ifi.dbs.elki.datasource.filter.transform.GlobalPrincipalComponentAnalysisTransform
de.lmu.ifi.dbs.elki.datasource.filter.transform.ClassicMultidimensionalScalingTransform
de.lmu.ifi.dbs.elki.datasource.filter.transform.LinearDiscriminantAnalysisFilter
@@ -29,4 +35,6 @@ de.lmu.ifi.dbs.elki.datasource.filter.transform.NumberVectorFeatureSelectionFilt
de.lmu.ifi.dbs.elki.datasource.filter.transform.NumberVectorRandomFeatureSelectionFilter
de.lmu.ifi.dbs.elki.datasource.filter.transform.LatLngToECEFFilter
de.lmu.ifi.dbs.elki.datasource.filter.transform.LngLatToECEFFilter
-de.lmu.ifi.dbs.elki.datasource.filter.transform.ProjectionFilter \ No newline at end of file
+de.lmu.ifi.dbs.elki.datasource.filter.transform.PerturbationFilter
+de.lmu.ifi.dbs.elki.datasource.filter.transform.ProjectionFilter
+de.lmu.ifi.dbs.elki.datasource.filter.transform.HistogramJitterFilter
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.filter.StreamFilter b/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.filter.StreamFilter
index 8ab5827f..f5db8968 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.filter.StreamFilter
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.filter.StreamFilter
@@ -1,15 +1,20 @@
de.lmu.ifi.dbs.elki.datasource.filter.NoOpFilter
-de.lmu.ifi.dbs.elki.datasource.filter.FixedDBIDsFilter
-de.lmu.ifi.dbs.elki.datasource.filter.ByLabelFilter
-de.lmu.ifi.dbs.elki.datasource.filter.ClassLabelFromPatternFilter
-de.lmu.ifi.dbs.elki.datasource.filter.DropNaNFilter
-de.lmu.ifi.dbs.elki.datasource.filter.ReplaceNaNWithRandomFilter
-de.lmu.ifi.dbs.elki.datasource.filter.NoMissingValuesFilter
-de.lmu.ifi.dbs.elki.datasource.filter.RandomSamplingStreamFilter
-de.lmu.ifi.dbs.elki.datasource.filter.HistogramJitterFilter
-de.lmu.ifi.dbs.elki.datasource.filter.normalization.LengthNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.typeconversions.ClassLabelFromPatternFilter
+de.lmu.ifi.dbs.elki.datasource.filter.typeconversions.MultivariateTimeSeriesFilter
+de.lmu.ifi.dbs.elki.datasource.filter.selection.ByLabelFilter
+de.lmu.ifi.dbs.elki.datasource.filter.selection.RandomSamplingStreamFilter
+de.lmu.ifi.dbs.elki.datasource.filter.cleaning.VectorDimensionalityFilter
+de.lmu.ifi.dbs.elki.datasource.filter.cleaning.DropNaNFilter
+de.lmu.ifi.dbs.elki.datasource.filter.cleaning.ReplaceNaNWithRandomFilter
+de.lmu.ifi.dbs.elki.datasource.filter.cleaning.NoMissingValuesFilter
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise.LengthNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise.HellingerHistogramNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise.InstanceMeanVarianceNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise.InstanceMinMaxNormalization
+de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise.Log1PlusNormalization
de.lmu.ifi.dbs.elki.datasource.filter.transform.NumberVectorFeatureSelectionFilter
de.lmu.ifi.dbs.elki.datasource.filter.transform.NumberVectorRandomFeatureSelectionFilter
de.lmu.ifi.dbs.elki.datasource.filter.transform.LatLngToECEFFilter
de.lmu.ifi.dbs.elki.datasource.filter.transform.LngLatToECEFFilter
de.lmu.ifi.dbs.elki.datasource.filter.transform.ProjectionFilter
+de.lmu.ifi.dbs.elki.datasource.filter.transform.HistogramJitterFilter
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.parser.Parser b/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.parser.Parser
index 57a71694..74d45151 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.parser.Parser
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.datasource.parser.Parser
@@ -1,12 +1,11 @@
de.lmu.ifi.dbs.elki.datasource.parser.NumberVectorLabelParser
de.lmu.ifi.dbs.elki.datasource.parser.ArffParser
de.lmu.ifi.dbs.elki.datasource.parser.SparseNumberVectorLabelParser
+de.lmu.ifi.dbs.elki.datasource.parser.LibSVMFormatParser
de.lmu.ifi.dbs.elki.datasource.parser.CategorialDataAsNumberVectorParser
-de.lmu.ifi.dbs.elki.datasource.parser.SparseBitVectorLabelParser
de.lmu.ifi.dbs.elki.datasource.parser.TermFrequencyParser
de.lmu.ifi.dbs.elki.datasource.parser.BitVectorLabelParser
de.lmu.ifi.dbs.elki.datasource.parser.SimplePolygonParser
de.lmu.ifi.dbs.elki.datasource.parser.StringParser
-# deprecated: de.lmu.ifi.dbs.elki.datasource.parser.DoubleVectorLabelParser
-# deprecated: de.lmu.ifi.dbs.elki.datasource.parser.FloatVectorLabelParser
-# deprecated: de.lmu.ifi.dbs.elki.datasource.parser.SparseFloatVectorLabelParser \ No newline at end of file
+de.lmu.ifi.dbs.elki.datasource.parser.SimpleTransactionParser
+de.lmu.ifi.dbs.elki.datasource.parser.ClusteringVectorParser \ No newline at end of file
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractIndexBasedDistanceFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractIndexBasedDistanceFunction
index 3c32949a..4ec25d0c 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractIndexBasedDistanceFunction
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractIndexBasedDistanceFunction
@@ -1,7 +1,2 @@
-de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.SharedNearestNeighborJaccardDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.ERiCDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.PCABasedCorrelationDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.LocalSubspaceDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DiSHDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.HiSCDistanceFunction
+
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction
index 3f1c0e2c..ade04e47 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction
@@ -10,20 +10,17 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.RandomStableDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.BrayCurtisDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.CanberraDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedCanberraDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedCanberraDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.ClarkDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.Kulczynski1DistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.LorentzianDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.SharedNearestNeighborJaccardDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.MinKDistance
-# de.lmu.ifi.dbs.elki.distance.distancefunction.ProxyDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedSquaredEuclideanDistanceFunction
+# de.lmu.ifi.dbs.elki.distance.distancefunction.MatrixWeightedDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedSquaredEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseManhattanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseLPNormDistanceFunction
@@ -36,10 +33,12 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram.HistogramIntersecti
de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram.RGBHistogramQuadraticDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.PearsonCorrelationDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.SquaredPearsonCorrelationDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.ERiCDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.PCABasedCorrelationDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedPearsonCorrelationDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedSquaredPearsonCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.AbsolutePearsonCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.UncenteredCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.SquaredUncenteredCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.AbsoluteUncenteredCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedPearsonCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedSquaredPearsonCorrelationDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.geo.DimensionSelectingLatLngDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LatLngDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LngLatDistanceFunction
@@ -47,30 +46,33 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.histogram.HistogramMatchDistanceFu
de.lmu.ifi.dbs.elki.distance.distancefunction.histogram.KolmogorovSmirnovDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.JeffreyDivergenceDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.ChiSquaredDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.HellingerDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.JensenShannonDivergenceDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.KullbackLeiblerDivergenceAsymmetricDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.SqrtJensenShannonDivergenceDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.set.HammingDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.set.JaccardSimilarityDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.strings.LevenshteinDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.strings.NormalizedLevenshteinDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceLPNormDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceManhattanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceMaximumDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DiSHDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.HiSCDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.LocalSubspaceDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.OnedimensionalDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.DTWDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.EDRDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.ERPDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.LCSSDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.DerivativeDTWDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.external.DiskCacheBasedDoubleDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.external.DiskCacheBasedFloatDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.external.FileBasedDoubleDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.external.FileBasedFloatDistanceFunction
-de.lmu.ifi.dbs.elki.distance.similarityfunction.JaccardPrimitiveSimilarityFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.LinearKernelFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.PolynomialKernelFunction
+de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster.ClusterIntersectionSimilarityFunction
+de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster.ClusterJaccardSimilarityFunction
+de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster.ClusteringAdjustedRandIndexSimilarityFunction
# tutorial.distancefunction.MultiLPNorm
# tutorial.distancefunction.TutorialDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.FilteredLocalPCABasedDistanceFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.FilteredLocalPCABasedDistanceFunction
deleted file mode 100644
index df161a0a..00000000
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.FilteredLocalPCABasedDistanceFunction
+++ /dev/null
@@ -1,4 +0,0 @@
-de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.ERiCDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.PCABasedCorrelationDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.LocalSubspaceDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction
deleted file mode 100644
index 6b852263..00000000
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction
+++ /dev/null
@@ -1 +0,0 @@
-de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.DoubleNorm b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.Norm
index 2b2a8e5c..ce1a6a1d 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.DoubleNorm
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.Norm
@@ -5,11 +5,11 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.MinimumDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction
# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPIntegerNormDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedSquaredEuclideanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedSquaredEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseManhattanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseLPNormDistanceFunction
@@ -18,5 +18,5 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceEuclideanDistance
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceLPNormDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceManhattanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceMaximumDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.OnedimensionalDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.LorentzianDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.NumberVectorDistanceFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.NumberVectorDistanceFunction
index 51c1f64f..65998259 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.NumberVectorDistanceFunction
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.NumberVectorDistanceFunction
@@ -9,23 +9,27 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.CosineDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.BrayCurtisDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.CanberraDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedCanberraDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedCanberraDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.ClarkDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.Kulczynski1DistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.LorentzianDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedSquaredEuclideanDistanceFunction
+# de.lmu.ifi.dbs.elki.distance.distancefunction.MatrixWeightedDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedSquaredEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram.HSBHistogramQuadraticDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram.HistogramIntersectionDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram.RGBHistogramQuadraticDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.PearsonCorrelationDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.SquaredPearsonCorrelationDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedPearsonCorrelationDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedSquaredPearsonCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.AbsolutePearsonCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.UncenteredCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.SquaredUncenteredCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.AbsoluteUncenteredCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedPearsonCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedSquaredPearsonCorrelationDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.geo.DimensionSelectingLatLngDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LatLngDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LngLatDistanceFunction
@@ -33,18 +37,22 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.histogram.HistogramMatchDistanceFu
de.lmu.ifi.dbs.elki.distance.distancefunction.histogram.KolmogorovSmirnovDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.JeffreyDivergenceDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.ChiSquaredDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.HellingerDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.JensenShannonDivergenceDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.KullbackLeiblerDivergenceAsymmetricDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.SqrtJensenShannonDivergenceDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.set.HammingDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.set.JaccardSimilarityDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceLPNormDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceManhattanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceMaximumDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.OnedimensionalDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.DTWDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.EDRDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.ERPDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.LCSSDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.DerivativeDTWDistanceFunction
# tutorial.distancefunction.MultiLPNorm
# tutorial.distancefunction.TutorialDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction
index 38a019c0..7ef75bb5 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction
@@ -9,16 +9,16 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.MinimumDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.BrayCurtisDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.CanberraDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedCanberraDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedCanberraDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.ClarkDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.Kulczynski1DistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.LorentzianDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedSquaredEuclideanDistanceFunction
+# de.lmu.ifi.dbs.elki.distance.distancefunction.MatrixWeightedDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedSquaredEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseManhattanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseLPNormDistanceFunction
@@ -28,8 +28,12 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram.HistogramIntersecti
de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram.RGBHistogramQuadraticDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.PearsonCorrelationDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.SquaredPearsonCorrelationDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedPearsonCorrelationDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedSquaredPearsonCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.AbsolutePearsonCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.UncenteredCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.SquaredUncenteredCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.AbsoluteUncenteredCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedPearsonCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedSquaredPearsonCorrelationDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.geo.DimensionSelectingLatLngDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LatLngDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LngLatDistanceFunction
@@ -37,23 +41,29 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.histogram.HistogramMatchDistanceFu
de.lmu.ifi.dbs.elki.distance.distancefunction.histogram.KolmogorovSmirnovDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.JeffreyDivergenceDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.ChiSquaredDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.HellingerDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.JensenShannonDivergenceDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.KullbackLeiblerDivergenceAsymmetricDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.SqrtJensenShannonDivergenceDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.set.HammingDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.set.JaccardSimilarityDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.strings.LevenshteinDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.strings.NormalizedLevenshteinDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceLPNormDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceManhattanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceMaximumDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.OnedimensionalDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.DTWDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.EDRDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.ERPDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.LCSSDistanceFunction
-de.lmu.ifi.dbs.elki.distance.similarityfunction.JaccardPrimitiveSimilarityFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.DerivativeDTWDistanceFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.LinearKernelFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.PolynomialKernelFunction
+de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster.ClusterIntersectionSimilarityFunction
+de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster.ClusterJaccardSimilarityFunction
+de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster.ClusteringAdjustedRandIndexSimilarityFunction
# tutorial.distancefunction.MultiLPNorm
# tutorial.distancefunction.TutorialDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction
deleted file mode 100644
index 1cae5172..00000000
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction
+++ /dev/null
@@ -1,57 +0,0 @@
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.ManhattanDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPIntegerNormDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.ArcCosineDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.CosineDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.MaximumDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.MinimumDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.BrayCurtisDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.CanberraDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedCanberraDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.ClarkDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.Kulczynski1DistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.LorentzianDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedSquaredEuclideanDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseEuclideanDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseManhattanDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseLPNormDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseMaximumDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram.HSBHistogramQuadraticDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram.HistogramIntersectionDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram.RGBHistogramQuadraticDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.PearsonCorrelationDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.SquaredPearsonCorrelationDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedPearsonCorrelationDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedSquaredPearsonCorrelationDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.geo.DimensionSelectingLatLngDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LatLngDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LngLatDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.histogram.HistogramMatchDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.histogram.KolmogorovSmirnovDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.JeffreyDivergenceDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.ChiSquaredDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.JensenShannonDivergenceDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.KullbackLeiblerDivergenceAsymmetricDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.KullbackLeiblerDivergenceReverseAsymmetricDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.SqrtJensenShannonDivergenceDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceEuclideanDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceLPNormDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceManhattanDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceMaximumDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.DTWDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.EDRDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.ERPDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.timeseries.LCSSDistanceFunction
-de.lmu.ifi.dbs.elki.distance.similarityfunction.JaccardPrimitiveSimilarityFunction
-de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.LinearKernelFunction
-de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.PolynomialKernelFunction
-# tutorial.distancefunction.MultiLPNorm
-# tutorial.distancefunction.TutorialDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction
index 138541c0..10b122f8 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction
@@ -8,25 +8,26 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.ArcCosineDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.CosineDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.BrayCurtisDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.CanberraDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedCanberraDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedCanberraDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.ClarkDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.Kulczynski1DistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.LorentzianDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedSquaredEuclideanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedSquaredEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram.HistogramIntersectionDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LatLngDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LngLatDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.geo.DimensionSelectingLatLngDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.histogram.HistogramMatchDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.ChiSquaredDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.JeffreyDivergenceDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.JensenShannonDivergenceDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceEuclideanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceLPNormDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceManhattanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceMaximumDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.OnedimensionalDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction
deleted file mode 100644
index ac3a8344..00000000
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction
+++ /dev/null
@@ -1,32 +0,0 @@
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.ManhattanDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPIntegerNormDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.MaximumDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.MinimumDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.ArcCosineDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.CosineDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.BrayCurtisDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.CanberraDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedCanberraDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.ClarkDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.Kulczynski1DistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.LorentzianDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedSquaredEuclideanDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram.HistogramIntersectionDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LatLngDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LngLatDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.geo.DimensionSelectingLatLngDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.ChiSquaredDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.JeffreyDivergenceDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.JensenShannonDivergenceDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceEuclideanDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceLPNormDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceManhattanDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceMaximumDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedNumberVectorDistanceFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedNumberVectorDistanceFunction
new file mode 100644
index 00000000..b7022678
--- /dev/null
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedNumberVectorDistanceFunction
@@ -0,0 +1,8 @@
+de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedCanberraDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedSquaredEuclideanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedPearsonCorrelationDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedSquaredPearsonCorrelationDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.external.DistanceParser b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.external.DistanceParser
index 199f56b9..46b4fa03 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.external.DistanceParser
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.external.DistanceParser
@@ -1 +1 @@
-de.lmu.ifi.dbs.elki.distance.distancefunction.external.NumberDistanceParser \ No newline at end of file
+de.lmu.ifi.dbs.elki.distance.distancefunction.external.AsciiDistanceParser \ No newline at end of file
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction
index 9bcd3af8..6752756a 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction
@@ -3,7 +3,7 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.ManhattanDistanceFunctio
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction
# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPIntegerNormDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.MaximumDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
-# de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedLPNormDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedMaximumDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingSubspaceDistanceFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingSubspaceDistanceFunction
index a683d421..3467fa9c 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingSubspaceDistanceFunction
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingSubspaceDistanceFunction
@@ -2,4 +2,4 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceEuclideanDistance
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceLPNormDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceManhattanDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceMaximumDistanceFunction
-de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingDistanceFunction \ No newline at end of file
+de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.OnedimensionalDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.NormalizedSimilarityFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.NormalizedSimilarityFunction
index 8289c203..0bf2576f 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.NormalizedSimilarityFunction
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.NormalizedSimilarityFunction
@@ -1,2 +1,2 @@
de.lmu.ifi.dbs.elki.distance.similarityfunction.FractionalSharedNearestNeighborSimilarityFunction
-de.lmu.ifi.dbs.elki.distance.similarityfunction.JaccardPrimitiveSimilarityFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.set.JaccardSimilarityDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFunction
index 65a44a1c..88b75dd9 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFunction
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFunction
@@ -1,5 +1,4 @@
de.lmu.ifi.dbs.elki.distance.similarityfunction.InvertedDistanceSimilarityFunction
-de.lmu.ifi.dbs.elki.distance.similarityfunction.JaccardPrimitiveSimilarityFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.Kulczynski1SimilarityFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.Kulczynski2SimilarityFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.LinearKernelFunction
@@ -7,4 +6,9 @@ de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.PolynomialKernelFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.RadialBasisFunctionKernelFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.SigmoidKernelFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.LaplaceKernelFunction
-de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.RationalQuadraticKernelFunction \ No newline at end of file
+de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.RationalQuadraticKernelFunction
+de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster.ClusterIntersectionSimilarityFunction
+de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster.ClusterJaccardSimilarityFunction
+de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster.ClusteringAdjustedRandIndexSimilarityFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.HellingerDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.set.JaccardSimilarityDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction
index 2d464325..c28f7c30 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction
@@ -3,10 +3,14 @@ de.lmu.ifi.dbs.elki.distance.similarityfunction.SharedNearestNeighborSimilarityF
de.lmu.ifi.dbs.elki.distance.similarityfunction.Kulczynski1SimilarityFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.Kulczynski2SimilarityFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.InvertedDistanceSimilarityFunction
-de.lmu.ifi.dbs.elki.distance.similarityfunction.JaccardPrimitiveSimilarityFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.LinearKernelFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.PolynomialKernelFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.RadialBasisFunctionKernelFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.SigmoidKernelFunction
de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.LaplaceKernelFunction
-de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.RationalQuadraticKernelFunction \ No newline at end of file
+de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.RationalQuadraticKernelFunction
+de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster.ClusterIntersectionSimilarityFunction
+de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster.ClusterJaccardSimilarityFunction
+de.lmu.ifi.dbs.elki.distance.similarityfunction.cluster.ClusteringAdjustedRandIndexSimilarityFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.HellingerDistanceFunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.set.JaccardSimilarityDistanceFunction
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.evaluation.Evaluator b/src/META-INF/elki/de.lmu.ifi.dbs.elki.evaluation.Evaluator
index 728e472f..1bfddcc5 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.evaluation.Evaluator
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.evaluation.Evaluator
@@ -1,10 +1,12 @@
de.lmu.ifi.dbs.elki.evaluation.AutomaticEvaluation
de.lmu.ifi.dbs.elki.evaluation.NoAutomaticEvaluation
de.lmu.ifi.dbs.elki.evaluation.clustering.EvaluateClustering
+de.lmu.ifi.dbs.elki.evaluation.clustering.internal.EvaluateSilhouette
de.lmu.ifi.dbs.elki.evaluation.clustering.pairsegments.ClusterPairSegmentAnalysis
de.lmu.ifi.dbs.elki.evaluation.histogram.ComputeOutlierHistogram
de.lmu.ifi.dbs.elki.evaluation.index.IndexPurity
de.lmu.ifi.dbs.elki.evaluation.index.IndexStatistics
+de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierRankingEvaluation
de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierROCCurve
de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierThresholdClustering
de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierPrecisionAtKCurve
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.evaluation.scores.ScoreEvaluation b/src/META-INF/elki/de.lmu.ifi.dbs.elki.evaluation.scores.ScoreEvaluation
new file mode 100644
index 00000000..9d85561e
--- /dev/null
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.evaluation.scores.ScoreEvaluation
@@ -0,0 +1,4 @@
+de.lmu.ifi.dbs.elki.evaluation.scores.AveragePrecisionEvaluation
+de.lmu.ifi.dbs.elki.evaluation.scores.MaximumF1Evaluation
+de.lmu.ifi.dbs.elki.evaluation.scores.PrecisionAtKEvaluation
+de.lmu.ifi.dbs.elki.evaluation.scores.ROCEvaluation
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.IndexFactory b/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.IndexFactory
index 24e24eaa..dd66590c 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.IndexFactory
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.IndexFactory
@@ -1,3 +1,4 @@
+de.lmu.ifi.dbs.elki.index.distancematrix.PrecomputedDistanceMatrix$Factory
de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTreeFactory
de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluTreeFactory
# de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.flat.FlatRStarTreeFactory
@@ -8,6 +9,8 @@ de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp.MkAppTreeFac
# de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop.MkCopTreeFactory
de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax.MkMaxTreeFactory
de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab.MkTabTreeFactory
+de.lmu.ifi.dbs.elki.index.idistance.InMemoryIDistanceIndex$Factory
+de.lmu.ifi.dbs.elki.index.invertedlist.InMemoryInvertedIndex$Factory
de.lmu.ifi.dbs.elki.index.lsh.InMemoryLSHIndex
de.lmu.ifi.dbs.elki.index.vafile.VAFile$Factory
de.lmu.ifi.dbs.elki.index.vafile.PartialVAFile$Factory
@@ -20,12 +23,9 @@ de.lmu.ifi.dbs.elki.index.preprocessed.knn.PartitionApproximationMaterializeKNNP
de.lmu.ifi.dbs.elki.index.preprocessed.knn.SpatialApproximationMaterializeKNNPreprocessor$Factory
de.lmu.ifi.dbs.elki.index.preprocessed.knn.RandomSampleKNNPreprocessor$Factory
de.lmu.ifi.dbs.elki.index.preprocessed.localpca.KNNQueryFilteredPCAIndex$Factory
-de.lmu.ifi.dbs.elki.index.preprocessed.localpca.RangeQueryFilteredPCAIndex$Factory
de.lmu.ifi.dbs.elki.index.preprocessed.preference.DiSHPreferenceVectorIndex$Factory
de.lmu.ifi.dbs.elki.index.preprocessed.preference.HiSCPreferenceVectorIndex$Factory
de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborPreprocessor$Factory
-de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj.FourCSubspaceIndex$Factory
-de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj.PreDeConSubspaceIndex$Factory
de.lmu.ifi.dbs.elki.index.projected.LatLngAsECEFIndex$Factory
de.lmu.ifi.dbs.elki.index.projected.LngLatAsECEFIndex$Factory
de.lmu.ifi.dbs.elki.index.projected.ProjectedIndex$Factory
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.KNNIndex b/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.KNNIndex
deleted file mode 100644
index 4d76c75a..00000000
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.KNNIndex
+++ /dev/null
@@ -1,23 +0,0 @@
-de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTreeIndex
-de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluTreeIndex
-de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.flat.FlatRStarTreeIndex
-# de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rdknn.RdKNNTree
-de.lmu.ifi.dbs.elki.index.tree.spatial.kd.MinimalisticMemoryKDTree
-de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mtree.MTreeIndex
-de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp.MkAppTreeIndex
-# de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop.MkCoPTreeIndex
-de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax.MkMaxTreeIndex
-de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab.MkTabTreeIndex
-de.lmu.ifi.dbs.elki.index.preprocessed.knn.CachedDoubleDistanceKNNPreprocessor
-de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNAndRKNNPreprocessor
-de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNPreprocessor
-de.lmu.ifi.dbs.elki.index.preprocessed.knn.KNNJoinMaterializeKNNPreprocessor
-de.lmu.ifi.dbs.elki.index.preprocessed.knn.MetricalIndexApproximationMaterializeKNNPreprocessor
-de.lmu.ifi.dbs.elki.index.preprocessed.knn.PartitionApproximationMaterializeKNNPreprocessor
-de.lmu.ifi.dbs.elki.index.preprocessed.knn.RandomSampleKNNPreprocessor
-de.lmu.ifi.dbs.elki.index.preprocessed.knn.SpatialApproximationMaterializeKNNPreprocessor
-de.lmu.ifi.dbs.elki.index.vafile.VAFile
-de.lmu.ifi.dbs.elki.index.vafile.PartialVAFile
-de.lmu.ifi.dbs.elki.index.projected.LatLngAsECEFIndex
-de.lmu.ifi.dbs.elki.index.projected.LngLatAsECEFIndex
-de.lmu.ifi.dbs.elki.index.projected.ProjectedIndex
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.RKNNIndex b/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.RKNNIndex
deleted file mode 100644
index 980543c4..00000000
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.RKNNIndex
+++ /dev/null
@@ -1,9 +0,0 @@
-de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNAndRKNNPreprocessor
-de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp.MkAppTreeIndex
-# de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop.MkCoPTreeIndex
-de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax.MkMaxTreeIndex
-de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab.MkTabTreeIndex
-# de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rdknn.RdKNNTree
-de.lmu.ifi.dbs.elki.index.projected.LatLngAsECEFIndex
-de.lmu.ifi.dbs.elki.index.projected.LngLatAsECEFIndex
-de.lmu.ifi.dbs.elki.index.projected.ProjectedIndex
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.RangeIndex b/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.RangeIndex
deleted file mode 100644
index 24f683a6..00000000
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.RangeIndex
+++ /dev/null
@@ -1,15 +0,0 @@
-de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTreeIndex
-de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluTreeIndex
-de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.flat.FlatRStarTreeIndex
-# de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rdknn.RdKNNTree
-de.lmu.ifi.dbs.elki.index.tree.spatial.kd.MinimalisticMemoryKDTree
-de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mtree.MTreeIndex
-de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp.MkAppTreeIndex
-# de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop.MkCoPTreeIndex
-de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax.MkMaxTreeIndex
-de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab.MkTabTreeIndex
-de.lmu.ifi.dbs.elki.index.vafile.PartialVAFile
-de.lmu.ifi.dbs.elki.index.vafile.VAFile
-de.lmu.ifi.dbs.elki.index.projected.LatLngAsECEFIndex
-de.lmu.ifi.dbs.elki.index.projected.LngLatAsECEFIndex
-de.lmu.ifi.dbs.elki.index.projected.ProjectedIndex
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.preprocessed.LocalProjectionIndex$Factory b/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.preprocessed.LocalProjectionIndex$Factory
index 296ec2ae..b681224d 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.preprocessed.LocalProjectionIndex$Factory
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.preprocessed.LocalProjectionIndex$Factory
@@ -1,4 +1,2 @@
de.lmu.ifi.dbs.elki.index.preprocessed.localpca.KNNQueryFilteredPCAIndex$Factory
-de.lmu.ifi.dbs.elki.index.preprocessed.localpca.RangeQueryFilteredPCAIndex$Factory
-de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj.FourCSubspaceIndex$Factory
-de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj.PreDeConSubspaceIndex$Factory
+
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.preprocessed.localpca.FilteredLocalPCAIndex$Factory b/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.preprocessed.localpca.FilteredLocalPCAIndex$Factory
index 6d19b635..12081c35 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.preprocessed.localpca.FilteredLocalPCAIndex$Factory
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.preprocessed.localpca.FilteredLocalPCAIndex$Factory
@@ -1,2 +1 @@
de.lmu.ifi.dbs.elki.index.preprocessed.localpca.KNNQueryFilteredPCAIndex$Factory
-de.lmu.ifi.dbs.elki.index.preprocessed.localpca.RangeQueryFilteredPCAIndex$Factory
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj.SubspaceProjectionIndex$Factory b/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj.SubspaceProjectionIndex$Factory
deleted file mode 100644
index 577610dc..00000000
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj.SubspaceProjectionIndex$Factory
+++ /dev/null
@@ -1,2 +0,0 @@
-de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj.FourCSubspaceIndex$Factory
-de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj.PreDeConSubspaceIndex$Factory
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert.ReinsertStrategy b/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert.ReinsertStrategy
new file mode 100644
index 00000000..55129226
--- /dev/null
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert.ReinsertStrategy
@@ -0,0 +1,2 @@
+de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert.CloseReinsert
+de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert.FarReinsert
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.math.statistics.dependence.DependenceMeasure b/src/META-INF/elki/de.lmu.ifi.dbs.elki.math.statistics.dependence.DependenceMeasure
new file mode 100644
index 00000000..36cfc5d9
--- /dev/null
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.math.statistics.dependence.DependenceMeasure
@@ -0,0 +1,12 @@
+de.lmu.ifi.dbs.elki.math.statistics.dependence.CorrelationDependenceMeasure
+de.lmu.ifi.dbs.elki.math.statistics.dependence.SpearmanCorrelationDependenceMeasure
+de.lmu.ifi.dbs.elki.math.statistics.dependence.DistanceCorrelationDependenceMeasure
+de.lmu.ifi.dbs.elki.math.statistics.dependence.MutualInformationEquiwidthDependenceMeasure
+de.lmu.ifi.dbs.elki.math.statistics.dependence.JensenShannonEquiwidthDependenceMeasure
+de.lmu.ifi.dbs.elki.math.statistics.dependence.HoeffdingsDDependenceMeasure
+de.lmu.ifi.dbs.elki.math.statistics.dependence.MCEDependenceMeasure
+de.lmu.ifi.dbs.elki.math.statistics.dependence.SlopeDependenceMeasure
+de.lmu.ifi.dbs.elki.math.statistics.dependence.SlopeInversionDependenceMeasure
+de.lmu.ifi.dbs.elki.math.statistics.dependence.HSMDependenceMeasure
+de.lmu.ifi.dbs.elki.math.statistics.dependence.HiCSDependenceMeasure
+de.lmu.ifi.dbs.elki.math.statistics.dependence.SURFINGDependenceMeasure
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.result.ResultHandler b/src/META-INF/elki/de.lmu.ifi.dbs.elki.result.ResultHandler
index d14bbc81..b785748d 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.result.ResultHandler
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.result.ResultHandler
@@ -1,8 +1,7 @@
de.lmu.ifi.dbs.elki.result.ResultWriter
-de.lmu.ifi.dbs.elki.visualization.gui.ResultVisualizer
+de.lmu.ifi.dbs.elki.result.ClusteringVectorDumper
de.lmu.ifi.dbs.elki.result.DiscardResultHandler
de.lmu.ifi.dbs.elki.result.KMLOutputHandler
-de.lmu.ifi.dbs.elki.visualization.ExportVisualizations
de.lmu.ifi.dbs.elki.application.jsmap.JSONResultHandler
de.lmu.ifi.dbs.elki.result.LogResultStructureResultHandler
tutorial.outlier.SimpleScoreDumper \ No newline at end of file
diff --git a/src/META-INF/elki/de.lmu.ifi.dbs.elki.visualization.visualizers.VisFactory b/src/META-INF/elki/de.lmu.ifi.dbs.elki.visualization.visualizers.VisFactory
index a4c5e72f..8e233817 100644
--- a/src/META-INF/elki/de.lmu.ifi.dbs.elki.visualization.visualizers.VisFactory
+++ b/src/META-INF/elki/de.lmu.ifi.dbs.elki.visualization.visualizers.VisFactory
@@ -36,7 +36,7 @@ de.lmu.ifi.dbs.elki.visualization.visualizers.parallel.selection.SelectionToolAx
de.lmu.ifi.dbs.elki.visualization.visualizers.parallel.selection.SelectionToolLineVisualization
de.lmu.ifi.dbs.elki.visualization.visualizers.pairsegments.CircleSegmentsVisualizer
de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.HistogramVisualization
-de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.ClusterEvaluationVisualization
+de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.EvaluationVisualization
de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.XYCurveVisualization
de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.LabelVisualization
de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.PixmapVisualizer
diff --git a/src/de/lmu/ifi/dbs/elki/KDDTask.java b/src/de/lmu/ifi/dbs/elki/KDDTask.java
index 38570301..4cc03df2 100644
--- a/src/de/lmu/ifi/dbs/elki/KDDTask.java
+++ b/src/de/lmu/ifi/dbs/elki/KDDTask.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki;
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,27 +25,23 @@ package de.lmu.ifi.dbs.elki;
import java.util.Collection;
-import de.lmu.ifi.dbs.elki.algorithm.Algorithm;
import de.lmu.ifi.dbs.elki.application.KDDCLIApplication;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.SettingsResult;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackedParameter;
import de.lmu.ifi.dbs.elki.workflow.AlgorithmStep;
import de.lmu.ifi.dbs.elki.workflow.EvaluationStep;
import de.lmu.ifi.dbs.elki.workflow.InputStep;
import de.lmu.ifi.dbs.elki.workflow.OutputStep;
/**
- * Provides a KDDTask that can be used to perform any algorithm implementing
- * {@link Algorithm Algorithm} using any DatabaseConnection implementing
- * {@link de.lmu.ifi.dbs.elki.datasource.DatabaseConnection DatabaseConnection}.
+ * KDDTask encapsulates the common workflow of an <i>unsupervised</i> knowledge
+ * discovery task.
*
* @author Arthur Zimek
*
@@ -54,11 +50,11 @@ import de.lmu.ifi.dbs.elki.workflow.OutputStep;
* @apiviz.composedOf EvaluationStep
* @apiviz.composedOf OutputStep
*/
-public class KDDTask implements Parameterizable {
+public class KDDTask {
/**
* The settings used, for settings reporting.
*/
- private Collection<Pair<Object, Parameter<?>>> settings;
+ private Collection<TrackedParameter> settings;
/**
* The data input step
@@ -94,7 +90,7 @@ public class KDDTask implements Parameterizable {
* @param outputStep
* @param settings
*/
- public KDDTask(InputStep inputStep, AlgorithmStep algorithmStep, EvaluationStep evaluationStep, OutputStep outputStep, Collection<Pair<Object, Parameter<?>>> settings) {
+ public KDDTask(InputStep inputStep, AlgorithmStep algorithmStep, EvaluationStep evaluationStep, OutputStep outputStep, Collection<TrackedParameter> settings) {
super();
this.inputStep = inputStep;
this.algorithmStep = algorithmStep;
@@ -147,7 +143,7 @@ public class KDDTask implements Parameterizable {
EvaluationStep evaluationStep = null;
- Collection<Pair<Object, Parameter<?>>> settings = null;
+ Collection<TrackedParameter> settings = null;
OutputStep outputStep = null;
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/APRIORI.java b/src/de/lmu/ifi/dbs/elki/algorithm/APRIORI.java
deleted file mode 100644
index a2f32989..00000000
--- a/src/de/lmu/ifi/dbs/elki/algorithm/APRIORI.java
+++ /dev/null
@@ -1,356 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm;
-
-/*
- 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.ArrayList;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import de.lmu.ifi.dbs.elki.data.BitVector;
-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.Database;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.result.AprioriResult;
-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;
-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.constraints.OneMustBeSetGlobalConstraint;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.OnlyOneIsAllowedToBeSetGlobalConstraint;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
-
-/**
- * Provides the APRIORI algorithm for Mining Association Rules.
- * <p>
- * Reference: <br>
- * R. Agrawal, R. Srikant: Fast Algorithms for Mining Association Rules in Large
- * Databases. <br>
- * In Proc. 20th Int. Conf. on Very Large Data Bases (VLDB '94), Santiago de
- * Chile, Chile 1994.
- * </p>
- *
- * @author Arthur Zimek
- */
-@Title("APRIORI: Algorithm for Mining Association Rules")
-@Description("Searches for frequent itemsets")
-@Reference(authors = "R. Agrawal, R. Srikant", title = "Fast Algorithms for Mining Association Rules in Large Databases", booktitle = "Proc. 20th Int. Conf. on Very Large Data Bases (VLDB '94), Santiago de Chile, Chile 1994", url = "http://www.acm.org/sigmod/vldb/conf/1994/P487.PDF")
-public class APRIORI extends AbstractAlgorithm<AprioriResult> {
- /**
- * The logger for this class.
- */
- private static final Logging LOG = Logging.getLogger(APRIORI.class);
-
- /**
- * Optional parameter to specify the threshold for minimum frequency, must be
- * a double greater than or equal to 0 and less than or equal to 1.
- * Alternatively to parameter {@link #MINSUPP_ID}).
- */
- public static final OptionID MINFREQ_ID = new OptionID("apriori.minfreq", "Threshold for minimum frequency as percentage value " + "(alternatively to parameter apriori.minsupp).");
-
- /**
- * Parameter to specify the threshold for minimum support as minimally
- * required number of transactions, must be an integer equal to or greater
- * than 0. Alternatively to parameter {@link #MINFREQ_ID} - setting
- * {@link #MINSUPP_ID} is slightly preferable over setting {@link #MINFREQ_ID}
- * in terms of efficiency.
- */
- public static final OptionID MINSUPP_ID = new OptionID("apriori.minsupp", "Threshold for minimum support as minimally required number of transactions " + "(alternatively to parameter apriori.minfreq" + " - setting apriori.minsupp is slightly preferable over setting " + "apriori.minfreq in terms of efficiency).");
-
- /**
- * Holds the value of {@link #MINFREQ_ID}.
- */
- private double minfreq = Double.NaN;
-
- /**
- * Holds the value of {@link #MINSUPP_ID}.
- */
- private int minsupp = Integer.MIN_VALUE;
-
- /**
- * Constructor with minimum frequency.
- *
- * @param minfreq Minimum frequency
- */
- public APRIORI(double minfreq) {
- super();
- this.minfreq = minfreq;
- }
-
- /**
- * Constructor with minimum support.
- *
- * @param minsupp Minimum support
- */
- public APRIORI(int minsupp) {
- super();
- this.minsupp = minsupp;
- }
-
- /**
- * Performs the APRIORI algorithm on the given database.
- *
- * @param database the Database to run APRIORI on
- * @param relation the Relation to process
- * @return the AprioriResult learned by this APRIORI
- */
- public AprioriResult run(Database database, Relation<BitVector> relation) {
- Map<BitSet, Integer> support = new HashMap<>();
- List<BitSet> solution = new ArrayList<>();
- final int size = relation.size();
- if(size > 0) {
- int dim;
- try {
- dim = RelationUtil.dimensionality(relation);
- }
- catch(UnsupportedOperationException e) {
- dim = 0;
- }
- BitSet[] candidates = new BitSet[dim];
- for(int i = 0; i < dim; i++) {
- candidates[i] = new BitSet();
- candidates[i].set(i);
- }
- while(candidates.length > 0) {
- StringBuilder msg = new StringBuilder();
- BitSet[] frequentItemsets = frequentItemsets(support, candidates, relation);
- if(LOG.isVerbose()) {
- msg.append("\ncandidates").append(Arrays.asList(candidates));
- msg.append("\nfrequentItemsets").append(Arrays.asList(frequentItemsets));
- }
- for(BitSet bitSet : frequentItemsets) {
- solution.add(bitSet);
- }
- BitSet[] joined = join(frequentItemsets);
- candidates = prune(support, joined, size);
- if(LOG.isVerbose()) {
- msg.append("\ncandidates after pruning").append(Arrays.asList(candidates));
- LOG.verbose(msg.toString());
- }
- }
- }
- return new AprioriResult("APRIORI", "apriori", solution, support);
- }
-
- /**
- * Prunes a given set of candidates to keep only those BitSets where all
- * subsets of bits flipping one bit are frequent already.
- *
- * @param support Support map
- * @param candidates the candidates to be pruned
- * @param size size of the database
- * @return a set of BitSets where all subsets of bits flipping one bit are
- * frequent already
- */
- protected BitSet[] prune(Map<BitSet, Integer> support, BitSet[] candidates, int size) {
- List<BitSet> candidateList = new ArrayList<>();
- // MinFreq pruning
- if(minfreq >= 0) {
- for(BitSet bitSet : candidates) {
- boolean unpruned = true;
- for(int i = bitSet.nextSetBit(0); i >= 0 && unpruned; i = bitSet.nextSetBit(i + 1)) {
- bitSet.clear(i);
- if(support.get(bitSet) != null) {
- unpruned = support.get(bitSet).doubleValue() / size >= minfreq;
- }
- else {
- unpruned = false;
- // logger.warning("Support not found for bitSet " + bitSet);
- }
- bitSet.set(i);
- }
- if(unpruned) {
- candidateList.add(bitSet);
- }
- }
- }
- else {
- // Minimum support pruning
- for(BitSet bitSet : candidates) {
- boolean unpruned = true;
- for(int i = bitSet.nextSetBit(0); i >= 0 && unpruned; i = bitSet.nextSetBit(i + 1)) {
- bitSet.clear(i);
- if(support.get(bitSet) != null) {
- unpruned = support.get(bitSet) >= minsupp;
- }
- else {
- unpruned = false;
- // logger.warning("Support not found for bitSet " + bitSet);
- }
- bitSet.set(i);
- }
- if(unpruned) {
- candidateList.add(bitSet);
- }
- }
- }
- return candidateList.toArray(new BitSet[candidateList.size()]);
- }
-
- /**
- * Returns a set of BitSets generated by joining pairs of given BitSets
- * (relying on the given BitSets being sorted), increasing the length by 1.
- *
- * @param frequentItemsets the BitSets to be joined
- * @return a set of BitSets generated by joining pairs of given BitSets,
- * increasing the length by 1
- */
- protected BitSet[] join(BitSet[] frequentItemsets) {
- List<BitSet> joined = new ArrayList<>();
- for(int i = 0; i < frequentItemsets.length; i++) {
- for(int j = i + 1; j < frequentItemsets.length; j++) {
- BitSet b1 = (BitSet) frequentItemsets[i].clone();
- BitSet b2 = (BitSet) frequentItemsets[j].clone();
- int b1i = b1.length() - 1;
- int b2i = b2.length() - 1;
- b1.clear(b1i);
- b2.clear(b2i);
- if(b1.equals(b2)) {
- b1.set(b1i);
- b1.set(b2i);
- joined.add(b1);
- }
- }
- }
- return joined.toArray(new BitSet[joined.size()]);
- }
-
- /**
- * Returns the frequent BitSets out of the given BitSets with respect to the
- * given database.
- *
- * @param support Support map.
- * @param candidates the candidates to be evaluated
- * @param database the database to evaluate the candidates on
- * @return the frequent BitSets out of the given BitSets with respect to the
- * given database
- */
- protected BitSet[] frequentItemsets(Map<BitSet, Integer> support, BitSet[] candidates, Relation<BitVector> database) {
- for(BitSet bitSet : candidates) {
- if(support.get(bitSet) == null) {
- support.put(bitSet, 0);
- }
- }
- for(DBIDIter iditer = database.iterDBIDs(); iditer.valid(); iditer.advance()) {
- BitVector bv = database.get(iditer);
- for(BitSet bitSet : candidates) {
- if(bv.contains(bitSet)) {
- support.put(bitSet, support.get(bitSet) + 1);
- }
- }
- }
- List<BitSet> frequentItemsets = new ArrayList<>();
- if(minfreq >= 0.0) {
- // TODO: work with integers?
- double critsupp = minfreq * database.size();
- for(BitSet bitSet : candidates) {
- if(support.get(bitSet).doubleValue() >= critsupp) {
- frequentItemsets.add(bitSet);
- }
- }
- }
- else {
- // Use minimum support
- for(BitSet bitSet : candidates) {
- if(support.get(bitSet) >= minsupp) {
- frequentItemsets.add(bitSet);
- }
- }
- }
- return frequentItemsets.toArray(new BitSet[frequentItemsets.size()]);
- }
-
- @Override
- public TypeInformation[] getInputTypeRestriction() {
- return TypeUtil.array(TypeUtil.BIT_VECTOR_FIELD);
- }
-
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer extends AbstractParameterizer {
- /**
- * Parameter for minFreq.
- */
- protected Double minfreq = null;
-
- /**
- * Parameter for minSupp.
- */
- protected Integer minsupp = null;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- DoubleParameter minfreqP = new DoubleParameter(MINFREQ_ID);
- minfreqP.setOptional(true);
- minfreqP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
- minfreqP.addConstraint(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
- if(config.grab(minfreqP)) {
- minfreq = minfreqP.getValue();
- }
-
- IntParameter minsuppP = new IntParameter(MINSUPP_ID);
- minsuppP.setOptional(true);
- minsuppP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_INT);
- if(config.grab(minsuppP)) {
- minsupp = minsuppP.getValue();
- }
-
- // global parameter constraints
- config.checkConstraint(new OnlyOneIsAllowedToBeSetGlobalConstraint(minfreqP, minsuppP));
- config.checkConstraint(new OneMustBeSetGlobalConstraint(minfreqP, minsuppP));
- }
-
- @Override
- protected APRIORI makeInstance() {
- if(minfreq != null) {
- return new APRIORI(minfreq);
- }
- if(minsupp != null) {
- return new APRIORI(minsupp);
- }
- return null;
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/AbstractAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/AbstractAlgorithm.java
index 65b86633..b4f5b734 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/AbstractAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/AbstractAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm;
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
@@ -152,7 +152,7 @@ public abstract class AbstractAlgorithm<R extends Result> implements Algorithm {
* @param restriction Restriction class
* @return Parameter object
*/
- public static <F extends DistanceFunction<?, ?>> ObjectParameter<F> makeParameterDistanceFunction(Class<?> defaultDistanceFunction, Class<?> restriction) {
+ public static <F extends DistanceFunction<?>> ObjectParameter<F> makeParameterDistanceFunction(Class<?> defaultDistanceFunction, Class<?> restriction) {
return new ObjectParameter<>(DistanceBasedAlgorithm.DISTANCE_FUNCTION_ID, restriction, defaultDistanceFunction);
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/AbstractDistanceBasedAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/AbstractDistanceBasedAlgorithm.java
index 3420e279..e5451a72 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/AbstractDistanceBasedAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/AbstractDistanceBasedAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm;
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,14 +25,13 @@ package de.lmu.ifi.dbs.elki.algorithm;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
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.result.Result;
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.ObjectParameter;
/**
- * Provides an abstract algorithm already setting the distance function.
+ * Abstract base class for distance-based algorithms.
*
* @author Arthur Zimek
*
@@ -41,22 +40,21 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.excludeSubtypes
*
* @param <O> the type of objects handled by this Algorithm
- * @param <D> the type of Distance used by this Algorithm
* @param <R> the type of result to retrieve from this Algorithm
*/
-public abstract class AbstractDistanceBasedAlgorithm<O, D extends Distance<D>, R extends Result> extends AbstractAlgorithm<R> implements DistanceBasedAlgorithm<O, D> {
+public abstract class AbstractDistanceBasedAlgorithm<O, R extends Result> extends AbstractAlgorithm<R> implements DistanceBasedAlgorithm<O> {
/**
* Holds the instance of the distance function specified by
* {@link DistanceBasedAlgorithm#DISTANCE_FUNCTION_ID}.
*/
- private DistanceFunction<? super O, D> distanceFunction;
+ private DistanceFunction<? super O> distanceFunction;
/**
* Constructor.
*
* @param distanceFunction Distance function
*/
- protected AbstractDistanceBasedAlgorithm(DistanceFunction<? super O, D> distanceFunction) {
+ protected AbstractDistanceBasedAlgorithm(DistanceFunction<? super O> distanceFunction) {
super();
this.distanceFunction = distanceFunction;
}
@@ -67,7 +65,7 @@ public abstract class AbstractDistanceBasedAlgorithm<O, D extends Distance<D>, R
* @return the distanceFunction
*/
@Override
- public DistanceFunction<? super O, D> getDistanceFunction() {
+ public DistanceFunction<? super O> getDistanceFunction() {
return distanceFunction;
}
@@ -78,16 +76,16 @@ public abstract class AbstractDistanceBasedAlgorithm<O, D extends Distance<D>, R
*
* @apiviz.exclude
*/
- public abstract static class Parameterizer<O, D extends Distance<D>> extends AbstractParameterizer {
+ public abstract static class Parameterizer<O> extends AbstractParameterizer {
/**
* The distance function to use.
*/
- protected DistanceFunction<O, D> distanceFunction;
+ protected DistanceFunction<O> distanceFunction;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- ObjectParameter<DistanceFunction<O, D>> distanceFunctionP = makeParameterDistanceFunction(EuclideanDistanceFunction.class, DistanceFunction.class);
+ ObjectParameter<DistanceFunction<O>> distanceFunctionP = makeParameterDistanceFunction(EuclideanDistanceFunction.class, DistanceFunction.class);
if(config.grab(distanceFunctionP)) {
distanceFunction = distanceFunctionP.instantiateClass(config);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/AbstractPrimitiveDistanceBasedAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/AbstractPrimitiveDistanceBasedAlgorithm.java
index 5d4b24c1..5186e9e0 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/AbstractPrimitiveDistanceBasedAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/AbstractPrimitiveDistanceBasedAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm;
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,17 @@ package de.lmu.ifi.dbs.elki.algorithm;
import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
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.result.Result;
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.ObjectParameter;
/**
- * Provides an abstract algorithm already setting the distance function.
+ * Abstract base class for distance-based algorithms that need to work with
+ * synthetic objects such as mean vectors.
*
- * This class only allows distances that are defined on arbitrary objects, not only database objects!
+ * This class only allows distances that are defined on arbitrary objects, not
+ * only database objects!
*
* @author Arthur Zimek
*
@@ -42,22 +43,21 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.excludeSubtypes
*
* @param <O> the type of objects handled by this Algorithm
- * @param <D> the type of Distance used by this Algorithm
* @param <R> the type of result to retrieve from this Algorithm
*/
-public abstract class AbstractPrimitiveDistanceBasedAlgorithm<O, D extends Distance<?>, R extends Result> extends AbstractAlgorithm<R> {
+public abstract class AbstractPrimitiveDistanceBasedAlgorithm<O, R extends Result> extends AbstractAlgorithm<R> {
/**
* Holds the instance of the distance function specified by
* {@link DistanceBasedAlgorithm#DISTANCE_FUNCTION_ID}.
*/
- protected PrimitiveDistanceFunction<? super O, D> distanceFunction;
+ protected PrimitiveDistanceFunction<? super O> distanceFunction;
/**
* Constructor.
*
* @param distanceFunction Distance function
*/
- protected AbstractPrimitiveDistanceBasedAlgorithm(PrimitiveDistanceFunction<? super O, D> distanceFunction) {
+ protected AbstractPrimitiveDistanceBasedAlgorithm(PrimitiveDistanceFunction<? super O> distanceFunction) {
super();
this.distanceFunction = distanceFunction;
}
@@ -67,7 +67,7 @@ public abstract class AbstractPrimitiveDistanceBasedAlgorithm<O, D extends Dista
*
* @return the distanceFunction
*/
- public PrimitiveDistanceFunction<? super O, D> getDistanceFunction() {
+ public PrimitiveDistanceFunction<? super O> getDistanceFunction() {
return distanceFunction;
}
@@ -78,16 +78,16 @@ public abstract class AbstractPrimitiveDistanceBasedAlgorithm<O, D extends Dista
*
* @apiviz.exclude
*/
- public abstract static class Parameterizer<O, D extends Distance<D>> extends AbstractParameterizer {
+ public abstract static class Parameterizer<O> extends AbstractParameterizer {
/**
* Distance function to use.
*/
- protected PrimitiveDistanceFunction<O, D> distanceFunction;
-
+ protected PrimitiveDistanceFunction<O> distanceFunction;
+
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- ObjectParameter<PrimitiveDistanceFunction<O, D>> distanceFunctionP = makeParameterDistanceFunction(EuclideanDistanceFunction.class, PrimitiveDistanceFunction.class);
+ ObjectParameter<PrimitiveDistanceFunction<O>> distanceFunctionP = makeParameterDistanceFunction(EuclideanDistanceFunction.class, PrimitiveDistanceFunction.class);
if(config.grab(distanceFunctionP)) {
distanceFunction = distanceFunctionP.instantiateClass(config);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/Algorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/Algorithm.java
index 9b367db4..0ad40557 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/Algorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/Algorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm;
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.algorithm;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.result.Result;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* <p>
@@ -47,7 +46,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
*
* @author Arthur Zimek
*/
-public interface Algorithm extends Parameterizable {
+public interface Algorithm {
/**
* Runs the algorithm.
*
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/DependencyDerivator.java b/src/de/lmu/ifi/dbs/elki/algorithm/DependencyDerivator.java
index dca3649e..ee43ecf4 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/DependencyDerivator.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/DependencyDerivator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm;
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
@@ -33,11 +33,10 @@ import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.Database;
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.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Centroid;
import de.lmu.ifi.dbs.elki.math.linearalgebra.LinearEquationSystem;
@@ -72,12 +71,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*
* @author Arthur Zimek
* @param <V> the type of FeatureVector handled by this Algorithm
- * @param <D> the type of Distance used by this Algorithm
*/
@Title("Dependency Derivator: Deriving numerical inter-dependencies on data")
@Description("Derives an equality-system describing dependencies between attributes in a correlation-cluster")
@Reference(authors = "E. Achtert, C. Böhm, H.-P. Kriegel, P. Kröger, A. Zimek", title = "Deriving Quantitative Dependencies for Correlation Clusters", booktitle = "Proc. 12th Int. Conf. on Knowledge Discovery and Data Mining (KDD '06), Philadelphia, PA 2006.", url = "http://dx.doi.org/10.1145/1150402.1150408")
-public class DependencyDerivator<V extends NumberVector<?>, D extends Distance<D>> extends AbstractPrimitiveDistanceBasedAlgorithm<V, D, CorrelationAnalysisSolution<V>> {
+public class DependencyDerivator<V extends NumberVector> extends AbstractPrimitiveDistanceBasedAlgorithm<V, CorrelationAnalysisSolution<V>> {
/**
* The logger for this class.
*/
@@ -112,7 +110,7 @@ public class DependencyDerivator<V extends NumberVector<?>, D extends Distance<D
/**
* Holds the object performing the pca.
*/
- private final PCAFilteredRunner<V> pca;
+ private final PCAFilteredRunner pca;
/**
* Number format for output of solution.
@@ -133,7 +131,7 @@ public class DependencyDerivator<V extends NumberVector<?>, D extends Distance<D
* @param sampleSize sample size
* @param randomsample flag for random sampling
*/
- public DependencyDerivator(PrimitiveDistanceFunction<V, D> distanceFunction, NumberFormat nf, PCAFilteredRunner<V> pca, int sampleSize, boolean randomsample) {
+ public DependencyDerivator(PrimitiveDistanceFunction<V> distanceFunction, NumberFormat nf, PCAFilteredRunner pca, int sampleSize, boolean randomsample) {
super(distanceFunction);
this.nf = nf;
this.pca = pca;
@@ -162,8 +160,8 @@ public class DependencyDerivator<V extends NumberVector<?>, D extends Distance<D
ids = DBIDUtil.randomSample(relation.getDBIDs(), this.sampleSize, 1L);
}
else {
- DistanceQuery<V, D> distanceQuery = database.getDistanceQuery(relation, getDistanceFunction());
- KNNList<D> queryResults = database.getKNNQuery(distanceQuery, this.sampleSize).getKNNForObject(centroidDV, this.sampleSize);
+ DistanceQuery<V> distanceQuery = database.getDistanceQuery(relation, getDistanceFunction());
+ KNNList queryResults = database.getKNNQuery(distanceQuery, this.sampleSize).getKNNForObject(centroidDV, this.sampleSize);
ids = DBIDUtil.newHashSet(queryResults);
}
}
@@ -221,7 +219,7 @@ public class DependencyDerivator<V extends NumberVector<?>, D extends Distance<D
log.append("Transposed weak Eigenvectors:\n");
log.append(FormatUtil.format(transposedWeakEigenvectors, nf)).append('\n');
log.append("Eigenvalues:\n");
- log.append(FormatUtil.format(pcares.getEigenvalues(), " , ", 2));
+ log.append(FormatUtil.format(pcares.getEigenvalues(), ", ", nf));
LOG.debugFine(log.toString());
}
Vector b = transposedWeakEigenvectors.times(centroid);
@@ -279,7 +277,7 @@ public class DependencyDerivator<V extends NumberVector<?>, D extends Distance<D
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends Distance<D>> extends AbstractPrimitiveDistanceBasedAlgorithm.Parameterizer<V, D> {
+ public static class Parameterizer<V extends NumberVector> extends AbstractPrimitiveDistanceBasedAlgorithm.Parameterizer<V> {
/**
* Output accuracy.
*/
@@ -298,7 +296,7 @@ public class DependencyDerivator<V extends NumberVector<?>, D extends Distance<D
/**
* Class to compute PCA with
*/
- protected PCAFilteredRunner<V> pca = null;
+ protected PCAFilteredRunner pca = null;
@Override
protected void makeOptions(Parameterization config) {
@@ -321,12 +319,12 @@ public class DependencyDerivator<V extends NumberVector<?>, D extends Distance<D
if(config.grab(randomSampleF)) {
randomSample = randomSampleF.getValue();
}
- Class<PCAFilteredRunner<V>> cls = ClassGenericsUtil.uglyCastIntoSubclass(PCAFilteredRunner.class);
+ Class<PCAFilteredRunner> cls = ClassGenericsUtil.uglyCastIntoSubclass(PCAFilteredRunner.class);
pca = config.tryInstantiate(cls);
}
@Override
- protected DependencyDerivator<V, D> makeInstance() {
+ protected DependencyDerivator<V> makeInstance() {
NumberFormat nf = NumberFormat.getInstance(Locale.US);
nf.setMaximumFractionDigits(outputAccuracy);
nf.setMinimumFractionDigits(outputAccuracy);
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/DistanceBasedAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/DistanceBasedAlgorithm.java
index 048d2782..cffb078d 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/DistanceBasedAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/DistanceBasedAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm;
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.algorithm;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
/**
@@ -32,9 +31,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public interface DistanceBasedAlgorithm<O, D extends Distance<?>> extends Algorithm {
+public interface DistanceBasedAlgorithm<O> extends Algorithm {
/**
* OptionID for {@link #DISTANCE_FUNCTION_ID}.
*/
@@ -45,5 +43,5 @@ public interface DistanceBasedAlgorithm<O, D extends Distance<?>> extends Algori
*
* @return the distanceFunction
*/
- DistanceFunction<? super O, D> getDistanceFunction();
+ DistanceFunction<? super O> getDistanceFunction();
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/DummyAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/DummyAlgorithm.java
index 24de36ce..c87ddf85 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/DummyAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/DummyAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm;
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,7 +32,6 @@ 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.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
@@ -53,7 +52,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
*/
@Title("Dummy Algorithm")
@Description("The algorithm executes an Euclidean 10NN query on all data points, and can be used in unit testing")
-public class DummyAlgorithm<O extends NumberVector<?>> extends AbstractAlgorithm<Result> {
+public class DummyAlgorithm<O extends NumberVector> extends AbstractAlgorithm<Result> {
/**
* The logger for this class.
*/
@@ -76,8 +75,8 @@ public class DummyAlgorithm<O extends NumberVector<?>> extends AbstractAlgorithm
public Result run(Database database, Relation<O> relation) {
// Get a distance and knn query for the Euclidean distance
// Hardcoded, only use this if you only allow the eucliden distance
- DistanceQuery<O, DoubleDistance> distQuery = database.getDistanceQuery(relation, EuclideanDistanceFunction.STATIC);
- KNNQuery<O, DoubleDistance> knnQuery = database.getKNNQuery(distQuery, 10);
+ DistanceQuery<O> distQuery = database.getDistanceQuery(relation, EuclideanDistanceFunction.STATIC);
+ KNNQuery<O> knnQuery = database.getKNNQuery(distQuery, 10);
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
// Get the actual object from the database (but discard the result)
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/KNNDistanceOrder.java b/src/de/lmu/ifi/dbs/elki/algorithm/KNNDistanceOrder.java
deleted file mode 100644
index 46cf2246..00000000
--- a/src/de/lmu/ifi/dbs/elki/algorithm/KNNDistanceOrder.java
+++ /dev/null
@@ -1,184 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm;
-
-/*
- 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.ArrayList;
-import java.util.Collections;
-import java.util.List;
-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.Database;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.result.KNNDistanceOrderResult;
-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.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;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
-
-/**
- * Provides an order of the kNN-distances for all objects within the database.
- *
- * @author Arthur Zimek
- * @param <O> the type of DatabaseObjects handled by this Algorithm
- * @param <D> the type of Distance used by this Algorithm
- */
-// TODO: redundant to kNN outlier detection?
-@Title("KNN-Distance-Order")
-@Description("Assesses the knn distances for a specified k and orders them.")
-public class KNNDistanceOrder<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm<O, D, KNNDistanceOrderResult<D>> {
- /**
- * The logger for this class.
- */
- private static final Logging LOG = Logging.getLogger(KNNDistanceOrder.class);
-
- /**
- * Parameter to specify the distance of the k-distant object to be assessed,
- * must be an integer greater than 0.
- */
- public static final OptionID K_ID = new OptionID("knndistanceorder.k", "Specifies the distance of the k-distant object to be assessed.");
-
- /**
- * Holds the value of {@link #K_ID}.
- */
- private int k;
-
- /**
- * Parameter to specify the average percentage of distances randomly chosen to
- * be provided in the result, must be a double greater than 0 and less than or
- * equal to 1.
- */
- public static final OptionID PERCENTAGE_ID = new OptionID("knndistanceorder.percentage", "The average percentage of distances randomly choosen to be provided in the result.");
-
- /**
- * Holds the value of {@link #PERCENTAGE_ID}.
- */
- private double percentage;
-
- /**
- * Constructor.
- *
- * @param distanceFunction Distance function
- * @param k k Parameter
- * @param percentage percentage parameter
- */
- public KNNDistanceOrder(DistanceFunction<O, D> distanceFunction, int k, double percentage) {
- super(distanceFunction);
- this.k = k;
- this.percentage = percentage;
- }
-
- /**
- * Provides an order of the kNN-distances for all objects within the specified
- * database.
- *
- * @param database Database
- * @param relation Relation
- * @return Result
- */
- public KNNDistanceOrderResult<D> run(Database database, Relation<O> relation) {
- final DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, getDistanceFunction());
- final KNNQuery<O, D> knnQuery = database.getKNNQuery(distanceQuery, k);
-
- final Random random = new Random();
- List<D> knnDistances = new ArrayList<>(relation.size());
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- if(random.nextDouble() < percentage) {
- final KNNList<D> neighbors = knnQuery.getKNNForDBID(iditer, k);
- knnDistances.add(neighbors.getKNNDistance());
- }
- }
- Collections.sort(knnDistances, Collections.reverseOrder());
- return new KNNDistanceOrderResult<>("kNN distance order", "knn-order", knnDistances);
- }
-
- @Override
- public TypeInformation[] getInputTypeRestriction() {
- return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
- }
-
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
- /**
- * Parameter k.
- */
- protected int k;
-
- /**
- * Percentage.
- */
- protected double percentage;
-
- /**
- * Constructor.
- */
- public Parameterizer() {
- super();
- }
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- IntParameter kP = new IntParameter(K_ID, 1);
- kP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
- if(config.grab(kP)) {
- k = kP.getValue();
- }
-
- DoubleParameter percentageP = new DoubleParameter(PERCENTAGE_ID, 1.0);
- percentageP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
- percentageP.addConstraint(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
- if(config.grab(percentageP)) {
- percentage = percentageP.getValue();
- }
- }
-
- @Override
- protected KNNDistanceOrder<O, D> makeInstance() {
- return new KNNDistanceOrder<>(distanceFunction, k, percentage);
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/KNNDistancesSampler.java b/src/de/lmu/ifi/dbs/elki/algorithm/KNNDistancesSampler.java
new file mode 100644
index 00000000..42cfef2c
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/KNNDistancesSampler.java
@@ -0,0 +1,268 @@
+package de.lmu.ifi.dbs.elki.algorithm;
+
+/*
+ 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 java.util.Iterator;
+
+import de.lmu.ifi.dbs.elki.algorithm.KNNDistancesSampler.KNNDistanceOrderResult;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+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.KNNList;
+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.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+import de.lmu.ifi.dbs.elki.result.BasicResult;
+import de.lmu.ifi.dbs.elki.result.IterableResult;
+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.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;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
+
+/**
+ * Provides an order of the kNN-distances for all objects within the database.
+ *
+ * This class can be used to estimate parameters for other algorithms, such as
+ * estimating the epsilon parameter for DBSCAN: set k to minPts-1, and then
+ * choose a percentile from the sample as epsilon, or plot the result as a graph
+ * and look for a bend or knee in this plot.
+ *
+ * @author Arthur Zimek
+ *
+ * @param <O> the type of objects handled by this Algorithm
+ */
+@Title("KNN-Distance-Order")
+@Description("Assesses the knn distances for a specified k and orders them.")
+public class KNNDistancesSampler<O> extends AbstractDistanceBasedAlgorithm<O, KNNDistanceOrderResult> {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(KNNDistancesSampler.class);
+
+ /**
+ * Parameter k.
+ */
+ protected int k;
+
+ /**
+ * Sampling percentage.
+ */
+ protected double sample;
+
+ /**
+ * Random number seeding.
+ */
+ private RandomFactory rnd;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function
+ * @param k k Parameter
+ * @param sample Sampling rate, or sample size (when > 1)
+ * @param rnd Random source.
+ */
+ public KNNDistancesSampler(DistanceFunction<O> distanceFunction, int k, double sample, RandomFactory rnd) {
+ super(distanceFunction);
+ this.k = k;
+ this.sample = sample;
+ this.rnd = rnd;
+ }
+
+ /**
+ * Provides an order of the kNN-distances for all objects within the specified
+ * database.
+ *
+ * @param database Database
+ * @param relation Relation
+ * @return Result
+ */
+ public KNNDistanceOrderResult run(Database database, Relation<O> relation) {
+ final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, getDistanceFunction());
+ final KNNQuery<O> knnQuery = database.getKNNQuery(distanceQuery, k + 1);
+
+ final int size = (int) ((sample <= 1.) ? Math.ceil(relation.size() * sample) : sample);
+ DBIDs sample = DBIDUtil.randomSample(relation.getDBIDs(), size, rnd);
+
+ FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Sampling kNN distances.", size, LOG) : null;
+ double[] knnDistances = new double[size];
+ int i = 0;
+ for(DBIDIter iditer = sample.iter(); iditer.valid(); iditer.advance(), i++) {
+ final KNNList neighbors = knnQuery.getKNNForDBID(iditer, k + 1);
+ knnDistances[i] = neighbors.getKNNDistance();
+ LOG.incrementProcessed(prog);
+ }
+ Arrays.sort(knnDistances);
+ LOG.ensureCompleted(prog);
+ return new KNNDistanceOrderResult("kNN distances sample", "knn-distances", knnDistances);
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Wraps a list containing the knn distances.
+ *
+ * @author Arthur Zimek
+ *
+ * @apiviz.exclude
+ */
+ public static class KNNDistanceOrderResult extends BasicResult implements IterableResult<Double> {
+ /**
+ * Store the kNN Distances
+ */
+ private final double[] knnDistances;
+
+ /**
+ * Construct result
+ *
+ * @param name The long name (for pretty printing)
+ * @param shortname the short name (for filenames etc.)
+ * @param knnDistances distance list to wrap.
+ */
+ public KNNDistanceOrderResult(String name, String shortname, final double[] knnDistances) {
+ super(name, shortname);
+ this.knnDistances = knnDistances;
+ }
+
+ /**
+ * Return an iterator.
+ */
+ @Override
+ public Iterator<Double> iterator() {
+ return new Iterator<Double>() {
+ int pos = 0;
+
+ @Override
+ public boolean hasNext() {
+ return (pos < knnDistances.length);
+ }
+
+ @Override
+ public Double next() {
+ return knnDistances[pos++];
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * Parameter to specify the distance of the k-distant object to be assessed,
+ * must be an integer greater than 0.
+ */
+ public static final OptionID K_ID = new OptionID("knndistanceorder.k", "Specifies the distance of the k-distant object to be assessed, ignoring the query object.");
+
+ /**
+ * Parameter to specify the average percentage of distances randomly chosen
+ * to be provided in the result, must be a double greater than 0 and less
+ * than or equal to 1.
+ */
+ public static final OptionID SAMPLING_ID = new OptionID("knndistanceorder.sample", "The percentage of objects to use for sampling, or the absolute number of samples.");
+
+ /**
+ * Random generator seed for distances.
+ */
+ public static final OptionID SEED_ID = new OptionID("knndistanceorder.seed", "Random generator seed for sampling.");
+
+ /**
+ * Parameter k.
+ */
+ protected int k;
+
+ /**
+ * Sampling percentage.
+ */
+ protected double percentage;
+
+ /**
+ * Random number seeding.
+ */
+ private RandomFactory rnd;
+
+ /**
+ * Constructor.
+ */
+ public Parameterizer() {
+ super();
+ }
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ IntParameter kP = new IntParameter(K_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(kP)) {
+ k = kP.getValue();
+ }
+
+ DoubleParameter percentageP = new DoubleParameter(SAMPLING_ID, 1.) //
+ .addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ if(config.grab(percentageP)) {
+ percentage = percentageP.getValue();
+ }
+
+ RandomParameter randomP = new RandomParameter(SEED_ID);
+ if(config.grab(randomP)) {
+ rnd = randomP.getValue();
+ }
+ }
+
+ @Override
+ protected KNNDistancesSampler<O> makeInstance() {
+ return new KNNDistancesSampler<>(distanceFunction, k, percentage, rnd);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/KNNJoin.java b/src/de/lmu/ifi/dbs/elki/algorithm/KNNJoin.java
index 0f5078fb..d1acf675 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/KNNJoin.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/KNNJoin.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm;
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
@@ -38,15 +38,11 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
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.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.index.tree.LeafEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialIndexTree;
@@ -78,25 +74,18 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* @author Erich Schubert
*
* @param <V> the type of FeatureVector handled by this Algorithm
- * @param <D> the type of Distance used by this Algorithm
* @param <N> the type of node used in the spatial index structure
* @param <E> the type of entry used in the spatial node
*/
@Title("K-Nearest Neighbor Join")
@Description("Algorithm to find the k-nearest neighbors of each object in a spatial database")
-public class KNNJoin<V extends NumberVector<?>, D extends Distance<D>, N extends SpatialNode<N, E>, E extends SpatialEntry> extends AbstractDistanceBasedAlgorithm<V, D, DataStore<KNNList<D>>> {
+public class KNNJoin<V extends NumberVector, N extends SpatialNode<N, E>, E extends SpatialEntry> extends AbstractDistanceBasedAlgorithm<V, DataStore<KNNList>> {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(KNNJoin.class);
/**
- * Parameter that specifies the k-nearest neighbors to be assigned, must be an
- * integer greater than 0. Default value: 1.
- */
- public static final OptionID K_ID = new OptionID("knnjoin.k", "Specifies the k-nearest neighbors to be assigned.");
-
- /**
* The k parameter.
*/
int k;
@@ -107,7 +96,7 @@ public class KNNJoin<V extends NumberVector<?>, D extends Distance<D>, N extends
* @param distanceFunction Distance function
* @param k k parameter
*/
- public KNNJoin(DistanceFunction<? super V, D> distanceFunction, int k) {
+ public KNNJoin(DistanceFunction<? super V> distanceFunction, int k) {
super(distanceFunction);
this.k = k;
}
@@ -120,7 +109,7 @@ public class KNNJoin<V extends NumberVector<?>, D extends Distance<D>, N extends
* @return result
*/
@SuppressWarnings("unchecked")
- public WritableDataStore<KNNList<D>> run(Database database, Relation<V> relation) {
+ public WritableDataStore<KNNList> run(Database database, Relation<V> relation) {
if(!(getDistanceFunction() instanceof SpatialPrimitiveDistanceFunction)) {
throw new IllegalStateException("Distance Function must be an instance of " + SpatialPrimitiveDistanceFunction.class.getName());
}
@@ -130,13 +119,13 @@ public class KNNJoin<V extends NumberVector<?>, D extends Distance<D>, N extends
}
// FIXME: Ensure were looking at the right relation!
SpatialIndexTree<N, E> index = indexes.iterator().next();
- SpatialPrimitiveDistanceFunction<V, D> distFunction = (SpatialPrimitiveDistanceFunction<V, D>) getDistanceFunction();
+ SpatialPrimitiveDistanceFunction<V> distFunction = (SpatialPrimitiveDistanceFunction<V>) getDistanceFunction();
DBIDs ids = relation.getDBIDs();
// data pages
List<E> ps_candidates = new ArrayList<>(index.getLeaves());
// knn heaps
- List<List<KNNHeap<D>>> heaps = new ArrayList<>(ps_candidates.size());
+ List<List<KNNHeap>> heaps = new ArrayList<>(ps_candidates.size());
ComparableMinHeap<Task> pq = new ComparableMinHeap<>(ps_candidates.size() * ps_candidates.size() / 10);
// Initialize with the page self-pairing
@@ -154,81 +143,65 @@ public class KNNJoin<V extends NumberVector<?>, D extends Distance<D>, N extends
FiniteProgress mprogress = LOG.isVerbose() ? new FiniteProgress("Comparing leaf MBRs", sqsize, LOG) : null;
for(int i = 0; i < ps_candidates.size(); i++) {
E pr_entry = ps_candidates.get(i);
- List<KNNHeap<D>> pr_heaps = heaps.get(i);
- D pr_knn_distance = computeStopDistance(pr_heaps);
+ List<KNNHeap> pr_heaps = heaps.get(i);
+ double pr_knn_distance = computeStopDistance(pr_heaps);
for(int j = i + 1; j < ps_candidates.size(); j++) {
E ps_entry = ps_candidates.get(j);
- List<KNNHeap<D>> ps_heaps = heaps.get(j);
- D ps_knn_distance = computeStopDistance(ps_heaps);
- D minDist = distFunction.minDist(pr_entry, ps_entry);
+ List<KNNHeap> ps_heaps = heaps.get(j);
+ double ps_knn_distance = computeStopDistance(ps_heaps);
+ double minDist = distFunction.minDist(pr_entry, ps_entry);
// Resolve immediately:
- if(minDist.isNullDistance()) {
+ if(minDist <= 0.) {
N pr = index.getNode(ps_candidates.get(i));
N ps = index.getNode(ps_candidates.get(j));
- processDataPagesOptimize(distFunction, pr_heaps, ps_heaps, pr, ps);
+ processDataPages(distFunction, pr_heaps, ps_heaps, pr, ps);
}
- else if(minDist.compareTo(pr_knn_distance) <= 0 || minDist.compareTo(ps_knn_distance) <= 0) {
+ else if(minDist <= pr_knn_distance || minDist <= ps_knn_distance) {
pq.add(new Task(minDist, i, j));
}
- if(mprogress != null) {
- mprogress.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(mprogress);
}
}
- if(mprogress != null) {
- mprogress.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(mprogress);
// Process the queue
FiniteProgress qprogress = LOG.isVerbose() ? new FiniteProgress("Processing queue", pq.size(), LOG) : null;
IndefiniteProgress fprogress = LOG.isVerbose() ? new IndefiniteProgress("Full comparisons", LOG) : null;
while(!pq.isEmpty()) {
Task task = pq.poll();
- List<KNNHeap<D>> pr_heaps = heaps.get(task.i);
- List<KNNHeap<D>> ps_heaps = heaps.get(task.j);
- D pr_knn_distance = computeStopDistance(pr_heaps);
- D ps_knn_distance = computeStopDistance(ps_heaps);
- boolean dor = task.mindist.compareTo(pr_knn_distance) <= 0;
- boolean dos = task.mindist.compareTo(ps_knn_distance) <= 0;
+ List<KNNHeap> pr_heaps = heaps.get(task.i);
+ List<KNNHeap> ps_heaps = heaps.get(task.j);
+ double pr_knn_distance = computeStopDistance(pr_heaps);
+ double ps_knn_distance = computeStopDistance(ps_heaps);
+ boolean dor = task.mindist <= pr_knn_distance;
+ boolean dos = task.mindist <= ps_knn_distance;
if(dor || dos) {
N pr = index.getNode(ps_candidates.get(task.i));
N ps = index.getNode(ps_candidates.get(task.j));
if(dor && dos) {
- processDataPagesOptimize(distFunction, pr_heaps, ps_heaps, pr, ps);
+ processDataPages(distFunction, pr_heaps, ps_heaps, pr, ps);
}
else {
if(dor) {
- processDataPagesOptimize(distFunction, pr_heaps, null, pr, ps);
+ processDataPages(distFunction, pr_heaps, null, pr, ps);
}
else /* dos */{
- processDataPagesOptimize(distFunction, ps_heaps, null, ps, pr);
+ processDataPages(distFunction, ps_heaps, null, ps, pr);
}
}
- if(fprogress != null) {
- fprogress.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(fprogress);
}
- if(qprogress != null) {
- qprogress.incrementProcessed(LOG);
- }
- }
- if(qprogress != null) {
- qprogress.ensureCompleted(LOG);
- }
- if(fprogress != null) {
- fprogress.setCompleted(LOG);
+ LOG.incrementProcessed(qprogress);
}
+ LOG.ensureCompleted(qprogress);
+ LOG.setCompleted(fprogress);
- WritableDataStore<KNNList<D>> knnLists = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_STATIC, KNNList.class);
- // FiniteProgress progress = logger.isVerbose() ? new
- // FiniteProgress(this.getClass().getName(), relation.size(), logger) :
- // null;
+ WritableDataStore<KNNList> knnLists = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_STATIC, KNNList.class);
FiniteProgress pageprog = LOG.isVerbose() ? new FiniteProgress("Number of processed data pages", ps_candidates.size(), LOG) : null;
- // int processed = 0;
for(int i = 0; i < ps_candidates.size(); i++) {
N pr = index.getNode(ps_candidates.get(i));
- List<KNNHeap<D>> pr_heaps = heaps.get(i);
+ List<KNNHeap> pr_heaps = heaps.get(i);
// Finalize lists
for(int j = 0; j < pr.getNumEntries(); j++) {
@@ -236,21 +209,9 @@ public class KNNJoin<V extends NumberVector<?>, D extends Distance<D>, N extends
}
// Forget heaps and pq
heaps.set(i, null);
- // processed += pr.getNumEntries();
-
- // if(progress != null) {
- // progress.setProcessed(processed, logger);
- // }
- if(pageprog != null) {
- pageprog.incrementProcessed(LOG);
- }
- }
- // if(progress != null) {
- // progress.ensureCompleted(logger);
- // }
- if(pageprog != null) {
- pageprog.ensureCompleted(LOG);
+ LOG.incrementProcessed(pageprog);
}
+ LOG.ensureCompleted(pageprog);
return knnLists;
}
@@ -261,15 +222,15 @@ public class KNNJoin<V extends NumberVector<?>, D extends Distance<D>, N extends
* @param pr Node to initialize for
* @return List of heaps
*/
- private List<KNNHeap<D>> initHeaps(SpatialPrimitiveDistanceFunction<V, D> distFunction, N pr) {
- List<KNNHeap<D>> pr_heaps = new ArrayList<>(pr.getNumEntries());
+ private List<KNNHeap> initHeaps(SpatialPrimitiveDistanceFunction<V> distFunction, N pr) {
+ List<KNNHeap> pr_heaps = new ArrayList<>(pr.getNumEntries());
// Create for each data object a knn heap
for(int j = 0; j < pr.getNumEntries(); j++) {
- pr_heaps.add(DBIDUtil.newHeap(distFunction.getDistanceFactory(), k));
+ pr_heaps.add(DBIDUtil.newHeap(k));
}
// Self-join first, as this is expected to improve most and cannot be
// pruned.
- processDataPagesOptimize(distFunction, pr_heaps, null, pr, pr);
+ processDataPages(distFunction, pr_heaps, null, pr, pr);
return pr_heaps;
}
@@ -277,53 +238,20 @@ public class KNNJoin<V extends NumberVector<?>, D extends Distance<D>, N extends
* Processes the two data pages pr and ps and determines the k-nearest
* neighbors of pr in ps.
*
- * @param distFunction the distance to use
- * @param pr the first data page
- * @param ps the second data page
- * @param pr_heaps the knn lists for each data object in pr
- * @param ps_heaps the knn lists for each data object in ps (if ps != pr)
- */
- @SuppressWarnings("unchecked")
- private void processDataPagesOptimize(SpatialPrimitiveDistanceFunction<V, D> distFunction, List<? extends KNNHeap<D>> pr_heaps, List<? extends KNNHeap<D>> ps_heaps, N pr, N ps) {
- if(DistanceUtil.isDoubleDistanceFunction(distFunction)) {
- List<?> khp = (List<?>) pr_heaps;
- List<?> khs = (List<?>) ps_heaps;
- processDataPagesDouble((SpatialPrimitiveDoubleDistanceFunction<? super V>) distFunction, pr, ps, (List<DoubleDistanceKNNHeap>) khp, (List<DoubleDistanceKNNHeap>) khs);
- }
- else {
- for(int j = 0; j < ps.getNumEntries(); j++) {
- final SpatialPointLeafEntry s_e = (SpatialPointLeafEntry) ps.getEntry(j);
- DBID s_id = s_e.getDBID();
- for(int i = 0; i < pr.getNumEntries(); i++) {
- final SpatialPointLeafEntry r_e = (SpatialPointLeafEntry) pr.getEntry(i);
- D distance = distFunction.minDist(s_e, r_e);
- pr_heaps.get(i).insert(distance, s_id);
- if(pr != ps && ps_heaps != null) {
- ps_heaps.get(j).insert(distance, r_e.getDBID());
- }
- }
- }
- }
- }
-
- /**
- * Processes the two data pages pr and ps and determines the k-nearest
- * neighbors of pr in ps.
- *
* @param df the distance function to use
* @param pr the first data page
* @param ps the second data page
* @param pr_heaps the knn lists for each data object
* @param ps_heaps the knn lists for each data object in ps
*/
- private void processDataPagesDouble(SpatialPrimitiveDoubleDistanceFunction<? super V> df, N pr, N ps, List<DoubleDistanceKNNHeap> pr_heaps, List<DoubleDistanceKNNHeap> ps_heaps) {
+ private void processDataPages(SpatialPrimitiveDistanceFunction<? super V> df, List<KNNHeap> pr_heaps, List<KNNHeap> ps_heaps, N pr, N ps) {
// Compare pairwise
for(int j = 0; j < ps.getNumEntries(); j++) {
final SpatialPointLeafEntry s_e = (SpatialPointLeafEntry) ps.getEntry(j);
DBID s_id = s_e.getDBID();
for(int i = 0; i < pr.getNumEntries(); i++) {
final SpatialPointLeafEntry r_e = (SpatialPointLeafEntry) pr.getEntry(i);
- double distance = df.doubleMinDist(s_e, r_e);
+ double distance = df.minDist(s_e, r_e);
pr_heaps.get(i).insert(distance, s_id);
if(pr != ps && ps_heaps != null) {
ps_heaps.get(j).insert(distance, r_e.getDBID());
@@ -338,20 +266,16 @@ public class KNNJoin<V extends NumberVector<?>, D extends Distance<D>, N extends
* @param heaps Heaps list
* @return the k-nearest neighbor distance of pr in ps
*/
- private D computeStopDistance(List<KNNHeap<D>> heaps) {
+ private double computeStopDistance(List<KNNHeap> heaps) {
// Update pruning distance
- D pr_knn_distance = null;
- for(KNNHeap<D> knnList : heaps) {
+ double pr_knn_distance = Double.NaN;
+ for(KNNHeap knnList : heaps) {
// set kNN distance of r
- if(pr_knn_distance == null) {
- pr_knn_distance = knnList.getKNNDistance();
- }
- else {
- pr_knn_distance = DistanceUtil.max(knnList.getKNNDistance(), pr_knn_distance);
- }
+ double kdist = knnList.getKNNDistance();
+ pr_knn_distance = (kdist < pr_knn_distance) ? pr_knn_distance : kdist;
}
- if(pr_knn_distance == null) {
- return getDistanceFunction().getDistanceFactory().infiniteDistance();
+ if(pr_knn_distance != pr_knn_distance) {
+ return Double.POSITIVE_INFINITY;
}
return pr_knn_distance;
}
@@ -377,7 +301,7 @@ public class KNNJoin<V extends NumberVector<?>, D extends Distance<D>, N extends
/**
* Minimum distance.
*/
- final D mindist;
+ final double mindist;
/**
* First offset.
@@ -396,7 +320,7 @@ public class KNNJoin<V extends NumberVector<?>, D extends Distance<D>, N extends
* @param i First offset
* @param j Second offset
*/
- public Task(D mindist, int i, int j) {
+ public Task(double mindist, int i, int j) {
super();
this.mindist = mindist;
this.i = i;
@@ -405,7 +329,7 @@ public class KNNJoin<V extends NumberVector<?>, D extends Distance<D>, N extends
@Override
public int compareTo(Task o) {
- return mindist.compareTo(o.mindist);
+ return Double.compare(mindist, o.mindist);
}
}
@@ -416,7 +340,12 @@ public class KNNJoin<V extends NumberVector<?>, D extends Distance<D>, N extends
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends Distance<D>, N extends SpatialNode<N, E>, E extends SpatialEntry> extends AbstractPrimitiveDistanceBasedAlgorithm.Parameterizer<V, D> {
+ public static class Parameterizer<V extends NumberVector, N extends SpatialNode<N, E>, E extends SpatialEntry> extends AbstractPrimitiveDistanceBasedAlgorithm.Parameterizer<V> {
+ /**
+ * Parameter that specifies the k-nearest neighbors to be assigned, must be an
+ * integer greater than 0. Default value: 1.
+ */
+ public static final OptionID K_ID = new OptionID("knnjoin.k", "Specifies the k-nearest neighbors to be assigned.");
/**
* K parameter.
*/
@@ -433,7 +362,7 @@ public class KNNJoin<V extends NumberVector<?>, D extends Distance<D>, N extends
}
@Override
- protected KNNJoin<V, D, N, E> makeInstance() {
+ protected KNNJoin<V, N, E> makeInstance() {
return new KNNJoin<>(distanceFunction, k);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/MaterializeDistances.java b/src/de/lmu/ifi/dbs/elki/algorithm/MaterializeDistances.java
index b02e9fed..bc16c11c 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/MaterializeDistances.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/MaterializeDistances.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm;
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,18 +29,18 @@ import java.util.Collection;
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.Database;
-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.DBIDUtil;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.result.CollectionResult;
+import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable;
+import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
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.pairs.CTriple;
/**
* Algorithm to materialize all the distances in a data set.
@@ -51,12 +51,11 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.CTriple;
* Symmetry is assumed.
*
* @param <O> Object type
- * @param <D> Distance type
*/
// TODO: use DBIDPair -> D map?
@Title("MaterializeDistances")
@Description("Materialize all distances in the data set to use as cached/precalculated data.")
-public class MaterializeDistances<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, CollectionResult<CTriple<DBID, DBID, Double>>> {
+public class MaterializeDistances<O> extends AbstractDistanceBasedAlgorithm<O, CollectionResult<MaterializeDistances.DistanceEntry>> {
/**
* The logger for this class.
*/
@@ -67,7 +66,7 @@ public class MaterializeDistances<O, D extends NumberDistance<D, ?>> extends Abs
*
* @param distanceFunction Parameterization
*/
- public MaterializeDistances(DistanceFunction<? super O, D> distanceFunction) {
+ public MaterializeDistances(DistanceFunction<? super O> distanceFunction) {
super(distanceFunction);
}
@@ -78,11 +77,11 @@ public class MaterializeDistances<O, D extends NumberDistance<D, ?>> extends Abs
* @param relation Relation to process
* @return Distance matrix
*/
- public CollectionResult<CTriple<DBID, DBID, Double>> run(Database database, Relation<O> relation) {
- DistanceQuery<O, D> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
+ public CollectionResult<DistanceEntry> run(Database database, Relation<O> relation) {
+ DistanceQuery<O> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
final int size = relation.size();
- Collection<CTriple<DBID, DBID, Double>> r = new ArrayList<>(size * (size + 1) >> 1);
+ Collection<DistanceEntry> r = new ArrayList<>(size * (size + 1) >> 1);
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
for(DBIDIter iditer2 = relation.iterDBIDs(); iditer2.valid(); iditer2.advance()) {
@@ -90,8 +89,8 @@ public class MaterializeDistances<O, D extends NumberDistance<D, ?>> extends Abs
if(DBIDUtil.compare(iditer2, iditer) > 0) {
continue;
}
- double d = distFunc.distance(iditer, iditer2).doubleValue();
- r.add(new CTriple<>(DBIDUtil.deref(iditer), DBIDUtil.deref(iditer2), d));
+ double d = distFunc.distance(iditer, iditer2);
+ r.add(new DistanceEntry(DBIDUtil.newPair(iditer, iditer2), d));
}
}
return new CollectionResult<>("Distance Matrix", "distance-matrix", r);
@@ -108,15 +107,54 @@ public class MaterializeDistances<O, D extends NumberDistance<D, ?>> extends Abs
}
/**
+ * Object representing a pairwise distance.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class DistanceEntry implements TextWriteable {
+ /**
+ * DBIDs compared.
+ */
+ DBIDPair ids;
+
+ /**
+ * Distance of the two objects
+ */
+ double distance;
+
+ /**
+ * Constructor.
+ *
+ * @param ids IDs
+ * @param distance Distance
+ */
+ public DistanceEntry(DBIDPair ids, double distance) {
+ this.ids = ids;
+ this.distance = distance;
+ }
+
+ @Override
+ public void writeToText(TextWriterStream out, String label) {
+ // TODO: use less memory;
+ // unless Hotspot was shown to optimize well enough!
+ out.inlinePrint(ids.getFirst());
+ out.inlinePrint(ids.getSecond());
+ out.inlinePrint(distance);
+ }
+ }
+
+ /**
* Parameterization class.
*
* @author Erich Schubert
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
@Override
- protected MaterializeDistances<O, D> makeInstance() {
+ protected MaterializeDistances<O> makeInstance() {
return new MaterializeDistances<>(distanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/NullAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/NullAlgorithm.java
index bb3f7f0d..3c0eed33 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/NullAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/NullAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm;
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/algorithm/benchmark/KNNBenchmarkAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/KNNBenchmarkAlgorithm.java
index 40726793..f0d5b08f 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/KNNBenchmarkAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/KNNBenchmarkAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.benchmark;
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,20 +31,18 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRange;
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.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.datasource.DatabaseConnection;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
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.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.result.Result;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.Util;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -65,7 +63,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
*
* @apiviz.uses KNNQuery
*/
-public class KNNBenchmarkAlgorithm<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm<O, D, Result> {
+public class KNNBenchmarkAlgorithm<O> extends AbstractDistanceBasedAlgorithm<O, Result> {
/**
* The logger for this class.
*/
@@ -100,7 +98,7 @@ public class KNNBenchmarkAlgorithm<O, D extends Distance<D>> extends AbstractDis
* @param sampling Sampling rate
* @param random Random factory
*/
- public KNNBenchmarkAlgorithm(DistanceFunction<? super O, D> distanceFunction, int k, DatabaseConnection queries, double sampling, RandomFactory random) {
+ public KNNBenchmarkAlgorithm(DistanceFunction<? super O> distanceFunction, int k, DatabaseConnection queries, double sampling, RandomFactory random) {
super(distanceFunction);
this.k = k;
this.queries = queries;
@@ -117,62 +115,58 @@ public class KNNBenchmarkAlgorithm<O, D extends Distance<D>> extends AbstractDis
*/
public Result run(Database database, Relation<O> relation) {
// Get a distance and kNN query instance.
- DistanceQuery<O, D> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
- KNNQuery<O, D> knnQuery = database.getKNNQuery(distQuery, k);
+ DistanceQuery<O> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
+ KNNQuery<O> knnQuery = database.getKNNQuery(distQuery, k);
// No query set - use original database.
- if (queries == null) {
+ if(queries == null) {
final DBIDs sample;
- if (sampling <= 0) {
+ if(sampling <= 0) {
sample = relation.getDBIDs();
- } else if (sampling < 1.1) {
+ }
+ else if(sampling < 1.1) {
int size = (int) Math.min(sampling * relation.size(), relation.size());
sample = DBIDUtil.randomSample(relation.getDBIDs(), size, random);
- } else {
+ }
+ else {
int size = (int) Math.min(sampling, relation.size());
sample = DBIDUtil.randomSample(relation.getDBIDs(), size, random);
}
FiniteProgress prog = LOG.isVeryVerbose() ? new FiniteProgress("kNN queries", sample.size(), LOG) : null;
int hash = 0;
MeanVariance mv = new MeanVariance(), mvdist = new MeanVariance();
- for (DBIDIter iditer = sample.iter(); iditer.valid(); iditer.advance()) {
- KNNList<D> knns = knnQuery.getKNNForDBID(iditer, k);
+ for(DBIDIter iditer = sample.iter(); iditer.valid(); iditer.advance()) {
+ KNNList knns = knnQuery.getKNNForDBID(iditer, k);
int ichecksum = 0;
- for (DBIDIter it = knns.iter(); it.valid(); it.advance()) {
- ichecksum += it.internalGetIndex();
+ for(DBIDIter it = knns.iter(); it.valid(); it.advance()) {
+ ichecksum += DBIDUtil.asInteger(it);
}
hash = Util.mixHashCodes(hash, ichecksum);
mv.put(knns.size());
- D kdist = knns.getKNNDistance();
- if (kdist instanceof NumberDistance) {
- mvdist.put(((NumberDistance<?, ?>) kdist).doubleValue());
- }
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if (prog != null) {
- prog.ensureCompleted(LOG);
+ mvdist.put(knns.getKNNDistance());
+ LOG.incrementProcessed(prog);
}
- if (LOG.isStatistics()) {
+ LOG.ensureCompleted(prog);
+ if(LOG.isStatistics()) {
LOG.statistics("Result hashcode: " + hash);
LOG.statistics("Mean number of results: " + mv.getMean() + " +- " + mv.getNaiveStddev());
- if (mvdist.getCount() > 0) {
+ if(mvdist.getCount() > 0) {
LOG.statistics("Mean k-distance: " + mvdist.getMean() + " +- " + mvdist.getNaiveStddev());
}
}
- } else {
+ }
+ else {
// Separate query set.
TypeInformation res = getDistanceFunction().getInputTypeRestriction();
MultipleObjectsBundle bundle = queries.loadData();
int col = -1;
- for (int i = 0; i < bundle.metaLength(); i++) {
- if (res.isAssignableFromType(bundle.meta(i))) {
+ for(int i = 0; i < bundle.metaLength(); i++) {
+ if(res.isAssignableFromType(bundle.meta(i))) {
col = i;
break;
}
}
- if (col < 0) {
+ if(col < 0) {
throw new AbortException("No compatible data type in query input was found. Expected: " + res.toString());
}
// Random sampling is a bit of hack, sorry.
@@ -180,45 +174,40 @@ public class KNNBenchmarkAlgorithm<O, D extends Distance<D>> extends AbstractDis
DBIDRange sids = DBIDUtil.generateStaticDBIDRange(bundle.dataLength());
final DBIDs sample;
- if (sampling <= 0) {
+ if(sampling <= 0) {
sample = sids;
- } else if (sampling < 1.1) {
+ }
+ else if(sampling < 1.1) {
int size = (int) Math.min(sampling * relation.size(), relation.size());
sample = DBIDUtil.randomSample(sids, size, random);
- } else {
+ }
+ else {
int size = (int) Math.min(sampling, sids.size());
sample = DBIDUtil.randomSample(sids, size, random);
}
FiniteProgress prog = LOG.isVeryVerbose() ? new FiniteProgress("kNN queries", sample.size(), LOG) : null;
int hash = 0;
MeanVariance mv = new MeanVariance(), mvdist = new MeanVariance();
- for (DBIDIter iditer = sample.iter(); iditer.valid(); iditer.advance()) {
+ for(DBIDIter iditer = sample.iter(); iditer.valid(); iditer.advance()) {
int off = sids.binarySearch(iditer);
assert (off >= 0);
@SuppressWarnings("unchecked")
O o = (O) bundle.data(off, col);
- KNNList<D> knns = knnQuery.getKNNForObject(o, k);
+ KNNList knns = knnQuery.getKNNForObject(o, k);
int ichecksum = 0;
- for (DBIDIter it = knns.iter(); it.valid(); it.advance()) {
- ichecksum += it.internalGetIndex();
+ for(DBIDIter it = knns.iter(); it.valid(); it.advance()) {
+ ichecksum += DBIDUtil.asInteger(it);
}
hash = Util.mixHashCodes(hash, ichecksum);
mv.put(knns.size());
- D kdist = knns.getKNNDistance();
- if (kdist instanceof NumberDistance) {
- mvdist.put(((NumberDistance<?, ?>) kdist).doubleValue());
- }
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if (prog != null) {
- prog.ensureCompleted(LOG);
+ mvdist.put(knns.getKNNDistance());
+ LOG.incrementProcessed(prog);
}
- if (LOG.isStatistics()) {
+ LOG.ensureCompleted(prog);
+ if(LOG.isStatistics()) {
LOG.statistics("Result hashcode: " + hash);
LOG.statistics("Mean number of results: " + mv.getMean() + " +- " + mv.getNaiveStddev());
- if (mvdist.getCount() > 0) {
+ if(mvdist.getCount() > 0) {
LOG.statistics("Mean k-distance: " + mvdist.getMean() + " +- " + mvdist.getNaiveStddev());
}
}
@@ -244,9 +233,8 @@ public class KNNBenchmarkAlgorithm<O, D extends Distance<D>> extends AbstractDis
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Parameter for the number of neighbors.
*/
@@ -291,27 +279,27 @@ public class KNNBenchmarkAlgorithm<O, D extends Distance<D>> extends AbstractDis
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
IntParameter kP = new IntParameter(K_ID);
- if (config.grab(kP)) {
+ if(config.grab(kP)) {
k = kP.intValue();
}
ObjectParameter<DatabaseConnection> queryP = new ObjectParameter<>(QUERY_ID, DatabaseConnection.class);
queryP.setOptional(true);
- if (config.grab(queryP)) {
+ if(config.grab(queryP)) {
queries = queryP.instantiateClass(config);
}
DoubleParameter samplingP = new DoubleParameter(SAMPLING_ID);
samplingP.setOptional(true);
- if (config.grab(samplingP)) {
+ if(config.grab(samplingP)) {
sampling = samplingP.doubleValue();
}
RandomParameter randomP = new RandomParameter(RANDOM_ID, RandomFactory.DEFAULT);
- if (config.grab(randomP)) {
+ if(config.grab(randomP)) {
random = randomP.getValue();
}
}
@Override
- protected KNNBenchmarkAlgorithm<O, D> makeInstance() {
+ protected KNNBenchmarkAlgorithm<O> makeInstance() {
return new KNNBenchmarkAlgorithm<>(distanceFunction, k, queries, sampling, random);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/RangeQueryBenchmarkAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/RangeQueryBenchmarkAlgorithm.java
index 1b5e827b..b5336aac 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/RangeQueryBenchmarkAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/RangeQueryBenchmarkAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.benchmark;
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.algorithm.benchmark;
import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.NumberVector.Factory;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
@@ -34,7 +33,7 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRange;
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.distance.DistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
@@ -42,12 +41,11 @@ import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.datasource.DatabaseConnection;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-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.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.result.Result;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.Util;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -93,11 +91,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
* @author Erich Schubert
*
* @param <O> Vector type
- * @param <D> Distance type
*
* @apiviz.uses RangeQuery
*/
-public class RangeQueryBenchmarkAlgorithm<O extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, Result> {
+public class RangeQueryBenchmarkAlgorithm<O extends NumberVector> extends AbstractDistanceBasedAlgorithm<O, Result> {
/**
* The logger for this class.
*/
@@ -126,7 +123,7 @@ public class RangeQueryBenchmarkAlgorithm<O extends NumberVector<?>, D extends N
* @param sampling Sampling rate
* @param random Random factory
*/
- public RangeQueryBenchmarkAlgorithm(DistanceFunction<? super O, D> distanceFunction, DatabaseConnection queries, double sampling, RandomFactory random) {
+ public RangeQueryBenchmarkAlgorithm(DistanceFunction<? super O> distanceFunction, DatabaseConnection queries, double sampling, RandomFactory random) {
super(distanceFunction);
this.queries = queries;
this.sampling = sampling;
@@ -141,45 +138,42 @@ public class RangeQueryBenchmarkAlgorithm<O extends NumberVector<?>, D extends N
* @param radrel Radius relation
* @return Null result
*/
- public Result run(Database database, Relation<O> relation, Relation<NumberVector<?>> radrel) {
- if (queries != null) {
+ public Result run(Database database, Relation<O> relation, Relation<NumberVector> radrel) {
+ if(queries != null) {
throw new AbortException("This 'run' method will not use the given query set!");
}
// Get a distance and kNN query instance.
- DistanceQuery<O, D> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
- RangeQuery<O, D> rangeQuery = database.getRangeQuery(distQuery);
- D dfactory = distQuery.getDistanceFactory();
+ DistanceQuery<O> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
+ RangeQuery<O> rangeQuery = database.getRangeQuery(distQuery);
final DBIDs sample;
- if (sampling <= 0) {
+ if(sampling <= 0) {
sample = relation.getDBIDs();
- } else if (sampling < 1.1) {
+ }
+ else if(sampling < 1.1) {
int size = (int) Math.min(sampling * relation.size(), relation.size());
sample = DBIDUtil.randomSample(relation.getDBIDs(), size, random);
- } else {
+ }
+ else {
int size = (int) Math.min(sampling, relation.size());
sample = DBIDUtil.randomSample(relation.getDBIDs(), size, random);
}
FiniteProgress prog = LOG.isVeryVerbose() ? new FiniteProgress("kNN queries", sample.size(), LOG) : null;
int hash = 0;
MeanVariance mv = new MeanVariance();
- for (DBIDIter iditer = sample.iter(); iditer.valid(); iditer.advance()) {
- D r = dfactory.fromDouble(radrel.get(iditer).doubleValue(0));
- DistanceDBIDList<D> rres = rangeQuery.getRangeForDBID(iditer, r);
+ for(DBIDIter iditer = sample.iter(); iditer.valid(); iditer.advance()) {
+ double r = radrel.get(iditer).doubleValue(0);
+ DoubleDBIDList rres = rangeQuery.getRangeForDBID(iditer, r);
int ichecksum = 0;
- for (DBIDIter it = rres.iter(); it.valid(); it.advance()) {
- ichecksum += it.internalGetIndex();
+ for(DBIDIter it = rres.iter(); it.valid(); it.advance()) {
+ ichecksum += DBIDUtil.asInteger(it);
}
hash = Util.mixHashCodes(hash, ichecksum);
mv.put(rres.size());
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
}
- if (prog != null) {
- prog.ensureCompleted(LOG);
- }
- if (LOG.isStatistics()) {
+ LOG.ensureCompleted(prog);
+ if(LOG.isStatistics()) {
LOG.statistics("Result hashcode: " + hash);
LOG.statistics("Mean number of results: " + mv.getMean() + " +- " + mv.getNaiveStddev());
}
@@ -194,33 +188,32 @@ public class RangeQueryBenchmarkAlgorithm<O extends NumberVector<?>, D extends N
* @return Null result
*/
public Result run(Database database, Relation<O> relation) {
- if (queries == null) {
+ if(queries == null) {
throw new AbortException("A query set is required for this 'run' method.");
}
// Get a distance and kNN query instance.
- DistanceQuery<O, D> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
- RangeQuery<O, D> rangeQuery = database.getRangeQuery(distQuery);
- D dfactory = distQuery.getDistanceFactory();
- Factory<O, ?> ofactory = RelationUtil.getNumberVectorFactory(relation);
+ DistanceQuery<O> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
+ RangeQuery<O> rangeQuery = database.getRangeQuery(distQuery);
+ NumberVector.Factory<O> ofactory = RelationUtil.getNumberVectorFactory(relation);
int dim = RelationUtil.dimensionality(relation);
// Separate query set.
- TypeInformation res = new VectorFieldTypeInformation<NumberVector<?>>(NumberVector.class, dim + 1);
+ TypeInformation res = VectorFieldTypeInformation.typeRequest(NumberVector.class, dim + 1, dim + 1);
MultipleObjectsBundle bundle = queries.loadData();
int col = -1;
- for (int i = 0; i < bundle.metaLength(); i++) {
- if (res.isAssignableFromType(bundle.meta(i))) {
+ for(int i = 0; i < bundle.metaLength(); i++) {
+ if(res.isAssignableFromType(bundle.meta(i))) {
col = i;
break;
}
}
- if (col < 0) {
+ if(col < 0) {
StringBuilder buf = new StringBuilder();
buf.append("No compatible data type in query input was found. Expected: ");
buf.append(res.toString());
buf.append(" have: ");
- for (int i = 0; i < bundle.metaLength(); i++) {
- if (i > 0) {
+ for(int i = 0; i < bundle.metaLength(); i++) {
+ if(i > 0) {
buf.append(' ');
}
buf.append(bundle.meta(i).toString());
@@ -232,12 +225,14 @@ public class RangeQueryBenchmarkAlgorithm<O extends NumberVector<?>, D extends N
DBIDRange sids = DBIDUtil.generateStaticDBIDRange(bundle.dataLength());
final DBIDs sample;
- if (sampling <= 0) {
+ if(sampling <= 0) {
sample = sids;
- } else if (sampling < 1.1) {
+ }
+ else if(sampling < 1.1) {
int size = (int) Math.min(sampling * relation.size(), relation.size());
sample = DBIDUtil.randomSample(sids, size, random);
- } else {
+ }
+ else {
int size = (int) Math.min(sampling, sids.size());
sample = DBIDUtil.randomSample(sids, size, random);
}
@@ -245,30 +240,26 @@ public class RangeQueryBenchmarkAlgorithm<O extends NumberVector<?>, D extends N
int hash = 0;
MeanVariance mv = new MeanVariance();
double[] buf = new double[dim];
- for (DBIDIter iditer = sample.iter(); iditer.valid(); iditer.advance()) {
+ for(DBIDIter iditer = sample.iter(); iditer.valid(); iditer.advance()) {
int off = sids.binarySearch(iditer);
assert (off >= 0);
- NumberVector<?> o = (NumberVector<?>) bundle.data(off, col);
- for (int i = 0; i < dim; i++) {
+ NumberVector o = (NumberVector) bundle.data(off, col);
+ for(int i = 0; i < dim; i++) {
buf[i] = o.doubleValue(i);
}
O v = ofactory.newNumberVector(buf);
- D r = dfactory.fromDouble(o.doubleValue(dim));
- DistanceDBIDList<D> rres = rangeQuery.getRangeForObject(v, r);
+ double r = o.doubleValue(dim);
+ DoubleDBIDList rres = rangeQuery.getRangeForObject(v, r);
int ichecksum = 0;
- for (DBIDIter it = rres.iter(); it.valid(); it.advance()) {
- ichecksum += it.internalGetIndex();
+ for(DBIDIter it = rres.iter(); it.valid(); it.advance()) {
+ ichecksum += DBIDUtil.asInteger(it);
}
hash = Util.mixHashCodes(hash, ichecksum);
mv.put(rres.size());
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
}
- if (prog != null) {
- prog.ensureCompleted(LOG);
- }
- if (LOG.isStatistics()) {
+ LOG.ensureCompleted(prog);
+ if(LOG.isStatistics()) {
LOG.statistics("Result hashcode: " + hash);
LOG.statistics("Mean number of results: " + mv.getMean() + " +- " + mv.getNaiveStddev());
}
@@ -277,9 +268,10 @@ public class RangeQueryBenchmarkAlgorithm<O extends NumberVector<?>, D extends N
@Override
public TypeInformation[] getInputTypeRestriction() {
- if (queries == null) {
- return TypeUtil.array(getDistanceFunction().getInputTypeRestriction(), new VectorFieldTypeInformation<NumberVector<?>>(NumberVector.class, 1));
- } else {
+ if(queries == null) {
+ return TypeUtil.array(getDistanceFunction().getInputTypeRestriction(), TypeUtil.NUMBER_VECTOR_FIELD_1D);
+ }
+ else {
return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
}
}
@@ -297,9 +289,8 @@ public class RangeQueryBenchmarkAlgorithm<O extends NumberVector<?>, D extends N
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O extends NumberVector> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Parameter for the query dataset.
*/
@@ -335,22 +326,22 @@ public class RangeQueryBenchmarkAlgorithm<O extends NumberVector<?>, D extends N
super.makeOptions(config);
ObjectParameter<DatabaseConnection> queryP = new ObjectParameter<>(QUERY_ID, DatabaseConnection.class);
queryP.setOptional(true);
- if (config.grab(queryP)) {
+ if(config.grab(queryP)) {
queries = queryP.instantiateClass(config);
}
DoubleParameter samplingP = new DoubleParameter(SAMPLING_ID);
samplingP.setOptional(true);
- if (config.grab(samplingP)) {
+ if(config.grab(samplingP)) {
sampling = samplingP.doubleValue();
}
RandomParameter randomP = new RandomParameter(RANDOM_ID, RandomFactory.DEFAULT);
- if (config.grab(randomP)) {
+ if(config.grab(randomP)) {
random = randomP.getValue();
}
}
@Override
- protected RangeQueryBenchmarkAlgorithm<O, D> makeInstance() {
+ protected RangeQueryBenchmarkAlgorithm<O> makeInstance() {
return new RangeQueryBenchmarkAlgorithm<>(distanceFunction, queries, sampling, random);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/ValidateApproximativeKNNIndex.java b/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/ValidateApproximativeKNNIndex.java
index 8b83b5d4..deaea154 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/ValidateApproximativeKNNIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/ValidateApproximativeKNNIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.benchmark;
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,7 +34,7 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRange;
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.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
@@ -43,14 +43,12 @@ import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.datasource.DatabaseConnection;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
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.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -72,7 +70,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
*
* @apiviz.uses KNNQuery
*/
-public class ValidateApproximativeKNNIndex<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm<O, D, Result> {
+public class ValidateApproximativeKNNIndex<O> extends AbstractDistanceBasedAlgorithm<O, Result> {
/**
* The logger for this class.
*/
@@ -119,7 +117,7 @@ public class ValidateApproximativeKNNIndex<O, D extends Distance<D>> extends Abs
* @param forcelinear Force the use of linear scanning.
* @param pattern
*/
- public ValidateApproximativeKNNIndex(DistanceFunction<? super O, D> distanceFunction, int k, DatabaseConnection queries, double sampling, boolean forcelinear, RandomFactory random, Pattern pattern) {
+ public ValidateApproximativeKNNIndex(DistanceFunction<? super O> distanceFunction, int k, DatabaseConnection queries, double sampling, boolean forcelinear, RandomFactory random, Pattern pattern) {
super(distanceFunction);
this.k = k;
this.queries = queries;
@@ -138,14 +136,14 @@ public class ValidateApproximativeKNNIndex<O, D extends Distance<D>> extends Abs
*/
public Result run(Database database, Relation<O> relation) {
// Get a distance and kNN query instance.
- DistanceQuery<O, D> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
+ DistanceQuery<O> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
// Approximate query:
- KNNQuery<O, D> knnQuery = database.getKNNQuery(distQuery, k, DatabaseQuery.HINT_OPTIMIZED_ONLY);
+ KNNQuery<O> knnQuery = database.getKNNQuery(distQuery, k, DatabaseQuery.HINT_OPTIMIZED_ONLY);
if(knnQuery == null || knnQuery instanceof LinearScanQuery) {
throw new AbortException("Expected an accelerated query, but got a linear scan -- index is not used.");
}
// Exact query:
- KNNQuery<O, D> truekNNQuery;
+ KNNQuery<O> truekNNQuery;
if(forcelinear) {
truekNNQuery = QueryUtil.getLinearScanKNNQuery(distQuery);
}
@@ -180,26 +178,23 @@ public class ValidateApproximativeKNNIndex<O, D extends Distance<D>> extends Abs
for(DBIDIter iditer = sample.iter(); iditer.valid(); iditer.advance()) {
if(pattern == null || pattern.matcher(lrel.get(iditer)).find()) {
// Query index:
- KNNList<D> knns = knnQuery.getKNNForDBID(iditer, k);
+ KNNList knns = knnQuery.getKNNForDBID(iditer, k);
// Query reference:
- KNNList<D> trueknns = truekNNQuery.getKNNForDBID(iditer, k);
+ KNNList trueknns = truekNNQuery.getKNNForDBID(iditer, k);
// Put adjusted knn size:
mv.put(knns.size() * k / (double) trueknns.size());
// Put recall:
- mvrec.put(DBIDUtil.intersectionSize(knns, trueknns) / trueknns.size());
+ mvrec.put(DBIDUtil.intersectionSize(knns, trueknns) / (double) trueknns.size());
if(knns.size() >= k) {
- D kdist = knns.getKNNDistance();
- if(kdist instanceof NumberDistance) {
- final double dist = ((NumberDistance<?, ?>) kdist).doubleValue();
- final double tdist = ((NumberDistance<?, ?>) trueknns.getKNNDistance()).doubleValue();
- if(tdist > 0.0) {
- mvdist.put(dist);
- mvdaerr.put(dist - tdist);
- mvdrerr.put(dist / tdist);
- }
+ double kdist = knns.getKNNDistance();
+ final double tdist = trueknns.getKNNDistance();
+ if(tdist > 0.0) {
+ mvdist.put(kdist);
+ mvdaerr.put(kdist - tdist);
+ mvdrerr.put(kdist / tdist);
}
}
else {
@@ -207,13 +202,9 @@ public class ValidateApproximativeKNNIndex<O, D extends Distance<D>> extends Abs
misses++;
}
}
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if(prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
if(LOG.isStatistics()) {
LOG.statistics("Mean number of results: " + mv.getMean() + " +- " + mv.getNaiveStddev());
LOG.statistics("Recall of true results: " + mvrec.getMean() + " +- " + mvrec.getNaiveStddev());
@@ -268,39 +259,32 @@ public class ValidateApproximativeKNNIndex<O, D extends Distance<D>> extends Abs
O o = (O) bundle.data(off, col);
// Query index:
- KNNList<D> knns = knnQuery.getKNNForObject(o, k);
+ KNNList knns = knnQuery.getKNNForObject(o, k);
// Query reference:
- KNNList<D> trueknns = truekNNQuery.getKNNForObject(o, k);
+ KNNList trueknns = truekNNQuery.getKNNForObject(o, k);
// Put adjusted knn size:
mv.put(knns.size() * k / (double) trueknns.size());
// Put recall:
- mvrec.put(DBIDUtil.intersectionSize(knns, trueknns) / trueknns.size());
+ mvrec.put(DBIDUtil.intersectionSize(knns, trueknns) / (double) trueknns.size());
if(knns.size() >= k) {
- D kdist = knns.getKNNDistance();
- if(kdist instanceof NumberDistance) {
- final double dist = ((NumberDistance<?, ?>) kdist).doubleValue();
- final double tdist = ((NumberDistance<?, ?>) trueknns.getKNNDistance()).doubleValue();
- if(tdist > 0.0) {
- mvdist.put(dist);
- mvdaerr.put(dist - tdist);
- mvdrerr.put(dist / tdist);
- }
+ double kdist = knns.getKNNDistance();
+ final double tdist = trueknns.getKNNDistance();
+ if(tdist > 0.0) {
+ mvdist.put(kdist);
+ mvdaerr.put(kdist - tdist);
+ mvdrerr.put(kdist / tdist);
}
}
else {
// Less than k objects.
misses++;
}
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if(prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
if(LOG.isStatistics()) {
LOG.statistics("Mean number of results: " + mv.getMean() + " +- " + mv.getNaiveStddev());
LOG.statistics("Recall of true results: " + mvrec.getMean() + " +- " + mvrec.getNaiveStddev());
@@ -334,9 +318,8 @@ public class ValidateApproximativeKNNIndex<O, D extends Distance<D>> extends Abs
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Parameter for the number of neighbors.
*/
@@ -432,7 +415,7 @@ public class ValidateApproximativeKNNIndex<O, D extends Distance<D>> extends Abs
}
@Override
- protected ValidateApproximativeKNNIndex<O, D> makeInstance() {
+ protected ValidateApproximativeKNNIndex<O> makeInstance() {
return new ValidateApproximativeKNNIndex<>(distanceFunction, k, queries, sampling, forcelinear, random, pattern);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/package-info.java
index b10ef2ed..5facc91e 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/benchmark/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/algorithm/classification/AbstractClassifier.java b/src/de/lmu/ifi/dbs/elki/algorithm/classification/AbstractClassifier.java
new file mode 100644
index 00000000..8548e1ec
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/classification/AbstractClassifier.java
@@ -0,0 +1,75 @@
+package de.lmu.ifi.dbs.elki.algorithm.classification;
+
+/*
+ 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.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
+import de.lmu.ifi.dbs.elki.data.ClassLabel;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.result.Result;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+
+/**
+ * Abstract base class for algorithms.
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Input type
+ * @param <R> Result type
+ */
+public abstract class AbstractClassifier<O, R extends Result> extends AbstractAlgorithm<R> implements Classifier<O> {
+ @Override
+ @Deprecated
+ public R run(Database database) {
+ throw new AbortException("Classifiers cannot auto-run on a database, but need to be trained and can then predict.");
+ }
+
+ /**
+ * Align the labels for a label query.
+ *
+ * @param l1 List of reference labels
+ * @param d1 Probabilities for these labels
+ * @param l2 List of requested labels
+ * @return Probabilities in desired output order
+ */
+ protected double[] alignLabels(List<ClassLabel> l1, double[] d1, Collection<ClassLabel> l2) {
+ assert (l1.size() == d1.length);
+ if(l1 == l2) {
+ return d1.clone();
+ }
+ double[] d2 = new double[l2.size()];
+ Iterator<ClassLabel> i2 = l2.iterator();
+ for(int i = 0; i2.hasNext();) {
+ ClassLabel l = i2.next();
+ int idx = l1.indexOf(l);
+ if(idx < 0 && getLogger().isDebuggingFiner()) {
+ getLogger().debugFiner("Label not found: " + l);
+ }
+ d2[i] = (idx >= 0) ? d1[idx] : 0.; // Default to 0 for unknown labels!
+ }
+ return d2;
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/classification/Classifier.java b/src/de/lmu/ifi/dbs/elki/algorithm/classification/Classifier.java
new file mode 100644
index 00000000..06cdcd32
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/classification/Classifier.java
@@ -0,0 +1,62 @@
+package de.lmu.ifi.dbs.elki.algorithm.classification;
+
+/*
+ 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.algorithm.Algorithm;
+import de.lmu.ifi.dbs.elki.data.ClassLabel;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+
+/**
+ * A Classifier is to hold a model that is built based on a database, and to
+ * classify a new instance of the same type.
+ *
+ * @author Arthur Zimek
+ *
+ * @param <O> the type of DatabaseObjects handled by this Algorithm
+ */
+public interface Classifier<O> extends Algorithm {
+ /**
+ * Performs the training. Sets available labels.
+ *
+ * @param database the database to build the model on
+ * @param classLabels the classes to be learned
+ */
+ public void buildClassifier(Database database, Relation<? extends ClassLabel> classLabels);
+
+ /**
+ * Classify a single instance.
+ *
+ * @param instance an instance to classify
+ * @return predicted class label of the given instance
+ */
+ public ClassLabel classify(O instance);
+
+ /**
+ * Produce a String representation of the classification model.
+ *
+ * @return a String representation of the classification model
+ */
+ public String model();
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/classification/KNNClassifier.java b/src/de/lmu/ifi/dbs/elki/algorithm/classification/KNNClassifier.java
new file mode 100644
index 00000000..faa16a95
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/classification/KNNClassifier.java
@@ -0,0 +1,204 @@
+package de.lmu.ifi.dbs.elki.algorithm.classification;
+
+/*
+ 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 gnu.trove.iterator.TObjectIntIterator;
+import gnu.trove.map.TObjectIntMap;
+import gnu.trove.map.hash.TObjectIntHashMap;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.data.ClassLabel;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+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.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.result.Result;
+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.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;
+
+/**
+ * KNNClassifier classifies instances based on the class distribution among the
+ * k nearest neighbors in a database.
+ *
+ * @author Arthur Zimek
+ * @param <O> the type of DatabaseObjects handled by this Algorithm
+ */
+@Title("kNN-classifier")
+@Description("Lazy classifier classifies a given instance to the majority class of the k-nearest neighbors.")
+public class KNNClassifier<O> extends AbstractDistanceBasedAlgorithm<O, Result> implements Classifier<O> {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(KNNClassifier.class);
+
+ /**
+ * Holds the value of @link #K_PARAM}.
+ */
+ protected int k;
+
+ /**
+ * kNN query class.
+ */
+ protected KNNQuery<O> knnq;
+
+ /**
+ * Class label representation.
+ */
+ protected Relation<? extends ClassLabel> labelrep;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function
+ * @param k Number of nearest neighbors to access.
+ */
+ public KNNClassifier(DistanceFunction<? super O> distanceFunction, int k) {
+ super(distanceFunction);
+ this.k = k;
+ }
+
+ @Override
+ public void buildClassifier(Database database, Relation<? extends ClassLabel> labels) {
+ Relation<O> relation = database.getRelation(getDistanceFunction().getInputTypeRestriction());
+ DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, getDistanceFunction());
+ this.knnq = database.getKNNQuery(distanceQuery, k);
+ this.labelrep = labels;
+ }
+
+ @Override
+ public ClassLabel classify(O instance) {
+ TObjectIntMap<ClassLabel> count = new TObjectIntHashMap<>();
+ KNNList query = knnq.getKNNForObject(instance, k);
+ for(DoubleDBIDListIter neighbor = query.iter(); neighbor.valid(); neighbor.advance()) {
+ count.adjustOrPutValue(labelrep.get(neighbor), 1, 1);
+ }
+
+ int bestoccur = Integer.MIN_VALUE;
+ ClassLabel bestl = null;
+ for(TObjectIntIterator<ClassLabel> iter = count.iterator(); iter.hasNext();) {
+ iter.advance();
+ if(iter.value() > bestoccur) {
+ bestoccur = iter.value();
+ bestl = iter.key();
+ }
+ }
+ return bestl;
+ }
+
+ public double[] classProbabilities(O instance, ArrayList<ClassLabel> labels) {
+ int[] occurences = new int[labels.size()];
+
+ KNNList query = knnq.getKNNForObject(instance, k);
+ for(DoubleDBIDListIter neighbor = query.iter(); neighbor.valid(); neighbor.advance()) {
+ int index = Collections.binarySearch(labels, labelrep.get(neighbor));
+ if(index >= 0) {
+ occurences[index]++;
+ }
+ }
+ double[] distribution = new double[labels.size()];
+ for(int i = 0; i < distribution.length; i++) {
+ distribution[i] = ((double) occurences[i]) / (double) query.size();
+ }
+ return distribution;
+ }
+
+ @Override
+ public String model() {
+ return "lazy learner - provides no model";
+ }
+
+ @Override
+ @Deprecated
+ public Result run(Database database) throws IllegalStateException {
+ throw new AbortException("Classifiers cannot auto-run on a database, but need to be trained and can then predict.");
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(TypeUtil.NUMBER_VECTOR_FIELD);
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <O> Object type
+ */
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+
+ /**
+ * Parameter to specify the number of neighbors to take into account for
+ * classification, must be an integer greater than 0.
+ * <p>
+ * Default value: {@code 1}
+ * </p>
+ * <p>
+ * Key: {@code -knnclassifier.k}
+ * </p>
+ */
+ public static final OptionID K_ID = new OptionID("knnclassifier.k", "The number of neighbors to take into account for classification.");
+
+ /**
+ * Holds the value of @link #K_PARAM}.
+ */
+ protected int k;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ IntParameter kP = new IntParameter(K_ID, 1)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(kP)) {
+ k = kP.intValue();
+ }
+ }
+
+ @Override
+ protected KNNClassifier<O> makeInstance() {
+ return new KNNClassifier<>(distanceFunction, k);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/classification/PriorProbabilityClassifier.java b/src/de/lmu/ifi/dbs/elki/algorithm/classification/PriorProbabilityClassifier.java
new file mode 100644
index 00000000..ce7cc0dc
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/classification/PriorProbabilityClassifier.java
@@ -0,0 +1,135 @@
+package de.lmu.ifi.dbs.elki.algorithm.classification;
+
+/*
+ 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 gnu.trove.iterator.TObjectIntIterator;
+import gnu.trove.map.TObjectIntMap;
+import gnu.trove.map.hash.TObjectIntHashMap;
+
+import java.util.ArrayList;
+
+import de.lmu.ifi.dbs.elki.data.ClassLabel;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.result.Result;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
+
+/**
+ * Classifier to classify instances based on the prior probability of classes in
+ * the database, without using the actual data values.
+ *
+ * @author Arthur Zimek
+ */
+@Title("Prior Probability Classifier")
+@Description("Classifier to predict simply prior probabilities for all classes as defined by their relative abundance in a given database.")
+public class PriorProbabilityClassifier extends AbstractClassifier<Object, Result> {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(PriorProbabilityClassifier.class);
+
+ /**
+ * Holds the prior probabilities.
+ */
+ protected double[] distribution;
+
+ /**
+ * Index of the most abundant class.
+ */
+ protected ClassLabel prediction;
+
+ /**
+ * Class labels seen.
+ */
+ protected ArrayList<ClassLabel> labels;
+
+ /**
+ * Constructor.
+ */
+ public PriorProbabilityClassifier() {
+ super();
+ }
+
+ /**
+ * Learns the prior probability for all classes.
+ */
+ @Override
+ public void buildClassifier(Database database, Relation<? extends ClassLabel> labelrep) {
+ TObjectIntMap<ClassLabel> count = new TObjectIntHashMap<>();
+ for(DBIDIter iter = labelrep.iterDBIDs(); iter.valid(); iter.advance()) {
+ count.adjustOrPutValue(labelrep.get(iter), 1, 1);
+ }
+ int max = Integer.MIN_VALUE;
+ double size = labelrep.size();
+
+ distribution = new double[count.size()];
+ labels = new ArrayList<>(count.size());
+ TObjectIntIterator<ClassLabel> iter = count.iterator();
+ for(int i = 0; iter.hasNext(); ++i) {
+ iter.advance();
+ distribution[i] = iter.value() / size;
+ labels.add(iter.key());
+ if(iter.value() > max) {
+ max = iter.value();
+ prediction = iter.key();
+ }
+ }
+ }
+
+ public double[] classProbabilities(Object instance, ArrayList<ClassLabel> labels) {
+ return alignLabels(this.labels, distribution, labels);
+ }
+
+ @Override
+ public ClassLabel classify(Object instance) {
+ return prediction;
+ }
+
+ @Override
+ public String model() {
+ StringBuilder output = new StringBuilder();
+ for(int i = 0; i < distribution.length; i++) {
+ output.append(labels.get(i));
+ output.append(" : ");
+ output.append(distribution[i]);
+ output.append('\n');
+ }
+ return output.toString();
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(TypeUtil.ANY);
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/classification/package-info.java
index 7fefbedd..5cea53fd 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/classification/package-info.java
@@ -1,11 +1,11 @@
/**
- * Distance-DBID pairs, lists and heaps.
+ * <p>Classification algorithms.</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
@@ -23,4 +23,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.database.ids.distance;
+package de.lmu.ifi.dbs.elki.algorithm.classification; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/AbstractProjectedClustering.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/AbstractProjectedClustering.java
index 96c95a9f..c38fb412 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/AbstractProjectedClustering.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/AbstractProjectedClustering.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering;
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,7 +32,6 @@ import de.lmu.ifi.dbs.elki.database.QueryUtil;
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.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -48,7 +47,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* @param <R> the result we return
* @param <V> the type of FeatureVector handled by this Algorithm
*/
-public abstract class AbstractProjectedClustering<R extends Clustering<?>, V extends NumberVector<?>> extends AbstractAlgorithm<R> implements ClusteringAlgorithm<R> {
+public abstract class AbstractProjectedClustering<R extends Clustering<?>, V extends NumberVector> extends AbstractAlgorithm<R> implements ClusteringAlgorithm<R> {
/**
* Holds the value of {@link Parameterizer#K_ID}.
*/
@@ -65,9 +64,9 @@ public abstract class AbstractProjectedClustering<R extends Clustering<?>, V ext
protected int l;
/**
- * The euclidean distance function.
+ * The Euclidean distance function.
*/
- private DistanceFunction<? super V, DoubleDistance> distanceFunction = EuclideanDistanceFunction.STATIC;
+ private DistanceFunction<? super V> distanceFunction = EuclideanDistanceFunction.STATIC;
/**
* Internal constructor.
@@ -88,7 +87,7 @@ public abstract class AbstractProjectedClustering<R extends Clustering<?>, V ext
*
* @return the distance function
*/
- protected DistanceFunction<? super V, DoubleDistance> getDistanceFunction() {
+ protected DistanceFunction<? super V> getDistanceFunction() {
return distanceFunction;
}
@@ -97,7 +96,7 @@ public abstract class AbstractProjectedClustering<R extends Clustering<?>, V ext
*
* @return the distance function
*/
- protected DistanceQuery<V, DoubleDistance> getDistanceQuery(Database database) {
+ protected DistanceQuery<V> getDistanceQuery(Database database) {
return QueryUtil.getDistanceQuery(database, distanceFunction);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/AbstractProjectedDBSCAN.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/AbstractProjectedDBSCAN.java
deleted file mode 100644
index 52e37197..00000000
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/AbstractProjectedDBSCAN.java
+++ /dev/null
@@ -1,445 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering;
-
-/*
- 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.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
-import de.lmu.ifi.dbs.elki.data.Cluster;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.model.ClusterModel;
-import de.lmu.ifi.dbs.elki.data.model.Model;
-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.Database;
-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.DBIDMIter;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
-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.distancefunction.IndexBasedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction;
-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.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
-import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
-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.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.DistanceParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
-
-/**
- * Provides an abstract algorithm requiring a VarianceAnalysisPreprocessor.
- *
- * @author Arthur Zimek
- * @param <V> the type of NumberVector handled by this Algorithm
- */
-public abstract class AbstractProjectedDBSCAN<R extends Clustering<Model>, V extends NumberVector<?>> extends AbstractAlgorithm<R> implements ClusteringAlgorithm<R> {
- /**
- * Parameter to specify the distance function to determine the distance
- * between database objects, must extend
- * {@link de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction}
- * .
- * <p>
- * Key: {@code -projdbscan.distancefunction}
- * </p>
- * <p>
- * Default value:
- * {@link de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction}
- * </p>
- */
- public static final OptionID OUTER_DISTANCE_FUNCTION_ID = new OptionID("projdbscan.outerdistancefunction", "Distance function to determine the distance between database objects.");
-
- /**
- * Parameter distance function
- */
- public static final OptionID INNER_DISTANCE_FUNCTION_ID = new OptionID("projdbscan.distancefunction", "Distance function to determine the neighbors for variance analysis.");
-
- /**
- * Parameter to specify the maximum radius of the neighborhood to be
- * considered, must be suitable to {@link LocallyWeightedDistanceFunction}.
- * <p>
- * Key: {@code -projdbscan.epsilon}
- * </p>
- */
- public static final OptionID EPSILON_ID = new OptionID("projdbscan.epsilon", "The maximum radius of the neighborhood to be considered.");
-
- /**
- * Parameter to specify the intrinsic dimensionality of the clusters to find,
- * must be an integer greater than 0.
- * <p>
- * Key: {@code -projdbscan.lambda}
- * </p>
- */
- public static final OptionID LAMBDA_ID = new OptionID("projdbscan.lambda", "The intrinsic dimensionality of the clusters to find.");
-
- /**
- * Parameter to specify the threshold for minimum number of points in the
- * epsilon-neighborhood of a point, must be an integer greater than 0.
- * <p>
- * Key: {@code -projdbscan.minpts}
- * </p>
- */
- public static final OptionID MINPTS_ID = new OptionID("projdbscan.minpts", "Threshold for minimum number of points in " + "the epsilon-neighborhood of a point.");
-
- /**
- * Holds the instance of the distance function specified by
- * {@link #INNER_DISTANCE_FUNCTION_ID}.
- */
- private LocallyWeightedDistanceFunction<V> distanceFunction;
-
- /**
- * Holds the value of {@link #EPSILON_ID}.
- */
- protected DoubleDistance epsilon;
-
- /**
- * Holds the value of {@link #LAMBDA_ID}.
- */
- private int lambda;
-
- /**
- * Holds the value of {@link #MINPTS_ID}.
- */
- protected int minpts = 1;
-
- /**
- * Holds a list of clusters found.
- */
- private List<ModifiableDBIDs> resultList;
-
- /**
- * Holds a set of noise.
- */
- private ModifiableDBIDs noise;
-
- /**
- * Holds a set of processed ids.
- */
- private ModifiableDBIDs processedIDs;
-
- /**
- * Constructor.
- *
- * @param epsilon Epsilon
- * @param minpts MinPts parameter
- * @param distanceFunction Outer distance function
- * @param lambda Lambda value
- */
- public AbstractProjectedDBSCAN(DoubleDistance epsilon, int minpts, LocallyWeightedDistanceFunction<V> distanceFunction, int lambda) {
- super();
- this.epsilon = epsilon;
- this.minpts = minpts;
- this.distanceFunction = distanceFunction;
- this.lambda = lambda;
- }
-
- /**
- * Run the algorithm
- *
- * @param database Database to process
- * @param relation Relation to process
- * @return Clustering result
- */
- public Clustering<Model> run(Database database, Relation<V> relation) {
- FiniteProgress objprog = getLogger().isVerbose() ? new FiniteProgress("Processing objects", relation.size(), getLogger()) : null;
- IndefiniteProgress clusprog = getLogger().isVerbose() ? new IndefiniteProgress("Number of clusters", getLogger()) : null;
- resultList = new ArrayList<>();
- noise = DBIDUtil.newHashSet();
- processedIDs = DBIDUtil.newHashSet(relation.size());
-
- LocallyWeightedDistanceFunction.Instance<V> distFunc = distanceFunction.instantiate(relation);
- RangeQuery<V, DoubleDistance> rangeQuery = database.getRangeQuery(distFunc);
-
- if(relation.size() >= minpts) {
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- if(!processedIDs.contains(iditer)) {
- expandCluster(distFunc, rangeQuery, DBIDUtil.deref(iditer), objprog, clusprog);
- if(processedIDs.size() == relation.size() && noise.size() == 0) {
- break;
- }
- }
- if(objprog != null && clusprog != null) {
- objprog.setProcessed(processedIDs.size(), getLogger());
- clusprog.setProcessed(resultList.size(), getLogger());
- }
- }
- }
- else {
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- noise.add(iditer);
- if(objprog != null && clusprog != null) {
- objprog.setProcessed(processedIDs.size(), getLogger());
- clusprog.setProcessed(resultList.size(), getLogger());
- }
- }
- }
-
- if(objprog != null && clusprog != null) {
- objprog.setProcessed(processedIDs.size(), getLogger());
- clusprog.setProcessed(resultList.size(), getLogger());
- }
-
- Clustering<Model> result = new Clustering<>(getLongResultName(), getShortResultName());
- for(Iterator<ModifiableDBIDs> resultListIter = resultList.iterator(); resultListIter.hasNext();) {
- Cluster<Model> c = new Cluster<Model>(resultListIter.next(), ClusterModel.CLUSTER);
- result.addToplevelCluster(c);
- }
-
- Cluster<Model> n = new Cluster<Model>(noise, true, ClusterModel.CLUSTER);
- result.addToplevelCluster(n);
-
- if(objprog != null && clusprog != null) {
- objprog.setProcessed(processedIDs.size(), getLogger());
- clusprog.setProcessed(resultList.size(), getLogger());
- }
- // Signal that the progress has completed.
- if(objprog != null && clusprog != null) {
- objprog.ensureCompleted(getLogger());
- clusprog.setCompleted(getLogger());
- }
- return result;
- }
-
- /**
- * Return the long result name.
- *
- * @return Long name for result
- */
- public abstract String getLongResultName();
-
- /**
- * Return the short result name.
- *
- * @return Short name for result
- */
- public abstract String getShortResultName();
-
- /**
- * ExpandCluster function of DBSCAN.
- *
- * @param distFunc Distance query to use
- * @param rangeQuery Range query
- * @param startObjectID the object id of the database object to start the
- * expansion with
- * @param objprog the progress object for logging the current status
- */
- protected void expandCluster(LocallyWeightedDistanceFunction.Instance<V> distFunc, RangeQuery<V, DoubleDistance> rangeQuery, DBID startObjectID, FiniteProgress objprog, IndefiniteProgress clusprog) {
- Integer corrDim = distFunc.getIndex().getLocalProjection(startObjectID).getCorrelationDimension();
-
- if(getLogger().isDebugging()) {
- getLogger().debugFine("EXPAND CLUSTER id = " + startObjectID + " " + corrDim + "\n#clusters: " + resultList.size());
- }
-
- // euclidean epsilon neighborhood < minpts OR local dimensionality >
- // lambda -> noise
- if(corrDim == null || corrDim > lambda) {
- noise.add(startObjectID);
- processedIDs.add(startObjectID);
- if(objprog != null && clusprog != null) {
- objprog.setProcessed(processedIDs.size(), getLogger());
- clusprog.setProcessed(resultList.size(), getLogger());
- }
- return;
- }
-
- // compute weighted epsilon neighborhood
- DistanceDBIDList<DoubleDistance> neighbors = rangeQuery.getRangeForDBID(startObjectID, epsilon);
- // neighbors < minPts -> noise
- if(neighbors.size() < minpts) {
- noise.add(startObjectID);
- processedIDs.add(startObjectID);
- if(objprog != null && clusprog != null) {
- objprog.setProcessed(processedIDs.size(), getLogger());
- clusprog.setProcessed(resultList.size(), getLogger());
- }
- return;
- }
-
- // try to expand the cluster
- ModifiableDBIDs currentCluster = DBIDUtil.newArray();
- ModifiableDBIDs seeds = DBIDUtil.newHashSet();
- for(DistanceDBIDListIter<DoubleDistance> seed = neighbors.iter(); seed.valid(); seed.advance()) {
- int nextID_corrDim = distFunc.getIndex().getLocalProjection(seed).getCorrelationDimension();
- // nextID is not reachable from start object
- if(nextID_corrDim > lambda) {
- continue;
- }
-
- if(!processedIDs.contains(seed)) {
- currentCluster.add(seed);
- processedIDs.add(seed);
- seeds.add(seed);
- }
- else if(noise.contains(seed)) {
- currentCluster.add(seed);
- noise.remove(seed);
- }
- }
-
- while(seeds.size() > 0) {
- DBIDMIter iter = seeds.iter();
- int corrDim_q = distFunc.getIndex().getLocalProjection(iter).getCorrelationDimension();
- // q forms no lambda-dim hyperplane
- if(corrDim_q > lambda) {
- continue;
- }
-
- DistanceDBIDList<DoubleDistance> reachables = rangeQuery.getRangeForDBID(iter, epsilon);
- iter.remove();
-
- if(reachables.size() > minpts) {
- for(DistanceDBIDListIter<DoubleDistance> r = reachables.iter(); r.valid(); r.advance()) {
- int corrDim_r = distFunc.getIndex().getLocalProjection(r).getCorrelationDimension();
- // r is not reachable from q
- if(corrDim_r > lambda) {
- continue;
- }
-
- boolean inNoise = noise.contains(r);
- boolean unclassified = !processedIDs.contains(r);
- if(inNoise || unclassified) {
- if(unclassified) {
- seeds.add(r);
- }
- currentCluster.add(r);
- processedIDs.add(r);
- if(inNoise) {
- noise.remove(r);
- }
- if(objprog != null && clusprog != null) {
- objprog.setProcessed(processedIDs.size(), getLogger());
- int numClusters = currentCluster.size() > minpts ? resultList.size() + 1 : resultList.size();
- clusprog.setProcessed(numClusters, getLogger());
- }
- }
- }
- }
-
- /*
- * if(processedIDs.size() == relation.size() && noise.size() == 0) {
- * break; }
- */
- }
-
- if(currentCluster.size() >= minpts) {
- resultList.add(currentCluster);
- }
- else {
- noise.addDBIDs(currentCluster);
- noise.add(startObjectID);
- processedIDs.add(startObjectID);
- }
-
- if(objprog != null && clusprog != null) {
- objprog.setProcessed(processedIDs.size(), getLogger());
- clusprog.setProcessed(resultList.size(), getLogger());
- }
- }
-
- @Override
- public TypeInformation[] getInputTypeRestriction() {
- return TypeUtil.array(distanceFunction.getInputTypeRestriction());
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public abstract static class Parameterizer<V extends NumberVector<?>, D extends Distance<D>> extends AbstractParameterizer {
- protected DistanceFunction<V, D> innerdist;
-
- protected D epsilon;
-
- protected LocallyWeightedDistanceFunction<V> outerdist;
-
- protected int minpts = -1;
-
- protected Integer lambda;
-
- protected void configInnerDistance(Parameterization config) {
- ObjectParameter<DistanceFunction<V, D>> innerdistP = new ObjectParameter<>(AbstractProjectedDBSCAN.INNER_DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
- if(config.grab(innerdistP)) {
- innerdist = innerdistP.instantiateClass(config);
- }
- }
-
- protected void configEpsilon(Parameterization config, DistanceFunction<V, D> innerdist) {
- D distanceParser = innerdist != null ? innerdist.getDistanceFactory() : null;
- DistanceParameter<D> epsilonP = new DistanceParameter<>(EPSILON_ID, distanceParser);
- if(config.grab(epsilonP)) {
- epsilon = epsilonP.getValue();
- }
- }
-
- protected void configMinPts(Parameterization config) {
- IntParameter minptsP = new IntParameter(MINPTS_ID);
- minptsP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
- if(config.grab(minptsP)) {
- minpts = minptsP.getValue();
- }
- }
-
- protected void configOuterDistance(Parameterization config, D epsilon, int minpts, Class<?> preprocessorClass, DistanceFunction<V, D> innerdist) {
- ObjectParameter<LocallyWeightedDistanceFunction<V>> outerdistP = new ObjectParameter<>(OUTER_DISTANCE_FUNCTION_ID, LocallyWeightedDistanceFunction.class, LocallyWeightedDistanceFunction.class);
- if(config.grab(outerdistP)) {
- // parameters for the distance function
- ListParameterization distanceFunctionParameters = new ListParameterization();
- // distanceFunctionParameters.addFlag(PreprocessorHandler.OMIT_PREPROCESSING_ID);
- distanceFunctionParameters.addParameter(IndexBasedDistanceFunction.INDEX_ID, preprocessorClass);
- distanceFunctionParameters.addParameter(AbstractProjectedDBSCAN.INNER_DISTANCE_FUNCTION_ID, innerdist);
- distanceFunctionParameters.addParameter(AbstractProjectedDBSCAN.EPSILON_ID, epsilon);
- distanceFunctionParameters.addParameter(AbstractProjectedDBSCAN.MINPTS_ID, minpts);
- ChainedParameterization combinedConfig = new ChainedParameterization(distanceFunctionParameters, config);
- combinedConfig.errorsTo(config);
- outerdist = outerdistP.instantiateClass(combinedConfig);
- }
- }
-
- protected void configLambda(Parameterization config) {
- IntParameter lambdaP = new IntParameter(LAMBDA_ID);
- lambdaP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
- if(config.grab(lambdaP)) {
- lambda = lambdaP.getValue();
- }
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/CanopyPreClustering.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/CanopyPreClustering.java
index 2dff7554..1b1a4026 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/CanopyPreClustering.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/CanopyPreClustering.java
@@ -1,9 +1,10 @@
package de.lmu.ifi.dbs.elki.algorithm.clustering;
+
/*
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 +28,7 @@ import java.util.ArrayList;
import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.model.ClusterModel;
+import de.lmu.ifi.dbs.elki.data.model.PrototypeModel;
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.Database;
@@ -38,20 +39,19 @@ import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
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.constraints.LessEqualGlobalConstraint;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DistanceParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
* Canopy pre-clustering is a simple preprocessing step for clustering.
*
+ * Reference:
* <p>
- * Reference:<br>
* A. McCallum, K. Nigam, L.H. Ungar<br />
* Efficient Clustering of High Dimensional Data Sets with Application to
* Reference Matching<br />
@@ -62,10 +62,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DistanceParameter
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
-@Reference(authors = "A. McCallum, K. Nigam, L.H. Ungar", title = "Efficient Clustering of High Dimensional Data Sets with Application to Reference Matching", booktitle = "Proc. 6th ACM SIGKDD international conference on Knowledge discovery and data mining", url = "http://dx.doi.org/10.1145%2F347090.347123")
-public class CanopyPreClustering<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm<O, D, Clustering<ClusterModel>> implements ClusteringAlgorithm<Clustering<ClusterModel>> {
+@Reference(authors = "A. McCallum, K. Nigam, L.H. Ungar", //
+title = "Efficient Clustering of High Dimensional Data Sets with Application to Reference Matching", //
+booktitle = "Proc. 6th ACM SIGKDD international conference on Knowledge discovery and data mining",//
+url = "http://dx.doi.org/10.1145%2F347090.347123")
+public class CanopyPreClustering<O> extends AbstractDistanceBasedAlgorithm<O, Clustering<PrototypeModel<O>>> implements ClusteringAlgorithm<Clustering<PrototypeModel<O>>> {
/**
* Class logger.
*/
@@ -74,12 +76,12 @@ public class CanopyPreClustering<O, D extends Distance<D>> extends AbstractDista
/**
* Threshold for inclusion
*/
- private D t1;
+ private double t1;
/**
* Threshold for removal
*/
- private D t2;
+ private double t2;
/**
* Constructor.
@@ -88,7 +90,7 @@ public class CanopyPreClustering<O, D extends Distance<D>> extends AbstractDista
* @param t1 Inclusion threshold
* @param t2 Exclusion threshold
*/
- public CanopyPreClustering(DistanceFunction<? super O, D> distanceFunction, D t1, D t2) {
+ public CanopyPreClustering(DistanceFunction<? super O> distanceFunction, double t1, double t2) {
super(distanceFunction);
this.t1 = t1;
this.t2 = t2;
@@ -100,13 +102,13 @@ public class CanopyPreClustering<O, D extends Distance<D>> extends AbstractDista
* @param database Database
* @param relation Relation to process
*/
- public Clustering<ClusterModel> run(Database database, Relation<O> relation) {
- DistanceQuery<O, D> dq = database.getDistanceQuery(relation, getDistanceFunction());
+ public Clustering<PrototypeModel<O>> run(Database database, Relation<O> relation) {
+ DistanceQuery<O> dq = database.getDistanceQuery(relation, getDistanceFunction());
ModifiableDBIDs ids = DBIDUtil.newHashSet(relation.getDBIDs());
- ArrayList<Cluster<ClusterModel>> clusters = new ArrayList<>();
+ ArrayList<Cluster<PrototypeModel<O>>> clusters = new ArrayList<>();
final int size = relation.size();
- if(t1.compareTo(t2) <= 0) {
+ if(t1 <= t2) {
LOG.warning(Parameterizer.T1_ID.getName() + " must be larger than " + Parameterizer.T2_ID.getName());
}
@@ -126,27 +128,25 @@ public class CanopyPreClustering<O, D extends Distance<D>> extends AbstractDista
// Compare to remaining objects:
for(; iter.valid(); iter.advance()) {
- D dist = dq.distance(first, iter);
+ double dist = dq.distance(first, iter);
// Inclusion threshold:
- if(t1.compareTo(dist) >= 0) {
+ if(dist <= t1) {
cids.add(iter);
}
// Removal threshold:
- if(t2.compareTo(dist) >= 0) {
+ if(dist <= t2) {
iter.remove();
}
}
// TODO: remember the central object using a CanopyModel?
// Construct cluster:
- clusters.add(new Cluster<>(cids, ClusterModel.CLUSTER));
+ clusters.add(new Cluster<>(cids, new PrototypeModel<>(relation.get(first))));
if(prog != null) {
prog.setProcessed(size - ids.size(), LOG);
}
}
- if(prog != null) {
- prog.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(prog);
return new Clustering<>("Canopy clustering", "canopy-clustering", clusters);
}
@@ -169,13 +169,12 @@ public class CanopyPreClustering<O, D extends Distance<D>> extends AbstractDista
* @apiviz.exclude
*
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Parameter for the inclusion threshold of canopy clustering.
*
- * Note: t1 > t2
+ * Note: t1 >= t2
*
* Syntax:
*
@@ -183,12 +182,12 @@ public class CanopyPreClustering<O, D extends Distance<D>> extends AbstractDista
* -canopy.t1 &lt;value&gt;
* </pre>
*/
- public static final OptionID T1_ID = new OptionID("canopy.t1", "Inclusion threshold for canopy clustering. t1 > t2!");
+ public static final OptionID T1_ID = new OptionID("canopy.t1", "Inclusion threshold for canopy clustering. t1 >= t2!");
/**
* Parameter for the removal threshold of canopy clustering.
*
- * Note: t1 > t2
+ * Note: t1 >= t2
*
* Syntax:
*
@@ -196,41 +195,38 @@ public class CanopyPreClustering<O, D extends Distance<D>> extends AbstractDista
* -canopy.t2 &lt;value&gt;
* </pre>
*/
- public static final OptionID T2_ID = new OptionID("canopy.t2", "Removal threshold for canopy clustering. t1 > t2!");
+ public static final OptionID T2_ID = new OptionID("canopy.t2", "Removal threshold for canopy clustering. t1 >= t2!");
/**
* Threshold for inclusion
*/
- private D t1;
+ private double t1;
/**
* Threshold for removal
*/
- private D t2;
+ private double t2;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- DistanceParameter<D> t1P = new DistanceParameter<>(T1_ID, distanceFunction);
+ DoubleParameter t1P = new DoubleParameter(T1_ID);
if(config.grab(t1P)) {
- t1 = t1P.getValue();
+ t1 = t1P.doubleValue();
}
- DistanceParameter<D> t2P = new DistanceParameter<>(T2_ID, distanceFunction);
- // TODO: add distance constraint t1 > t2
+ DoubleParameter t2P = new DoubleParameter(T2_ID);
if(config.grab(t2P)) {
- t2 = t2P.getValue();
- if(t1.compareTo(t2) <= 0) {
- config.reportError(new WrongParameterValueException(t2P, T1_ID.getName() + " must be larger than " + T2_ID.getName()));
- }
+ t2 = t2P.doubleValue();
}
+ // Check that t1 >= t2:
+ config.checkConstraint(new LessEqualGlobalConstraint<>(t2P, t1P));
}
@Override
- protected CanopyPreClustering<O, D> makeInstance() {
+ protected CanopyPreClustering<O> makeInstance() {
return new CanopyPreClustering<>(distanceFunction, t1, t2);
}
-
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/ClusteringAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/ClusteringAlgorithm.java
index 249dc313..f62d0ea1 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/ClusteringAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/ClusteringAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering;
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
@@ -42,7 +42,6 @@ import de.lmu.ifi.dbs.elki.database.Database;
*
* @apiviz.has Clustering
* @apiviz.has Model
- * @apiviz.excludeSubtypes
*
* @param <C> Clustering type
*/
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/DBSCAN.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/DBSCAN.java
index 09c78fec..9d597d74 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/DBSCAN.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/DBSCAN.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering;
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
@@ -43,7 +43,6 @@ import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
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.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
@@ -53,28 +52,31 @@ 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.DistanceParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
/**
- * DBSCAN provides the DBSCAN algorithm, an algorithm to find density-connected
- * sets in a database.
+ * Density-Based Clustering of Applications with Noise (DBSCAN), an algorithm to
+ * find density-connected sets in a database.
* <p>
* Reference: <br>
- * M. Ester, H.-P. Kriegel, J. Sander, and X. Xu: A Density-Based Algorithm for
- * Discovering Clusters in Large Spatial Databases with Noise. <br>
+ * M. Ester, H.-P. Kriegel, J. Sander, and X. Xu:<br />
+ * A Density-Based Algorithm for Discovering Clusters in Large Spatial Databases
+ * with Noise<br />
* In Proc. 2nd Int. Conf. on Knowledge Discovery and Data Mining (KDD '96),
* Portland, OR, 1996.
* </p>
*
* @author Arthur Zimek
* @param <O> the type of Object the algorithm is applied to
- * @param <D> the type of Distance used
*/
@Title("DBSCAN: Density-Based Clustering of Applications with Noise")
@Description("Algorithm to find density-connected sets in a database based on the parameters 'minpts' and 'epsilon' (specifying a volume). " + "These two parameters determine a density threshold for clustering.")
-@Reference(authors = "M. Ester, H.-P. Kriegel, J. Sander, and X. Xu", title = "A Density-Based Algorithm for Discovering Clusters in Large Spatial Databases with Noise", booktitle = "Proc. 2nd Int. Conf. on Knowledge Discovery and Data Mining (KDD '96), Portland, OR, 1996", url = "http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.71.1980")
-public class DBSCAN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm<O, D, Clustering<Model>> implements ClusteringAlgorithm<Clustering<Model>> {
+@Reference(authors = "M. Ester, H.-P. Kriegel, J. Sander, and X. Xu", //
+title = "A Density-Based Algorithm for Discovering Clusters in Large Spatial Databases with Noise", //
+booktitle = "Proc. 2nd Int. Conf. on Knowledge Discovery and Data Mining (KDD '96), Portland, OR, 1996", //
+url = "http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.71.1980")
+public class DBSCAN<O> extends AbstractDistanceBasedAlgorithm<O, Clustering<Model>> implements ClusteringAlgorithm<Clustering<Model>> {
/**
* The logger for this class.
*/
@@ -83,7 +85,7 @@ public class DBSCAN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgor
/**
* Holds the epsilon radius threshold.
*/
- protected D epsilon;
+ protected double epsilon;
/**
* Holds the minimum cluster size.
@@ -112,7 +114,7 @@ public class DBSCAN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgor
* @param epsilon Epsilon value
* @param minpts Minpts parameter
*/
- public DBSCAN(DistanceFunction<? super O, D> distanceFunction, D epsilon, int minpts) {
+ public DBSCAN(DistanceFunction<? super O> distanceFunction, double epsilon, int minpts) {
super(distanceFunction);
this.epsilon = epsilon;
this.minpts = minpts;
@@ -122,7 +124,7 @@ public class DBSCAN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgor
* Performs the DBSCAN algorithm on the given database.
*/
public Clustering<Model> run(Relation<O> relation) {
- RangeQuery<O, D> rangeQuery = QueryUtil.getRangeQuery(relation, getDistanceFunction());
+ RangeQuery<O> rangeQuery = QueryUtil.getRangeQuery(relation, getDistanceFunction());
final int size = relation.size();
FiniteProgress objprog = LOG.isVerbose() ? new FiniteProgress("Processing objects", size, LOG) : null;
@@ -152,12 +154,8 @@ public class DBSCAN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgor
}
}
// Finish progress logging
- if(objprog != null) {
- objprog.ensureCompleted(LOG);
- }
- if(clusprog != null) {
- clusprog.setCompleted(LOG);
- }
+ LOG.ensureCompleted(objprog);
+ LOG.setCompleted(clusprog);
Clustering<Model> result = new Clustering<>("DBSCAN Clustering", "dbscan-clustering");
for(ModifiableDBIDs res : resultList) {
@@ -181,7 +179,7 @@ public class DBSCAN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgor
* @param startObjectID potential seed of a new potential cluster
* @param objprog the progress object for logging the current status
*/
- protected void expandCluster(Relation<O> relation, RangeQuery<O, D> rangeQuery, DBIDRef startObjectID, FiniteProgress objprog, IndefiniteProgress clusprog) {
+ protected void expandCluster(Relation<O> relation, RangeQuery<O> rangeQuery, DBIDRef startObjectID, FiniteProgress objprog, IndefiniteProgress clusprog) {
DBIDs neighbors = rangeQuery.getRangeForDBID(startObjectID, epsilon);
// startObject is no core-object
@@ -270,7 +268,7 @@ public class DBSCAN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgor
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Parameter to specify the maximum radius of the neighborhood to be
* considered, must be suitable to the distance function specified.
@@ -283,14 +281,14 @@ public class DBSCAN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgor
*/
public static final OptionID MINPTS_ID = new OptionID("dbscan.minpts", "Threshold for minimum number of points in the epsilon-neighborhood of a point.");
- protected D epsilon = null;
+ protected double epsilon;
protected int minpts = 0;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- DistanceParameter<D> epsilonP = new DistanceParameter<>(EPSILON_ID, distanceFunction);
+ DoubleParameter epsilonP = new DoubleParameter(EPSILON_ID);
if(config.grab(epsilonP)) {
epsilon = epsilonP.getValue();
}
@@ -303,7 +301,7 @@ public class DBSCAN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgor
}
@Override
- protected DBSCAN<O, D> makeInstance() {
+ protected DBSCAN<O> makeInstance() {
return new DBSCAN<>(distanceFunction, epsilon, minpts);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/NaiveMeanShiftClustering.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/NaiveMeanShiftClustering.java
index a4d6e307..1d52b80d 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/NaiveMeanShiftClustering.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/NaiveMeanShiftClustering.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering;
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
@@ -35,15 +35,14 @@ import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
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.distancefunction.DistanceFunction;
-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.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Centroid;
@@ -52,7 +51,7 @@ import de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions.KernelDensityFunction
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
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.DistanceParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
@@ -80,10 +79,9 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
* @author Erich Schubert
*
* @param <V> Vector type
- * @param <D> Distance type
*/
@Reference(authors = "Y. Cheng", title = "Mean shift, mode seeking, and clustering", booktitle = "IEEE Transactions on Pattern Analysis and Machine Intelligence 17-8", url = "http://dx.doi.org/10.1109/34.400568")
-public class NaiveMeanShiftClustering<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<V, D, Clustering<MeanModel<V>>> implements ClusteringAlgorithm<Clustering<MeanModel<V>>> {
+public class NaiveMeanShiftClustering<V extends NumberVector> extends AbstractDistanceBasedAlgorithm<V, Clustering<MeanModel>> implements ClusteringAlgorithm<Clustering<MeanModel>> {
/**
* Class logger.
*/
@@ -97,7 +95,7 @@ public class NaiveMeanShiftClustering<V extends NumberVector<?>, D extends Numbe
/**
* Range of the kernel.
*/
- D range;
+ double bandwidth;
/**
* Maximum number of iterations.
@@ -111,10 +109,10 @@ public class NaiveMeanShiftClustering<V extends NumberVector<?>, D extends Numbe
* @param kernel Kernel function
* @param range Kernel radius
*/
- public NaiveMeanShiftClustering(DistanceFunction<? super V, D> distanceFunction, KernelDensityFunction kernel, D range) {
+ public NaiveMeanShiftClustering(DistanceFunction<? super V> distanceFunction, KernelDensityFunction kernel, double range) {
super(distanceFunction);
this.kernel = kernel;
- this.range = range;
+ this.bandwidth = range;
}
/**
@@ -124,13 +122,11 @@ public class NaiveMeanShiftClustering<V extends NumberVector<?>, D extends Numbe
* @param relation Data relation
* @return Clustering result
*/
- public Clustering<MeanModel<V>> run(Database database, Relation<V> relation) {
- final DistanceQuery<V, D> distq = database.getDistanceQuery(relation, getDistanceFunction());
- final RangeQuery<V, D> rangeq = database.getRangeQuery(distq);
+ public Clustering<MeanModel> run(Database database, Relation<V> relation) {
+ final DistanceQuery<V> distq = database.getDistanceQuery(relation, getDistanceFunction());
+ final RangeQuery<V> rangeq = database.getRangeQuery(distq);
final int dim = RelationUtil.dimensionality(relation);
- // Kernel bandwidth, for normalization
- final double bandwidth = range.doubleValue();
// Stopping threshold
final double threshold = bandwidth * 1E-10;
@@ -141,25 +137,25 @@ public class NaiveMeanShiftClustering<V extends NumberVector<?>, D extends Numbe
FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Mean-shift clustering", relation.size(), LOG) : null;
- for (DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
// Initial position:
V position = relation.get(iter);
- iterations: for (int j = 1; j <= MAXITER; j++) {
+ iterations: for(int j = 1; j <= MAXITER; j++) {
// Compute new position:
V newvec = null;
{
- DistanceDBIDList<D> neigh = rangeq.getRangeForObject(position, range);
+ DoubleDBIDList neigh = rangeq.getRangeForObject(position, bandwidth);
boolean okay = (neigh.size() > 1) || (neigh.size() >= 1 && j > 1);
- if (okay) {
+ if(okay) {
Centroid newpos = new Centroid(dim);
- for (DistanceDBIDListIter<D> niter = neigh.iter(); niter.valid(); niter.advance()) {
- final double weight = kernel.density(niter.getDistance().doubleValue() / bandwidth);
+ for(DoubleDBIDListIter niter = neigh.iter(); niter.valid(); niter.advance()) {
+ final double weight = kernel.density(niter.doubleValue() / bandwidth);
newpos.put(relation.get(niter), weight);
}
newvec = newpos.toVector(relation);
// TODO: detect 0 weight!
}
- if (!okay) {
+ if(!okay) {
noise.add(iter);
break iterations;
}
@@ -167,28 +163,28 @@ public class NaiveMeanShiftClustering<V extends NumberVector<?>, D extends Numbe
// Test if we are close to one of the known clusters:
double bestd = Double.POSITIVE_INFINITY;
Pair<V, ModifiableDBIDs> bestp = null;
- for (Pair<V, ModifiableDBIDs> pair : clusters) {
- final double merged = distq.distance(newvec, pair.first).doubleValue();
- if (merged < bestd) {
+ for(Pair<V, ModifiableDBIDs> pair : clusters) {
+ final double merged = distq.distance(newvec, pair.first);
+ if(merged < bestd) {
bestd = merged;
bestp = pair;
}
}
// Check for convergence:
- D delta = distq.distance(position, newvec);
- if (bestd < 10 * threshold || bestd * 2 < delta.doubleValue()) {
+ double delta = distq.distance(position, newvec);
+ if(bestd < 10 * threshold || bestd * 2 < delta) {
bestp.second.add(iter);
break iterations;
}
- if (j == MAXITER) {
- LOG.warning("No convergence after " + MAXITER + " iterations. Distance: " + delta.toString());
+ if(j == MAXITER) {
+ LOG.warning("No convergence after " + MAXITER + " iterations. Distance: " + delta);
}
- if (Double.isNaN(delta.doubleValue())) {
+ if(Double.isNaN(delta)) {
LOG.warning("Encountered NaN distance. Invalid center vector? " + newvec.toString());
break iterations;
}
- if (j == MAXITER || delta.doubleValue() < threshold) {
- if (LOG.isDebuggingFine()) {
+ if(j == MAXITER || delta < threshold) {
+ if(LOG.isDebuggingFine()) {
LOG.debugFine("New cluster:" + newvec + " delta: " + delta + " threshold: " + threshold + " bestd: " + bestd);
}
ArrayModifiableDBIDs cids = DBIDUtil.newArray();
@@ -198,22 +194,18 @@ public class NaiveMeanShiftClustering<V extends NumberVector<?>, D extends Numbe
}
position = newvec;
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if (prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
- ArrayList<Cluster<MeanModel<V>>> cs = new ArrayList<>(clusters.size());
- for (Pair<V, ModifiableDBIDs> pair : clusters) {
- cs.add(new Cluster<>(pair.second, new MeanModel<>(pair.first)));
+ ArrayList<Cluster<MeanModel>> cs = new ArrayList<>(clusters.size());
+ for(Pair<V, ModifiableDBIDs> pair : clusters) {
+ cs.add(new Cluster<>(pair.second, new MeanModel(pair.first.getColumnVector())));
}
- if (noise.size() > 0) {
- cs.add(new Cluster<MeanModel<V>>(noise, true));
+ if(noise.size() > 0) {
+ cs.add(new Cluster<MeanModel>(noise, true));
}
- Clustering<MeanModel<V>> c = new Clustering<>("Mean-shift Clustering", "mean-shift-clustering", cs);
+ Clustering<MeanModel> c = new Clustering<>("Mean-shift Clustering", "mean-shift-clustering", cs);
return c;
}
@@ -235,9 +227,8 @@ public class NaiveMeanShiftClustering<V extends NumberVector<?>, D extends Numbe
* @apiviz.exclude
*
* @param <V> Vector type
- * @param <D> Distance type
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<V, D> {
+ public static class Parameterizer<V extends NumberVector> extends AbstractDistanceBasedAlgorithm.Parameterizer<V> {
/**
* Parameter for kernel function.
*/
@@ -256,23 +247,23 @@ public class NaiveMeanShiftClustering<V extends NumberVector<?>, D extends Numbe
/**
* Kernel radius.
*/
- D range;
+ double range;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
ObjectParameter<KernelDensityFunction> kernelP = new ObjectParameter<>(KERNEL_ID, KernelDensityFunction.class, EpanechnikovKernelDensityFunction.class);
- if (config.grab(kernelP)) {
+ if(config.grab(kernelP)) {
kernel = kernelP.instantiateClass(config);
}
- DistanceParameter<D> rangeP = new DistanceParameter<>(RANGE_ID, distanceFunction);
- if (config.grab(rangeP)) {
+ DoubleParameter rangeP = new DoubleParameter(RANGE_ID);
+ if(config.grab(rangeP)) {
range = rangeP.getValue();
}
}
@Override
- protected NaiveMeanShiftClustering<V, D> makeInstance() {
+ protected NaiveMeanShiftClustering<V> makeInstance() {
return new NaiveMeanShiftClustering<>(distanceFunction, kernel, range);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICS.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICS.java
deleted file mode 100644
index a4a922df..00000000
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICS.java
+++ /dev/null
@@ -1,319 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering;
-
-/*
- 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.algorithm.AbstractDistanceBasedAlgorithm;
-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.Database;
-import de.lmu.ifi.dbs.elki.database.QueryUtil;
-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.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
-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.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
-import de.lmu.ifi.dbs.elki.result.optics.DoubleDistanceClusterOrderEntry;
-import de.lmu.ifi.dbs.elki.result.optics.GenericClusterOrderEntry;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.UpdatableHeap;
-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;
-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.DistanceParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
-
-/**
- * OPTICS provides the OPTICS algorithm.
- * <p>
- * Reference: M. Ankerst, M. Breunig, H.-P. Kriegel, and J. Sander: OPTICS:
- * Ordering Points to Identify the Clustering Structure. <br>
- * In: Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '99).
- * </p>
- *
- * @author Elke Achtert
- * @param <O> the type of DatabaseObjects handled by the algorithm
- * @param <D> the type of Distance used to discern objects
- */
-@Title("OPTICS: Density-Based Hierarchical Clustering")
-@Description("Algorithm to find density-connected sets in a database based on the parameters 'minPts' and 'epsilon' (specifying a volume). These two parameters determine a density threshold for clustering.")
-@Reference(authors = "M. Ankerst, M. Breunig, H.-P. Kriegel, and J. Sander", title = "OPTICS: Ordering Points to Identify the Clustering Structure", booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '99)", url = "http://dx.doi.org/10.1145/304181.304187")
-public class OPTICS<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm<O, D, ClusterOrderResult<D>> implements OPTICSTypeAlgorithm<D> {
- /**
- * The logger for this class.
- */
- private static final Logging LOG = Logging.getLogger(OPTICS.class);
-
- /**
- * Parameter to specify the maximum radius of the neighborhood to be
- * considered, must be suitable to the distance function specified.
- */
- public static final OptionID EPSILON_ID = new OptionID("optics.epsilon", "The maximum radius of the neighborhood to be considered.");
-
- /**
- * Parameter to specify the threshold for minimum number of points in the
- * epsilon-neighborhood of a point, must be an integer greater than 0.
- */
- public static final OptionID MINPTS_ID = new OptionID("optics.minpts", "Threshold for minimum number of points in the epsilon-neighborhood of a point.");
-
- /**
- * Hold the value of {@link #EPSILON_ID}.
- */
- private D epsilon;
-
- /**
- * Holds the value of {@link #MINPTS_ID}.
- */
- private int minpts;
-
- /**
- * Holds a set of processed ids.
- */
- private ModifiableDBIDs processedIDs;
-
- /**
- * Constructor.
- *
- * @param distanceFunction Distance function
- * @param epsilon Epsilon value
- * @param minpts Minpts value
- */
- public OPTICS(DistanceFunction<? super O, D> distanceFunction, D epsilon, int minpts) {
- super(distanceFunction);
- this.epsilon = epsilon;
- this.minpts = minpts;
- }
-
- /**
- * Run OPTICS on the database.
- *
- * @param database Database
- * @param relation Relation
- * @return Result
- */
- public ClusterOrderResult<D> run(Database database, Relation<O> relation) {
- // Default value is infinite distance
- if(epsilon == null) {
- epsilon = getDistanceFunction().getDistanceFactory().infiniteDistance();
- }
- RangeQuery<O, D> rangeQuery = QueryUtil.getRangeQuery(relation, getDistanceFunction(), epsilon);
-
- int size = relation.size();
- final FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("OPTICS", size, LOG) : null;
-
- processedIDs = DBIDUtil.newHashSet(size);
- ClusterOrderResult<D> clusterOrder = new ClusterOrderResult<>("OPTICS Clusterorder", "optics-clusterorder");
-
- if(getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction && DoubleDistance.class.isInstance(epsilon)) {
- // Optimized codepath for double-based distances. Avoids Java
- // boxing/unboxing.
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- if(!processedIDs.contains(iditer)) {
- // We need to do some ugly casts to be able to run the optimized
- // version, unfortunately.
- @SuppressWarnings("unchecked")
- final ClusterOrderResult<DoubleDistance> doubleClusterOrder = ClusterOrderResult.class.cast(clusterOrder);
- @SuppressWarnings("unchecked")
- final RangeQuery<O, DoubleDistance> doubleRangeQuery = RangeQuery.class.cast(rangeQuery);
- final DoubleDistance depsilon = DoubleDistance.class.cast(epsilon);
- expandClusterOrderDouble(doubleClusterOrder, database, doubleRangeQuery, DBIDUtil.deref(iditer), depsilon, progress);
- }
- }
- }
- else {
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- if(!processedIDs.contains(iditer)) {
- expandClusterOrder(clusterOrder, database, rangeQuery, DBIDUtil.deref(iditer), epsilon, progress);
- }
- }
- }
- if(progress != null) {
- progress.ensureCompleted(LOG);
- }
-
- return clusterOrder;
- }
-
- /**
- * OPTICS-function expandClusterOrder.
- *
- * @param clusterOrder Cluster order result to expand
- * @param database the database on which the algorithm is run
- * @param rangeQuery the range query to use
- * @param objectID the currently processed object
- * @param epsilon Epsilon range value
- * @param progress the progress object to actualize the current progress if
- * the algorithm
- */
- protected void expandClusterOrder(ClusterOrderResult<D> clusterOrder, Database database, RangeQuery<O, D> rangeQuery, DBID objectID, D epsilon, FiniteProgress progress) {
- UpdatableHeap<ClusterOrderEntry<D>> heap = new UpdatableHeap<>();
- heap.add(new GenericClusterOrderEntry<>(objectID, null, getDistanceFunction().getDistanceFactory().infiniteDistance()));
-
- while(!heap.isEmpty()) {
- final ClusterOrderEntry<D> current = heap.poll();
- clusterOrder.add(current);
- processedIDs.add(current.getID());
-
- DistanceDBIDList<D> neighbors = rangeQuery.getRangeForDBID(current.getID(), epsilon);
- if(neighbors.size() >= minpts) {
- final DistanceDBIDPair<D> last = neighbors.get(minpts - 1);
- D coreDistance = last.getDistance();
-
- for(DistanceDBIDListIter<D> neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
- if(processedIDs.contains(neighbor)) {
- continue;
- }
- D reachability = DistanceUtil.max(neighbor.getDistance(), coreDistance);
- heap.add(new GenericClusterOrderEntry<>(DBIDUtil.deref(neighbor), current.getID(), reachability));
- }
- }
- if(progress != null) {
- progress.setProcessed(processedIDs.size(), LOG);
- }
- }
- }
-
- /**
- * OPTICS-function expandClusterOrder.
- *
- * @param clusterOrder Cluster order result to expand
- * @param database the database on which the algorithm is run
- * @param rangeQuery the range query to use
- * @param objectID the currently processed object
- * @param epsilon Query epsilon
- * @param progress the progress object to actualize the current progress if
- * the algorithm
- */
- protected void expandClusterOrderDouble(ClusterOrderResult<DoubleDistance> clusterOrder, Database database, RangeQuery<O, DoubleDistance> rangeQuery, DBID objectID, DoubleDistance epsilon, FiniteProgress progress) {
- UpdatableHeap<DoubleDistanceClusterOrderEntry> heap = new UpdatableHeap<>();
- heap.add(new DoubleDistanceClusterOrderEntry(objectID, null, Double.POSITIVE_INFINITY));
-
- while(!heap.isEmpty()) {
- final DoubleDistanceClusterOrderEntry current = heap.poll();
- clusterOrder.add(current);
- processedIDs.add(current.getID());
-
- DistanceDBIDList<DoubleDistance> neighbors = rangeQuery.getRangeForDBID(current.getID(), epsilon);
- if(neighbors.size() >= minpts) {
- final DistanceDBIDPair<DoubleDistance> last = neighbors.get(minpts - 1);
- if(last instanceof DoubleDistanceDBIDPair) {
- double coreDistance = ((DoubleDistanceDBIDPair) last).doubleDistance();
-
- for(DistanceDBIDListIter<DoubleDistance> neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
- if(processedIDs.contains(neighbor)) {
- continue;
- }
- double reachability = Math.max(((DoubleDistanceDBIDListIter) neighbor).doubleDistance(), coreDistance);
- heap.add(new DoubleDistanceClusterOrderEntry(DBIDUtil.deref(neighbor), current.getID(), reachability));
- }
- }
- else {
- // Actually we have little gains in this situation,
- // Only if we got an optimized result before.
- double coreDistance = last.getDistance().doubleValue();
-
- for(DistanceDBIDListIter<DoubleDistance> neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
- if(processedIDs.contains(neighbor)) {
- continue;
- }
- double reachability = Math.max(neighbor.getDistance().doubleValue(), coreDistance);
- heap.add(new DoubleDistanceClusterOrderEntry(DBIDUtil.deref(neighbor), current.getID(), reachability));
- }
- }
- }
- if(progress != null) {
- progress.setProcessed(processedIDs.size(), LOG);
- }
- }
- }
-
- @Override
- public int getMinPts() {
- return minpts;
- }
-
- @Override
- public D getDistanceFactory() {
- return getDistanceFunction().getDistanceFactory();
- }
-
- @Override
- public TypeInformation[] getInputTypeRestriction() {
- return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
- }
-
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
- protected D epsilon = null;
-
- protected int minpts = 0;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- DistanceParameter<D> epsilonP = new DistanceParameter<>(EPSILON_ID, distanceFunction, true);
- if(config.grab(epsilonP)) {
- epsilon = epsilonP.getValue();
- }
-
- IntParameter minptsP = new IntParameter(MINPTS_ID);
- minptsP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
- if(config.grab(minptsP)) {
- minpts = minptsP.intValue();
- }
- }
-
- @Override
- protected OPTICS<O, D> makeInstance() {
- return new OPTICS<>(distanceFunction, epsilon, minpts);
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/SNNClustering.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/SNNClustering.java
index 86bb9a09..d785b83f 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/SNNClustering.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/SNNClustering.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering;
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
@@ -38,11 +38,11 @@ import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
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.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.database.query.similarity.SimilarityQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.IntegerDistance;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.SharedNearestNeighborSimilarityFunction;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
@@ -55,7 +55,6 @@ 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.DistanceParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
/**
@@ -76,7 +75,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*/
@Title("SNN: Shared Nearest Neighbor Clustering")
@Description("Algorithm to find shared-nearest-neighbors-density-connected sets in a database based on the " + "parameters 'minPts' and 'epsilon' (specifying a volume). " + "These two parameters determine a density threshold for clustering.")
-@Reference(authors = "L. Ertöz, M. Steinbach, V. Kumar", title = "Finding Clusters of Different Sizes, Shapes, and Densities in Noisy, High Dimensional Data", booktitle = "Proc. of SIAM Data Mining (SDM), 2003", url = "http://www.siam.org/meetings/sdm03/proceedings/sdm03_05.pdf")
+@Reference(authors = "L. Ertöz, M. Steinbach, V. Kumar", //
+title = "Finding Clusters of Different Sizes, Shapes, and Densities in Noisy, High Dimensional Data", //
+booktitle = "Proc. of SIAM Data Mining (SDM), 2003", //
+url = "http://www.siam.org/meetings/sdm03/proceedings/sdm03_05.pdf")
public class SNNClustering<O> extends AbstractAlgorithm<Clustering<Model>> implements ClusteringAlgorithm<Clustering<Model>> {
/**
* The logger for this class.
@@ -84,24 +86,12 @@ public class SNNClustering<O> extends AbstractAlgorithm<Clustering<Model>> imple
private static final Logging LOG = Logging.getLogger(SNNClustering.class);
/**
- * Parameter to specify the minimum SNN density, must be an integer greater
- * than 0.
+ * Epsilon radius threshold.
*/
- public static final OptionID EPSILON_ID = new OptionID("snn.epsilon", "The minimum SNN density.");
+ private int epsilon;
/**
- * Holds the value of {@link #EPSILON_ID}.
- */
- private IntegerDistance epsilon;
-
- /**
- * Parameter to specify the threshold for minimum number of points in the
- * epsilon-SNN-neighborhood of a point, must be an integer greater than 0.
- */
- public static final OptionID MINPTS_ID = new OptionID("snn.minpts", "Threshold for minimum number of points in " + "the epsilon-SNN-neighborhood of a point.");
-
- /**
- * Holds the value of {@link #MINPTS_ID}.
+ * Minimum number of clusters for connectedness.
*/
private int minpts;
@@ -132,7 +122,7 @@ public class SNNClustering<O> extends AbstractAlgorithm<Clustering<Model>> imple
* @param epsilon Epsilon
* @param minpts Minpts
*/
- public SNNClustering(SharedNearestNeighborSimilarityFunction<O> similarityFunction, IntegerDistance epsilon, int minpts) {
+ public SNNClustering(SharedNearestNeighborSimilarityFunction<O> similarityFunction, int epsilon, int minpts) {
super();
this.similarityFunction = similarityFunction;
this.epsilon = epsilon;
@@ -147,7 +137,7 @@ public class SNNClustering<O> extends AbstractAlgorithm<Clustering<Model>> imple
* @return Result
*/
public Clustering<Model> run(Database database, Relation<O> relation) {
- SimilarityQuery<O, IntegerDistance> snnInstance = similarityFunction.instantiate(relation);
+ SimilarityQuery<O> snnInstance = similarityFunction.instantiate(relation);
FiniteProgress objprog = LOG.isVerbose() ? new FiniteProgress("SNNClustering", relation.size(), LOG) : null;
IndefiniteProgress clusprog = LOG.isVerbose() ? new IndefiniteProgress("Number of clusters", LOG) : null;
@@ -155,9 +145,9 @@ public class SNNClustering<O> extends AbstractAlgorithm<Clustering<Model>> imple
noise = DBIDUtil.newHashSet();
processedIDs = DBIDUtil.newHashSet(relation.size());
if(relation.size() >= minpts) {
- for(DBIDIter id = snnInstance.getRelation().iterDBIDs(); id.valid(); id.advance()) {
+ for(DBIDIter id = relation.iterDBIDs(); id.valid(); id.advance()) {
if(!processedIDs.contains(id)) {
- expandCluster(snnInstance, DBIDUtil.deref(id), objprog, clusprog);
+ expandCluster(snnInstance, id, objprog, clusprog);
if(processedIDs.size() == relation.size() && noise.size() == 0) {
break;
}
@@ -169,7 +159,7 @@ public class SNNClustering<O> extends AbstractAlgorithm<Clustering<Model>> imple
}
}
else {
- for(DBIDIter id = snnInstance.getRelation().iterDBIDs(); id.valid(); id.advance()) {
+ for(DBIDIter id = relation.iterDBIDs(); id.valid(); id.advance()) {
noise.add(id);
if(objprog != null && clusprog != null) {
objprog.setProcessed(noise.size(), LOG);
@@ -178,10 +168,8 @@ public class SNNClustering<O> extends AbstractAlgorithm<Clustering<Model>> imple
}
}
// Finish progress logging
- if(objprog != null && clusprog != null) {
- objprog.ensureCompleted(LOG);
- clusprog.setCompleted(LOG);
- }
+ LOG.ensureCompleted(objprog);
+ LOG.setCompleted(clusprog);
Clustering<Model> result = new Clustering<>("Shared-Nearest-Neighbor Clustering", "snn-clustering");
for(Iterator<ModifiableDBIDs> resultListIter = resultList.iterator(); resultListIter.hasNext();) {
@@ -201,10 +189,10 @@ public class SNNClustering<O> extends AbstractAlgorithm<Clustering<Model>> imple
* @return the shared nearest neighbors of the specified query object in the
* given database
*/
- protected ArrayModifiableDBIDs findSNNNeighbors(SimilarityQuery<O, IntegerDistance> snnInstance, DBID queryObject) {
+ protected ArrayModifiableDBIDs findSNNNeighbors(SimilarityQuery<O> snnInstance, DBIDRef queryObject) {
ArrayModifiableDBIDs neighbors = DBIDUtil.newArray();
for(DBIDIter iditer = snnInstance.getRelation().iterDBIDs(); iditer.valid(); iditer.advance()) {
- if(snnInstance.similarity(queryObject, iditer).compareTo(epsilon) >= 0) {
+ if(snnInstance.similarity(queryObject, iditer) >= epsilon) {
neighbors.add(iditer);
}
}
@@ -222,7 +210,7 @@ public class SNNClustering<O> extends AbstractAlgorithm<Clustering<Model>> imple
* @param objprog the progress object to report about the progress of
* clustering
*/
- protected void expandCluster(SimilarityQuery<O, IntegerDistance> snnInstance, DBID startObjectID, FiniteProgress objprog, IndefiniteProgress clusprog) {
+ protected void expandCluster(SimilarityQuery<O> snnInstance, DBIDRef startObjectID, FiniteProgress objprog, IndefiniteProgress clusprog) {
ArrayModifiableDBIDs seeds = findSNNNeighbors(snnInstance, startObjectID);
// startObject is no core-object
@@ -310,7 +298,19 @@ public class SNNClustering<O> extends AbstractAlgorithm<Clustering<Model>> imple
* @param <O> object type
*/
public static class Parameterizer<O> extends AbstractParameterizer {
- protected IntegerDistance epsilon;
+ /**
+ * Parameter to specify the minimum SNN density, must be an integer greater
+ * than 0.
+ */
+ public static final OptionID EPSILON_ID = new OptionID("snn.epsilon", "The minimum SNN density.");
+
+ /**
+ * Parameter to specify the threshold for minimum number of points in the
+ * epsilon-SNN-neighborhood of a point, must be an integer greater than 0.
+ */
+ public static final OptionID MINPTS_ID = new OptionID("snn.minpts", "Threshold for minimum number of points in " + "the epsilon-SNN-neighborhood of a point.");
+
+ protected int epsilon;
protected int minpts;
@@ -322,7 +322,7 @@ public class SNNClustering<O> extends AbstractAlgorithm<Clustering<Model>> imple
Class<SharedNearestNeighborSimilarityFunction<O>> cls = ClassGenericsUtil.uglyCastIntoSubclass(SharedNearestNeighborSimilarityFunction.class);
similarityFunction = config.tryInstantiate(cls);
- DistanceParameter<IntegerDistance> epsilonP = new DistanceParameter<>(EPSILON_ID, IntegerDistance.FACTORY);
+ IntParameter epsilonP = new IntParameter(EPSILON_ID);
if(config.grab(epsilonP)) {
epsilon = epsilonP.getValue();
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/AffinityPropagationClusteringAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/AffinityPropagationClusteringAlgorithm.java
index 68dacf34..dcc23273 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/AffinityPropagationClusteringAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/AffinityPropagationClusteringAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.affinitypropagation;
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
@@ -195,9 +195,7 @@ public class AffinityPropagationClusteringAlgorithm<O> extends AbstractAlgorithm
}
}
inactive = (changed > 0) ? 0 : (inactive + 1);
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
if(aprog != null) {
aprog.setProcessed(size - changed, LOG);
}
@@ -205,9 +203,7 @@ public class AffinityPropagationClusteringAlgorithm<O> extends AbstractAlgorithm
if(aprog != null) {
aprog.setProcessed(aprog.getTotal(), LOG);
}
- if(prog != null) {
- prog.setCompleted(LOG);
- }
+ LOG.setCompleted(prog);
// Cluster map, by lead object
TIntObjectHashMap<ModifiableDBIDs> map = new TIntObjectHashMap<>();
DBIDArrayIter i1 = ids.iter();
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/AffinityPropagationInitialization.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/AffinityPropagationInitialization.java
index 5dbc54de..9a5877ea 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/AffinityPropagationInitialization.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/AffinityPropagationInitialization.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.affinitypropagation;
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,14 +27,13 @@ import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Initialization methods for affinity propagation.
*
* @author Erich Schubert
*/
-public interface AffinityPropagationInitialization<O> extends Parameterizable {
+public interface AffinityPropagationInitialization<O> {
/**
* Quantile to use for the diagonal entries.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/DistanceBasedInitializationWithMedian.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/DistanceBasedInitializationWithMedian.java
index 2c8cabf9..aadadefb 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/DistanceBasedInitializationWithMedian.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/DistanceBasedInitializationWithMedian.java
@@ -1,9 +1,10 @@
package de.lmu.ifi.dbs.elki.algorithm.clustering.affinitypropagation;
+
/*
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,7 +31,6 @@ 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.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.utilities.datastructures.QuickSelect;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -44,13 +44,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class DistanceBasedInitializationWithMedian<O, D extends NumberDistance<D, ?>> implements AffinityPropagationInitialization<O> {
+public class DistanceBasedInitializationWithMedian<O> implements AffinityPropagationInitialization<O> {
/**
* Distance function.
*/
- DistanceFunction<? super O, D> distance;
+ DistanceFunction<? super O> distance;
/**
* Quantile to use.
@@ -63,7 +62,7 @@ public class DistanceBasedInitializationWithMedian<O, D extends NumberDistance<D
* @param distance Similarity function
* @param quantile Quantile
*/
- public DistanceBasedInitializationWithMedian(DistanceFunction<? super O, D> distance, double quantile) {
+ public DistanceBasedInitializationWithMedian(DistanceFunction<? super O> distance, double quantile) {
super();
this.distance = distance;
this.quantile = quantile;
@@ -72,16 +71,16 @@ public class DistanceBasedInitializationWithMedian<O, D extends NumberDistance<D
@Override
public double[][] getSimilarityMatrix(Database db, Relation<O> relation, ArrayDBIDs ids) {
final int size = ids.size();
- DistanceQuery<O, D> dq = db.getDistanceQuery(relation, distance);
+ DistanceQuery<O> dq = db.getDistanceQuery(relation, distance);
double[][] mat = new double[size][size];
double[] flat = new double[(size * (size - 1)) >> 1];
// TODO: optimize for double valued primitive distances.
DBIDArrayIter i1 = ids.iter(), i2 = ids.iter();
- for (int i = 0, j = 0; i < size; i++, i1.advance()) {
+ for(int i = 0, j = 0; i < size; i++, i1.advance()) {
double[] mati = mat[i];
i2.seek(i + 1);
- for (int k = i + 1; k < size; k++, i2.advance()) {
- mati[k] = -dq.distance(i1, i2).doubleValue();
+ for(int k = i + 1; k < size; k++, i2.advance()) {
+ mati[k] = -dq.distance(i1, i2);
mat[k][i] = mati[k]; // symmetry.
flat[j] = mati[k];
j++;
@@ -89,7 +88,7 @@ public class DistanceBasedInitializationWithMedian<O, D extends NumberDistance<D
}
double median = QuickSelect.quantile(flat, quantile);
// On the diagonal, we place the median
- for (int i = 0; i < size; i++) {
+ for(int i = 0; i < size; i++) {
mat[i][i] = median;
}
return mat;
@@ -108,9 +107,8 @@ public class DistanceBasedInitializationWithMedian<O, D extends NumberDistance<D
* @apiviz.exclude
*
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractParameterizer {
+ public static class Parameterizer<O> extends AbstractParameterizer {
/**
* Parameter for the distance function.
*/
@@ -119,7 +117,7 @@ public class DistanceBasedInitializationWithMedian<O, D extends NumberDistance<D
/**
* istance function.
*/
- DistanceFunction<? super O, D> distance;
+ DistanceFunction<? super O> distance;
/**
* Quantile to use.
@@ -129,19 +127,19 @@ public class DistanceBasedInitializationWithMedian<O, D extends NumberDistance<D
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- ObjectParameter<DistanceFunction<? super O, D>> param = new ObjectParameter<>(DISTANCE_ID, DistanceFunction.class, SquaredEuclideanDistanceFunction.class);
- if (config.grab(param)) {
+ ObjectParameter<DistanceFunction<? super O>> param = new ObjectParameter<>(DISTANCE_ID, DistanceFunction.class, SquaredEuclideanDistanceFunction.class);
+ if(config.grab(param)) {
distance = param.instantiateClass(config);
}
DoubleParameter quantileP = new DoubleParameter(QUANTILE_ID, .5);
- if (config.grab(quantileP)) {
+ if(config.grab(quantileP)) {
quantile = quantileP.doubleValue();
}
}
@Override
- protected DistanceBasedInitializationWithMedian<O, D> makeInstance() {
+ protected DistanceBasedInitializationWithMedian<O> makeInstance() {
return new DistanceBasedInitializationWithMedian<>(distance, quantile);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/SimilarityBasedInitializationWithMedian.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/SimilarityBasedInitializationWithMedian.java
index a138da96..71bd6126 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/SimilarityBasedInitializationWithMedian.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/SimilarityBasedInitializationWithMedian.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.affinitypropagation;
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.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
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.SimilarityFunction;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.LinearKernelFunction;
import de.lmu.ifi.dbs.elki.utilities.datastructures.QuickSelect;
@@ -44,13 +43,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class SimilarityBasedInitializationWithMedian<O, D extends NumberDistance<D, ?>> implements AffinityPropagationInitialization<O> {
+public class SimilarityBasedInitializationWithMedian<O> implements AffinityPropagationInitialization<O> {
/**
* Similarity function.
*/
- SimilarityFunction<? super O, D> similarity;
+ SimilarityFunction<? super O> similarity;
/**
* Quantile to use.
@@ -63,7 +61,7 @@ public class SimilarityBasedInitializationWithMedian<O, D extends NumberDistance
* @param similarity Similarity function
* @param quantile Quantile
*/
- public SimilarityBasedInitializationWithMedian(SimilarityFunction<? super O, D> similarity, double quantile) {
+ public SimilarityBasedInitializationWithMedian(SimilarityFunction<? super O> similarity, double quantile) {
super();
this.similarity = similarity;
this.quantile = quantile;
@@ -72,21 +70,21 @@ public class SimilarityBasedInitializationWithMedian<O, D extends NumberDistance
@Override
public double[][] getSimilarityMatrix(Database db, Relation<O> relation, ArrayDBIDs ids) {
final int size = ids.size();
- SimilarityQuery<O, D> sq = db.getSimilarityQuery(relation, similarity);
+ SimilarityQuery<O> sq = db.getSimilarityQuery(relation, similarity);
double[][] mat = new double[size][size];
double[] flat = new double[(size * (size - 1)) >> 1];
// TODO: optimize for double valued primitive distances.
DBIDArrayIter i1 = ids.iter(), i2 = ids.iter();
// Compute self-similarities first, for centering:
for (int i = 0; i < size; i++, i1.advance()) {
- mat[i][i] = sq.similarity(i1, i1).doubleValue() * .5;
+ mat[i][i] = sq.similarity(i1, i1) * .5;
}
i1.seek(0);
for (int i = 0, j = 0; i < size; i++, i1.advance()) {
final double[] mati = mat[i]; // Probably faster access.
i2.seek(i + 1);
for (int k = i + 1; k < size; k++, i2.advance()) {
- mati[k] = sq.similarity(i1, i2).doubleValue() - mati[i] - mat[k][k];
+ mati[k] = sq.similarity(i1, i2) - mati[i] - mat[k][k];
mat[k][i] = mati[k]; // symmetry.
flat[j] = mati[k];
j++;
@@ -113,9 +111,8 @@ public class SimilarityBasedInitializationWithMedian<O, D extends NumberDistance
* @apiviz.exclude
*
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractParameterizer {
+ public static class Parameterizer<O> extends AbstractParameterizer {
/**
* Parameter for the similarity function.
*/
@@ -124,7 +121,7 @@ public class SimilarityBasedInitializationWithMedian<O, D extends NumberDistance
/**
* Similarity function.
*/
- SimilarityFunction<? super O, D> similarity;
+ SimilarityFunction<? super O> similarity;
/**
* Quantile to use.
@@ -134,7 +131,7 @@ public class SimilarityBasedInitializationWithMedian<O, D extends NumberDistance
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- ObjectParameter<SimilarityFunction<? super O, D>> param = new ObjectParameter<>(SIMILARITY_ID, SimilarityFunction.class, LinearKernelFunction.class);
+ ObjectParameter<SimilarityFunction<? super O>> param = new ObjectParameter<>(SIMILARITY_ID, SimilarityFunction.class, LinearKernelFunction.class);
if (config.grab(param)) {
similarity = param.instantiateClass(config);
}
@@ -146,7 +143,7 @@ public class SimilarityBasedInitializationWithMedian<O, D extends NumberDistance
}
@Override
- protected SimilarityBasedInitializationWithMedian<O, D> makeInstance() {
+ protected SimilarityBasedInitializationWithMedian<O> makeInstance() {
return new SimilarityBasedInitializationWithMedian<>(similarity, quantile);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/package-info.java
index bc6059ac..46393d96 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/affinitypropagation/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/algorithm/clustering/biclustering/AbstractBiclustering.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/biclustering/AbstractBiclustering.java
index 8b875340..f57a66e3 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/biclustering/AbstractBiclustering.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/biclustering/AbstractBiclustering.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.biclustering;
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
@@ -58,7 +58,7 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
* columns relate to the attribute values of these objects
* @param <M> Cluster model type
*/
-public abstract class AbstractBiclustering<V extends NumberVector<?>, M extends BiclusterModel> extends AbstractAlgorithm<Clustering<M>> implements ClusteringAlgorithm<Clustering<M>> {
+public abstract class AbstractBiclustering<V extends NumberVector, M extends BiclusterModel> extends AbstractAlgorithm<Clustering<M>> implements ClusteringAlgorithm<Clustering<M>> {
/**
* Keeps the currently set database.
*/
@@ -218,7 +218,7 @@ public abstract class AbstractBiclustering<V extends NumberVector<?>, M extends
* @return integer column ids
*/
protected int[] colsBitsetToIDs(long[] cols) {
- int[] colIDs = new int[(int) BitsUtil.cardinality(cols)];
+ int[] colIDs = new int[BitsUtil.cardinality(cols)];
int colsIndex = 0;
for (int cpos = 0, clpos = 0; clpos < cols.length; ++clpos) {
long clong = cols[clpos];
@@ -243,7 +243,7 @@ public abstract class AbstractBiclustering<V extends NumberVector<?>, M extends
* @return integer row ids
*/
protected ArrayDBIDs rowsBitsetToIDs(long[] rows) {
- ArrayModifiableDBIDs rowIDs = DBIDUtil.newArray((int) BitsUtil.cardinality(rows));
+ ArrayModifiableDBIDs rowIDs = DBIDUtil.newArray(BitsUtil.cardinality(rows));
DBIDArrayIter iter = this.rowIDs.iter();
outer: for (int rlpos = 0; rlpos < rows.length; ++rlpos) {
long rlong = rows[rlpos];
@@ -265,7 +265,7 @@ public abstract class AbstractBiclustering<V extends NumberVector<?>, M extends
}
/**
- * Provides the number of rows of the data matrix.
+ * The number of rows of the data matrix.
*
* @return the number of rows of the data matrix
*/
@@ -274,7 +274,7 @@ public abstract class AbstractBiclustering<V extends NumberVector<?>, M extends
}
/**
- * Provides the number of columns of the data matrix.
+ * The number of columns of the data matrix.
*
* @return the number of columns of the data matrix
*/
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/biclustering/ChengAndChurch.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/biclustering/ChengAndChurch.java
index e110faff..57511b3e 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/biclustering/ChengAndChurch.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/biclustering/ChengAndChurch.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.biclustering;
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
@@ -64,7 +64,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @param <V> Vector type.
*/
@Reference(authors = "Y. Cheng, G. M. Church", title = "Biclustering of expression data", booktitle = "Proc. 8th International Conference on Intelligent Systems for Molecular Biology (ISMB)")
-public class ChengAndChurch<V extends NumberVector<?>> extends AbstractBiclustering<V, BiclusterWithInversionsModel> {
+public class ChengAndChurch<V extends NumberVector> extends AbstractBiclustering<V, BiclusterWithInversionsModel> {
/**
* The logger for this class.
*/
@@ -555,9 +555,7 @@ public class ChengAndChurch<V extends NumberVector<?>> extends AbstractBicluster
// LOG.verbose("Total number of masked values: " + maskedVals.size() +
// "\n");
}
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
}
// Add a noise cluster, full-dimensional.
if(!noise.isEmpty()) {
@@ -565,9 +563,7 @@ public class ChengAndChurch<V extends NumberVector<?>> extends AbstractBicluster
BiclusterWithInversionsModel model = new BiclusterWithInversionsModel(colsBitsetToIDs(allcols), DBIDUtil.EMPTYDBIDS);
result.addToplevelCluster(new Cluster<>(noise, true, model));
}
- if(prog != null) {
- prog.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(prog);
return result;
}
@@ -805,7 +801,7 @@ public class ChengAndChurch<V extends NumberVector<?>> extends AbstractBicluster
*
* @param <V> Vector type
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* Parameter to specify the distribution of replacement values when masking
* a cluster.
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/biclustering/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/biclustering/package-info.java
index 21363bfc..ed3c8c64 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/biclustering/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/biclustering/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/algorithm/clustering/correlation/CASH.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/CASH.java
index 8e5fa627..adef67ff 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/CASH.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/CASH.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.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
@@ -57,8 +57,7 @@ import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.datasource.filter.normalization.NonNumericFeaturesException;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.WeightedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.MatrixWeightedDistanceFunction;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.linearalgebra.LinearEquationSystem;
@@ -82,19 +81,20 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
/**
- * Provides the CASH algorithm, an subspace clustering algorithm based on the
- * Hough transform.
+ * The CASH algorithm is a subspace clustering algorithm based on the Hough
+ * transform.
*
+ * Reference:
* <p>
- * Reference: E. Achtert, C. Böhm, J. David, P. Kröger, A. Zimek: Robust
- * clustering in arbitrarily oriented subspaces. <br>
+ * E. Achtert, C. Böhm, J. David, P. Kröger, A. Zimek:<br />
+ * Robust clustering in arbitrarily oriented subspaces. <br>
* In Proc. 8th SIAM Int. Conf. on Data Mining (SDM'08), Atlanta, GA, 2008
* </p>
*
* @author Elke Achtert
*
* @apiviz.has CASHInterval
- * @apiviz.uses ParameterizationFunction
+ * @apiviz.has ParameterizationFunction
* @apiviz.has LinearEquationModel
*
* @param <V> Vector type
@@ -102,8 +102,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
// todo elke hierarchy (later)
@Title("CASH: Robust clustering in arbitrarily oriented subspaces")
@Description("Subspace clustering algorithm based on the Hough transform.")
-@Reference(authors = "E. Achtert, C. Böhm, J. David, P. Kröger, A. Zimek", title = "Robust clustering in arbitraily oriented subspaces", booktitle = "Proc. 8th SIAM Int. Conf. on Data Mining (SDM'08), Atlanta, GA, 2008", url = "http://www.siam.org/proceedings/datamining/2008/dm08_69_AchtertBoehmDavidKroegerZimek.pdf")
-public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<Model>> implements ClusteringAlgorithm<Clustering<Model>> {
+@Reference(authors = "E. Achtert, C. Böhm, J. David, P. Kröger, A. Zimek", //
+title = "Robust clustering in arbitraily oriented subspaces",//
+booktitle = "Proc. 8th SIAM Int. Conf. on Data Mining (SDM'08), Atlanta, GA, 2008",//
+url = "http://www.siam.org/proceedings/datamining/2008/dm08_69_AchtertBoehmDavidKroegerZimek.pdf")
+public class CASH<V extends NumberVector> extends AbstractAlgorithm<Clustering<Model>> implements ClusteringAlgorithm<Clustering<Model>> {
/**
* The logger for this class.
*/
@@ -224,7 +227,7 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
*/
public Clustering<Model> run(Database database, Relation<V> vrel) {
this.fulldatabase = preprocess(database, vrel);
- if (LOG.isVerbose()) {
+ if(LOG.isVerbose()) {
StringBuilder msg = new StringBuilder();
msg.append("DB size: ").append(fulldatabase.size());
msg.append("\nmin Dim: ").append(minDim);
@@ -236,17 +239,16 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("CASH Clustering", fulldatabase.size(), LOG) : null;
Clustering<Model> result = doRun(fulldatabase, progress);
- if (progress != null) {
- progress.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(progress);
- if (LOG.isVerbose()) {
+ if(LOG.isVerbose()) {
StringBuilder msg = new StringBuilder();
- for (Cluster<Model> c : result.getAllClusters()) {
- if (c.getModel() instanceof LinearEquationModel) {
+ for(Cluster<Model> c : result.getAllClusters()) {
+ if(c.getModel() instanceof LinearEquationModel) {
LinearEquationModel s = (LinearEquationModel) c.getModel();
msg.append("\n Cluster: Dim: " + s.getLes().subspacedim() + " size: " + c.size());
- } else {
+ }
+ else {
msg.append("\n Cluster: " + c.getModel().getClass().getName() + " size: " + c.size());
}
}
@@ -268,7 +270,7 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
MaterializedRelation<ParameterizationFunction> prep = new MaterializedRelation<>(db, type, ids);
// Project
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
ParameterizationFunction f = new ParameterizationFunction(vrel.get(iter));
prep.set(iter, f);
}
@@ -294,51 +296,54 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
ModifiableDBIDs noiseIDs = DBIDUtil.newHashSet(relation.getDBIDs());
initHeap(heap, relation, dim, noiseIDs);
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
StringBuilder msg = new StringBuilder();
msg.append("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
msg.append("\nXXXX dim ").append(dim);
msg.append("\nXXXX database.size ").append(relation.size());
msg.append("\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
LOG.debugFine(msg.toString());
- } else if (LOG.isVerbose()) {
+ }
+ else if(LOG.isVerbose()) {
StringBuilder msg = new StringBuilder();
msg.append("XXXX dim ").append(dim).append(" database.size ").append(relation.size());
LOG.verbose(msg.toString());
}
// get the ''best'' d-dimensional intervals at max level
- while (!heap.isEmpty()) {
+ while(!heap.isEmpty()) {
CASHInterval interval = determineNextIntervalAtMaxLevel(heap);
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
LOG.debugFine("next interval in dim " + dim + ": " + interval);
- } else if (LOG.isVerbose()) {
+ }
+ else if(LOG.isVerbose()) {
LOG.verbose("next interval in dim " + dim + ": " + interval);
}
// only noise left
- if (interval == null) {
+ if(interval == null) {
break;
}
// do a dim-1 dimensional run
ModifiableDBIDs clusterIDs = DBIDUtil.newHashSet();
- if (dim > minDim + 1) {
+ if(dim > minDim + 1) {
ModifiableDBIDs ids;
Matrix basis_dim_minus_1;
- if (adjust) {
+ if(adjust) {
ids = DBIDUtil.newHashSet();
basis_dim_minus_1 = runDerivator(relation, dim, interval, ids);
- } else {
+ }
+ else {
ids = interval.getIDs();
basis_dim_minus_1 = determineBasis(SpatialUtil.centroid(interval));
}
- if (ids.size() != 0) {
+ if(ids.size() != 0) {
MaterializedRelation<ParameterizationFunction> db = buildDB(dim, basis_dim_minus_1, ids, relation);
// add result of dim-1 to this result
Clustering<Model> res_dim_minus_1 = doRun(db, progress);
- for (Cluster<Model> cluster : res_dim_minus_1.getAllClusters()) {
+ for(Cluster<Model> cluster : res_dim_minus_1.getAllClusters()) {
res.addToplevelCluster(cluster);
noiseIDs.removeDBIDs(cluster.getIDs());
clusterIDs.addDBIDs(cluster.getIDs());
@@ -358,30 +363,31 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
// Rebuild heap
ArrayList<IntegerPriorityObject<CASHInterval>> heapVector = new ArrayList<>(heap.size());
- for (ObjectHeap.UnsortedIter<IntegerPriorityObject<CASHInterval>> iter = heap.unsortedIter(); iter.valid(); iter.advance()) {
+ for(ObjectHeap.UnsortedIter<IntegerPriorityObject<CASHInterval>> iter = heap.unsortedIter(); iter.valid(); iter.advance()) {
heapVector.add(iter.get());
}
heap.clear();
- for (IntegerPriorityObject<CASHInterval> pair : heapVector) {
+ for(IntegerPriorityObject<CASHInterval> pair : heapVector) {
CASHInterval currentInterval = pair.getObject();
currentInterval.removeIDs(clusterIDs);
- if (currentInterval.getIDs().size() >= minPts) {
+ if(currentInterval.getIDs().size() >= minPts) {
heap.add(new IntegerPriorityObject<>(currentInterval.priority(), currentInterval));
}
}
- if (progress != null) {
+ if(progress != null) {
progress.setProcessed(processedIDs.size(), LOG);
}
}
// put noise to clusters
- if (!noiseIDs.isEmpty()) {
- if (dim == noiseDim) {
+ if(!noiseIDs.isEmpty()) {
+ if(dim == noiseDim) {
Cluster<Model> c = new Cluster<Model>(noiseIDs, true, ClusterModel.CLUSTER);
res.addToplevelCluster(c);
processedIDs.addDBIDs(noiseIDs);
- } else if (noiseIDs.size() >= minPts) {
+ }
+ else if(noiseIDs.size() >= minPts) {
LinearEquationSystem les = runDerivator(fulldatabase, dim - 1, noiseIDs);
Cluster<Model> c = new Cluster<Model>(noiseIDs, true, new LinearEquationModel(les));
res.addToplevelCluster(c);
@@ -389,22 +395,23 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
}
}
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
StringBuilder msg = new StringBuilder();
msg.append("noise fuer dim ").append(dim).append(": ").append(noiseIDs.size());
- for (Cluster<Model> c : res.getAllClusters()) {
- if (c.getModel() instanceof LinearEquationModel) {
+ for(Cluster<Model> c : res.getAllClusters()) {
+ if(c.getModel() instanceof LinearEquationModel) {
LinearEquationModel s = (LinearEquationModel) c.getModel();
msg.append("\n Cluster: Dim: " + s.getLes().subspacedim() + " size: " + c.size());
- } else {
+ }
+ else {
msg.append("\n Cluster: " + c.getModel().getClass().getName() + " size: " + c.size());
}
}
LOG.debugFine(msg.toString());
}
- if (progress != null) {
+ if(progress != null) {
progress.setProcessed(processedIDs.size(), LOG);
}
return res;
@@ -442,14 +449,15 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
double[] d_mins = new double[numDIntervals];
double[] d_maxs = new double[numDIntervals];
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
StringBuilder msg = new StringBuilder();
msg.append("d_min ").append(d_min);
msg.append("\nd_max ").append(d_max);
msg.append("\nnumDIntervals ").append(numDIntervals);
msg.append("\ndIntervalSize ").append(dIntervalSize);
LOG.debugFine(msg.toString());
- } else if (LOG.isVerbose()) {
+ }
+ else if(LOG.isVerbose()) {
StringBuilder msg = new StringBuilder();
msg.append("d_min ").append(d_min);
msg.append("\nd_max ").append(d_max);
@@ -463,28 +471,30 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
double[] alphaMax = new double[dim - 1];
Arrays.fill(alphaMax, Math.PI);
- for (int i = 0; i < numDIntervals; i++) {
- if (i == 0) {
+ for(int i = 0; i < numDIntervals; i++) {
+ if(i == 0) {
d_mins[i] = d_min;
- } else {
+ }
+ else {
d_mins[i] = d_maxs[i - 1];
}
- if (i < numDIntervals - 1) {
+ if(i < numDIntervals - 1) {
d_maxs[i] = d_mins[i] + dIntervalSize;
- } else {
+ }
+ else {
d_maxs[i] = d_max - d_mins[i];
}
HyperBoundingBox alphaInterval = new HyperBoundingBox(alphaMin, alphaMax);
ModifiableDBIDs intervalIDs = split.determineIDs(ids, alphaInterval, d_mins[i], d_maxs[i]);
- if (intervalIDs != null && intervalIDs.size() >= minPts) {
+ if(intervalIDs != null && intervalIDs.size() >= minPts) {
CASHInterval rootInterval = new CASHInterval(alphaMin, alphaMax, split, intervalIDs, -1, 0, d_mins[i], d_maxs[i]);
heap.add(new IntegerPriorityObject<>(rootInterval.priority(), rootInterval));
}
}
- if (LOG.isDebuggingFiner()) {
+ if(LOG.isDebuggingFiner()) {
StringBuilder msg = new StringBuilder();
msg.append("heap.size ").append(heap.size());
LOG.debugFiner(msg.toString());
@@ -509,12 +519,12 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
proxy.addRelation(prep);
// Project
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
ParameterizationFunction f = project(basis, relation.get(iter));
prep.set(iter, f);
}
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
LOG.debugFine("db fuer dim " + (dim - 1) + ": " + ids.size());
}
@@ -546,7 +556,7 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
*/
private Matrix determineBasis(double[] alpha) {
double[] nn = new double[alpha.length + 1];
- for (int i = 0; i < nn.length; i++) {
+ for(int i = 0; i < nn.length; i++) {
double alpha_i = i == alpha.length ? 0 : alpha[i];
nn[i] = sinusProduct(0, i, alpha) * StrictMath.cos(alpha_i);
}
@@ -566,7 +576,7 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
*/
private double sinusProduct(int start, int end, double[] alpha) {
double result = 1;
- for (int j = start; j < end; j++) {
+ for(int j = start; j < end; j++) {
result *= Math.sin(alpha[j]);
}
return result;
@@ -582,8 +592,8 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
private CASHInterval determineNextIntervalAtMaxLevel(ObjectHeap<IntegerPriorityObject<CASHInterval>> heap) {
CASHInterval next = doDetermineNextIntervalAtMaxLevel(heap);
// noise path was chosen
- while (next == null) {
- if (heap.isEmpty()) {
+ while(next == null) {
+ if(heap.isEmpty()) {
return null;
}
next = doDetermineNextIntervalAtMaxLevel(heap);
@@ -602,45 +612,48 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
private CASHInterval doDetermineNextIntervalAtMaxLevel(ObjectHeap<IntegerPriorityObject<CASHInterval>> heap) {
CASHInterval interval = heap.poll().getObject();
int dim = interval.getDimensionality();
- while (true) {
+ while(true) {
// max level is reached
- if (interval.getLevel() >= maxLevel && interval.getMaxSplitDimension() == (dim - 1)) {
+ if(interval.getLevel() >= maxLevel && interval.getMaxSplitDimension() == (dim - 1)) {
return interval;
}
- if (heap.size() % 10000 == 0 && LOG.isVerbose()) {
+ if(heap.size() % 10000 == 0 && LOG.isVerbose()) {
LOG.verbose("heap size " + heap.size());
}
- if (heap.size() >= 40000) {
+ if(heap.size() >= 40000) {
LOG.warning("Heap size > 40.000!!!");
heap.clear();
return null;
}
- if (LOG.isDebuggingFiner()) {
+ if(LOG.isDebuggingFiner()) {
LOG.debugFiner("split " + interval.toString() + " " + interval.getLevel() + "-" + interval.getMaxSplitDimension());
}
interval.split();
// noise
- if (!interval.hasChildren()) {
+ if(!interval.hasChildren()) {
return null;
}
CASHInterval bestInterval;
- if (interval.getLeftChild() != null && interval.getRightChild() != null) {
+ if(interval.getLeftChild() != null && interval.getRightChild() != null) {
int comp = interval.getLeftChild().compareTo(interval.getRightChild());
- if (comp < 0) {
+ if(comp < 0) {
bestInterval = interval.getRightChild();
heap.add(new IntegerPriorityObject<>(interval.getLeftChild().priority(), interval.getLeftChild()));
- } else {
+ }
+ else {
bestInterval = interval.getLeftChild();
heap.add(new IntegerPriorityObject<>(interval.getRightChild().priority(), interval.getRightChild()));
}
- } else if (interval.getLeftChild() == null) {
+ }
+ else if(interval.getLeftChild() == null) {
bestInterval = interval.getRightChild();
- } else {
+ }
+ else {
bestInterval = interval.getLeftChild();
}
@@ -665,7 +678,7 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
double d_min = Double.POSITIVE_INFINITY;
double d_max = Double.NEGATIVE_INFINITY;
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
ParameterizationFunction f = relation.get(iditer);
HyperBoundingBox minMax = f.determineAlphaMinMax(box);
double f_min = f.function(SpatialUtil.getMin(minMax));
@@ -694,25 +707,25 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
// set the parameters
ListParameterization parameters = new ListParameterization();
- parameters.addParameter(PCAFilteredRunner.PCA_EIGENPAIR_FILTER, FirstNEigenPairFilter.class.getName());
+ parameters.addParameter(PCAFilteredRunner.Parameterizer.PCA_EIGENPAIR_FILTER, FirstNEigenPairFilter.class.getName());
parameters.addParameter(FirstNEigenPairFilter.EIGENPAIR_FILTER_N, Integer.toString(dim - 1));
- DependencyDerivator<DoubleVector, DoubleDistance> derivator = null;
- Class<DependencyDerivator<DoubleVector, DoubleDistance>> cls = ClassGenericsUtil.uglyCastIntoSubclass(DependencyDerivator.class);
+ DependencyDerivator<DoubleVector> derivator = null;
+ Class<DependencyDerivator<DoubleVector>> cls = ClassGenericsUtil.uglyCastIntoSubclass(DependencyDerivator.class);
derivator = parameters.tryInstantiate(cls);
CorrelationAnalysisSolution<DoubleVector> model = derivator.run(derivatorDB);
Matrix weightMatrix = model.getSimilarityMatrix();
DoubleVector centroid = new DoubleVector(model.getCentroid());
- DistanceQuery<DoubleVector, DoubleDistance> df = QueryUtil.getDistanceQuery(derivatorDB, new WeightedDistanceFunction(weightMatrix));
- DoubleDistance eps = new DoubleDistance(0.25);
+ DistanceQuery<DoubleVector> df = QueryUtil.getDistanceQuery(derivatorDB, new MatrixWeightedDistanceFunction(weightMatrix));
+ double eps = .25;
ids.addDBIDs(interval.getIDs());
// Search for nearby vectors in original database
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- DoubleVector v = new DoubleVector(relation.get(iditer).getColumnVector().getArrayRef());
- DoubleDistance d = df.distance(v, centroid);
- if (d.compareTo(eps) < 0) {
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ DoubleVector v = new DoubleVector(relation.get(iditer).getColumnVector());
+ double d = df.distance(v, centroid);
+ if(d <= eps) {
ids.add(iditer);
}
}
@@ -739,12 +752,12 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
proxy.addRelation(prep);
// Project
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
DoubleVector v = new DoubleVector(relation.get(iter).getColumnVector().getArrayRef());
prep.set(iter, v);
}
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
LOG.debugFine("db fuer derivator : " + prep.size());
}
@@ -767,16 +780,17 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
Database derivatorDB = buildDerivatorDB(relation, ids);
ListParameterization parameters = new ListParameterization();
- parameters.addParameter(PCAFilteredRunner.PCA_EIGENPAIR_FILTER, FirstNEigenPairFilter.class.getName());
+ parameters.addParameter(PCAFilteredRunner.Parameterizer.PCA_EIGENPAIR_FILTER, FirstNEigenPairFilter.class.getName());
parameters.addParameter(FirstNEigenPairFilter.EIGENPAIR_FILTER_N, Integer.toString(dimensionality));
- DependencyDerivator<DoubleVector, DoubleDistance> derivator = null;
- Class<DependencyDerivator<DoubleVector, DoubleDistance>> cls = ClassGenericsUtil.uglyCastIntoSubclass(DependencyDerivator.class);
+ DependencyDerivator<DoubleVector> derivator = null;
+ Class<DependencyDerivator<DoubleVector>> cls = ClassGenericsUtil.uglyCastIntoSubclass(DependencyDerivator.class);
derivator = parameters.tryInstantiate(cls);
CorrelationAnalysisSolution<DoubleVector> model = derivator.run(derivatorDB);
LinearEquationSystem les = model.getNormalizedLinearEquationSystem(null);
return les;
- } catch (NonNumericFeaturesException e) {
+ }
+ catch(NonNumericFeaturesException e) {
throw new IllegalStateException("Error during normalization" + e);
}
}
@@ -798,7 +812,7 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
proxy.addRelation(prep);
// Project
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
DoubleVector v = new DoubleVector(relation.get(iter).getColumnVector().getArrayRef());
prep.set(iter, v);
}
@@ -839,32 +853,32 @@ public class CASH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
super.makeOptions(config);
IntParameter minptsP = new IntParameter(MINPTS_ID);
minptsP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
- if (config.grab(minptsP)) {
+ if(config.grab(minptsP)) {
minpts = minptsP.getValue();
}
IntParameter maxlevelP = new IntParameter(MAXLEVEL_ID);
maxlevelP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
- if (config.grab(maxlevelP)) {
+ if(config.grab(maxlevelP)) {
maxlevel = maxlevelP.getValue();
}
IntParameter mindimP = new IntParameter(MINDIM_ID, 1);
mindimP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
- if (config.grab(mindimP)) {
+ if(config.grab(mindimP)) {
mindim = mindimP.getValue();
}
DoubleParameter jitterP = new DoubleParameter(JITTER_ID);
jitterP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
- if (config.grab(jitterP)) {
+ if(config.grab(jitterP)) {
jitter = jitterP.getValue();
}
Flag adjustF = new Flag(ADJUST_ID);
- if (config.grab(adjustF)) {
+ if(config.grab(adjustF)) {
adjust = adjustF.getValue();
}
}
@Override
- protected CASH<NumberVector<?>> makeInstance() {
+ protected CASH<NumberVector> makeInstance() {
return new CASH<>(minpts, maxlevel, mindim, jitter, adjust);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/COPAC.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/COPAC.java
index 68878aef..8075a9f7 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/COPAC.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/COPAC.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.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
@@ -23,270 +23,109 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.correlation;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
-import de.lmu.ifi.dbs.elki.algorithm.DistanceBasedAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.COPACNeighborPredicate;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.CorePredicate;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.GeneralizedDBSCAN;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.MinPtsCorePredicate;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.model.ClusterModel;
import de.lmu.ifi.dbs.elki.data.model.DimensionModel;
import de.lmu.ifi.dbs.elki.data.model.Model;
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.ProxyDatabase;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-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.database.relation.RelationUtil;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.FilteredLocalPCABasedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.IndexBasedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.ProxyDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.LocalProjectionIndex;
-import de.lmu.ifi.dbs.elki.index.preprocessed.LocalProjectionIndex.Factory;
import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredRunner;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy;
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;
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.constraints.CommonConstraints;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
/**
- * Provides the COPAC algorithm, an algorithm to partition a database according
- * to the correlation dimension of its objects and to then perform an arbitrary
- * clustering algorithm over the partitions.
+ * COPAC is an algorithm to partition a database according to the correlation
+ * dimension of its objects and to then perform an arbitrary clustering
+ * algorithm over the partitions.
+ *
+ * Reference:
* <p>
- * Reference: Achtert E., Böhm C., Kriegel H.-P., Kröger P., Zimek A.: Robust,
- * Complete, and Efficient Correlation Clustering. <br>
+ * E. Achtert, C. Böhm, H.-P. Kriegel, P. Kröger, A. Zimek:<br />
+ * Robust, Complete, and Efficient Correlation Clustering.<br />
* In Proc. 7th SIAM International Conference on Data Mining (SDM'07),
* Minneapolis, MN, 2007
* </p>
*
* @author Arthur Zimek
*
- * @apiviz.uses LocalProjectionIndex
- * @apiviz.uses FilteredLocalPCABasedDistanceFunction
* @apiviz.has DimensionModel
+ * @apiviz.composedOf COPACNeighborPredicate
*
* @param <V> the type of NumberVector handled by this Algorithm
*/
@Title("COPAC: COrrelation PArtition Clustering")
-@Description("Partitions a database according to the correlation dimension of its objects and performs " + "a clustering algorithm over the partitions.")
-@Reference(authors = "E. Achtert, C. Böhm, H.-P. Kriegel, P. Kröger P., A. Zimek", title = "Robust, Complete, and Efficient Correlation Clustering", booktitle = "Proc. 7th SIAM International Conference on Data Mining (SDM'07), Minneapolis, MN, 2007", url = "http://www.siam.org/proceedings/datamining/2007/dm07_037achtert.pdf")
-public class COPAC<V extends NumberVector<?>, D extends Distance<D>> extends AbstractAlgorithm<Clustering<Model>> implements ClusteringAlgorithm<Clustering<Model>> {
+@Description("Partitions a database according to the correlation dimension of its objects and performs " //
+ + "a clustering algorithm over the partitions.")
+@Reference(authors = "E. Achtert, C. Böhm, H.-P. Kriegel, P. Kröger, A. Zimek", //
+title = "Robust, Complete, and Efficient Correlation Clustering", //
+booktitle = "Proc. 7th SIAM International Conference on Data Mining (SDM'07), Minneapolis, MN, 2007", //
+url = "http://www.siam.org/proceedings/datamining/2007/dm07_037achtert.pdf")
+public class COPAC<V extends NumberVector> extends AbstractAlgorithm<Clustering<DimensionModel>> implements ClusteringAlgorithm<Clustering<DimensionModel>> {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(COPAC.class);
/**
- * Parameter to specify the local PCA preprocessor to derive partition
- * criterion, must extend
- * {@link de.lmu.ifi.dbs.elki.index.preprocessed.localpca.AbstractFilteredPCAIndex}.
- * <p>
- * Key: {@code -copac.preprocessor}
- * </p>
- */
- public static final OptionID PREPROCESSOR_ID = new OptionID("copac.preprocessor", "Local PCA Preprocessor to derive partition criterion.");
-
- /**
- * Parameter to specify the distance function to use inside the partitions
- * {@link de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractIndexBasedDistanceFunction}
- * .
- * <p>
- * Default value:
- * {@link de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction}
- * </p>
- * <p>
- * Key: {@code -copac.partitionDistance}
- * </p>
- */
- public static final OptionID PARTITION_DISTANCE_ID = new OptionID("copac.partitionDistance", "Distance to use for the inner algorithms.");
-
- /**
- * Parameter to specify the clustering algorithm to apply to each partition,
- * must extend
- * {@link de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm}.
- * <p>
- * Key: {@code -copac.partitionAlgorithm}
- * </p>
- */
- public static final OptionID PARTITION_ALGORITHM_ID = new OptionID("copac.partitionAlgorithm", "Clustering algorithm to apply to each partition.");
-
- /**
- * Holds the instance of the preprocessed distance function
- * {@link #PARTITION_DISTANCE_ID}.
- */
- private FilteredLocalPCABasedDistanceFunction<V, ?, D> partitionDistanceFunction;
-
- /**
- * Get the algorithm to run on each partition.
- */
- private Class<? extends ClusteringAlgorithm<Clustering<Model>>> partitionAlgorithm;
-
- /**
- * Holds the parameters of the algorithm to run on each partition.
- */
- private Collection<Pair<OptionID, Object>> partitionAlgorithmParameters;
-
- /**
- * The last used distance query
+ * Settings class.
*/
- // FIXME: remove this when migrating to a full Factory pattern! This is
- // non-reentrant!
- private FilteredLocalPCABasedDistanceFunction.Instance<V, LocalProjectionIndex<V, ?>, D> partitionDistanceQuery;
+ COPAC.Settings settings;
/**
* Constructor.
*
- * @param partitionDistanceFunction Distance function
- * @param partitionAlgorithm Algorithm to use on partitions
- * @param partitionAlgorithmParameters Parameters for Algorithm to run on
- * partitions
+ * @param settings COPAC parameters
*/
- public COPAC(FilteredLocalPCABasedDistanceFunction<V, ?, D> partitionDistanceFunction, Class<? extends ClusteringAlgorithm<Clustering<Model>>> partitionAlgorithm, Collection<Pair<OptionID, Object>> partitionAlgorithmParameters) {
+ public COPAC(COPAC.Settings settings) {
super();
- this.partitionDistanceFunction = partitionDistanceFunction;
- this.partitionAlgorithm = partitionAlgorithm;
- this.partitionAlgorithmParameters = partitionAlgorithmParameters;
- }
-
- /**
- * Performs the COPAC algorithm on the given database.
- *
- * @param relation Relation to process
- * @return Clustering result
- */
- @SuppressWarnings("unchecked")
- public Clustering<Model> run(Relation<V> relation) {
- if(LOG.isVerbose()) {
- LOG.verbose("Running COPAC on db size = " + relation.size() + " with dimensionality = " + RelationUtil.dimensionality(relation));
- }
-
- partitionDistanceQuery = (FilteredLocalPCABasedDistanceFunction.Instance<V, LocalProjectionIndex<V, ?>, D>) partitionDistanceFunction.instantiate(relation);
- LocalProjectionIndex<V, ?> preprocin = partitionDistanceQuery.getIndex();
-
- // partitioning
- Map<Integer, ModifiableDBIDs> partitionMap = new HashMap<>();
- FiniteProgress partitionProgress = LOG.isVerbose() ? new FiniteProgress("Partitioning", relation.size(), LOG) : null;
- int processed = 1;
-
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- int corrdim = preprocin.getLocalProjection(iditer).getCorrelationDimension();
-
- if(!partitionMap.containsKey(corrdim)) {
- partitionMap.put(corrdim, DBIDUtil.newArray());
- }
-
- partitionMap.get(corrdim).add(iditer);
- if(partitionProgress != null) {
- partitionProgress.setProcessed(processed++, LOG);
- }
- }
-
- if(partitionProgress != null) {
- partitionProgress.ensureCompleted(LOG);
- }
- if(LOG.isVerbose()) {
- for(Integer corrDim : partitionMap.keySet()) {
- ModifiableDBIDs list = partitionMap.get(corrDim);
- LOG.verbose("Partition [corrDim = " + corrDim + "]: " + list.size() + " objects.");
- }
- }
-
- // convert for partition algorithm.
- // TODO: do this with DynamicDBIDs instead
- Map<Integer, DBIDs> pmap = new HashMap<>();
- for(Entry<Integer, ModifiableDBIDs> ent : partitionMap.entrySet()) {
- pmap.put(ent.getKey(), ent.getValue());
- }
- // running partition algorithm
- return runPartitionAlgorithm(relation, pmap, partitionDistanceQuery);
+ this.settings = settings;
}
/**
- * Runs the partition algorithm and creates the result.
+ * Run the COPAC algorithm.
*
- * @param relation the database to run this algorithm on
- * @param partitionMap the map of partition IDs to object ids
- * @param query The preprocessor based query function
+ * @param database Database
+ * @param relation Vector field relation
+ * @return COPAC clustering
*/
- private Clustering<Model> runPartitionAlgorithm(Relation<V> relation, Map<Integer, DBIDs> partitionMap, DistanceQuery<V, D> query) {
- Clustering<Model> result = new Clustering<>("COPAC clustering", "copac-clustering");
-
- // TODO: use an extra finite progress for the partitions?
- for(Entry<Integer, DBIDs> pair : partitionMap.entrySet()) {
- // noise partition
- if(pair.getKey() == RelationUtil.dimensionality(relation)) {
- // Make a Noise cluster
- result.addToplevelCluster(new Cluster<Model>(pair.getValue(), true, ClusterModel.CLUSTER));
- }
- else {
- DBIDs partids = pair.getValue();
- ProxyDatabase proxy = new ProxyDatabase(partids, relation);
-
- ClusteringAlgorithm<Clustering<Model>> partitionAlgorithm = getPartitionAlgorithm(query);
- if(LOG.isVerbose()) {
- LOG.verbose("Running " + partitionAlgorithm.getClass().getName() + " on partition [corrDim = " + pair.getKey() + "]...");
- }
- Clustering<Model> p = partitionAlgorithm.run(proxy);
- // Re-Wrap resulting Clusters as DimensionModel clusters.
- for(Cluster<Model> clus : p.getAllClusters()) {
- if(clus.isNoise()) {
- result.addToplevelCluster(new Cluster<Model>(clus.getIDs(), true, ClusterModel.CLUSTER));
- }
- else {
- result.addToplevelCluster(new Cluster<Model>(clus.getIDs(), new DimensionModel(pair.getKey())));
- }
- }
+ public Clustering<DimensionModel> run(Database database, Relation<V> relation) {
+ COPACNeighborPredicate.Instance npred = new COPACNeighborPredicate<V>(settings).instantiate(database, relation);
+ CorePredicate.Instance<DBIDs> cpred = new MinPtsCorePredicate(settings.minpts).instantiate(database, TypeUtil.DBIDS);
+ Clustering<Model> dclusters = new GeneralizedDBSCAN.Instance<>(npred, cpred, false).run();
+ // Re-wrap the detected clusters for COPAC:
+ Clustering<DimensionModel> result = new Clustering<>("COPAC clustering", "copac-clustering");
+ // Generalized DBSCAN clusterings will be flat.
+ for(Hierarchy.Iter<Cluster<Model>> iter = dclusters.iterToplevelClusters(); iter.valid(); iter.advance()) {
+ Cluster<Model> clus = iter.get();
+ if(clus.size() > 0) {
+ int dim = npred.dimensionality(clus.getIDs().iter());
+ DimensionModel model = new DimensionModel(dim);
+ result.addToplevelCluster(new Cluster<>(clus.getIDs(), model));
}
}
return result;
}
- /**
- * Returns the partition algorithm.
- *
- * @return the specified partition algorithm
- */
- public ClusteringAlgorithm<Clustering<Model>> getPartitionAlgorithm(DistanceQuery<V, D> query) {
- ListParameterization reconfig = new ListParameterization(partitionAlgorithmParameters);
- ProxyDistanceFunction<V, D> dist = ProxyDistanceFunction.proxy(query);
- reconfig.addParameter(DistanceBasedAlgorithm.DISTANCE_FUNCTION_ID, dist);
- ClusteringAlgorithm<Clustering<Model>> instance = reconfig.tryInstantiate(partitionAlgorithm);
- reconfig.failOnErrors();
- return instance;
- }
-
- /**
- * Get the last used distance query (to expose access to the preprocessor)
- *
- * Used by ERiC. TODO: migrate to factory pattern!
- *
- * @return distance query
- */
- public FilteredLocalPCABasedDistanceFunction.Instance<V, LocalProjectionIndex<V, ?>, D> getPartitionDistanceQuery() {
- return partitionDistanceQuery;
- }
-
@Override
public TypeInformation[] getInputTypeRestriction() {
return TypeUtil.array(TypeUtil.NUMBER_VECTOR_FIELD);
@@ -298,57 +137,128 @@ public class COPAC<V extends NumberVector<?>, D extends Distance<D>> extends Abs
}
/**
- * Parameterization class.
+ * Class to wrap the COPAC settings.
*
* @author Erich Schubert
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends Distance<D>> extends AbstractParameterizer {
- protected LocalProjectionIndex.Factory<V, ?> indexI = null;
-
- protected FilteredLocalPCABasedDistanceFunction<V, ?, D> pdistI = null;
-
- protected Class<? extends ClusteringAlgorithm<Clustering<Model>>> algC = null;
+ public static class Settings {
+ /**
+ * Neighborhood size.
+ */
+ public int k;
+
+ /**
+ * Class to compute PCA.
+ */
+ public PCAFilteredRunner pca;
+
+ /**
+ * Epsilon value for GDBSCAN.
+ */
+ public double epsilon;
+
+ /**
+ * MinPts parameter.
+ */
+ public int minpts;
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Size for the kNN neighborhood used in the PCA step of COPAC.
+ */
+ public static final OptionID K_ID = new OptionID("copac.knn", "Number of neighbors to use for PCA.");
+
+ /**
+ * Settings to build.
+ */
+ Settings settings;
+
+ @Override
+ public void makeOptions(Parameterization config) {
+ settings = new Settings();
+ configK(config);
+ // TODO: allow using other PCA runners?
+ settings.pca = config.tryInstantiate(PCAFilteredRunner.class);
+ configEpsilon(config);
+ configMinPts(config);
+ }
- protected Collection<Pair<OptionID, Object>> algO = null;
+ /**
+ * Configure the kNN parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configK(Parameterization config) {
+ IntParameter kP = new IntParameter(K_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(kP)) {
+ settings.k = kP.intValue();
+ }
+ }
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- ClassParameter<Factory<V, ?>> indexP = new ClassParameter<>(PREPROCESSOR_ID, LocalProjectionIndex.Factory.class);
- if(config.grab(indexP)) {
- indexI = indexP.instantiateClass(config);
+ /**
+ * Configure the epsilon radius parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configEpsilon(Parameterization config) {
+ DoubleParameter epsilonP = new DoubleParameter(DBSCAN.Parameterizer.EPSILON_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ if(config.grab(epsilonP)) {
+ settings.epsilon = epsilonP.doubleValue();
+ }
}
- ObjectParameter<FilteredLocalPCABasedDistanceFunction<V, ?, D>> pdistP = new ObjectParameter<>(PARTITION_DISTANCE_ID, FilteredLocalPCABasedDistanceFunction.class, LocallyWeightedDistanceFunction.class);
- if(config.grab(pdistP)) {
- ListParameterization predefinedDist = new ListParameterization();
- predefinedDist.addParameter(IndexBasedDistanceFunction.INDEX_ID, indexI);
- ChainedParameterization chainDist = new ChainedParameterization(predefinedDist, config);
- chainDist.errorsTo(config);
- pdistI = pdistP.instantiateClass(chainDist);
- predefinedDist.reportInternalParameterizationErrors(config);
+ /**
+ * Configure the minPts aka "mu" parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configMinPts(Parameterization config) {
+ IntParameter minptsP = new IntParameter(DBSCAN.Parameterizer.MINPTS_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(minptsP)) {
+ settings.minpts = minptsP.intValue();
+ }
}
- // Parameterize algorithm:
- ClassParameter<ClusteringAlgorithm<Clustering<Model>>> algP = new ClassParameter<>(PARTITION_ALGORITHM_ID, ClusteringAlgorithm.class);
- if(config.grab(algP)) {
- ListParameterization predefined = new ListParameterization();
- predefined.addParameter(DistanceBasedAlgorithm.DISTANCE_FUNCTION_ID, pdistI);
- TrackParameters trackpar = new TrackParameters(config);
- ChainedParameterization chain = new ChainedParameterization(predefined, trackpar);
- chain.errorsTo(config);
- algP.instantiateClass(chain);
- algC = algP.getValue();
- algO = trackpar.getGivenParameters();
- predefined.reportInternalParameterizationErrors(chain);
+ @Override
+ public Settings makeInstance() {
+ return settings;
}
}
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * COPAC settings.
+ */
+ protected COPAC.Settings settings;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ settings = config.tryInstantiate(COPAC.Settings.class);
+ }
@Override
- protected COPAC<V, D> makeInstance() {
- return new COPAC<>(pdistI, algC, algO);
+ protected COPAC<V> makeInstance() {
+ return new COPAC<>(settings);
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/ERiC.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/ERiC.java
index d535e136..87f7d519 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/ERiC.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/ERiC.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.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
@@ -29,50 +29,51 @@ import java.util.List;
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.CorePredicate;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.ERiCNeighborPredicate;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.GeneralizedDBSCAN;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.MinPtsCorePredicate;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.model.CorrelationModel;
-import de.lmu.ifi.dbs.elki.data.model.DimensionModel;
import de.lmu.ifi.dbs.elki.data.model.Model;
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.Database;
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.ModifiableDBIDs;
-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.database.relation.RelationUtil;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.ProxyDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.ERiCDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.BitDistance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.IntegerDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Centroid;
import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.FirstNEigenPairFilter;
import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredResult;
import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredRunner;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.StandardCovarianceMatrixBuilder;
import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy;
import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy.Iter;
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;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
+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;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
/**
* Performs correlation clustering on the data partitioned according to local
* correlation dimensionality and builds a hierarchy of correlation clusters
* that allows multiple inheritance from the clustering result.
+ *
+ * Reference:
* <p>
- * Reference: E. Achtert, C. Böhm, H.-P. Kriegel, P. Kröger, and A. Zimek: On
- * Exploring Complex Relationships of Correlation Clusters. <br>
+ * E. Achtert, C. Böhm, H.-P. Kriegel, P. Kröger, and A. Zimek:<br />
+ * On Exploring Complex Relationships of Correlation Clusters.<br />
* In Proc. 19th International Conference on Scientific and Statistical Database
* Management (SSDBM 2007), Banff, Canada, 2007.
* </p>
@@ -81,36 +82,39 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
*
* @apiviz.composedOf COPAC
* @apiviz.composedOf DBSCAN
- * @apiviz.composedOf ERiCDistanceFunction
* @apiviz.composedOf FirstNEigenPairFilter
* @apiviz.composedOf PCAFilteredRunner
+ * @apiviz.composedOf ERiCNeighborPredicate
* @apiviz.has CorrelationModel
*
* @param <V> the type of NumberVector handled by this Algorithm
*/
-// TODO: Re-use PCARunner objects somehow?
@Title("ERiC: Exploring Relationships among Correlation Clusters")
-@Description("Performs the DBSCAN algorithm on the data using a special distance function taking into account correlations among attributes and builds " + "a hierarchy that allows multiple inheritance from the correlation clustering result.")
-@Reference(authors = "E. Achtert, C. Böhm, H.-P. Kriegel, P. Kröger, and A. Zimek", title = "On Exploring Complex Relationships of Correlation Clusters", booktitle = "Proc. 19th International Conference on Scientific and Statistical Database Management (SSDBM 2007), Banff, Canada, 2007", url = "http://dx.doi.org/10.1109/SSDBM.2007.21")
-public class ERiC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<CorrelationModel<V>>> implements ClusteringAlgorithm<Clustering<CorrelationModel<V>>> {
+@Description("Performs the DBSCAN algorithm on the data using a special distance function taking into account correlations among attributes and builds " //
+ + "a hierarchy that allows multiple inheritance from the correlation clustering result.")
+@Reference(authors = "E. Achtert, C. Böhm, H.-P. Kriegel, P. Kröger, and A. Zimek",//
+title = "On Exploring Complex Relationships of Correlation Clusters", //
+booktitle = "Proc. 19th International Conference on Scientific and Statistical Database Management (SSDBM 2007), Banff, Canada, 2007", //
+url = "http://dx.doi.org/10.1109/SSDBM.2007.21")
+public class ERiC<V extends NumberVector> extends AbstractAlgorithm<Clustering<CorrelationModel<V>>> implements ClusteringAlgorithm<Clustering<CorrelationModel<V>>> {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(ERiC.class);
/**
- * The COPAC clustering algorithm.
+ * ERiC Settings.
*/
- private COPAC<V, IntegerDistance> copacAlgorithm;
+ private ERiC.Settings settings;
/**
* Constructor.
*
- * @param copacAlgorithm COPAC to use
+ * @param settings ERiC clustering settings
*/
- public ERiC(COPAC<V, IntegerDistance> copacAlgorithm) {
+ public ERiC(ERiC.Settings settings) {
super();
- this.copacAlgorithm = copacAlgorithm;
+ this.settings = settings;
}
/**
@@ -119,30 +123,27 @@ public class ERiC<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
* @param relation Relation to process
* @return Clustering result
*/
- public Clustering<CorrelationModel<V>> run(Relation<V> relation) {
+ public Clustering<CorrelationModel<V>> run(Database database, Relation<V> relation) {
final int dimensionality = RelationUtil.dimensionality(relation);
StepProgress stepprog = LOG.isVerbose() ? new StepProgress(3) : null;
- // run COPAC
- if (stepprog != null) {
- stepprog.beginStep(1, "Preprocessing local correlation dimensionalities and partitioning data", LOG);
- }
- Clustering<Model> copacResult = copacAlgorithm.run(relation);
-
- DistanceQuery<V, IntegerDistance> query = copacAlgorithm.getPartitionDistanceQuery();
+ // Run Generalized DBSCAN
+ LOG.beginStep(stepprog, 1, "Preprocessing local correlation dimensionalities and partitioning data");
+ // FIXME: how to ensure we are running on the same relation?
+ ERiCNeighborPredicate<V>.Instance npred = new ERiCNeighborPredicate<V>(settings).instantiate(database, relation);
+ CorePredicate.Instance<DBIDs> cpred = new MinPtsCorePredicate(settings.minpts).instantiate(database, TypeUtil.DBIDS);
+ Clustering<Model> copacResult = new GeneralizedDBSCAN.Instance<>(npred, cpred, false).run();
// extract correlation clusters
- if (stepprog != null) {
- stepprog.beginStep(2, "Extract correlation clusters", LOG);
- }
- List<List<Cluster<CorrelationModel<V>>>> clusterMap = extractCorrelationClusters(copacResult, relation, dimensionality);
- if (LOG.isDebugging()) {
+ LOG.beginStep(stepprog, 2, "Extract correlation clusters");
+ List<List<Cluster<CorrelationModel<V>>>> clusterMap = extractCorrelationClusters(copacResult, relation, dimensionality, npred);
+ if(LOG.isDebugging()) {
StringBuilder msg = new StringBuilder("Step 2: Extract correlation clusters...");
- for (int corrDim = 0; corrDim < clusterMap.size(); corrDim++) {
+ for(int corrDim = 0; corrDim < clusterMap.size(); corrDim++) {
List<Cluster<CorrelationModel<V>>> correlationClusters = clusterMap.get(corrDim);
msg.append("\n\ncorrDim ").append(corrDim);
- for (Cluster<CorrelationModel<V>> cluster : correlationClusters) {
+ for(Cluster<CorrelationModel<V>> cluster : correlationClusters) {
msg.append("\n cluster ").append(cluster).append(", ids: ").append(cluster.getIDs().size());
// .append(", level: ").append(cluster.getLevel()).append(", index: ").append(cluster.getLevelIndex());
// msg.append("\n basis " +
@@ -152,42 +153,38 @@ public class ERiC<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
}
LOG.debugFine(msg.toString());
}
- if (LOG.isVerbose()) {
+ if(LOG.isVerbose()) {
int clusters = 0;
- for (List<Cluster<CorrelationModel<V>>> correlationClusters : clusterMap) {
+ for(List<Cluster<CorrelationModel<V>>> correlationClusters : clusterMap) {
clusters += correlationClusters.size();
}
LOG.verbose(clusters + " clusters extracted.");
}
// build hierarchy
- if (stepprog != null) {
- stepprog.beginStep(3, "Building hierarchy", LOG);
- }
+ LOG.beginStep(stepprog, 3, "Building hierarchy");
Clustering<CorrelationModel<V>> clustering = new Clustering<>("ERiC clustering", "eric-clustering");
- buildHierarchy(clustering, clusterMap, query);
- if (LOG.isDebugging()) {
+ buildHierarchy(clustering, clusterMap, npred);
+ if(LOG.isDebugging()) {
StringBuilder msg = new StringBuilder("Step 3: Build hierarchy");
- for (int corrDim = 0; corrDim < clusterMap.size(); corrDim++) {
+ for(int corrDim = 0; corrDim < clusterMap.size(); corrDim++) {
List<Cluster<CorrelationModel<V>>> correlationClusters = clusterMap.get(corrDim);
- for (Cluster<CorrelationModel<V>> cluster : correlationClusters) {
+ for(Cluster<CorrelationModel<V>> cluster : correlationClusters) {
msg.append("\n cluster ").append(cluster).append(", ids: ").append(cluster.getIDs().size());
// .append(", level: ").append(cluster.getLevel()).append(", index: ").append(cluster.getLevelIndex());
- for (Iter<Cluster<CorrelationModel<V>>> iter = clustering.getClusterHierarchy().iterParents(cluster); iter.valid(); iter.advance()) {
+ for(Iter<Cluster<CorrelationModel<V>>> iter = clustering.getClusterHierarchy().iterParents(cluster); iter.valid(); iter.advance()) {
msg.append("\n parent ").append(iter.get());
}
- for (Iter<Cluster<CorrelationModel<V>>> iter = clustering.getClusterHierarchy().iterChildren(cluster); iter.valid(); iter.advance()) {
+ for(Iter<Cluster<CorrelationModel<V>>> iter = clustering.getClusterHierarchy().iterChildren(cluster); iter.valid(); iter.advance()) {
msg.append("\n child ").append(iter.get());
}
}
}
LOG.debugFine(msg.toString());
}
- if (stepprog != null) {
- stepprog.setCompleted(LOG);
- }
+ LOG.setCompleted(stepprog);
- for (Cluster<CorrelationModel<V>> rc : clusterMap.get(clusterMap.size() - 1)) {
+ for(Cluster<CorrelationModel<V>> rc : clusterMap.get(clusterMap.size() - 1)) {
clustering.addToplevelCluster(rc);
}
return clustering;
@@ -199,16 +196,17 @@ public class ERiC<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
* correlation dimension. Each cluster is defined by the basis vectors
* defining the subspace in which the cluster appears.
*
- * @param copacResult
+ * @param dbscanResult
*
* @param database the database containing the objects
* @param dimensionality the dimensionality of the feature space
+ * @param npred ERiC predicate
* @return a list of clusters for each dimensionality
*/
- private List<List<Cluster<CorrelationModel<V>>>> extractCorrelationClusters(Clustering<Model> copacResult, Relation<V> database, int dimensionality) {
+ private List<List<Cluster<CorrelationModel<V>>>> extractCorrelationClusters(Clustering<Model> dbscanResult, Relation<V> database, int dimensionality, ERiCNeighborPredicate<V>.Instance npred) {
// result
List<List<Cluster<CorrelationModel<V>>>> clusterMap = new ArrayList<>();
- for (int i = 0; i <= dimensionality; i++) {
+ for(int i = 0; i <= dimensionality; i++) {
clusterMap.add(new ArrayList<Cluster<CorrelationModel<V>>>());
}
@@ -216,47 +214,38 @@ public class ERiC<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
Cluster<Model> noise = null;
// iterate over correlation dimensions
- for (Cluster<Model> clus : copacResult.getAllClusters()) {
+ for(Cluster<Model> clus : dbscanResult.getAllClusters()) {
DBIDs group = clus.getIDs();
- if (clus.getModel() != null && clus.getModel() instanceof DimensionModel) {
- int correlationDimension = ((DimensionModel) clus.getModel()).getDimension();
+ int dim = clus.isNoise() ? dimensionality : npred.dimensionality(clus.getIDs().iter());
- ListParameterization parameters = pcaParameters(correlationDimension);
- Class<PCAFilteredRunner<V>> cls = ClassGenericsUtil.uglyCastIntoSubclass(PCAFilteredRunner.class);
- PCAFilteredRunner<V> pca = parameters.tryInstantiate(cls);
- parameters.failOnErrors();
+ if(dim < dimensionality) {
+ PCAFilteredRunner pca = new PCAFilteredRunner(new StandardCovarianceMatrixBuilder(), new FirstNEigenPairFilter(dim), 1., 0.);
// get cluster list for this dimension.
- List<Cluster<CorrelationModel<V>>> correlationClusters = clusterMap.get(correlationDimension);
+ List<Cluster<CorrelationModel<V>>> correlationClusters = clusterMap.get(dim);
PCAFilteredResult pcares = pca.processIds(group, database);
V centroid = Centroid.make(database, group).toVector(database);
- Cluster<CorrelationModel<V>> correlationCluster = new Cluster<>("[" + correlationDimension + "_" + correlationClusters.size() + "]", group, new CorrelationModel<>(pcares, centroid));
+ Cluster<CorrelationModel<V>> correlationCluster = new Cluster<>("[" + dim + "_" + correlationClusters.size() + "]", group, new CorrelationModel<>(pcares, centroid));
correlationClusters.add(correlationCluster);
}
// partition containing noise
- else if (clus.getModel() != null && clus.isNoise()) {
- if (noise == null) {
+ else {
+ if(noise == null) {
noise = clus;
- } else {
+ }
+ else {
ModifiableDBIDs merged = DBIDUtil.newHashSet(noise.getIDs());
merged.addDBIDs(clus.getIDs());
noise.setIDs(merged);
}
- } else {
- throw new IllegalStateException("Unexpected group returned: " + clus.getClass().getName());
}
}
- if (noise != null && noise.size() > 0) {
+ if(noise != null && noise.size() > 0) {
// get cluster list for this dimension.
List<Cluster<CorrelationModel<V>>> correlationClusters = clusterMap.get(dimensionality);
- ListParameterization parameters = pcaParameters(dimensionality);
- Class<PCAFilteredRunner<V>> cls = ClassGenericsUtil.uglyCastIntoSubclass(PCAFilteredRunner.class);
- PCAFilteredRunner<V> pca = parameters.tryInstantiate(cls);
- for (ParameterException e : parameters.getErrors()) {
- LOG.warning("Error in internal parameterization: " + e.getMessage());
- }
+ PCAFilteredRunner pca = new PCAFilteredRunner(new StandardCovarianceMatrixBuilder(), new FirstNEigenPairFilter(dimensionality), 1., 0.);
PCAFilteredResult pcares = pca.processIds(noise.getIDs(), database);
V centroid = Centroid.make(database, noise.getIDs()).toVector(database);
@@ -265,8 +254,8 @@ public class ERiC<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
}
// Delete dimensionalities not found.
- for (int i = dimensionality; i > 0; i--) {
- if (clusterMap.get(i).size() > 0) {
+ for(int i = dimensionality; i > 0; i--) {
+ if(clusterMap.get(i).size() > 0) {
break;
}
clusterMap.remove(i);
@@ -275,63 +264,35 @@ public class ERiC<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
return clusterMap;
}
- /**
- * Returns the parameters for the PCA for the specified correlation dimension.
- *
- * @param correlationDimension the correlation dimension
- * @return the parameters for the PCA for the specified correlation dimension
- */
- private ListParameterization pcaParameters(int correlationDimension) {
- ListParameterization parameters = new ListParameterization();
-
- parameters.addParameter(PCAFilteredRunner.PCA_EIGENPAIR_FILTER, FirstNEigenPairFilter.class);
- parameters.addParameter(FirstNEigenPairFilter.EIGENPAIR_FILTER_N, correlationDimension);
-
- return parameters;
- }
-
- private void buildHierarchy(Clustering<CorrelationModel<V>> clustering, List<List<Cluster<CorrelationModel<V>>>> clusterMap, DistanceQuery<V, IntegerDistance> query) {
+ private void buildHierarchy(Clustering<CorrelationModel<V>> clustering, List<List<Cluster<CorrelationModel<V>>>> clusterMap, ERiCNeighborPredicate<V>.Instance npred) {
StringBuilder msg = LOG.isDebuggingFine() ? new StringBuilder() : null;
Hierarchy<Cluster<CorrelationModel<V>>> hier = clustering.getClusterHierarchy();
- DBSCAN<V, DoubleDistance> dbscan = ClassGenericsUtil.castWithGenericsOrNull(DBSCAN.class, copacAlgorithm.getPartitionAlgorithm(query));
- if (dbscan == null) {
- // TODO: appropriate exception class?
- throw new IllegalArgumentException("ERiC was run without DBSCAN as COPAC algorithm!");
- }
- DistanceFunction<? super V, ?> dfun = ProxyDistanceFunction.unwrapDistance(dbscan.getDistanceFunction());
- ERiCDistanceFunction distanceFunction = ClassGenericsUtil.castWithGenericsOrNull(ERiCDistanceFunction.class, dfun);
- if (distanceFunction == null) {
- // TODO: appropriate exception class?
- throw new IllegalArgumentException("ERiC was run without ERiCDistanceFunction as distance function: got " + dfun.getClass());
- }
// Find maximum dimensionality found:
int lambda_max = clusterMap.size() - 1;
- for (int childCorrDim = 0; childCorrDim < lambda_max; childCorrDim++) {
+ for(int childCorrDim = 0; childCorrDim < lambda_max; childCorrDim++) {
List<Cluster<CorrelationModel<V>>> children = clusterMap.get(childCorrDim);
- // SortedMap<Integer, List<Cluster<CorrelationModel<V>>>> parentMap =
- // clusterMap.tailMap(childCorrDim + 1);
- if (msg != null) {
+ if(msg != null) {
msg.append("\ncorrdim ").append(childCorrDim);
- // msg.append("\nparents ").append(parentMap.keySet());
}
- for (Cluster<CorrelationModel<V>> child : children) {
- for (int parentCorrDim = childCorrDim + 1; parentCorrDim <= lambda_max; parentCorrDim++) {
+ for(Cluster<CorrelationModel<V>> child : children) {
+ for(int parentCorrDim = childCorrDim + 1; parentCorrDim <= lambda_max; parentCorrDim++) {
List<Cluster<CorrelationModel<V>>> parents = clusterMap.get(parentCorrDim);
- for (Cluster<CorrelationModel<V>> parent : parents) {
+ for(Cluster<CorrelationModel<V>> parent : parents) {
int subspaceDim_parent = parent.getModel().getPCAResult().getCorrelationDimension();
- if (subspaceDim_parent == lambda_max && hier.numParents(child) == 0) {
+ if(subspaceDim_parent == lambda_max && hier.numParents(child) == 0) {
clustering.addChildCluster(parent, child);
- if (msg != null) {
+ if(msg != null) {
msg.append('\n').append(parent).append(" is parent of ").append(child);
}
- } else {
- BitDistance dist = distanceFunction.distance(parent.getModel().getCentroid(), child.getModel().getCentroid(), parent.getModel().getPCAResult(), child.getModel().getPCAResult());
- if (!dist.bitValue() && (hier.numParents(child) == 0 || !isParent(distanceFunction, parent, hier.iterParents(child)))) {
+ }
+ else {
+ boolean dist = npred.weakNeighbors(parent.getModel().getCentroid(), child.getModel().getCentroid(), parent.getModel().getPCAResult(), child.getModel().getPCAResult());
+ if(!dist && (hier.numParents(child) == 0 || !isParent(npred, parent, hier.iterParents(child)))) {
clustering.addChildCluster(parent, child);
- if (msg != null) {
+ if(msg != null) {
msg.append('\n').append(parent).append(" is parent of ").append(child);
}
}
@@ -340,45 +301,43 @@ public class ERiC<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
}
}
}
- if (msg != null) {
+ if(msg != null) {
LOG.debugFine(msg.toString());
}
-
}
/**
* Returns true, if the specified parent cluster is a parent of one child of
* the children clusters.
*
- * @param distanceFunction the distance function for distance computation
- * between the clusters
+ * @param npred Neighborhood predicate
* @param parent the parent to be tested
* @param iter the list of children to be tested
* @return true, if the specified parent cluster is a parent of one child of
* the children clusters, false otherwise
*/
- private boolean isParent(ERiCDistanceFunction distanceFunction, Cluster<CorrelationModel<V>> parent, Iter<Cluster<CorrelationModel<V>>> iter) {
+ private boolean isParent(ERiCNeighborPredicate<V>.Instance npred, Cluster<CorrelationModel<V>> parent, Iter<Cluster<CorrelationModel<V>>> iter) {
StringBuilder msg = LOG.isDebugging() ? new StringBuilder() : null;
- for (; iter.valid(); iter.advance()) {
+ for(; iter.valid(); iter.advance()) {
Cluster<CorrelationModel<V>> child = iter.get();
- if (parent.getModel().getPCAResult().getCorrelationDimension() == child.getModel().getPCAResult().getCorrelationDimension()) {
+ if(parent.getModel().getPCAResult().getCorrelationDimension() == child.getModel().getPCAResult().getCorrelationDimension()) {
return false;
}
- BitDistance dist = distanceFunction.distance(parent.getModel().getCentroid(), child.getModel().getCentroid(), parent.getModel().getPCAResult(), child.getModel().getPCAResult());
- if (msg != null) {
+ boolean dist = npred.weakNeighbors(parent.getModel().getCentroid(), child.getModel().getCentroid(), parent.getModel().getPCAResult(), child.getModel().getPCAResult());
+ if(msg != null) {
msg.append("\ndist(").append(child).append(" - ").append(parent).append(") = ").append(dist);
}
- if (!dist.bitValue()) {
- if (msg != null) {
+ if(dist) {
+ if(msg != null) {
LOG.debugFine(msg);
}
return true;
}
}
- if (msg != null) {
+ if(msg != null) {
LOG.debugFine(msg.toString());
}
return false;
@@ -395,28 +354,184 @@ public class ERiC<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
}
/**
+ * Class to wrap the ERiC settings.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Settings {
+ /**
+ * Neighborhood size.
+ */
+ public int k;
+
+ /**
+ * Class to compute PCA.
+ */
+ public PCAFilteredRunner pca;
+
+ /**
+ * 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.
+ */
+ public double delta;
+
+ /**
+ * 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.
+ */
+ public double tau;
+
+ /**
+ * Minimum neighborhood size (density).
+ */
+ public int minpts;
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Size for the kNN neighborhood used in the PCA step of ERiC.
+ */
+ public static final OptionID K_ID = new OptionID("eric.k", "Number of neighbors to use for PCA.");
+
+ /**
+ * 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.");
+
+ /**
+ * Settings to build.
+ */
+ Settings settings;
+
+ @Override
+ public void makeOptions(Parameterization config) {
+ settings = new Settings();
+ configK(config);
+ // TODO: allow using other PCA runners?
+ settings.pca = config.tryInstantiate(PCAFilteredRunner.class);
+ configDelta(config);
+ configTau(config);
+ configMinPts(config);
+ }
+
+ /**
+ * Configure the kNN parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configK(Parameterization config) {
+ IntParameter kP = new IntParameter(K_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(kP)) {
+ settings.k = kP.intValue();
+ }
+ }
+
+ /**
+ * Configure the delta parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configDelta(Parameterization config) {
+ final DoubleParameter deltaP = new DoubleParameter(DELTA_ID, 0.1);
+ deltaP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ if(config.grab(deltaP)) {
+ settings.delta = deltaP.doubleValue();
+ }
+ }
+
+ /**
+ * Configure the tau parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configTau(Parameterization config) {
+ final DoubleParameter tauP = new DoubleParameter(TAU_ID, 0.1);
+ tauP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ if(config.grab(tauP)) {
+ settings.tau = tauP.doubleValue();
+ }
+ }
+
+ /**
+ * Configure the minPts aka "mu" parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configMinPts(Parameterization config) {
+ IntParameter minptsP = new IntParameter(DBSCAN.Parameterizer.MINPTS_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(minptsP)) {
+ settings.minpts = minptsP.intValue();
+ }
+ }
+
+ @Override
+ public Settings makeInstance() {
+ return settings;
+ }
+ }
+ }
+
+ /**
* Parameterization class.
*
* @author Erich Schubert
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
- * The COPAC instance to use
+ * The settings to use.
*/
- protected COPAC<V, IntegerDistance> copac;
+ protected ERiC.Settings settings;
- @SuppressWarnings("unchecked")
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- copac = config.tryInstantiate(COPAC.class);
+ settings = config.tryInstantiate(ERiC.Settings.class);
}
@Override
protected ERiC<V> makeInstance() {
- return new ERiC<>(copac);
+ return new ERiC<>(settings);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/FourC.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/FourC.java
index 5235273c..c6b18812 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/FourC.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/FourC.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.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
@@ -23,41 +23,53 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.correlation;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.algorithm.clustering.AbstractProjectedDBSCAN;
-import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.FourCCorePredicate;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.FourCNeighborPredicate;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.GeneralizedDBSCAN;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj.FourCSubspaceIndex;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.LimitEigenPairFilter;
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;
+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.DoubleParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
/**
* 4C identifies local subgroups of data objects sharing a uniform correlation.
* The algorithm is based on a combination of PCA and density-based clustering
* (DBSCAN).
+ *
+ * Reference:
* <p>
- * Reference: Christian Böhm, Karin Kailing, Peer Kröger, Arthur Zimek:
+ * C. Böhm, K. Kailing, P. Kröger, A. Zimek:<br />
* Computing Clusters of Correlation Connected Objects. <br>
* In Proc. ACM SIGMOD Int. Conf. on Management of Data, Paris, France, 2004.
* </p>
*
* @author Arthur Zimek
*
- * @apiviz.uses FourCSubspaceIndex
+ * @apiviz.composedOf FourCNeighborPredicate
+ * @apiviz.composedOf FourCCorePredicate
*
* @param <V> type of NumberVector handled by this Algorithm
*/
@Title("4C: Computing Correlation Connected Clusters")
-@Description("4C identifies local subgroups of data objects sharing a uniform correlation. " + "The algorithm is based on a combination of PCA and density-based clustering (DBSCAN).")
-@Reference(authors = "C. Böhm, K. Kailing, P. Kröger, A. Zimek", title = "Computing Clusters of Correlation Connected Objects", booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data, Paris, France, 2004, 455-466", url = "http://dx.doi.org/10.1145/1007568.1007620")
-public class FourC<V extends NumberVector<?>> extends AbstractProjectedDBSCAN<Clustering<Model>, V> {
+@Description("4C identifies local subgroups of data objects sharing a uniform correlation. " //
+ + "The algorithm is based on a combination of PCA and density-based clustering (DBSCAN).")
+@Reference(authors = "C. Böhm, K. Kailing, P. Kröger, A. Zimek", //
+title = "Computing Clusters of Correlation Connected Objects", //
+booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data, Paris, France, 2004, 455-466", //
+url = "http://dx.doi.org/10.1145/1007568.1007620")
+public class FourC<V extends NumberVector> extends GeneralizedDBSCAN {
/**
* The logger for this class.
*/
@@ -66,23 +78,10 @@ public class FourC<V extends NumberVector<?>> extends AbstractProjectedDBSCAN<Cl
/**
* Constructor.
*
- * @param epsilon Epsilon value
- * @param minpts MinPts value
- * @param distanceFunction Distance function
- * @param lambda Lambda value
+ * @param settings FourC settings.
*/
- public FourC(DoubleDistance epsilon, int minpts, LocallyWeightedDistanceFunction<V> distanceFunction, int lambda) {
- super(epsilon, minpts, distanceFunction, lambda);
- }
-
- @Override
- public String getLongResultName() {
- return "4C Clustering";
- }
-
- @Override
- public String getShortResultName() {
- return "4c-clustering";
+ public FourC(FourC.Settings settings) {
+ super(new FourCNeighborPredicate<V>(settings), new FourCCorePredicate(settings), false);
}
@Override
@@ -96,26 +95,196 @@ public class FourC<V extends NumberVector<?>> extends AbstractProjectedDBSCAN<Cl
}
/**
+ * Class wrapping the 4C parameter settings.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Settings {
+ /**
+ * Query radius epsilon.
+ */
+ public double epsilon;
+
+ /**
+ * Use absolute variance, not relative variance.
+ */
+ public boolean absolute = false;
+
+ /**
+ * Delta parameter, for selecting strong Eigenvectors.
+ */
+ public double delta = 0.0;
+
+ /**
+ * Kappa penalty parameter, to punish deviation in low-variance
+ * Eigenvectors.
+ */
+ public double kappa = 50.;
+
+ /**
+ * Maximum subspace dimensionality lambda.
+ */
+ public int lambda = Integer.MAX_VALUE;
+
+ /**
+ * MinPts / mu parameter.
+ */
+ public int minpts;
+
+ /**
+ * Parameterization class for 4C settings.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * The default value for delta.
+ */
+ public static final double DEFAULT_DELTA = .1;
+
+ /**
+ * Parameter Kappa: penalty for deviations in preferred dimensions.
+ */
+ public static final OptionID KAPPA_ID = new OptionID("predecon.kappa", "Penalty factor for deviations in preferred (low-variance) dimensions.");
+
+ /**
+ * Default for kappa parameter.
+ */
+ public static final double KAPPA_DEFAULT = 20.;
+
+ /**
+ * Parameter Lambda: maximum dimensionality allowed.
+ */
+ public static final OptionID LAMBDA_ID = new OptionID("predecon.lambda", "Maximum dimensionality to consider for core points.");
+
+ /**
+ * Settings storage.
+ */
+ Settings settings;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ settings = new Settings();
+ configEpsilon(config);
+ configMinPts(config);
+ configDelta(config);
+ configKappa(config);
+ configLambda(config);
+ }
+
+ /**
+ * Configure the epsilon radius parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configEpsilon(Parameterization config) {
+ DoubleParameter epsilonP = new DoubleParameter(DBSCAN.Parameterizer.EPSILON_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ if(config.grab(epsilonP)) {
+ settings.epsilon = epsilonP.doubleValue();
+ }
+ }
+
+ /**
+ * Configure the minPts aka "mu" parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configMinPts(Parameterization config) {
+ IntParameter minptsP = new IntParameter(DBSCAN.Parameterizer.MINPTS_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(minptsP)) {
+ settings.minpts = minptsP.intValue();
+ }
+ }
+
+ /**
+ * Configure the delta parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configDelta(Parameterization config) {
+ // Flag for using absolute variances
+ Flag absoluteF = new Flag(LimitEigenPairFilter.EIGENPAIR_FILTER_ABSOLUTE);
+ if(config.grab(absoluteF)) {
+ settings.absolute = absoluteF.isTrue();
+ }
+
+ // Parameter delta
+ DoubleParameter deltaP = new DoubleParameter(LimitEigenPairFilter.EIGENPAIR_FILTER_DELTA) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ if(!settings.absolute) {
+ deltaP.setDefaultValue(DEFAULT_DELTA);
+ }
+ else {
+ deltaP.addConstraint(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
+ }
+ if(config.grab(deltaP)) {
+ settings.delta = deltaP.doubleValue();
+ }
+ }
+
+ /**
+ * Configure the kappa parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configKappa(Parameterization config) {
+ DoubleParameter kappaP = new DoubleParameter(KAPPA_ID) //
+ .addConstraint(CommonConstraints.GREATER_THAN_ONE_DOUBLE) //
+ .setDefaultValue(KAPPA_DEFAULT);
+ if(config.grab(kappaP)) {
+ settings.kappa = kappaP.doubleValue();
+ }
+ }
+
+ /**
+ * Configure the delta parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configLambda(Parameterization config) {
+ IntParameter lambdaP = new IntParameter(LAMBDA_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT) //
+ .setOptional(true);
+ if(config.grab(lambdaP)) {
+ settings.lambda = lambdaP.intValue();
+ }
+ }
+
+ @Override
+ protected Object makeInstance() {
+ return settings;
+ }
+ }
+ }
+
+ /**
* Parameterization class.
*
* @author Erich Schubert
*
* @apiviz.exclude
*/
- public static class Parameterizer<O extends NumberVector<?>> extends AbstractProjectedDBSCAN.Parameterizer<O, DoubleDistance> {
+ public static class Parameterizer<O extends NumberVector> extends AbstractParameterizer {
+ /**
+ * Settings storage.
+ */
+ Settings settings;
+
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- configInnerDistance(config);
- configEpsilon(config, innerdist);
- configMinPts(config);
- configOuterDistance(config, epsilon, minpts, FourCSubspaceIndex.Factory.class, innerdist);
- configLambda(config);
+ settings = config.tryInstantiate(FourC.Settings.class);
}
@Override
protected FourC<O> makeInstance() {
- return new FourC<>(epsilon, minpts, outerdist, lambda);
+ return new FourC<>(settings);
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/HiCO.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/HiCO.java
index 79ddc16e..a46240cf 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/HiCO.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/HiCO.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.correlation;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,14 +23,30 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.correlation;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICS;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderResult;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.CorrelationClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.GeneralizedOPTICS;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.IndexBasedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.PCABasedCorrelationDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.PCACorrelationDistance;
+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.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
+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.logging.Logging;
+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.math.linearalgebra.pca.PercentageEigenPairFilter;
+import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
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;
@@ -55,87 +71,205 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*
* @author Elke Achtert
*
- * @apiviz.uses KNNQueryFilteredPCAIndex
- * @apiviz.uses PCABasedCorrelationDistanceFunction
+ * @apiviz.uses FilteredLocalPCAIndex
*
* @param <V> the type of NumberVector handled by the algorithm
*/
@Title("Mining Hierarchies of Correlation Clusters")
@Description("Algorithm for detecting hierarchies of correlation clusters.")
@Reference(authors = "E. Achtert, C. Böhm, P. Kröger, A. Zimek", title = "Mining Hierarchies of Correlation Clusters", booktitle = "Proc. Int. Conf. on Scientific and Statistical Database Management (SSDBM'06), Vienna, Austria, 2006", url = "http://dx.doi.org/10.1109/SSDBM.2006.35")
-public class HiCO<V extends NumberVector<?>> extends OPTICS<V, PCACorrelationDistance> {
+public class HiCO<V extends NumberVector> extends GeneralizedOPTICS<V, HiCO.HiCOClusterOrderEntry> {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(HiCO.class);
/**
- * Parameter to specify the smoothing factor, must be an integer greater than
- * 0. The {link {@link #MU_ID}-nearest neighbor is used to compute the
- * correlation reachability of an object.
- *
- * <p>
- * Key: {@code -hico.mu}
- * </p>
+ * The default value for {@link Parameterizer#DELTA_ID}.
*/
- public static final OptionID MU_ID = new OptionID("hico.mu", "Specifies the smoothing factor. The mu-nearest neighbor is used to compute the correlation reachability of an object.");
+ public static final double DEFAULT_DELTA = 0.25;
/**
- * Optional parameter to specify the number of nearest neighbors considered in
- * the PCA, must be an integer greater than 0. If this parameter is not set, k
- * is set to the value of {@link #MU_ID}.
- * <p>
- * Key: {@code -hico.k}
- * </p>
- * <p>
- * Default value: {@link #MU_ID}
- * </p>
+ * The default value for {@link Parameterizer#ALPHA_ID}.
*/
- public static final OptionID K_ID = new OptionID("hico.k", "Optional parameter to specify the number of nearest neighbors considered in the PCA. If this parameter is not set, k is set to the value of parameter mu.");
+ public static final double DEFAULT_ALPHA = 0.85;
/**
- * 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 -hico.delta}
- * </p>
+ * Factory to produce
*/
- public static final OptionID DELTA_ID = new OptionID("hico.delta", "Threshold of a distance between a vector q and a given space that indicates that " + "q adds a new dimension to the space.");
+ private IndexFactory<V, FilteredLocalPCAIndex<NumberVector>> indexfactory;
/**
- * The threshold for 'strong' eigenvectors: the 'strong' eigenvectors explain
- * a portion of at least alpha of the total variance.
- * <p>
- * Default value: {@link #DEFAULT_ALPHA}
- * </p>
- * <p>
- * Key: {@code -hico.alpha}
- * </p>
+ * Instantiated index.
*/
- public static final OptionID ALPHA_ID = new OptionID("hico.alpha", "The threshold for 'strong' eigenvectors: the 'strong' eigenvectors explain a portion of at least alpha of the total variance.");
+ private FilteredLocalPCAIndex<NumberVector> index;
/**
- * The default value for {@link #DELTA_ID}.
+ * Delta parameter
*/
- public static final double DEFAULT_DELTA = 0.25;
+ double delta;
/**
- * The default value for {@link #ALPHA_ID}.
+ * Constructor.
+ *
+ * @param indexfactory Index factory
+ * @param mu Mu parameter
*/
- public static final double DEFAULT_ALPHA = 0.85;
+ public HiCO(IndexFactory<V, FilteredLocalPCAIndex<NumberVector>> indexfactory, int mu, double delta) {
+ super(mu);
+ this.indexfactory = indexfactory;
+ this.delta = delta;
+ }
+
+ @Override
+ public ClusterOrderResult<HiCOClusterOrderEntry> run(Relation<V> relation) {
+ assert (this.index == null) : "Running algorithm instance multiple times in parallel is not supported.";
+ this.index = indexfactory.instantiate(relation);
+ ClusterOrderResult<HiCOClusterOrderEntry> result = super.run(relation);
+ this.index = null;
+ return result;
+ }
+
+ @Override
+ protected HiCOClusterOrderEntry makeSeedEntry(Relation<V> relation, DBID objectID) {
+ return new HiCOClusterOrderEntry(objectID, null, Integer.MAX_VALUE, Double.POSITIVE_INFINITY);
+ }
+
+ @Override
+ protected Collection<HiCOClusterOrderEntry> getNeighborsForDBID(Relation<V> relation, DBID id) {
+ DBID id1 = DBIDUtil.deref(id);
+ PCAFilteredResult pca1 = index.getLocalProjection(id1);
+ V dv1 = relation.get(id1);
+ final int dim = dv1.getDimensionality();
+
+ ArrayList<HiCOClusterOrderEntry> result = new ArrayList<>();
+ for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
+ PCAFilteredResult pca2 = index.getLocalProjection(iter);
+ V dv2 = relation.get(iter);
+
+ int correlationDistance = correlationDistance(pca1, pca2, dim);
+ double euclideanDistance = EuclideanDistanceFunction.STATIC.distance(dv1, dv2);
+
+ result.add(new HiCOClusterOrderEntry(DBIDUtil.deref(iter), id1, correlationDistance, euclideanDistance));
+ }
+ Collections.sort(result);
+ // This is a hack, but needed to enforce core-distance of OPTICS:
+ if(result.size() >= getMinPts()) {
+ HiCOClusterOrderEntry coredist = result.get(getMinPts() - 1);
+ for(int i = 0; i < getMinPts() - 1; i++) {
+ result.set(i, new HiCOClusterOrderEntry(result.get(i).getID(), id1, coredist.getCorrelationValue(), coredist.getEuclideanValue()));
+ }
+ }
+ return result;
+ }
/**
- * Constructor.
+ * Computes the correlation distance between the two subspaces defined by the
+ * specified PCAs.
*
- * @param distanceFunction Distance function
- * @param mu Mu parameter
+ * @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 HiCO(PCABasedCorrelationDistanceFunction distanceFunction, int mu) {
- super(distanceFunction, distanceFunction.getDistanceFactory().infiniteDistance(), mu);
+ 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);
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(indexfactory.getInputTypeRestriction());
+ }
+
+ @Override
+ public Class<? super HiCOClusterOrderEntry> getEntryType() {
+ return HiCOClusterOrderEntry.class;
}
@Override
@@ -144,16 +278,98 @@ public class HiCO<V extends NumberVector<?>> extends OPTICS<V, PCACorrelationDis
}
/**
+ * Cluster order entry for HiCO.
+ *
+ * @author Elke Achtert
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class HiCOClusterOrderEntry extends CorrelationClusterOrderEntry<HiCOClusterOrderEntry> {
+ /**
+ * Constructs a new CorrelationDistance object.
+ *
+ * @param correlationValue the correlation dimension to be represented by
+ * the CorrelationDistance
+ * @param euclideanValue the Euclidean distance to be represented by the
+ * CorrelationDistance
+ */
+ public HiCOClusterOrderEntry(DBID objectID, DBID predecessorID, int correlationValue, double euclideanValue) {
+ super(objectID, predecessorID, correlationValue, euclideanValue);
+ }
+ }
+
+ /**
* Parameterization class.
*
* @author Erich Schubert
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * Parameter to specify the smoothing factor, must be an integer greater
+ * than 0. The {link {@link #MU_ID}-nearest neighbor is used to compute the
+ * correlation reachability of an object.
+ *
+ * <p>
+ * Key: {@code -hico.mu}
+ * </p>
+ */
+ public static final OptionID MU_ID = new OptionID("hico.mu", "Specifies the smoothing factor. The mu-nearest neighbor is used to compute the correlation reachability of an object.");
+
+ /**
+ * Optional parameter to specify the number of nearest neighbors considered
+ * in the PCA, must be an integer greater than 0. If this parameter is not
+ * set, k is set to the value of {@link #MU_ID}.
+ * <p>
+ * Key: {@code -hico.k}
+ * </p>
+ * <p>
+ * Default value: {@link #MU_ID}
+ * </p>
+ */
+ public static final OptionID K_ID = new OptionID("hico.k", "Optional parameter to specify the number of nearest neighbors considered in the PCA. If this parameter is not set, k is set to the value of parameter mu.");
+
+ /**
+ * 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 -hico.delta}
+ * </p>
+ */
+ public static final OptionID DELTA_ID = new OptionID("hico.delta", "Threshold of a distance between a vector q and a given space that indicates that " + "q adds a new dimension to the space.");
+
+ /**
+ * The threshold for 'strong' eigenvectors: the 'strong' eigenvectors
+ * explain a portion of at least alpha of the total variance.
+ * <p>
+ * Default value: {@link #DEFAULT_ALPHA}
+ * </p>
+ * <p>
+ * Key: {@code -hico.alpha}
+ * </p>
+ */
+ public static final OptionID ALPHA_ID = new OptionID("hico.alpha", "The threshold for 'strong' eigenvectors: the 'strong' eigenvectors explain a portion of at least alpha of the total variance.");
+
+ /**
+ * Mu parameter
+ */
int mu = -1;
- PCABasedCorrelationDistanceFunction distance;
+ /**
+ * Delta parameter
+ */
+ double delta;
+
+ /**
+ * Factory to produce
+ */
+ private IndexFactory<V, FilteredLocalPCAIndex<NumberVector>> indexfactory;
@Override
protected void makeOptions(Parameterization config) {
@@ -168,17 +384,11 @@ public class HiCO<V extends NumberVector<?>> extends OPTICS<V, PCACorrelationDis
IntParameter kP = new IntParameter(K_ID);
kP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
kP.setOptional(true);
- final int k;
- if(config.grab(kP)) {
- k = kP.getValue();
- }
- else {
- k = mu;
- }
+ final int k = config.grab(kP) ? kP.getValue() : mu;
DoubleParameter deltaP = new DoubleParameter(DELTA_ID, DEFAULT_DELTA);
deltaP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
- double delta = DEFAULT_DELTA;
+ delta = DEFAULT_DELTA;
if(config.grab(deltaP)) {
delta = deltaP.doubleValue();
}
@@ -192,21 +402,20 @@ public class HiCO<V extends NumberVector<?>> extends OPTICS<V, PCACorrelationDis
}
// Configure Distance function
- ListParameterization opticsParameters = new ListParameterization();
+ ListParameterization params = new ListParameterization();
// preprocessor
- opticsParameters.addParameter(IndexBasedDistanceFunction.INDEX_ID, KNNQueryFilteredPCAIndex.Factory.class);
- opticsParameters.addParameter(KNNQueryFilteredPCAIndex.Factory.K_ID, k);
- opticsParameters.addParameter(PercentageEigenPairFilter.ALPHA_ID, alpha);
- opticsParameters.addParameter(PCABasedCorrelationDistanceFunction.DELTA_ID, delta);
+ params.addParameter(KNNQueryFilteredPCAIndex.Factory.Parameterizer.K_ID, k);
+ params.addParameter(PercentageEigenPairFilter.ALPHA_ID, alpha);
- ChainedParameterization chain = new ChainedParameterization(opticsParameters, config);
+ ChainedParameterization chain = new ChainedParameterization(params, config);
chain.errorsTo(config);
- distance = chain.tryInstantiate(PCABasedCorrelationDistanceFunction.class);
+ final Class<? extends IndexFactory<V, FilteredLocalPCAIndex<NumberVector>>> cls = ClassGenericsUtil.uglyCrossCast(KNNQueryFilteredPCAIndex.Factory.class, IndexFactory.class);
+ indexfactory = chain.tryInstantiate(cls);
}
@Override
protected HiCO<V> makeInstance() {
- return new HiCO<>(distance, mu);
+ return new HiCO<>(indexfactory, mu, delta);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/LMCLUS.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/LMCLUS.java
index 99144b42..176b7508 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/LMCLUS.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/LMCLUS.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.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
@@ -47,7 +47,7 @@ import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
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.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.datastructures.histogram.DoubleDynamicHistogram;
import de.lmu.ifi.dbs.elki.utilities.datastructures.histogram.DoubleHistogram;
import de.lmu.ifi.dbs.elki.utilities.datastructures.histogram.DoubleStaticHistogram.Iter;
@@ -158,7 +158,7 @@ public class LMCLUS extends AbstractAlgorithm<Clustering<Model>> {
* @param relation Relation
* @return Clustering result
*/
- public Clustering<Model> run(Database database, Relation<NumberVector<?>> relation) {
+ public Clustering<Model> run(Database database, Relation<NumberVector> relation) {
Clustering<Model> ret = new Clustering<>("LMCLUS Clustering", "lmclus-clustering");
FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("Clustered objects", relation.size(), LOG) : null;
IndefiniteProgress cprogress = LOG.isVerbose() ? new IndefiniteProgress("Clusters found", LOG) : null;
@@ -225,9 +225,7 @@ public class LMCLUS extends AbstractAlgorithm<Clustering<Model>> {
progress.setProcessed(relation.size(), LOG);
progress.ensureCompleted(LOG);
}
- if(cprogress != null) {
- cprogress.setCompleted(LOG);
- }
+ LOG.setCompleted(cprogress);
return ret;
}
@@ -264,7 +262,7 @@ public class LMCLUS extends AbstractAlgorithm<Clustering<Model>> {
* @return the overall goodness of the separation. The values origin basis and
* threshold are returned indirectly over class variables.
*/
- private Separation findSeparation(Relation<NumberVector<?>> relation, DBIDs currentids, int dimension, Random r) {
+ private Separation findSeparation(Relation<NumberVector> relation, DBIDs currentids, int dimension, Random r) {
Separation separation = new Separation();
// determine the number of samples needed, to secure that with a specific
// probability
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/ORCLUS.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/ORCLUS.java
index 7733ddaa..d01c52f1 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/ORCLUS.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/ORCLUS.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.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
@@ -42,11 +42,10 @@ 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.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
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.database.relation.RelationUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Centroid;
@@ -55,8 +54,8 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.SortedEigenPairs;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAResult;
import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCARunner;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
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;
@@ -67,8 +66,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
/**
- * ORCLUS provides the ORCLUS algorithm, an algorithm to find clusters in high
- * dimensional spaces.
+ * ORCLUS: Arbitrarily ORiented projected CLUSter generation.
+ *
* <p>
* Reference: C. C. Aggarwal, P. S. Yu: Finding Generalized Projected Clusters
* in High Dimensional Spaces. <br/>
@@ -77,14 +76,17 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
*
* @author Elke Achtert
*
- * @apiviz.uses PCARunner
+ * @apiviz.has PCARunner
*
* @param <V> the type of NumberVector handled by this Algorithm
*/
@Title("ORCLUS: Arbitrarily ORiented projected CLUSter generation")
@Description("Algorithm to find correlation clusters in high dimensional spaces.")
-@Reference(authors = "C. C. Aggarwal, P. S. Yu", title = "Finding Generalized Projected Clusters in High Dimensional Spaces", booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '00)", url = "http://dx.doi.org/10.1145/342009.335383")
-public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClustering<Clustering<Model>, V> {
+@Reference(authors = "C. C. Aggarwal, P. S. Yu", //
+title = "Finding Generalized Projected Clusters in High Dimensional Spaces", //
+booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '00)", //
+url = "http://dx.doi.org/10.1145/342009.335383")
+public class ORCLUS<V extends NumberVector> extends AbstractProjectedClustering<Clustering<Model>, V> {
/**
* The logger for this class.
*/
@@ -103,7 +105,7 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
/**
* The PCA utility object.
*/
- private PCARunner<V> pca;
+ private PCARunner pca;
/**
* Java constructor.
@@ -115,7 +117,7 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
* @param rnd Random generator
* @param pca PCA runner
*/
- public ORCLUS(int k, int k_i, int l, double alpha, RandomFactory rnd, PCARunner<V> pca) {
+ public ORCLUS(int k, int k_i, int l, double alpha, RandomFactory rnd, PCARunner pca) {
super(k, k_i, l);
this.alpha = alpha;
this.rnd = rnd;
@@ -130,7 +132,7 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
*/
public Clustering<Model> run(Database database, Relation<V> relation) {
try {
- DistanceQuery<V, DoubleDistance> distFunc = this.getDistanceQuery(database);
+ DistanceQuery<V> distFunc = this.getDistanceQuery(database);
// current dimensionality associated with each seed
int dim_c = RelationUtil.dimensionality(relation);
@@ -171,10 +173,7 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
}
assign(relation, distFunc, clusters);
- if(cprogress != null) {
- cprogress.setProcessed(clusters.size());
- cprogress.setCompleted(LOG);
- }
+ LOG.setCompleted(cprogress);
// get the result
Clustering<Model> r = new Clustering<>("ORCLUS clustering", "orclus-clustering");
@@ -197,7 +196,7 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
*/
private List<ORCLUSCluster> initialSeeds(Relation<V> database, int k) {
DBIDs randomSample = DBIDUtil.randomSample(database.getDBIDs(), k, rnd);
- NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(database);
+ NumberVector.Factory<V> factory = RelationUtil.getNumberVectorFactory(database);
List<ORCLUSCluster> seeds = new ArrayList<>();
for(DBIDIter iter = randomSample.iter(); iter.valid(); iter.advance()) {
seeds.add(new ORCLUSCluster(database.get(iter), iter, factory));
@@ -214,8 +213,8 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
* @param clusters the array of clusters to which the objects should be
* assigned to
*/
- private void assign(Relation<V> database, DistanceQuery<V, DoubleDistance> distFunc, List<ORCLUSCluster> clusters) {
- NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(database);
+ private void assign(Relation<V> database, DistanceQuery<V> distFunc, List<ORCLUSCluster> clusters) {
+ NumberVector.Factory<V> factory = RelationUtil.getNumberVectorFactory(database);
// clear the current clusters
for(ORCLUSCluster cluster : clusters) {
cluster.objectIDs.clear();
@@ -231,15 +230,15 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
for(DBIDIter it = database.iterDBIDs(); it.valid(); it.advance()) {
V o = database.get(it);
- DoubleDistance minDist = null;
+ double minDist = Double.POSITIVE_INFINITY;
ORCLUSCluster minCluster = null;
// determine projected distance between o and cluster
for(int i = 0; i < clusters.size(); i++) {
ORCLUSCluster c = clusters.get(i);
V o_proj = projection(c, o, factory);
- DoubleDistance dist = distFunc.distance(o_proj, projectedCentroids.get(i));
- if(minDist == null || minDist.compareTo(dist) > 0) {
+ double dist = distFunc.distance(o_proj, projectedCentroids.get(i));
+ if(dist < minDist) {
minDist = dist;
minCluster = c;
}
@@ -267,12 +266,12 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
* @param dim the dimensionality of the subspace
* @return matrix defining the basis of the subspace for the specified cluster
*/
- private Matrix findBasis(Relation<V> database, DistanceQuery<V, DoubleDistance> distFunc, ORCLUSCluster cluster, int dim) {
+ private Matrix findBasis(Relation<V> database, DistanceQuery<V> distFunc, ORCLUSCluster cluster, int dim) {
// covariance matrix of cluster
// Matrix covariance = Util.covarianceMatrix(database, cluster.objectIDs);
- GenericDistanceDBIDList<DoubleDistance> results = new GenericDistanceDBIDList<>(cluster.objectIDs.size());
+ ModifiableDoubleDBIDList results = DBIDUtil.newDistanceDBIDList(cluster.objectIDs.size());
for(DBIDIter it = cluster.objectIDs.iter(); it.valid(); it.advance()) {
- DoubleDistance distance = distFunc.distance(cluster.centroid, database.get(it));
+ double distance = distFunc.distance(cluster.centroid, database.get(it));
results.add(distance, it);
}
results.sort();
@@ -302,7 +301,7 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
* @param k_new the new number of seeds
* @param d_new the new dimensionality of the subspaces for each seed
*/
- private void merge(Relation<V> database, DistanceQuery<V, DoubleDistance> distFunc, List<ORCLUSCluster> clusters, int k_new, int d_new, IndefiniteProgress cprogress) {
+ private void merge(Relation<V> database, DistanceQuery<V> distFunc, List<ORCLUSCluster> clusters, int k_new, int d_new, IndefiniteProgress cprogress) {
ArrayList<ProjectedEnergy> projectedEnergies = new ArrayList<>();
for(int i = 0; i < clusters.size(); i++) {
for(int j = 0; j < clusters.size(); j++) {
@@ -384,16 +383,16 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
* @param dim the dimensionality of the clusters
* @return the projected energy of the specified cluster
*/
- private ProjectedEnergy projectedEnergy(Relation<V> database, DistanceQuery<V, DoubleDistance> distFunc, ORCLUSCluster c_i, ORCLUSCluster c_j, int i, int j, int dim) {
+ private ProjectedEnergy projectedEnergy(Relation<V> database, DistanceQuery<V> distFunc, ORCLUSCluster c_i, ORCLUSCluster c_j, int i, int j, int dim) {
// union of cluster c_i and c_j
ORCLUSCluster c_ij = union(database, distFunc, c_i, c_j, dim);
- NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(database);
+ NumberVector.Factory<V> factory = RelationUtil.getNumberVectorFactory(database);
double sum = 0.;
V c_proj = projection(c_ij, c_ij.centroid, factory);
for(DBIDIter iter = c_ij.objectIDs.iter(); iter.valid(); iter.advance()) {
V o_proj = projection(c_ij, database.get(iter), factory);
- double dist = distFunc.distance(o_proj, c_proj).doubleValue();
+ double dist = distFunc.distance(o_proj, c_proj);
sum += dist * dist;
}
sum /= c_ij.objectIDs.size();
@@ -411,7 +410,7 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
* @param dim the dimensionality of the union cluster
* @return the union of the two specified clusters
*/
- private ORCLUSCluster union(Relation<V> relation, DistanceQuery<V, DoubleDistance> distFunc, ORCLUSCluster c1, ORCLUSCluster c2, int dim) {
+ private ORCLUSCluster union(Relation<V> relation, DistanceQuery<V> distFunc, ORCLUSCluster c1, ORCLUSCluster c2, int dim) {
ORCLUSCluster c = new ORCLUSCluster();
c.objectIDs = DBIDUtil.newHashSet(c1.objectIDs);
@@ -424,7 +423,7 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
c.basis = findBasis(relation, distFunc, c, dim);
}
else {
- NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(relation);
+ NumberVector.Factory<V> factory = RelationUtil.getNumberVectorFactory(relation);
Vector cent = c1.centroid.getColumnVector().plusEquals(c2.centroid.getColumnVector()).timesEquals(0.5);
c.centroid = factory.newNumberVector(cent.getArrayRef());
double[][] doubles = new double[c1.basis.getRowDimensionality()][dim];
@@ -445,7 +444,7 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
* @param factory Factory object / prototype
* @return the projection of double vector o in the subspace of cluster c
*/
- private V projection(ORCLUSCluster c, V o, NumberVector.Factory<V, ?> factory) {
+ private V projection(ORCLUSCluster c, V o, NumberVector.Factory<V> factory) {
Matrix o_proj = o.getColumnVector().transposeTimes(c.basis);
double[] values = o_proj.getColumnPackedCopy();
return factory.newNumberVector(values);
@@ -497,7 +496,7 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
* @param id Object id
* @param factory Factory object / prototype
*/
- ORCLUSCluster(V o, DBIDRef id, NumberVector.Factory<V, ?> factory) {
+ ORCLUSCluster(V o, DBIDRef id, NumberVector.Factory<V> factory) {
this.objectIDs.add(id);
// initially the basis ist the original axis-system
@@ -552,7 +551,7 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractProjectedClustering.Parameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractProjectedClustering.Parameterizer {
/**
* Parameter to specify the factor for reducing the number of current
* clusters in each iteration, must be an integer greater than 0 and less
@@ -575,7 +574,7 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
protected RandomFactory rnd;
- protected PCARunner<V> pca = null;
+ protected PCARunner pca = null;
@Override
protected void makeOptions(Parameterization config) {
@@ -587,7 +586,7 @@ public class ORCLUS<V extends NumberVector<?>> extends AbstractProjectedClusteri
configSeed(config);
// TODO: make configurable, to allow using stabilized PCA
- Class<PCARunner<V>> cls = ClassGenericsUtil.uglyCastIntoSubclass(PCARunner.class);
+ Class<PCARunner> cls = ClassGenericsUtil.uglyCastIntoSubclass(PCARunner.class);
pca = config.tryInstantiate(cls);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/CASHInterval.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/CASHInterval.java
index 95cb2e58..dd4fe30c 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/CASHInterval.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/CASHInterval.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.correlation.cash;
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/algorithm/clustering/correlation/cash/CASHIntervalSplit.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/CASHIntervalSplit.java
index 328fe3b3..632a7db6 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/CASHIntervalSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/CASHIntervalSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.correlation.cash;
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/algorithm/clustering/correlation/cash/ParameterizationFunction.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/ParameterizationFunction.java
index 5c690feb..0dfa8ab2 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/ParameterizationFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/ParameterizationFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.correlation.cash;
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
@@ -77,7 +77,7 @@ public class ParameterizationFunction {
/**
* The actual vector.
*/
- private NumberVector<?> vec;
+ private NumberVector vec;
/**
* Provides a new parameterization function describing all lines in a
@@ -85,7 +85,7 @@ public class ParameterizationFunction {
*
* @param vec Existing vector
*/
- public ParameterizationFunction(NumberVector<?> vec) {
+ public ParameterizationFunction(NumberVector vec) {
super();
this.vec = vec;
determineGlobalExtremum();
@@ -403,7 +403,7 @@ public class ParameterizationFunction {
if(d != 0) {
result.append(" + \n").append(FormatUtil.whitespace(offset));
}
- result.append(FormatUtil.format(vec.doubleValue(d)));
+ result.append(vec.doubleValue(d));
for(int j = 0; j < d; j++) {
result.append(" * sin(a_").append(j + 1).append(')');
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/package-info.java
index bfc272fd..94889149 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/cash/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/algorithm/clustering/correlation/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/package-info.java
index 89d3c930..2d35e1cc 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/package-info.java
@@ -1,28 +1,26 @@
/**
* <p>Correlation clustering algorithms</p>
- *
- *
*/
/*
-This file is part of ELKI:
-Environment for Developing KDD-Applications Supported by Index-Structures
+ 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
+ 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 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.
+ 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/>.
-*/
+ 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.algorithm.clustering.correlation; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/AbstractEMModelFactory.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/AbstractEMModelFactory.java
new file mode 100644
index 00000000..605c3aed
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/AbstractEMModelFactory.java
@@ -0,0 +1,89 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.em;
+
+/*
+ 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.algorithm.clustering.kmeans.initialization.KMeansInitialization;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.RandomlyGeneratedInitialMeans;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.MeanModel;
+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;
+
+/**
+ * Abstract base class for initializing EM.
+ *
+ * @author Erich Schubert
+ *
+ * @param <V> Vector type
+ * @param <M> Model type
+ */
+public abstract class AbstractEMModelFactory<V extends NumberVector, M extends MeanModel> implements EMClusterModelFactory<V, M> {
+ /**
+ * Class to choose the initial means
+ */
+ protected KMeansInitialization<V> initializer;
+
+ /**
+ * Constructor.
+ *
+ * @param initializer Class for choosing the initial seeds.
+ */
+ public AbstractEMModelFactory(KMeansInitialization<V> initializer) {
+ super();
+ this.initializer = initializer;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <V> vector type
+ */
+ public abstract static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * Parameter to specify the cluster center initialization.
+ */
+ public static final OptionID INIT_ID = new OptionID("em.centers", //
+ "Method to choose the initial cluster centers.");
+
+ /**
+ * Initialization method
+ */
+ protected KMeansInitialization<V> initializer;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ ObjectParameter<KMeansInitialization<V>> initialP = new ObjectParameter<>(INIT_ID, KMeansInitialization.class, RandomlyGeneratedInitialMeans.class);
+ if(config.grab(initialP)) {
+ initializer = initialP.instantiateClass(config);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/DiagonalGaussianModel.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/DiagonalGaussianModel.java
new file mode 100644
index 00000000..4ba9290f
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/DiagonalGaussianModel.java
@@ -0,0 +1,200 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.em;
+
+/*
+ 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.data.model.EMModel;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+
+/**
+ * Simpler model for a single Gaussian cluster, without covariances.
+ *
+ * @author Erich Schubert
+ */
+public class DiagonalGaussianModel implements EMClusterModel<EMModel> {
+ /**
+ * Class logger.
+ */
+ private static Logging LOG = Logging.getLogger(DiagonalGaussianModel.class);
+
+ /**
+ * Mean vector.
+ */
+ Vector mean;
+
+ /**
+ * Per-dimension variances.
+ */
+ double[] variances;
+
+ /**
+ * Temporary storage, to avoid reallocations.
+ */
+ double[] nmea, mref;
+
+ /**
+ * Normalization factor.
+ */
+ double norm, normDistrFactor;
+
+ /**
+ * Weight aggregation sum
+ */
+ double weight, wsum;
+
+ /**
+ * Constructor.
+ *
+ * @param weight Cluster weight
+ * @param mean Initial mean
+ */
+ public DiagonalGaussianModel(double weight, Vector mean) {
+ this(weight, mean, MathUtil.powi(MathUtil.TWOPI, mean.getDimensionality()));
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param weight Cluster weight
+ * @param mean Initial mean
+ * @param norm Normalization factor.
+ */
+ public DiagonalGaussianModel(double weight, Vector mean, double norm) {
+ this.weight = weight;
+ final int dim = mean.getDimensionality();
+ this.mean = mean;
+ this.norm = norm;
+ this.normDistrFactor = 1. / Math.sqrt(norm); // assume det=1
+ this.mref = mean.getArrayRef();
+ this.nmea = new double[dim];
+ this.variances = new double[dim];
+ Arrays.fill(variances, 1.);
+ this.wsum = 0.;
+ }
+
+ @Override
+ public void beginEStep() {
+ wsum = 0.;
+ }
+
+ @Override
+ public void updateE(NumberVector vec, double wei) {
+ assert (vec.getDimensionality() == mref.length);
+ final double nwsum = wsum + wei;
+ // Compute new means
+ for(int i = 0; i < mref.length; i++) {
+ final double delta = vec.doubleValue(i) - mref[i];
+ final double rval = delta * wei / nwsum;
+ nmea[i] = mref[i] + rval;
+ }
+ // Update variances
+ for(int i = 0; i < mref.length; i++) {
+ // We DO want to use the new mean once and the old mean once!
+ // It does not matter which one is which.
+ variances[i] += (vec.doubleValue(i) - nmea[i]) * (vec.doubleValue(i) - mref[i]) * wei;
+ }
+ // Use new values.
+ wsum = nwsum;
+ System.arraycopy(nmea, 0, mref, 0, nmea.length);
+ }
+
+ @Override
+ public void finalizeEStep() {
+ if(wsum > 0.) {
+ final double s = 1. / wsum;
+ double det = 1.;
+ for(int i = 0; i < variances.length; i++) {
+ double v = variances[i];
+ v = v > 0 ? v * s : Matrix.SINGULARITY_CHEAT;
+ variances[i] = v;
+ det *= v;
+ }
+ normDistrFactor = 1. / Math.sqrt(norm * det);
+ }
+ else {
+ // Degenerate
+ normDistrFactor = 1. / Math.sqrt(norm);
+ }
+ }
+
+ /**
+ * Compute the Mahalanobis distance from the centroid for a given vector.
+ *
+ * @param vec Vector
+ * @return Mahalanobis distance
+ */
+ public double mahalanobisDistance(Vector vec) {
+ double[] difference = vec.minus(mean).getArrayRef();
+ double agg = 0.;
+ for(int i = 0; i < variances.length; i++) {
+ agg += difference[i] / variances[i] * difference[i];
+ }
+ return agg;
+ }
+
+ /**
+ * Compute the Mahalanobis distance from the centroid for a given vector.
+ *
+ * @param vec Vector
+ * @return Mahalanobis distance
+ */
+ public double mahalanobisDistance(NumberVector vec) {
+ double[] difference = vec.getColumnVector().minusEquals(mean).getArrayRef();
+ double agg = 0.;
+ for(int i = 0; i < variances.length; i++) {
+ agg += difference[i] / variances[i] * difference[i];
+ }
+ return agg;
+ }
+
+ @Override
+ public double estimateDensity(NumberVector vec) {
+ double power = mahalanobisDistance(vec) * .5;
+ double prob = normDistrFactor * Math.exp(-power);
+ if(!(prob >= 0.)) {
+ LOG.warning("Invalid probability: " + prob + " power: " + power + " factor: " + normDistrFactor);
+ prob = 0.;
+ }
+ return prob * weight;
+ }
+
+ @Override
+ public double getWeight() {
+ return weight;
+ }
+
+ @Override
+ public void setWeight(double weight) {
+ this.weight = weight;
+ }
+
+ @Override
+ public EMModel finalizeCluster() {
+ return new EMModel(mean, Matrix.diagonal(variances));
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/DiagonalGaussianModelFactory.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/DiagonalGaussianModelFactory.java
new file mode 100644
index 00000000..3ac02dae
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/DiagonalGaussianModelFactory.java
@@ -0,0 +1,88 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.em;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.EMModel;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+
+/**
+ * Factory for EM with multivariate gaussian models using diagonal matrixes.
+ *
+ * These models have individual variances, but no covariance, so this
+ * corresponds to the {@code 'VVI'} model in Mclust (R).
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has DiagonalGaussianModel
+ *
+ * @param <V> vector type
+ */
+public class DiagonalGaussianModelFactory<V extends NumberVector> extends AbstractEMModelFactory<V, EMModel> {
+ /**
+ * Constructor.
+ *
+ * @param initializer Class for choosing the inital seeds.
+ */
+ public DiagonalGaussianModelFactory(KMeansInitialization<V> initializer) {
+ super(initializer);
+ }
+
+ @Override
+ public List<DiagonalGaussianModel> buildInitialModels(Database database, Relation<V> relation, int k, PrimitiveDistanceFunction<? super NumberVector> df) {
+ final List<Vector> initialMeans = initializer.chooseInitialMeans(database, relation, k, df, Vector.FACTORY);
+ assert (initialMeans.size() == k);
+ final int dimensionality = initialMeans.get(0).getDimensionality();
+ final double norm = MathUtil.powi(MathUtil.TWOPI, dimensionality);
+ List<DiagonalGaussianModel> models = new ArrayList<>(k);
+ for(Vector nv : initialMeans) {
+ models.add(new DiagonalGaussianModel(1. / k, nv, norm));
+ }
+ return models;
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <V> Vector type
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractEMModelFactory.Parameterizer<V> {
+ @Override
+ protected DiagonalGaussianModelFactory<V> makeInstance() {
+ return new DiagonalGaussianModelFactory<>(initializer);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/EM.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/EM.java
index e82ec674..076c819b 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/EM.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/EM.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.em;
/*
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,13 +27,12 @@ import java.util.ArrayList;
import java.util.List;
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeans;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansInitialization;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.RandomlyGeneratedInitialMeans;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.model.EMModel;
+import de.lmu.ifi.dbs.elki.data.model.MeanModel;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
@@ -46,14 +45,9 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
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.distancefunction.minkowski.EuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.math.MathUtil;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.CovarianceMatrix;
-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.FormatUtil;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
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;
@@ -66,12 +60,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
- * Provides the EM algorithm (clustering by expectation maximization).
- * <p/>
- * Initialization is implemented as random initialization of means (uniformly
- * distributed within the attribute ranges of the given database) and initial
- * zero-covariance and variance=1 in covariance matrices.
- * </p>
+ * Clustering by expectation maximization (EM-Algorithm), also known as Gaussian
+ * Mixture Modeling (GMM).
+ *
* <p>
* Reference: A. P. Dempster, N. M. Laird, D. B. Rubin:<br />
* Maximum Likelihood from Incomplete Data via the EM algorithm.<br>
@@ -79,28 +70,27 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* </p>
*
* @author Arthur Zimek
+ * @author Erich Schubert
*
- * @apiviz.has EMModel
+ * @apiviz.composedOf EMClusterModelFactory
*
- * @param <V> a type of {@link NumberVector} as a suitable datatype for this
- * algorithm
+ * @param <V> vector type to analyze
+ * @param <M> model type to produce
*/
@Title("EM-Clustering: Clustering by Expectation Maximization")
-@Description("Provides k Gaussian mixtures maximizing the probability of the given data")
-@Reference(authors = "A. P. Dempster, N. M. Laird, D. B. Rubin", title = "Maximum Likelihood from Incomplete Data via the EM algorithm", booktitle = "Journal of the Royal Statistical Society, Series B, 39(1), 1977, pp. 1-31", url = "http://www.jstor.org/stable/2984875")
-public class EM<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<EMModel<V>>> implements ClusteringAlgorithm<Clustering<EMModel<V>>> {
+@Description("Cluster data via Gaussian mixture modeling and the EM algorithm")
+@Reference(authors = "A. P. Dempster, N. M. Laird, D. B. Rubin", //
+title = "Maximum Likelihood from Incomplete Data via the EM algorithm", //
+booktitle = "Journal of the Royal Statistical Society, Series B, 39(1), 1977, pp. 1-31", //
+url = "http://www.jstor.org/stable/2984875")
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.clustering.EM", "EM" })
+public class EM<V extends NumberVector, M extends MeanModel> extends AbstractAlgorithm<Clustering<M>> implements ClusteringAlgorithm<Clustering<M>> {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(EM.class);
/**
- * Small value to increment diagonally of a matrix in order to avoid
- * singularity before building the inverse.
- */
- private static final double SINGULARITY_CHEAT = 1E-9;
-
- /**
* Number of clusters
*/
private int k;
@@ -111,9 +101,9 @@ public class EM<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<
private double delta;
/**
- * Class to choose the initial means
+ * Factory for producing the initial cluster model.
*/
- private KMeansInitialization<V> initializer;
+ private EMClusterModelFactory<V, M> mfactory;
/**
* Maximum number of iterations to allow
@@ -137,15 +127,15 @@ public class EM<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<
*
* @param k k parameter
* @param delta delta parameter
- * @param initializer Class to choose the initial means
+ * @param mfactory EM cluster model factory
* @param maxiter Maximum number of iterations
* @param soft Include soft assignments
*/
- public EM(int k, double delta, KMeansInitialization<V> initializer, int maxiter, boolean soft) {
+ public EM(int k, double delta, EMClusterModelFactory<V, M> mfactory, int maxiter, boolean soft) {
super();
this.k = k;
this.delta = delta;
- this.initializer = initializer;
+ this.mfactory = mfactory;
this.maxiter = maxiter;
this.setSoft(soft);
}
@@ -162,7 +152,7 @@ public class EM<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<
* @param relation Relation
* @return Result
*/
- public Clustering<EMModel<V>> run(Database database, Relation<V> relation) {
+ public Clustering<M> run(Database database, Relation<V> relation) {
if(relation.size() == 0) {
throw new IllegalArgumentException("database empty: must contain elements");
}
@@ -170,32 +160,9 @@ public class EM<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<
if(LOG.isVerbose()) {
LOG.verbose("initializing " + k + " models");
}
- final List<V> initialMeans = initializer.chooseInitialMeans(database, relation, k, EuclideanDistanceFunction.STATIC);
- assert (initialMeans.size() == k);
- Vector[] means = new Vector[k];
- {
- int i = 0;
- for(NumberVector<?> nv : initialMeans) {
- means[i] = nv.getColumnVector();
- i++;
- }
- }
- Matrix[] covarianceMatrices = new Matrix[k];
- double[] normDistrFactor = new double[k];
- Matrix[] invCovMatr = new Matrix[k];
- double[] clusterWeights = new double[k];
+ List<? extends EMClusterModel<M>> models = mfactory.buildInitialModels(database, relation, k, SquaredEuclideanDistanceFunction.STATIC);
WritableDataStore<double[]> probClusterIGivenX = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_SORTED, double[].class);
-
- final int dimensionality = means[0].getDimensionality();
- final double norm = MathUtil.powi(MathUtil.TWOPI, dimensionality);
- for(int i = 0; i < k; i++) {
- Matrix m = Matrix.identity(dimensionality, dimensionality);
- covarianceMatrices[i] = m;
- normDistrFactor[i] = 1.0 / Math.sqrt(norm);
- invCovMatr[i] = Matrix.identity(dimensionality, dimensionality);
- clusterWeights[i] = 1.0 / k;
- }
- double emNew = assignProbabilitiesToInstances(relation, normDistrFactor, means, invCovMatr, clusterWeights, probClusterIGivenX);
+ double emNew = assignProbabilitiesToInstances(relation, models, probClusterIGivenX);
// iteration unless no change
if(LOG.isVerbose()) {
@@ -207,10 +174,9 @@ public class EM<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<
for(int it = 1; it <= maxiter || maxiter < 0; it++) {
final double emOld = emNew;
- recomputeCovarianceMatrices(relation, probClusterIGivenX, means, covarianceMatrices, dimensionality);
- computeInverseMatrixes(covarianceMatrices, invCovMatr, normDistrFactor, norm);
+ recomputeCovarianceMatrices(relation, probClusterIGivenX, models);
// reassign probabilities
- emNew = assignProbabilitiesToInstances(relation, normDistrFactor, means, invCovMatr, clusterWeights, probClusterIGivenX);
+ emNew = assignProbabilitiesToInstances(relation, models, probClusterIGivenX);
if(LOG.isVerbose()) {
LOG.verbose("iteration " + it + " - expectation value: " + emNew);
@@ -243,14 +209,13 @@ public class EM<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<
}
hardClusters.get(maxIndex).add(iditer);
}
- final NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(relation);
- Clustering<EMModel<V>> result = new Clustering<>("EM Clustering", "em-clustering");
+ Clustering<M> result = new Clustering<>("EM Clustering", "em-clustering");
// provide models within the result
for(int i = 0; i < k; i++) {
// TODO: re-do labeling.
// SimpleClassLabel label = new SimpleClassLabel();
// label.init(result.canonicalClusterLabel(i));
- Cluster<EMModel<V>> model = new Cluster<>(hardClusters.get(i), new EMModel<>(factory.newNumberVector(means[i].getArrayRef()), covarianceMatrices[i]));
+ Cluster<M> model = new Cluster<>(hardClusters.get(i), models.get(i).finalizeCluster());
result.addToplevelCluster(model);
}
if(isSoft()) {
@@ -263,61 +228,35 @@ public class EM<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<
}
/**
- * Compute the inverse cluster matrices.
- *
- * @param covarianceMatrices Input covariance matrices
- * @param invCovMatr Output array for inverse matrices
- * @param normDistrFactor Output array for norm distribution factors.
- * @param norm Normalization factor, usually (2pi)^d
- */
- public static void computeInverseMatrixes(Matrix[] covarianceMatrices, Matrix[] invCovMatr, double[] normDistrFactor, final double norm) {
- int k = covarianceMatrices.length;
- for(int i = 0; i < k; i++) {
- final double det = covarianceMatrices[i].det();
- if(det > 0.) {
- normDistrFactor[i] = 1. / Math.sqrt(norm * det);
- }
- else {
- LOG.warning("Encountered matrix with 0 determinant - degenerated.");
- normDistrFactor[i] = 1.; // Not really well defined
- }
- invCovMatr[i] = covarianceMatrices[i].inverse();
- }
- }
-
- /**
* Recompute the covariance matrixes.
*
* @param relation Vector data
* @param probClusterIGivenX Object probabilities
- * @param means Cluster means output
- * @param covarianceMatrices Output covariance matrixes
- * @param dimensionality Data set dimensionality
+ * @param models Cluster models to update
*/
- public static void recomputeCovarianceMatrices(Relation<? extends NumberVector<?>> relation, WritableDataStore<double[]> probClusterIGivenX, Vector[] means, Matrix[] covarianceMatrices, final int dimensionality) {
- final int k = means.length;
- CovarianceMatrix[] cms = new CovarianceMatrix[k];
- for(int i = 0; i < k; i++) {
- cms[i] = new CovarianceMatrix(dimensionality);
+ public static void recomputeCovarianceMatrices(Relation<? extends NumberVector> relation, WritableDataStore<double[]> probClusterIGivenX, List<? extends EMClusterModel<?>> models) {
+ for(EMClusterModel<?> m : models) {
+ m.beginEStep();
}
+ double[] wsum = new double[models.size()];
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
double[] clusterProbabilities = probClusterIGivenX.get(iditer);
- Vector instance = relation.get(iditer).getColumnVector();
- for(int i = 0; i < k; i++) {
- if(clusterProbabilities[i] > 0.) {
- cms[i].put(instance, clusterProbabilities[i]);
+ NumberVector instance = relation.get(iditer);
+ int i = 0;
+ for(EMClusterModel<?> m : models) {
+ final double prior = clusterProbabilities[i];
+ if(prior > 0.) {
+ m.updateE(instance, prior);
}
+ wsum[i] += prior;
+ ++i;
}
}
- for(int i = 0; i < k; i++) {
- if(cms[i].getWeight() <= 0.) {
- means[i] = new Vector(dimensionality);
- covarianceMatrices[i] = Matrix.identity(dimensionality, dimensionality);
- }
- else {
- means[i] = cms[i].getMeanVector();
- covarianceMatrices[i] = cms[i].destroyToNaiveMatrix().cheatToAvoidSingularity(SINGULARITY_CHEAT);
- }
+ int i = 0;
+ for(EMClusterModel<?> m : models) {
+ m.finalizeEStep();
+ m.setWeight(wsum[i] / relation.size());
+ i++;
}
}
@@ -329,56 +268,36 @@ public class EM<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<
* instance.
*
* @param relation the database used for assignment to instances
- * @param normDistrFactor normalization factor for density function, based on
- * current covariance matrix
- * @param means the current means
- * @param invCovMatr the inverse covariance matrices
- * @param clusterWeights the weights of the current clusters
+ * @param models Cluster models
+ * @param probClusterIGivenX Output storage for cluster probabilities
* @return the expectation value of the current mixture of distributions
*/
- public static double assignProbabilitiesToInstances(Relation<? extends NumberVector<?>> relation, double[] normDistrFactor, Vector[] means, Matrix[] invCovMatr, double[] clusterWeights, WritableDataStore<double[]> probClusterIGivenX) {
- final int k = clusterWeights.length;
+ public static double assignProbabilitiesToInstances(Relation<? extends NumberVector> relation, List<? extends EMClusterModel<?>> models, WritableDataStore<double[]> probClusterIGivenX) {
+ final int k = models.size();
double emSum = 0.;
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- Vector x = relation.get(iditer).getColumnVector();
+ NumberVector vec = relation.get(iditer);
double[] probabilities = new double[k];
- for(int i = 0; i < k; i++) {
- Vector difference = x.minus(means[i]);
- double rowTimesCovTimesCol = difference.transposeTimesTimes(invCovMatr[i], difference);
- double power = rowTimesCovTimesCol / 2.;
- double prob = normDistrFactor[i] * Math.exp(-power);
- if(LOG.isDebuggingFinest()) {
- LOG.debugFinest(" difference vector= ( " + difference.toString() + " )\n" + //
- " difference:\n" + FormatUtil.format(difference, " ") + "\n" + //
- " rowTimesCovTimesCol:\n" + rowTimesCovTimesCol + "\n" + //
- " power= " + power + "\n" + " prob=" + prob + "\n" + //
- " inv cov matrix: \n" + FormatUtil.format(invCovMatr[i], " "));
- }
- if(!(prob >= 0.)) {
- LOG.warning("Invalid probability: " + prob + " power: " + power + " factor: " + normDistrFactor[i]);
- prob = 0.;
+ {
+ int i = 0;
+ for(EMClusterModel<?> m : models) {
+ probabilities[i] = m.estimateDensity(vec);
+ ++i;
}
- probabilities[i] = prob;
}
double priorProbability = 0.;
for(int i = 0; i < k; i++) {
- priorProbability += probabilities[i] * clusterWeights[i];
+ priorProbability += probabilities[i];
}
double logP = Math.max(Math.log(priorProbability), MIN_LOGLIKELIHOOD);
- if(!Double.isNaN(logP)) {
- emSum += logP;
- }
+ emSum += (logP == logP) ? logP : 0.; /* avoid NaN */
double[] clusterProbabilities = new double[k];
- for(int i = 0; i < k; i++) {
- assert (clusterWeights[i] >= 0.);
- // do not divide by zero!
- if(priorProbability > 0.) {
- clusterProbabilities[i] = probabilities[i] / priorProbability * clusterWeights[i];
- }
- else {
- clusterProbabilities[i] = 0.;
+ if(priorProbability > 0.) {
+ for(int i = 0; i < k; i++) {
+ // do not divide by zero!
+ clusterProbabilities[i] = probabilities[i] / priorProbability;
}
}
probClusterIGivenX.put(iditer, clusterProbabilities);
@@ -418,7 +337,7 @@ public class EM<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector, M extends MeanModel> extends AbstractParameterizer {
/**
* Parameter to specify the number of clusters to find, must be an integer
* greater than 0.
@@ -434,10 +353,10 @@ public class EM<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<
"E(M) - E(M') < em.delta");
/**
- * Parameter to specify the initialization method
+ * Parameter to specify the EM cluster models to use.
*/
- public static final OptionID INIT_ID = new OptionID("kmeans.initialization", //
- "Method to choose the initial means.");
+ public static final OptionID INIT_ID = new OptionID("em.model", //
+ "Model factory.");
/**
* Number of clusters.
@@ -452,7 +371,7 @@ public class EM<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<
/**
* Initialization method
*/
- protected KMeansInitialization<V> initializer;
+ protected EMClusterModelFactory<V, M> initializer;
/**
* Maximum number of iterations.
@@ -468,27 +387,27 @@ public class EM<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<
k = kP.getValue();
}
- ObjectParameter<KMeansInitialization<V>> initialP = new ObjectParameter<>(INIT_ID, KMeansInitialization.class, RandomlyGeneratedInitialMeans.class);
+ ObjectParameter<EMClusterModelFactory<V, M>> initialP = new ObjectParameter<>(INIT_ID, EMClusterModelFactory.class, MultivariateGaussianModelFactory.class);
if(config.grab(initialP)) {
initializer = initialP.instantiateClass(config);
}
- DoubleParameter deltaP = new DoubleParameter(DELTA_ID, 0.0);
- deltaP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ DoubleParameter deltaP = new DoubleParameter(DELTA_ID, 0.)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
if(config.grab(deltaP)) {
delta = deltaP.getValue();
}
- IntParameter maxiterP = new IntParameter(KMeans.MAXITER_ID);
- maxiterP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_INT);
- maxiterP.setOptional(true);
+ IntParameter maxiterP = new IntParameter(KMeans.MAXITER_ID)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_INT) //
+ .setOptional(true);
if(config.grab(maxiterP)) {
maxiter = maxiterP.getValue();
}
}
@Override
- protected EM<V> makeInstance() {
+ protected EM<V, M> makeInstance() {
return new EM<>(k, delta, initializer, maxiter, false);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/EMClusterModel.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/EMClusterModel.java
new file mode 100644
index 00000000..f08e6444
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/EMClusterModel.java
@@ -0,0 +1,81 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.em;
+
+/*
+ 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.model.MeanModel;
+
+/**
+ * Models useable in EM clustering.
+ *
+ * @author Erich Schubert
+ */
+public interface EMClusterModel<M extends MeanModel> {
+ /**
+ * Begin the E step.
+ */
+ void beginEStep();
+
+ /**
+ * Update the
+ *
+ * @param vec Vector to process
+ * @param weight Weight
+ */
+ void updateE(NumberVector vec, double weight);
+
+ /**
+ * Finalize the E step.
+ */
+ void finalizeEStep();
+
+ /**
+ * Estimate the likelihood of a vector.
+ *
+ * @param vec Vector
+ * @return Likelihood.
+ */
+ double estimateDensity(NumberVector vec);
+
+ /**
+ * Finalize a cluster model.
+ *
+ * @return Cluster model
+ */
+ M finalizeCluster();
+
+ /**
+ * Get the cluster weight.
+ *
+ * @return Cluster weight
+ */
+ double getWeight();
+
+ /**
+ * Set the cluster weight.
+ *
+ * @param weight Cluster weight
+ */
+ void setWeight(double weight);
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/AbstractDataBasedQuery.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/EMClusterModelFactory.java
index 5d0e8444..223ebcd6 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/AbstractDataBasedQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/EMClusterModelFactory.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.database.query;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.em;
/*
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,37 +23,30 @@ package de.lmu.ifi.dbs.elki.database.query;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.MeanModel;
+import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
/**
- * Abstract query bound to a certain representation.
+ * Factory for initializing the EM models.
*
* @author Erich Schubert
*
- * @param <O> Database object type
+ * @param <V> Vector type
*/
-public abstract class AbstractDataBasedQuery<O> implements DatabaseQuery {
- /**
- * The data to use for this query
- */
- final protected Relation<? extends O> relation;
-
- /**
- * Database this query works on.
- *
- * @param relation Representation
- */
- public AbstractDataBasedQuery(Relation<? extends O> relation) {
- super();
- this.relation = relation;
- }
-
+public interface EMClusterModelFactory<V extends NumberVector, M extends MeanModel> {
/**
- * Get the queries relation.
+ * Build the initial models
*
- * @return Relation
+ * @param database Database
+ * @param relation Relation
+ * @param k Number of clusters
+ * @param df Distance function
+ * @return Initial models
*/
- public Relation<? extends O> getRelation() {
- return relation;
- }
+ List<? extends EMClusterModel<M>> buildInitialModels(Database database, Relation<V> relation, int k, PrimitiveDistanceFunction<? super NumberVector> df);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/MultivariateGaussianModel.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/MultivariateGaussianModel.java
new file mode 100644
index 00000000..e134edff
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/MultivariateGaussianModel.java
@@ -0,0 +1,212 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.em;
+
+/*
+ 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.model.EMModel;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.LUDecomposition;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.VMath;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+
+/**
+ * Model for a single Gaussian cluster.
+ *
+ * @author Erich Schubert
+ */
+public class MultivariateGaussianModel implements EMClusterModel<EMModel> {
+ /**
+ * Class logger.
+ */
+ private static Logging LOG = Logging.getLogger(MultivariateGaussianModel.class);
+
+ /**
+ * Mean vector.
+ */
+ Vector mean;
+
+ /**
+ * Covariance matrix, and inverse.
+ */
+ Matrix covariance, invCovMatr;
+
+ /**
+ * Temporary storage, to avoid reallocations.
+ */
+ double[] nmea, mref;
+
+ /**
+ * Matrix element reference.
+ */
+ double[][] elements;
+
+ /**
+ * Normalization factor.
+ */
+ double norm, normDistrFactor;
+
+ /**
+ * Weight aggregation sum
+ */
+ double weight, wsum;
+
+ /**
+ * Constructor.
+ *
+ * @param weight Cluster weight
+ * @param mean Initial mean
+ */
+ public MultivariateGaussianModel(double weight, Vector mean) {
+ this(weight, mean, MathUtil.powi(MathUtil.TWOPI, mean.getDimensionality()));
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param weight Cluster weight
+ * @param mean Initial mean
+ * @param norm Normalization factor.
+ */
+ public MultivariateGaussianModel(double weight, Vector mean, double norm) {
+ this.weight = weight;
+ final int dim = mean.getDimensionality();
+ this.mean = mean;
+ this.norm = norm;
+ this.normDistrFactor = 1. / Math.sqrt(norm); // assume det=1
+ this.mref = mean.getArrayRef();
+ this.nmea = new double[dim];
+ this.covariance = new Matrix(dim, dim);
+ this.elements = this.covariance.getArrayRef();
+ this.wsum = 0.;
+ }
+
+ @Override
+ public void beginEStep() {
+ if(covariance == null) {
+ covariance = new Matrix(mean.getDimensionality(), mean.getDimensionality());
+ return;
+ }
+ wsum = 0.;
+ }
+
+ @Override
+ public void updateE(NumberVector vec, double wei) {
+ assert (vec.getDimensionality() == mref.length);
+ final double nwsum = wsum + wei;
+ // Compute new means
+ for(int i = 0; i < mref.length; i++) {
+ final double delta = vec.doubleValue(i) - mref[i];
+ final double rval = delta * wei / nwsum;
+ nmea[i] = mref[i] + rval;
+ }
+ // Update covariance matrix
+ for(int i = 0; i < mref.length; i++) {
+ for(int j = i; j < mref.length; j++) {
+ // We DO want to use the new mean once and the old mean once!
+ // It does not matter which one is which.
+ double delta = (vec.doubleValue(i) - nmea[i]) * (vec.doubleValue(j) - mref[j]) * wei;
+ elements[i][j] = elements[i][j] + delta;
+ // Optimize via symmetry
+ if(i != j) {
+ elements[j][i] = elements[j][i] + delta;
+ }
+ }
+ }
+ // Use new values.
+ wsum = nwsum;
+ System.arraycopy(nmea, 0, mref, 0, nmea.length);
+ }
+
+ @Override
+ public void finalizeEStep() {
+ final int dim = mean.getDimensionality();
+ // TODO: improve handling of degenerated cases?
+ if(wsum > 0.) {
+ covariance.timesEquals(1. / wsum);
+ }
+ LUDecomposition lu = new LUDecomposition(covariance);
+ double det = lu.det();
+ if(det <= 0.) {
+ // Add a small value to the diagonal
+ covariance.plusDiagonalEquals(Matrix.SINGULARITY_CHEAT);
+ lu = new LUDecomposition(covariance); // Should no longer be zero now.
+ det = lu.det();
+ assert (det > 0) : "Singularity cheat did not resolve zero determinant.";
+ }
+ normDistrFactor = 1. / Math.sqrt(norm * det);
+ invCovMatr = lu.solve(Matrix.identity(dim, dim));
+ }
+
+ /**
+ * Compute the Mahalanobis distance from the centroid for a given vector.
+ *
+ * @param vec Vector
+ * @return Mahalanobis distance
+ */
+ public double mahalanobisDistance(Vector vec) {
+ if (invCovMatr != null) {
+ return VMath.mahalanobisDistance(invCovMatr.getArrayRef(), vec.getArrayRef(), mref);
+ }
+ Vector difference = vec.minus(mean);
+ return difference.transposeTimes(difference);
+ }
+
+ /**
+ * Compute the Mahalanobis distance from the centroid for a given vector.
+ *
+ * @param vec Vector
+ * @return Mahalanobis distance
+ */
+ public double mahalanobisDistance(NumberVector vec) {
+ Vector difference = vec.getColumnVector().minusEquals(mean);
+ return (invCovMatr != null) ? difference.transposeTimesTimes(invCovMatr, difference) : difference.transposeTimes(difference);
+ }
+
+ @Override
+ public double estimateDensity(NumberVector vec) {
+ double power = mahalanobisDistance(vec) * .5;
+ double prob = normDistrFactor * Math.exp(-power);
+ if(!(prob >= 0.)) {
+ LOG.warning("Invalid probability: " + prob + " power: " + power + " factor: " + normDistrFactor);
+ prob = 0.;
+ }
+ return prob * weight;
+ }
+
+ @Override
+ public double getWeight() {
+ return weight;
+ }
+
+ @Override
+ public void setWeight(double weight) {
+ this.weight = weight;
+ }
+
+ @Override
+ public EMModel finalizeCluster() {
+ return new EMModel(mean, covariance);
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/MultivariateGaussianModelFactory.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/MultivariateGaussianModelFactory.java
new file mode 100644
index 00000000..ca0b7db4
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/MultivariateGaussianModelFactory.java
@@ -0,0 +1,89 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.em;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.EMModel;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+
+/**
+ * Factory for EM with multivariate gaussian models (with covariance; also known
+ * as Gaussian Mixture Modeling, GMM).
+ *
+ * These models have individual covariance matrixes, so this corresponds to the
+ * {@code 'VVV'} model in Mclust (R).
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has MultivariateGaussianModel
+ *
+ * @param <V> vector type
+ */
+public class MultivariateGaussianModelFactory<V extends NumberVector> extends AbstractEMModelFactory<V, EMModel> {
+ /**
+ * Constructor.
+ *
+ * @param initializer Class for choosing the inital seeds.
+ */
+ public MultivariateGaussianModelFactory(KMeansInitialization<V> initializer) {
+ super(initializer);
+ }
+
+ @Override
+ public List<MultivariateGaussianModel> buildInitialModels(Database database, Relation<V> relation, int k, PrimitiveDistanceFunction<? super NumberVector> df) {
+ final List<Vector> initialMeans = initializer.chooseInitialMeans(database, relation, k, df, Vector.FACTORY);
+ assert (initialMeans.size() == k);
+ final int dimensionality = initialMeans.get(0).getDimensionality();
+ final double norm = MathUtil.powi(MathUtil.TWOPI, dimensionality);
+ List<MultivariateGaussianModel> models = new ArrayList<>(k);
+ for(Vector nv : initialMeans) {
+ models.add(new MultivariateGaussianModel(1. / k, nv, norm));
+ }
+ return models;
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <V> Vector type
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractEMModelFactory.Parameterizer<V> {
+ @Override
+ protected MultivariateGaussianModelFactory<V> makeInstance() {
+ return new MultivariateGaussianModelFactory<>(initializer);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/SphericalGaussianModel.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/SphericalGaussianModel.java
new file mode 100644
index 00000000..b1d62a17
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/SphericalGaussianModel.java
@@ -0,0 +1,190 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.em;
+
+/*
+ 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.model.EMModel;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+
+/**
+ * Simple spherical Gaussian cluster.
+ *
+ * @author Erich Schubert
+ */
+public class SphericalGaussianModel implements EMClusterModel<EMModel> {
+ /**
+ * Class logger.
+ */
+ private static Logging LOG = Logging.getLogger(SphericalGaussianModel.class);
+
+ /**
+ * Mean vector.
+ */
+ Vector mean;
+
+ /**
+ * Variances.
+ */
+ double variance;
+
+ /**
+ * Temporary storage, to avoid reallocations.
+ */
+ double[] nmea, mref;
+
+ /**
+ * Normalization factor.
+ */
+ double norm, normDistrFactor;
+
+ /**
+ * Weight aggregation sum
+ */
+ double weight, wsum;
+
+ /**
+ * Constructor.
+ *
+ * @param weight Cluster weight
+ * @param mean Initial mean
+ */
+ public SphericalGaussianModel(double weight, Vector mean) {
+ this(weight, mean, MathUtil.powi(MathUtil.TWOPI, mean.getDimensionality()));
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param weight Cluster weight
+ * @param mean Initial mean
+ * @param norm Normalization factor.
+ */
+ public SphericalGaussianModel(double weight, Vector mean, double norm) {
+ this.weight = weight;
+ final int dim = mean.getDimensionality();
+ this.mean = mean;
+ this.norm = norm;
+ this.normDistrFactor = 1. / Math.sqrt(norm); // assume det=1
+ this.mref = mean.getArrayRef();
+ this.nmea = new double[dim];
+ this.variance = 1.;
+ this.wsum = 0.;
+ }
+
+ @Override
+ public void beginEStep() {
+ wsum = 0.;
+ }
+
+ @Override
+ public void updateE(NumberVector vec, double wei) {
+ assert (vec.getDimensionality() == mref.length);
+ final double nwsum = wsum + wei;
+ // Compute new means
+ for(int i = 0; i < mref.length; i++) {
+ final double delta = vec.doubleValue(i) - mref[i];
+ final double rval = delta * wei / nwsum;
+ nmea[i] = mref[i] + rval;
+ }
+ // Update variances
+ for(int i = 0; i < mref.length; i++) {
+ // We DO want to use the new mean once and the old mean once!
+ // It does not matter which one is which.
+ variance += (vec.doubleValue(i) - nmea[i]) * (vec.doubleValue(i) - mref[i]) * wei;
+ }
+ // Use new values.
+ wsum = nwsum;
+ System.arraycopy(nmea, 0, mref, 0, nmea.length);
+ }
+
+ @Override
+ public void finalizeEStep() {
+ if(wsum > 0.) {
+ variance = variance / (wsum * mref.length);
+ normDistrFactor = 1. / Math.sqrt(norm * variance);
+ }
+ else {
+ // Degenerate
+ normDistrFactor = 1. / Math.sqrt(norm);
+ }
+ }
+
+ /**
+ * Compute the Mahalanobis distance from the centroid for a given vector.
+ *
+ * @param vec Vector
+ * @return Mahalanobis distance
+ */
+ public double mahalanobisDistance(Vector vec) {
+ double[] difference = vec.minus(mean).getArrayRef();
+ double agg = 0.;
+ for(int i = 0; i < difference.length; i++) {
+ agg += difference[i] / variance * difference[i];
+ }
+ return agg;
+ }
+
+ /**
+ * Compute the Mahalanobis distance from the centroid for a given vector.
+ *
+ * @param vec Vector
+ * @return Mahalanobis distance
+ */
+ public double mahalanobisDistance(NumberVector vec) {
+ double[] difference = vec.getColumnVector().minusEquals(mean).getArrayRef();
+ double agg = 0.;
+ for(int i = 0; i < difference.length; i++) {
+ agg += difference[i] / variance * difference[i];
+ }
+ return agg;
+ }
+
+ @Override
+ public double estimateDensity(NumberVector vec) {
+ double power = mahalanobisDistance(vec) * .5;
+ double prob = normDistrFactor * Math.exp(-power);
+ if(!(prob >= 0.)) {
+ LOG.warning("Invalid probability: " + prob + " power: " + power + " factor: " + normDistrFactor);
+ prob = 0.;
+ }
+ return prob * weight;
+ }
+
+ @Override
+ public double getWeight() {
+ return weight;
+ }
+
+ @Override
+ public void setWeight(double weight) {
+ this.weight = weight;
+ }
+
+ @Override
+ public EMModel finalizeCluster() {
+ return new EMModel(mean, Matrix.identity(nmea.length, nmea.length).timesEquals(variance));
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/SphericalGaussianModelFactory.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/SphericalGaussianModelFactory.java
new file mode 100644
index 00000000..7de77188
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/SphericalGaussianModelFactory.java
@@ -0,0 +1,88 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.em;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.EMModel;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+
+/**
+ * Factory for EM with multivariate gaussian models using diagonal matrixes.
+ *
+ * These models have individual variances, but no covariance, so this
+ * corresponds to the {@code 'VVI'} model in Mclust (R).
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has SphericalGaussianModel
+ *
+ * @param <V> vector type
+ */
+public class SphericalGaussianModelFactory<V extends NumberVector> extends AbstractEMModelFactory<V, EMModel> {
+ /**
+ * Constructor.
+ *
+ * @param initializer Class for choosing the inital seeds.
+ */
+ public SphericalGaussianModelFactory(KMeansInitialization<V> initializer) {
+ super(initializer);
+ }
+
+ @Override
+ public List<SphericalGaussianModel> buildInitialModels(Database database, Relation<V> relation, int k, PrimitiveDistanceFunction<? super NumberVector> df) {
+ final List<Vector> initialMeans = initializer.chooseInitialMeans(database, relation, k, df, Vector.FACTORY);
+ assert (initialMeans.size() == k);
+ final int dimensionality = initialMeans.get(0).getDimensionality();
+ final double norm = MathUtil.powi(MathUtil.TWOPI, dimensionality);
+ List<SphericalGaussianModel> models = new ArrayList<>(k);
+ for(Vector nv : initialMeans) {
+ models.add(new SphericalGaussianModel(1. / k, nv, norm));
+ }
+ return models;
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <V> Vector type
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractEMModelFactory.Parameterizer<V> {
+ @Override
+ protected SphericalGaussianModelFactory<V> makeInstance() {
+ return new SphericalGaussianModelFactory<>(initializer);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/package-info.java
index e96621b5..22f0b669 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distanceresultlist/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/em/package-info.java
@@ -1,11 +1,12 @@
/**
- * <p>Classes for building and storing the results of distance-based queries</p>
+ * Expectation-Maximization clustering algorithm.
*/
+
/*
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.algorithm.clustering.em; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/AbstractRangeQueryNeighborPredicate.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/AbstractRangeQueryNeighborPredicate.java
new file mode 100644
index 00000000..8b35648c
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/AbstractRangeQueryNeighborPredicate.java
@@ -0,0 +1,217 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan;
+
+/*
+ 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.algorithm.DistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN;
+import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
+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.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
+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.distancefunction.minkowski.EuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.logging.statistics.Duration;
+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.DoubleParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
+
+/**
+ * Abstract local model neighborhood predicate.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has Instance
+ *
+ * @param <O> object type
+ * @param <M> model type
+ */
+public abstract class AbstractRangeQueryNeighborPredicate<O, M> implements NeighborPredicate {
+ /**
+ * Range to query with.
+ */
+ protected double epsilon;
+
+ /**
+ * Distance function to use.
+ */
+ protected DistanceFunction<? super O> distFunc;
+
+ /**
+ * Full constructor.
+ *
+ * @param epsilon Epsilon value
+ * @param distFunc Distance function to use
+ */
+ public AbstractRangeQueryNeighborPredicate(double epsilon, DistanceFunction<? super O> distFunc) {
+ super();
+ this.epsilon = epsilon;
+ this.distFunc = distFunc;
+ }
+
+ @Override
+ public TypeInformation getInputTypeRestriction() {
+ return distFunc.getInputTypeRestriction();
+ }
+
+ /**
+ * Perform the preprocessing step.
+ *
+ * @param modelcls Class of models
+ * @param relation Data relation
+ * @param query Range query
+ * @return Precomputed models
+ */
+ public DataStore<M> preprocess(Class<? super M> modelcls, Relation<O> relation, RangeQuery<O> query) {
+ WritableDataStore<M> storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, modelcls);
+
+ Duration time = getLogger().newDuration(this.getClass().getName() + ".preprocessing-time").begin();
+ FiniteProgress progress = getLogger().isVerbose() ? new FiniteProgress(this.getClass().getName(), relation.size(), getLogger()) : null;
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ DoubleDBIDList neighbors = query.getRangeForDBID(iditer, epsilon);
+ storage.put(iditer, computeLocalModel(iditer, neighbors, relation));
+ getLogger().incrementProcessed(progress);
+ }
+ getLogger().ensureCompleted(progress);
+ getLogger().statistics(time.end());
+ return storage;
+ }
+
+ /**
+ * Method to compute the actual data model.
+ *
+ * @param id Object ID
+ * @param neighbors Neighbors
+ * @param relation Data relation
+ * @return Model for this object.
+ */
+ abstract protected M computeLocalModel(DBIDRef id, DoubleDBIDList neighbors, Relation<O> relation);
+
+ /**
+ * Get the class logger.
+ *
+ * @return Logger
+ */
+ abstract Logging getLogger();
+
+ /**
+ * Instance for a particular data set.
+ *
+ * @author Erich Schubert
+ *
+ * @param <N> Neighborhood type
+ * @param <M> model type
+ */
+ public abstract static class Instance<N, M> implements NeighborPredicate.Instance<N> {
+ /**
+ * DBIDs to process
+ */
+ protected DBIDs ids;
+
+ /**
+ * Model storage.
+ */
+ protected DataStore<M> storage;
+
+ /**
+ * Constructor.
+ *
+ * @param ids DBIDs to process
+ * @param storage Model storage
+ */
+ public Instance(DBIDs ids, DataStore<M> storage) {
+ super();
+ this.ids = ids;
+ this.storage = storage;
+ }
+
+ @Override
+ public DBIDs getIDs() {
+ return ids;
+ }
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <O> object type
+ */
+ public abstract static class Parameterizer<O> extends AbstractParameterizer {
+ /**
+ * Range to query with
+ */
+ double epsilon;
+
+ /**
+ * Distance function to use
+ */
+ DistanceFunction<O> distfun = null;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ configDistance(config);
+ configEpsilon(config);
+ }
+
+ /**
+ * Configure the distance parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configDistance(Parameterization config) {
+ // Get a distance function.
+ ObjectParameter<DistanceFunction<O>> distanceP = new ObjectParameter<>(DistanceBasedAlgorithm.DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
+ if(config.grab(distanceP)) {
+ distfun = distanceP.instantiateClass(config);
+ }
+ }
+
+ /**
+ * Configure the epsilon parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configEpsilon(Parameterization config) {
+ // Get the epsilon parameter
+ DoubleParameter epsilonP = new DoubleParameter(DBSCAN.Parameterizer.EPSILON_ID);
+ if(config.grab(epsilonP)) {
+ epsilon = epsilonP.getValue();
+ }
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/COPACNeighborPredicate.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/COPACNeighborPredicate.java
new file mode 100644
index 00000000..0216ad09
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/COPACNeighborPredicate.java
@@ -0,0 +1,310 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan;
+
+/*
+ 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.algorithm.clustering.correlation.COPAC;
+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.TypeInformation;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
+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.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.SetDBIDs;
+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.distancefunction.minkowski.EuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.logging.statistics.Duration;
+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.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+
+/**
+ * COPAC neighborhood predicate.
+ *
+ * Reference:
+ * <p>
+ * E. Achtert, C. Böhm H.-P. Kriegel, P. Kröger, A. Zimek:<br />
+ * Robust, Complete, and Efficient Correlation Clustering.<br />
+ * In Proc. 7th SIAM International Conference on Data Mining (SDM'07),
+ * Minneapolis, MN, 2007
+ * </p>
+ *
+ * TODO: improve performance by allowing index support for finding neighbors
+ * and/or exploiting the data partitioning better.
+ *
+ * @author Arthur Zimek
+ * @author Erich Schubert
+ *
+ * @param <V> the type of NumberVector handled by this Algorithm
+ */
+@Reference(authors = "E. Achtert, C. Böhm, H.-P. Kriegel, P. Kröger, A. Zimek", //
+title = "Robust, Complete, and Efficient Correlation Clustering", //
+booktitle = "Proc. 7th SIAM International Conference on Data Mining (SDM'07), Minneapolis, MN, 2007", //
+url = "http://www.siam.org/proceedings/datamining/2007/dm07_037achtert.pdf")
+public class COPACNeighborPredicate<V extends NumberVector> implements NeighborPredicate {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(COPACNeighborPredicate.class);
+
+ /**
+ * COPAC parameters
+ */
+ protected final COPAC.Settings settings;
+
+ /**
+ * Squared value of epsilon.
+ */
+ protected double epsilonsq;
+
+ /**
+ * Constructor.
+ *
+ * @param settings COPAC settings
+ */
+ public COPACNeighborPredicate(COPAC.Settings settings) {
+ super();
+ this.settings = settings;
+ this.epsilonsq = settings.epsilon * settings.epsilon;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> NeighborPredicate.Instance<T> instantiate(Database database, SimpleTypeInformation<?> type) {
+ Relation<V> relation = database.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
+ return (NeighborPredicate.Instance<T>) instantiate(database, relation);
+ }
+
+ /**
+ * Full instantiation method.
+ *
+ * @param database Database
+ * @param relation Vector relation
+ * @return Instance
+ */
+ public COPACNeighborPredicate.Instance instantiate(Database database, Relation<V> relation) {
+ DistanceQuery<V> dq = database.getDistanceQuery(relation, EuclideanDistanceFunction.STATIC);
+ KNNQuery<V> knnq = database.getKNNQuery(dq, settings.k);
+
+ WritableDataStore<COPACModel> storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, COPACModel.class);
+
+ Duration time = LOG.newDuration(this.getClass().getName() + ".preprocessing-time").begin();
+ FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress(this.getClass().getName(), relation.size(), LOG) : null;
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ DoubleDBIDList ref = knnq.getKNNForDBID(iditer, settings.k);
+ storage.put(iditer, computeLocalModel(iditer, ref, relation));
+ LOG.incrementProcessed(progress);
+ }
+ LOG.ensureCompleted(progress);
+ LOG.statistics(time.end());
+ return new Instance(relation.getDBIDs(), storage);
+ }
+
+ /**
+ * COPAC model computation
+ *
+ * @param id Query object
+ * @param knnneighbors k nearest neighbors
+ * @param relation Data relation
+ * @return COPAC object model
+ */
+ protected COPACModel computeLocalModel(DBIDRef id, DoubleDBIDList knnneighbors, Relation<V> relation) {
+ PCAFilteredResult pcares = settings.pca.processQueryResult(knnneighbors, relation);
+
+ int pdim = pcares.getCorrelationDimension();
+ Matrix mat = pcares.similarityMatrix();
+
+ Vector vecP = relation.get(id).getColumnVector();
+
+ if(pdim == vecP.getDimensionality()) {
+ // Full dimensional - noise!
+ return new COPACModel(pdim, DBIDUtil.EMPTYDBIDS);
+ }
+
+ // Check which neighbors survive
+ HashSetModifiableDBIDs survivors = DBIDUtil.newHashSet();
+ for(DBIDIter neighbor = relation.iterDBIDs(); neighbor.valid(); neighbor.advance()) {
+ Vector diff = relation.get(neighbor).getColumnVector().minusEquals(vecP);
+ double cdistP = diff.transposeTimesTimes(mat, diff);
+
+ if(cdistP <= epsilonsq) {
+ survivors.add(neighbor);
+ }
+ }
+
+ return new COPACModel(pdim, survivors);
+ }
+
+ @Override
+ public TypeInformation getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_FIELD;
+ }
+
+ /**
+ * Model used by COPAC for core point property.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class COPACModel implements SetDBIDs {
+ /**
+ * Correlation dimensionality.
+ */
+ int cdim;
+
+ /**
+ * Neighbor ids.
+ */
+ SetDBIDs ids;
+
+ /**
+ * COPAC model.
+ *
+ * @param cdim Correlation dimensionality
+ * @param ids Neighbor ids
+ */
+ public COPACModel(int cdim, SetDBIDs ids) {
+ super();
+ this.cdim = cdim;
+ this.ids = ids;
+ }
+
+ @Override
+ public DBIDIter iter() {
+ return ids.iter();
+ }
+
+ @Override
+ public int size() {
+ return ids.size();
+ }
+
+ @Override
+ public boolean contains(DBIDRef o) {
+ return ids.contains(o);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return ids.isEmpty();
+ }
+ }
+
+ @Override
+ public SimpleTypeInformation<?>[] getOutputType() {
+ return new SimpleTypeInformation[] { new SimpleTypeInformation<>(COPACModel.class) };
+ }
+
+ /**
+ * Instance for a particular data set.
+ *
+ * @author Erich Schubert
+ */
+ public static class Instance extends AbstractRangeQueryNeighborPredicate.Instance<COPACModel, COPACModel> {
+ /**
+ * Constructor.
+ *
+ * @param ids IDs this is defined for.
+ * @param storage Stored models
+ */
+ public Instance(DBIDs ids, DataStore<COPACModel> storage) {
+ super(ids, storage);
+ }
+
+ @Override
+ public COPACModel getNeighbors(DBIDRef reference) {
+ final COPACModel asymmetric = storage.get(reference);
+ // We use empty models for noise (full-dimensional).
+ if(asymmetric.ids.size() <= 0) {
+ return asymmetric;
+ }
+ // Check for mutual preference reachability:
+ HashSetModifiableDBIDs ids = DBIDUtil.newHashSet(asymmetric.ids.size());
+ for(DBIDIter neighbor = asymmetric.ids.iter(); neighbor.valid(); neighbor.advance()) {
+ final COPACModel nmodel = storage.get(neighbor);
+ // Check correlation dimensionality and mutual reachability
+ if(nmodel.cdim == asymmetric.cdim && nmodel.ids.contains(reference)) {
+ ids.add(neighbor);
+ }
+ }
+ return new COPACModel(asymmetric.cdim, ids);
+ }
+
+ @Override
+ public void addDBIDs(ModifiableDBIDs ids, COPACModel neighbors) {
+ ids.addDBIDs(neighbors.ids);
+ }
+
+ /**
+ * Get the correlation dimensionality of a single object.
+ *
+ * @param id Object ID
+ * @return correlation dimensionality
+ */
+ public int dimensionality(DBIDRef id) {
+ return storage.get(id).cdim;
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * COPAC settings.
+ */
+ protected COPAC.Settings settings;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ settings = config.tryInstantiate(COPAC.Settings.class);
+ }
+
+ @Override
+ protected COPACNeighborPredicate<V> makeInstance() {
+ return new COPACNeighborPredicate<>(settings);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/CorePredicate.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/CorePredicate.java
index 27cc48d6..10f3871e 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/CorePredicate.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/CorePredicate.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan;
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/algorithm/clustering/gdbscan/ERiCNeighborPredicate.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/ERiCNeighborPredicate.java
new file mode 100644
index 00000000..bf152138
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/ERiCNeighborPredicate.java
@@ -0,0 +1,314 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan;
+
+/*
+ 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.algorithm.clustering.correlation.ERiC;
+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.TypeInformation;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
+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.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
+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.distancefunction.minkowski.EuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.logging.statistics.Duration;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
+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.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+
+/**
+ * ERiC neighborhood predicate.
+ *
+ * Reference:
+ * <p>
+ * E. Achtert, C. Böhm, H.-P. Kriegel, P. Kröger, and A. Zimek:<br />
+ * On Exploring Complex Relationships of Correlation Clusters.<br />
+ * In Proc. 19th International Conference on Scientific and Statistical Database
+ * Management (SSDBM 2007), Banff, Canada, 2007.
+ * </p>
+ *
+ * TODO: improve performance by allowing index support for finding neighbors
+ * and/or exploiting the data partitioning better.
+ *
+ * @author Elke Achtert
+ * @author Erich Schubert
+ *
+ * @param <V> the type of NumberVector handled by this Algorithm
+ */
+@Reference(authors = "E. Achtert, C. Böhm, H.-P. Kriegel, P. Kröger, and A. Zimek",//
+title = "On Exploring Complex Relationships of Correlation Clusters", //
+booktitle = "Proc. 19th International Conference on Scientific and Statistical Database Management (SSDBM 2007), Banff, Canada, 2007", //
+url = "http://dx.doi.org/10.1109/SSDBM.2007.21")
+public class ERiCNeighborPredicate<V extends NumberVector> implements NeighborPredicate {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(ERiCNeighborPredicate.class);
+
+ /**
+ * ERiC parameters
+ */
+ protected final ERiC.Settings settings;
+
+ /**
+ * Squared delta value.
+ */
+ private double deltasq;
+
+ /**
+ * Constructor.
+ *
+ * @param settings ERiC settings
+ */
+ public ERiCNeighborPredicate(ERiC.Settings settings) {
+ super();
+ this.settings = settings;
+ this.deltasq = settings.delta * settings.delta;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> NeighborPredicate.Instance<T> instantiate(Database database, SimpleTypeInformation<?> type) {
+ Relation<V> relation = database.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
+ return (NeighborPredicate.Instance<T>) instantiate(database, relation);
+ }
+
+ /**
+ * Full instantiation interface.
+ *
+ * @param database Database
+ * @param relation Relation
+ * @return Instance
+ */
+ public Instance instantiate(Database database, Relation<V> relation) {
+ DistanceQuery<V> dq = database.getDistanceQuery(relation, EuclideanDistanceFunction.STATIC);
+ KNNQuery<V> knnq = database.getKNNQuery(dq, settings.k);
+
+ WritableDataStore<PCAFilteredResult> storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, PCAFilteredResult.class);
+
+ Duration time = LOG.newDuration(this.getClass().getName() + ".preprocessing-time").begin();
+ FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress(this.getClass().getName(), relation.size(), LOG) : null;
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ DoubleDBIDList ref = knnq.getKNNForDBID(iditer, settings.k);
+ storage.put(iditer, settings.pca.processQueryResult(ref, relation));
+ LOG.incrementProcessed(progress);
+ }
+ LOG.ensureCompleted(progress);
+ LOG.statistics(time.end());
+ return new Instance(relation.getDBIDs(), storage, relation);
+ }
+
+ @Override
+ public TypeInformation getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_FIELD;
+ }
+
+ @Override
+ public SimpleTypeInformation<?>[] getOutputType() {
+ return new SimpleTypeInformation[] { new SimpleTypeInformation<>(PCAFilteredResult.class) };
+ }
+
+ /**
+ * Instance for a particular data set.
+ *
+ * @author Erich Schubert
+ */
+ public class Instance extends AbstractRangeQueryNeighborPredicate.Instance<DBIDs, PCAFilteredResult> {
+ /**
+ * Vector data relation.
+ */
+ private Relation<? extends NumberVector> relation;
+
+ /**
+ * Constructor.
+ *
+ * @param ids IDs this is defined for.
+ * @param storage Stored models
+ */
+ public Instance(DBIDs ids, DataStore<PCAFilteredResult> storage, Relation<? extends NumberVector> relation) {
+ super(ids, storage);
+ this.relation = relation;
+ }
+
+ @Override
+ public DBIDs getNeighbors(DBIDRef reference) {
+ final PCAFilteredResult pca1 = storage.get(reference);
+ NumberVector v1 = relation.get(reference);
+
+ // Check for mutual preference reachability:
+ HashSetModifiableDBIDs ids = DBIDUtil.newHashSet();
+ for(DBIDIter neighbor = relation.iterDBIDs(); neighbor.valid(); neighbor.advance()) {
+ final PCAFilteredResult pca2 = storage.get(neighbor);
+ NumberVector v2 = relation.get(neighbor);
+ // Check correlation dimensionality and mutual reachability
+ if(strongNeighbors(v1, v2, pca1, pca2)) {
+ ids.add(neighbor);
+ }
+ }
+ return ids;
+ }
+
+ @Override
+ public void addDBIDs(ModifiableDBIDs ids, DBIDs neighbors) {
+ ids.addDBIDs(neighbors);
+ }
+
+ /**
+ * 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 {@code true} when the two vectors are close enough.
+ */
+ public boolean strongNeighbors(NumberVector v1, NumberVector v2, PCAFilteredResult pca1, PCAFilteredResult pca2) {
+ if(pca1.getCorrelationDimension() != pca2.getCorrelationDimension()) {
+ return false;
+ }
+
+ if(!approximatelyLinearDependent(pca1, pca2) || !approximatelyLinearDependent(pca2, pca1)) {
+ return false;
+ }
+
+ Vector v1_minus_v2 = v1.getColumnVector().minusEquals(v2.getColumnVector());
+ return MathUtil.mahalanobisDistance(pca1.similarityMatrix(), v1_minus_v2) <= settings.tau && MathUtil.mahalanobisDistance(pca2.similarityMatrix(), v1_minus_v2) <= settings.tau;
+ }
+
+ /**
+ * 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 {@code true} when the two vectors are close enough.
+ */
+ public boolean weakNeighbors(NumberVector v1, NumberVector v2, PCAFilteredResult pca1, PCAFilteredResult pca2) {
+ if(pca1.getCorrelationDimension() < pca2.getCorrelationDimension()) {
+ return false;
+ }
+
+ if(!approximatelyLinearDependent(pca1, pca2)) {
+ return false;
+ }
+ if(pca1.getCorrelationDimension() == pca2.getCorrelationDimension() && !approximatelyLinearDependent(pca2, pca1)) {
+ return false;
+ }
+
+ Vector v1_minus_v2 = v1.getColumnVector().minusEquals(v2.getColumnVector());
+ if(MathUtil.mahalanobisDistance(pca1.similarityMatrix(), v1_minus_v2) > settings.tau) {
+ return false;
+ }
+ if(pca1.getCorrelationDimension() == pca2.getCorrelationDimension()) {
+ return MathUtil.mahalanobisDistance(pca2.similarityMatrix(), v1_minus_v2) <= settings.tau;
+ }
+ return true;
+ }
+
+ /**
+ * Returns true, if the strong eigenvectors of the two specified PCAs span
+ * up the same space. Note, that the first PCA must have at least as many
+ * 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
+ */
+ protected 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 distsq = v2_i.transposeTimes(v2_i) - v2_i.transposeTimesTimes(m1_czech, v2_i);
+
+ // if so, return false
+ if(distsq > deltasq) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Get the correlation dimensionality of a single object.
+ *
+ * @param id Object ID
+ * @return correlation dimensionality
+ */
+ public int dimensionality(DBIDRef id) {
+ return storage.get(id).getCorrelationDimension();
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * ERiC settings.
+ */
+ protected ERiC.Settings settings;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ settings = config.tryInstantiate(ERiC.Settings.class);
+ }
+
+ @Override
+ protected ERiCNeighborPredicate<V> makeInstance() {
+ return new ERiCNeighborPredicate<>(settings);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/EpsilonNeighborPredicate.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/EpsilonNeighborPredicate.java
index 1b316c7c..7281f2a5 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/EpsilonNeighborPredicate.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/EpsilonNeighborPredicate.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan;
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,17 +32,16 @@ import de.lmu.ifi.dbs.elki.database.Database;
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.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
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.documentation.Reference;
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.DistanceParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
@@ -61,19 +60,19 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @apiviz.has Instance
*
- * @param <D> Distance type
+ * @param <O> object type
*/
@Reference(authors = "M. Ester, H.-P. Kriegel, J. Sander, and X. Xu", title = "A Density-Based Algorithm for Discovering Clusters in Large Spatial Databases with Noise", booktitle = "Proc. 2nd Int. Conf. on Knowledge Discovery and Data Mining (KDD '96), Portland, OR, 1996", url = "http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.71.1980")
-public class EpsilonNeighborPredicate<O, D extends Distance<D>> implements NeighborPredicate {
+public class EpsilonNeighborPredicate<O> implements NeighborPredicate {
/**
* Range to query with
*/
- protected D epsilon;
+ protected double epsilon;
/**
* Distance function to use
*/
- protected DistanceFunction<O, D> distFunc;
+ protected DistanceFunction<? super O> distFunc;
/**
* Full constructor.
@@ -81,7 +80,7 @@ public class EpsilonNeighborPredicate<O, D extends Distance<D>> implements Neigh
* @param epsilon Epsilon value
* @param distFunc Distance function to use
*/
- public EpsilonNeighborPredicate(D epsilon, DistanceFunction<O, D> distFunc) {
+ public EpsilonNeighborPredicate(double epsilon, DistanceFunction<? super O> distFunc) {
super();
this.epsilon = epsilon;
this.distFunc = distFunc;
@@ -90,9 +89,9 @@ public class EpsilonNeighborPredicate<O, D extends Distance<D>> implements Neigh
@SuppressWarnings("unchecked")
@Override
public <T> NeighborPredicate.Instance<T> instantiate(Database database, SimpleTypeInformation<?> type) {
- DistanceQuery<O, D> dq = QueryUtil.getDistanceQuery(database, distFunc);
- RangeQuery<O, D> rq = database.getRangeQuery(dq);
- return (NeighborPredicate.Instance<T>) new Instance<>(epsilon, rq, dq.getRelation().getDBIDs());
+ DistanceQuery<O> dq = QueryUtil.getDistanceQuery(database, distFunc);
+ RangeQuery<O> rq = database.getRangeQuery(dq);
+ return (NeighborPredicate.Instance<T>) new Instance(epsilon, rq, dq.getRelation().getDBIDs());
}
@Override
@@ -110,16 +109,16 @@ public class EpsilonNeighborPredicate<O, D extends Distance<D>> implements Neigh
*
* @author Erich Schubert
*/
- public static class Instance<D extends Distance<D>> implements NeighborPredicate.Instance<DistanceDBIDList<D>> {
+ public static class Instance implements NeighborPredicate.Instance<DoubleDBIDList> {
/**
* Range to query with
*/
- D epsilon;
+ double epsilon;
/**
* Range query to use on the database.
*/
- RangeQuery<?, D> rq;
+ RangeQuery<?> rq;
/**
* DBIDs to process
@@ -133,7 +132,7 @@ public class EpsilonNeighborPredicate<O, D extends Distance<D>> implements Neigh
* @param rq Range query to use
* @param ids DBIDs to process
*/
- public Instance(D epsilon, RangeQuery<?, D> rq, DBIDs ids) {
+ public Instance(double epsilon, RangeQuery<?> rq, DBIDs ids) {
super();
this.epsilon = epsilon;
this.rq = rq;
@@ -146,12 +145,12 @@ public class EpsilonNeighborPredicate<O, D extends Distance<D>> implements Neigh
}
@Override
- public DistanceDBIDList<D> getNeighbors(DBIDRef reference) {
+ public DoubleDBIDList getNeighbors(DBIDRef reference) {
return rq.getRangeForDBID(reference, epsilon);
}
@Override
- public void addDBIDs(ModifiableDBIDs ids, DistanceDBIDList<D> neighbors) {
+ public void addDBIDs(ModifiableDBIDs ids, DoubleDBIDList neighbors) {
ids.addDBIDs(neighbors);
}
}
@@ -162,37 +161,37 @@ public class EpsilonNeighborPredicate<O, D extends Distance<D>> implements Neigh
* @author Erich Schubert
*
* @apiviz.exclude
+ *
+ * @param <O> object type
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractParameterizer {
+ public static class Parameterizer<O> extends AbstractParameterizer {
/**
* Range to query with
*/
- D epsilon;
+ double epsilon;
/**
* Distance function to use
*/
- DistanceFunction<O, D> distfun = null;
+ DistanceFunction<O> distfun = null;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
// Get a distance function.
- ObjectParameter<DistanceFunction<O, D>> distanceP = new ObjectParameter<>(DistanceBasedAlgorithm.DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
- D distanceFactory = null;
+ ObjectParameter<DistanceFunction<O>> distanceP = new ObjectParameter<>(DistanceBasedAlgorithm.DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
if(config.grab(distanceP)) {
distfun = distanceP.instantiateClass(config);
- distanceFactory = distfun.getDistanceFactory();
}
// Get the epsilon parameter
- DistanceParameter<D> epsilonP = new DistanceParameter<>(DBSCAN.Parameterizer.EPSILON_ID, distanceFactory);
+ DoubleParameter epsilonP = new DoubleParameter(DBSCAN.Parameterizer.EPSILON_ID);
if(config.grab(epsilonP)) {
epsilon = epsilonP.getValue();
}
}
@Override
- protected EpsilonNeighborPredicate<O, D> makeInstance() {
+ protected EpsilonNeighborPredicate<O> makeInstance() {
return new EpsilonNeighborPredicate<>(epsilon, distfun);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/FourCCorePredicate.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/FourCCorePredicate.java
new file mode 100644
index 00000000..c2d9feab
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/FourCCorePredicate.java
@@ -0,0 +1,133 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan;
+
+/*
+ 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.algorithm.clustering.correlation.FourC;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.PreDeConNeighborPredicate.PreDeConModel;
+import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+
+/**
+ * The PreDeCon core point predicate -- having at least minpts. neighbors, and a
+ * maximum preference dimensionality of lambda.
+ *
+ * <p>
+ * Reference:
+ * <p>
+ * C. Böhm, K. Kailing, P. Kröger, A. Zimek:<br />
+ * Computing Clusters of Correlation Connected Objects. <br>
+ * In Proc. ACM SIGMOD Int. Conf. on Management of Data, Paris, France, 2004.
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has Instance
+ */
+@Reference(authors = "C. Böhm, K. Kailing, P. Kröger, A. Zimek", //
+title = "Computing Clusters of Correlation Connected Objects", //
+booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data, Paris, France, 2004, 455-466", //
+url = "http://dx.doi.org/10.1145/1007568.1007620")
+public class FourCCorePredicate implements CorePredicate {
+ /**
+ * The PreDeCon settings class.
+ */
+ protected FourC.Settings settings;
+
+ /**
+ * Default constructor.
+ *
+ * @param settings PreDeCon settings
+ */
+ public FourCCorePredicate(FourC.Settings settings) {
+ super();
+ this.settings = settings;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> CorePredicate.Instance<T> instantiate(Database database, SimpleTypeInformation<?> type) {
+ return (CorePredicate.Instance<T>) new Instance(settings);
+ }
+
+ @Override
+ public boolean acceptsType(SimpleTypeInformation<?> type) {
+ return (type.getRestrictionClass().isAssignableFrom(PreDeConModel.class));
+ }
+
+ /**
+ * Instance for a particular data set.
+ *
+ * @author Erich Schubert
+ */
+ public static class Instance implements CorePredicate.Instance<PreDeConModel> {
+ /**
+ * The PreDeCon settings class.
+ */
+ protected FourC.Settings settings;
+
+ /**
+ * Constructor for this predicate.
+ *
+ * @param settings PreDeCon settings
+ */
+ public Instance(FourC.Settings settings) {
+ super();
+ this.settings = settings;
+ }
+
+ @Override
+ public boolean isCorePoint(DBIDRef point, PreDeConModel model) {
+ return (model.pdim <= settings.lambda) && (model.ids.size() >= settings.minpts);
+ }
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * The PreDeCon settings class.
+ */
+ protected FourC.Settings settings;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ settings = config.tryInstantiate(FourC.Settings.class);
+ }
+
+ @Override
+ protected FourCCorePredicate makeInstance() {
+ return new FourCCorePredicate(settings);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/FourCNeighborPredicate.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/FourCNeighborPredicate.java
new file mode 100644
index 00000000..e620e9e0
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/FourCNeighborPredicate.java
@@ -0,0 +1,240 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan;
+
+/*
+ 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.algorithm.clustering.correlation.FourC;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.PreDeConNeighborPredicate.PreDeConModel;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.QueryUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStore;
+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.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
+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.distancefunction.minkowski.EuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.MeanVariance;
+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.LimitEigenPairFilter;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredResult;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredRunner;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.StandardCovarianceMatrixBuilder;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+
+/**
+ * 4C identifies local subgroups of data objects sharing a uniform correlation.
+ * The algorithm is based on a combination of PCA and density-based clustering
+ * (DBSCAN).
+ * <p>
+ * Reference: Christian Böhm, Karin Kailing, Peer Kröger, Arthur Zimek:
+ * Computing Clusters of Correlation Connected Objects. <br>
+ * In Proc. ACM SIGMOD Int. Conf. on Management of Data, Paris, France, 2004.
+ * </p>
+ *
+ * @author Arthur Zimek
+ * @author Erich Schubert
+ *
+ * @param <V> the type of NumberVector handled by this Algorithm
+ */
+@Reference(authors = "C. Böhm, K. Kailing, P. Kröger, A. Zimek", //
+title = "Computing Clusters of Correlation Connected Objects", //
+booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data, Paris, France, 2004, 455-466", //
+url = "http://dx.doi.org/10.1145/1007568.1007620")
+public class FourCNeighborPredicate<V extends NumberVector> extends AbstractRangeQueryNeighborPredicate<V, PreDeConNeighborPredicate.PreDeConModel> {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(FourCNeighborPredicate.class);
+
+ /**
+ * 4C settings class.
+ */
+ private FourC.Settings settings;
+
+ /**
+ * Tool to help with parameterization.
+ */
+ private MeanVariance mvSize = new MeanVariance(), mvSize2 = new MeanVariance(), mvCorDim = new MeanVariance();
+
+ /**
+ * The Filtered PCA Runner
+ */
+ private PCAFilteredRunner pca;
+
+ /**
+ * Constructor.
+ *
+ * @param settings 4C settings
+ */
+ public FourCNeighborPredicate(FourC.Settings settings) {
+ super(settings.epsilon, EuclideanDistanceFunction.STATIC);
+ this.settings = settings;
+ this.pca = new PCAFilteredRunner(new StandardCovarianceMatrixBuilder(), new LimitEigenPairFilter(settings.delta, settings.absolute), settings.kappa, 1);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> NeighborPredicate.Instance<T> instantiate(Database database, SimpleTypeInformation<?> type) {
+ DistanceQuery<V> dq = QueryUtil.getDistanceQuery(database, distFunc);
+ Relation<V> relation = (Relation<V>) dq.getRelation();
+ RangeQuery<V> rq = database.getRangeQuery(dq);
+ mvSize.reset();
+ mvSize2.reset();
+ mvCorDim.reset();
+ DataStore<PreDeConModel> storage = preprocess(PreDeConModel.class, relation, rq);
+ if(LOG.isVerbose()) {
+ LOG.verbose("Average neighborhood size: " + mvSize.toString());
+ LOG.verbose("Average correlation dimensionality: " + mvCorDim.toString());
+ LOG.verbose("Average correlated neighborhood size: " + mvSize2.toString());
+ final int dim = RelationUtil.dimensionality(relation);
+ if(mvSize.getMean() < 5 * dim) {
+ LOG.verbose("The epsilon parameter may be chosen too small.");
+ }
+ else if(mvSize.getMean() > .5 * relation.size()) {
+ LOG.verbose("The epsilon parameter may be chosen too large.");
+ }
+ else if(mvSize2.getMean() < 10) {
+ LOG.verbose("The epsilon parameter may be chosen too large, or delta too small.");
+ }
+ else if(mvSize2.getMean() < settings.minpts) {
+ LOG.verbose("The minPts parameter may be chosen too large.");
+ }
+ else {
+ LOG.verbose("As a first guess, you can try minPts < " + ((int) mvSize2.getMean()) //
+ + ", but you will need to experiment with these parameters and epsilon.");
+ }
+ }
+ return (NeighborPredicate.Instance<T>) new Instance(dq.getRelation().getDBIDs(), storage);
+ }
+
+ @Override
+ protected PreDeConModel computeLocalModel(DBIDRef id, DoubleDBIDList neighbors, Relation<V> relation) {
+ mvSize.put(neighbors.size());
+ PCAFilteredResult pcares = pca.processIds(neighbors, relation);
+ int cordim = pcares.getCorrelationDimension();
+ Matrix m_hat = pcares.similarityMatrix();
+
+ Vector obj = relation.get(id).getColumnVector();
+
+ // To save computing the square root below.
+ double sqeps = settings.epsilon * settings.epsilon;
+
+ HashSetModifiableDBIDs survivors = DBIDUtil.newHashSet(neighbors.size());
+ for(DBIDIter iter = neighbors.iter(); iter.valid(); iter.advance()) {
+ // Compute weighted / projected distance:
+ Vector diff = relation.get(iter).getColumnVector().minusEquals(obj);
+ double dist = diff.transposeTimesTimes(m_hat, diff);
+ if(dist <= sqeps) {
+ survivors.add(iter);
+ }
+ }
+ if (cordim <= settings.lambda) {
+ mvSize2.put(survivors.size());
+ }
+ mvCorDim.put(cordim);
+
+ return new PreDeConModel(cordim, survivors);
+ }
+
+ @Override
+ Logging getLogger() {
+ return LOG;
+ }
+
+ @Override
+ public SimpleTypeInformation<?>[] getOutputType() {
+ return new SimpleTypeInformation[] { new SimpleTypeInformation<>(PreDeConModel.class) };
+ }
+
+ /**
+ * Instance for a particular data set.
+ *
+ * @author Erich Schubert
+ */
+ public static class Instance extends AbstractRangeQueryNeighborPredicate.Instance<PreDeConModel, PreDeConModel> {
+ /**
+ * Constructor.
+ *
+ * @param ids IDs this is defined for.
+ * @param storage Stored models
+ */
+ public Instance(DBIDs ids, DataStore<PreDeConModel> storage) {
+ super(ids, storage);
+ }
+
+ @Override
+ public PreDeConModel getNeighbors(DBIDRef reference) {
+ final PreDeConModel asymmetric = storage.get(reference);
+ // Check for mutual preference reachability:
+ HashSetModifiableDBIDs ids = DBIDUtil.newHashSet(asymmetric.ids.size());
+ for(DBIDIter neighbor = asymmetric.ids.iter(); neighbor.valid(); neighbor.advance()) {
+ if(storage.get(neighbor).ids.contains(reference)) {
+ ids.add(neighbor);
+ }
+ }
+ return new PreDeConModel(asymmetric.pdim, ids);
+ }
+
+ @Override
+ public void addDBIDs(ModifiableDBIDs ids, PreDeConModel neighbors) {
+ ids.addDBIDs(neighbors.ids);
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<O extends NumberVector> extends AbstractParameterizer {
+ /**
+ * 4C settings.
+ */
+ protected FourC.Settings settings;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ settings = config.tryInstantiate(FourC.Settings.class);
+ }
+
+ @Override
+ protected FourCNeighborPredicate<O> makeInstance() {
+ return new FourCNeighborPredicate<>(settings);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/GeneralizedDBSCAN.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/GeneralizedDBSCAN.java
index 1e0a8642..9c8d0e48 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/GeneralizedDBSCAN.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/GeneralizedDBSCAN.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan;
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
@@ -76,7 +76,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.composedOf CorePredicate
* @apiviz.composedOf NeighborPredicate
*/
-@Reference(authors = "Jörg Sander, Martin Ester, Hans-Peter Kriegel, Xiaowei Xu", title = "Density-Based Clustering in Spatial Databases: The Algorithm GDBSCAN and Its Applications", booktitle = "Data Mining and Knowledge Discovery", url = "http://dx.doi.org/10.1023/A:1009745219419")
+@Reference(authors = "Jörg Sander, Martin Ester, Hans-Peter Kriegel, Xiaowei Xu", //
+title = "Density-Based Clustering in Spatial Databases: The Algorithm GDBSCAN and Its Applications", //
+booktitle = "Data Mining and Knowledge Discovery", //
+url = "http://dx.doi.org/10.1023/A:1009745219419")
public class GeneralizedDBSCAN extends AbstractAlgorithm<Clustering<Model>> implements ClusteringAlgorithm<Clustering<Model>> {
/**
* Get a logger for this algorithm
@@ -114,8 +117,8 @@ public class GeneralizedDBSCAN extends AbstractAlgorithm<Clustering<Model>> impl
@Override
public Clustering<Model> run(Database database) {
- for (SimpleTypeInformation<?> t : npred.getOutputType()) {
- if (corepred.acceptsType(t)) {
+ for(SimpleTypeInformation<?> t : npred.getOutputType()) {
+ if(corepred.acceptsType(t)) {
return new Instance<>(npred.instantiate(database, t), corepred.instantiate(database, t), coremodel).run();
}
}
@@ -140,16 +143,16 @@ public class GeneralizedDBSCAN extends AbstractAlgorithm<Clustering<Model>> impl
* @apiviz.composedOf CorePredicate.Instance
* @apiviz.composedOf NeighborPredicate.Instance
*/
- public class Instance<T> {
+ public static class Instance<T> {
/**
* Unprocessed IDs
*/
- private static final int UNPROCESSED = 0;
+ protected static final int UNPROCESSED = 0;
/**
* Noise IDs
*/
- private static final int NOISE = 1;
+ protected static final int NOISE = 1;
/**
* The neighborhood predicate
@@ -159,7 +162,7 @@ public class GeneralizedDBSCAN extends AbstractAlgorithm<Clustering<Model>> impl
/**
* The core object property
*/
- final CorePredicate.Instance<T> corepred;
+ final CorePredicate.Instance<? super T> corepred;
/**
* Track which objects are "core" objects.
@@ -173,7 +176,7 @@ public class GeneralizedDBSCAN extends AbstractAlgorithm<Clustering<Model>> impl
* @param corepred Core object predicate
* @param coremodel Keep track of core points.
*/
- public Instance(NeighborPredicate.Instance<T> npred, CorePredicate.Instance<T> corepred, boolean coremodel) {
+ public Instance(NeighborPredicate.Instance<T> npred, CorePredicate.Instance<? super T> corepred, boolean coremodel) {
super();
this.npred = npred;
this.corepred = corepred;
@@ -201,69 +204,65 @@ public class GeneralizedDBSCAN extends AbstractAlgorithm<Clustering<Model>> impl
// reduced memory use in the HashMap!
int clusterid = NOISE + 1;
// Iterate over all objects in the database.
- for (DBIDIter id = ids.iter(); id.valid(); id.advance()) {
+ for(DBIDIter id = ids.iter(); id.valid(); id.advance()) {
// Skip already processed ids.
- if (clusterids.intValue(id) != UNPROCESSED) {
+ if(clusterids.intValue(id) != UNPROCESSED) {
continue;
}
// Evaluate Neighborhood predicate
final T neighbors = npred.getNeighbors(id);
// Evaluate Core-Point predicate:
- if (corepred.isCorePoint(id, neighbors)) {
+ if(corepred.isCorePoint(id, neighbors)) {
clusterids.putInt(id, clusterid);
clustersizes.add(expandCluster(clusterid, clusterids, neighbors, progress));
// start next cluster on next iteration.
++clusterid;
- if (clusprogress != null) {
+ if(clusprogress != null) {
clusprogress.setProcessed(clusterid, LOG);
}
- } else {
+ }
+ else {
// otherwise, it's a noise point
clusterids.putInt(id, NOISE);
clustersizes.set(NOISE, clustersizes.get(NOISE) + 1);
}
// We've completed this element
- if (progress != null) {
- progress.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(progress);
}
// Finish progress logging.
- if (progress != null) {
- progress.ensureCompleted(LOG);
- }
- if (clusprogress != null) {
- clusprogress.setCompleted(LOG);
- }
+ LOG.ensureCompleted(progress);
+ LOG.setCompleted(clusprogress);
// Transform cluster ID mapping into a clustering result:
ArrayList<ArrayModifiableDBIDs> clusterlists = new ArrayList<>(clusterid);
ArrayList<ArrayModifiableDBIDs> corelists = coremodel ? new ArrayList<ArrayModifiableDBIDs>(clusterid) : null;
// add storage containers for clusters
- for (int i = 0; i < clustersizes.size(); i++) {
+ for(int i = 0; i < clustersizes.size(); i++) {
clusterlists.add(DBIDUtil.newArray(clustersizes.get(i)));
- if (corelists != null) {
+ if(corelists != null) {
corelists.add(DBIDUtil.newArray(clustersizes.get(i)));
}
}
// do the actual inversion
- for (DBIDIter id = ids.iter(); id.valid(); id.advance()) {
+ for(DBIDIter id = ids.iter(); id.valid(); id.advance()) {
// Negative values are non-core points:
int cid = clusterids.intValue(id);
int cluster = Math.abs(cid);
clusterlists.get(cluster).add(id);
- if (corelists != null && cid > NOISE) {
+ if(corelists != null && cid > NOISE) {
corelists.get(cluster).add(id);
}
}
clusterids.destroy();
Clustering<Model> result = new Clustering<>("GDBSCAN", "gdbscan-clustering");
- for (int cid = NOISE; cid < clusterlists.size(); cid++) {
+ for(int cid = NOISE; cid < clusterlists.size(); cid++) {
boolean isNoise = (cid == NOISE);
Cluster<Model> c;
- if (corelists != null) {
+ if(corelists != null) {
c = new Cluster<Model>(clusterlists.get(cid), isNoise, new CoreObjectsModel(corelists.get(cid)));
- } else {
+ }
+ else {
c = new Cluster<Model>(clusterlists.get(cid), isNoise, ClusterModel.CLUSTER);
}
result.addToplevelCluster(c);
@@ -287,32 +286,32 @@ public class GeneralizedDBSCAN extends AbstractAlgorithm<Clustering<Model>> impl
npred.addDBIDs(activeSet, neighbors);
// run expandCluster as long as this set is non-empty (non-recursive
// implementation)
- while (!activeSet.isEmpty()) {
+ while(!activeSet.isEmpty()) {
final DBID id = activeSet.remove(activeSet.size() - 1);
// Assign object to cluster
final int oldclus = clusterids.intValue(id);
- if (oldclus == NOISE) {
+ if(oldclus == NOISE) {
clustersize += 1;
// Non core point cluster member:
clusterids.putInt(id, -clusterid);
- } else if (oldclus == UNPROCESSED) {
+ }
+ else if(oldclus == UNPROCESSED) {
clustersize += 1;
// expandCluster again:
// Evaluate Neighborhood predicate
final T newneighbors = npred.getNeighbors(id);
// Evaluate Core-Point predicate
- if (corepred.isCorePoint(id, newneighbors)) {
+ if(corepred.isCorePoint(id, newneighbors)) {
// Note: the recursion is unrolled into iteration over the active
// set.
npred.addDBIDs(activeSet, newneighbors);
clusterids.putInt(id, clusterid);
- } else {
+ }
+ else {
// Non core point cluster member:
clusterids.putInt(id, -clusterid);
}
- if (progress != null) {
- progress.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(progress);
}
}
return clustersize;
@@ -361,18 +360,18 @@ public class GeneralizedDBSCAN extends AbstractAlgorithm<Clustering<Model>> impl
protected void makeOptions(Parameterization config) {
// Neighborhood predicate
ObjectParameter<NeighborPredicate> npredOpt = new ObjectParameter<>(NEIGHBORHOODPRED_ID, NeighborPredicate.class, EpsilonNeighborPredicate.class);
- if (config.grab(npredOpt)) {
+ if(config.grab(npredOpt)) {
npred = npredOpt.instantiateClass(config);
}
// Core point predicate
ObjectParameter<CorePredicate> corepredOpt = new ObjectParameter<>(COREPRED_ID, CorePredicate.class, MinPtsCorePredicate.class);
- if (config.grab(corepredOpt)) {
+ if(config.grab(corepredOpt)) {
corepred = corepredOpt.instantiateClass(config);
}
Flag coremodelOpt = new Flag(COREMODEL_ID);
- if (config.grab(coremodelOpt)) {
+ if(config.grab(coremodelOpt)) {
coremodel = coremodelOpt.isTrue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/LSDBC.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/LSDBC.java
new file mode 100644
index 00000000..f1cc5402
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/LSDBC.java
@@ -0,0 +1,351 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan;
+
+/*
+ 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 gnu.trove.list.array.TIntArrayList;
+
+import java.util.ArrayList;
+
+import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm;
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.ClusterModel;
+import de.lmu.ifi.dbs.elki.data.model.Model;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
+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.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+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.database.relation.RelationUtil;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
+import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
+import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+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;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+
+/**
+ * Locally scaled Density Based Clustering.
+ *
+ * This is a variant of DBSCAN which starts with the most dense point first,
+ * then expands clusters until density has dropped below a threshold.
+ *
+ * Reference:
+ * <p>
+ * E. Biçici and D. Yuret<br />
+ * Locally Scaled Density Based Clustering<br />
+ * Adaptive and Natural Computing Algorithms<br />
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Object type
+ */
+@Reference(authors = "E. Biçici and D. Yuret", //
+title = "Locally Scaled Density Based Clustering", //
+booktitle = "Adaptive and Natural Computing Algorithms", //
+url = "http://dx.doi.org/10.1007/978-3-540-71618-1_82")
+public class LSDBC<O extends NumberVector> extends AbstractDistanceBasedAlgorithm<O, Clustering<Model>> implements ClusteringAlgorithm<Clustering<Model>> {
+ /**
+ * Class logger.
+ */
+ private static Logging LOG = Logging.getLogger(LSDBC.class);
+
+ /**
+ * kNN parameter.
+ */
+ protected int k;
+
+ /**
+ * Alpha parameter.
+ */
+ protected double alpha;
+
+ /**
+ * Constants used internally.
+ */
+ protected static int UNPROCESSED = GeneralizedDBSCAN.Instance.UNPROCESSED, //
+ NOISE = GeneralizedDBSCAN.Instance.NOISE;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function to use
+ * @param k Neighborhood size parameter
+ * @param alpha Alpha parameter
+ */
+ public LSDBC(DistanceFunction<? super O> distanceFunction, int k, double alpha) {
+ super(distanceFunction);
+ this.k = k + 1; // Skip query point
+ this.alpha = alpha;
+ }
+
+ /**
+ * Run the LSDBC algorithm
+ *
+ * @param database Database to process
+ * @param relation Data relation
+ * @return Clustering result
+ */
+ public Clustering<Model> run(Database database, Relation<O> relation) {
+ StepProgress stepprog = LOG.isVerbose() ? new StepProgress("LSDBC", 3) : null;
+ final int dim = RelationUtil.dimensionality(relation);
+ final double factor = Math.pow(2., alpha / dim);
+
+ final DBIDs ids = relation.getDBIDs();
+ LOG.beginStep(stepprog, 1, "Materializing kNN neighborhoods");
+ KNNQuery<O> knnq = DatabaseUtil.precomputedKNNQuery(database, relation, getDistanceFunction(), k);
+
+ LOG.beginStep(stepprog, 2, "Sorting by density");
+ WritableDoubleDataStore dens = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
+ fillDensities(knnq, ids, dens);
+ ArrayModifiableDBIDs sids = DBIDUtil.newArray(ids);
+ sids.sort(new DataStoreUtil.AscendingByDoubleDataStore(dens));
+
+ LOG.beginStep(stepprog, 3, "Computing clusters");
+ // Setup progress logging
+ final FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("LSDBC Clustering", ids.size(), LOG) : null;
+ final IndefiniteProgress clusprogress = LOG.isVerbose() ? new IndefiniteProgress("Number of clusters found", LOG) : null;
+ // (Temporary) store the cluster ID assigned.
+ final WritableIntegerDataStore clusterids = DataStoreUtil.makeIntegerStorage(ids, DataStoreFactory.HINT_TEMP, UNPROCESSED);
+ // Note: these are not exact, as objects may be stolen from noise.
+ final TIntArrayList clustersizes = new TIntArrayList();
+ clustersizes.add(0); // Unprocessed dummy value.
+ clustersizes.add(0); // Noise counter.
+
+ // Implementation Note: using Integer objects should result in
+ // reduced memory use in the HashMap!
+ int clusterid = NOISE + 1;
+ // Iterate over all objects in the database.
+ for(DBIDIter id = sids.iter(); id.valid(); id.advance()) {
+ // Skip already processed ids.
+ if(clusterids.intValue(id) != UNPROCESSED) {
+ continue;
+ }
+ // Evaluate Neighborhood predicate
+ final KNNList neighbors = knnq.getKNNForDBID(id, k);
+ // Evaluate Core-Point predicate:
+ if(isLocalMaximum(neighbors.getKNNDistance(), neighbors, dens)) {
+ double mindens = factor * neighbors.getKNNDistance();
+ clusterids.putInt(id, clusterid);
+ clustersizes.add(expandCluster(clusterid, clusterids, knnq, neighbors, mindens, progress));
+ // start next cluster on next iteration.
+ ++clusterid;
+ if(clusprogress != null) {
+ clusprogress.setProcessed(clusterid, LOG);
+ }
+ }
+ else {
+ // otherwise, it's a noise point
+ clusterids.putInt(id, NOISE);
+ clustersizes.set(NOISE, clustersizes.get(NOISE) + 1);
+ }
+ // We've completed this element
+ LOG.incrementProcessed(progress);
+ }
+ // Finish progress logging.
+ LOG.ensureCompleted(progress);
+ LOG.setCompleted(clusprogress);
+
+ LOG.setCompleted(stepprog);
+
+ // Transform cluster ID mapping into a clustering result:
+ ArrayList<ArrayModifiableDBIDs> clusterlists = new ArrayList<>(clusterid);
+ // add storage containers for clusters
+ for(int i = 0; i < clustersizes.size(); i++) {
+ clusterlists.add(DBIDUtil.newArray(clustersizes.get(i)));
+ }
+ // do the actual inversion
+ for(DBIDIter id = ids.iter(); id.valid(); id.advance()) {
+ // Negative values are non-core points:
+ int cid = clusterids.intValue(id);
+ int cluster = Math.abs(cid);
+ clusterlists.get(cluster).add(id);
+ }
+ clusterids.destroy();
+
+ Clustering<Model> result = new Clustering<>("LSDBC", "lsdbc-clustering");
+ for(int cid = NOISE; cid < clusterlists.size(); cid++) {
+ boolean isNoise = (cid == NOISE);
+ Cluster<Model> c;
+ c = new Cluster<Model>(clusterlists.get(cid), isNoise, ClusterModel.CLUSTER);
+ result.addToplevelCluster(c);
+ }
+ return result;
+ }
+
+ /**
+ * Test if a point is a local density maximum.
+ *
+ * @param kdist k-distance of current
+ * @param neighbors Neighbor points
+ * @param kdists kNN distances
+ * @return {@code true} when the point is a local maximum
+ */
+ private boolean isLocalMaximum(double kdist, DBIDs neighbors, WritableDoubleDataStore kdists) {
+ for(DBIDIter it = neighbors.iter(); it.valid(); it.advance()) {
+ if(kdists.doubleValue(it) < kdist) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Set-based expand cluster implementation.
+ *
+ * @param clusterid ID of the current cluster.
+ * @param clusterids Current object to cluster mapping.
+ * @param knnq kNNQuery
+ * @param neighbors Neighbors acquired by initial getNeighbors call.
+ * @param maxkdist Maximum k-distance
+ * @param progress Progress logging
+ *
+ * @return cluster size
+ */
+ protected int expandCluster(final int clusterid, final WritableIntegerDataStore clusterids, final KNNQuery<O> knnq, final DBIDs neighbors, final double maxkdist, final FiniteProgress progress) {
+ int clustersize = 1; // initial seed!
+ final ArrayModifiableDBIDs activeSet = DBIDUtil.newArray();
+ activeSet.addDBIDs(neighbors);
+ // run expandCluster as long as this set is non-empty (non-recursive
+ // implementation)
+ while(!activeSet.isEmpty()) {
+ final DBID id = activeSet.remove(activeSet.size() - 1);
+ // Assign object to cluster
+ final int oldclus = clusterids.intValue(id);
+ if(oldclus == NOISE) {
+ clustersize += 1;
+ // Non core point cluster member:
+ clusterids.putInt(id, -clusterid);
+ }
+ else if(oldclus == UNPROCESSED) {
+ clustersize += 1;
+ // expandCluster again:
+ // Evaluate Neighborhood predicate
+ final KNNList newneighbors = knnq.getKNNForDBID(id, k);
+ // Evaluate Core-Point predicate
+ if(newneighbors.getKNNDistance() <= maxkdist) {
+ activeSet.addDBIDs(newneighbors);
+ }
+ clusterids.putInt(id, clusterid);
+ LOG.incrementProcessed(progress);
+ }
+ }
+ return clustersize;
+ }
+
+ /**
+ * Collect all densities into an array for sorting.
+ *
+ * @param knnq kNN query
+ * @param ids DBIDs to process
+ * @param dens Density storage
+ */
+ private void fillDensities(KNNQuery<O> knnq, DBIDs ids, WritableDoubleDataStore dens) {
+ FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Densities", ids.size(), LOG) : null;
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ final KNNList neighbors = knnq.getKNNForDBID(iter, k);
+ dens.putDouble(iter, neighbors.getKNNDistance());
+ LOG.incrementProcessed(prog);
+ }
+ LOG.ensureCompleted(prog);
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<O extends NumberVector> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * Parameter for neighborhood size.
+ */
+ public static final OptionID K_ID = new OptionID("lsdbc.k", "Neighborhood size (k)");
+
+ /**
+ * Parameter for the maximum density difference.
+ */
+ public static final OptionID ALPHA_ID = new OptionID("lsdbc.alpha", "Density difference factor");
+
+ /**
+ * kNN parameter.
+ */
+ protected int k;
+
+ /**
+ * Alpha parameter.
+ */
+ protected double alpha;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ IntParameter kP = new IntParameter(K_ID)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(kP)) {
+ k = kP.intValue();
+ }
+
+ DoubleParameter alphaP = new DoubleParameter(ALPHA_ID) //
+ .addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ if(config.grab(alphaP)) {
+ alpha = alphaP.doubleValue();
+ }
+ }
+
+ @Override
+ protected LSDBC<O> makeInstance() {
+ return new LSDBC<>(distanceFunction, k, alpha);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/MinPtsCorePredicate.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/MinPtsCorePredicate.java
index ac7ba81d..2c5747f7 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/MinPtsCorePredicate.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/MinPtsCorePredicate.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan;
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/algorithm/clustering/gdbscan/NeighborPredicate.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/NeighborPredicate.java
index c3e1e8c9..a4549f2a 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/NeighborPredicate.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/NeighborPredicate.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan;
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/algorithm/clustering/gdbscan/PreDeConCorePredicate.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/PreDeConCorePredicate.java
new file mode 100644
index 00000000..adcde0d0
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/PreDeConCorePredicate.java
@@ -0,0 +1,132 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan;
+
+/*
+ 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.algorithm.clustering.gdbscan.PreDeConNeighborPredicate.PreDeConModel;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.subspace.PreDeCon;
+import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+
+/**
+ * The PreDeCon core point predicate -- having at least minpts. neighbors, and a
+ * maximum preference dimensionality of lambda.
+ *
+ * Reference:
+ * <p>
+ * C. Böhm, K. Kailing, H.-P. Kriegel, P. Kröger:<br />
+ * Density Connected Clustering with Local Subspace Preferences.<br />
+ * In Proc. 4th IEEE Int. Conf. on Data Mining (ICDM'04), Brighton, UK, 2004.
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has Instance
+ */
+@Reference(authors = "C. Böhm, K. Kailing, H.-P. Kriegel, P. Kröger", //
+title = "Density Connected Clustering with Local Subspace Preferences", //
+booktitle = "Proc. 4th IEEE Int. Conf. on Data Mining (ICDM'04), Brighton, UK, 2004", //
+url = "http://dx.doi.org/10.1109/ICDM.2004.10087")
+public class PreDeConCorePredicate implements CorePredicate {
+ /**
+ * The PreDeCon settings class.
+ */
+ protected PreDeCon.Settings settings;
+
+ /**
+ * Default constructor.
+ *
+ * @param settings PreDeCon settings
+ */
+ public PreDeConCorePredicate(PreDeCon.Settings settings) {
+ super();
+ this.settings = settings;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> CorePredicate.Instance<T> instantiate(Database database, SimpleTypeInformation<?> type) {
+ return (CorePredicate.Instance<T>) new Instance(settings);
+ }
+
+ @Override
+ public boolean acceptsType(SimpleTypeInformation<?> type) {
+ return (type.getRestrictionClass().isAssignableFrom(PreDeConModel.class));
+ }
+
+ /**
+ * Instance for a particular data set.
+ *
+ * @author Erich Schubert
+ */
+ public static class Instance implements CorePredicate.Instance<PreDeConModel> {
+ /**
+ * The PreDeCon settings class.
+ */
+ protected PreDeCon.Settings settings;
+
+ /**
+ * Constructor for this predicate.
+ *
+ * @param settings PreDeCon settings
+ */
+ public Instance(PreDeCon.Settings settings) {
+ super();
+ this.settings = settings;
+ }
+
+ @Override
+ public boolean isCorePoint(DBIDRef point, PreDeConModel model) {
+ return (model.pdim <= settings.lambda) && (model.ids.size() >= settings.minpts);
+ }
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * The PreDeCon settings class.
+ */
+ protected PreDeCon.Settings settings;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ settings = config.tryInstantiate(PreDeCon.Settings.class);
+ }
+
+ @Override
+ protected PreDeConCorePredicate makeInstance() {
+ return new PreDeConCorePredicate(settings);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/PreDeConNeighborPredicate.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/PreDeConNeighborPredicate.java
new file mode 100644
index 00000000..09258b43
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/PreDeConNeighborPredicate.java
@@ -0,0 +1,285 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan;
+
+/*
+ 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.algorithm.clustering.subspace.PreDeCon;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.QueryUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStore;
+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.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.SetDBIDs;
+import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
+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.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.MeanVariance;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+
+/**
+ * Neighborhood predicate used by PreDeCon.
+ *
+ * Reference:
+ * <p>
+ * C. Böhm, K. Kailing, H.-P. Kriegel, P. Kröger:<br />
+ * Density Connected Clustering with Local Subspace Preferences.<br />
+ * In Proc. 4th IEEE Int. Conf. on Data Mining (ICDM'04), Brighton, UK, 2004.
+ * </p>
+ *
+ * @author Peer Kröger
+ * @author Erich Schubert
+ *
+ * @param <V> the type of NumberVector handled by this Algorithm
+ */
+@Reference(authors = "C. Böhm, K. Kailing, H.-P. Kriegel, P. Kröger",//
+title = "Density Connected Clustering with Local Subspace Preferences",//
+booktitle = "Proc. 4th IEEE Int. Conf. on Data Mining (ICDM'04), Brighton, UK, 2004",//
+url = "http://dx.doi.org/10.1109/ICDM.2004.10087")
+public class PreDeConNeighborPredicate<V extends NumberVector> extends AbstractRangeQueryNeighborPredicate<V, PreDeConNeighborPredicate.PreDeConModel> {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(PreDeConNeighborPredicate.class);
+
+ /**
+ * Tool to help with parameterization.
+ */
+ private MeanVariance mvSize = new MeanVariance(), mvVar = new MeanVariance();
+
+ /**
+ * PreDeCon settings class.
+ */
+ private PreDeCon.Settings settings;
+
+ /**
+ * Constructor.
+ *
+ * @param settings PreDeCon settings
+ */
+ public PreDeConNeighborPredicate(PreDeCon.Settings settings) {
+ // Note: we use squared epsilon!
+ super(settings.epsilon * settings.epsilon, SquaredEuclideanDistanceFunction.STATIC);
+ this.settings = settings;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> NeighborPredicate.Instance<T> instantiate(Database database, SimpleTypeInformation<?> type) {
+ DistanceQuery<V> dq = QueryUtil.getDistanceQuery(database, distFunc);
+ Relation<V> relation = (Relation<V>) dq.getRelation();
+ RangeQuery<V> rq = database.getRangeQuery(dq);
+ mvSize.reset();
+ mvVar.reset();
+ DataStore<PreDeConModel> storage = preprocess(PreDeConModel.class, relation, rq);
+ if(LOG.isVerbose()) {
+ LOG.verbose("Average neighborhood size: " + mvSize.toString());
+ LOG.verbose("Average variance size: " + mvVar.toString());
+ final int dim = RelationUtil.dimensionality(relation);
+ if(mvSize.getMean() < 5 * dim) {
+ LOG.verbose("The epsilon parameter may be chosen too small.");
+ }
+ else if(mvSize.getMean() > .5 * relation.size()) {
+ LOG.verbose("The epsilon parameter may be chosen too large.");
+ }
+ else {
+ LOG.verbose("As a first guess, you can try minPts < " + ((int) mvSize.getMean() / dim) //
+ + " and delta > " + mvVar.getMean() + //
+ ", but you will need to experiment with these parameters and epsilon.");
+ }
+ }
+ return (NeighborPredicate.Instance<T>) new Instance(dq.getRelation().getDBIDs(), storage);
+ }
+
+ @Override
+ protected PreDeConModel computeLocalModel(DBIDRef id, DoubleDBIDList neighbors, Relation<V> relation) {
+ final int referenceSetSize = neighbors.size();
+ mvSize.put(referenceSetSize);
+
+ // Shouldn't happen:
+ if(referenceSetSize < 0) {
+ LOG.warning("Empty reference set - should at least include the query point!");
+ return new PreDeConModel(Integer.MAX_VALUE, DBIDUtil.EMPTYDBIDS);
+ }
+
+ V obj = relation.get(id);
+ final int dim = obj.getDimensionality();
+
+ // Per-dimension variances:
+ double[] s = new double[dim];
+ for(DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ V o = relation.get(neighbor);
+ for(int d = 0; d < dim; d++) {
+ final double diff = obj.doubleValue(d) - o.doubleValue(d);
+ s[d] += diff * diff;
+ }
+ }
+ // Adjust for sample size
+ for(int d = 0; d < dim; d++) {
+ s[d] /= referenceSetSize;
+ mvVar.put(s[d]);
+ }
+
+ // Preference weight vector
+ double[] weights = new double[dim];
+ int pdim = 0;
+ for(int d = 0; d < dim; d++) {
+ if(s[d] <= settings.delta) {
+ weights[d] = settings.kappa;
+ pdim++;
+ }
+ else {
+ weights[d] = 1.;
+ }
+ }
+
+ // Check which neighbors survive
+ HashSetModifiableDBIDs survivors = DBIDUtil.newHashSet(referenceSetSize);
+ for(DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ V o = relation.get(neighbor);
+ // Weighted Euclidean distance:
+ double dev = 0.;
+ for(int d = 0; d < dim; d++) {
+ final double diff = obj.doubleValue(d) - o.doubleValue(d);
+ dev += weights[d] * diff * diff;
+ }
+ // Note: epsilon was squared - this saves us the sqrt here:
+ if(dev <= epsilon) {
+ survivors.add(neighbor);
+ }
+ }
+
+ return new PreDeConModel(pdim, survivors);
+ }
+
+ @Override
+ Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Model used by PreDeCon for core point property.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class PreDeConModel {
+ /**
+ * Preference dimensionality.
+ */
+ int pdim;
+
+ /**
+ * Neighbor ids.
+ */
+ SetDBIDs ids;
+
+ /**
+ * PreDeCon model.
+ *
+ * @param pdim Preference dimensionality
+ * @param ids Neighbor ids
+ */
+ public PreDeConModel(int pdim, SetDBIDs ids) {
+ super();
+ this.pdim = pdim;
+ this.ids = ids;
+ }
+ }
+
+ @Override
+ public SimpleTypeInformation<?>[] getOutputType() {
+ return new SimpleTypeInformation[] { new SimpleTypeInformation<>(PreDeConModel.class) };
+ }
+
+ /**
+ * Instance for a particular data set.
+ *
+ * @author Erich Schubert
+ */
+ public static class Instance extends AbstractRangeQueryNeighborPredicate.Instance<PreDeConModel, PreDeConModel> {
+ /**
+ * Constructor.
+ *
+ * @param ids IDs this is defined for.
+ * @param storage Stored models
+ */
+ public Instance(DBIDs ids, DataStore<PreDeConModel> storage) {
+ super(ids, storage);
+ }
+
+ @Override
+ public PreDeConModel getNeighbors(DBIDRef reference) {
+ final PreDeConModel asymmetric = storage.get(reference);
+ // Check for mutual preference reachability:
+ HashSetModifiableDBIDs ids = DBIDUtil.newHashSet(asymmetric.ids.size());
+ for(DBIDIter neighbor = asymmetric.ids.iter(); neighbor.valid(); neighbor.advance()) {
+ if(storage.get(neighbor).ids.contains(reference)) {
+ ids.add(neighbor);
+ }
+ }
+ return new PreDeConModel(asymmetric.pdim, ids);
+ }
+
+ @Override
+ public void addDBIDs(ModifiableDBIDs ids, PreDeConModel neighbors) {
+ ids.addDBIDs(neighbors.ids);
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * PreDeCon settings.
+ */
+ protected PreDeCon.Settings settings;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ settings = config.tryInstantiate(PreDeCon.Settings.class);
+ }
+
+ @Override
+ protected PreDeConNeighborPredicate<V> makeInstance() {
+ return new PreDeConNeighborPredicate<>(settings);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/package-info.java
index 7ea3c7e4..aec61cf4 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/gdbscan/package-info.java
@@ -17,12 +17,14 @@
* Applications<br />
* In: Data Mining and Knowledge Discovery, 1998.
* </p>
+ *
+ * @apiviz.exclude .*\.Instance$
*/
/*
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/algorithm/clustering/hierarchical/CentroidLinkageMethod.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/CentroidLinkageMethod.java
index 72b6fb57..f0be669f 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/CentroidLinkageMethod.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/CentroidLinkageMethod.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
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/algorithm/clustering/hierarchical/CompleteLinkageMethod.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/CompleteLinkageMethod.java
index 0cb47fa7..4f205001 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/CompleteLinkageMethod.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/CompleteLinkageMethod.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
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/algorithm/clustering/hierarchical/ExtractFlatClusteringFromHierarchy.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/ExtractFlatClusteringFromHierarchy.java
index f6dbc88f..3a26a96c 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/ExtractFlatClusteringFromHierarchy.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/ExtractFlatClusteringFromHierarchy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
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.algorithm.clustering.hierarchical;
import gnu.trove.list.array.TDoubleArrayList;
import java.util.ArrayList;
-import java.util.Comparator;
import de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm;
import de.lmu.ifi.dbs.elki.data.Cluster;
@@ -35,10 +34,9 @@ import de.lmu.ifi.dbs.elki.data.model.DendrogramModel;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.datastore.DBIDDataStore;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStore;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
-import de.lmu.ifi.dbs.elki.database.datastore.DoubleDistanceDataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.DoubleDataStore;
import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
@@ -48,8 +46,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
@@ -57,7 +53,7 @@ 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.DistanceParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.EnumParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
@@ -75,7 +71,7 @@ import de.lmu.ifi.dbs.elki.workflow.AlgorithmStep;
* @apiviz.uses PointerHierarchyRepresentationResult
* @apiviz.has Clustering
*/
-public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implements ClusteringAlgorithm<Clustering<DendrogramModel<D>>> {
+public class ExtractFlatClusteringFromHierarchy implements ClusteringAlgorithm<Clustering<DendrogramModel>> {
/**
* Class logger.
*/
@@ -119,7 +115,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
/**
* Clustering algorithm to run to obtain the hierarchy.
*/
- private HierarchicalClusteringAlgorithm<D> algorithm;
+ private HierarchicalClusteringAlgorithm algorithm;
/**
* Include empty cluster in the hierarchy produced.
@@ -129,7 +125,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
/**
* Threshold for extracting clusters.
*/
- private D threshold = null;
+ private double threshold;
/**
* Disallow singleton clusters, but add them to the parent cluster instead.
@@ -144,10 +140,10 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
* @param outputmode Output mode: truncated hierarchy or strict partitions.
* @param singletons Allow producing singleton clusters.
*/
- public ExtractFlatClusteringFromHierarchy(HierarchicalClusteringAlgorithm<D> algorithm, int minclusters, OutputMode outputmode, boolean singletons) {
+ public ExtractFlatClusteringFromHierarchy(HierarchicalClusteringAlgorithm algorithm, int minclusters, OutputMode outputmode, boolean singletons) {
super();
this.algorithm = algorithm;
- this.threshold = null;
+ this.threshold = Double.NaN;
this.minclusters = minclusters;
this.outputmode = outputmode;
this.singletons = singletons;
@@ -161,7 +157,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
* @param outputmode Output mode: truncated hierarchy or strict partitions.
* @param singletons Allow producing singleton clusters.
*/
- public ExtractFlatClusteringFromHierarchy(HierarchicalClusteringAlgorithm<D> algorithm, D threshold, OutputMode outputmode, boolean singletons) {
+ public ExtractFlatClusteringFromHierarchy(HierarchicalClusteringAlgorithm algorithm, double threshold, OutputMode outputmode, boolean singletons) {
super();
this.algorithm = algorithm;
this.threshold = threshold;
@@ -171,19 +167,13 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
}
@Override
- public Clustering<DendrogramModel<D>> run(Database database) {
- PointerHierarchyRepresentationResult<D> pointerresult = algorithm.run(database);
+ public Clustering<DendrogramModel> run(Database database) {
+ PointerHierarchyRepresentationResult pointerresult = algorithm.run(database);
DBIDs ids = pointerresult.getDBIDs();
DBIDDataStore pi = pointerresult.getParentStore();
- DataStore<D> lambda = pointerresult.getParentDistanceStore();
+ DoubleDataStore lambda = pointerresult.getParentDistanceStore();
- Clustering<DendrogramModel<D>> result;
- if(lambda instanceof DoubleDistanceDataStore) {
- result = extractClustersDouble(ids, pi, (DoubleDistanceDataStore) lambda);
- }
- else {
- result = extractClusters(ids, pi, lambda);
- }
+ Clustering<DendrogramModel> result = extractClusters(ids, pi, lambda);
result.addChildResult(pointerresult);
return result;
@@ -198,245 +188,14 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
*
* @return Hierarchical clustering
*/
- private Clustering<DendrogramModel<D>> extractClusters(DBIDs ids, final DBIDDataStore pi, final DataStore<D> lambda) {
- FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("Extracting clusters", ids.size(), LOG) : null;
-
- // Sort DBIDs by lambda. We need this for two things:
- // a) to determine the stop distance from "minclusters" parameter
- // b) to process arrows in decreasing / increasing order
- ArrayModifiableDBIDs order = DBIDUtil.newArray(ids);
- order.sort(new CompareByLambda<>(lambda));
- DBIDArrayIter it = order.iter(); // Used multiple times!
-
- int split;
- if(minclusters > 0) {
- split = Math.max(ids.size() - minclusters, 0);
- // Stop distance:
- final D stopdist = lambda.get(order.get(split));
-
- // Tie handling: decrement split.
- while(split > 0) {
- it.seek(split - 1);
- if(stopdist.compareTo(lambda.get(it)) <= 0) {
- split--;
- }
- else {
- break;
- }
- }
- }
- else if(threshold != null) {
- split = ids.size();
- it.seek(split - 1);
- while(threshold.compareTo(lambda.get(it)) <= 0 && it.valid()) {
- split--;
- it.retract();
- }
- }
- else { // full hierarchy
- split = 0;
- }
-
- // Extract the child clusters
- int expcnum = ids.size() - split;
- WritableIntegerDataStore cluster_map = DataStoreUtil.makeIntegerStorage(ids, DataStoreFactory.HINT_TEMP, -1);
- ArrayList<ModifiableDBIDs> cluster_dbids = new ArrayList<>(expcnum);
- ArrayList<D> cluster_dist = new ArrayList<>(expcnum);
- ArrayModifiableDBIDs cluster_leads = DBIDUtil.newArray(expcnum);
-
- DBIDVar succ = DBIDUtil.newVar(); // Variable for successor.
- // Go backwards on the lower part.
- for(it.seek(split - 1); it.valid(); it.retract()) {
- D dist = lambda.get(it); // Distance to successor
- pi.assignVar(it, succ); // succ = pi(it)
- int clusterid = cluster_map.intValue(succ);
- // Successor cluster has already been created:
- if(clusterid >= 0) {
- cluster_dbids.get(clusterid).add(it);
- cluster_map.putInt(it, clusterid);
- // Update distance to maximum encountered:
- if(cluster_dist.get(clusterid).compareTo(dist) < 0) {
- cluster_dist.set(clusterid, dist);
- }
- }
- else {
- // Need to start a new cluster:
- clusterid = cluster_dbids.size(); // next cluster number.
- ModifiableDBIDs cids = DBIDUtil.newArray();
- // Add element and successor as initial members:
- cids.add(succ);
- cluster_map.putInt(succ, clusterid);
- cids.add(it);
- cluster_map.putInt(it, clusterid);
- // Store new cluster.
- cluster_dbids.add(cids);
- cluster_leads.add(succ);
- cluster_dist.add(dist);
- }
-
- // Decrement counter
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
- }
- final Clustering<DendrogramModel<D>> dendrogram;
- switch(outputmode){
- case PARTIAL_HIERARCHY: {
- // Build a hierarchy out of these clusters.
- dendrogram = new Clustering<>("Hierarchical Clustering", "hierarchical-clustering");
- Cluster<DendrogramModel<D>> root = null;
- ArrayList<Cluster<DendrogramModel<D>>> clusters = new ArrayList<>(expcnum);
- // Convert initial clusters to cluster objects
- {
- int i = 0;
- for(DBIDIter it2 = cluster_leads.iter(); it2.valid(); it2.advance(), i++) {
- clusters.add(makeCluster(it2, cluster_dist.get(i), cluster_dbids.get(i)));
- }
- cluster_dist = null; // Invalidate
- cluster_dbids = null; // Invalidate
- }
- // Process the upper part, bottom-up.
- for(it.seek(split); it.valid(); it.advance()) {
- int clusterid = cluster_map.intValue(it);
- // The current cluster led by the current element:
- final Cluster<DendrogramModel<D>> clus;
- if(clusterid >= 0) {
- clus = clusters.get(clusterid);
- }
- else if(!singletons && ids.size() != 1) {
- clus = null;
- }
- else {
- clus = makeCluster(it, null, DBIDUtil.deref(it));
- }
- // The successor to join:
- pi.assignVar(it, succ); // succ = pi(it)
- if(DBIDUtil.equal(it, succ)) {
- assert (root == null);
- root = clus;
- }
- else {
- // Parent cluster:
- int parentid = cluster_map.intValue(succ);
- D depth = lambda.get(it);
- // Parent cluster exists - merge as a new cluster:
- if(parentid >= 0) {
- final Cluster<DendrogramModel<D>> pclus = clusters.get(parentid);
- if(pclus.getModel().getDistance().equals(depth)) {
- if(clus == null) {
- ((ModifiableDBIDs) pclus.getIDs()).add(it);
- }
- else {
- dendrogram.addChildCluster(pclus, clus);
- }
- }
- else {
- // Merge at new depth:
- ModifiableDBIDs cids = DBIDUtil.newArray(clus == null ? 1 : 0);
- if(clus == null) {
- cids.add(it);
- }
- Cluster<DendrogramModel<D>> npclus = makeCluster(succ, depth, cids);
- if(clus != null) {
- dendrogram.addChildCluster(npclus, clus);
- }
- dendrogram.addChildCluster(npclus, pclus);
- // Replace existing parent cluster: new depth
- clusters.set(parentid, npclus);
- }
- }
- else {
- // Merge with parent at this depth:
- final Cluster<DendrogramModel<D>> pclus;
- if(!singletons) {
- ModifiableDBIDs cids = DBIDUtil.newArray(clus == null ? 2 : 1);
- cids.add(succ);
- if(clus == null) {
- cids.add(it);
- }
- // New cluster for parent and/or new point
- pclus = makeCluster(succ, depth, cids);
- }
- else {
- // Create a new, one-element cluster for parent, and a merged
- // cluster on top.
- pclus = makeCluster(succ, depth, DBIDUtil.EMPTYDBIDS);
- dendrogram.addChildCluster(pclus, makeCluster(succ, null, DBIDUtil.deref(succ)));
- }
- if(clus != null) {
- dendrogram.addChildCluster(pclus, clus);
- }
- // Store cluster:
- parentid = clusters.size();
- clusters.add(pclus); // Remember parent cluster
- cluster_map.putInt(succ, parentid); // Reference
- }
- }
-
- // Decrement counter
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
- }
- assert (root != null);
- // attach root
- dendrogram.addToplevelCluster(root);
- break;
- }
- case STRICT_PARTITIONS: {
- // Build a hierarchy out of these clusters.
- dendrogram = new Clustering<>("Flattened Hierarchical Clustering", "flattened-hierarchical-clustering");
- // Convert initial clusters to cluster objects
- {
- int i = 0;
- for(DBIDIter it2 = cluster_leads.iter(); it2.valid(); it2.advance(), i++) {
- dendrogram.addToplevelCluster(makeCluster(it2, cluster_dist.get(i), cluster_dbids.get(i)));
- }
- cluster_dist = null; // Invalidate
- cluster_dbids = null; // Invalidate
- }
- // Process the upper part, bottom-up.
- for(it.seek(split); it.valid(); it.advance()) {
- int clusterid = cluster_map.intValue(it);
- if(clusterid < 0) {
- dendrogram.addToplevelCluster(makeCluster(it, null, DBIDUtil.deref(it)));
- }
-
- // Decrement counter
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
- }
- break;
- }
- default:
- throw new AbortException("Unsupported output mode.");
- }
-
- if(progress != null) {
- progress.ensureCompleted(LOG);
- }
-
- return dendrogram;
- }
-
- /**
- * Extract all clusters from the pi-lambda-representation.
- *
- * @param ids Object ids to process
- * @param pi Pi store
- * @param lambda Lambda store
- *
- * @return Hierarchical clustering
- */
- private Clustering<DendrogramModel<D>> extractClustersDouble(DBIDs ids, final DBIDDataStore pi, final DoubleDistanceDataStore lambda) {
+ private Clustering<DendrogramModel> extractClusters(DBIDs ids, final DBIDDataStore pi, final DoubleDataStore lambda) {
FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("Extracting clusters", ids.size(), LOG) : null;
// Sort DBIDs by lambda. We need this for two things:
// a) to determine the stop distance from "minclusters" parameter
// b) to process arrows in decreasing / increasing order
ArrayModifiableDBIDs order = DBIDUtil.newArray(ids);
- order.sort(new CompareByDoubleLambda(lambda));
+ order.sort(new DataStoreUtil.AscendingByDoubleDataStore(lambda));
DBIDArrayIter it = order.iter(); // Used multiple times!
int split;
@@ -456,11 +215,10 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
}
}
}
- else if(threshold != null) {
+ else if(!Double.isNaN(threshold)) {
split = ids.size();
it.seek(split - 1);
- double stopdist = ((DoubleDistance) threshold).doubleValue();
- while(stopdist <= lambda.doubleValue(it) && it.valid()) {
+ while(threshold <= lambda.doubleValue(it) && it.valid()) {
split--;
it.retract();
}
@@ -507,23 +265,20 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
}
// Decrement counter
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(progress);
}
- final Clustering<DendrogramModel<D>> dendrogram;
+ final Clustering<DendrogramModel> dendrogram;
switch(outputmode){
case PARTIAL_HIERARCHY: {
// Build a hierarchy out of these clusters.
dendrogram = new Clustering<>("Hierarchical Clustering", "hierarchical-clustering");
- Cluster<DendrogramModel<D>> root = null;
- ArrayList<Cluster<DendrogramModel<D>>> clusters = new ArrayList<>(expcnum);
+ Cluster<DendrogramModel> root = null;
+ ArrayList<Cluster<DendrogramModel>> clusters = new ArrayList<>(expcnum);
// Convert initial clusters to cluster objects
{
int i = 0;
for(DBIDIter it2 = cluster_leads.iter(); it2.valid(); it2.advance(), i++) {
- @SuppressWarnings("unchecked")
- D depth = (D) new DoubleDistance(cluster_dist.get(i));
+ double depth = cluster_dist.get(i);
clusters.add(makeCluster(it2, depth, cluster_dbids.get(i)));
}
cluster_dist = null; // Invalidate
@@ -533,7 +288,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
for(it.seek(split); it.valid(); it.advance()) {
int clusterid = cluster_map.intValue(it);
// The current cluster led by the current element:
- final Cluster<DendrogramModel<D>> clus;
+ final Cluster<DendrogramModel> clus;
if(clusterid >= 0) {
clus = clusters.get(clusterid);
}
@@ -541,7 +296,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
clus = null;
}
else {
- clus = makeCluster(it, null, DBIDUtil.deref(it));
+ clus = makeCluster(it, Double.NaN, DBIDUtil.deref(it));
}
// The successor to join:
pi.assignVar(it, succ); // succ = pi(it)
@@ -552,12 +307,11 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
else {
// Parent cluster:
int parentid = cluster_map.intValue(succ);
- @SuppressWarnings("unchecked")
- D depth = (D) new DoubleDistance(lambda.doubleValue(it));
+ double depth = lambda.doubleValue(it);
// Parent cluster exists - merge as a new cluster:
if(parentid >= 0) {
- final Cluster<DendrogramModel<D>> pclus = clusters.get(parentid);
- if(pclus.getModel().getDistance().equals(depth)) {
+ final Cluster<DendrogramModel> pclus = clusters.get(parentid);
+ if(pclus.getModel().getDistance() == depth) {
if(clus == null) {
((ModifiableDBIDs) pclus.getIDs()).add(it);
}
@@ -571,7 +325,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
if(clus == null) {
cids.add(it);
}
- Cluster<DendrogramModel<D>> npclus = makeCluster(succ, depth, cids);
+ Cluster<DendrogramModel> npclus = makeCluster(succ, depth, cids);
if(clus != null) {
dendrogram.addChildCluster(npclus, clus);
}
@@ -582,7 +336,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
}
else {
// Merge with parent at this depth:
- final Cluster<DendrogramModel<D>> pclus;
+ final Cluster<DendrogramModel> pclus;
if(!singletons) {
ModifiableDBIDs cids = DBIDUtil.newArray(clus == null ? 2 : 1);
cids.add(succ);
@@ -596,7 +350,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
// Create a new, one-element cluster for parent, and a merged
// cluster on top.
pclus = makeCluster(succ, depth, DBIDUtil.EMPTYDBIDS);
- dendrogram.addChildCluster(pclus, makeCluster(succ, null, DBIDUtil.deref(succ)));
+ dendrogram.addChildCluster(pclus, makeCluster(succ, Double.NaN, DBIDUtil.deref(succ)));
}
if(clus != null) {
dendrogram.addChildCluster(pclus, clus);
@@ -609,9 +363,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
}
// Decrement counter
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(progress);
}
assert (root != null);
// attach root
@@ -625,8 +377,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
{
int i = 0;
for(DBIDIter it2 = cluster_leads.iter(); it2.valid(); it2.advance(), i++) {
- @SuppressWarnings("unchecked")
- D depth = (D) new DoubleDistance(cluster_dist.get(i));
+ double depth = cluster_dist.get(i);
dendrogram.addToplevelCluster(makeCluster(it2, depth, cluster_dbids.get(i)));
}
cluster_dist = null; // Invalidate
@@ -636,13 +387,11 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
for(it.seek(split); it.valid(); it.advance()) {
int clusterid = cluster_map.intValue(it);
if(clusterid < 0) {
- dendrogram.addToplevelCluster(makeCluster(it, null, DBIDUtil.deref(it)));
+ dendrogram.addToplevelCluster(makeCluster(it, Double.NaN, DBIDUtil.deref(it)));
}
// Decrement counter
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(progress);
}
break;
}
@@ -650,9 +399,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
throw new AbortException("Unsupported output mode.");
}
- if(progress != null) {
- progress.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(progress);
return dendrogram;
}
@@ -665,22 +412,22 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
* @param members Member objects
* @return Cluster
*/
- private Cluster<DendrogramModel<D>> makeCluster(DBIDRef lead, D depth, DBIDs members) {
+ private Cluster<DendrogramModel> makeCluster(DBIDRef lead, double depth, DBIDs members) {
final String name;
if(members.size() == 0) {
name = "mrg_" + DBIDUtil.toString(lead) + "_" + depth;
}
- else if(depth != null && depth.isInfiniteDistance() || (members.size() == 1 && members.contains(lead))) {
+ else if(!Double.isNaN(depth) && Double.isInfinite(depth) || (members.size() == 1 && members.contains(lead))) {
name = "obj_" + DBIDUtil.toString(lead);
}
- else if(depth != null) {
+ else if(!Double.isNaN(depth)) {
name = "clu_" + DBIDUtil.toString(lead) + "_" + depth;
}
else {
// Complete data set only?
name = "clu_" + DBIDUtil.toString(lead);
}
- Cluster<DendrogramModel<D>> cluster = new Cluster<>(name, members, new DendrogramModel<>(depth));
+ Cluster<DendrogramModel> cluster = new Cluster<>(name, members, new DendrogramModel(depth));
return cluster;
}
@@ -690,77 +437,13 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
}
/**
- * Order a DBID collection by the lambda value.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- *
- * @param <D> Distance type
- */
- private static final class CompareByLambda<D extends Distance<D>> implements Comparator<DBIDRef> {
- /**
- * Lambda storage
- */
- private final DataStore<D> lambda;
-
- /**
- * Constructor.
- *
- * @param lambda Lambda storage
- */
- protected CompareByLambda(DataStore<D> lambda) {
- this.lambda = lambda;
- }
-
- @Override
- public int compare(DBIDRef id1, DBIDRef id2) {
- D k1 = lambda.get(id1);
- D k2 = lambda.get(id2);
- assert (k1 != null);
- assert (k2 != null);
- return k1.compareTo(k2);
- }
- }
-
- /**
- * Order a DBID collection by the lambda value.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- private static final class CompareByDoubleLambda implements Comparator<DBIDRef> {
- /**
- * Lambda storage
- */
- private final DoubleDistanceDataStore lambda;
-
- /**
- * Constructor.
- *
- * @param lambda Lambda storage
- */
- protected CompareByDoubleLambda(DoubleDistanceDataStore lambda) {
- this.lambda = lambda;
- }
-
- @Override
- public int compare(DBIDRef id1, DBIDRef id2) {
- double k1 = lambda.doubleValue(id1);
- double k2 = lambda.doubleValue(id2);
- return Double.compare(k1, k2);
- }
- }
-
- /**
* Parameterization class.
*
* @author Erich Schubert
*
* @apiviz.exclude
*/
- public static class Parameterizer<D extends Distance<D>> extends AbstractParameterizer {
+ public static class Parameterizer extends AbstractParameterizer {
/**
* Extraction mode to use.
*/
@@ -794,7 +477,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
/**
* Threshold level.
*/
- D threshold = null;
+ double threshold = Double.NaN;
/**
* Flag to produce empty clusters to model the hierarchy above.
@@ -804,7 +487,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
/**
* The hierarchical clustering algorithm to run.
*/
- HierarchicalClusteringAlgorithm<D> algorithm;
+ HierarchicalClusteringAlgorithm algorithm;
/**
* Threshold mode.
@@ -819,7 +502,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- ObjectParameter<HierarchicalClusteringAlgorithm<D>> algorithmP = new ObjectParameter<>(AlgorithmStep.Parameterizer.ALGORITHM_ID, HierarchicalClusteringAlgorithm.class);
+ ObjectParameter<HierarchicalClusteringAlgorithm> algorithmP = new ObjectParameter<>(AlgorithmStep.Parameterizer.ALGORITHM_ID, HierarchicalClusteringAlgorithm.class);
if(config.grab(algorithmP)) {
algorithm = algorithmP.instantiateClass(config);
}
@@ -838,10 +521,7 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
}
if(thresholdmode == null || ThresholdMode.BY_THRESHOLD.equals(thresholdmode)) {
- // Fallback to double when no algorithm chosen yet:
- @SuppressWarnings("unchecked")
- final D factory = algorithm != null ? algorithm.getDistanceFactory() : (D) DoubleDistance.FACTORY;
- DistanceParameter<D> distP = new DistanceParameter<>(THRESHOLD_ID, factory);
+ DoubleParameter distP = new DoubleParameter(THRESHOLD_ID);
if(config.grab(distP)) {
threshold = distP.getValue();
}
@@ -866,13 +546,13 @@ public class ExtractFlatClusteringFromHierarchy<D extends Distance<D>> implement
}
@Override
- protected ExtractFlatClusteringFromHierarchy<D> makeInstance() {
+ protected ExtractFlatClusteringFromHierarchy makeInstance() {
switch(thresholdmode){
case NO_THRESHOLD:
case BY_MINCLUSTERS:
- return new ExtractFlatClusteringFromHierarchy<>(algorithm, minclusters, outputmode, singletons);
+ return new ExtractFlatClusteringFromHierarchy(algorithm, minclusters, outputmode, singletons);
case BY_THRESHOLD:
- return new ExtractFlatClusteringFromHierarchy<>(algorithm, threshold, outputmode, singletons);
+ return new ExtractFlatClusteringFromHierarchy(algorithm, threshold, outputmode, singletons);
default:
throw new AbortException("Unknown extraction mode.");
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/GroupAverageLinkageMethod.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/GroupAverageLinkageMethod.java
index 079fb69b..5795ba08 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/GroupAverageLinkageMethod.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/GroupAverageLinkageMethod.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
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/algorithm/clustering/hierarchical/HierarchicalClusteringAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/HierarchicalClusteringAlgorithm.java
index f3595d51..88c1bf46 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/HierarchicalClusteringAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/HierarchicalClusteringAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
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.algorithm.clustering.hierarchical;
*/
import de.lmu.ifi.dbs.elki.algorithm.Algorithm;
import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Interface for hierarchical clustering algorithms.
@@ -35,17 +34,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @author Erich Schubert
*
* @apiviz.has PointerHierarchyRepresentationResult
- *
- * @param <D> Distance type
*/
-public interface HierarchicalClusteringAlgorithm<D extends Distance<D>> extends Algorithm {
+public interface HierarchicalClusteringAlgorithm extends Algorithm {
@Override
- public PointerHierarchyRepresentationResult<D> run(Database db);
-
- /**
- * Return the distance type that will be used by the algorithm.
- *
- * @return Distance factory.
- */
- public D getDistanceFactory();
+ public PointerHierarchyRepresentationResult run(Database db);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/LinkageMethod.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/LinkageMethod.java
index 68d0b4d8..0327010c 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/LinkageMethod.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/LinkageMethod.java
@@ -6,7 +6,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
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/algorithm/clustering/hierarchical/MedianLinkageMethod.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/MedianLinkageMethod.java
index fe167cec..eb4ea2a9 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/MedianLinkageMethod.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/MedianLinkageMethod.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
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/algorithm/clustering/hierarchical/NaiveAgglomerativeHierarchicalClustering.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/NaiveAgglomerativeHierarchicalClustering.java
index ee3052a4..083a13dd 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/NaiveAgglomerativeHierarchicalClustering.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/NaiveAgglomerativeHierarchicalClustering.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
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,7 +30,7 @@ import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDBIDDataStore;
-import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDistanceDataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
@@ -40,8 +40,6 @@ 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.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
-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.FiniteProgress;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
@@ -51,11 +49,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
- * This tutorial will step you through implementing a well known clustering
- * algorithm, agglomerative hierarchical clustering, in multiple steps.
- *
- * This is the third step, where we add support for different linkage
- * strategies.
+ * Hierarchical Agglomerative Clustering (HAC) is a classic hierarchical
+ * clustering algorithm. Initially, each element is its own cluster; the closest
+ * clusters are merged at every step, until all the data has become a single
+ * cluster.
*
* This is the naive O(n^3) algorithm. See {@link SLINK} for a much faster
* algorithm (however, only for single-linkage).
@@ -81,8 +78,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @param <O> Object type
*/
-@Reference(authors = "G. N. Lance and W. T. Williams", title = "A general theory of classificatory sorting strategies 1. Hierarchical systems", booktitle = "The computer journal 9.4", url = "http://dx.doi.org/ 10.1093/comjnl/9.4.373")
-public class NaiveAgglomerativeHierarchicalClustering<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, PointerHierarchyRepresentationResult<DoubleDistance>> implements HierarchicalClusteringAlgorithm<DoubleDistance> {
+@Reference(authors = "G. N. Lance and W. T. Williams", //
+title = "A general theory of classificatory sorting strategies 1. Hierarchical systems", //
+booktitle = "The computer journal 9.4", //
+url = "http://dx.doi.org/ 10.1093/comjnl/9.4.373")
+public class NaiveAgglomerativeHierarchicalClustering<O> extends AbstractDistanceBasedAlgorithm<O, PointerHierarchyRepresentationResult> implements HierarchicalClusteringAlgorithm {
/**
* Class logger
*/
@@ -99,7 +99,7 @@ public class NaiveAgglomerativeHierarchicalClustering<O, D extends NumberDistanc
* @param distanceFunction Distance function to use
* @param linkage Linkage method
*/
- public NaiveAgglomerativeHierarchicalClustering(DistanceFunction<? super O, D> distanceFunction, LinkageMethod linkage) {
+ public NaiveAgglomerativeHierarchicalClustering(DistanceFunction<? super O> distanceFunction, LinkageMethod linkage) {
super(distanceFunction);
this.linkage = linkage;
}
@@ -111,15 +111,15 @@ public class NaiveAgglomerativeHierarchicalClustering<O, D extends NumberDistanc
* @param relation Relation
* @return Clustering hierarchy
*/
- public PointerHierarchyRepresentationResult<DoubleDistance> run(Database db, Relation<O> relation) {
- DistanceQuery<O, D> dq = db.getDistanceQuery(relation, getDistanceFunction());
+ public PointerHierarchyRepresentationResult run(Database db, Relation<O> relation) {
+ DistanceQuery<O> dq = db.getDistanceQuery(relation, getDistanceFunction());
ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs());
final int size = ids.size();
- if (size > 0x10000) {
+ if(size > 0x10000) {
throw new AbortException("This implementation does not scale to data sets larger than " + 0x10000 + " instances (~17 GB RAM), which results in an integer overflow.");
}
- if (SingleLinkageMethod.class.isInstance(linkage)) {
+ if(SingleLinkageMethod.class.isInstance(linkage)) {
LOG.verbose("Notice: SLINK is a much faster algorithm for single-linkage clustering!");
}
@@ -129,11 +129,11 @@ public class NaiveAgglomerativeHierarchicalClustering<O, D extends NumberDistanc
// Position counter - must agree with computeOffset!
int pos = 0;
boolean square = WardLinkageMethod.class.isInstance(linkage) && !(SquaredEuclideanDistanceFunction.class.isInstance(getDistanceFunction()));
- for (ix.seek(0); ix.valid(); ix.advance()) {
- for (iy.seek(0); iy.getOffset() < ix.getOffset(); iy.advance()) {
- scratch[pos] = dq.distance(ix, iy).doubleValue();
+ for(ix.seek(0); ix.valid(); ix.advance()) {
+ for(iy.seek(0); iy.getOffset() < ix.getOffset(); iy.advance()) {
+ scratch[pos] = dq.distance(ix, iy);
// Ward uses variances -- i.e. squared values
- if (square) {
+ if(square) {
scratch[pos] *= scratch[pos];
}
pos++;
@@ -142,9 +142,9 @@ public class NaiveAgglomerativeHierarchicalClustering<O, D extends NumberDistanc
// Initialize space for result:
WritableDBIDDataStore pi = DataStoreUtil.makeDBIDStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_STATIC);
- WritableDoubleDistanceDataStore lambda = DataStoreUtil.makeDoubleDistanceStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_STATIC);
+ WritableDoubleDataStore lambda = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_STATIC);
WritableIntegerDataStore csize = DataStoreUtil.makeIntegerStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
- for (DBIDIter it = ids.iter(); it.valid(); it.advance()) {
+ for(DBIDIter it = ids.iter(); it.valid(); it.advance()) {
pi.put(it, it);
lambda.put(it, Double.POSITIVE_INFINITY);
csize.put(it, 1);
@@ -152,20 +152,20 @@ public class NaiveAgglomerativeHierarchicalClustering<O, D extends NumberDistanc
// Repeat until everything merged into 1 cluster
FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Agglomerative clustering", size - 1, LOG) : null;
- for (int i = 1; i < size; i++) {
+ for(int i = 1; i < size; i++) {
double mindist = Double.POSITIVE_INFINITY;
int x = -1, y = -1;
- for (ix.seek(0); ix.valid(); ix.advance()) {
- if (lambda.doubleValue(ix) < Double.POSITIVE_INFINITY) {
+ for(ix.seek(0); ix.valid(); ix.advance()) {
+ if(lambda.doubleValue(ix) < Double.POSITIVE_INFINITY) {
continue;
}
final int xbase = triangleSize(ix.getOffset());
- for (iy.seek(0); iy.getOffset() < ix.getOffset(); iy.advance()) {
- if (lambda.doubleValue(iy) < Double.POSITIVE_INFINITY) {
+ for(iy.seek(0); iy.getOffset() < ix.getOffset(); iy.advance()) {
+ if(lambda.doubleValue(iy) < Double.POSITIVE_INFINITY) {
continue;
}
final int idx = xbase + iy.getOffset();
- if (scratch[idx] <= mindist) {
+ if(scratch[idx] <= mindist) {
mindist = scratch[idx];
x = ix.getOffset();
y = iy.getOffset();
@@ -176,7 +176,7 @@ public class NaiveAgglomerativeHierarchicalClustering<O, D extends NumberDistanc
// Avoid allocating memory, by reusing existing iterators:
ix.seek(x);
iy.seek(y);
- if (LOG.isDebuggingFine()) {
+ if(LOG.isDebuggingFine()) {
LOG.debugFine("Merging: " + DBIDUtil.toString(ix) + " -> " + DBIDUtil.toString(iy));
}
// Perform merge in data structure: x -> y
@@ -195,8 +195,8 @@ public class NaiveAgglomerativeHierarchicalClustering<O, D extends NumberDistanc
ij.seek(0);
// Write to (y, j), with j < y
- for (; ij.getOffset() < y; ij.advance()) {
- if (lambda.doubleValue(ij) < Double.POSITIVE_INFINITY) {
+ for(; ij.getOffset() < y; ij.advance()) {
+ if(lambda.doubleValue(ij) < Double.POSITIVE_INFINITY) {
continue;
}
final int sizej = csize.intValue(ij);
@@ -204,8 +204,8 @@ public class NaiveAgglomerativeHierarchicalClustering<O, D extends NumberDistanc
}
ij.advance(); // Skip y
// Write to (j, y), with y < j < x
- for (; ij.getOffset() < x; ij.advance()) {
- if (lambda.doubleValue(ij) < Double.POSITIVE_INFINITY) {
+ for(; ij.getOffset() < x; ij.advance()) {
+ if(lambda.doubleValue(ij) < Double.POSITIVE_INFINITY) {
continue;
}
final int jbase = triangleSize(ij.getOffset());
@@ -214,23 +214,19 @@ public class NaiveAgglomerativeHierarchicalClustering<O, D extends NumberDistanc
}
ij.advance(); // Skip x
// Write to (j, y), with y < x < j
- for (; ij.valid(); ij.advance()) {
- if (lambda.doubleValue(ij) < Double.POSITIVE_INFINITY) {
+ for(; ij.valid(); ij.advance()) {
+ if(lambda.doubleValue(ij) < Double.POSITIVE_INFINITY) {
continue;
}
final int sizej = csize.intValue(ij);
final int jbase = triangleSize(ij.getOffset());
scratch[jbase + y] = linkage.combine(sizex, scratch[jbase + x], sizey, scratch[jbase + y], sizej, mindist);
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if (prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
- return new PointerHierarchyRepresentationResult<>(ids, pi, lambda);
+ return new PointerHierarchyRepresentationResult(ids, pi, lambda);
}
/**
@@ -244,11 +240,6 @@ public class NaiveAgglomerativeHierarchicalClustering<O, D extends NumberDistanc
}
@Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
- }
-
- @Override
public TypeInformation[] getInputTypeRestriction() {
// The input relation must match our distance function:
return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
@@ -267,9 +258,8 @@ public class NaiveAgglomerativeHierarchicalClustering<O, D extends NumberDistanc
* @apiviz.exclude
*
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Option ID for linkage parameter.
*/
@@ -283,20 +273,20 @@ public class NaiveAgglomerativeHierarchicalClustering<O, D extends NumberDistanc
@Override
protected void makeOptions(Parameterization config) {
// We don't call super, because we want a different default distance.
- ObjectParameter<DistanceFunction<O, D>> distanceFunctionP = makeParameterDistanceFunction(SquaredEuclideanDistanceFunction.class, DistanceFunction.class);
- if (config.grab(distanceFunctionP)) {
+ ObjectParameter<DistanceFunction<O>> distanceFunctionP = makeParameterDistanceFunction(SquaredEuclideanDistanceFunction.class, DistanceFunction.class);
+ if(config.grab(distanceFunctionP)) {
distanceFunction = distanceFunctionP.instantiateClass(config);
}
ObjectParameter<LinkageMethod> linkageP = new ObjectParameter<>(LINKAGE_ID, LinkageMethod.class);
linkageP.setDefaultValue(WardLinkageMethod.class);
- if (config.grab(linkageP)) {
+ if(config.grab(linkageP)) {
linkage = linkageP.instantiateClass(config);
}
}
@Override
- protected NaiveAgglomerativeHierarchicalClustering<O, D> makeInstance() {
+ protected NaiveAgglomerativeHierarchicalClustering<O> makeInstance() {
return new NaiveAgglomerativeHierarchicalClustering<>(distanceFunction, linkage);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/PointerHierarchyRepresentationResult.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/PointerHierarchyRepresentationResult.java
index c339fb09..3f6f4155 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/PointerHierarchyRepresentationResult.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/PointerHierarchyRepresentationResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
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,9 +24,8 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
*/
import de.lmu.ifi.dbs.elki.database.datastore.DBIDDataStore;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.DoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.result.BasicResult;
/**
@@ -35,10 +34,8 @@ import de.lmu.ifi.dbs.elki.result.BasicResult;
* objects cluster.
*
* @author Erich Schubert
- *
- * @param <D> Distance type
*/
-public class PointerHierarchyRepresentationResult<D extends Distance<D>> extends BasicResult {
+public class PointerHierarchyRepresentationResult extends BasicResult {
/**
* The DBIDs in this result.
*/
@@ -52,7 +49,7 @@ public class PointerHierarchyRepresentationResult<D extends Distance<D>> extends
/**
* Distance to the parent object.
*/
- DataStore<D> parentDistance;
+ DoubleDataStore parentDistance;
/**
* Constructor.
@@ -61,7 +58,7 @@ public class PointerHierarchyRepresentationResult<D extends Distance<D>> extends
* @param parent Parent pointer.
* @param parentDistance Distance to parent.
*/
- public PointerHierarchyRepresentationResult(DBIDs ids, DBIDDataStore parent, DataStore<D> parentDistance) {
+ public PointerHierarchyRepresentationResult(DBIDs ids, DBIDDataStore parent, DoubleDataStore parentDistance) {
super("Pointer Representation", "pointer-representation");
this.ids = ids;
this.parent = parent;
@@ -91,7 +88,7 @@ public class PointerHierarchyRepresentationResult<D extends Distance<D>> extends
*
* @return Parent distance.
*/
- public DataStore<D> getParentDistanceStore() {
+ public DoubleDataStore getParentDistanceStore() {
return parentDistance;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/SLINK.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/SLINK.java
index f1b58868..3e8f0fdb 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/SLINK.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/SLINK.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
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,8 +30,7 @@ import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDBIDDataStore;
-import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
-import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDistanceDataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
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;
@@ -40,10 +39,8 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
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.DistanceUtil;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.utilities.Alias;
@@ -67,13 +64,12 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
* @apiviz.has SingleLinkageMethod
*
* @param <O> the type of DatabaseObject the algorithm is applied on
- * @param <D> the type of Distance used
*/
@Title("SLINK: Single Link Clustering")
@Description("Hierarchical clustering algorithm based on single-link connectivity.")
@Reference(authors = "R. Sibson", title = "SLINK: An optimally efficient algorithm for the single-link cluster method", booktitle = "The Computer Journal 16 (1973), No. 1, p. 30-34.", url = "http://dx.doi.org/10.1093/comjnl/16.1.30")
@Alias(value = { "de.lmu.ifi.dbs.elki.algorithm.clustering.SLINK", "clustering.SLINK", "SLINK", "single-link", "single-linkage" })
-public class SLINK<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm<O, D, PointerHierarchyRepresentationResult<D>> implements HierarchicalClusteringAlgorithm<D> {
+public class SLINK<O> extends AbstractDistanceBasedAlgorithm<O, PointerHierarchyRepresentationResult> implements HierarchicalClusteringAlgorithm {
/**
* The logger for this class.
*/
@@ -84,70 +80,60 @@ public class SLINK<O, D extends Distance<D>> extends AbstractDistanceBasedAlgori
*
* @param distanceFunction Distance function
*/
- public SLINK(DistanceFunction<? super O, D> distanceFunction) {
+ public SLINK(DistanceFunction<? super O> distanceFunction) {
super(distanceFunction);
}
/**
* Performs the SLINK algorithm on the given database.
+ *
+ * @param database Database to process
+ * @param relation Data relation to use
*/
- public PointerHierarchyRepresentationResult<D> run(Database database, Relation<O> relation) {
+ public PointerHierarchyRepresentationResult run(Database database, Relation<O> relation) {
DBIDs ids = relation.getDBIDs();
- DistanceQuery<O, D> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
- @SuppressWarnings("unchecked")
- Class<D> distCls = (Class<D>) getDistanceFunction().getDistanceFactory().getClass();
WritableDBIDDataStore pi = DataStoreUtil.makeDBIDStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_STATIC);
- WritableDataStore<D> lambda = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_STATIC, distCls);
+ WritableDoubleDataStore lambda = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_STATIC);
// Temporary storage for m.
- WritableDataStore<D> m = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, distCls);
+ WritableDoubleDataStore m = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("Running SLINK", ids.size(), LOG) : null;
// has to be an array for monotonicity reasons!
ModifiableDBIDs processedIDs = DBIDUtil.newArray(ids.size());
- // Optimized code path for double distances
- if (getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction && lambda instanceof WritableDoubleDistanceDataStore && m instanceof WritableDoubleDistanceDataStore) {
- @SuppressWarnings("unchecked")
- PrimitiveDoubleDistanceFunction<? super O> dist = (PrimitiveDoubleDistanceFunction<? super O>) getDistanceFunction();
- WritableDoubleDistanceDataStore lambdad = (WritableDoubleDistanceDataStore) lambda;
- WritableDoubleDistanceDataStore md = (WritableDoubleDistanceDataStore) m;
- // apply the algorithm
- for (DBIDIter id = ids.iter(); id.valid(); id.advance()) {
- step1double(id, pi, lambdad);
- step2double(id, processedIDs, distQuery.getRelation(), dist, md);
- step3double(id, pi, lambdad, processedIDs, md);
- step4double(id, pi, lambdad, processedIDs);
+ if(getDistanceFunction() instanceof PrimitiveDistanceFunction) {
+ PrimitiveDistanceFunction<? super O> distf = (PrimitiveDistanceFunction<? super O>) getDistanceFunction();
+ for(DBIDIter id = ids.iter(); id.valid(); id.advance()) {
+ step1(id, pi, lambda);
+ step2primitive(id, processedIDs, relation, distf, m);
+ step3(id, pi, lambda, processedIDs, m);
+ step4(id, pi, lambda, processedIDs);
processedIDs.add(id);
- if (progress != null) {
- progress.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(progress);
}
- } else {
- // apply the algorithm
- for (DBIDIter id = ids.iter(); id.valid(); id.advance()) {
+ }
+ else {
+ DistanceQuery<O> distQ = database.getDistanceQuery(relation, getDistanceFunction());
+ for(DBIDIter id = ids.iter(); id.valid(); id.advance()) {
step1(id, pi, lambda);
- step2(id, processedIDs, distQuery, m);
+ step2(id, processedIDs, distQ, m);
step3(id, pi, lambda, processedIDs, m);
step4(id, pi, lambda, processedIDs);
processedIDs.add(id);
- if (progress != null) {
- progress.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(progress);
}
}
- if (progress != null) {
- progress.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(progress);
// We don't need m anymore.
m.destroy();
m = null;
- return new PointerHierarchyRepresentationResult<>(ids, pi, lambda);
+ return new PointerHierarchyRepresentationResult(ids, pi, lambda);
}
/**
@@ -158,11 +144,11 @@ public class SLINK<O, D extends Distance<D>> extends AbstractDistanceBasedAlgori
* @param pi Pi data store
* @param lambda Lambda data store
*/
- private void step1(DBIDRef id, WritableDBIDDataStore pi, WritableDataStore<D> lambda) {
+ private void step1(DBIDRef id, WritableDBIDDataStore pi, WritableDoubleDataStore lambda) {
// P(n+1) = n+1:
pi.put(id, id);
// L(n+1) = infinity
- lambda.put(id, getDistanceFunction().getDistanceFactory().infiniteDistance());
+ lambda.putDouble(id, Double.POSITIVE_INFINITY);
}
/**
@@ -172,93 +158,17 @@ public class SLINK<O, D extends Distance<D>> extends AbstractDistanceBasedAlgori
* @param id the id of the object to be inserted into the pointer
* representation
* @param processedIDs the already processed ids
+ * @param distQuery Distnace query
* @param m Data store
- * @param distFunc Distance function to use
*/
- private void step2(DBIDRef id, DBIDs processedIDs, DistanceQuery<O, D> distFunc, WritableDataStore<D> m) {
- O newObj = distFunc.getRelation().get(id);
- for (DBIDIter it = processedIDs.iter(); it.valid(); it.advance()) {
+ private void step2(DBIDRef id, DBIDs processedIDs, DistanceQuery<? super O> distQuery, WritableDoubleDataStore m) {
+ for(DBIDIter it = processedIDs.iter(); it.valid(); it.advance()) {
// M(i) = dist(i, n+1)
- m.put(it, distFunc.distance(it, newObj));
- }
- }
-
- /**
- * Third step: Determine the values for P and L
- *
- * @param id the id of the object to be inserted into the pointer
- * representation
- * @param pi Pi data store
- * @param lambda Lambda data store
- * @param processedIDs the already processed ids
- * @param m Data store
- */
- private void step3(DBIDRef id, WritableDBIDDataStore pi, WritableDataStore<D> lambda, DBIDs processedIDs, WritableDataStore<D> m) {
- DBIDVar p_i = DBIDUtil.newVar();
- // for i = 1..n
- for (DBIDIter it = processedIDs.iter(); it.valid(); it.advance()) {
- D l_i = lambda.get(it);
- D m_i = m.get(it);
- pi.assignVar(it, p_i); // p_i = pi(it)
- D mp_i = m.get(p_i);
-
- // if L(i) >= M(i)
- if (l_i.compareTo(m_i) >= 0) {
- // M(P(i)) = min { M(P(i)), L(i) }
- m.put(p_i, DistanceUtil.min(mp_i, l_i));
-
- // L(i) = M(i)
- lambda.put(it, m_i);
-
- // P(i) = n+1;
- pi.put(it, id);
- } else {
- // M(P(i)) = min { M(P(i)), M(i) }
- m.put(p_i, DistanceUtil.min(mp_i, m_i));
- }
+ m.putDouble(it, distQuery.distance(it, id));
}
}
/**
- * Fourth step: Actualize the clusters if necessary
- *
- * @param id the id of the current object
- * @param pi Pi data store
- * @param lambda Lambda data store
- * @param processedIDs the already processed ids
- */
- private void step4(DBIDRef id, WritableDBIDDataStore pi, WritableDataStore<D> lambda, DBIDs processedIDs) {
- DBIDVar p_i = DBIDUtil.newVar();
- // for i = 1..n
- for (DBIDIter it = processedIDs.iter(); it.valid(); it.advance()) {
- D l_i = lambda.get(it);
- pi.assignVar(it, p_i); // p_i = pi(it)
- D lp_i = lambda.get(p_i);
-
- // if L(i) >= L(P(i))
- if (l_i.compareTo(lp_i) >= 0) {
- // P(i) = n+1
- pi.put(it, id);
- }
- }
- }
-
- /**
- * First step: Initialize P(id) = id, L(id) = infinity.
- *
- * @param id the id of the object to be inserted into the pointer
- * representation
- * @param pi Pi data store
- * @param lambda Lambda data store
- */
- private void step1double(DBIDRef id, WritableDBIDDataStore pi, WritableDoubleDistanceDataStore lambda) {
- // P(n+1) = n+1:
- pi.put(id, id);
- // L(n+1) = infinity
- lambda.putDouble(id, Double.POSITIVE_INFINITY);
- }
-
- /**
* Second step: Determine the pairwise distances from all objects in the
* pointer representation to the new object with the specified id.
*
@@ -269,11 +179,11 @@ public class SLINK<O, D extends Distance<D>> extends AbstractDistanceBasedAlgori
* @param relation Data relation
* @param distFunc Distance function to use
*/
- private void step2double(DBIDRef id, DBIDs processedIDs, Relation<? extends O> relation, PrimitiveDoubleDistanceFunction<? super O> distFunc, WritableDoubleDistanceDataStore m) {
+ private void step2primitive(DBIDRef id, DBIDs processedIDs, Relation<? extends O> relation, PrimitiveDistanceFunction<? super O> distFunc, WritableDoubleDataStore m) {
O newObj = relation.get(id);
- for (DBIDIter it = processedIDs.iter(); it.valid(); it.advance()) {
+ for(DBIDIter it = processedIDs.iter(); it.valid(); it.advance()) {
// M(i) = dist(i, n+1)
- m.putDouble(it, distFunc.doubleDistance(relation.get(it), newObj));
+ m.putDouble(it, distFunc.distance(relation.get(it), newObj));
}
}
@@ -287,17 +197,17 @@ public class SLINK<O, D extends Distance<D>> extends AbstractDistanceBasedAlgori
* @param processedIDs the already processed ids
* @param m Data store
*/
- private void step3double(DBIDRef id, WritableDBIDDataStore pi, WritableDoubleDistanceDataStore lambda, DBIDs processedIDs, WritableDoubleDistanceDataStore m) {
+ private void step3(DBIDRef id, WritableDBIDDataStore pi, WritableDoubleDataStore lambda, DBIDs processedIDs, WritableDoubleDataStore m) {
DBIDVar p_i = DBIDUtil.newVar();
// for i = 1..n
- for (DBIDIter it = processedIDs.iter(); it.valid(); it.advance()) {
+ for(DBIDIter it = processedIDs.iter(); it.valid(); it.advance()) {
double l_i = lambda.doubleValue(it);
double m_i = m.doubleValue(it);
pi.assignVar(it, p_i); // p_i = pi(it)
double mp_i = m.doubleValue(p_i);
// if L(i) >= M(i)
- if (l_i >= m_i) {
+ if(l_i >= m_i) {
// M(P(i)) = min { M(P(i)), L(i) }
m.putDouble(p_i, Math.min(mp_i, l_i));
@@ -306,7 +216,8 @@ public class SLINK<O, D extends Distance<D>> extends AbstractDistanceBasedAlgori
// P(i) = n+1;
pi.put(it, id);
- } else {
+ }
+ else {
// M(P(i)) = min { M(P(i)), M(i) }
m.putDouble(p_i, Math.min(mp_i, m_i));
}
@@ -321,16 +232,16 @@ public class SLINK<O, D extends Distance<D>> extends AbstractDistanceBasedAlgori
* @param lambda Lambda data store
* @param processedIDs the already processed ids
*/
- private void step4double(DBIDRef id, WritableDBIDDataStore pi, WritableDoubleDistanceDataStore lambda, DBIDs processedIDs) {
+ private void step4(DBIDRef id, WritableDBIDDataStore pi, WritableDoubleDataStore lambda, DBIDs processedIDs) {
DBIDVar p_i = DBIDUtil.newVar();
// for i = 1..n
- for (DBIDIter it = processedIDs.iter(); it.valid(); it.advance()) {
+ for(DBIDIter it = processedIDs.iter(); it.valid(); it.advance()) {
double l_i = lambda.doubleValue(it);
pi.assignVar(it, p_i); // p_i = pi(it)
double lp_i = lambda.doubleValue(p_i);
// if L(i) >= L(P(i))
- if (l_i >= lp_i) {
+ if(l_i >= lp_i) {
// P(i) = n+1
pi.put(it, id);
}
@@ -338,11 +249,6 @@ public class SLINK<O, D extends Distance<D>> extends AbstractDistanceBasedAlgori
}
@Override
- public D getDistanceFactory() {
- return getDistanceFunction().getDistanceFactory();
- }
-
- @Override
public TypeInformation[] getInputTypeRestriction() {
return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
}
@@ -359,9 +265,9 @@ public class SLINK<O, D extends Distance<D>> extends AbstractDistanceBasedAlgori
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
@Override
- protected SLINK<O, D> makeInstance() {
+ protected SLINK<O> makeInstance() {
return new SLINK<>(distanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/SingleLinkageMethod.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/SingleLinkageMethod.java
index 7ef81692..83543411 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/SingleLinkageMethod.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/SingleLinkageMethod.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
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/algorithm/clustering/hierarchical/WardLinkageMethod.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/WardLinkageMethod.java
index 488f011c..dc6f7079 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/WardLinkageMethod.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/WardLinkageMethod.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
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/algorithm/clustering/hierarchical/WeightedAverageLinkageMethod.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/WeightedAverageLinkageMethod.java
index ac0b17f5..df913a89 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/WeightedAverageLinkageMethod.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/WeightedAverageLinkageMethod.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
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/algorithm/clustering/hierarchical/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/package-info.java
new file mode 100644
index 00000000..1783800c
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Hierarchical agglomerative clustering (HAC).
+ */
+/*
+ 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.algorithm.clustering.hierarchical;
+
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/AbstractKMeans.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/AbstractKMeans.java
index 5754e961..bdfc2f04 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/AbstractKMeans.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/AbstractKMeans.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
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,14 +24,17 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
*/
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import de.lmu.ifi.dbs.elki.algorithm.AbstractPrimitiveDistanceBasedAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.RandomlyChosenInitialMeans;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.VectorUtil.SortDBIDsBySingleDimension;
-import de.lmu.ifi.dbs.elki.data.model.MeanModel;
+import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.data.type.CombinedTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
@@ -43,11 +46,10 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
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.distancefunction.PrimitiveDoubleDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.statistics.DoubleStatistic;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.utilities.datastructures.QuickSelect;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -60,28 +62,26 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
- * @apiviz.has MeanModel
* @apiviz.composedOf KMeansInitialization
*
* @param <V> Vector type
- * @param <D> Distance type
* @param <M> Cluster model type
*/
-public abstract class AbstractKMeans<V extends NumberVector<?>, D extends Distance<D>, M extends MeanModel<V>> extends AbstractPrimitiveDistanceBasedAlgorithm<NumberVector<?>, D, Clustering<M>> implements KMeans<V, D, M>, ClusteringAlgorithm<Clustering<M>> {
+public abstract class AbstractKMeans<V extends NumberVector, M extends Model> extends AbstractPrimitiveDistanceBasedAlgorithm<NumberVector, Clustering<M>> implements KMeans<V, M>, ClusteringAlgorithm<Clustering<M>> {
/**
- * Holds the value of {@link #K_ID}.
+ * Number of cluster centers to initialize.
*/
protected int k;
/**
- * Holds the value of {@link #MAXITER_ID}.
+ * Maximum number of iterations
*/
protected int maxiter;
/**
* Method to choose initial means.
*/
- protected KMeansInitialization<V> initializer;
+ protected KMeansInitialization<? super V> initializer;
/**
* Constructor.
@@ -91,7 +91,7 @@ public abstract class AbstractKMeans<V extends NumberVector<?>, D extends Distan
* @param maxiter Maxiter parameter
* @param initializer Function to generate the initial means
*/
- public AbstractKMeans(PrimitiveDistanceFunction<? super NumberVector<?>, D> distanceFunction, int k, int maxiter, KMeansInitialization<V> initializer) {
+ public AbstractKMeans(PrimitiveDistanceFunction<? super NumberVector> distanceFunction, int k, int maxiter, KMeansInitialization<? super V> initializer) {
super(distanceFunction);
this.k = k;
this.maxiter = maxiter;
@@ -106,43 +106,26 @@ public abstract class AbstractKMeans<V extends NumberVector<?>, D extends Distan
* @param means a list of k means
* @param clusters cluster assignment
* @param assignment Current cluster assignment
+ * @param varsum Variance sum output
* @return true when the object was reassigned
*/
- protected boolean assignToNearestCluster(Relation<V> relation, List<? extends NumberVector<?>> means, List<? extends ModifiableDBIDs> clusters, WritableIntegerDataStore assignment) {
+ protected boolean assignToNearestCluster(Relation<? extends V> relation, List<? extends NumberVector> means, List<? extends ModifiableDBIDs> clusters, WritableIntegerDataStore assignment, double[] varsum) {
boolean changed = false;
-
- if(getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction) {
- @SuppressWarnings("unchecked")
- final PrimitiveDoubleDistanceFunction<? super NumberVector<?>> df = (PrimitiveDoubleDistanceFunction<? super NumberVector<?>>) getDistanceFunction();
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- double mindist = Double.POSITIVE_INFINITY;
- V fv = relation.get(iditer);
- int minIndex = 0;
- for(int i = 0; i < k; i++) {
- double dist = df.doubleDistance(fv, means.get(i));
- if(dist < mindist) {
- minIndex = i;
- mindist = dist;
- }
+ Arrays.fill(varsum, 0.);
+ final PrimitiveDistanceFunction<? super NumberVector> df = getDistanceFunction();
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ double mindist = Double.POSITIVE_INFINITY;
+ V fv = relation.get(iditer);
+ int minIndex = 0;
+ for(int i = 0; i < k; i++) {
+ double dist = df.distance(fv, means.get(i));
+ if(dist < mindist) {
+ minIndex = i;
+ mindist = dist;
}
- changed |= updateAssignment(iditer, clusters, assignment, minIndex);
- }
- }
- else {
- final PrimitiveDistanceFunction<? super NumberVector<?>, D> df = getDistanceFunction();
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- D mindist = df.getDistanceFactory().infiniteDistance();
- V fv = relation.get(iditer);
- int minIndex = 0;
- for(int i = 0; i < k; i++) {
- D dist = df.distance(fv, means.get(i));
- if(dist.compareTo(mindist) < 0) {
- minIndex = i;
- mindist = dist;
- }
- }
- changed |= updateAssignment(iditer, clusters, assignment, minIndex);
}
+ varsum[minIndex] += mindist;
+ changed |= updateAssignment(iditer, clusters, assignment, minIndex);
}
return changed;
}
@@ -173,7 +156,7 @@ public abstract class AbstractKMeans<V extends NumberVector<?>, D extends Distan
* @param database the database containing the vectors
* @return the mean vectors of the given clusters in the given database
*/
- protected List<Vector> means(List<? extends ModifiableDBIDs> clusters, List<? extends NumberVector<?>> means, Relation<V> database) {
+ protected List<Vector> means(List<? extends ModifiableDBIDs> clusters, List<? extends NumberVector> means, Relation<V> database) {
// TODO: use Kahan summation for better numerical precision?
List<Vector> newMeans = new ArrayList<>(k);
for(int i = 0; i < k; i++) {
@@ -187,7 +170,7 @@ public abstract class AbstractKMeans<V extends NumberVector<?>, D extends Distan
iter.advance();
// Update with remaining instances
for(; iter.valid(); iter.advance()) {
- NumberVector<?> vec = database.get(iter);
+ NumberVector vec = database.get(iter);
for(int j = 0; j < mean.getDimensionality(); j++) {
raw[j] += vec.doubleValue(j);
}
@@ -211,24 +194,23 @@ public abstract class AbstractKMeans<V extends NumberVector<?>, D extends Distan
* @param database the database containing the vectors
* @return the mean vectors of the given clusters in the given database
*/
- protected List<NumberVector<?>> medians(List<? extends ModifiableDBIDs> clusters, List<? extends NumberVector<?>> medians, Relation<V> database) {
+ protected List<Vector> medians(List<? extends ModifiableDBIDs> clusters, List<Vector> medians, Relation<V> database) {
final int dim = medians.get(0).getDimensionality();
final SortDBIDsBySingleDimension sorter = new SortDBIDsBySingleDimension(database);
- List<NumberVector<?>> newMedians = new ArrayList<>(k);
+ List<Vector> newMedians = new ArrayList<>(k);
for(int i = 0; i < k; i++) {
ArrayModifiableDBIDs list = DBIDUtil.newArray(clusters.get(i));
- if(list.size() > 0) {
- Vector mean = new Vector(dim);
- for(int d = 0; d < dim; d++) {
- sorter.setDimension(d);
- DBID id = QuickSelect.median(list, sorter);
- mean.set(d, database.get(id).doubleValue(d));
- }
- newMedians.add(mean);
+ if(list.size() <= 0) {
+ newMedians.add(medians.get(i));
+ continue;
}
- else {
- newMedians.add((NumberVector<?>) medians.get(i));
+ Vector mean = new Vector(dim);
+ for(int d = 0; d < dim; d++) {
+ sorter.setDimension(d);
+ DBID id = QuickSelect.median(list, sorter);
+ mean.set(d, database.get(id).doubleValue(d));
}
+ newMedians.add(mean);
}
return newMedians;
}
@@ -256,49 +238,30 @@ public abstract class AbstractKMeans<V extends NumberVector<?>, D extends Distan
* @param means Means
* @param clusters Clusters
* @param assignment Current cluster assignment
+ * @param varsum Variance sum output
* @return true when the means have changed
*/
- protected boolean macQueenIterate(Relation<V> relation, List<Vector> means, List<ModifiableDBIDs> clusters, WritableIntegerDataStore assignment) {
+ protected boolean macQueenIterate(Relation<V> relation, List<Vector> means, List<ModifiableDBIDs> clusters, WritableIntegerDataStore assignment, double[] varsum) {
boolean changed = false;
-
- if(getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction) {
- // Raw distance function
- @SuppressWarnings("unchecked")
- final PrimitiveDoubleDistanceFunction<? super NumberVector<?>> df = (PrimitiveDoubleDistanceFunction<? super NumberVector<?>>) getDistanceFunction();
-
- // Incremental update
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- double mindist = Double.POSITIVE_INFINITY;
- V fv = relation.get(iditer);
- int minIndex = 0;
- for(int i = 0; i < k; i++) {
- double dist = df.doubleDistance(fv, means.get(i));
- if(dist < mindist) {
- minIndex = i;
- mindist = dist;
- }
- }
- changed |= updateMeanAndAssignment(clusters, means, minIndex, fv, iditer, assignment);
- }
- }
- else {
- // Raw distance function
- final PrimitiveDistanceFunction<? super NumberVector<?>, D> df = getDistanceFunction();
-
- // Incremental update
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- D mindist = df.getDistanceFactory().infiniteDistance();
- V fv = relation.get(iditer);
- int minIndex = 0;
- for(int i = 0; i < k; i++) {
- D dist = df.distance(fv, means.get(i));
- if(dist.compareTo(mindist) < 0) {
- minIndex = i;
- mindist = dist;
- }
+ Arrays.fill(varsum, 0.);
+
+ // Raw distance function
+ final PrimitiveDistanceFunction<? super NumberVector> df = getDistanceFunction();
+
+ // Incremental update
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ double mindist = Double.POSITIVE_INFINITY;
+ V fv = relation.get(iditer);
+ int minIndex = 0;
+ for(int i = 0; i < k; i++) {
+ double dist = df.distance(fv, means.get(i));
+ if(dist < mindist) {
+ minIndex = i;
+ mindist = dist;
}
- changed |= updateMeanAndAssignment(clusters, means, minIndex, fv, iditer, assignment);
}
+ varsum[minIndex] += mindist;
+ changed |= updateMeanAndAssignment(clusters, means, minIndex, fv, iditer, assignment);
}
return changed;
}
@@ -339,18 +302,36 @@ public abstract class AbstractKMeans<V extends NumberVector<?>, D extends Distan
}
@Override
- public void setDistanceFunction(PrimitiveDistanceFunction<? super NumberVector<?>, D> distanceFunction) {
+ public void setDistanceFunction(PrimitiveDistanceFunction<? super NumberVector> distanceFunction) {
this.distanceFunction = distanceFunction;
}
/**
+ * Log statistics on the variance sum.
+ *
+ * @param varstat Statistics log instance
+ * @param varsum Variance sum per cluster
+ */
+ protected void logVarstat(DoubleStatistic varstat, double[] varsum) {
+ if(varstat == null) {
+ return;
+ }
+ double s = 0.;
+ for(double v : varsum) {
+ s += v;
+ }
+ varstat.setDouble(s);
+ getLogger().statistics(varstat);
+ }
+
+ /**
* Parameterization class.
*
* @author Erich Schubert
*
* @apiviz.exclude
*/
- public abstract static class Parameterizer<V extends NumberVector<?>, D extends Distance<D>> extends AbstractPrimitiveDistanceBasedAlgorithm.Parameterizer<NumberVector<?>, D> {
+ public abstract static class Parameterizer<V extends NumberVector> extends AbstractPrimitiveDistanceBasedAlgorithm.Parameterizer<NumberVector> {
/**
* k Parameter.
*/
@@ -368,25 +349,58 @@ public abstract class AbstractKMeans<V extends NumberVector<?>, D extends Distan
@Override
protected void makeOptions(Parameterization config) {
- ObjectParameter<PrimitiveDistanceFunction<NumberVector<?>, D>> distanceFunctionP = makeParameterDistanceFunction(SquaredEuclideanDistanceFunction.class, PrimitiveDistanceFunction.class);
- if(config.grab(distanceFunctionP)) {
- distanceFunction = distanceFunctionP.instantiateClass(config);
- if(!(distanceFunction instanceof EuclideanDistanceFunction) && !(distanceFunction instanceof SquaredEuclideanDistanceFunction)) {
- getLogger().warning("k-means optimizes the sum of squares - it should be used with squared euclidean distance and may stop converging otherwise!");
- }
- }
+ getParameterK(config);
+ getParameterInitialization(config);
+ getParameterDistanceFunction(config);
+ getParameterMaxIter(config);
+ }
+ /**
+ * Get the k parameter.
+ *
+ * @param config Parameterization
+ */
+ protected void getParameterK(Parameterization config) {
IntParameter kP = new IntParameter(K_ID);
kP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
if(config.grab(kP)) {
k = kP.getValue();
}
+ }
+ /**
+ * Get the distance function parameter.
+ *
+ * @param config Parameterization
+ */
+ protected void getParameterDistanceFunction(Parameterization config) {
+ ObjectParameter<PrimitiveDistanceFunction<NumberVector>> distanceFunctionP = makeParameterDistanceFunction(SquaredEuclideanDistanceFunction.class, PrimitiveDistanceFunction.class);
+ if(config.grab(distanceFunctionP)) {
+ distanceFunction = distanceFunctionP.instantiateClass(config);
+ if(!(distanceFunction instanceof EuclideanDistanceFunction) && !(distanceFunction instanceof SquaredEuclideanDistanceFunction)) {
+ getLogger().warning("k-means optimizes the sum of squares - it should be used with squared euclidean distance and may stop converging otherwise!");
+ }
+ }
+ }
+
+ /**
+ * Get the initialization method parameter.
+ *
+ * @param config Parameterization
+ */
+ protected void getParameterInitialization(Parameterization config) {
ObjectParameter<KMeansInitialization<V>> initialP = new ObjectParameter<>(INIT_ID, KMeansInitialization.class, RandomlyChosenInitialMeans.class);
if(config.grab(initialP)) {
initializer = initialP.instantiateClass(config);
}
+ }
+ /**
+ * Get the max iterations parameter.
+ *
+ * @param config Parameterization
+ */
+ protected void getParameterMaxIter(Parameterization config) {
IntParameter maxiterP = new IntParameter(MAXITER_ID, 0);
maxiterP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_INT);
if(config.grab(maxiterP)) {
@@ -402,6 +416,6 @@ public abstract class AbstractKMeans<V extends NumberVector<?>, D extends Distan
abstract protected Logging getLogger();
@Override
- abstract protected AbstractKMeans<V, D, ?> makeInstance();
+ abstract protected AbstractKMeans<V, ?> makeInstance();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/BestOfMultipleKMeans.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/BestOfMultipleKMeans.java
index 51e7ace9..1c9c6a71 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/BestOfMultipleKMeans.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/BestOfMultipleKMeans.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
/*
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,7 +32,6 @@ import de.lmu.ifi.dbs.elki.database.Database;
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.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
@@ -50,10 +49,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @author Erich Schubert
*
* @param <V> Vector type
- * @param <D> Distance type
* @param <M> Model type
*/
-public class BestOfMultipleKMeans<V extends NumberVector<?>, D extends Distance<?>, M extends MeanModel<V>> extends AbstractAlgorithm<Clustering<M>> implements KMeans<V, D, M> {
+public class BestOfMultipleKMeans<V extends NumberVector, M extends MeanModel> extends AbstractAlgorithm<Clustering<M>> implements KMeans<V, M> {
/**
* The logger for this class.
*/
@@ -67,12 +65,12 @@ public class BestOfMultipleKMeans<V extends NumberVector<?>, D extends Distance<
/**
* Variant of kMeans for the bisecting step.
*/
- private KMeans<V, D, M> innerkMeans;
+ private KMeans<V, M> innerkMeans;
/**
* Quality measure which should be used.
*/
- private KMeansQualityMeasure<? super V, ? super D> qualityMeasure;
+ private KMeansQualityMeasure<? super V> qualityMeasure;
/**
* Constructor.
@@ -81,7 +79,7 @@ public class BestOfMultipleKMeans<V extends NumberVector<?>, D extends Distance<
* @param innerkMeans K-Means variant to actually use.
* @param qualityMeasure Quality measure
*/
- public BestOfMultipleKMeans(int trials, KMeans<V, D, M> innerkMeans, KMeansQualityMeasure<? super V, ? super D> qualityMeasure) {
+ public BestOfMultipleKMeans(int trials, KMeans<V, M> innerkMeans, KMeansQualityMeasure<? super V> qualityMeasure) {
super();
this.trials = trials;
this.innerkMeans = innerkMeans;
@@ -93,34 +91,27 @@ public class BestOfMultipleKMeans<V extends NumberVector<?>, D extends Distance<
if(!(innerkMeans.getDistanceFunction() instanceof PrimitiveDistanceFunction)) {
throw new AbortException("K-Means results can only be evaluated for primitive distance functions, got: " + innerkMeans.getDistanceFunction().getClass());
}
- final PrimitiveDistanceFunction<? super V, D> df = (PrimitiveDistanceFunction<? super V, D>) innerkMeans.getDistanceFunction();
+ @SuppressWarnings("unchecked")
+ final PrimitiveDistanceFunction<? super NumberVector> df = (PrimitiveDistanceFunction<? super NumberVector>) innerkMeans.getDistanceFunction();
+
Clustering<M> bestResult = null;
- if(trials > 1) {
- double bestCost = Double.POSITIVE_INFINITY;
- FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("K-means iterations", trials, LOG) : null;
- for(int i = 0; i < trials; i++) {
- Clustering<M> currentCandidate = innerkMeans.run(database, relation);
- double currentCost = qualityMeasure.calculateCost(currentCandidate, df, relation);
-
- if(LOG.isVerbose()) {
- LOG.verbose("Cost of candidate " + i + ": " + currentCost);
- }
-
- if(currentCost < bestCost) {
- bestResult = currentCandidate;
- bestCost = currentCost;
- }
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
+ double bestCost = Double.NaN;
+ FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("K-means iterations", trials, LOG) : null;
+ for(int i = 0; i < trials; i++) {
+ Clustering<M> currentCandidate = innerkMeans.run(database, relation);
+ double currentCost = qualityMeasure.quality(currentCandidate, df, relation);
+
+ if(LOG.isVerbose()) {
+ LOG.verbose("Cost of candidate " + i + ": " + currentCost);
}
- if(prog != null) {
- prog.ensureCompleted(LOG);
+
+ if(qualityMeasure.isBetter(currentCost, bestCost)) {
+ bestResult = currentCandidate;
+ bestCost = currentCost;
}
+ LOG.incrementProcessed(prog);
}
- else {
- bestResult = innerkMeans.run(database);
- }
+ LOG.ensureCompleted(prog);
return bestResult;
}
@@ -131,7 +122,7 @@ public class BestOfMultipleKMeans<V extends NumberVector<?>, D extends Distance<
}
@Override
- public DistanceFunction<? super V, D> getDistanceFunction() {
+ public DistanceFunction<? super V> getDistanceFunction() {
return innerkMeans.getDistanceFunction();
}
@@ -141,7 +132,7 @@ public class BestOfMultipleKMeans<V extends NumberVector<?>, D extends Distance<
}
@Override
- public void setDistanceFunction(PrimitiveDistanceFunction<? super NumberVector<?>, D> distanceFunction) {
+ public void setDistanceFunction(PrimitiveDistanceFunction<? super NumberVector> distanceFunction) {
innerkMeans.setDistanceFunction(distanceFunction);
}
@@ -159,10 +150,9 @@ public class BestOfMultipleKMeans<V extends NumberVector<?>, D extends Distance<
* @apiviz.exclude
*
* @param <V> Vector type
- * @param <D> Distance type
* @param <M> Model type
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends Distance<D>, M extends MeanModel<V>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector, M extends MeanModel> extends AbstractParameterizer {
/**
* Parameter to specify the iterations of the bisecting step.
*/
@@ -186,12 +176,12 @@ public class BestOfMultipleKMeans<V extends NumberVector<?>, D extends Distance<
/**
* Variant of kMeans to use.
*/
- protected KMeans<V, D, M> kMeansVariant;
+ protected KMeans<V, M> kMeansVariant;
/**
* Quality measure.
*/
- protected KMeansQualityMeasure<? super V, ? super D> qualityMeasure;
+ protected KMeansQualityMeasure<? super V> qualityMeasure;
@Override
protected void makeOptions(Parameterization config) {
@@ -201,19 +191,19 @@ public class BestOfMultipleKMeans<V extends NumberVector<?>, D extends Distance<
trials = trialsP.intValue();
}
- ObjectParameter<KMeans<V, D, M>> kMeansVariantP = new ObjectParameter<>(KMEANS_ID, KMeans.class);
+ ObjectParameter<KMeans<V, M>> kMeansVariantP = new ObjectParameter<>(KMEANS_ID, KMeans.class);
if(config.grab(kMeansVariantP)) {
kMeansVariant = kMeansVariantP.instantiateClass(config);
}
- ObjectParameter<KMeansQualityMeasure<V, ? super D>> qualityMeasureP = new ObjectParameter<>(QUALITYMEASURE_ID, KMeansQualityMeasure.class);
+ ObjectParameter<KMeansQualityMeasure<V>> qualityMeasureP = new ObjectParameter<>(QUALITYMEASURE_ID, KMeansQualityMeasure.class);
if(config.grab(qualityMeasureP)) {
qualityMeasure = qualityMeasureP.instantiateClass(config);
}
}
@Override
- protected BestOfMultipleKMeans<V, D, M> makeInstance() {
+ protected BestOfMultipleKMeans<V, M> makeInstance() {
return new BestOfMultipleKMeans<>(trials, kMeansVariant, qualityMeasure);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/CLARA.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/CLARA.java
new file mode 100644
index 00000000..0a47deba
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/CLARA.java
@@ -0,0 +1,244 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMedoidsInitialization;
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.data.model.MedoidModel;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+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.ModifiableDBIDs;
+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.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+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;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
+
+/**
+ * Clustering Large Applications (CLARA) is a clustering method for large data
+ * sets based on PAM, partitioning around medoids ({@link KMedoidsPAM}) based on
+ * sampling.
+ *
+ * Reference:
+ * <p>
+ * L. Kaufman, P. J. Rousseeuw<br />
+ * Clustering Large Data Sets (with discussion)<br />
+ * in: Pattern Recognition in Practice II
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @param <V> Vector type
+ */
+@Reference(authors = "L. Kaufman, P. J. Rousseeuw",//
+title = "Clustering Large Data Sets (with discussion)", //
+booktitle = "Pattern Recognition in Practice II")
+public class CLARA<V> extends KMedoidsPAM<V> {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(CLARA.class);
+
+ /**
+ * Sampling rate. If less than 1, it is considered to be a relative value.
+ */
+ double sampling;
+
+ /**
+ * Number of samples to draw (i.e. iterations).
+ */
+ int numsamples;
+
+ /**
+ * Random factory for initialization.
+ */
+ RandomFactory random;
+
+ public CLARA(DistanceFunction<? super V> distanceFunction, int k, int maxiter, KMedoidsInitialization<V> initializer, int numsamples, double sampling, RandomFactory random) {
+ super(distanceFunction, k, maxiter, initializer);
+ this.numsamples = numsamples;
+ this.sampling = sampling;
+ this.random = random;
+ }
+
+ @Override
+ public Clustering<MedoidModel> run(Database database, Relation<V> relation) {
+ if(relation.size() <= 0) {
+ return new Clustering<>("CLARA Clustering", "clara-clustering");
+ }
+ DBIDs ids = relation.getDBIDs();
+ int sampleSize = (int) ((sampling < 1.) ? sampling * ids.size() : sampling);
+ DistanceQuery<V> distQ = database.getDistanceQuery(relation, getDistanceFunction());
+
+ double best = Double.POSITIVE_INFINITY;
+ ArrayModifiableDBIDs bestmedoids = null;
+ List<ModifiableDBIDs> bestclusters = null;
+
+ FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Random samples.", numsamples, LOG) : null;
+ for(int j = 0; j < numsamples; j++) {
+ DBIDs rids = DBIDUtil.randomSample(ids, sampleSize, random);
+ // Choose initial medoids
+ ArrayModifiableDBIDs medoids = DBIDUtil.newArray(initializer.chooseInitialMedoids(k, rids, distQ));
+ // Setup cluster assignment store
+ List<ModifiableDBIDs> clusters = new ArrayList<>();
+ for(int i = 0; i < k; i++) {
+ clusters.add(DBIDUtil.newHashSet(relation.size() / k));
+ }
+ runPAMOptimization(distQ, rids, medoids, clusters);
+ double score = assignRemainingToNearestCluster(medoids, ids, rids, clusters, distQ);
+ if(score < best) {
+ best = score;
+ bestmedoids = medoids;
+ bestclusters = clusters;
+ }
+ LOG.incrementProcessed(prog);
+ }
+ LOG.ensureCompleted(prog);
+
+ // Wrap result
+ Clustering<MedoidModel> result = new Clustering<>("CLARA Clustering", "clara-clustering");
+ for(int i = 0; i < bestclusters.size(); i++) {
+ MedoidModel model = new MedoidModel(bestmedoids.get(i));
+ result.addToplevelCluster(new Cluster<>(bestclusters.get(i), model));
+ }
+ return result;
+ }
+
+ /**
+ * Returns a list of clusters. The k<sup>th</sup> cluster contains the ids of
+ * those FeatureVectors, that are nearest to the k<sup>th</sup> mean.
+ *
+ * @param means Object centroids
+ * @param ids Object ids
+ * @param rids Sample that was already assigned
+ * @param clusters cluster assignment
+ * @param distQ distance query
+ * @return Sum of distances.
+ */
+ protected double assignRemainingToNearestCluster(ArrayDBIDs means, DBIDs ids, DBIDs rids, List<? extends ModifiableDBIDs> clusters, DistanceQuery<V> distQ) {
+ rids = DBIDUtil.ensureSet(rids); // Ensure we have fast contains
+ double distsum = 0.;
+ DBIDArrayIter miter = means.iter();
+ for(DBIDIter iditer = distQ.getRelation().iterDBIDs(); iditer.valid(); iditer.advance()) {
+ if(rids.contains(iditer)) {
+ continue;
+ }
+ double mindist = Double.POSITIVE_INFINITY;
+ int minIndex = 0;
+ miter.seek(0); // Reuse iterator.
+ for(int i = 0; miter.valid(); miter.advance(), i++) {
+ double dist = distQ.distance(iditer, miter);
+ if(dist < mindist) {
+ minIndex = i;
+ mindist = dist;
+ }
+ }
+ distsum += mindist;
+ clusters.get(minIndex).add(iditer);
+ }
+ return distsum;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V> extends KMedoidsPAM.Parameterizer<V> {
+ /**
+ * The number of samples to run.
+ */
+ public static final OptionID NUMSAMPLES_ID = new OptionID("clara.samples", "Number of samples (iterations) to run.");
+
+ /**
+ * The sample size.
+ */
+ public static final OptionID SAMPLESIZE_ID = new OptionID("clara.samplesize", "The size of the sample.");
+
+ /**
+ * Random generator.
+ */
+ public static final OptionID RANDOM_ID = new OptionID("clara.random", "Random generator seed.");
+
+ /**
+ * Sampling rate. If less than 1, it is considered to be a relative value.
+ */
+ double sampling;
+
+ /**
+ * Number of samples to draw (i.e. iterations).
+ */
+ int numsamples;
+
+ /**
+ * Random factory for initialization.
+ */
+ RandomFactory random;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ IntParameter numsamplesP = new IntParameter(NUMSAMPLES_ID, 5) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(numsamplesP)) {
+ numsamples = numsamplesP.intValue();
+ }
+
+ DoubleParameter samplingP = new DoubleParameter(SAMPLESIZE_ID) //
+ .addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ if(config.grab(samplingP)) {
+ sampling = samplingP.doubleValue();
+ }
+
+ RandomParameter randomP = new RandomParameter(RANDOM_ID);
+ if(config.grab(randomP)) {
+ random = randomP.getValue();
+ }
+ }
+
+ @Override
+ protected CLARA<V> makeInstance() {
+ return new CLARA<>(distanceFunction, k, maxiter, initializer, numsamples, sampling, random);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeans.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeans.java
index 29c0a5c8..32d7a978 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeans.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeans.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
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,11 +27,10 @@ import de.lmu.ifi.dbs.elki.algorithm.DistanceBasedAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.model.MeanModel;
+import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.database.Database;
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.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
/**
@@ -40,10 +39,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
* @author Erich Schubert
*
* @param <V> Number vector type
- * @param <D> Distance type
* @param <M> Actual model type
*/
-public interface KMeans<V extends NumberVector<?>, D extends Distance<?>, M extends MeanModel<V>> extends ClusteringAlgorithm<Clustering<M>>, DistanceBasedAlgorithm<V, D> {
+public interface KMeans<V extends NumberVector, M extends Model> extends ClusteringAlgorithm<Clustering<M>>, DistanceBasedAlgorithm<V> {
/**
* Parameter to specify the initialization method
*/
@@ -81,11 +79,11 @@ public interface KMeans<V extends NumberVector<?>, D extends Distance<?>, M exte
* @param k K parameter
*/
void setK(int k);
-
+
/**
* Set the distance function to use.
*
* @param distanceFunction Distance function.
*/
- void setDistanceFunction(PrimitiveDistanceFunction<? super NumberVector<?>, D> distanceFunction);
+ void setDistanceFunction(PrimitiveDistanceFunction<? super NumberVector> distanceFunction);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansBatchedLloyd.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansBatchedLloyd.java
index aec4fe0f..57c2a295 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansBatchedLloyd.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansBatchedLloyd.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
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,6 +27,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
@@ -43,13 +44,12 @@ import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
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.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
+import de.lmu.ifi.dbs.elki.logging.statistics.DoubleStatistic;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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;
@@ -57,7 +57,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
/**
- * Provides the k-means algorithm, using Lloyd-style bulk iterations.
+ * An algorithm for k-means, using Lloyd-style bulk iterations.
*
* However, in contrast to Lloyd's k-means and similar to MacQueen, we do update
* the mean vectors multiple times, not only at the very end of the iteration.
@@ -71,9 +71,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
* @apiviz.has KMeansModel
*
* @param <V> vector datatype
- * @param <D> distance value type
*/
-public class KMeansBatchedLloyd<V extends NumberVector<?>, D extends Distance<D>> extends AbstractKMeans<V, D, KMeansModel<V>> {
+public class KMeansBatchedLloyd<V extends NumberVector> extends AbstractKMeans<V, KMeansModel> {
/**
* The logger for this class.
*/
@@ -99,26 +98,21 @@ public class KMeansBatchedLloyd<V extends NumberVector<?>, D extends Distance<D>
* @param blocks Number of blocks
* @param random Random factory used for partitioning.
*/
- public KMeansBatchedLloyd(PrimitiveDistanceFunction<NumberVector<?>, D> distanceFunction, int k, int maxiter, KMeansInitialization<V> initializer, int blocks, RandomFactory random) {
+ public KMeansBatchedLloyd(PrimitiveDistanceFunction<NumberVector> distanceFunction, int k, int maxiter, KMeansInitialization<? super V> initializer, int blocks, RandomFactory random) {
super(distanceFunction, k, maxiter, initializer);
this.blocks = blocks;
this.random = random;
}
@Override
- public Clustering<KMeansModel<V>> run(Database database, Relation<V> relation) {
+ public Clustering<KMeansModel> run(Database database, Relation<V> relation) {
final int dim = RelationUtil.dimensionality(relation);
// Choose initial means
- List<? extends NumberVector<?>> mvs = initializer.chooseInitialMeans(database, relation, k, getDistanceFunction());
- // Convert to (modifiable) math vectors.
- List<Vector> means = new ArrayList<>(k);
- for (NumberVector<?> m : mvs) {
- means.add(m.getColumnVector());
- }
+ List<Vector> means = initializer.chooseInitialMeans(database, relation, k, getDistanceFunction(), Vector.FACTORY);
// Setup cluster assignment store
List<ModifiableDBIDs> clusters = new ArrayList<>();
- for (int i = 0; i < k; i++) {
+ for(int i = 0; i < k; i++) {
clusters.add(DBIDUtil.newHashSet((int) (relation.size() * 2. / k)));
}
WritableIntegerDataStore assignment = DataStoreUtil.makeIntegerStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, -1);
@@ -127,45 +121,44 @@ public class KMeansBatchedLloyd<V extends NumberVector<?>, D extends Distance<D>
double[][] meanshift = new double[k][dim];
int[] changesize = new int[k];
+ double[] varsum = new double[k];
IndefiniteProgress prog = LOG.isVerbose() ? new IndefiniteProgress("K-Means iteration", LOG) : null;
- for (int iteration = 0; maxiter <= 0 || iteration < maxiter; iteration++) {
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
+ DoubleStatistic varstat = LOG.isStatistics() ? new DoubleStatistic(this.getClass().getName() + ".variance-sum") : null;
+ for(int iteration = 0; maxiter <= 0 || iteration < maxiter; iteration++) {
+ LOG.incrementProcessed(prog);
boolean changed = false;
FiniteProgress pprog = LOG.isVerbose() ? new FiniteProgress("Batch", parts.length, LOG) : null;
- for (int p = 0; p < parts.length; p++) {
+ for(int p = 0; p < parts.length; p++) {
// Initialize new means scratch space.
- for (int i = 0; i < k; i++) {
+ for(int i = 0; i < k; i++) {
Arrays.fill(meanshift[i], 0.);
}
Arrays.fill(changesize, 0);
- changed |= assignToNearestCluster(relation, parts[p], means, meanshift, changesize, clusters, assignment);
+ Arrays.fill(varsum, 0.);
+ changed |= assignToNearestCluster(relation, parts[p], means, meanshift, changesize, clusters, assignment, varsum);
// Recompute means.
updateMeans(means, meanshift, clusters, changesize);
- if (pprog != null) {
- pprog.incrementProcessed(LOG);
- }
- }
- if (pprog != null) {
- pprog.ensureCompleted(LOG);
+ LOG.incrementProcessed(pprog);
}
+ LOG.ensureCompleted(pprog);
+ logVarstat(varstat, varsum);
// Stop if no cluster assignment changed.
- if (!changed) {
+ if(!changed) {
break;
}
}
- if (prog != null) {
- prog.setCompleted(LOG);
- }
+ LOG.setCompleted(prog);
// Wrap result
- final NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(relation);
- Clustering<KMeansModel<V>> result = new Clustering<>("k-Means Clustering", "kmeans-clustering");
- for (int i = 0; i < clusters.size(); i++) {
- KMeansModel<V> model = new KMeansModel<>(factory.newNumberVector(means.get(i).getColumnVector().getArrayRef()));
- result.addToplevelCluster(new Cluster<>(clusters.get(i), model));
+ Clustering<KMeansModel> result = new Clustering<>("k-Means Clustering", "kmeans-clustering");
+ for(int i = 0; i < clusters.size(); i++) {
+ DBIDs ids = clusters.get(i);
+ if(ids.size() == 0) {
+ continue;
+ }
+ KMeansModel model = new KMeansModel(means.get(i), varsum[i]);
+ result.addToplevelCluster(new Cluster<>(ids, model));
}
return result;
}
@@ -181,42 +174,26 @@ public class KMeansBatchedLloyd<V extends NumberVector<?>, D extends Distance<D>
* @param changesize New cluster sizes
* @param clusters cluster assignment
* @param assignment Current cluster assignment
+ * @param varsum Sum of variances
* @return true when the object was reassigned
*/
- protected boolean assignToNearestCluster(Relation<V> relation, DBIDs ids, List<? extends NumberVector<?>> oldmeans, double[][] meanshift, int[] changesize, List<? extends ModifiableDBIDs> clusters, WritableIntegerDataStore assignment) {
+ protected boolean assignToNearestCluster(Relation<V> relation, DBIDs ids, List<? extends NumberVector> oldmeans, double[][] meanshift, int[] changesize, List<? extends ModifiableDBIDs> clusters, WritableIntegerDataStore assignment, double[] varsum) {
boolean changed = false;
- if (getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction) {
- @SuppressWarnings("unchecked")
- final PrimitiveDoubleDistanceFunction<? super NumberVector<?>> df = (PrimitiveDoubleDistanceFunction<? super NumberVector<?>>) getDistanceFunction();
- for (DBIDIter iditer = ids.iter(); iditer.valid(); iditer.advance()) {
- double mindist = Double.POSITIVE_INFINITY;
- V fv = relation.get(iditer);
- int minIndex = 0;
- for (int i = 0; i < k; i++) {
- double dist = df.doubleDistance(fv, oldmeans.get(i));
- if (dist < mindist) {
- minIndex = i;
- mindist = dist;
- }
- }
- changed |= updateAssignment(iditer, fv, clusters, assignment, meanshift, changesize, minIndex);
- }
- } else {
- final PrimitiveDistanceFunction<? super NumberVector<?>, D> df = getDistanceFunction();
- for (DBIDIter iditer = ids.iter(); iditer.valid(); iditer.advance()) {
- D mindist = df.getDistanceFactory().infiniteDistance();
- V fv = relation.get(iditer);
- int minIndex = 0;
- for (int i = 0; i < k; i++) {
- D dist = df.distance(fv, oldmeans.get(i));
- if (dist.compareTo(mindist) < 0) {
- minIndex = i;
- mindist = dist;
- }
+ final PrimitiveDistanceFunction<? super NumberVector> df = getDistanceFunction();
+ for(DBIDIter iditer = ids.iter(); iditer.valid(); iditer.advance()) {
+ double mindist = Double.POSITIVE_INFINITY;
+ V fv = relation.get(iditer);
+ int minIndex = 0;
+ for(int i = 0; i < k; i++) {
+ double dist = df.distance(fv, oldmeans.get(i));
+ if(dist < mindist) {
+ minIndex = i;
+ mindist = dist;
}
- changed |= updateAssignment(iditer, fv, clusters, assignment, meanshift, changesize, minIndex);
}
+ varsum[minIndex] += mindist;
+ changed |= updateAssignment(iditer, fv, clusters, assignment, meanshift, changesize, minIndex);
}
return changed;
}
@@ -235,7 +212,7 @@ public class KMeansBatchedLloyd<V extends NumberVector<?>, D extends Distance<D>
*/
protected boolean updateAssignment(DBIDIter id, V fv, List<? extends ModifiableDBIDs> clusters, WritableIntegerDataStore assignment, double[][] meanshift, int[] changesize, int minIndex) {
int cur = assignment.intValue(id);
- if (cur == minIndex) {
+ if(cur == minIndex) {
return false;
}
// Add to new cluster.
@@ -243,16 +220,16 @@ public class KMeansBatchedLloyd<V extends NumberVector<?>, D extends Distance<D>
clusters.get(minIndex).add(id);
changesize[minIndex]++;
double[] raw = meanshift[minIndex];
- for (int j = 0; j < fv.getDimensionality(); j++) {
+ for(int j = 0; j < fv.getDimensionality(); j++) {
raw[j] += fv.doubleValue(j);
}
}
// Remove from previous cluster
- if (cur >= 0) {
+ if(cur >= 0) {
clusters.get(cur).remove(id);
changesize[cur]--;
double[] raw = meanshift[cur];
- for (int j = 0; j < fv.getDimensionality(); j++) {
+ for(int j = 0; j < fv.getDimensionality(); j++) {
raw[j] -= fv.doubleValue(j);
}
}
@@ -269,16 +246,16 @@ public class KMeansBatchedLloyd<V extends NumberVector<?>, D extends Distance<D>
* @param changesize Size of change (for weighting!)
*/
protected void updateMeans(List<Vector> means, double[][] meanshift, List<ModifiableDBIDs> clusters, int[] changesize) {
- for (int i = 0; i < k; i++) {
+ for(int i = 0; i < k; i++) {
int newsize = clusters.get(i).size(), oldsize = newsize - changesize[i];
- if (newsize == 0) {
+ if(newsize == 0) {
continue; // Keep previous mean vector.
}
- if (oldsize == 0) {
+ if(oldsize == 0) {
means.set(i, new Vector(meanshift[i]).times(1. / newsize));
continue; // Replace with new vector.
}
- if (oldsize == newsize) {
+ if(oldsize == newsize) {
means.get(i).plusTimesEquals(new Vector(meanshift[i]), 1. / (double) newsize);
continue;
}
@@ -298,7 +275,7 @@ public class KMeansBatchedLloyd<V extends NumberVector<?>, D extends Distance<D>
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends Distance<D>> extends AbstractKMeans.Parameterizer<V, D> {
+ public static class Parameterizer<V extends NumberVector> extends AbstractKMeans.Parameterizer<V> {
/**
* Parameter for the number of blocks.
*/
@@ -324,11 +301,11 @@ public class KMeansBatchedLloyd<V extends NumberVector<?>, D extends Distance<D>
super.makeOptions(config);
IntParameter blocksP = new IntParameter(BLOCKS_ID, 10);
blocksP.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
- if (config.grab(blocksP)) {
+ if(config.grab(blocksP)) {
blocks = blocksP.intValue();
}
RandomParameter randomP = new RandomParameter(RANDOM_ID);
- if (config.grab(randomP)) {
+ if(config.grab(randomP)) {
random = randomP.getValue();
}
}
@@ -339,7 +316,7 @@ public class KMeansBatchedLloyd<V extends NumberVector<?>, D extends Distance<D>
}
@Override
- protected KMeansBatchedLloyd<V, D> makeInstance() {
+ protected KMeansBatchedLloyd<V> makeInstance() {
return new KMeansBatchedLloyd<>(distanceFunction, k, maxiter, initializer, blocks, random);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansBisecting.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansBisecting.java
index 80a581b1..c6361550 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansBisecting.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansBisecting.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
/*
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
@@ -35,7 +35,6 @@ import de.lmu.ifi.dbs.elki.database.ProxyDatabase;
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.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
@@ -63,11 +62,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @author Stephan Baier
*
* @param <V> Vector type
- * @param <D> Distance type
* @param <M> Model type
*/
@Reference(authors = "M. Steinbach, G. Karypis, V. Kumar", title = "A Comparison of Document Clustering Techniques", booktitle = "KDD workshop on text mining. Vol. 400. No. 1")
-public class KMeansBisecting<V extends NumberVector<?>, D extends Distance<?>, M extends MeanModel<V>> extends AbstractAlgorithm<Clustering<M>> implements KMeans<V, D, M> {
+public class KMeansBisecting<V extends NumberVector, M extends MeanModel> extends AbstractAlgorithm<Clustering<M>> implements KMeans<V, M> {
/**
* The logger for this class.
*/
@@ -76,7 +74,7 @@ public class KMeansBisecting<V extends NumberVector<?>, D extends Distance<?>, M
/**
* Variant of kMeans for the bisecting step.
*/
- private KMeans<V, D, M> innerkMeans;
+ private KMeans<V, M> innerkMeans;
/**
* Desired value of k.
@@ -89,7 +87,7 @@ public class KMeansBisecting<V extends NumberVector<?>, D extends Distance<?>, M
* @param k k parameter - number of result clusters
* @param innerkMeans KMeans variant parameter - for bisecting step
*/
- public KMeansBisecting(int k, KMeans<V, D, M> innerkMeans) {
+ public KMeansBisecting(int k, KMeans<V, M> innerkMeans) {
super();
this.k = k;
this.innerkMeans = innerkMeans;
@@ -128,16 +126,12 @@ public class KMeansBisecting<V extends NumberVector<?>, D extends Distance<?>, M
// Add resulting clusters to current result.
currentClusterList.addAll(innerResult.getAllClusters());
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
if (LOG.isVerbose()) {
LOG.verbose("Iteration " + j);
}
}
- if (prog != null) {
- prog.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(prog);
// add all current clusters to the result
Clustering<M> result = new Clustering<>("Bisecting k-Means Result", "Bisecting-k-means");
@@ -153,7 +147,7 @@ public class KMeansBisecting<V extends NumberVector<?>, D extends Distance<?>, M
}
@Override
- public DistanceFunction<? super V, D> getDistanceFunction() {
+ public DistanceFunction<? super V> getDistanceFunction() {
return innerkMeans.getDistanceFunction();
}
@@ -163,7 +157,7 @@ public class KMeansBisecting<V extends NumberVector<?>, D extends Distance<?>, M
}
@Override
- public void setDistanceFunction(PrimitiveDistanceFunction<? super NumberVector<?>, D> distanceFunction) {
+ public void setDistanceFunction(PrimitiveDistanceFunction<? super NumberVector> distanceFunction) {
innerkMeans.setDistanceFunction(distanceFunction);
}
@@ -181,10 +175,9 @@ public class KMeansBisecting<V extends NumberVector<?>, D extends Distance<?>, M
* @apiviz.exclude
*
* @param <V> Vector type
- * @param <D> Distance type
* @param <M> Model type
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends Distance<?>, M extends MeanModel<V>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector, M extends MeanModel> extends AbstractParameterizer {
/**
* Parameter to specify the kMeans variant.
*/
@@ -193,7 +186,7 @@ public class KMeansBisecting<V extends NumberVector<?>, D extends Distance<?>, M
/**
* Variant of kMeans
*/
- protected KMeans<V, D, M> kMeansVariant;
+ protected KMeans<V, M> kMeansVariant;
/**
* Desired number of clusters.
@@ -210,7 +203,7 @@ public class KMeansBisecting<V extends NumberVector<?>, D extends Distance<?>, M
k = kP.intValue();
}
- ObjectParameter<KMeans<V, D, M>> kMeansVariantP = new ObjectParameter<>(KMEANS_ID, KMeans.class, BestOfMultipleKMeans.class);
+ ObjectParameter<KMeans<V, M>> kMeansVariantP = new ObjectParameter<>(KMEANS_ID, KMeans.class, BestOfMultipleKMeans.class);
if (config.grab(kMeansVariantP)) {
ListParameterization kMeansVariantParameters = new ListParameterization();
@@ -224,7 +217,7 @@ public class KMeansBisecting<V extends NumberVector<?>, D extends Distance<?>, M
}
@Override
- protected KMeansBisecting<V, D, M> makeInstance() {
+ protected KMeansBisecting<V, M> makeInstance() {
return new KMeansBisecting<>(k, kMeansVariant);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansHybridLloydMacQueen.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansHybridLloydMacQueen.java
index 2a60ef27..a978745a 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansHybridLloydMacQueen.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansHybridLloydMacQueen.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
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,6 +26,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
import java.util.ArrayList;
import java.util.List;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
@@ -35,28 +36,26 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
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.ModifiableDBIDs;
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.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
+import de.lmu.ifi.dbs.elki.logging.statistics.DoubleStatistic;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
/**
- * Provides the k-means algorithm, alternating between MacQueen-style
- * incremental processing and Lloyd-Style batch steps.
+ * A hybrid k-means algorithm, alternating between MacQueen-style incremental
+ * processing and Lloyd-Style batch steps.
*
* @author Erich Schubert
*
- * @apiviz.landmark
* @apiviz.has KMeansModel
*
* @param <V> vector datatype
- * @param <D> distance value type
*/
-public class KMeansHybridLloydMacQueen<V extends NumberVector<?>, D extends Distance<D>> extends AbstractKMeans<V, D, KMeansModel<V>> {
+public class KMeansHybridLloydMacQueen<V extends NumberVector> extends AbstractKMeans<V, KMeansModel> {
/**
* The logger for this class.
*/
@@ -70,61 +69,59 @@ public class KMeansHybridLloydMacQueen<V extends NumberVector<?>, D extends Dist
* @param maxiter Maxiter parameter
* @param initializer Initialization method
*/
- public KMeansHybridLloydMacQueen(PrimitiveDistanceFunction<NumberVector<?>, D> distanceFunction, int k, int maxiter, KMeansInitialization<V> initializer) {
+ public KMeansHybridLloydMacQueen(PrimitiveDistanceFunction<NumberVector> distanceFunction, int k, int maxiter, KMeansInitialization<? super V> initializer) {
super(distanceFunction, k, maxiter, initializer);
}
@Override
- public Clustering<KMeansModel<V>> run(Database database, Relation<V> relation) {
- if (relation.size() <= 0) {
+ public Clustering<KMeansModel> run(Database database, Relation<V> relation) {
+ if(relation.size() <= 0) {
return new Clustering<>("k-Means Clustering", "kmeans-clustering");
}
// Choose initial means
- List<Vector> means = new ArrayList<>(k);
- for (NumberVector<?> nv : initializer.chooseInitialMeans(database, relation, k, getDistanceFunction())) {
- means.add(nv.getColumnVector());
- }
+ List<Vector> means = initializer.chooseInitialMeans(database, relation, k, getDistanceFunction(), Vector.FACTORY);
// Setup cluster assignment store
List<ModifiableDBIDs> clusters = new ArrayList<>();
- for (int i = 0; i < k; i++) {
+ for(int i = 0; i < k; i++) {
clusters.add(DBIDUtil.newHashSet((int) (relation.size() * 2. / k)));
}
WritableIntegerDataStore assignment = DataStoreUtil.makeIntegerStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, -1);
+ double[] varsum = new double[k];
IndefiniteProgress prog = LOG.isVerbose() ? new IndefiniteProgress("K-Means iteration", LOG) : null;
- for (int iteration = 0; maxiter <= 0 || iteration < maxiter; iteration += 2) {
+ DoubleStatistic varstat = LOG.isStatistics() ? new DoubleStatistic(this.getClass().getName() + ".variance-sum") : null;
+ for(int iteration = 0; maxiter <= 0 || iteration < maxiter; iteration += 2) {
{ // MacQueen
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- boolean changed = macQueenIterate(relation, means, clusters, assignment);
- if (!changed) {
+ LOG.incrementProcessed(prog);
+ boolean changed = macQueenIterate(relation, means, clusters, assignment, varsum);
+ logVarstat(varstat, varsum);
+ if(!changed) {
break;
}
}
{ // Lloyd
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- boolean changed = assignToNearestCluster(relation, means, clusters, assignment);
+ LOG.incrementProcessed(prog);
+ boolean changed = assignToNearestCluster(relation, means, clusters, assignment, varsum);
+ logVarstat(varstat, varsum);
// Stop if no cluster assignment changed.
- if (!changed) {
+ if(!changed) {
break;
}
// Recompute means.
means = means(clusters, means, relation);
}
}
- if (prog != null) {
- prog.setCompleted(LOG);
- }
+ LOG.setCompleted(prog);
// Wrap result
- final NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(relation);
- Clustering<KMeansModel<V>> result = new Clustering<>("k-Means Clustering", "kmeans-clustering");
- for (int i = 0; i < clusters.size(); i++) {
- KMeansModel<V> model = new KMeansModel<>(factory.newNumberVector(means.get(i).getColumnVector().getArrayRef()));
- result.addToplevelCluster(new Cluster<>(clusters.get(i), model));
+ Clustering<KMeansModel> result = new Clustering<>("k-Means Clustering", "kmeans-clustering");
+ for(int i = 0; i < clusters.size(); i++) {
+ DBIDs ids = clusters.get(i);
+ if(ids.size() == 0) {
+ continue;
+ }
+ KMeansModel model = new KMeansModel(means.get(i), varsum[i]);
+ result.addToplevelCluster(new Cluster<>(ids, model));
}
return result;
}
@@ -141,14 +138,14 @@ public class KMeansHybridLloydMacQueen<V extends NumberVector<?>, D extends Dist
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends Distance<D>> extends AbstractKMeans.Parameterizer<V, D> {
+ public static class Parameterizer<V extends NumberVector> extends AbstractKMeans.Parameterizer<V> {
@Override
protected Logging getLogger() {
return LOG;
}
@Override
- protected KMeansHybridLloydMacQueen<V, D> makeInstance() {
+ protected KMeansHybridLloydMacQueen<V> makeInstance() {
return new KMeansHybridLloydMacQueen<>(distanceFunction, k, maxiter, initializer);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansLloyd.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansLloyd.java
index 686e2076..ed92190d 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansLloyd.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansLloyd.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
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,6 +26,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
import java.util.ArrayList;
import java.util.List;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
@@ -35,19 +36,20 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
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.ModifiableDBIDs;
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.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
+import de.lmu.ifi.dbs.elki.logging.statistics.DoubleStatistic;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
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;
/**
- * Provides the k-means algorithm, using Lloyd-style bulk iterations.
+ * The standard k-means algorithm, using Lloyd-style bulk iterations.
*
* <p>
* Reference:<br />
@@ -63,12 +65,14 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
* @apiviz.has KMeansModel
*
* @param <V> vector datatype
- * @param <D> distance value type
*/
@Title("K-Means")
-@Description("Finds a partitioning into k clusters.")
-@Reference(authors = "S. Lloyd", title = "Least squares quantization in PCM", booktitle = "IEEE Transactions on Information Theory 28 (2): 129–137.", url = "http://dx.doi.org/10.1109/TIT.1982.1056489")
-public class KMeansLloyd<V extends NumberVector<?>, D extends Distance<D>> extends AbstractKMeans<V, D, KMeansModel<V>> {
+@Description("Finds a least-squared partitioning into k clusters.")
+@Reference(authors = "S. Lloyd", //
+title = "Least squares quantization in PCM", //
+booktitle = "IEEE Transactions on Information Theory 28 (2): 129–137.", //
+url = "http://dx.doi.org/10.1109/TIT.1982.1056489")
+public class KMeansLloyd<V extends NumberVector> extends AbstractKMeans<V, KMeansModel> {
/**
* The logger for this class.
*/
@@ -82,47 +86,49 @@ public class KMeansLloyd<V extends NumberVector<?>, D extends Distance<D>> exten
* @param maxiter Maxiter parameter
* @param initializer Initialization method
*/
- public KMeansLloyd(PrimitiveDistanceFunction<NumberVector<?>, D> distanceFunction, int k, int maxiter, KMeansInitialization<V> initializer) {
+ public KMeansLloyd(PrimitiveDistanceFunction<NumberVector> distanceFunction, int k, int maxiter, KMeansInitialization<? super V> initializer) {
super(distanceFunction, k, maxiter, initializer);
}
@Override
- public Clustering<KMeansModel<V>> run(Database database, Relation<V> relation) {
- if (relation.size() <= 0) {
+ public Clustering<KMeansModel> run(Database database, Relation<V> relation) {
+ if(relation.size() <= 0) {
return new Clustering<>("k-Means Clustering", "kmeans-clustering");
}
// Choose initial means
- List<? extends NumberVector<?>> means = initializer.chooseInitialMeans(database, relation, k, getDistanceFunction());
+ List<Vector> means = initializer.chooseInitialMeans(database, relation, k, getDistanceFunction(), Vector.FACTORY);
// Setup cluster assignment store
List<ModifiableDBIDs> clusters = new ArrayList<>();
- for (int i = 0; i < k; i++) {
+ for(int i = 0; i < k; i++) {
clusters.add(DBIDUtil.newHashSet((int) (relation.size() * 2. / k)));
}
WritableIntegerDataStore assignment = DataStoreUtil.makeIntegerStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, -1);
+ double[] varsum = new double[k];
IndefiniteProgress prog = LOG.isVerbose() ? new IndefiniteProgress("K-Means iteration", LOG) : null;
- for (int iteration = 0; maxiter <= 0 || iteration < maxiter; iteration++) {
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- boolean changed = assignToNearestCluster(relation, means, clusters, assignment);
+ DoubleStatistic varstat = LOG.isStatistics() ? new DoubleStatistic(this.getClass().getName() + ".variance-sum") : null;
+ for(int iteration = 0; maxiter <= 0 || iteration < maxiter; iteration++) {
+ LOG.incrementProcessed(prog);
+ boolean changed = assignToNearestCluster(relation, means, clusters, assignment, varsum);
+ logVarstat(varstat, varsum);
// Stop if no cluster assignment changed.
- if (!changed) {
+ if(!changed) {
break;
}
// Recompute means.
means = means(clusters, means, relation);
}
- if (prog != null) {
- prog.setCompleted(LOG);
- }
+ LOG.setCompleted(prog);
// Wrap result
- final NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(relation);
- Clustering<KMeansModel<V>> result = new Clustering<>("k-Means Clustering", "kmeans-clustering");
- for (int i = 0; i < clusters.size(); i++) {
- KMeansModel<V> model = new KMeansModel<>(factory.newNumberVector(means.get(i).getColumnVector().getArrayRef()));
- result.addToplevelCluster(new Cluster<>(clusters.get(i), model));
+ Clustering<KMeansModel> result = new Clustering<>("k-Means Clustering", "kmeans-clustering");
+ for(int i = 0; i < clusters.size(); i++) {
+ DBIDs ids = clusters.get(i);
+ if(ids.size() == 0) {
+ continue;
+ }
+ KMeansModel model = new KMeansModel(means.get(i), varsum[i]);
+ result.addToplevelCluster(new Cluster<>(ids, model));
}
return result;
}
@@ -139,14 +145,14 @@ public class KMeansLloyd<V extends NumberVector<?>, D extends Distance<D>> exten
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends Distance<D>> extends AbstractKMeans.Parameterizer<V, D> {
+ public static class Parameterizer<V extends NumberVector> extends AbstractKMeans.Parameterizer<V> {
@Override
protected Logging getLogger() {
return LOG;
}
@Override
- protected KMeansLloyd<V, D> makeInstance() {
+ protected KMeansLloyd<V> makeInstance() {
return new KMeansLloyd<>(distanceFunction, k, maxiter, initializer);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansMacQueen.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansMacQueen.java
index a0f4bb3f..7d2f805a 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansMacQueen.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansMacQueen.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
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,6 +26,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
import java.util.ArrayList;
import java.util.List;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
@@ -38,18 +39,22 @@ 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.ModifiableDBIDs;
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.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
+import de.lmu.ifi.dbs.elki.logging.statistics.DoubleStatistic;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
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;
/**
- * Provides the k-means algorithm, using MacQueen style incremental updates.
+ * The original k-means algorithm, using MacQueen style incremental updates;
+ * making this effectively an "online" (streaming) algorithm.
+ *
+ * This implementation will by default iterate over the data set until
+ * convergence, although MacQueen likely only meant to do a single pass over the
+ * data.
*
* <p>
* Reference:<br />
@@ -62,12 +67,14 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
* @apiviz.has KMeansModel
*
* @param <V> vector type to use
- * @param <D> distance function value type
*/
@Title("K-Means")
-@Description("Finds a partitioning into k clusters.")
-@Reference(authors = "J. MacQueen", title = "Some Methods for Classification and Analysis of Multivariate Observations", booktitle = "5th Berkeley Symp. Math. Statist. Prob., Vol. 1, 1967, pp 281-297", url = "http://projecteuclid.org/euclid.bsmsp/1200512992")
-public class KMeansMacQueen<V extends NumberVector<?>, D extends Distance<D>> extends AbstractKMeans<V, D, KMeansModel<V>> {
+@Description("Finds a least-squares partitioning into k clusters.")
+@Reference(authors = "J. MacQueen", //
+title = "Some Methods for Classification and Analysis of Multivariate Observations", //
+booktitle = "5th Berkeley Symp. Math. Statist. Prob., Vol. 1, 1967, pp 281-297", //
+url = "http://projecteuclid.org/euclid.bsmsp/1200512992")
+public class KMeansMacQueen<V extends NumberVector> extends AbstractKMeans<V, KMeansModel> {
/**
* The logger for this class.
*/
@@ -81,47 +88,44 @@ public class KMeansMacQueen<V extends NumberVector<?>, D extends Distance<D>> ex
* @param maxiter Maxiter parameter
* @param initializer Initialization method
*/
- public KMeansMacQueen(PrimitiveDistanceFunction<NumberVector<?>, D> distanceFunction, int k, int maxiter, KMeansInitialization<V> initializer) {
+ public KMeansMacQueen(PrimitiveDistanceFunction<NumberVector> distanceFunction, int k, int maxiter, KMeansInitialization<? super V> initializer) {
super(distanceFunction, k, maxiter, initializer);
}
@Override
- public Clustering<KMeansModel<V>> run(Database database, Relation<V> relation) {
- if (relation.size() <= 0) {
+ public Clustering<KMeansModel> run(Database database, Relation<V> relation) {
+ if(relation.size() <= 0) {
return new Clustering<>("k-Means Clustering", "kmeans-clustering");
}
// Choose initial means
- List<Vector> means = new ArrayList<>(k);
- for (NumberVector<?> nv : initializer.chooseInitialMeans(database, relation, k, getDistanceFunction())) {
- means.add(nv.getColumnVector());
- }
- // Initialize cluster and assign objects
+ List<Vector> means = initializer.chooseInitialMeans(database, relation, k, getDistanceFunction(), Vector.FACTORY);
List<ModifiableDBIDs> clusters = new ArrayList<>();
- for (int i = 0; i < k; i++) {
+ for(int i = 0; i < k; i++) {
clusters.add(DBIDUtil.newHashSet((int) (relation.size() * 2. / k)));
}
WritableIntegerDataStore assignment = DataStoreUtil.makeIntegerStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, -1);
+ double[] varsum = new double[k];
IndefiniteProgress prog = LOG.isVerbose() ? new IndefiniteProgress("K-Means iteration", LOG) : null;
- // Refine result
- for (int iteration = 0; maxiter <= 0 || iteration < maxiter; iteration++) {
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- boolean changed = macQueenIterate(relation, means, clusters, assignment);
- if (!changed) {
+ DoubleStatistic varstat = LOG.isStatistics() ? new DoubleStatistic(this.getClass().getName() + ".variance-sum") : null;
+ // Iterate MacQueen
+ for(int iteration = 0; maxiter <= 0 || iteration < maxiter; iteration++) {
+ LOG.incrementProcessed(prog);
+ boolean changed = macQueenIterate(relation, means, clusters, assignment, varsum);
+ logVarstat(varstat, varsum);
+ if(!changed) {
break;
}
}
- if (prog != null) {
- prog.setCompleted(LOG);
- }
+ LOG.setCompleted(prog);
- final NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(relation);
- Clustering<KMeansModel<V>> result = new Clustering<>("k-Means Clustering", "kmeans-clustering");
- for (int i = 0; i < clusters.size(); i++) {
+ Clustering<KMeansModel> result = new Clustering<>("k-Means Clustering", "kmeans-clustering");
+ for(int i = 0; i < clusters.size(); i++) {
DBIDs ids = clusters.get(i);
- KMeansModel<V> model = new KMeansModel<>(factory.newNumberVector(means.get(i).getArrayRef()));
+ if(ids.size() == 0) {
+ continue;
+ }
+ KMeansModel model = new KMeansModel(means.get(i), varsum[i]);
result.addToplevelCluster(new Cluster<>(ids, model));
}
return result;
@@ -139,14 +143,14 @@ public class KMeansMacQueen<V extends NumberVector<?>, D extends Distance<D>> ex
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends Distance<D>> extends AbstractKMeans.Parameterizer<V, D> {
+ public static class Parameterizer<V extends NumberVector> extends AbstractKMeans.Parameterizer<V> {
@Override
protected Logging getLogger() {
return LOG;
}
@Override
- protected KMeansMacQueen<V, D> makeInstance() {
+ protected KMeansMacQueen<V> makeInstance() {
return new KMeansMacQueen<>(distanceFunction, k, maxiter, initializer);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMediansLloyd.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMediansLloyd.java
index 0a97c4d3..49b67599 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMediansLloyd.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMediansLloyd.java
@@ -1,147 +1,148 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
-
-/*
- 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.ArrayList;
-import java.util.List;
-
-import de.lmu.ifi.dbs.elki.data.Cluster;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.model.MeanModel;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
-import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-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.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-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.Reference;
-import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
-
-/**
- * Provides the k-medians clustering algorithm, using Lloyd-style bulk
- * iterations.
- *
- * Reference:
- * <p>
- * Clustering via Concave Minimization<br />
- * P. S. Bradley, O. L. Mangasarian, W. N. Street<br />
- * in: Advances in neural information processing systems
- * </p>
- *
- * @author Erich Schubert
- *
- * @param <V> vector datatype
- * @param <D> distance value type
- */
-@Title("K-Medians")
-@Reference(title = "Clustering via Concave Minimization", authors = "P. S. Bradley, O. L. Mangasarian, W. N. Street", booktitle = "Advances in neural information processing systems", url = "http://nips.djvuzone.org/djvu/nips09/0368.djvu")
-public class KMediansLloyd<V extends NumberVector<?>, D extends Distance<D>> extends AbstractKMeans<V, D, MeanModel<V>> {
- /**
- * The logger for this class.
- */
- private static final Logging LOG = Logging.getLogger(KMediansLloyd.class);
-
- /**
- * Constructor.
- *
- * @param distanceFunction distance function
- * @param k k parameter
- * @param maxiter Maxiter parameter
- * @param initializer Initialization method
- */
- public KMediansLloyd(PrimitiveDistanceFunction<NumberVector<?>, D> distanceFunction, int k, int maxiter, KMeansInitialization<V> initializer) {
- super(distanceFunction, k, maxiter, initializer);
- }
-
- @Override
- public Clustering<MeanModel<V>> run(Database database, Relation<V> relation) {
- if (relation.size() <= 0) {
- return new Clustering<>("k-Medians Clustering", "kmedians-clustering");
- }
- // Choose initial medians
- List<? extends NumberVector<?>> medians = initializer.chooseInitialMeans(database, relation, k, getDistanceFunction());
- // Setup cluster assignment store
- List<ModifiableDBIDs> clusters = new ArrayList<>();
- for (int i = 0; i < k; i++) {
- clusters.add(DBIDUtil.newHashSet((int) (relation.size() * 2. / k)));
- }
- WritableIntegerDataStore assignment = DataStoreUtil.makeIntegerStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, -1);
-
- IndefiniteProgress prog = LOG.isVerbose() ? new IndefiniteProgress("K-Medians iteration", LOG) : null;
- for (int iteration = 0; maxiter <= 0 || iteration < maxiter; iteration++) {
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- boolean changed = assignToNearestCluster(relation, medians, clusters, assignment);
- // Stop if no cluster assignment changed.
- if (!changed) {
- break;
- }
- // Recompute medians.
- medians = medians(clusters, medians, relation);
- }
- if (prog != null) {
- prog.setCompleted(LOG);
- }
- // Wrap result
- final NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(relation);
- Clustering<MeanModel<V>> result = new Clustering<>("k-Medians Clustering", "kmedians-clustering");
- for (int i = 0; i < clusters.size(); i++) {
- MeanModel<V> model = new MeanModel<>(factory.newNumberVector(medians.get(i).getColumnVector().getArrayRef()));
- result.addToplevelCluster(new Cluster<>(clusters.get(i), model));
- }
- return result;
- }
-
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<V extends NumberVector<?>, D extends Distance<D>> extends AbstractKMeans.Parameterizer<V, D> {
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-
- @Override
- protected KMediansLloyd<V, D> makeInstance() {
- return new KMediansLloyd<>(distanceFunction, k, maxiter, initializer);
- }
- }
-}
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization;
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.MeanModel;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
+
+/**
+ * k-medians clustering algorithm, but using Lloyd-style bulk iterations instead
+ * of the more complicated approach suggested by Kaufman and Rousseeuw (see
+ * {@link KMedoidsPAM} instead).
+ *
+ * Reference:
+ * <p>
+ * Clustering via Concave Minimization<br />
+ * P. S. Bradley, O. L. Mangasarian, W. N. Street<br />
+ * in: Advances in Neural Information Processing Systems (NIPS)
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has MeanModel
+ *
+ * @param <V> vector datatype
+ */
+@Title("K-Medians")
+@Reference(title = "Clustering via Concave Minimization", //
+authors = "P. S. Bradley, O. L. Mangasarian, W. N. Street", //
+booktitle = "Advances in Neural Information Processing Systems", //
+url = "https://papers.nips.cc/paper/1260-clustering-via-concave-minimization.pdf")
+public class KMediansLloyd<V extends NumberVector> extends AbstractKMeans<V, MeanModel> {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(KMediansLloyd.class);
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction distance function
+ * @param k k parameter
+ * @param maxiter Maxiter parameter
+ * @param initializer Initialization method
+ */
+ public KMediansLloyd(PrimitiveDistanceFunction<? super NumberVector> distanceFunction, int k, int maxiter, KMeansInitialization<? super V> initializer) {
+ super(distanceFunction, k, maxiter, initializer);
+ }
+
+ @Override
+ public Clustering<MeanModel> run(Database database, Relation<V> relation) {
+ if(relation.size() <= 0) {
+ return new Clustering<>("k-Medians Clustering", "kmedians-clustering");
+ }
+ // Choose initial medians
+ List<Vector> medians = initializer.chooseInitialMeans(database, relation, k, getDistanceFunction(), Vector.FACTORY);
+ // Setup cluster assignment store
+ List<ModifiableDBIDs> clusters = new ArrayList<>();
+ for(int i = 0; i < k; i++) {
+ clusters.add(DBIDUtil.newHashSet((int) (relation.size() * 2. / k)));
+ }
+ WritableIntegerDataStore assignment = DataStoreUtil.makeIntegerStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, -1);
+ double[] distsum = new double[k];
+
+ IndefiniteProgress prog = LOG.isVerbose() ? new IndefiniteProgress("K-Medians iteration", LOG) : null;
+ for(int iteration = 0; maxiter <= 0 || iteration < maxiter; iteration++) {
+ LOG.incrementProcessed(prog);
+ boolean changed = assignToNearestCluster(relation, medians, clusters, assignment, distsum);
+ // Stop if no cluster assignment changed.
+ if(!changed) {
+ break;
+ }
+ // Recompute medians.
+ medians = medians(clusters, medians, relation);
+ }
+ LOG.setCompleted(prog);
+ // Wrap result
+ Clustering<MeanModel> result = new Clustering<>("k-Medians Clustering", "kmedians-clustering");
+ for(int i = 0; i < clusters.size(); i++) {
+ MeanModel model = new MeanModel(medians.get(i));
+ result.addToplevelCluster(new Cluster<>(clusters.get(i), model));
+ }
+ return result;
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractKMeans.Parameterizer<V> {
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ @Override
+ protected KMediansLloyd<V> makeInstance() {
+ return new KMediansLloyd<>(distanceFunction, k, maxiter, initializer);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMedoidsEM.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMedoidsEM.java
index 41cca225..d2f98466 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMedoidsEM.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMedoidsEM.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
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,9 @@ import java.util.ArrayList;
import java.util.List;
import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractPrimitiveDistanceBasedAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.FarthestPointsInitialMeans;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMedoidsInitialization;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.model.MedoidModel;
@@ -43,8 +44,7 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
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.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
import de.lmu.ifi.dbs.elki.math.Mean;
@@ -54,8 +54,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
- * Provides the k-medoids clustering algorithm, using a "bulk" variation of the
- * "Partitioning Around Medoids" approach.
+ * A k-medoids clustering algorithm, implemented as EM-style bulk algorithm.
*
* In contrast to PAM, which will in each iteration update one medoid with one
* (arbitrary) non-medoid, this implementation follows the EM pattern. In the
@@ -72,9 +71,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.composedOf KMedoidsInitialization
*
* @param <V> vector datatype
- * @param <D> distance value type
*/
-public class KMedoidsEM<V, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<V, D, Clustering<MedoidModel>> implements ClusteringAlgorithm<Clustering<MedoidModel>> {
+public class KMedoidsEM<V> extends AbstractDistanceBasedAlgorithm<V, Clustering<MedoidModel>> implements ClusteringAlgorithm<Clustering<MedoidModel>> {
/**
* The logger for this class.
*/
@@ -103,7 +101,7 @@ public class KMedoidsEM<V, D extends NumberDistance<D, ?>> extends AbstractDista
* @param maxiter Maxiter parameter
* @param initializer Function to generate the initial means
*/
- public KMedoidsEM(PrimitiveDistanceFunction<? super V, D> distanceFunction, int k, int maxiter, KMedoidsInitialization<V> initializer) {
+ public KMedoidsEM(DistanceFunction<? super V> distanceFunction, int k, int maxiter, KMedoidsInitialization<V> initializer) {
super(distanceFunction);
this.k = k;
this.maxiter = maxiter;
@@ -121,9 +119,9 @@ public class KMedoidsEM<V, D extends NumberDistance<D, ?>> extends AbstractDista
if(relation.size() <= 0) {
return new Clustering<>("k-Medoids Clustering", "kmedoids-clustering");
}
- DistanceQuery<V, D> distQ = database.getDistanceQuery(relation, getDistanceFunction());
+ DistanceQuery<V> distQ = database.getDistanceQuery(relation, getDistanceFunction());
// Choose initial medoids
- ArrayModifiableDBIDs medoids = DBIDUtil.newArray(initializer.chooseInitialMedoids(k, distQ));
+ ArrayModifiableDBIDs medoids = DBIDUtil.newArray(initializer.chooseInitialMedoids(k, relation.getDBIDs(), distQ));
// Setup cluster assignment store
List<ModifiableDBIDs> clusters = new ArrayList<>();
for(int i = 0; i < k; i++) {
@@ -139,9 +137,7 @@ public class KMedoidsEM<V, D extends NumberDistance<D, ?>> extends AbstractDista
// Swap phase
boolean changed = true;
while(changed) {
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
changed = false;
// Try to swap the medoid with a better cluster member:
int i = 0;
@@ -154,7 +150,7 @@ public class KMedoidsEM<V, D extends NumberDistance<D, ?>> extends AbstractDista
}
Mean mdist = new Mean();
for(DBIDIter iter2 = clusters.get(i).iter(); iter2.valid(); iter2.advance()) {
- mdist.put(distQ.distance(iter, iter2).doubleValue());
+ mdist.put(distQ.distance(iter, iter2));
}
if(mdist.getMean() < bestm.getMean()) {
best = DBIDUtil.deref(iter);
@@ -172,9 +168,7 @@ public class KMedoidsEM<V, D extends NumberDistance<D, ?>> extends AbstractDista
assignToNearestCluster(medoids, mdists, clusters, distQ);
}
}
- if(prog != null) {
- prog.setCompleted(LOG);
- }
+ LOG.setCompleted(prog);
// Wrap result
Clustering<MedoidModel> result = new Clustering<>("k-Medoids Clustering", "kmedoids-clustering");
@@ -195,7 +189,7 @@ public class KMedoidsEM<V, D extends NumberDistance<D, ?>> extends AbstractDista
* @param distQ distance query
* @return true when the object was reassigned
*/
- protected boolean assignToNearestCluster(ArrayDBIDs means, Mean[] mdist, List<? extends ModifiableDBIDs> clusters, DistanceQuery<V, D> distQ) {
+ protected boolean assignToNearestCluster(ArrayDBIDs means, Mean[] mdist, List<? extends ModifiableDBIDs> clusters, DistanceQuery<V> distQ) {
boolean changed = false;
double[] dists = new double[k];
@@ -205,7 +199,7 @@ public class KMedoidsEM<V, D extends NumberDistance<D, ?>> extends AbstractDista
{
int i = 0;
for(DBIDIter miter = means.iter(); miter.valid(); miter.advance(), i++) {
- dists[i] = distQ.distance(iditer, miter).doubleValue();
+ dists[i] = distQ.distance(iditer, miter);
if(dists[i] < mindist) {
minIndex = i;
mindist = dists[i];
@@ -247,7 +241,7 @@ public class KMedoidsEM<V, D extends NumberDistance<D, ?>> extends AbstractDista
*
* @apiviz.exclude
*/
- public static class Parameterizer<V, D extends NumberDistance<D, ?>> extends AbstractPrimitiveDistanceBasedAlgorithm.Parameterizer<V, D> {
+ public static class Parameterizer<V> extends AbstractDistanceBasedAlgorithm.Parameterizer<V> {
protected int k;
protected int maxiter;
@@ -263,7 +257,7 @@ public class KMedoidsEM<V, D extends NumberDistance<D, ?>> extends AbstractDista
k = kP.intValue();
}
- ObjectParameter<KMedoidsInitialization<V>> initialP = new ObjectParameter<>(KMeans.INIT_ID, KMedoidsInitialization.class, PAMInitialMeans.class);
+ ObjectParameter<KMedoidsInitialization<V>> initialP = new ObjectParameter<>(KMeans.INIT_ID, KMedoidsInitialization.class, FarthestPointsInitialMeans.class);
if(config.grab(initialP)) {
initializer = initialP.instantiateClass(config);
}
@@ -276,7 +270,7 @@ public class KMedoidsEM<V, D extends NumberDistance<D, ?>> extends AbstractDista
}
@Override
- protected KMedoidsEM<V, D> makeInstance() {
+ protected KMedoidsEM<V> makeInstance() {
return new KMedoidsEM<>(distanceFunction, k, maxiter, initializer);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMedoidsPAM.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMedoidsPAM.java
index c9e1dc47..30bb56e5 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMedoidsPAM.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMedoidsPAM.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
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,9 @@ import java.util.ArrayList;
import java.util.List;
import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractPrimitiveDistanceBasedAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMedoidsInitialization;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.PAMInitialMeans;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.model.MedoidModel;
@@ -40,15 +41,15 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
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.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
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.Reference;
@@ -59,14 +60,14 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
- * Provides the k-medoids clustering algorithm, using the
- * "Partitioning Around Medoids" approach.
+ * The original PAM algorithm or k-medoids clustering, as proposed by Kaufman
+ * and Rousseeuw in "Partitioning Around Medoids".
*
* Reference:
* <p>
* Clustering my means of Medoids<br />
* Kaufman, L. and Rousseeuw, P.J.<br />
- * in: Statistical Data Analysis Based on the L_1–Norm and Related Methods
+ * in: Statistical Data Analysis Based on the L1-Norm and Related Methods
* </p>
*
* @author Erich Schubert
@@ -75,23 +76,24 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.composedOf KMedoidsInitialization
*
* @param <V> vector datatype
- * @param <D> distance value type
*/
@Title("Partioning Around Medoids")
-@Reference(title = "Clustering my means of Medoids", authors = "Kaufman, L. and Rousseeuw, P.J.", booktitle = "Statistical Data Analysis Based on the L_1–Norm and Related Methods")
-public class KMedoidsPAM<V, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<V, D, Clustering<MedoidModel>> implements ClusteringAlgorithm<Clustering<MedoidModel>> {
+@Reference(title = "Clustering by means of Medoids", //
+authors = "Kaufman, L. and Rousseeuw, P.J.", //
+booktitle = "Statistical Data Analysis Based on the L1-Norm and Related Methods")
+public class KMedoidsPAM<V> extends AbstractDistanceBasedAlgorithm<V, Clustering<MedoidModel>> implements ClusteringAlgorithm<Clustering<MedoidModel>> {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(KMedoidsPAM.class);
/**
- * Holds the value of {@link AbstractKMeans#K_ID}.
+ * The number of clusters to produce.
*/
protected int k;
/**
- * Holds the value of {@link AbstractKMeans#MAXITER_ID}.
+ * The maximum number of iterations.
*/
protected int maxiter;
@@ -108,7 +110,7 @@ public class KMedoidsPAM<V, D extends NumberDistance<D, ?>> extends AbstractDist
* @param maxiter Maxiter parameter
* @param initializer Function to generate the initial means
*/
- public KMedoidsPAM(PrimitiveDistanceFunction<? super V, D> distanceFunction, int k, int maxiter, KMedoidsInitialization<V> initializer) {
+ public KMedoidsPAM(DistanceFunction<? super V> distanceFunction, int k, int maxiter, KMedoidsInitialization<V> initializer) {
super(distanceFunction);
this.k = k;
this.maxiter = maxiter;
@@ -126,16 +128,36 @@ public class KMedoidsPAM<V, D extends NumberDistance<D, ?>> extends AbstractDist
if(relation.size() <= 0) {
return new Clustering<>("k-Medoids Clustering", "kmedoids-clustering");
}
- DistanceQuery<V, D> distQ = database.getDistanceQuery(relation, getDistanceFunction());
+ DistanceQuery<V> distQ = database.getDistanceQuery(relation, getDistanceFunction());
DBIDs ids = relation.getDBIDs();
// Choose initial medoids
- ArrayModifiableDBIDs medoids = DBIDUtil.newArray(initializer.chooseInitialMedoids(k, distQ));
+ ArrayModifiableDBIDs medoids = DBIDUtil.newArray(initializer.chooseInitialMedoids(k, ids, distQ));
// Setup cluster assignment store
List<ModifiableDBIDs> clusters = new ArrayList<>();
for(int i = 0; i < k; i++) {
clusters.add(DBIDUtil.newHashSet(relation.size() / k));
}
+ runPAMOptimization(distQ, ids, medoids, clusters);
+
+ // Wrap result
+ Clustering<MedoidModel> result = new Clustering<>("k-Medoids Clustering", "kmedoids-clustering");
+ for(int i = 0; i < clusters.size(); i++) {
+ MedoidModel model = new MedoidModel(medoids.get(i));
+ result.addToplevelCluster(new Cluster<>(clusters.get(i), model));
+ }
+ return result;
+ }
+
+ /**
+ * Run the PAM optimization phase.
+ *
+ * @param distQ Distance query
+ * @param ids IDs to process
+ * @param medoids Medoids list
+ * @param clusters Clusters
+ */
+ protected void runPAMOptimization(DistanceQuery<V> distQ, DBIDs ids, ArrayModifiableDBIDs medoids, List<ModifiableDBIDs> clusters) {
WritableDoubleDataStore second = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
// Initial assignment to nearest medoids
// TODO: reuse this information, from the build phase, when possible?
@@ -143,15 +165,13 @@ public class KMedoidsPAM<V, D extends NumberDistance<D, ?>> extends AbstractDist
IndefiniteProgress prog = LOG.isVerbose() ? new IndefiniteProgress("PAM iteration", LOG) : null;
// Swap phase
+ DBIDVar bestid = DBIDUtil.newVar();
boolean changed = true;
while(changed) {
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
changed = false;
// Try to swap the medoid with a better cluster member:
double best = 0;
- DBID bestid = null;
int bestcluster = -1;
int i = 0;
for(DBIDIter miter = medoids.iter(); miter.valid(); miter.advance(), i++) {
@@ -159,30 +179,28 @@ public class KMedoidsPAM<V, D extends NumberDistance<D, ?>> extends AbstractDist
if(DBIDUtil.equal(miter, iter)) {
continue;
}
- // double disti = distQ.distance(id, med).doubleValue();
double cost = 0;
- DBIDIter olditer = medoids.iter();
- for(int j = 0; j < k; j++, olditer.advance()) {
+ DBIDIter miter2 = medoids.iter();
+ for(int j = 0; j < k; j++, miter2.advance()) {
for(DBIDIter iter2 = clusters.get(j).iter(); iter2.valid(); iter2.advance()) {
- double distcur = distQ.distance(iter2, olditer).doubleValue();
- double distnew = distQ.distance(iter2, iter).doubleValue();
+ if(DBIDUtil.equal(miter2, iter2)) {
+ continue;
+ }
+ double distcur = distQ.distance(iter2, miter2);
+ double distnew = distQ.distance(iter2, iter);
if(j == i) {
// Cases 1 and 2.
double distsec = second.doubleValue(iter2);
- if(distcur > distsec) {
- // Case 1, other would switch to a third medoid
- cost += distsec - distcur; // Always positive!
- }
- else { // Would remain with the candidate
- cost += distnew - distcur; // Could be negative
- }
+ cost += (distcur > distsec) ? //
+ // Case 1, other would switch to a third medoid
+ distsec - distcur // Always positive!
+ : // Would remain with the candidate
+ distnew - distcur; // Could be negative
}
else {
// Cases 3-4: objects from other clusters
- if(distcur < distnew) {
- // Case 3: no change
- }
- else {
+ // Case 3: is no change
+ if(distcur > distnew) {
// Case 4: would switch to new medoid
cost += distnew - distcur; // Always negative
}
@@ -191,18 +209,15 @@ public class KMedoidsPAM<V, D extends NumberDistance<D, ?>> extends AbstractDist
}
if(cost < best) {
best = cost;
- bestid = DBIDUtil.deref(iter);
+ bestid.set(iter);
bestcluster = i;
}
}
}
- if(prog != null) {
- prog.setCompleted(LOG);
- }
if(LOG.isDebugging()) {
LOG.debug("Best cost: " + best);
}
- if(bestid != null) {
+ if(best < 0.) {
changed = true;
medoids.set(bestcluster, bestid);
}
@@ -212,14 +227,7 @@ public class KMedoidsPAM<V, D extends NumberDistance<D, ?>> extends AbstractDist
assignToNearestCluster(medoids, ids, second, clusters, distQ);
}
}
-
- // Wrap result
- Clustering<MedoidModel> result = new Clustering<>("k-Medoids Clustering", "kmedoids-clustering");
- for(int i = 0; i < clusters.size(); i++) {
- MedoidModel model = new MedoidModel(medoids.get(i));
- result.addToplevelCluster(new Cluster<>(clusters.get(i), model));
- }
- return result;
+ LOG.setCompleted(prog);
}
/**
@@ -233,36 +241,32 @@ public class KMedoidsPAM<V, D extends NumberDistance<D, ?>> extends AbstractDist
* @param distQ distance query
* @return true when any object was reassigned
*/
- protected boolean assignToNearestCluster(ArrayDBIDs means, DBIDs ids, WritableDoubleDataStore second, List<? extends ModifiableDBIDs> clusters, DistanceQuery<V, D> distQ) {
+ protected boolean assignToNearestCluster(ArrayDBIDs means, DBIDs ids, WritableDoubleDataStore second, List<? extends ModifiableDBIDs> clusters, DistanceQuery<V> distQ) {
boolean changed = false;
+ DBIDArrayIter miter = means.iter();
for(DBIDIter iditer = distQ.getRelation().iterDBIDs(); iditer.valid(); iditer.advance()) {
+ double mindist = Double.POSITIVE_INFINITY, mindist2 = Double.POSITIVE_INFINITY;
int minIndex = 0;
- double mindist = Double.POSITIVE_INFINITY;
- double mindist2 = Double.POSITIVE_INFINITY;
- {
- int i = 0;
- for(DBIDIter miter = means.iter(); miter.valid(); miter.advance(), i++) {
- double dist = distQ.distance(iditer, miter).doubleValue();
- if(dist < mindist) {
- minIndex = i;
- mindist2 = mindist;
- mindist = dist;
- }
- else if(dist < mindist2) {
- mindist2 = dist;
- }
+ miter.seek(0); // Reuse iterator.
+ for(int i = 0; miter.valid(); miter.advance(), i++) {
+ double dist = distQ.distance(iditer, miter);
+ if(dist < mindist) {
+ minIndex = i;
+ mindist2 = mindist;
+ mindist = dist;
+ }
+ else if(dist < mindist2) {
+ mindist2 = dist;
}
}
if(clusters.get(minIndex).add(iditer)) {
changed = true;
// Remove from previous cluster
// TODO: keep a list of cluster assignments to save this search?
- for(int i = 0; i < k; i++) {
- if(i != minIndex) {
- if(clusters.get(i).remove(iditer)) {
- break;
- }
+ for(int j = 0; j < k; j++) {
+ if(j != minIndex && clusters.get(j).remove(iditer)) {
+ break;
}
}
}
@@ -288,18 +292,27 @@ public class KMedoidsPAM<V, D extends NumberDistance<D, ?>> extends AbstractDist
*
* @apiviz.exclude
*/
- public static class Parameterizer<V, D extends NumberDistance<D, ?>> extends AbstractPrimitiveDistanceBasedAlgorithm.Parameterizer<V, D> {
+ public static class Parameterizer<V> extends AbstractDistanceBasedAlgorithm.Parameterizer<V> {
+ /**
+ * The number of clusters to produce.
+ */
protected int k;
+ /**
+ * The maximum number of iterations.
+ */
protected int maxiter;
+ /**
+ * Method to choose initial means.
+ */
protected KMedoidsInitialization<V> initializer;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- IntParameter kP = new IntParameter(KMeans.K_ID);
- kP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ IntParameter kP = new IntParameter(KMeans.K_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
if(config.grab(kP)) {
k = kP.intValue();
}
@@ -309,15 +322,15 @@ public class KMedoidsPAM<V, D extends NumberDistance<D, ?>> extends AbstractDist
initializer = initialP.instantiateClass(config);
}
- IntParameter maxiterP = new IntParameter(KMeans.MAXITER_ID, 0);
- maxiterP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_INT);
+ IntParameter maxiterP = new IntParameter(KMeans.MAXITER_ID, 0) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_INT);
if(config.grab(maxiterP)) {
maxiter = maxiterP.intValue();
}
}
@Override
- protected KMedoidsPAM<V, D> makeInstance() {
+ protected KMedoidsPAM<V> makeInstance() {
return new KMedoidsPAM<>(distanceFunction, k, maxiter, initializer);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/SingleAssignmentKMeans.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/SingleAssignmentKMeans.java
new file mode 100644
index 00000000..d63d52d4
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/SingleAssignmentKMeans.java
@@ -0,0 +1,130 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization;
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.KMeansModel;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+
+/**
+ * Pseudo-k-Means variations, that assigns each object to the nearest center.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has KMeansModel
+ *
+ * @param <V> vector datatype
+ */
+public class SingleAssignmentKMeans<V extends NumberVector> extends AbstractKMeans<V, KMeansModel> {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(SingleAssignmentKMeans.class);
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction distance function
+ * @param k k parameter
+ * @param initializer Initialization method
+ */
+ public SingleAssignmentKMeans(PrimitiveDistanceFunction<NumberVector> distanceFunction, int k, KMeansInitialization<? super V> initializer) {
+ super(distanceFunction, k, -1, initializer);
+ }
+
+ @Override
+ public Clustering<KMeansModel> run(Database database, Relation<V> relation) {
+ if(relation.size() <= 0) {
+ return new Clustering<>("k-Means Assignment", "kmeans-assignment");
+ }
+ // Choose initial means
+ List<Vector> means = initializer.chooseInitialMeans(database, relation, k, getDistanceFunction(), Vector.FACTORY);
+ // Setup cluster assignment store
+ List<ModifiableDBIDs> clusters = new ArrayList<>();
+ for(int i = 0; i < k; i++) {
+ clusters.add(DBIDUtil.newHashSet((int) (relation.size() * 2. / k)));
+ }
+ WritableIntegerDataStore assignment = DataStoreUtil.makeIntegerStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, -1);
+ double[] varsum = new double[k];
+
+ assignToNearestCluster(relation, means, clusters, assignment, varsum);
+
+ // Wrap result
+ Clustering<KMeansModel> result = new Clustering<>("Nearest Centroid Clustering", "nearest-center-clustering");
+ for(int i = 0; i < clusters.size(); i++) {
+ KMeansModel model = new KMeansModel(means.get(i), varsum[i]);
+ result.addToplevelCluster(new Cluster<>(clusters.get(i), model));
+ }
+ return result;
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractKMeans.Parameterizer<V> {
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ // Do NOT invoke super.makeOptions, as we don't want to have the maxiter
+ // parameter, nor a warning for other distance functions.
+ getParameterDistanceFunction(config);
+ getParameterK(config);
+ getParameterInitialization(config);
+ }
+
+ @Override
+ protected SingleAssignmentKMeans<V> makeInstance() {
+ return new SingleAssignmentKMeans<>(distanceFunction, k, initializer);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/XMeans.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/XMeans.java
new file mode 100644
index 00000000..4e31a6ba
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/XMeans.java
@@ -0,0 +1,393 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.PredefinedInitialMeans;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.KMeansQualityMeasure;
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.VectorUtil;
+import de.lmu.ifi.dbs.elki.data.model.MeanModel;
+import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.ProxyDatabase;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+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.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.MutableProgress;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+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.constraints.LessEqualGlobalConstraint;
+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.IntParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
+
+/**
+ * X-means: Extending K-means with Efficient Estimation on the Number of
+ * Clusters.
+ *
+ * Note: this implementation does currently <em>not</em> use a k-d-tree for
+ * acceleration. Also note that k_max is not a hard threshold - the algorithm
+ * can return up to 2*k_max clusters!
+ *
+ * Reference:<br>
+ * <p>
+ * D. Pelleg, A. Moore:<br />
+ * X-means: Extending K-means with Efficient Estimation on the Number of
+ * Clusters<br />
+ * In: Proceedings of the 17th International Conference on Machine Learning
+ * (ICML 2000)
+ * </p>
+ *
+ * @author Tibor Goldschwendt
+ * @author Erich Schubert
+ *
+ * @param <V> Vector type
+ * @param <M> Model type
+ */
+@Reference(authors = "D. Pelleg, A. Moore", //
+booktitle = "X-means: Extending K-means with Efficient Estimation on the Number of Clusters", //
+title = "Proceedings of the 17th International Conference on Machine Learning (ICML 2000)", //
+url = "http://www.pelleg.org/shared/hp/download/xmeans.ps")
+public class XMeans<V extends NumberVector, M extends MeanModel> extends AbstractKMeans<V, M> {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(XMeans.class);
+
+ /**
+ * Inner k-means algorithm.
+ */
+ private KMeans<V, M> innerKMeans;
+
+ /**
+ * Effective number of clusters, minimum and maximum.
+ */
+ private int k, k_min, k_max;
+
+ /**
+ * Initializer for k-means.
+ */
+ PredefinedInitialMeans splitInitializer;
+
+ /**
+ * Information criterion to choose the better split.
+ */
+ KMeansQualityMeasure<V> informationCriterion;
+
+ /**
+ * Random factory.
+ */
+ RandomFactory rnd;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function
+ * @param k_min k_min parameter - minimum number of result clusters
+ * @param k_max k_max parameter - maximum number of result clusters
+ * @param maxiter Maximum number of iterations each.
+ * @param innerKMeans K-Means variant to use inside.
+ * @param informationCriterion The information criterion used for the
+ * splitting step
+ * @param random Random factory
+ */
+ public XMeans(PrimitiveDistanceFunction<? super NumberVector> distanceFunction, int k_min, int k_max, int maxiter, KMeans<V, M> innerKMeans, KMeansInitialization<? super V> initializer, PredefinedInitialMeans splitInitializer, KMeansQualityMeasure<V> informationCriterion, RandomFactory random) {
+ super(distanceFunction, k_min, maxiter, initializer);
+ this.k_min = k_min;
+ this.k_max = k_max;
+ this.k = k_min;
+ this.innerKMeans = innerKMeans;
+ this.splitInitializer = splitInitializer;
+ this.informationCriterion = informationCriterion;
+ this.rnd = random;
+ }
+
+ /**
+ * Run the algorithm on a database and relation.
+ *
+ * @param database Database to process
+ * @param relation Data relation
+ * @return Clustering result.
+ */
+ @Override
+ public Clustering<M> run(Database database, Relation<V> relation) {
+ MutableProgress prog = LOG.isVerbose() ? new MutableProgress("X-means number of clusters", k_max, LOG) : null;
+
+ // Run initial k-means to find at least k_min clusters
+ innerKMeans.setK(k_min);
+ splitInitializer.setInitialMeans(initializer.chooseInitialMeans(database, relation, k_min, getDistanceFunction(), Vector.FACTORY));
+ Clustering<M> clustering = innerKMeans.run(database, relation);
+
+ if(prog != null) {
+ prog.setProcessed(k_min, LOG);
+ }
+
+ ArrayList<Cluster<M>> clusters = new ArrayList<>(clustering.getAllClusters());
+ while(clusters.size() <= k_max) {
+ // Improve-Structure:
+ ArrayList<Cluster<M>> nextClusters = new ArrayList<>();
+ for(Cluster<M> cluster : clusters) {
+ // Try to split this cluster:
+ List<Cluster<M>> childClusterList = splitCluster(cluster, database, relation);
+ nextClusters.addAll(childClusterList);
+ if(childClusterList.size() > 1) {
+ k += childClusterList.size() - 1;
+ if(prog != null) {
+ if(k >= k_max) {
+ prog.setTotal(k + 1);
+ }
+ prog.setProcessed(k, LOG);
+ }
+ }
+ }
+ if(clusters.size() == nextClusters.size()) {
+ break;
+ }
+ // Improve-Params:
+ splitInitializer.setInitialClusters(nextClusters);
+ innerKMeans.setK(nextClusters.size());
+ clustering = innerKMeans.run(database, relation);
+ clusters.clear();
+ clusters.addAll(clustering.getAllClusters());
+ }
+
+ // Ensure that the progress bar finished.
+ if(prog != null) {
+ prog.setTotal(k);
+ prog.setProcessed(k, LOG);
+ }
+
+ if(LOG.isDebugging()) {
+ LOG.debug("X-means returned k=" + k + " clusters.");
+ }
+
+ // add all current clusters to the result
+ Clustering<M> result = new Clustering<>("X-Means Result", "X-Means", clusters);
+ return result;
+ }
+
+ /**
+ * Conditionally splits the clusters based on the information criterion.
+ *
+ * @param parentCluster Cluster to split
+ * @param database Database
+ * @param relation Data relation
+ * @return Parent cluster when split decreases clustering quality or child
+ * clusters when split improves clustering.
+ */
+ protected List<Cluster<M>> splitCluster(Cluster<M> parentCluster, Database database, Relation<V> relation) {
+ // Transform parent cluster into a clustering
+ ArrayList<Cluster<M>> parentClusterList = new ArrayList<Cluster<M>>(1);
+ parentClusterList.add(parentCluster);
+ Clustering<M> parentClustering = new Clustering<>(parentCluster.getName(), parentCluster.getName(), parentClusterList);
+
+ if(parentCluster.size() < 2) {
+ // Split is not possbile
+ return parentClusterList;
+ }
+
+ ProxyDatabase proxyDB = new ProxyDatabase(parentCluster.getIDs(), database);
+
+ splitInitializer.setInitialMeans(splitCentroid(parentCluster, relation));
+ innerKMeans.setK(2);
+ Clustering<M> childClustering = innerKMeans.run(proxyDB);
+
+ double parentEvaluation = informationCriterion.quality(parentClustering, getDistanceFunction(), relation);
+ double childrenEvaluation = informationCriterion.quality(childClustering, getDistanceFunction(), relation);
+
+ if(LOG.isDebugging()) {
+ LOG.debug("parentEvaluation: " + parentEvaluation);
+ LOG.debug("childrenEvaluation: " + childrenEvaluation);
+ }
+
+ // Check if split is an improvement:
+ return (childrenEvaluation > parentEvaluation) ^ informationCriterion.ascending() ? parentClusterList : childClustering.getAllClusters();
+ }
+
+ /**
+ * Split an existing centroid into two initial centers.
+ *
+ * @param parentCluster Existing cluster
+ * @param relation Data relation
+ * @return List of new centroids
+ */
+ protected List<? extends NumberVector> splitCentroid(Cluster<? extends MeanModel> parentCluster, Relation<V> relation) {
+ Vector parentCentroid = parentCluster.getModel().getMean();
+
+ // Compute size of cluster/region
+ double radius = 0.;
+ for(DBIDIter it = parentCluster.getIDs().iter(); it.valid(); it.advance()) {
+ double d = getDistanceFunction().distance(relation.get(it), parentCentroid);
+ radius = (d > radius) ? d : radius;
+ }
+
+ // Choose random vector
+ Random random = rnd.getSingleThreadedRandom();
+ final int dim = RelationUtil.dimensionality(relation);
+ Vector randomVector = VectorUtil.randomVector(Vector.FACTORY, dim, random).normalize();
+ randomVector.timesEquals((.4 + random.nextDouble() * .5) * radius);
+
+ // Get the new centroids
+ ArrayList<Vector> vecs = new ArrayList<>(2);
+ vecs.add(parentCentroid.minus(randomVector));
+ vecs.add(randomVector.plusEquals(parentCentroid));
+ return vecs;
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return innerKMeans.getInputTypeRestriction();
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Tibor Goldschwendt
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <V> Vector type
+ * @param <M> Model type of inner algorithm
+ */
+ public static class Parameterizer<V extends NumberVector, M extends MeanModel> extends AbstractKMeans.Parameterizer<V> {
+ /**
+ * Parameter to specify the kMeans variant.
+ */
+ public static final OptionID INNER_KMEANS_ID = new OptionID("xmeans.kmeans", "kMeans algorithm to use.");
+
+ /**
+ * Minimum number of clusters.
+ */
+ public static final OptionID K_MIN_ID = new OptionID("xmeans.k_min", "The minimum number of clusters to find.");
+
+ /**
+ * Randomization seed.
+ */
+ public static final OptionID SEED_ID = new OptionID("xmeans.seed", "Random seed for splitting clusters.");
+
+ /**
+ * Quality measure to use for evaluating splits.
+ */
+ public static final OptionID INFORMATION_CRITERION_ID = new OptionID("xmeans.quality", "The quality measure to evaluate splits (e.g. AIC, BIC)");
+
+ /**
+ * Variant of kMeans
+ */
+ protected KMeans<V, M> innerKMeans;
+
+ /**
+ * Class to feed splits to the internal k-means algorithm.
+ */
+ protected PredefinedInitialMeans splitInitializer;
+
+ /**
+ * Information criterion.
+ */
+ protected KMeansQualityMeasure<V> informationCriterion;
+
+ /**
+ * Minimum and maximum number of result clusters.
+ */
+ protected int k_min, k_max;
+
+ /**
+ * Random number generator.
+ */
+ private RandomFactory random;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ // Do NOT invoke super.makeOptions to hide the "k" parameter.
+ IntParameter kMinP = new IntParameter(K_MIN_ID, 2) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(kMinP)) {
+ k_min = kMinP.intValue();
+ }
+ IntParameter kMaxP = new IntParameter(KMeans.K_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(kMaxP)) {
+ k_max = kMaxP.intValue();
+ }
+ // We allow k_min = k_max.
+ config.checkConstraint(new LessEqualGlobalConstraint<>(kMinP, kMaxP));
+ getParameterInitialization(config);
+ getParameterMaxIter(config);
+ getParameterDistanceFunction(config);
+
+ RandomParameter rndP = new RandomParameter(SEED_ID);
+ if(config.grab(rndP)) {
+ random = rndP.getValue();
+ }
+ splitInitializer = new PredefinedInitialMeans((List<Vector>) null);
+
+ ObjectParameter<KMeans<V, M>> innerKMeansP = new ObjectParameter<>(INNER_KMEANS_ID, KMeans.class, KMeansLloyd.class);
+ if(config.grab(innerKMeansP)) {
+ ListParameterization initialKMeansVariantParameters = new ListParameterization();
+ initialKMeansVariantParameters.addParameter(KMeans.K_ID, k_min);
+ initialKMeansVariantParameters.addParameter(KMeans.INIT_ID, splitInitializer);
+ initialKMeansVariantParameters.addParameter(KMeans.MAXITER_ID, maxiter);
+ initialKMeansVariantParameters.addParameter(KMeans.DISTANCE_FUNCTION_ID, distanceFunction);
+ ChainedParameterization combinedConfig = new ChainedParameterization(initialKMeansVariantParameters, config);
+ combinedConfig.errorsTo(config);
+ innerKMeans = innerKMeansP.instantiateClass(combinedConfig);
+ }
+
+ ObjectParameter<KMeansQualityMeasure<V>> informationCriterionP = new ObjectParameter<>(INFORMATION_CRITERION_ID, KMeansQualityMeasure.class);
+ if(config.grab(informationCriterionP)) {
+ informationCriterion = informationCriterionP.instantiateClass(config);
+ }
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ @Override
+ protected XMeans<V, M> makeInstance() {
+ return new XMeans<V, M>(distanceFunction, k_min, k_max, maxiter, innerKMeans, initializer, splitInitializer, informationCriterion, random);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/AbstractKMeansInitialization.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/AbstractKMeansInitialization.java
index 9e3eb478..43c59c65 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/AbstractKMeansInitialization.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/AbstractKMeansInitialization.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization;
/*
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,7 +22,9 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
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.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeans;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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.RandomParameter;
@@ -34,7 +36,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
*
* @param <V> Vector type
*/
-public abstract class AbstractKMeansInitialization<V> implements KMeansInitialization<V> {
+public abstract class AbstractKMeansInitialization<V extends NumberVector> implements KMeansInitialization<V> {
/**
* Random number generator
*/
@@ -56,7 +58,7 @@ public abstract class AbstractKMeansInitialization<V> implements KMeansInitializ
*
* @apiviz.exclude
*/
- public abstract static class Parameterizer<V> extends AbstractParameterizer {
+ public abstract static class Parameterizer extends AbstractParameterizer {
/**
* Random generator
*/
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/FarthestPointsInitialMeans.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/FarthestPointsInitialMeans.java
index 9edfd816..599c3975 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/FarthestPointsInitialMeans.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/FarthestPointsInitialMeans.java
@@ -1,183 +1,199 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
-
-/*
- 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.ArrayList;
-import java.util.List;
-
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-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.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
-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.Flag;
-
-/**
- * K-Means initialization by repeatedly choosing the farthest point.
- *
- * Note: this is less random than other initializations, so running multiple
- * times will be more likely to return the same local minima.
- *
- * @author Erich Schubert
- *
- * @param <V> Vector type
- * @param <D> Distance type
- */
-public class FarthestPointsInitialMeans<V, D extends NumberDistance<D, ?>> extends AbstractKMeansInitialization<V> implements KMedoidsInitialization<V> {
- /**
- * Discard the first vector.
- */
- boolean dropfirst = true;
-
- /**
- * Constructor.
- *
- * @param rnd Random generator.
- * @param dropfirst Flag to discard the first vector.
- */
- public FarthestPointsInitialMeans(RandomFactory rnd, boolean dropfirst) {
- super(rnd);
- this.dropfirst = dropfirst;
- }
-
- @Override
- public List<V> chooseInitialMeans(Database database, Relation<V> relation, int k, PrimitiveDistanceFunction<? super NumberVector<?>, ?> distanceFunction) {
- // Get a distance query
- if(!(distanceFunction.getDistanceFactory() instanceof NumberDistance)) {
- throw new AbortException("Farthest points K-Means initialization can only be used with numerical distances.");
- }
- @SuppressWarnings("unchecked")
- final PrimitiveDistanceFunction<? super V, D> distF = (PrimitiveDistanceFunction<? super V, D>) distanceFunction;
- DistanceQuery<V, D> distQ = database.getDistanceQuery(relation, distF);
-
- // Chose first mean
- List<V> means = new ArrayList<>(k);
-
- DBIDIter first = DBIDUtil.randomSample(relation.getDBIDs(), 1, rnd).iter();
- means.add(relation.get(first));
-
- DBIDVar best = DBIDUtil.newVar(first);
- for(int i = (dropfirst ? 0 : 1); i < k; i++) {
- // Find farthest object:
- double maxdist = Double.NEGATIVE_INFINITY;
- for(DBIDIter it = relation.iterDBIDs(); it.valid(); it.advance()) {
- double dsum = 0.;
- for(V ex : means) {
- dsum += distQ.distance(ex, it).doubleValue();
- }
- if(dsum > maxdist) {
- maxdist = dsum;
- best.set(it);
- }
- }
- // Add new mean:
- if(k == 0) {
- means.clear(); // Remove temporary first element.
- }
- means.add(relation.get(best));
- }
-
- return means;
- }
-
- @Override
- public DBIDs chooseInitialMedoids(int k, DistanceQuery<? super V, ?> distQ2) {
- if(!(distQ2.getDistanceFactory() instanceof NumberDistance)) {
- throw new AbortException("Farthest points K-Means initialization can only be used with numerical distances.");
- }
- @SuppressWarnings("unchecked")
- DistanceQuery<? super V, D> distQ = (DistanceQuery<? super V, D>) distQ2;
- final Relation<?> relation = distQ.getRelation();
- // Chose first mean
- ArrayModifiableDBIDs means = DBIDUtil.newArray(k);
-
- DBIDIter first = DBIDUtil.randomSample(relation.getDBIDs(), 1, rnd).iter();
- means.add(first);
-
- DBIDVar best = DBIDUtil.newVar(first);
- for(int i = (dropfirst ? 0 : 1); i < k; i++) {
- // Find farthest object:
- double maxdist = Double.NEGATIVE_INFINITY;
- for(DBIDIter it = relation.iterDBIDs(); it.valid(); it.advance()) {
- double dsum = 0.;
- for(DBIDIter ex = means.iter(); ex.valid(); ex.advance()) {
- dsum += distQ.distance(ex, it).doubleValue();
- }
- if(dsum > maxdist) {
- maxdist = dsum;
- best.set(it);
- }
- }
- // Add new mean:
- if(k == 0) {
- means.clear(); // Remove temporary first element.
- }
- means.add(best);
- }
-
- return means;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<V, D extends NumberDistance<D, ?>> extends AbstractKMeansInitialization.Parameterizer<V> {
- /**
- * Option ID to control the handling of the first object chosen.
- */
- public static final OptionID DROPFIRST_ID = new OptionID("farthest.dropfirst", "Drop the first object chosen (which is chosen randomly) for the farthest points heuristic.");
-
- /**
- * Flag for discarding the first object chosen.
- */
- protected boolean dropfirst = true;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- Flag dropfirstP = new Flag(DROPFIRST_ID);
- if(config.grab(dropfirstP)) {
- dropfirst = dropfirstP.isTrue();
- }
- }
-
- @Override
- protected FarthestPointsInitialMeans<V, D> makeInstance() {
- return new FarthestPointsInitialMeans<>(rnd, dropfirst);
- }
- }
-}
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
+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.DBIDVar;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+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.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+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.Flag;
+
+/**
+ * K-Means initialization by repeatedly choosing the farthest point (by the
+ * <em>minimum</em> distance to earlier points).
+ *
+ * Note: this is less random than other initializations, so running multiple
+ * times will be more likely to return the same local minima.
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Object type for kMedoids and kMedians
+ */
+public class FarthestPointsInitialMeans<O> extends AbstractKMeansInitialization<NumberVector> implements KMedoidsInitialization<O> {
+ /**
+ * Discard the first vector.
+ */
+ boolean dropfirst = true;
+
+ /**
+ * Constructor.
+ *
+ * @param rnd Random generator.
+ * @param dropfirst Flag to discard the first vector.
+ */
+ public FarthestPointsInitialMeans(RandomFactory rnd, boolean dropfirst) {
+ super(rnd);
+ this.dropfirst = dropfirst;
+ }
+
+ @Override
+ public <T extends NumberVector, V extends NumberVector> List<V> chooseInitialMeans(Database database, Relation<T> relation, int k, PrimitiveDistanceFunction<? super T> distanceFunction, NumberVector.Factory<V> factory) {
+ // Get a distance query
+ DistanceQuery<T> distQ = database.getDistanceQuery(relation, distanceFunction);
+
+ DBIDs ids = relation.getDBIDs();
+ WritableDoubleDataStore store = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, Double.POSITIVE_INFINITY);
+
+ // Chose first mean
+ List<V> means = new ArrayList<>(k);
+
+ DBIDRef first = DBIDUtil.randomSample(ids, 1, rnd).iter();
+ T prevmean = relation.get(first);
+ means.add(factory.newNumberVector(prevmean));
+
+ // Find farthest object each.
+ DBIDVar best = DBIDUtil.newVar(first);
+ for(int i = (dropfirst ? 0 : 1); i < k; i++) {
+ double maxdist = Double.NEGATIVE_INFINITY;
+ for(DBIDIter it = ids.iter(); it.valid(); it.advance()) {
+ final double prev = store.doubleValue(it);
+ if(prev != prev) {
+ continue; // NaN: already chosen!
+ }
+ double val = Math.min(prev, distQ.distance(prevmean, it));
+ // Don't store distance to first mean, when it will be dropped below.
+ if(i > 0) {
+ store.putDouble(it, val);
+ }
+ if(val > maxdist) {
+ maxdist = val;
+ best.set(it);
+ }
+ }
+ // Add new mean (and drop the initial mean when desired)
+ if(i == 0) {
+ means.clear(); // Remove temporary first element.
+ }
+ store.putDouble(best, Double.NaN); // So it won't be chosen twice.
+ prevmean = relation.get(best);
+ means.add(factory.newNumberVector(prevmean));
+ }
+
+ // Explicitly destroy temporary data.
+ store.destroy();
+ return means;
+ }
+
+ @Override
+ public DBIDs chooseInitialMedoids(int k, DBIDs ids, DistanceQuery<? super O> distQ) {
+ @SuppressWarnings("unchecked")
+ final Relation<O> relation = (Relation<O>) distQ.getRelation();
+
+ WritableDoubleDataStore store = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, Double.POSITIVE_INFINITY);
+
+ ArrayModifiableDBIDs means = DBIDUtil.newArray(k);
+
+ DBIDRef first = DBIDUtil.randomSample(ids, 1, rnd).iter();
+ means.add(first);
+ O prevmean = relation.get(first);
+
+ DBIDVar best = DBIDUtil.newVar(first);
+ for(int i = (dropfirst ? 0 : 1); i < k; i++) {
+ // Find farthest object:
+ double maxdist = Double.NEGATIVE_INFINITY;
+ for(DBIDIter it = relation.iterDBIDs(); it.valid(); it.advance()) {
+ final double prev = store.doubleValue(it);
+ if(prev != prev) {
+ continue; // NaN: already chosen!
+ }
+ double val = Math.min(prev, distQ.distance(prevmean, it));
+ // Don't store distance to first mean, when it will be dropped below.
+ if(i > 0) {
+ store.putDouble(it, val);
+ }
+ if(val > maxdist) {
+ maxdist = val;
+ best.set(it);
+ }
+ }
+ // Add new mean:
+ if(i == 0) {
+ means.clear(); // Remove temporary first element.
+ }
+ store.putDouble(best, Double.NaN); // So it won't be chosen twice.
+ prevmean = relation.get(best);
+ means.add(best);
+ }
+
+ return means;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<O> extends AbstractKMeansInitialization.Parameterizer {
+ /**
+ * Option ID to control the handling of the first object chosen.
+ */
+ public static final OptionID KEEPFIRST_ID = new OptionID("farthest.keepfirst", "Keep the first object chosen (which is chosen randomly) for the farthest points heuristic.");
+
+ /**
+ * Flag for discarding the first object chosen.
+ */
+ protected boolean keepfirst = false;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ Flag dropfirstP = new Flag(KEEPFIRST_ID);
+ if(config.grab(dropfirstP)) {
+ keepfirst = dropfirstP.isTrue();
+ }
+ }
+
+ @Override
+ protected FarthestPointsInitialMeans<O> makeInstance() {
+ return new FarthestPointsInitialMeans<>(rnd, !keepfirst);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/FarthestSumPointsInitialMeans.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/FarthestSumPointsInitialMeans.java
new file mode 100644
index 00000000..c6b02e67
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/FarthestSumPointsInitialMeans.java
@@ -0,0 +1,176 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
+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.DBIDVar;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+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.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+
+/**
+ * K-Means initialization by repeatedly choosing the farthest point (by the
+ * <em>sum</em> of distances to previous objects).
+ *
+ * Note: this is less random than other initializations, so running multiple
+ * times will be more likely to return the same local minima.
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Object type for kmedoids and kmedians
+ */
+public class FarthestSumPointsInitialMeans<O> extends FarthestPointsInitialMeans<O> {
+ /**
+ * Constructor.
+ *
+ * @param rnd Random generator.
+ * @param dropfirst Flag to discard the first vector.
+ */
+ public FarthestSumPointsInitialMeans(RandomFactory rnd, boolean dropfirst) {
+ super(rnd, dropfirst);
+ }
+
+ @Override
+ public <T extends NumberVector, V extends NumberVector> List<V> chooseInitialMeans(Database database, Relation<T> relation, int k, PrimitiveDistanceFunction<? super T> distanceFunction, NumberVector.Factory<V> factory) {
+ // Get a distance query
+ DistanceQuery<T> distQ = database.getDistanceQuery(relation, distanceFunction);
+
+ DBIDs ids = relation.getDBIDs();
+ WritableDoubleDataStore store = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, 0.);
+
+ // Chose first mean
+ List<V> means = new ArrayList<>(k);
+
+ DBIDRef first = DBIDUtil.randomSample(ids, 1, rnd).iter();
+ T prevmean = relation.get(first);
+ means.add(factory.newNumberVector(prevmean));
+
+ // Find farthest object each.
+ DBIDVar best = DBIDUtil.newVar(first);
+ for(int i = (dropfirst ? 0 : 1); i < k; i++) {
+ double maxdist = Double.NEGATIVE_INFINITY;
+ for(DBIDIter it = ids.iter(); it.valid(); it.advance()) {
+ final double prev = store.doubleValue(it);
+ if(prev != prev) {
+ continue; // NaN: already chosen!
+ }
+ double dsum = prev + distQ.distance(prevmean, it);
+ // Don't store distance to first mean, when it will be dropped below.
+ if(i > 0) {
+ store.putDouble(it, dsum);
+ }
+ if(dsum > maxdist) {
+ maxdist = dsum;
+ best.set(it);
+ }
+ }
+ // Add new mean (and drop the initial mean when desired)
+ if(i == 0) {
+ means.clear(); // Remove temporary first element.
+ }
+ store.putDouble(best, Double.NaN); // So it won't be chosen twice.
+ prevmean = relation.get(best);
+ means.add(factory.newNumberVector(prevmean));
+ }
+
+ // Explicitly destroy temporary data.
+ store.destroy();
+ return means;
+ }
+
+ @Override
+ public DBIDs chooseInitialMedoids(int k, DBIDs ids, DistanceQuery<? super O> distQ) {
+ @SuppressWarnings("unchecked")
+ final Relation<O> relation = (Relation<O>) distQ.getRelation();
+
+ WritableDoubleDataStore store = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, 0.);
+
+ ArrayModifiableDBIDs means = DBIDUtil.newArray(k);
+
+ DBIDRef first = DBIDUtil.randomSample(ids, 1, rnd).iter();
+ means.add(first);
+ O prevmean = relation.get(first);
+
+ DBIDVar best = DBIDUtil.newVar(first);
+ for(int i = (dropfirst ? 0 : 1); i < k; i++) {
+ // Find farthest object:
+ double maxdist = Double.NEGATIVE_INFINITY;
+ for(DBIDIter it = relation.iterDBIDs(); it.valid(); it.advance()) {
+ final double prev = store.doubleValue(it);
+ if(prev != prev) {
+ continue; // NaN: already chosen!
+ }
+ double dsum = prev + distQ.distance(prevmean, it);
+ // Don't store distance to first mean, when it will be dropped below.
+ if(i > 0) {
+ store.putDouble(it, dsum);
+ }
+ if(dsum > maxdist) {
+ maxdist = dsum;
+ best.set(it);
+ }
+ }
+ // Add new mean:
+ if(k == 0) {
+ means.clear(); // Remove temporary first element.
+ }
+ store.putDouble(best, Double.NaN); // So it won't be chosen twice.
+ prevmean = relation.get(best);
+ means.add(best);
+ }
+
+ return means;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V> extends FarthestPointsInitialMeans.Parameterizer<V> {
+ /**
+ * Flag for discarding the first object chosen.
+ */
+ protected boolean keepfirst = false;
+
+ @Override
+ protected FarthestSumPointsInitialMeans<V> makeInstance() {
+ return new FarthestSumPointsInitialMeans<>(rnd, !keepfirst);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/FirstKInitialMeans.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/FirstKInitialMeans.java
index 08e2f116..af5a7717 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/FirstKInitialMeans.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/FirstKInitialMeans.java
@@ -1,87 +1,87 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
-
-/*
- 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.ArrayList;
-import java.util.List;
-
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-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.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-
-/**
- * Initialize K-means by using the first k objects as initial means.
- *
- * @author Erich Schubert
- *
- * @param <V> Vector type
- */
-public class FirstKInitialMeans<V> implements KMeansInitialization<V>, KMedoidsInitialization<V> {
- /**
- * Constructor.
- */
- public FirstKInitialMeans() {
- super();
- }
-
- @Override
- public List<V> chooseInitialMeans(Database database, Relation<V> relation, int k, PrimitiveDistanceFunction<? super NumberVector<?>, ?> distanceFunction) {
- DBIDIter iter = relation.iterDBIDs();
- List<V> means = new ArrayList<>(k);
- for(int i = 0; i < k && iter.valid(); i++, iter.advance()) {
- means.add(relation.get(iter));
- }
- return means;
- }
-
- @Override
- public DBIDs chooseInitialMedoids(int k, DistanceQuery<? super V, ?> distanceFunction) {
- DBIDIter iter = distanceFunction.getRelation().iterDBIDs();
- ArrayModifiableDBIDs means = DBIDUtil.newArray(k);
- for(int i = 0; i < k && iter.valid(); i++, iter.advance()) {
- means.add(iter);
- }
- return means;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
- @Override
- protected FirstKInitialMeans<V> makeInstance() {
- return new FirstKInitialMeans<>();
- }
- }
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+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.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Initialize K-means by using the first k objects as initial means.
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Object type for KMedoids
+ */
+public class FirstKInitialMeans<O> implements KMeansInitialization<NumberVector>, KMedoidsInitialization<O> {
+ /**
+ * Constructor.
+ */
+ public FirstKInitialMeans() {
+ super();
+ }
+
+ @Override
+ public <T extends NumberVector, V extends NumberVector> List<V> chooseInitialMeans(Database database, Relation<T> relation, int k, PrimitiveDistanceFunction<? super T> distanceFunction, NumberVector.Factory<V> factory) {
+ DBIDIter iter = relation.iterDBIDs();
+ List<V> means = new ArrayList<>(k);
+ for(int i = 0; i < k && iter.valid(); i++, iter.advance()) {
+ means.add(factory.newNumberVector(relation.get(iter)));
+ }
+ return means;
+ }
+
+ @Override
+ public DBIDs chooseInitialMedoids(int k, DBIDs ids, DistanceQuery<? super O> distanceFunction) {
+ DBIDIter iter = ids.iter();
+ ArrayModifiableDBIDs means = DBIDUtil.newArray(k);
+ for(int i = 0; i < k && iter.valid(); i++, iter.advance()) {
+ means.add(iter);
+ }
+ return means;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ @Override
+ protected FirstKInitialMeans<V> makeInstance() {
+ return new FirstKInitialMeans<>();
+ }
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansInitialization.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/KMeansInitialization.java
index 06fb10c1..e87b9d14 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansInitialization.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/KMeansInitialization.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization;
/*
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
@@ -36,9 +36,9 @@ import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
*
* @apiviz.landmark
*
- * @param <V> Object type
+ * @param <V> Vector type
*/
-public interface KMeansInitialization<V> {
+public interface KMeansInitialization<V extends NumberVector> {
/**
* Choose initial means
*
@@ -46,8 +46,10 @@ public interface KMeansInitialization<V> {
* @param relation Relation
* @param k Parameter k
* @param distanceFunction Distance function
- *
+ * @param factory Factory for output vectors.
+ * @param <T> Input vector type
+ * @param <O> Output vector type
* @return List of chosen means for k-means
*/
- public abstract List<V> chooseInitialMeans(Database database, Relation<V> relation, int k, PrimitiveDistanceFunction<? super NumberVector<?>, ?> distanceFunction);
+ public abstract <T extends V, O extends NumberVector> List<O> chooseInitialMeans(Database database, Relation<T> relation, int k, PrimitiveDistanceFunction<? super T> distanceFunction, NumberVector.Factory<O> factory);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansPlusPlusInitialMeans.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/KMeansPlusPlusInitialMeans.java
index 6fc514eb..977a4182 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMeansPlusPlusInitialMeans.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/KMeansPlusPlusInitialMeans.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization;
/*
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,21 +28,21 @@ import java.util.Random;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
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.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.query.distance.DistanceQuery;
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.distancefunction.PrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
/**
* K-Means++ initialization for k-means.
@@ -57,11 +57,10 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
*
* @author Erich Schubert
*
- * @param <V> Vector type
- * @param <D> Distance type
+ * @param <O> Vector type
*/
@Reference(authors = "D. Arthur, S. Vassilvitskii", title = "k-means++: the advantages of careful seeding", booktitle = "Proc. of the Eighteenth Annual ACM-SIAM Symposium on Discrete Algorithms, SODA 2007", url = "http://dx.doi.org/10.1145/1283383.1283494")
-public class KMeansPlusPlusInitialMeans<V, D extends NumberDistance<D, ?>> extends AbstractKMeansInitialization<V> implements KMedoidsInitialization<V> {
+public class KMeansPlusPlusInitialMeans<O> extends AbstractKMeansInitialization<NumberVector> implements KMedoidsInitialization<O> {
/**
* Constructor.
*
@@ -72,25 +71,20 @@ public class KMeansPlusPlusInitialMeans<V, D extends NumberDistance<D, ?>> exten
}
@Override
- public List<V> chooseInitialMeans(Database database, Relation<V> relation, int k, PrimitiveDistanceFunction<? super NumberVector<?>, ?> distanceFunction) {
- // Get a distance query
- if(!(distanceFunction.getDistanceFactory() instanceof NumberDistance)) {
- throw new AbortException("K-Means++ initialization can only be used with numerical distances.");
- }
- @SuppressWarnings("unchecked")
- final PrimitiveDistanceFunction<? super V, D> distF = (PrimitiveDistanceFunction<? super V, D>) distanceFunction;
- DistanceQuery<V, D> distQ = database.getDistanceQuery(relation, distF);
+ public <T extends NumberVector, V extends NumberVector> List<V> chooseInitialMeans(Database database, Relation<T> relation, int k, PrimitiveDistanceFunction<? super T> distanceFunction, NumberVector.Factory<V> factory) {
+ DistanceQuery<T> distQ = database.getDistanceQuery(relation, distanceFunction);
+
+ DBIDs ids = relation.getDBIDs();
+ WritableDoubleDataStore weights = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, 0.);
// Chose first mean
List<V> means = new ArrayList<>(k);
Random random = rnd.getSingleThreadedRandom();
- DBID first = DBIDUtil.deref(DBIDUtil.randomSample(relation.getDBIDs(), 1, random).iter());
- means.add(relation.get(first));
+ DBID first = DBIDUtil.deref(DBIDUtil.randomSample(ids, 1, random).iter());
+ means.add(factory.newNumberVector(relation.get(first)));
- ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs());
// Initialize weights
- double[] weights = new double[ids.size()];
double weightsum = initialWeights(weights, ids, first, distQ);
while(means.size() < k) {
if(weightsum > Double.MAX_VALUE) {
@@ -100,47 +94,43 @@ public class KMeansPlusPlusInitialMeans<V, D extends NumberDistance<D, ?>> exten
LoggingUtil.warning("Could not choose a reasonable mean for k-means++ - to few data points?");
}
double r = random.nextDouble() * weightsum;
- int pos = 0;
- while(r > 0 && pos < weights.length - 1) {
- r -= weights[pos];
- pos++;
+ DBIDIter it = ids.iter();
+ for(; r > 0. && it.valid(); it.advance()) {
+ double w = weights.doubleValue(it);
+ if(w != w) {
+ continue; // NaN: alrady chosen.
+ }
+ r -= w;
}
// Add new mean:
- DBID newmean = ids.get(pos);
- means.add(relation.get(newmean));
+ final T newmean = relation.get(it);
+ means.add(factory.newNumberVector(newmean));
// Update weights:
- weights[pos] = 0.0;
+ weights.putDouble(it, Double.NaN);
// Choose optimized version for double distances, if applicable.
- if(distF instanceof PrimitiveDoubleDistanceFunction) {
- @SuppressWarnings("unchecked")
- PrimitiveDoubleDistanceFunction<V> ddist = (PrimitiveDoubleDistanceFunction<V>) distF;
- weightsum = updateWeights(weights, ids, newmean, ddist, relation);
- }
- else {
- weightsum = updateWeights(weights, ids, newmean, distQ);
- }
+ weightsum = updateWeights(weights, ids, newmean, distQ);
}
+ // Explicitly destroy temporary data.
+ weights.destroy();
+
return means;
}
@Override
- public DBIDs chooseInitialMedoids(int k, DistanceQuery<? super V, ?> distQ2) {
- if(!(distQ2.getDistanceFactory() instanceof NumberDistance)) {
- throw new AbortException("K-Means++ initialization initialization can only be used with numerical distances.");
- }
+ public DBIDs chooseInitialMedoids(int k, DBIDs ids, DistanceQuery<? super O> distQ) {
@SuppressWarnings("unchecked")
- DistanceQuery<? super V, D> distQ = (DistanceQuery<? super V, D>) distQ2;
- // Chose first mean
+ final Relation<O> rel = (Relation<O>) distQ.getRelation();
+
ArrayModifiableDBIDs means = DBIDUtil.newArray(k);
+ WritableDoubleDataStore weights = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, 0.);
+
Random random = rnd.getSingleThreadedRandom();
- DBID first = DBIDUtil.deref(DBIDUtil.randomSample(distQ.getRelation().getDBIDs(), 1, random).iter());
+ DBIDRef first = DBIDUtil.randomSample(ids, 1, random).iter();
means.add(first);
- ArrayDBIDs ids = DBIDUtil.ensureArray(distQ.getRelation().getDBIDs());
// Initialize weights
- double[] weights = new double[ids.size()];
double weightsum = initialWeights(weights, ids, first, distQ);
while(means.size() < k) {
if(weightsum > Double.MAX_VALUE) {
@@ -150,17 +140,19 @@ public class KMeansPlusPlusInitialMeans<V, D extends NumberDistance<D, ?>> exten
LoggingUtil.warning("Could not choose a reasonable mean for k-means++ - to few data points?");
}
double r = random.nextDouble() * weightsum;
- int pos = 0;
- while(r > 0 && pos < weights.length) {
- r -= weights[pos];
- pos++;
+ DBIDIter it = ids.iter();
+ for(; r > 0. && it.valid(); it.advance()) {
+ double w = weights.doubleValue(it);
+ if(w != w) {
+ continue; // NaN: alrady chosen.
+ }
+ r -= w;
}
// Add new mean:
- DBID newmean = ids.get(pos);
- means.add(newmean);
+ means.add(it);
// Update weights:
- weights[pos] = 0.0;
- weightsum = updateWeights(weights, ids, newmean, distQ);
+ weights.putDouble(it, Double.NaN);
+ weightsum = updateWeights(weights, ids, rel.get(it), distQ);
}
return means;
@@ -175,18 +167,13 @@ public class KMeansPlusPlusInitialMeans<V, D extends NumberDistance<D, ?>> exten
* @param distQ Distance query
* @return Weight sum
*/
- protected double initialWeights(double[] weights, ArrayDBIDs ids, DBID latest, DistanceQuery<? super V, D> distQ) {
- double weightsum = 0.0;
- DBIDIter it = ids.iter();
- for(int i = 0; i < weights.length; i++, it.advance()) {
- if(DBIDUtil.equal(latest, it)) {
- weights[i] = 0.0;
- }
- else {
- double d = distQ.distance(latest, it).doubleValue();
- weights[i] = d * d;
- }
- weightsum += weights[i];
+ protected double initialWeights(WritableDoubleDataStore weights, DBIDs ids, DBIDRef latest, DistanceQuery<?> distQ) {
+ double weightsum = 0.;
+ for(DBIDIter it = ids.iter(); it.valid(); it.advance()) {
+ // Distance will usually already be squared
+ double weight = distQ.distance(latest, it);
+ weights.putDouble(it, weight);
+ weightsum += weight;
}
return weightsum;
}
@@ -200,38 +187,19 @@ public class KMeansPlusPlusInitialMeans<V, D extends NumberDistance<D, ?>> exten
* @param distQ Distance query
* @return Weight sum
*/
- protected double updateWeights(double[] weights, ArrayDBIDs ids, DBID latest, DistanceQuery<? super V, D> distQ) {
- double weightsum = 0.0;
- DBIDIter it = ids.iter();
- for(int i = 0; i < weights.length; i++, it.advance()) {
- if(weights[i] > 0.0) {
- double d = distQ.distance(latest, it).doubleValue();
- weights[i] = Math.min(weights[i], d * d);
- weightsum += weights[i];
+ protected <T> double updateWeights(WritableDoubleDataStore weights, DBIDs ids, T latest, DistanceQuery<? super T> distQ) {
+ double weightsum = 0.;
+ for(DBIDIter it = ids.iter(); it.valid(); it.advance()) {
+ double weight = weights.doubleValue(it);
+ if(weight != weight) {
+ continue; // NaN: already chosen!
}
- }
- return weightsum;
- }
-
- /**
- * Update the weight list.
- *
- * @param weights Weight list
- * @param ids IDs
- * @param latest Added ID
- * @param distF Distance function
- * @return Weight sum
- */
- protected double updateWeights(double[] weights, ArrayDBIDs ids, DBID latest, PrimitiveDoubleDistanceFunction<V> distF, Relation<V> rel) {
- final V lv = rel.get(latest);
- double weightsum = 0.0;
- DBIDIter it = ids.iter();
- for(int i = 0; i < weights.length; i++, it.advance()) {
- if(weights[i] > 0.0) {
- double d = distF.doubleDistance(lv, rel.get(it));
- weights[i] = Math.min(weights[i], d * d);
- weightsum += weights[i];
+ double newweight = distQ.distance(latest, it);
+ if(newweight < weight) {
+ weights.putDouble(it, newweight);
+ weight = newweight;
}
+ weightsum += weight;
}
return weightsum;
}
@@ -243,9 +211,9 @@ public class KMeansPlusPlusInitialMeans<V, D extends NumberDistance<D, ?>> exten
*
* @apiviz.exclude
*/
- public static class Parameterizer<V, D extends NumberDistance<D, ?>> extends AbstractKMeansInitialization.Parameterizer<V> {
+ public static class Parameterizer<V> extends AbstractKMeansInitialization.Parameterizer {
@Override
- protected KMeansPlusPlusInitialMeans<V, D> makeInstance() {
+ protected KMeansPlusPlusInitialMeans<V> makeInstance() {
return new KMeansPlusPlusInitialMeans<>(rnd);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMedoidsInitialization.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/KMedoidsInitialization.java
index 136a4129..9ae59961 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/KMedoidsInitialization.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/KMedoidsInitialization.java
@@ -1,9 +1,9 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization;
/*
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
@@ -38,8 +38,9 @@ public interface KMedoidsInitialization<V> {
* Choose initial means
*
* @param k Parameter k
+ * @param ids Candidate IDs.
* @param distanceFunction Distance function
* @return List of chosen means for k-means
*/
- public abstract DBIDs chooseInitialMedoids(int k, DistanceQuery<? super V, ?> distanceFunction);
+ public abstract DBIDs chooseInitialMedoids(int k, DBIDs ids, DistanceQuery<? super V> distanceFunction);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/PAMInitialMeans.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/PAMInitialMeans.java
index c7e1751f..812ea4ab 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/PAMInitialMeans.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/PAMInitialMeans.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization;
/*
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
@@ -38,7 +38,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
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.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.math.Mean;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
@@ -58,11 +57,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Erich Schubert
*
- * @param <V> Vector type
- * @param <D> Distance type
+ * @param <O> Object type for KMedoids initialization
*/
-@Reference(title = "Clustering my means of Medoids", authors = "Kaufman, L. and Rousseeuw, P.J.", booktitle = "Statistical Data Analysis Based on the L_1–Norm and Related Methods")
-public class PAMInitialMeans<V, D extends NumberDistance<D, ?>> implements KMeansInitialization<V>, KMedoidsInitialization<V> {
+@Reference(title = "Clustering my means of Medoids", //
+authors = "Kaufman, L. and Rousseeuw, P.J.", //
+booktitle = "Statistical Data Analysis Based on the L_1–Norm and Related Methods")
+public class PAMInitialMeans<O> implements KMeansInitialization<NumberVector>, KMedoidsInitialization<O> {
/**
* Constructor.
*/
@@ -71,31 +71,24 @@ public class PAMInitialMeans<V, D extends NumberDistance<D, ?>> implements KMean
}
@Override
- public List<V> chooseInitialMeans(Database database, Relation<V> relation, int k, PrimitiveDistanceFunction<? super NumberVector<?>, ?> distanceFunction) {
+ public <T extends NumberVector, V extends NumberVector> List<V> chooseInitialMeans(Database database, Relation<T> relation, int k, PrimitiveDistanceFunction<? super T> distanceFunction, NumberVector.Factory<V> factory) {
+ // Ugly cast; but better than code duplication.
+ @SuppressWarnings("unchecked")
+ Relation<O> rel = (Relation<O>) relation;
// Get a distance query
- if(!(distanceFunction.getDistanceFactory() instanceof NumberDistance)) {
- throw new AbortException("PAM initialization can only be used with numerical distances.");
- }
@SuppressWarnings("unchecked")
- final PrimitiveDistanceFunction<? super V, D> distF = (PrimitiveDistanceFunction<? super V, D>) distanceFunction;
- final DistanceQuery<V, D> distQ = database.getDistanceQuery(relation, distF);
- DBIDs medids = chooseInitialMedoids(k, distQ);
+ final PrimitiveDistanceFunction<? super O> distF = (PrimitiveDistanceFunction<? super O>) distanceFunction;
+ final DistanceQuery<O> distQ = database.getDistanceQuery(rel, distF);
+ DBIDs medids = chooseInitialMedoids(k, rel.getDBIDs(), distQ);
List<V> medoids = new ArrayList<>(k);
for(DBIDIter iter = medids.iter(); iter.valid(); iter.advance()) {
- medoids.add(relation.get(iter));
+ medoids.add(factory.newNumberVector(relation.get(iter)));
}
return medoids;
}
@Override
- public DBIDs chooseInitialMedoids(int k, DistanceQuery<? super V, ?> distQ2) {
- if(!(distQ2.getDistanceFactory() instanceof NumberDistance)) {
- throw new AbortException("PAM initialization can only be used with numerical distances.");
- }
- @SuppressWarnings("unchecked")
- DistanceQuery<? super V, D> distQ = (DistanceQuery<? super V, D>) distQ2;
- final DBIDs ids = distQ.getRelation().getDBIDs();
-
+ public DBIDs chooseInitialMedoids(int k, DBIDs ids, DistanceQuery<? super O> distQ) {
ArrayModifiableDBIDs medids = DBIDUtil.newArray(k);
double best = Double.POSITIVE_INFINITY;
Mean mean = new Mean(); // Mean is numerically more stable than sum.
@@ -109,7 +102,7 @@ public class PAMInitialMeans<V, D extends NumberDistance<D, ?>> implements KMean
WritableDoubleDataStore newd = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
mean.reset();
for(DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) {
- double d = distQ.distance(iter, iter2).doubleValue();
+ double d = distQ.distance(iter, iter2);
mean.put(d);
newd.putDouble(iter2, d);
}
@@ -141,7 +134,7 @@ public class PAMInitialMeans<V, D extends NumberDistance<D, ?>> implements KMean
WritableDoubleDataStore newd = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
mean.reset();
for(DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) {
- double dn = distQ.distance(iter, iter2).doubleValue();
+ double dn = distQ.distance(iter, iter2);
double v = Math.min(dn, mindist.doubleValue(iter2));
mean.put(v);
newd.put(iter2, v);
@@ -178,9 +171,9 @@ public class PAMInitialMeans<V, D extends NumberDistance<D, ?>> implements KMean
*
* @apiviz.exclude
*/
- public static class Parameterizer<V, D extends NumberDistance<D, ?>> extends AbstractParameterizer {
+ public static class Parameterizer<V> extends AbstractParameterizer {
@Override
- protected PAMInitialMeans<V, D> makeInstance() {
+ protected PAMInitialMeans<V> makeInstance() {
return new PAMInitialMeans<>();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/PredefinedInitialMeans.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/PredefinedInitialMeans.java
new file mode 100644
index 00000000..01df56ae
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/PredefinedInitialMeans.java
@@ -0,0 +1,161 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.NumberVector.Factory;
+import de.lmu.ifi.dbs.elki.data.model.MeanModel;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+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.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.VectorListParameter;
+
+/**
+ * Run k-means with prespecified initial means.
+ *
+ * @author Erich Schubert
+ */
+public class PredefinedInitialMeans extends AbstractKMeansInitialization<NumberVector> {
+ /**
+ * Initial means to return.
+ */
+ List<? extends NumberVector> initialMeans;
+
+ /**
+ * Constructor.
+ *
+ * @param initialMeans Initial means
+ */
+ public PredefinedInitialMeans(List<? extends NumberVector> initialMeans) {
+ super(null);
+ this.setInitialMeans(initialMeans);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param initialMeans Initial means
+ */
+ public PredefinedInitialMeans(double[][] initialMeans) {
+ super(null);
+ this.setInitialMeans(initialMeans);
+ }
+
+ /**
+ * Set the initial means.
+ *
+ * Important notice: Use with care - the means are <em>not copied</em>!
+ *
+ * @param initialMeans initial means.
+ */
+ public void setInitialMeans(List<? extends NumberVector> initialMeans) {
+ this.initialMeans = initialMeans;
+ }
+
+ /**
+ * Set the initial means.
+ *
+ * Important notice: Use with care - the means are <em>not copied</em>!
+ *
+ * @param initialMeans initial means.
+ */
+ public void setInitialClusters(List<? extends Cluster<? extends MeanModel>> initialMeans) {
+ List<Vector> vecs = new ArrayList<>(initialMeans.size());
+ for(Cluster<? extends MeanModel> cluster : initialMeans) {
+ vecs.add(cluster.getModel().getMean().copy());
+ }
+ this.initialMeans = vecs;
+ }
+
+ /**
+ * Set the initial means.
+ *
+ * Important notice: Use with care - the means are <em>not copied</em>!
+ *
+ * @param initialMeans initial means.
+ */
+ public void setInitialMeans(double[][] initialMeans) {
+ List<Vector> vecs = new ArrayList<>(initialMeans.length);
+ for(int i = 0; i < initialMeans.length; ++i) {
+ vecs.add(new Vector(initialMeans[i]));
+ }
+ this.initialMeans = vecs;
+ }
+
+ @Override
+ public <T extends NumberVector, O extends NumberVector> List<O> chooseInitialMeans(Database database, Relation<T> relation, int k, PrimitiveDistanceFunction<? super T> distanceFunction, Factory<O> factory) {
+ if(k != initialMeans.size()) {
+ throw new AbortException("Predefined initial means contained " + initialMeans.size() + " means, algorithm requested " + k + " means instead.");
+ }
+ // Chose first mean
+ List<O> means = new ArrayList<>(k);
+
+ for(NumberVector v : initialMeans) {
+ means.add(factory.newNumberVector(v));
+ }
+ return means;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Option to specify the initial means to use.
+ */
+ public static final OptionID INITIAL_MEANS = new OptionID("kmeans.means", "Initial means for k-means.");
+
+ /**
+ * Initial means.
+ */
+ protected List<Vector> initialMeans;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ VectorListParameter meansP = new VectorListParameter(INITIAL_MEANS);
+ if(config.grab(meansP)) {
+ initialMeans = meansP.getValue();
+ }
+ }
+
+ @Override
+ protected PredefinedInitialMeans makeInstance() {
+ return new PredefinedInitialMeans(initialMeans);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/RandomlyChosenInitialMeans.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/RandomlyChosenInitialMeans.java
index 214f4ce6..fe6b7281 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/RandomlyChosenInitialMeans.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/RandomlyChosenInitialMeans.java
@@ -1,84 +1,84 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
-
-/*
- 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.ArrayList;
-import java.util.List;
-
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-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.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
-
-/**
- * Initialize K-means by randomly choosing k exsiting elements as cluster
- * centers.
- *
- * @author Erich Schubert
- *
- * @param <V> Vector type
- */
-public class RandomlyChosenInitialMeans<V> extends AbstractKMeansInitialization<V> implements KMedoidsInitialization<V> {
- /**
- * Constructor.
- *
- * @param rnd Random generator.
- */
- public RandomlyChosenInitialMeans(RandomFactory rnd) {
- super(rnd);
- }
-
- @Override
- public List<V> chooseInitialMeans(Database database, Relation<V> relation, int k, PrimitiveDistanceFunction<? super NumberVector<?>, ?> distanceFunction) {
- DBIDs ids = DBIDUtil.randomSample(relation.getDBIDs(), k, rnd);
- List<V> means = new ArrayList<>(k);
- for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- means.add(relation.get(iter));
- }
- return means;
- }
-
- @Override
- public DBIDs chooseInitialMedoids(int k, DistanceQuery<? super V, ?> distanceFunction) {
- return DBIDUtil.randomSample(distanceFunction.getRelation().getDBIDs(), k, rnd);
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<V> extends AbstractKMeansInitialization.Parameterizer<V> {
- @Override
- protected RandomlyChosenInitialMeans<V> makeInstance() {
- return new RandomlyChosenInitialMeans<>(rnd);
- }
- }
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+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.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+
+/**
+ * Initialize K-means by randomly choosing k exsiting elements as cluster
+ * centers.
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Vector type
+ */
+public class RandomlyChosenInitialMeans<O> extends AbstractKMeansInitialization<NumberVector> implements KMedoidsInitialization<O> {
+ /**
+ * Constructor.
+ *
+ * @param rnd Random generator.
+ */
+ public RandomlyChosenInitialMeans(RandomFactory rnd) {
+ super(rnd);
+ }
+
+ @Override
+ public <T extends NumberVector, V extends NumberVector> List<V> chooseInitialMeans(Database database, Relation<T> relation, int k, PrimitiveDistanceFunction<? super T> distanceFunction, NumberVector.Factory<V> factory) {
+ DBIDs ids = DBIDUtil.randomSample(relation.getDBIDs(), k, rnd);
+ List<V> means = new ArrayList<>(k);
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ means.add(factory.newNumberVector(relation.get(iter)));
+ }
+ return means;
+ }
+
+ @Override
+ public DBIDs chooseInitialMedoids(int k, DBIDs ids, DistanceQuery<? super O> distanceFunction) {
+ return DBIDUtil.randomSample(ids, k, rnd);
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V> extends AbstractKMeansInitialization.Parameterizer {
+ @Override
+ protected RandomlyChosenInitialMeans<V> makeInstance() {
+ return new RandomlyChosenInitialMeans<>(rnd);
+ }
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/RandomlyGeneratedInitialMeans.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/RandomlyGeneratedInitialMeans.java
index 1329132e..4f7a21a0 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/RandomlyGeneratedInitialMeans.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/RandomlyGeneratedInitialMeans.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization;
/*
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,19 +32,15 @@ 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.distancefunction.PrimitiveDistanceFunction;
import de.lmu.ifi.dbs.elki.math.MathUtil;
-import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
/**
* Initialize k-means by generating random vectors (within the data sets value
* range).
*
* @author Erich Schubert
- *
- * @param <V> Vector type
*/
-public class RandomlyGeneratedInitialMeans<V extends NumberVector<?>> extends AbstractKMeansInitialization<V> {
+public class RandomlyGeneratedInitialMeans extends AbstractKMeansInitialization<NumberVector> {
/**
* Constructor.
*
@@ -55,17 +51,20 @@ public class RandomlyGeneratedInitialMeans<V extends NumberVector<?>> extends Ab
}
@Override
- public List<V> chooseInitialMeans(Database database, Relation<V> relation, int k, PrimitiveDistanceFunction<? super NumberVector<?>, ?> distanceFunction) {
+ public <T extends NumberVector, V extends NumberVector> List<V> chooseInitialMeans(Database database, Relation<T> relation, int k, PrimitiveDistanceFunction<? super T> distanceFunction, NumberVector.Factory<V> factory) {
final int dim = RelationUtil.dimensionality(relation);
- NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(relation);
- Pair<V, V> minmax = DatabaseUtil.computeMinMax(relation);
+ double[][] minmax = RelationUtil.computeMinMax(relation);
+ double[] min = minmax[0], scale = minmax[1];
+ for(int d = 0; d < dim; d++) {
+ scale[d] = scale[d] - min[d];
+ }
List<V> means = new ArrayList<>(k);
final Random random = rnd.getSingleThreadedRandom();
for(int i = 0; i < k; i++) {
double[] r = MathUtil.randomDoubleArray(dim, random);
// Rescale
for(int d = 0; d < dim; d++) {
- r[d] = minmax.first.doubleValue(d) + (minmax.second.doubleValue(d) - minmax.first.doubleValue(d)) * r[d];
+ r[d] = min[d] + scale[d] * r[d];
}
means.add(factory.newNumberVector(r));
}
@@ -79,10 +78,10 @@ public class RandomlyGeneratedInitialMeans<V extends NumberVector<?>> extends Ab
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractKMeansInitialization.Parameterizer<V> {
+ public static class Parameterizer extends AbstractKMeansInitialization.Parameterizer {
@Override
- protected RandomlyGeneratedInitialMeans<V> makeInstance() {
- return new RandomlyGeneratedInitialMeans<>(rnd);
+ protected RandomlyGeneratedInitialMeans makeInstance() {
+ return new RandomlyGeneratedInitialMeans(rnd);
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/SampleKMeansInitialization.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/SampleKMeansInitialization.java
index 79013364..bd1bc5a8 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/SampleKMeansInitialization.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/SampleKMeansInitialization.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization;
/*
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,10 +26,12 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
import java.util.ArrayList;
import java.util.List;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeans;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.model.MeanModel;
+import de.lmu.ifi.dbs.elki.data.model.ModelUtil;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ProxyDatabase;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
@@ -38,8 +40,8 @@ import de.lmu.ifi.dbs.elki.database.relation.ProxyView;
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.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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;
@@ -54,11 +56,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @param <V> Vector type
*/
-public class SampleKMeansInitialization<V extends NumberVector<?>, D extends Distance<?>> extends AbstractKMeansInitialization<V> {
+public class SampleKMeansInitialization<V extends NumberVector> extends AbstractKMeansInitialization<V> {
/**
- * Variant of kMeans for the bisecting step.
+ * Variant of kMeans to use for initialization.
*/
- private KMeans<V, D, ?> innerkMeans;
+ private KMeans<V, ?> innerkMeans;
/**
* Sample size.
@@ -72,28 +74,36 @@ public class SampleKMeansInitialization<V extends NumberVector<?>, D extends Dis
* @param innerkMeans Inner k-means algorithm.
* @param rate Sampling rate.
*/
- public SampleKMeansInitialization(RandomFactory rnd, KMeans<V, D, ?> innerkMeans, double rate) {
+ public SampleKMeansInitialization(RandomFactory rnd, KMeans<V, ?> innerkMeans, double rate) {
super(rnd);
this.innerkMeans = innerkMeans;
this.rate = rate;
}
@Override
- public List<V> chooseInitialMeans(Database database, Relation<V> relation, int k, PrimitiveDistanceFunction<? super NumberVector<?>, ?> distanceFunction) {
+ public <T extends V, O extends NumberVector> List<O> chooseInitialMeans(Database database, Relation<T> relation, int k, PrimitiveDistanceFunction<? super T> distanceFunction, NumberVector.Factory<O> factory) {
final int samplesize = (int) Math.ceil(rate * relation.size());
final DBIDs sample = DBIDUtil.randomSample(relation.getDBIDs(), samplesize, rnd);
- ProxyView<V> proxyv = new ProxyView<>(database, sample, relation);
+ // Ugly cast, sorry
+ @SuppressWarnings("unchecked")
+ Relation<V> rel = (Relation<V>) relation;
+ // FIXME: This does not necessarily hold. Check and fail!
+ if(!distanceFunction.getInputTypeRestriction().isAssignableFromType(TypeUtil.NUMBER_VECTOR_FIELD)) {
+ LoggingUtil.warning("Initializing k-means with k-means using specialized distance functions MAY fail, if the initialization method does require a distance defined on arbitrary number vectors.");
+ }
+ @SuppressWarnings("unchecked")
+ PrimitiveDistanceFunction<? super NumberVector> pdf = (PrimitiveDistanceFunction<? super NumberVector>) distanceFunction;
+ ProxyView<V> proxyv = new ProxyView<>(database, sample, rel);
ProxyDatabase proxydb = new ProxyDatabase(sample, proxyv);
innerkMeans.setK(k);
- @SuppressWarnings("unchecked")
- PrimitiveDistanceFunction<? super NumberVector<?>, D> df = (PrimitiveDistanceFunction<? super NumberVector<?>, D>) distanceFunction;
- innerkMeans.setDistanceFunction(df);
- Clustering<? extends MeanModel<V>> clusters = innerkMeans.run(proxydb, proxyv);
- List<V> means = new ArrayList<>();
- for (Cluster<? extends MeanModel<V>> cluster : clusters.getAllClusters()) {
- means.add(cluster.getModel().getMean());
+ innerkMeans.setDistanceFunction(pdf);
+ Clustering<?> clusters = innerkMeans.run(proxydb, proxyv);
+
+ List<O> means = new ArrayList<>();
+ for(Cluster<?> cluster : clusters.getAllClusters()) {
+ means.add(factory.newNumberVector(ModelUtil.getPrototype(cluster.getModel(), relation)));
}
return means;
@@ -107,9 +117,8 @@ public class SampleKMeansInitialization<V extends NumberVector<?>, D extends Dis
* @apiviz.exclude
*
* @param <V> Vector type
- * @param <D> Distance type
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends Distance<?>> extends AbstractKMeansInitialization.Parameterizer<V> {
+ public static class Parameterizer<V extends NumberVector> extends AbstractKMeansInitialization.Parameterizer {
/**
* Parameter to specify the kMeans variant.
*/
@@ -123,8 +132,8 @@ public class SampleKMeansInitialization<V extends NumberVector<?>, D extends Dis
/**
* Inner k-means algorithm to use.
*/
- protected KMeans<V, D, ?> innerkMeans;
-
+ protected KMeans<V, ?> innerkMeans;
+
/**
* Sampling rate.
*/
@@ -133,8 +142,8 @@ public class SampleKMeansInitialization<V extends NumberVector<?>, D extends Dis
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- ObjectParameter<KMeans<V, D, ?>> kMeansVariantP = new ObjectParameter<>(KMEANS_ID, KMeans.class);
- if (config.grab(kMeansVariantP)) {
+ ObjectParameter<KMeans<V, ?>> kMeansVariantP = new ObjectParameter<>(KMEANS_ID, KMeans.class);
+ if(config.grab(kMeansVariantP)) {
ListParameterization kMeansVariantParameters = new ListParameterization();
// We will always invoke this with k as requested from outside!
@@ -145,15 +154,15 @@ public class SampleKMeansInitialization<V extends NumberVector<?>, D extends Dis
combinedConfig.errorsTo(config);
innerkMeans = kMeansVariantP.instantiateClass(combinedConfig);
}
-
+
DoubleParameter sampleP = new DoubleParameter(SAMPLE_ID);
- if (config.grab(sampleP)) {
+ if(config.grab(sampleP)) {
rate = sampleP.doubleValue();
}
}
@Override
- protected SampleKMeansInitialization<V, D> makeInstance() {
+ protected SampleKMeansInitialization<V> makeInstance() {
return new SampleKMeansInitialization<>(rnd, innerkMeans, rate);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/package-info.java
new file mode 100644
index 00000000..14af1d69
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/initialization/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Initialization strategies for k-means.
+ */
+
+/*
+ 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.algorithm.clustering.kmeans.initialization; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/package-info.java
index aa4c3e24..da9bd20e 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/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/algorithm/clustering/kmeans/parallel/KMeansProcessor.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/parallel/KMeansProcessor.java
new file mode 100644
index 00000000..38133c6b
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/parallel/KMeansProcessor.java
@@ -0,0 +1,272 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.parallel;
+
+/*
+ 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.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
+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.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.VMath;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.parallel.Executor;
+import de.lmu.ifi.dbs.elki.parallel.processor.Processor;
+
+/**
+ * Parallel k-means implementation.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has Instance
+ */
+public class KMeansProcessor<V extends NumberVector> implements Processor {
+ /**
+ * Data relation.
+ */
+ Relation<V> relation;
+
+ /**
+ * Distance function.
+ */
+ PrimitiveDistanceFunction<? super NumberVector> distance;
+
+ /**
+ * Assignment storage.
+ */
+ WritableIntegerDataStore assignment;
+
+ /**
+ * Mean vectors.
+ */
+ List<Vector> means;
+
+ /**
+ * Updated cluster centroids
+ */
+ double[][] centroids;
+
+ /**
+ * (Partial) cluster sizes
+ */
+ int[] sizes;
+
+ /**
+ * Variance sum.
+ */
+ double[] varsum;
+
+ /**
+ * Whether the assignment changed during the last iteration.
+ */
+ boolean changed = false;
+
+ /**
+ * Constructor.
+ *
+ * @param relation Data relation
+ * @param distance Distance function
+ * @param assignment Cluster assignment
+ * @param varsum Variance sums
+ */
+ public KMeansProcessor(Relation<V> relation, PrimitiveDistanceFunction<? super NumberVector> distance, WritableIntegerDataStore assignment, double[] varsum) {
+ super();
+ this.distance = distance;
+ this.relation = relation;
+ this.assignment = assignment;
+ this.varsum = varsum;
+ }
+
+ /**
+ * Get the "has changed" value.
+ *
+ * @return Changed flag.
+ */
+ public boolean changed() {
+ return changed;
+ }
+
+ /**
+ * Initialize for a new iteration.
+ *
+ * @param means New means.
+ */
+ public void nextIteration(List<Vector> means) {
+ this.means = means;
+ changed = false;
+ final int k = means.size();
+ final int dim = means.get(0).getDimensionality();
+ centroids = new double[k][dim];
+ sizes = new int[k];
+ Arrays.fill(varsum, 0.);
+ }
+
+ @Override
+ public Instance instantiate(Executor exectutor) {
+ return new Instance(relation, distance, assignment, means);
+ }
+
+ @Override
+ public void cleanup(Processor.Instance inst) {
+ @SuppressWarnings("unchecked")
+ Instance instance = (Instance) inst;
+ synchronized(this) {
+ changed |= instance.changed;
+ for(int i = 0; i < centroids.length; i++) {
+ int sizeb = instance.sizes[i];
+ if(sizeb == 0) {
+ continue;
+ }
+ int sizea = sizes[i];
+ double sum = sizea + sizeb;
+ double[] cent = centroids[i];
+ if(sizea > 0) {
+ VMath.timesEquals(cent, sizea / sum);
+ }
+ VMath.plusTimesEquals(cent, instance.centroids[i], 1. / sum);
+ sizes[i] += sizeb;
+ VMath.plusEquals(varsum, instance.varsum);
+ }
+ }
+ }
+
+ /**
+ * Get the new means.
+ *
+ * @return New means
+ */
+ public List<Vector> getMeans() {
+ ArrayList<Vector> newmeans = new ArrayList<>(centroids.length);
+ for(int i = 0; i < centroids.length; i++) {
+ if(sizes[i] == 0) {
+ newmeans.add(means.get(i)); // Keep old mean.
+ continue;
+ }
+ newmeans.add(new Vector(centroids[i]));
+ }
+ return newmeans;
+ }
+
+ /**
+ * Instance to process part of the data set, for a single iteration.
+ *
+ * @author Erich Schubert
+ */
+ public class Instance implements Processor.Instance {
+ /**
+ * Data relation.
+ */
+ private Relation<V> relation;
+
+ /**
+ * Distance function.
+ */
+ private PrimitiveDistanceFunction<? super NumberVector> distance;
+
+ /**
+ * Cluster assignment storage.
+ */
+ private WritableIntegerDataStore assignment;
+
+ /**
+ * Current mean vectors.
+ */
+ private Vector[] means;
+
+ /**
+ * Updated cluster centroids
+ */
+ private double[][] centroids;
+
+ /**
+ * (Partial) cluster sizes
+ */
+ private int[] sizes;
+
+ /**
+ * Variance sum.
+ */
+ private double[] varsum;
+
+ /**
+ * Changed flag.
+ */
+ private boolean changed = false;
+
+ /**
+ * Constructor.
+ *
+ * @param relation Data relation
+ * @param distance Distance function
+ * @param assignment Current assignment
+ * @param means Previous mean vectors
+ */
+ public Instance(Relation<V> relation, PrimitiveDistanceFunction<? super NumberVector> distance, WritableIntegerDataStore assignment, List<? extends NumberVector> means) {
+ super();
+ this.relation = relation;
+ this.distance = distance;
+ this.assignment = assignment;
+ final int k = means.size();
+ this.means = new Vector[k];
+ Iterator<? extends NumberVector> iter = means.iterator();
+ for(int i = 0; i < k; i++) {
+ this.means[i] = iter.next().getColumnVector(); // Make local copy!
+ }
+ // Storage for updated means.
+ final int dim = this.means[0].getDimensionality();
+ this.centroids = new double[k][dim];
+ this.sizes = new int[k];
+ this.varsum = new double[k];
+ }
+
+ @Override
+ public void map(DBIDRef id) {
+ final V fv = relation.get(id);
+ // Find minimum:
+ double mindist = Double.POSITIVE_INFINITY;
+ int minIndex = 0;
+ for(int i = 0; i < means.length; i++) {
+ final double dist = distance.distance(fv, means[i]);
+ if(dist < mindist) {
+ minIndex = i;
+ mindist = dist;
+ }
+ }
+ varsum[minIndex] += mindist;
+ // Update assignment:
+ int prev = assignment.putInt(id, minIndex);
+ // Update changed flag:
+ changed |= (prev != minIndex);
+ double[] cent = centroids[minIndex];
+ for(int d = 0; d < fv.getDimensionality(); d++) {
+ // TODO: improve numerical stability via Kahan summation?
+ cent[d] += fv.doubleValue(d);
+ }
+ ++sizes[minIndex];
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/parallel/ParallelLloydKMeans.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/parallel/ParallelLloydKMeans.java
new file mode 100644
index 00000000..35262616
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/parallel/ParallelLloydKMeans.java
@@ -0,0 +1,154 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.parallel;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.AbstractKMeans;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization;
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.KMeansModel;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+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.ModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.parallel.ParallelExecutor;
+
+/**
+ * Parallel implementation of k-Means clustering.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has KMeansProcessor
+ *
+ * @param <V> Vector type
+ */
+public class ParallelLloydKMeans<V extends NumberVector> extends AbstractKMeans<V, KMeansModel> {
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function
+ * @param k K parameter
+ */
+ public ParallelLloydKMeans(PrimitiveDistanceFunction<? super NumberVector> distanceFunction, int k, int maxiter, KMeansInitialization<? super V> initializer) {
+ super(distanceFunction, k, maxiter, initializer);
+ }
+
+ /**
+ * Class logger
+ */
+ private static final Logging LOG = Logging.getLogger(ParallelLloydKMeans.class);
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
+ }
+
+ @Override
+ public Clustering<KMeansModel> run(Database database, Relation<V> relation) {
+ DBIDs ids = relation.getDBIDs();
+
+ // Choose initial means
+ List<Vector> means = initializer.chooseInitialMeans(database, relation, k, getDistanceFunction(), Vector.FACTORY);
+
+ // Store for current cluster assignment.
+ WritableIntegerDataStore assignment = DataStoreUtil.makeIntegerStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, -1);
+ double[] varsum = new double[k];
+ KMeansProcessor<V> kmm = new KMeansProcessor<>(relation, distanceFunction, assignment, varsum);
+
+ IndefiniteProgress prog = LOG.isVerbose() ? new IndefiniteProgress("K-Means iteration", LOG) : null;
+ for (int iteration = 0; maxiter <= 0 || iteration < maxiter; iteration++) {
+ LOG.incrementProcessed(prog);
+ kmm.nextIteration(means);
+ ParallelExecutor.run(ids, kmm);
+ // Stop if no cluster assignment changed.
+ if (!kmm.changed()) {
+ break;
+ }
+ means = kmm.getMeans();
+ }
+ LOG.setCompleted(prog);
+
+ // Wrap result
+ List<ModifiableDBIDs> clusters = new ArrayList<>();
+ for (int i = 0; i < k; i++) {
+ // TODO: use cluster sizes from kmm!
+ clusters.add(DBIDUtil.newHashSet((int) (relation.size() * 2. / k)));
+ }
+ for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ clusters.get(assignment.intValue(iter)).add(iter);
+ }
+
+ Clustering<KMeansModel> result = new Clustering<>("k-Means Clustering", "kmeans-clustering");
+ for (int i = 0; i < clusters.size(); i++) {
+ DBIDs cids = clusters.get(i);
+ if (cids.size() == 0) {
+ continue;
+ }
+ KMeansModel model = new KMeansModel(means.get(i), varsum[i]);
+ result.addToplevelCluster(new Cluster<>(cids, model));
+ }
+ return result;
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <V> Vector type
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractKMeans.Parameterizer<V> {
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ @Override
+ protected ParallelLloydKMeans<V> makeInstance() {
+ return new ParallelLloydKMeans<>(distanceFunction, k, maxiter, initializer);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/parallel/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/parallel/package-info.java
new file mode 100644
index 00000000..89941cc3
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/parallel/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Parallelized implementations of k-means.
+ */
+
+/*
+ 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.algorithm.clustering.kmeans.parallel; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/AbstractKMeansQualityMeasure.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/AbstractKMeansQualityMeasure.java
new file mode 100644
index 00000000..88279023
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/AbstractKMeansQualityMeasure.java
@@ -0,0 +1,239 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality;
+
+/*
+ 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.Iterator;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.KMeansModel;
+import de.lmu.ifi.dbs.elki.data.model.MeanModel;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+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.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+
+/**
+ * Base class for evaluating clusterings by information criteria (such as AIC or
+ * BIC). Provides helper functions (e.g. max likelihood calculation) to its
+ * subclasses.
+ *
+ * The use of information-theoretic criteria for evaluating k-means was
+ * popularized by X-means:
+ * <p>
+ * D. Pelleg, A. Moore:<br />
+ * X-means: Extending K-means with Efficient Estimation on the Number of
+ * Clusters<br />
+ * In: Proceedings of the 17th International Conference on Machine Learning
+ * (ICML 2000)
+ * </p>
+ *
+ * A different version of logLikelihood is derived in:
+ * <p>
+ * Q. Zhao, M. Xu, P. Fränti:<br />
+ * Knee Point Detection on Bayesian Information Criterion<br />
+ * 20th IEEE International Conference on Tools with Artificial Intelligence
+ * </p>
+ *
+ * @author Tibor Goldschwendt
+ * @author Erich Schubert
+ */
+@Reference(authors = "D. Pelleg, A. Moore", //
+booktitle = "X-means: Extending K-means with Efficient Estimation on the Number of Clusters", //
+title = "Proceedings of the 17th International Conference on Machine Learning (ICML 2000)", //
+url = "http://www.pelleg.org/shared/hp/download/xmeans.ps")
+public abstract class AbstractKMeansQualityMeasure<O extends NumberVector> implements KMeansQualityMeasure<O> {
+ /**
+ * Compute the number of points in a given set of clusters (which may be
+ * <i>less</i> than the complete data set for X-means!)
+ *
+ * @param clustering Clustering to analyze
+ * @return Number of points
+ */
+ public static int numPoints(Clustering<? extends MeanModel> clustering) {
+ int n = 0;
+ for(Cluster<? extends MeanModel> aCluster : clustering.getAllClusters()) {
+ n += aCluster.size();
+ }
+ return n;
+ }
+
+ /**
+ * Variance contribution of a single cluster.
+ *
+ * If possible, this information is reused from the clustering process (when a
+ * KMeansModel is returned).
+ *
+ * @param cluster Cluster to access
+ * @param distanceFunction Distance function
+ * @param relation Data relation
+ * @return Cluster variance
+ */
+ public static double varianceOfCluster(Cluster<? extends MeanModel> cluster, PrimitiveDistanceFunction<? super NumberVector> distanceFunction, Relation<? extends NumberVector> relation) {
+ MeanModel model = cluster.getModel();
+ if(model instanceof KMeansModel) {
+ return ((KMeansModel) model).getVarianceContribution();
+ }
+ // Re-compute:
+ DBIDs ids = cluster.getIDs();
+ Vector mean = model.getMean();
+
+ boolean squared = (distanceFunction instanceof SquaredEuclideanDistanceFunction);
+ double variance = 0.;
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ double dist = distanceFunction.distance(relation.get(iter), mean);
+ variance += squared ? dist : dist * dist;
+ }
+ return variance;
+ }
+
+ /**
+ * Computes log likelihood of an entire clustering.
+ *
+ * Version as used in the X-means publication.
+ *
+ * @param relation Data relation
+ * @param clustering Clustering
+ * @param distanceFunction Distance function
+ * @return Log Likelihood.
+ */
+ @Reference(authors = "D. Pelleg, A. Moore", //
+ booktitle = "X-means: Extending K-means with Efficient Estimation on the Number of Clusters", //
+ title = "Proceedings of the 17th International Conference on Machine Learning (ICML 2000)", //
+ url = "http://www.pelleg.org/shared/hp/download/xmeans.ps")
+ public static double logLikelihood(Relation<? extends NumberVector> relation, Clustering<? extends MeanModel> clustering, PrimitiveDistanceFunction<? super NumberVector> distanceFunction) {
+ List<? extends Cluster<? extends MeanModel>> clusters = clustering.getAllClusters();
+ // dimensionality of data points
+ final int dim = RelationUtil.dimensionality(relation);
+ // number of clusters
+ final int m = clusters.size();
+
+ // number of objects in the clustering
+ int n = 0;
+ // cluster sizes
+ int[] n_i = new int[m];
+ // total variance
+ double d = 0.;
+ // variances
+ double[] d_i = new double[m];
+
+ // Iterate over clusters:
+ Iterator<? extends Cluster<? extends MeanModel>> it = clusters.iterator();
+ for(int i = 0; it.hasNext(); ++i) {
+ Cluster<? extends MeanModel> cluster = it.next();
+ n += n_i[i] = cluster.size();
+ d += d_i[i] = varianceOfCluster(cluster, distanceFunction, relation);
+ }
+
+ // Total variance (corrected for bias)
+ final double v = d / (n - m), logv = Math.log(v);
+ // log likelihood of this clustering
+ double logLikelihood = 0.;
+
+ // Aggregate
+ for(int i = 0; i < m; i++) {
+ logLikelihood += n_i[i] * Math.log(n_i[i]) // Posterior entropy, Rn log Rn
+ - n_i[i] * .5 * MathUtil.LOGTWOPI // Rn/2 log2pi
+ - n_i[i] * dim * .5 * logv // Rn M/2 log sigma^2
+ - (d_i[i] - m) * .5; // (Rn-K)/2
+ }
+ logLikelihood -= n * Math.log(n); // Prior entropy, sum_i Rn log R
+
+ return logLikelihood;
+ }
+
+ /**
+ * Computes log likelihood of an entire clustering.
+ *
+ * Version as used by Zhao et al.
+ *
+ * @param relation Data relation
+ * @param clustering Clustering
+ * @param distanceFunction Distance function
+ * @return Log Likelihood.
+ */
+ @Reference(authors = "Q. Zhao, M. Xu, P. Fränti", //
+ title = "Knee Point Detection on Bayesian Information Criterion", //
+ booktitle = "20th IEEE International Conference on Tools with Artificial Intelligence", //
+ url = "http://dx.doi.org/10.1109/ICTAI.2008.154")
+ public static double logLikelihoodAlternate(Relation<? extends NumberVector> relation, Clustering<? extends MeanModel> clustering, PrimitiveDistanceFunction<? super NumberVector> distanceFunction) {
+ List<? extends Cluster<? extends MeanModel>> clusters = clustering.getAllClusters();
+ // dimensionality of data points
+ final int dim = RelationUtil.dimensionality(relation);
+ // number of clusters
+ final int m = clusters.size();
+
+ // number of objects in the clustering
+ int n = 0;
+ // cluster sizes
+ int[] n_i = new int[m];
+ // variances
+ double[] d_i = new double[m];
+
+ // Iterate over clusters:
+ Iterator<? extends Cluster<? extends MeanModel>> it = clusters.iterator();
+ for(int i = 0; it.hasNext(); ++i) {
+ Cluster<? extends MeanModel> cluster = it.next();
+ n += n_i[i] = cluster.size();
+ d_i[i] = varianceOfCluster(cluster, distanceFunction, relation);
+ }
+
+ // log likelihood of this clustering
+ double logLikelihood = 0.;
+
+ // Aggregate
+ for(int i = 0; i < m; i++) {
+ logLikelihood += n_i[i] * Math.log(n_i[i] / (double) n) // ni log ni/n
+ - n_i[i] * dim * .5 * MathUtil.LOGTWOPI // ni*d/2 log2pi
+ - n_i[i] * .5 * Math.log(d_i[i]) // ni/2 log sigma_i
+ - (n_i[i] - m) * .5; // (ni-m)/2
+ }
+ return logLikelihood;
+ }
+
+ /**
+ * Compute the number of free parameters.
+ *
+ * @param relation Data relation (for dimensionality)
+ * @param clustering Set of clusters
+ * @return Number of free parameters
+ */
+ public static int numberOfFreeParameters(Relation<? extends NumberVector> relation, Clustering<? extends MeanModel> clustering) {
+ // number of clusters
+ int m = clustering.getAllClusters().size(); // num_ctrs
+
+ // dimensionality of data points
+ int dim = RelationUtil.dimensionality(relation); // num_dims
+
+ // number of free parameters
+ return (m - 1) + m * dim + m;
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/AkaikeInformationCriterion.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/AkaikeInformationCriterion.java
new file mode 100644
index 00000000..f1619386
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/AkaikeInformationCriterion.java
@@ -0,0 +1,74 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality;
+
+/*
+ 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.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.MeanModel;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+
+/**
+ * Akaike Information Criterion (AIC).
+ *
+ * Reference:
+ * <p>
+ * H. Akaike<br />
+ * On entropy maximization principle<br />
+ * Application of statistics, 1977, North-Holland
+ * </p>
+ *
+ * The use for k-means was popularized by:
+ * <p>
+ * D. Pelleg, A. Moore:<br />
+ * X-means: Extending K-means with Efficient Estimation on the Number of
+ * Clusters<br />
+ * In: Proceedings of the 17th International Conference on Machine Learning
+ * (ICML 2000)
+ * </p>
+ *
+ * @author Tibor Goldschwendt
+ * @author Erich Schubert
+ */
+@Reference(authors = "H. Akaike", //
+title = "On entropy maximization principle", //
+booktitle = "Application of statistics, 1977, North-Holland")
+public class AkaikeInformationCriterion extends AbstractKMeansQualityMeasure<NumberVector> {
+ @Override
+ public <V extends NumberVector> double quality(Clustering<? extends MeanModel> clustering, PrimitiveDistanceFunction<? super NumberVector> distanceFunction, Relation<V> relation) {
+ return logLikelihood(relation, clustering, distanceFunction) - numberOfFreeParameters(relation, clustering);
+ }
+
+ @Override
+ public boolean ascending() {
+ return true;
+ }
+
+ @Override
+ public boolean isBetter(double currentCost, double bestCost) {
+ // Careful: bestCost may be NaN!
+ return !(currentCost <= bestCost);
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/BayesianInformationCriterion.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/BayesianInformationCriterion.java
new file mode 100644
index 00000000..73b0c501
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/BayesianInformationCriterion.java
@@ -0,0 +1,77 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality;
+
+/*
+ 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.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.MeanModel;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+
+/**
+ * Bayesian Information Criterion (BIC), also known as Schwarz criterion (SBC,
+ * SBIC) for the use with evaluating k-means results.
+ *
+ * Reference:
+ * <p>
+ * G. Schwarz<br />
+ * Estimating the dimension of a model<br />
+ * The annals of statistics 6.2.
+ * </p>
+ *
+ * The use for k-means was popularized by:
+ * <p>
+ * D. Pelleg, A. Moore:<br />
+ * X-means: Extending K-means with Efficient Estimation on the Number of
+ * Clusters<br />
+ * In: Proceedings of the 17th International Conference on Machine Learning
+ * (ICML 2000)
+ * </p>
+ *
+ * @author Tibor Goldschwendt
+ * @author Erich Schubert
+ */
+@Reference(authors = "G. Schwarz", //
+title = "Estimating the dimension of a model", //
+booktitle = "The annals of statistics 6.2", //
+url = "http://dx.doi.org/10.1214/aos/1176344136")
+public class BayesianInformationCriterion extends AbstractKMeansQualityMeasure<NumberVector> {
+ @Override
+ public <V extends NumberVector> double quality(Clustering<? extends MeanModel> clustering, PrimitiveDistanceFunction<? super NumberVector> distanceFunction, Relation<V> relation) {
+ return logLikelihood(relation, clustering, distanceFunction) //
+ - (.5 * numberOfFreeParameters(relation, clustering)) * Math.log(numPoints(clustering));
+ }
+
+ @Override
+ public boolean ascending() {
+ return true;
+ }
+
+ @Override
+ public boolean isBetter(double currentCost, double bestCost) {
+ // Careful: bestCost may be NaN!
+ return !(currentCost <= bestCost);
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/BayesianInformationCriterionZhao.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/BayesianInformationCriterionZhao.java
new file mode 100644
index 00000000..3fa646c2
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/BayesianInformationCriterionZhao.java
@@ -0,0 +1,67 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality;
+
+/*
+ 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.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.MeanModel;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+
+/**
+ * Different version of the BIC criterion.
+ *
+ * Reference:
+ * <p>
+ * Q. Zhao, M. Xu, P. Fränti:<br />
+ * Knee Point Detection on Bayesian Information Criterion<br />
+ * 20th IEEE International Conference on Tools with Artificial Intelligence
+ * </p>
+ *
+ * @author Tibor Goldschwendt
+ * @author Erich Schubert
+ */
+@Reference(authors = "Q. Zhao, M. Xu, P. Fränti", //
+title = "Knee Point Detection on Bayesian Information Criterion", //
+booktitle = "20th IEEE International Conference on Tools with Artificial Intelligence", //
+url = "http://dx.doi.org/10.1109/ICTAI.2008.154")
+public class BayesianInformationCriterionZhao extends AbstractKMeansQualityMeasure<NumberVector> {
+ @Override
+ public <V extends NumberVector> double quality(Clustering<? extends MeanModel> clustering, PrimitiveDistanceFunction<? super NumberVector> distanceFunction, Relation<V> relation) {
+ return logLikelihoodAlternate(relation, clustering, distanceFunction) //
+ - (.5 * clustering.getAllClusters().size()) * Math.log(numPoints(clustering));
+ }
+
+ @Override
+ public boolean ascending() {
+ return true;
+ }
+
+ @Override
+ public boolean isBetter(double currentCost, double bestCost) {
+ // Careful: bestCost may be NaN!
+ return !(currentCost <= bestCost);
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/KMeansQualityMeasure.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/KMeansQualityMeasure.java
index f2de7846..2a234261 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/KMeansQualityMeasure.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/KMeansQualityMeasure.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality;
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,17 +28,17 @@ import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.model.MeanModel;
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.distancevalue.Distance;
/**
* Interface for computing the quality of a K-Means clustering.
*
+ * Important note: some measures are ascending, others are descending!
+ *
* @author Erich Schubert
*
* @param <O> Input Object restriction type
- * @param <D> Distance restriction type
*/
-public interface KMeansQualityMeasure<O extends NumberVector<?>, D extends Distance<?>> {
+public interface KMeansQualityMeasure<O extends NumberVector> {
/**
* Calculates and returns the quality measure.
*
@@ -50,5 +50,22 @@ public interface KMeansQualityMeasure<O extends NumberVector<?>, D extends Dista
*
* @return quality measure
*/
- <V extends O> double calculateCost(Clustering<? extends MeanModel<V>> clustering, PrimitiveDistanceFunction<? super V, ? extends D> distanceFunction, Relation<V> relation);
+ <V extends O> double quality(Clustering<? extends MeanModel> clustering, PrimitiveDistanceFunction<? super NumberVector> distanceFunction, Relation<V> relation);
+
+ /**
+ * Use ascending or descending ordering.
+ *
+ * @return {@code true} when larger scores are better.
+ */
+ boolean ascending();
+
+ /**
+ * Compare two scores.
+ *
+ * @param currentCost New (candiate) cost/score
+ * @param bestCost Existing best cost/score (may be {@code NaN})
+ * @return {@code true} when the new score is better, or the old score is
+ * {@code NaN}.
+ */
+ boolean isBetter(double currentCost, double bestCost);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/WithinClusterMeanDistanceQualityMeasure.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/WithinClusterMeanDistanceQualityMeasure.java
index e0ddfff0..9083f924 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/WithinClusterMeanDistanceQualityMeasure.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/WithinClusterMeanDistanceQualityMeasure.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality;
/*
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,8 +22,6 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.List;
-
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
@@ -32,8 +30,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
/**
* Class for computing the average overall distance.
@@ -42,48 +38,35 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
*
* @author Stephan Baier
*/
-public class WithinClusterMeanDistanceQualityMeasure implements KMeansQualityMeasure<NumberVector<?>, NumberDistance<?, ?>> {
+public class WithinClusterMeanDistanceQualityMeasure implements KMeansQualityMeasure<NumberVector> {
@Override
- public <V extends NumberVector<?>> double calculateCost(Clustering<? extends MeanModel<V>> clustering, PrimitiveDistanceFunction<? super V, ? extends NumberDistance<?, ?>> distanceFunction, Relation<V> relation) {
- @SuppressWarnings("unchecked")
- final List<Cluster<MeanModel<V>>> clusterList = (List<Cluster<MeanModel<V>>>) (List<?>) clustering.getAllClusters();
-
- if (distanceFunction instanceof PrimitiveDoubleDistanceFunction) {
- @SuppressWarnings("unchecked")
- PrimitiveDoubleDistanceFunction<? super V> df = (PrimitiveDoubleDistanceFunction<? super V>) distanceFunction;
- double clusterDistanceSum = 0;
- for (Cluster<MeanModel<V>> cluster : clusterList) {
- DBIDs ids = cluster.getIDs();
+ public <V extends NumberVector> double quality(Clustering<? extends MeanModel> clustering, PrimitiveDistanceFunction<? super NumberVector> distanceFunction, Relation<V> relation) {
+ double clusterDistanceSum = 0;
+ for(Cluster<? extends MeanModel> cluster : clustering.getAllClusters()) {
+ DBIDs ids = cluster.getIDs();
- // Compute sum of pairwise distances:
- double clusterPairwiseDistanceSum = 0;
- for (DBIDIter iter1 = ids.iter(); iter1.valid(); iter1.advance()) {
- V obj1 = relation.get(iter1);
- for (DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) {
- clusterPairwiseDistanceSum += df.doubleDistance(obj1, relation.get(iter2));
- }
+ // Compute sum of pairwise distances:
+ double clusterPairwiseDistanceSum = 0;
+ for(DBIDIter iter1 = ids.iter(); iter1.valid(); iter1.advance()) {
+ V obj1 = relation.get(iter1);
+ for(DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) {
+ clusterPairwiseDistanceSum += distanceFunction.distance(obj1, relation.get(iter2));
}
- clusterDistanceSum += clusterPairwiseDistanceSum / (ids.size() * ids.size());
}
+ clusterDistanceSum += clusterPairwiseDistanceSum / (ids.size() * ids.size());
+ }
- return clusterDistanceSum / clusterList.size();
- } else {
- double clusterDistanceSum = 0;
- for (Cluster<MeanModel<V>> cluster : clusterList) {
- DBIDs ids = cluster.getIDs();
+ return clusterDistanceSum / clustering.getAllClusters().size();
+ }
- // Compute sum of pairwise distances:
- double clusterPairwiseDistanceSum = 0;
- for (DBIDIter iter1 = ids.iter(); iter1.valid(); iter1.advance()) {
- V obj1 = relation.get(iter1);
- for (DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) {
- clusterPairwiseDistanceSum += distanceFunction.distance(obj1, relation.get(iter2)).doubleValue();
- }
- }
- clusterDistanceSum += clusterPairwiseDistanceSum / (ids.size() * ids.size());
- }
+ @Override
+ public boolean ascending() {
+ return false;
+ }
- return clusterDistanceSum / clusterList.size();
- }
+ @Override
+ public boolean isBetter(double currentCost, double bestCost) {
+ // Careful: bestCost may be NaN!
+ return !(currentCost >= bestCost);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/WithinClusterVarianceQualityMeasure.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/WithinClusterVarianceQualityMeasure.java
index 32ad5210..513e3ca3 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/WithinClusterVarianceQualityMeasure.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/WithinClusterVarianceQualityMeasure.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality;
/*
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,62 +22,37 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.List;
-
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.model.MeanModel;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-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.distancefunction.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
/**
* Class for computing the variance in a clustering result (sum-of-squares).
*
* @author Stephan Baier
+ * @author Erich Schubert
*/
-public class WithinClusterVarianceQualityMeasure implements KMeansQualityMeasure<NumberVector<?>, NumberDistance<?, ?>> {
+public class WithinClusterVarianceQualityMeasure extends AbstractKMeansQualityMeasure<NumberVector> {
@Override
- public <V extends NumberVector<?>> double calculateCost(Clustering<? extends MeanModel<V>> clustering, PrimitiveDistanceFunction<? super V, ? extends NumberDistance<?, ?>> distanceFunction, Relation<V> relation) {
- @SuppressWarnings("unchecked")
- final List<Cluster<MeanModel<V>>> clusterList = (List<Cluster<MeanModel<V>>>) (List<?>) clustering.getAllClusters();
-
- boolean squared = (distanceFunction instanceof SquaredEuclideanDistanceFunction);
- if (distanceFunction instanceof PrimitiveDoubleDistanceFunction) {
- @SuppressWarnings("unchecked")
- PrimitiveDoubleDistanceFunction<? super V> df = (PrimitiveDoubleDistanceFunction<? super V>) distanceFunction;
- double variance = 0.0;
- for (Cluster<MeanModel<V>> cluster : clusterList) {
- DBIDs ids = cluster.getIDs();
- V mean = cluster.getModel().getMean();
+ public <V extends NumberVector> double quality(Clustering<? extends MeanModel> clustering, PrimitiveDistanceFunction<? super NumberVector> distanceFunction, Relation<V> relation) {
+ double variance = 0.;
+ for(Cluster<? extends MeanModel> cluster : clustering.getAllClusters()) {
+ variance += varianceOfCluster(cluster, distanceFunction, relation);
+ }
+ return variance;
+ }
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- double dist = df.doubleDistance(relation.get(iter), mean);
- if (squared) {
- variance += dist;
- } else {
- variance += dist * dist;
- }
- }
- }
- return variance;
- } else {
- double variance = 0.0;
- for (Cluster<MeanModel<V>> cluster : clusterList) {
- DBIDs ids = cluster.getIDs();
- V mean = cluster.getModel().getMean();
+ @Override
+ public boolean ascending() {
+ return false;
+ }
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- double dist = distanceFunction.distance(relation.get(iter), mean).doubleValue();
- variance += dist * dist;
- }
- }
- return variance;
- }
+ @Override
+ public boolean isBetter(double currentCost, double bestCost) {
+ // Careful: bestCost may be NaN!
+ return !(currentCost >= bestCost);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/package-info.java
index 1be19bd1..767048db 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/quality/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/algorithm/clustering/onedimensional/KNNKernelDensityMinimaClustering.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/onedimensional/KNNKernelDensityMinimaClustering.java
index 55114f7d..4e31f3a1 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/onedimensional/KNNKernelDensityMinimaClustering.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/onedimensional/KNNKernelDensityMinimaClustering.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.onedimensional;
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
@@ -59,7 +59,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*/
-public class KNNKernelDensityMinimaClustering<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<ClusterModel>> implements ClusteringAlgorithm<Clustering<ClusterModel>> {
+public class KNNKernelDensityMinimaClustering<V extends NumberVector> extends AbstractAlgorithm<Clustering<ClusterModel>> implements ClusteringAlgorithm<Clustering<ClusterModel>> {
/**
* Class logger.
*/
@@ -138,9 +138,7 @@ public class KNNKernelDensityMinimaClustering<V extends NumberVector<?>> extends
StepProgress sprog = LOG.isVerbose() ? new StepProgress("Clustering steps", 2) : null;
- if(sprog != null) {
- sprog.beginStep(1, "Kernel density estimation.", LOG);
- }
+ LOG.beginStep(sprog, 1, "Kernel density estimation.");
{
double[] scratch = new double[2 * k];
iter.seek(0);
@@ -216,9 +214,7 @@ public class KNNKernelDensityMinimaClustering<V extends NumberVector<?>> extends
}
}
- if(sprog != null) {
- sprog.beginStep(2, "Local minima detection.", LOG);
- }
+ LOG.beginStep(sprog, 2, "Local minima detection.");
Clustering<ClusterModel> clustering = new Clustering<>("onedimensional-kde-clustering", "One-Dimensional clustering using kernel density estimation.");
{
double[] scratch = new double[2 * minwindow + 1];
@@ -270,15 +266,13 @@ public class KNNKernelDensityMinimaClustering<V extends NumberVector<?>> extends
clustering.addToplevelCluster(new Cluster<>(cids, ClusterModel.CLUSTER));
}
- if(sprog != null) {
- sprog.setCompleted(LOG);
- }
+ LOG.ensureCompleted(sprog);
return clustering;
}
@Override
public TypeInformation[] getInputTypeRestriction() {
- return TypeUtil.array(new VectorFieldTypeInformation<>(NumberVector.class, dim + 1, Integer.MAX_VALUE));
+ return TypeUtil.array(VectorFieldTypeInformation.typeRequest(NumberVector.class, dim + 1, Integer.MAX_VALUE));
}
@Override
@@ -293,7 +287,7 @@ public class KNNKernelDensityMinimaClustering<V extends NumberVector<?>> extends
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* Dimension to use for clustering.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/onedimensional/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/onedimensional/package-info.java
index c6c55244..124bc7d7 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/onedimensional/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/onedimensional/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/result/optics/ClusterOrderEntry.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/ClusterOrderEntry.java
index fab3a8c3..e2f720fc 100644
--- a/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/ClusterOrderEntry.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.result.optics;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.optics;
/*
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.result.optics;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Generic Cluster Order Entry Interface.
@@ -34,11 +33,10 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @apiviz.landmark
*
* @apiviz.composedOf DBID
- * @apiviz.composedOf Distance
- *
- * @param <D> Distance type
+ *
+ * @param <SELF> Type self-reference.
*/
-public interface ClusterOrderEntry<D extends Distance<D>> {
+public interface ClusterOrderEntry<SELF> extends Comparable<SELF> {
/**
* Returns the object id of this entry.
*
@@ -53,11 +51,4 @@ public interface ClusterOrderEntry<D extends Distance<D>> {
* @return the id of the predecessor of this entry
*/
public DBID getPredecessorID();
-
- /**
- * Returns the reachability distance of this entry
- *
- * @return the reachability distance of this entry
- */
- public D getReachability();
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/ClusterOrderResult.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/ClusterOrderResult.java
new file mode 100644
index 00000000..fd98bf11
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/ClusterOrderResult.java
@@ -0,0 +1,229 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.optics;
+
+/*
+ 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.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
+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.result.BasicResult;
+import de.lmu.ifi.dbs.elki.result.IterableResult;
+import de.lmu.ifi.dbs.elki.result.OrderingResult;
+import de.lmu.ifi.dbs.elki.result.ResultAdapter;
+
+/**
+ * Class to store the result of an ordering clustering algorithm such as OPTICS.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.landmark
+ *
+ * @apiviz.has ClusterOrderEntry oneway - - contains
+ * @apiviz.composedOf ClusterOrderResult.ClusterOrderAdapter
+ *
+ * @param <E> entry type.
+ */
+public class ClusterOrderResult<E extends ClusterOrderEntry<?>> extends BasicResult implements IterableResult<E>, Relation<E> {
+ /**
+ * Cluster order storage
+ */
+ private ArrayList<E> clusterOrder;
+
+ /**
+ * Map of object IDs to their cluster order entry
+ */
+ private WritableDataStore<E> map;
+
+ /**
+ * The DBIDs we are defined for
+ */
+ DBIDs ids;
+
+ /**
+ * The database.
+ */
+ Database database;
+
+ /**
+ * Constructor
+ *
+ * @param database Database to attach the result to
+ * @param ids Object IDs included
+ * @param name The long name (for pretty printing)
+ * @param shortname the short name (for filenames etc.)
+ */
+ public ClusterOrderResult(Database database, DBIDs ids, String name, String shortname) {
+ super(name, shortname);
+ this.ids = ids;
+ this.clusterOrder = new ArrayList<>(ids.size());
+ this.map = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_DB, ClusterOrderEntry.class);
+
+ addChildResult(new ClusterOrderAdapter(this.clusterOrder));
+ }
+
+ /**
+ * Retrieve the complete cluster order.
+ *
+ * @return cluster order
+ */
+ public List<E> getClusterOrder() {
+ return clusterOrder;
+ }
+
+ /**
+ * Get the type of entries in this cluster order.
+ *
+ * @return Cluster order
+ */
+ public Class<? super E> getEntryType() {
+ if(clusterOrder.size() <= 0) {
+ return null;
+ }
+ @SuppressWarnings("unchecked")
+ Class<? super E> cls = (Class<? super E>) clusterOrder.get(0).getClass();
+ return cls;
+ }
+
+ /**
+ * The cluster order is iterable
+ */
+ @Override
+ public Iterator<E> iterator() {
+ return clusterOrder.iterator();
+ }
+
+ /**
+ * Add an object to the cluster order.
+ *
+ * @param ce Entry
+ */
+ public void add(E ce) {
+ clusterOrder.add(ce);
+ map.put(ce.getID(), ce);
+ }
+
+ @Override
+ public Database getDatabase() {
+ return database;
+ }
+
+ @Override
+ public SimpleTypeInformation<E> getDataTypeInformation() {
+ return new SimpleTypeInformation<>(ClusterOrderEntry.class);
+ }
+
+ @Override
+ public DBIDs getDBIDs() {
+ return ids;
+ }
+
+ @Override
+ public DBIDIter iterDBIDs() {
+ return ids.iter();
+ }
+
+ @Override
+ public int size() {
+ return ids.size();
+ }
+
+ @Override
+ public E get(DBIDRef id) {
+ return map.get(id);
+ }
+
+ @Override
+ public void set(DBIDRef id, E val) {
+ map.put(id, val);
+ }
+
+ @Override
+ public void delete(DBIDRef id) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Ordering part of the result.
+ *
+ * @author Erich Schubert
+ */
+ class ClusterOrderAdapter implements OrderingResult, ResultAdapter {
+ /**
+ * Access reference.
+ */
+ private ArrayList<E> clusterOrder;
+
+ /**
+ * Constructor.
+ *
+ * @param clusterOrder order to return
+ */
+ public ClusterOrderAdapter(final ArrayList<E> clusterOrder) {
+ super();
+ this.clusterOrder = clusterOrder;
+ }
+
+ @Override
+ public DBIDs getDBIDs() {
+ return ids;
+ }
+
+ /**
+ * Use the cluster order to sort the given collection ids.
+ *
+ * Implementation of the {@link OrderingResult} interface.
+ */
+ @Override
+ public ArrayModifiableDBIDs iter(DBIDs ids) {
+ ArrayModifiableDBIDs res = DBIDUtil.newArray(ids.size());
+ for(E e : clusterOrder) {
+ if(ids.contains(e.getID())) {
+ res.add(e.getID());
+ }
+ }
+ return res;
+ }
+
+ @Override
+ public String getLongName() {
+ return "Derived Object Order";
+ }
+
+ @Override
+ public String getShortName() {
+ return "clusterobjectorder";
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/CorrelationClusterOrderEntry.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/CorrelationClusterOrderEntry.java
new file mode 100644
index 00000000..b621ac24
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/CorrelationClusterOrderEntry.java
@@ -0,0 +1,170 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.optics;
+
+/*
+ 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.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.result.textwriter.TextWriteable;
+import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
+
+/**
+ * Cluster order entry for correlation-based OPTICS variants.
+ *
+ * @author Elke Achtert
+ * @author Erich Schubert
+ *
+ * @param <SELF> Type self-reference
+ */
+public abstract class CorrelationClusterOrderEntry<SELF extends CorrelationClusterOrderEntry<SELF>> implements ClusterOrderEntry<SELF>, Comparable<SELF>, TextWriteable {
+ /**
+ * The component separator used by correlation distances.
+ *
+ * Note: Do NOT use regular expression syntax characters!
+ */
+ public static final String SEPARATOR = "x";
+
+ /**
+ * The id of the entry.
+ */
+ protected DBID objectID;
+
+ /**
+ * The id of the entry's predecessor.
+ */
+ protected DBID predecessorID;
+
+ /**
+ * The correlation dimension.
+ */
+ protected int correlationValue;
+
+ /**
+ * The Euclidean distance in the subspace.
+ */
+ protected double euclideanValue;
+
+ /**
+ * Constructs a new CorrelationDistance object.
+ *
+ * @param correlationValue the correlation dimension to be represented by the
+ * CorrelationDistance
+ * @param euclideanValue the Euclidean distance to be represented by the
+ * CorrelationDistance
+ */
+ public CorrelationClusterOrderEntry(DBID objectID, DBID predecessorID, int correlationValue, double euclideanValue) {
+ this.objectID = objectID;
+ this.predecessorID = predecessorID;
+ this.correlationValue = correlationValue;
+ this.euclideanValue = euclideanValue;
+ }
+
+ @Override
+ public String toString() {
+ return Integer.toString(correlationValue) + SEPARATOR + Double.toString(euclideanValue);
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this one.
+ *
+ * NOTE: for the use in an UpdatableHeap, only the ID is used! This is
+ * important, otherwise OPTICS will not work.
+ *
+ * @param o the reference object with which to compare.
+ * @return <code>true</code> if this object has the same attribute values as
+ * the o argument; <code>false</code> otherwise.
+ */
+ @Override
+ public final boolean equals(Object o) {
+ if(this == o) {
+ return true;
+ }
+ if(!(o instanceof ClusterOrderEntry)) {
+ return false;
+ }
+
+ final ClusterOrderEntry<?> that = (ClusterOrderEntry<?>) o;
+ // Compare by ID only, for UpdatableHeap!
+ return DBIDUtil.equal(objectID, that.getID());
+ }
+
+ /**
+ * Returns a hash code value for the object.
+ *
+ * NOTE: for the use in an UpdatableHeap, only the ID is used! This is
+ * important, otherwise OPTICS will not work.
+ *
+ * @return the object id if this entry
+ */
+ @Override
+ public final int hashCode() {
+ return objectID.hashCode();
+ }
+
+ @Override
+ public int compareTo(SELF other) {
+ if(this.correlationValue < other.correlationValue) {
+ return -1;
+ }
+ if(this.correlationValue > other.correlationValue) {
+ return +1;
+ }
+ return Double.compare(this.euclideanValue, other.euclideanValue);
+ }
+
+ @Override
+ public DBID getID() {
+ return objectID;
+ }
+
+ @Override
+ public DBID getPredecessorID() {
+ return predecessorID;
+ }
+
+ /**
+ * Get the correlation dimensionality.
+ *
+ * @return Correlation dimensionality
+ */
+ public int getCorrelationValue() {
+ return correlationValue;
+ }
+
+ /**
+ * Get the Euclidean distance in the orthogonal space.
+ *
+ * @return Euclidean distance
+ */
+ public double getEuclideanValue() {
+ return euclideanValue;
+ }
+
+ @Override
+ public void writeToText(TextWriterStream out, String label) {
+ out.inlinePrint("predecessor=" + DBIDUtil.toString((DBIDRef) predecessorID));
+ out.inlinePrint("reach-dim=" + correlationValue);
+ out.inlinePrint("reachability=" + euclideanValue);
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/DeLiClu.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/DeLiClu.java
index 814b4cc4..a14781d9 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/DeLiClu.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/DeLiClu.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.optics;
/*
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
@@ -36,14 +36,12 @@ import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.datastore.DataStore;
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.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.index.tree.LeafEntry;
import de.lmu.ifi.dbs.elki.index.tree.TreeIndexPathComponent;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry;
@@ -55,7 +53,7 @@ import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluTreeI
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.UpdatableHeap;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
@@ -67,8 +65,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
/**
- * DeLiClu provides the DeLiClu algorithm, a hierarchical algorithm to find
- * density-connected sets in a database.
+ * DeliClu: Density-Based Hierarchical Clustering, a hierarchical algorithm to
+ * find density-connected sets in a database.
* <p>
* Reference: <br>
* E. Achtert, C. Böhm, P. Kröger: DeLiClu: Boosting Robustness, Completeness,
@@ -80,24 +78,21 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*
* @author Elke Achtert
* @param <NV> the type of NumberVector handled by this Algorithm
- * @param <D> the type of Distance used
*/
@Title("DeliClu: Density-Based Hierarchical Clustering")
@Description("Hierachical algorithm to find density-connected sets in a database based on the parameter 'minpts'.")
-@Reference(authors = "E. Achtert, C. Böhm, P. Kröger", title = "DeLiClu: Boosting Robustness, Completeness, Usability, and Efficiency of Hierarchical Clustering by a Closest Pair Ranking", booktitle = "Proc. 10th Pacific-Asia Conference on Knowledge Discovery and Data Mining (PAKDD 2006), Singapore, 2006", url = "http://dx.doi.org/10.1007/11731139_16")
-public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm<NV, D, ClusterOrderResult<D>> implements OPTICSTypeAlgorithm<D> {
+@Reference(authors = "E. Achtert, C. Böhm, P. Kröger", //
+title = "DeLiClu: Boosting Robustness, Completeness, Usability, and Efficiency of Hierarchical Clustering by a Closest Pair Ranking", //
+booktitle = "Proc. 10th Pacific-Asia Conference on Knowledge Discovery and Data Mining (PAKDD 2006), Singapore, 2006", //
+url = "http://dx.doi.org/10.1007/11731139_16")
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.clustering.DeLiClu" })
+public class DeLiClu<NV extends NumberVector> extends AbstractDistanceBasedAlgorithm<NV, ClusterOrderResult<DoubleDistanceClusterOrderEntry>> implements OPTICSTypeAlgorithm<DoubleDistanceClusterOrderEntry> {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(DeLiClu.class);
/**
- * Parameter to specify the threshold for minimum number of points within a
- * cluster, must be an integer greater than 0.
- */
- public static final OptionID MINPTS_ID = new OptionID("deliclu.minpts", "Threshold for minimum number of points within a cluster.");
-
- /**
* The priority queue for the algorithm.
*/
private UpdatableHeap<SpatialObjectPair> heap;
@@ -105,10 +100,10 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
/**
* Holds the knnJoin algorithm.
*/
- private KNNJoin<NV, D, DeLiCluNode, DeLiCluEntry> knnJoin;
+ private KNNJoin<NV, DeLiCluNode, DeLiCluEntry> knnJoin;
/**
- * Holds the value of {@link #MINPTS_ID}.
+ * Density threshold in number of objects.
*/
private int minpts;
@@ -118,13 +113,13 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
* @param distanceFunction Distance function
* @param minpts MinPts
*/
- public DeLiClu(DistanceFunction<? super NV, D> distanceFunction, int minpts) {
+ public DeLiClu(DistanceFunction<? super NV> distanceFunction, int minpts) {
super(distanceFunction);
this.knnJoin = new KNNJoin<>(distanceFunction, minpts);
this.minpts = minpts;
}
- public ClusterOrderResult<D> run(Database database, Relation<NV> relation) {
+ public ClusterOrderResult<DoubleDistanceClusterOrderEntry> run(Database database, Relation<NV> relation) {
Collection<DeLiCluTreeIndex<NV>> indexes = ResultUtil.filterResults(database, DeLiCluTreeIndex.class);
if(indexes.size() != 1) {
throw new AbortException("DeLiClu found " + indexes.size() + " DeLiCluTree indexes. DeLiClu needs a special index to operate, therefore you need to add this index to your database.");
@@ -132,31 +127,32 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
DeLiCluTreeIndex<NV> index = indexes.iterator().next();
// FIXME: check that the index matches the relation!
- if(!(getDistanceFunction() instanceof SpatialPrimitiveDistanceFunction<?, ?>)) {
+ if(!(getDistanceFunction() instanceof SpatialPrimitiveDistanceFunction<?>)) {
throw new IllegalArgumentException("Distance Function must be an instance of " + SpatialPrimitiveDistanceFunction.class.getName());
}
@SuppressWarnings("unchecked")
- SpatialPrimitiveDistanceFunction<NV, D> distFunction = (SpatialPrimitiveDistanceFunction<NV, D>) getDistanceFunction();
+ SpatialPrimitiveDistanceFunction<NV> distFunction = (SpatialPrimitiveDistanceFunction<NV>) getDistanceFunction();
// first do the knn-Join
if(LOG.isVerbose()) {
LOG.verbose("knnJoin...");
}
- DataStore<KNNList<D>> knns = knnJoin.run(database, relation);
+ DataStore<KNNList> knns = knnJoin.run(database, relation);
+ DBIDs ids = relation.getDBIDs();
+ final int size = ids.size();
- FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("DeLiClu", relation.size(), LOG) : null;
- final int size = relation.size();
+ FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("DeLiClu", size, LOG) : null;
- ClusterOrderResult<D> clusterOrder = new ClusterOrderResult<>("DeLiClu Clustering", "deliclu-clustering");
+ ClusterOrderResult<DoubleDistanceClusterOrderEntry> clusterOrder = new ClusterOrderResult<>(database, ids, "DeLiClu Clustering", "deliclu-clustering");
heap = new UpdatableHeap<>();
// add start object to cluster order and (root, root) to priority queue
- DBID startID = getStartObject(relation);
- clusterOrder.add(startID, null, distFunction.getDistanceFactory().infiniteDistance());
+ DBID startID = DBIDUtil.deref(ids.iter());
+ clusterOrder.add(new DoubleDistanceClusterOrderEntry(startID, null, Double.POSITIVE_INFINITY));
int numHandled = 1;
index.setHandled(startID, relation.get(startID));
SpatialDirectoryEntry rootEntry = (SpatialDirectoryEntry) index.getRootEntry();
- SpatialObjectPair spatialObjectPair = new SpatialObjectPair(distFunction.getDistanceFactory().nullDistance(), rootEntry, rootEntry, true);
+ SpatialObjectPair spatialObjectPair = new SpatialObjectPair(0., rootEntry, rootEntry, true);
heap.add(spatialObjectPair);
while(numHandled < size) {
@@ -180,7 +176,7 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
throw new RuntimeException("snh: parent(" + e1id + ") = null!!!");
}
// add to cluster order
- clusterOrder.add(e1id, e2.getDBID(), dataPair.distance);
+ clusterOrder.add(new DoubleDistanceClusterOrderEntry(e1id, e2.getDBID(), dataPair.distance));
numHandled++;
// reinsert expanded leafs
reinsertExpanded(distFunction, index, path, knns);
@@ -190,27 +186,11 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
}
}
}
- if(progress != null) {
- progress.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(progress);
return clusterOrder;
}
/**
- * Returns the id of the start object for the run method.
- *
- * @param relation the database relation storing the objects
- * @return the id of the start object for the run method
- */
- private DBID getStartObject(Relation<NV> relation) {
- DBIDIter it = relation.iterDBIDs();
- if(!it.valid()) {
- return null;
- }
- return DBIDUtil.deref(it);
- }
-
- /**
* Expands the spatial nodes of the specified pair.
*
* @param index the index storing the objects
@@ -218,7 +198,7 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
* @param nodePair the pair of nodes to be expanded
* @param knns the knn list
*/
- private void expandNodes(DeLiCluTree index, SpatialPrimitiveDistanceFunction<NV, D> distFunction, SpatialObjectPair nodePair, DataStore<KNNList<D>> knns) {
+ private void expandNodes(DeLiCluTree index, SpatialPrimitiveDistanceFunction<NV> distFunction, SpatialObjectPair nodePair, DataStore<KNNList> knns) {
DeLiCluNode node1 = index.getNode(((SpatialDirectoryEntry) nodePair.entry1).getPageID());
DeLiCluNode node2 = index.getNode(((SpatialDirectoryEntry) nodePair.entry2).getPageID());
@@ -239,7 +219,7 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
* @param node1 the first node
* @param node2 the second node
*/
- private void expandDirNodes(SpatialPrimitiveDistanceFunction<NV, D> distFunction, DeLiCluNode node1, DeLiCluNode node2) {
+ private void expandDirNodes(SpatialPrimitiveDistanceFunction<NV> distFunction, DeLiCluNode node1, DeLiCluNode node2) {
if(LOG.isDebuggingFinest()) {
LOG.debugFinest("ExpandDirNodes: " + node1.getPageID() + " + " + node2.getPageID());
}
@@ -259,7 +239,7 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
if(!entry2.hasHandled()) {
continue;
}
- D distance = distFunction.minDist(entry1, entry2);
+ double distance = distFunction.minDist(entry1, entry2);
SpatialObjectPair nodePair = new SpatialObjectPair(distance, entry1, entry2, true);
heap.add(nodePair);
@@ -275,7 +255,7 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
* @param node2 the second node
* @param knns the knn list
*/
- private void expandLeafNodes(SpatialPrimitiveDistanceFunction<NV, D> distFunction, DeLiCluNode node1, DeLiCluNode node2, DataStore<KNNList<D>> knns) {
+ private void expandLeafNodes(SpatialPrimitiveDistanceFunction<NV> distFunction, DeLiCluNode node1, DeLiCluNode node2, DataStore<KNNList> knns) {
if(LOG.isDebuggingFinest()) {
LOG.debugFinest("ExpandLeafNodes: " + node1.getPageID() + " + " + node2.getPageID());
}
@@ -295,8 +275,8 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
continue;
}
- D distance = distFunction.minDist(entry1, entry2);
- D reach = DistanceUtil.max(distance, knns.get(((LeafEntry) entry2).getDBID()).getKNNDistance());
+ double distance = distFunction.minDist(entry1, entry2);
+ double reach = Math.max(distance, knns.get(((LeafEntry) entry2).getDBID()).getKNNDistance());
SpatialObjectPair dataPair = new SpatialObjectPair(reach, entry1, entry2, false);
heap.add(dataPair);
}
@@ -311,12 +291,12 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
* @param path the path of the object inserted last
* @param knns the knn list
*/
- private void reinsertExpanded(SpatialPrimitiveDistanceFunction<NV, D> distFunction, DeLiCluTree index, List<TreeIndexPathComponent<DeLiCluEntry>> path, DataStore<KNNList<D>> knns) {
+ private void reinsertExpanded(SpatialPrimitiveDistanceFunction<NV> distFunction, DeLiCluTree index, List<TreeIndexPathComponent<DeLiCluEntry>> path, DataStore<KNNList> knns) {
SpatialDirectoryEntry rootEntry = (SpatialDirectoryEntry) path.remove(0).getEntry();
reinsertExpanded(distFunction, index, path, 0, rootEntry, knns);
}
- private void reinsertExpanded(SpatialPrimitiveDistanceFunction<NV, D> distFunction, DeLiCluTree index, List<TreeIndexPathComponent<DeLiCluEntry>> path, int pos, SpatialDirectoryEntry parentEntry, DataStore<KNNList<D>> knns) {
+ private void reinsertExpanded(SpatialPrimitiveDistanceFunction<NV> distFunction, DeLiCluTree index, List<TreeIndexPathComponent<DeLiCluEntry>> path, int pos, SpatialDirectoryEntry parentEntry, DataStore<KNNList> knns) {
DeLiCluNode parentNode = index.getNode(parentEntry.getPageID());
SpatialEntry entry2 = path.get(pos).getEntry();
@@ -326,8 +306,8 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
if(entry1.hasHandled()) {
continue;
}
- D distance = distFunction.minDist(entry1, entry2);
- D reach = DistanceUtil.max(distance, knns.get(((LeafEntry) entry2).getDBID()).getKNNDistance());
+ double distance = distFunction.minDist(entry1, entry2);
+ double reach = Math.max(distance, knns.get(((LeafEntry) entry2).getDBID()).getKNNDistance());
SpatialObjectPair dataPair = new SpatialObjectPair(reach, entry1, entry2, false);
heap.add(dataPair);
}
@@ -339,7 +319,7 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
// not yet expanded
if(!expanded.contains(entry1.getPageID())) {
- D distance = distFunction.minDist(entry1, entry2);
+ double distance = distFunction.minDist(entry1, entry2);
SpatialObjectPair nodePair = new SpatialObjectPair(distance, entry1, entry2, true);
heap.add(nodePair);
}
@@ -358,8 +338,8 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
}
@Override
- public D getDistanceFactory() {
- return getDistanceFunction().getDistanceFactory();
+ public Class<? super DoubleDistanceClusterOrderEntry> getEntryType() {
+ return DoubleDistanceClusterOrderEntry.class;
}
@Override
@@ -396,7 +376,7 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
/**
* The current distance.
*/
- D distance;
+ double distance;
/**
* Creates a new entry with the specified parameters.
@@ -406,7 +386,7 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
* @param isExpandable if true, this pair is expandable (a pair of nodes),
* otherwise this pair is not expandable (a pair of objects)
*/
- public SpatialObjectPair(D distance, SpatialEntry entry1, SpatialEntry entry2, boolean isExpandable) {
+ public SpatialObjectPair(double distance, SpatialEntry entry1, SpatialEntry entry2, boolean isExpandable) {
this.distance = distance;
this.entry1 = entry1;
this.entry2 = entry2;
@@ -436,7 +416,7 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
* return 1; } return 0;
*/
// FIXME: inverted?
- return this.distance.compareTo(other.distance);
+ return Double.compare(this.distance, other.distance);
}
/**
@@ -489,7 +469,13 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
*
* @apiviz.exclude
*/
- public static class Parameterizer<NV extends NumberVector<?>, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm.Parameterizer<NV, D> {
+ public static class Parameterizer<NV extends NumberVector> extends AbstractDistanceBasedAlgorithm.Parameterizer<NV> {
+ /**
+ * Parameter to specify the threshold for minimum number of points within a
+ * cluster, must be an integer greater than 0.
+ */
+ public static final OptionID MINPTS_ID = new OptionID("deliclu.minpts", "Threshold for minimum number of points within a cluster.");
+
protected int minpts = 0;
@Override
@@ -503,7 +489,7 @@ public class DeLiClu<NV extends NumberVector<?>, D extends Distance<D>> extends
}
@Override
- protected DeLiClu<NV, D> makeInstance() {
+ protected DeLiClu<NV> makeInstance() {
return new DeLiClu<>(distanceFunction, minpts);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/result/optics/DoubleDistanceClusterOrderEntry.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/DoubleDistanceClusterOrderEntry.java
index 74f65e73..91040721 100644
--- a/src/de/lmu/ifi/dbs/elki/result/optics/DoubleDistanceClusterOrderEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/DoubleDistanceClusterOrderEntry.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.result.optics;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.optics;
/*
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,15 +24,17 @@ package de.lmu.ifi.dbs.elki.result.optics;
*/
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.result.textwriter.TextWriteable;
+import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
/**
- * Provides an entry in a cluster order.
+ * Entry in a {@link ClusterOrderResult}.
*
* @author Elke Achtert
*/
-public class DoubleDistanceClusterOrderEntry implements Comparable<ClusterOrderEntry<DoubleDistance>>, ClusterOrderEntry<DoubleDistance> {
+public class DoubleDistanceClusterOrderEntry implements ClusterOrderEntry<DoubleDistanceClusterOrderEntry>, TextWriteable {
/**
* The id of the entry.
*/
@@ -130,25 +132,24 @@ public class DoubleDistanceClusterOrderEntry implements Comparable<ClusterOrderE
*
* @return the reachability distance of this entry
*/
- @Override
- public DoubleDistance getReachability() {
- return new DoubleDistance(reachability);
+ public double getReachability() {
+ return reachability;
}
@Override
- public int compareTo(ClusterOrderEntry<DoubleDistance> o) {
- if(o instanceof DoubleDistanceClusterOrderEntry) {
- int delta = Double.compare(this.reachability, ((DoubleDistanceClusterOrderEntry) o).reachability);
- if(delta != 0) {
- return delta;
- }
+ public int compareTo(DoubleDistanceClusterOrderEntry o) {
+ if(this.reachability < o.reachability) {
+ return -1;
}
- else {
- int delta = this.getReachability().compareTo(o.getReachability());
- if(delta != 0) {
- return delta;
- }
+ if(this.reachability > o.reachability) {
+ return +1;
}
return -getID().compareTo(o.getID());
}
+
+ @Override
+ public void writeToText(TextWriterStream out, String label) {
+ out.inlinePrint("predecessor=" + DBIDUtil.toString((DBIDRef) predecessorID));
+ out.inlinePrint("reachability=" + reachability);
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/GeneralizedOPTICS.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/GeneralizedOPTICS.java
new file mode 100644
index 00000000..feeeb6ef
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/GeneralizedOPTICS.java
@@ -0,0 +1,154 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.optics;
+
+/*
+ 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.Collection;
+
+import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
+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.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.UpdatableHeap;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+
+/**
+ * A trivial generalization of OPTICS that is not restricted to numerical
+ * distances, and serves as a base for several other algorithms (HiCO, HiSC).
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> the type of DatabaseObjects handled by the algorithm
+ * @param <E> the type of entries in the cluster order
+ */
+public abstract class GeneralizedOPTICS<O, E extends ClusterOrderEntry<E>> extends AbstractAlgorithm<ClusterOrderResult<E>> implements OPTICSTypeAlgorithm<E> {
+ /**
+ * Parameter to specify the threshold for minimum number of points in the
+ * epsilon-neighborhood of a point, must be an integer greater than 0.
+ */
+ public static final OptionID MINPTS_ID = new OptionID("optics.minpts", "Threshold for minimum number of points in the epsilon-neighborhood of a point.");
+
+ /**
+ * Density threshold in number of points.
+ */
+ private int minpts;
+
+ /**
+ * Holds a set of processed ids.
+ */
+ private ModifiableDBIDs processedIDs;
+
+ /**
+ * Constructor.
+ *
+ * @param minpts Minpts value
+ */
+ public GeneralizedOPTICS(int minpts) {
+ super();
+ this.minpts = minpts;
+ }
+
+ /**
+ * Run OPTICS on the database.
+ *
+ * @param relation Relation
+ * @return Result
+ */
+ public ClusterOrderResult<E> run(Relation<O> relation) {
+ final DBIDs ids = relation.getDBIDs();
+ final int size = ids.size();
+ final FiniteProgress progress = getLogger().isVerbose() ? new FiniteProgress("Generalized OPTICS", size, getLogger()) : null;
+
+ processedIDs = DBIDUtil.newHashSet(size);
+ ClusterOrderResult<E> clusterOrder = new ClusterOrderResult<>(relation.getDatabase(), ids, "OPTICS Clusterorder", "optics-clusterorder");
+
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ if(!processedIDs.contains(iditer)) {
+ expandClusterOrder(clusterOrder, relation, DBIDUtil.deref(iditer), progress);
+ }
+ }
+ getLogger().ensureCompleted(progress);
+
+ return clusterOrder;
+ }
+
+ /**
+ * OPTICS-function expandClusterOrder.
+ *
+ * @param clusterOrder Cluster order result to expand
+ * @param relation the data relation to run on
+ * @param objectID the currently processed object
+ * @param progress the progress object to actualize the current progress if
+ * the algorithm
+ */
+ protected void expandClusterOrder(ClusterOrderResult<E> clusterOrder, Relation<O> relation, DBID objectID, FiniteProgress progress) {
+ UpdatableHeap<E> heap = new UpdatableHeap<>();
+ heap.add(makeSeedEntry(relation, objectID));
+
+ while(!heap.isEmpty()) {
+ final E current = heap.poll();
+ clusterOrder.add(current);
+ processedIDs.add(current.getID());
+
+ Collection<E> neighbors = getNeighborsForDBID(relation, current.getID());
+ if(neighbors != null && neighbors.size() >= minpts) {
+ for(E entry : neighbors) {
+ if(processedIDs.contains(entry.getID())) {
+ continue;
+ }
+ heap.add(entry);
+ }
+ }
+ if(progress != null) {
+ progress.setProcessed(processedIDs.size(), getLogger());
+ }
+ }
+ }
+
+ /**
+ * Create the initial element to seed the algorithm.
+ *
+ * @param relation Data relation
+ * @param objectID Object ID
+ * @return Seed element.
+ */
+ abstract protected E makeSeedEntry(Relation<O> relation, DBID objectID);
+
+ /**
+ * Compute the neighbors for the given DBID.
+ *
+ * @param relation Data relation
+ * @param id Current object ID
+ * @return Neighbors
+ */
+ abstract protected Collection<E> getNeighborsForDBID(Relation<O> relation, DBID id);
+
+ @Override
+ public int getMinPts() {
+ return minpts;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/OPTICS.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/OPTICS.java
new file mode 100644
index 00000000..742b9f4f
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/OPTICS.java
@@ -0,0 +1,238 @@
+package de.lmu.ifi.dbs.elki.algorithm.clustering.optics;
+
+/*
+ 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.algorithm.AbstractDistanceBasedAlgorithm;
+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.QueryUtil;
+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.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.UpdatableHeap;
+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;
+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;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+
+/**
+ * The OPTICS algorithm for density-based hierarchical clustering.
+ *
+ * Reference:
+ * <p>
+ * M. Ankerst, M. Breunig, H.-P. Kriegel, and J. Sander:<br />
+ * OPTICS: Ordering Points to Identify the Clustering Structure. <br/>
+ * In: Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '99).
+ * </p>
+ *
+ * @author Elke Achtert
+ * @param <O> the type of DatabaseObjects handled by the algorithm
+ */
+@Title("OPTICS: Density-Based Hierarchical Clustering")
+@Description("Algorithm to find density-connected sets in a database based on the parameters 'minPts' and 'epsilon' (specifying a volume). These two parameters determine a density threshold for clustering.")
+@Reference(authors = "M. Ankerst, M. Breunig, H.-P. Kriegel, and J. Sander", //
+title = "OPTICS: Ordering Points to Identify the Clustering Structure", //
+booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '99)", //
+url = "http://dx.doi.org/10.1145/304181.304187")
+@Alias({ "OPTICS", "de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICS" })
+public class OPTICS<O> extends AbstractDistanceBasedAlgorithm<O, ClusterOrderResult<DoubleDistanceClusterOrderEntry>> implements OPTICSTypeAlgorithm<DoubleDistanceClusterOrderEntry> {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(OPTICS.class);
+
+ /**
+ * Holds the maximum distance to search for objects (performance parameter)
+ */
+ private double epsilon;
+
+ /**
+ * The density threshold, in number of points.
+ */
+ private int minpts;
+
+ /**
+ * Holds a set of processed ids.
+ */
+ private ModifiableDBIDs processedIDs;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function
+ * @param epsilon Epsilon value
+ * @param minpts Minpts value
+ */
+ public OPTICS(DistanceFunction<? super O> distanceFunction, double epsilon, int minpts) {
+ super(distanceFunction);
+ this.epsilon = epsilon;
+ this.minpts = minpts;
+ }
+
+ /**
+ * Run OPTICS on the database.
+ *
+ * @param relation Relation
+ * @return Result
+ */
+ public ClusterOrderResult<DoubleDistanceClusterOrderEntry> run(Relation<O> relation) {
+ RangeQuery<O> rangeQuery = QueryUtil.getRangeQuery(relation, getDistanceFunction(), epsilon);
+ DBIDs ids = relation.getDBIDs();
+
+ int size = ids.size();
+ final FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("OPTICS", size, LOG) : null;
+
+ processedIDs = DBIDUtil.newHashSet(size);
+ ClusterOrderResult<DoubleDistanceClusterOrderEntry> clusterOrder = new ClusterOrderResult<>(relation.getDatabase(), ids, "OPTICS Clusterorder", "optics-clusterorder");
+
+ for(DBIDIter iditer = ids.iter(); iditer.valid(); iditer.advance()) {
+ if(!processedIDs.contains(iditer)) {
+ expandClusterOrder(clusterOrder, relation, rangeQuery, DBIDUtil.deref(iditer), epsilon, progress);
+ }
+ }
+ LOG.ensureCompleted(progress);
+
+ return clusterOrder;
+ }
+
+ /**
+ * OPTICS-function expandClusterOrder.
+ *
+ * @param clusterOrder Cluster order result to expand
+ * @param database the database on which the algorithm is run
+ * @param rangeQuery the range query to use
+ * @param objectID the currently processed object
+ * @param epsilon Query epsilon
+ * @param progress the progress object to actualize the current progress if
+ * the algorithm
+ */
+ protected void expandClusterOrder(ClusterOrderResult<DoubleDistanceClusterOrderEntry> clusterOrder, Relation<O> database, RangeQuery<O> rangeQuery, DBID objectID, double epsilon, FiniteProgress progress) {
+ UpdatableHeap<DoubleDistanceClusterOrderEntry> heap = new UpdatableHeap<>();
+ heap.add(new DoubleDistanceClusterOrderEntry(objectID, null, Double.POSITIVE_INFINITY));
+
+ while(!heap.isEmpty()) {
+ final DoubleDistanceClusterOrderEntry current = heap.poll();
+ clusterOrder.add(current);
+ processedIDs.add(current.getID());
+
+ DoubleDBIDList neighbors = rangeQuery.getRangeForDBID(current.getID(), epsilon);
+ if(neighbors.size() >= minpts) {
+ final DoubleDBIDPair last = neighbors.get(minpts - 1);
+ double coreDistance = last.doubleValue();
+
+ for(DoubleDBIDListIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ if(processedIDs.contains(neighbor)) {
+ continue;
+ }
+ double reachability = Math.max(neighbor.doubleValue(), coreDistance);
+ heap.add(new DoubleDistanceClusterOrderEntry(DBIDUtil.deref(neighbor), current.getID(), reachability));
+ }
+ }
+ if(progress != null) {
+ progress.setProcessed(processedIDs.size(), LOG);
+ }
+ }
+ }
+
+ @Override
+ public int getMinPts() {
+ return minpts;
+ }
+
+ @Override
+ public Class<? super DoubleDistanceClusterOrderEntry> getEntryType() {
+ return DoubleDistanceClusterOrderEntry.class;
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * Parameter to specify the maximum radius of the neighborhood to be
+ * considered, must be suitable to the distance function specified.
+ */
+ public static final OptionID EPSILON_ID = new OptionID("optics.epsilon", "The maximum radius of the neighborhood to be considered.");
+
+ /**
+ * Parameter to specify the threshold for minimum number of points in the
+ * epsilon-neighborhood of a point, must be an integer greater than 0.
+ */
+ public static final OptionID MINPTS_ID = new OptionID("optics.minpts", "Threshold for minimum number of points in the epsilon-neighborhood of a point.");
+
+ protected double epsilon = Double.POSITIVE_INFINITY;
+
+ protected int minpts = 0;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ DoubleParameter epsilonP = new DoubleParameter(EPSILON_ID);
+ epsilonP.setOptional(true);
+ if(config.grab(epsilonP)) {
+ epsilon = epsilonP.getValue();
+ }
+
+ IntParameter minptsP = new IntParameter(MINPTS_ID);
+ minptsP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(minptsP)) {
+ minpts = minptsP.intValue();
+ }
+ }
+
+ @Override
+ protected OPTICS<O> makeInstance() {
+ return new OPTICS<>(distanceFunction, epsilon, minpts);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICSTypeAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/OPTICSTypeAlgorithm.java
index 82d7ec88..0296ffb3 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICSTypeAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/OPTICSTypeAlgorithm.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.optics;
/*
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,6 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering;
import de.lmu.ifi.dbs.elki.algorithm.Algorithm;
import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
/**
* Interface for OPTICS type algorithms, that can be analysed by OPTICS Xi etc.
@@ -35,12 +33,12 @@ import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
*
* @apiviz.has ClusterOrderResult
*
- * @param <D> Distance type
+ * @param <E> Cluster order entry type
*/
-public interface OPTICSTypeAlgorithm<D extends Distance<D>> extends Algorithm {
+public interface OPTICSTypeAlgorithm<E extends ClusterOrderEntry<E>> extends Algorithm {
@Override
- ClusterOrderResult<D> run(Database database);
-
+ ClusterOrderResult<E> run(Database database);
+
/**
* Get the minpts value used. Needed for OPTICS Xi etc.
*
@@ -49,9 +47,9 @@ public interface OPTICSTypeAlgorithm<D extends Distance<D>> extends Algorithm {
public int getMinPts();
/**
- * Get the distance factory. Needed for type checking (i.e. is number distance)
+ * Get the entry type. Needed for type checking (i.e. is number distance)
*
- * @return distance factory
+ * @return entry type
*/
- public D getDistanceFactory();
+ public Class<? super E> getEntryType();
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICSXi.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/OPTICSXi.java
index db343f3a..28c1f71b 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICSXi.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/OPTICSXi.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.optics;
/*
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,7 @@ import java.util.List;
import java.util.ListIterator;
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.model.OPTICSModel;
@@ -41,11 +42,9 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.result.IterableResult;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
+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;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -58,32 +57,21 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
*
* @author Erich Schubert
*
- * @apiviz.composedOf OPTICSTypeAlgorithm oneway
- * @apiviz.uses ClusterOrderResult oneway
- * @apiviz.has SteepAreaResult
- *
- * @param <N> Number distance used by OPTICS
+ * @apiviz.composedOf OPTICSTypeAlgorithm oneway - «runs»
+ * @apiviz.uses ClusterOrderResult oneway - «reads»
+ * @apiviz.has SteepAreaResult oneway - «produces»
*/
-public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<Clustering<OPTICSModel>> implements ClusteringAlgorithm<Clustering<OPTICSModel>> {
+@Alias({ "OPTICSXi", "de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICSXi" })
+public class OPTICSXi extends AbstractAlgorithm<Clustering<OPTICSModel>> implements ClusteringAlgorithm<Clustering<OPTICSModel>> {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(OPTICSXi.class);
/**
- * Parameter to specify the actual OPTICS algorithm to use.
- */
- public static final OptionID XIALG_ID = new OptionID("opticsxi.algorithm", "The actual OPTICS-type algorithm to use.");
-
- /**
- * Parameter to specify the steepness threshold.
- */
- public static final OptionID XI_ID = new OptionID("opticsxi.xi", "Threshold for the steepness requirement.");
-
- /**
* The actual algorithm we use.
*/
- OPTICSTypeAlgorithm<N> optics;
+ OPTICSTypeAlgorithm<DoubleDistanceClusterOrderEntry> optics;
/**
* Xi parameter
@@ -96,21 +84,25 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
* @param optics OPTICS algorithm to use
* @param xi Xi value
*/
- public OPTICSXi(OPTICSTypeAlgorithm<N> optics, double xi) {
+ public OPTICSXi(OPTICSTypeAlgorithm<DoubleDistanceClusterOrderEntry> optics, double xi) {
super();
this.optics = optics;
this.xi = xi;
}
public Clustering<OPTICSModel> run(Database database, Relation<?> relation) {
+ if(!DoubleDistanceClusterOrderEntry.class.isAssignableFrom(optics.getEntryType())) {
+ LOG.warning("Xi cluster extraction only supported for number distances!");
+ return null;
+ }
+
// TODO: ensure we are using the same relation?
- ClusterOrderResult<N> opticsresult = optics.run(database);
+ ClusterOrderResult<DoubleDistanceClusterOrderEntry> opticsresult = optics.run(database);
- if(!NumberDistance.class.isInstance(optics.getDistanceFactory())) {
- LOG.verbose("Xi cluster extraction only supported for number distances!");
+ if(!DoubleDistanceClusterOrderEntry.class.isAssignableFrom(opticsresult.getEntryType())) {
+ LOG.warning("Xi cluster extraction only supported for number distances!");
return null;
}
-
if(LOG.isVerbose()) {
LOG.verbose("Extracting clusters with Xi: " + xi);
}
@@ -126,9 +118,9 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
* @param minpts Parameter minPts
*/
// TODO: resolve handling of the last point in the cluster order
- private Clustering<OPTICSModel> extractClusters(ClusterOrderResult<N> clusterOrderResult, Relation<?> relation, double ixi, int minpts) {
+ private Clustering<OPTICSModel> extractClusters(ClusterOrderResult<DoubleDistanceClusterOrderEntry> clusterOrderResult, Relation<?> relation, double ixi, int minpts) {
// TODO: add progress?
- List<ClusterOrderEntry<N>> clusterOrder = clusterOrderResult.getClusterOrder();
+ List<DoubleDistanceClusterOrderEntry> clusterOrder = clusterOrderResult.getClusterOrder();
double mib = 0.0;
// TODO: make it configurable to keep this list; this is mostly useful for
// visualization
@@ -138,18 +130,18 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
HashSet<Cluster<OPTICSModel>> curclusters = new HashSet<>();
HashSetModifiableDBIDs unclaimedids = DBIDUtil.newHashSet(relation.getDBIDs());
- SteepScanPosition<N> scan = new SteepScanPosition<>(clusterOrder);
+ SteepScanPosition scan = new SteepScanPosition(clusterOrder);
while(scan.hasNext()) {
final int curpos = scan.index;
// Update maximum-inbetween
- mib = Math.max(mib, scan.ecurr.getReachability().doubleValue());
+ mib = Math.max(mib, scan.ecurr.getReachability());
// The last point cannot be the start of a steep area.
if(scan.esucc != null) {
// Xi-steep down area
if(scan.steepDown(ixi)) {
// Update mib values with current mib and filter
updateFilterSDASet(mib, sdaset, ixi);
- final double startval = scan.ecurr.getReachability().doubleValue();
+ final double startval = scan.ecurr.getReachability();
int startsteep = scan.index;
int endsteep = Math.min(scan.index + 1, clusterOrder.size());
{
@@ -171,7 +163,7 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
}
}
}
- mib = clusterOrder.get(endsteep).getReachability().doubleValue();
+ mib = clusterOrder.get(endsteep).getReachability();
final SteepDownArea sda = new SteepDownArea(startsteep, endsteep, startval, 0);
if(LOG.isDebuggingFinest()) {
LOG.debugFinest("Xi " + sda.toString());
@@ -192,8 +184,8 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
{
int startsteep = scan.index;
int endsteep = scan.index + 1;
- mib = scan.ecurr.getReachability().doubleValue();
- double esuccr = scan.esucc.getReachability().doubleValue();
+ mib = scan.ecurr.getReachability();
+ double esuccr = scan.esucc.getReachability();
// There is nothing higher than infinity
if(!Double.isInfinite(esuccr)) {
// find end of steep-up-area, eventually updating mib again
@@ -206,8 +198,8 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
// still steep - continue.
if(scan.steepUp(ixi)) {
endsteep = Math.min(scan.index + 1, clusterOrder.size() - 1);
- mib = scan.ecurr.getReachability().doubleValue();
- esuccr = scan.esucc.getReachability().doubleValue();
+ mib = scan.ecurr.getReachability();
+ esuccr = scan.esucc.getReachability();
}
else {
// Stop looking after minpts non-up steps.
@@ -240,7 +232,7 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
int cstart = sda.getStartIndex();
int cend = sua.getEndIndex();
// Hotfix: never include infinity-reachable points at the end
- while(cend > cstart && Double.isInfinite(clusterOrder.get(cend).getReachability().doubleValue())) {
+ while(cend > cstart && Double.isInfinite(clusterOrder.get(cend).getReachability())) {
--cend;
}
// However, we sometimes have to adjust this (Condition 4):
@@ -248,7 +240,7 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
// Case b)
if(sda.getMaximum() * ixi >= sua.getMaximum()) {
while(cstart < sda.getEndIndex()) {
- if(clusterOrder.get(cstart + 1).getReachability().doubleValue() > sua.getMaximum()) {
+ if(clusterOrder.get(cstart + 1).getReachability() > sua.getMaximum()) {
cstart++;
}
else {
@@ -259,7 +251,7 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
// Case c)
else if(sua.getMaximum() * ixi >= sda.getMaximum()) {
while(cend > sua.getStartIndex()) {
- if(clusterOrder.get(cend - 1).getReachability().doubleValue() > sda.getMaximum()) {
+ if(clusterOrder.get(cend - 1).getReachability() > sda.getMaximum()) {
cend--;
}
else {
@@ -311,7 +303,7 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
if(curclusters.size() > 0 || unclaimedids.size() > 0) {
if(unclaimedids.size() > 0) {
final Cluster<OPTICSModel> allcluster;
- if(clusterOrder.get(clusterOrder.size() - 1).getReachability().isInfiniteDistance()) {
+ if(clusterOrder.get(clusterOrder.size() - 1).getReachability() >= Double.POSITIVE_INFINITY) {
allcluster = new Cluster<>("Noise", unclaimedids, true, new OPTICSModel(0, clusterOrder.size() - 1));
}
else {
@@ -372,14 +364,12 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
* @author Erich Schubert
*
* @apiviz.exclude
- *
- * @param <N> Distance type
*/
- private static class SteepScanPosition<N extends NumberDistance<N, ?>> {
+ private static class SteepScanPosition {
/**
* Cluster order
*/
- List<ClusterOrderEntry<N>> co;
+ List<DoubleDistanceClusterOrderEntry> co;
/**
* Current position
@@ -389,19 +379,19 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
/**
* Current entry
*/
- ClusterOrderEntry<N> ecurr = null;
+ DoubleDistanceClusterOrderEntry ecurr = null;
/**
* Next entry
*/
- ClusterOrderEntry<N> esucc = null;
+ DoubleDistanceClusterOrderEntry esucc = null;
/**
* Constructor.
*
* @param co Cluster order
*/
- public SteepScanPosition(List<ClusterOrderEntry<N>> co) {
+ public SteepScanPosition(List<DoubleDistanceClusterOrderEntry> co) {
super();
this.co = co;
this.ecurr = (co.size() >= 1) ? co.get(0) : null;
@@ -435,13 +425,13 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
* @return truth value
*/
public boolean steepUp(double ixi) {
- if(ecurr.getReachability().isInfiniteDistance()) {
+ if(ecurr.getReachability() >= Double.POSITIVE_INFINITY) {
return false;
}
if(esucc == null) {
return true;
}
- return ecurr.getReachability().doubleValue() <= esucc.getReachability().doubleValue() * ixi;
+ return ecurr.getReachability() <= esucc.getReachability() * ixi;
}
/**
@@ -454,10 +444,10 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
if(esucc == null) {
return false;
}
- if(esucc.getReachability().isInfiniteDistance()) {
+ if(esucc.getReachability() >= Double.POSITIVE_INFINITY) {
return false;
}
- return ecurr.getReachability().doubleValue() * ixi >= esucc.getReachability().doubleValue();
+ return ecurr.getReachability() * ixi >= esucc.getReachability();
}
}
@@ -648,10 +638,20 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
*
* @apiviz.exclude
*/
- public static class Parameterizer<D extends NumberDistance<D, ?>> extends AbstractParameterizer {
- protected OPTICSTypeAlgorithm<D> optics;
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Parameter to specify the actual OPTICS algorithm to use.
+ */
+ public static final OptionID XIALG_ID = new OptionID("opticsxi.algorithm", "The actual OPTICS-type algorithm to use.");
+
+ /**
+ * Parameter to specify the steepness threshold.
+ */
+ public static final OptionID XI_ID = new OptionID("opticsxi.xi", "Threshold for the steepness requirement.");
+
+ protected OPTICSTypeAlgorithm<DoubleDistanceClusterOrderEntry> optics;
- protected double xi = 0.0;
+ protected double xi = 0.;
@Override
protected void makeOptions(Parameterization config) {
@@ -663,15 +663,15 @@ public class OPTICSXi<N extends NumberDistance<N, ?>> extends AbstractAlgorithm<
xi = xiP.doubleValue();
}
- ClassParameter<OPTICSTypeAlgorithm<D>> opticsP = new ClassParameter<>(XIALG_ID, OPTICSTypeAlgorithm.class, OPTICS.class);
+ ClassParameter<OPTICSTypeAlgorithm<DoubleDistanceClusterOrderEntry>> opticsP = new ClassParameter<>(XIALG_ID, OPTICSTypeAlgorithm.class, OPTICS.class);
if(config.grab(opticsP)) {
optics = opticsP.instantiateClass(config);
}
}
@Override
- protected OPTICSXi<D> makeInstance() {
- return new OPTICSXi<>(optics, xi);
+ protected OPTICSXi makeInstance() {
+ return new OPTICSXi(optics, xi);
}
}
-} \ No newline at end of file
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/package-info.java
new file mode 100644
index 00000000..64ecf8f9
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/optics/package-info.java
@@ -0,0 +1,33 @@
+/**
+ * OPTICS family of clustering algorithms.
+ *
+ * Note that some OPTICS based algorithms (HiCO, DiSH) are in the
+ * subspace and correlation packages, which better describes their use case.
+ *
+ * @apiviz.exclude ^java\.lang\.
+ * @apiviz.exclude ^de.lmu.ifi.dbs.elki.result.textwriter
+ * @apiviz.exclude ^de.lmu.ifi.dbs.elki.algorithm.Abstract
+ */
+/*
+ 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.algorithm.clustering.optics; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/package-info.java
index 26fb3024..a83d677c 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/package-info.java
@@ -19,7 +19,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/algorithm/clustering/subspace/CLIQUE.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/CLIQUE.java
index 617d74cd..f55ec964 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/CLIQUE.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/CLIQUE.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.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
@@ -35,9 +35,9 @@ import java.util.TreeMap;
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.clustering.subspace.clique.CLIQUESubspace;
import de.lmu.ifi.dbs.elki.algorithm.clustering.subspace.clique.CLIQUEUnit;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.subspace.clique.CLIQUEInterval;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.Interval;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.Subspace;
import de.lmu.ifi.dbs.elki.data.model.SubspaceModel;
@@ -95,7 +95,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
@Title("CLIQUE: Automatic Subspace Clustering of High Dimensional Data for Data Mining Applications")
@Description("Grid-based algorithm to identify dense clusters in subspaces of maximum dimensionality.")
@Reference(authors = "R. Agrawal, J. Gehrke, D. Gunopulos, P. Raghavan", title = "Automatic Subspace Clustering of High Dimensional Data for Data Mining Applications", booktitle = "Proc. SIGMOD Conference, Seattle, WA, 1998", url = "http://dx.doi.org/10.1145/276304.276314")
-public class CLIQUE<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<SubspaceModel<V>>> implements SubspaceClusteringAlgorithm<SubspaceModel<V>> {
+public class CLIQUE<V extends NumberVector> extends AbstractAlgorithm<Clustering<SubspaceModel>> implements SubspaceClusteringAlgorithm<SubspaceModel> {
/**
* The logger for this class.
*/
@@ -165,7 +165,7 @@ public class CLIQUE<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
* @param relation Data relation to process
* @return Clustering result
*/
- public Clustering<SubspaceModel<V>> run(Relation<V> relation) {
+ public Clustering<SubspaceModel> run(Relation<V> relation) {
// 1. Identification of subspaces that contain clusters
// TODO: use step logging.
if(LOG.isVerbose()) {
@@ -203,7 +203,7 @@ public class CLIQUE<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
}
// build result
int numClusters = 1;
- Clustering<SubspaceModel<V>> result = new Clustering<>("CLIQUE clustering", "clique-clustering");
+ Clustering<SubspaceModel> result = new Clustering<>("CLIQUE clustering", "clique-clustering");
for(Integer dim : dimensionToDenseSubspaces.keySet()) {
List<CLIQUESubspace<V>> subspaces = dimensionToDenseSubspaces.get(dim);
List<Pair<Subspace, ModifiableDBIDs>> modelsAndClusters = determineClusters(subspaces);
@@ -213,8 +213,8 @@ public class CLIQUE<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
}
for(Pair<Subspace, ModifiableDBIDs> modelAndCluster : modelsAndClusters) {
- Cluster<SubspaceModel<V>> newCluster = new Cluster<>(modelAndCluster.second);
- newCluster.setModel(new SubspaceModel<>(modelAndCluster.first, Centroid.make(relation, modelAndCluster.second).toVector(relation)));
+ Cluster<SubspaceModel> newCluster = new Cluster<>(modelAndCluster.second);
+ newCluster.setModel(new SubspaceModel(modelAndCluster.first, Centroid.make(relation, modelAndCluster.second)));
newCluster.setName("cluster_" + numClusters++);
result.addToplevelCluster(newCluster);
}
@@ -313,9 +313,9 @@ public class CLIQUE<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
if(LOG.isDebuggingFiner()) {
StringBuilder msg = new StringBuilder();
- msg.append(" minima: ").append(FormatUtil.format(minima, ", ", 2));
- msg.append("\n maxima: ").append(FormatUtil.format(maxima, ", ", 2));
- msg.append("\n unit lengths: ").append(FormatUtil.format(unit_lengths, ", ", 2));
+ msg.append(" minima: ").append(FormatUtil.format(minima, ", ", FormatUtil.NF2));
+ msg.append("\n maxima: ").append(FormatUtil.format(maxima, ", ", FormatUtil.NF2));
+ msg.append("\n unit lengths: ").append(FormatUtil.format(unit_lengths, ", ", FormatUtil.NF2));
LOG.debugFiner(msg.toString());
}
@@ -341,7 +341,7 @@ public class CLIQUE<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
List<CLIQUEUnit<V>> units = new ArrayList<>((xsi * dimensionality));
for(int x = 0; x < xsi; x++) {
for(int d = 0; d < dimensionality; d++) {
- units.add(new CLIQUEUnit<V>(new Interval(d, unit_bounds[x][d], unit_bounds[x + 1][d])));
+ units.add(new CLIQUEUnit<V>(new CLIQUEInterval(d, unit_bounds[x][d], unit_bounds[x + 1][d])));
}
}
@@ -582,7 +582,7 @@ public class CLIQUE<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
protected int xsi;
protected double tau;
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/DOC.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/DOC.java
index 5f798a66..fa8bbbe4 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/DOC.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/DOC.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.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,7 +23,6 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.BitSet;
import java.util.Random;
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
@@ -47,12 +46,12 @@ import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
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.distancefunction.subspace.SubspaceMaximumDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Centroid;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
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;
@@ -66,14 +65,14 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
/**
* <p>
- * Provides the DOC algorithm, and it's heuristic variant, FastDOC. DOC is a
- * sampling based subspace clustering algorithm.
+ * The DOC algorithm, and it's heuristic variant, FastDOC. DOC is a sampling
+ * based subspace clustering algorithm.
* </p>
*
* <p>
* Reference: <br/>
* C. M. Procopiuc, M. Jones, P. K. Agarwal, T. M. Murali<br />
- * A Monte Carlo algorithm for fast projective clustering. <br/>
+ * A Monte Carlo algorithm for fast projective clustering. <br />
* In: Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '02).
* </p>
*
@@ -84,8 +83,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
* @param <V> the type of NumberVector handled by this Algorithm.
*/
@Title("DOC: Density-based Optimal projective Clustering")
-@Reference(authors = "C. M. Procopiuc, M. Jones, P. K. Agarwal, T. M. Murali", title = "A Monte Carlo algorithm for fast projective clustering", booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '02)", url = "http://dx.doi.org/10.1145/564691.564739")
-public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<SubspaceModel<V>>> implements SubspaceClusteringAlgorithm<SubspaceModel<V>> {
+@Reference(authors = "C. M. Procopiuc, M. Jones, P. K. Agarwal, T. M. Murali", //
+title = "A Monte Carlo algorithm for fast projective clustering", //
+booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '02)", //
+url = "http://dx.doi.org/10.1145/564691.564739")
+public class DOC<V extends NumberVector> extends AbstractAlgorithm<Clustering<SubspaceModel>> implements SubspaceClusteringAlgorithm<SubspaceModel> {
/**
* The logger for this class.
*/
@@ -152,7 +154,7 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
* @param database Database
* @param relation Data relation
*/
- public Clustering<SubspaceModel<V>> run(Database database, Relation<V> relation) {
+ public Clustering<SubspaceModel> run(Database database, Relation<V> relation) {
// Dimensionality of our set.
final int d = RelationUtil.dimensionality(relation);
@@ -173,7 +175,7 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
int minClusterSize = (int) (alpha * S.size());
// List of all clusters we found.
- Clustering<SubspaceModel<V>> result = new Clustering<>("DOC Clusters", "DOC");
+ Clustering<SubspaceModel> result = new Clustering<>("DOC Clusters", "DOC");
// Inform the user about the number of actual clusters found so far.
IndefiniteProgress cprogress = LOG.isVerbose() ? new IndefiniteProgress("Number of clusters", LOG) : null;
@@ -181,7 +183,7 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
// To not only find a single cluster, we continue running until our set
// of points is empty.
while(S.size() > minClusterSize) {
- Cluster<SubspaceModel<V>> C;
+ Cluster<SubspaceModel> C;
if(heuristics) {
C = runFastDOC(relation, S, d, n, m, (int) r);
}
@@ -206,15 +208,10 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
// Add the remainder as noise.
if(S.size() > 0) {
- BitSet alldims = new BitSet();
- alldims.set(0, d);
- result.addToplevelCluster(new Cluster<>(S, true, new SubspaceModel<>(new Subspace(alldims), Centroid.make(relation, S).toVector(relation))));
+ long[] alldims = BitsUtil.ones(d);
+ result.addToplevelCluster(new Cluster<>(S, true, new SubspaceModel(new Subspace(alldims), Centroid.make(relation, S))));
}
-
- if(cprogress != null) {
- cprogress.setCompleted(LOG);
- }
-
+ LOG.setCompleted(cprogress);
return result;
}
@@ -230,12 +227,11 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
* @param minClusterSize Minimum size a cluster must have to be accepted.
* @return a cluster, if one is found, else <code>null</code>.
*/
- private Cluster<SubspaceModel<V>> runDOC(Relation<V> relation, ArrayModifiableDBIDs S, final int d, int n, int m, int r, int minClusterSize) {
- final DoubleDistance wd = new DoubleDistance(w);
+ private Cluster<SubspaceModel> runDOC(Relation<V> relation, ArrayModifiableDBIDs S, final int d, int n, int m, int r, int minClusterSize) {
// Best cluster for the current run.
DBIDs C = null;
// Relevant attributes for the best cluster.
- BitSet D = null;
+ long[] D = null;
// Quality of the best cluster.
double quality = Double.NEGATIVE_INFINITY;
@@ -244,9 +240,9 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
// double[d], new double[d]);
// Weights for distance (= rectangle query)
- SubspaceMaximumDistanceFunction df = new SubspaceMaximumDistanceFunction(new BitSet(d));
- DistanceQuery<V, DoubleDistance> dq = relation.getDatabase().getDistanceQuery(relation, df);
- RangeQuery<V, DoubleDistance> rq = relation.getDatabase().getRangeQuery(dq);
+ SubspaceMaximumDistanceFunction df = new SubspaceMaximumDistanceFunction(BitsUtil.zero(d));
+ DistanceQuery<V> dq = relation.getDatabase().getDistanceQuery(relation, df);
+ RangeQuery<V> rq = relation.getDatabase().getRangeQuery(dq);
// Inform the user about the progress in the current iteration.
FiniteProgress iprogress = LOG.isVerbose() ? new FiniteProgress("Iteration progress for current cluster", m * n, LOG) : null;
@@ -263,22 +259,22 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
DBIDs randomSet = DBIDUtil.randomSample(S, Math.min(S.size(), r), random);
// Initialize cluster info.
- BitSet nD = new BitSet(d);
+ long[] nD = BitsUtil.zero(d);
// Test each dimension and build bounding box.
for(int k = 0; k < d; ++k) {
if(dimensionIsRelevant(k, relation, randomSet)) {
- nD.set(k);
+ BitsUtil.setI(nD, k);
}
}
- if(nD.cardinality() > 0) {
+ if(BitsUtil.cardinality(nD) > 0) {
// Get all points in the box.
df.setSelectedDimensions(nD);
// TODO: add filtering capabilities into query API!
- DBIDs nC = DBIDUtil.intersection(S, rq.getRangeForDBID(iter, wd));
+ DBIDs nC = DBIDUtil.intersection(S, rq.getRangeForDBID(iter, w));
if(LOG.isDebuggingFiner()) {
- LOG.finer("Testing a cluster candidate, |C| = " + nC.size() + ", |D| = " + nD.cardinality());
+ LOG.finer("Testing a cluster candidate, |C| = " + nC.size() + ", |D| = " + BitsUtil.cardinality(nD));
}
// Is the cluster large enough?
@@ -290,7 +286,7 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
}
else {
// Better cluster than before?
- double nQuality = computeClusterQuality(nC.size(), nD.cardinality());
+ double nQuality = computeClusterQuality(nC.size(), BitsUtil.cardinality(nD));
if(nQuality > quality) {
if(LOG.isDebuggingFiner()) {
LOG.finer("... and it's the best so far: " + nQuality + " vs. " + quality);
@@ -306,23 +302,12 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
}
}
}
-
- if(iprogress != null) {
- iprogress.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(iprogress);
}
}
+ LOG.ensureCompleted(iprogress);
- if(iprogress != null) {
- iprogress.ensureCompleted(LOG);
- }
-
- if(C != null) {
- return makeCluster(relation, C, D);
- }
- else {
- return null;
- }
+ return (C != null) ? makeCluster(relation, C, D) : null;
}
/**
@@ -336,9 +321,9 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
* @param n Number of outer iterations (seed points).
* @return a cluster, if one is found, else <code>null</code>.
*/
- private Cluster<SubspaceModel<V>> runFastDOC(Relation<V> relation, ArrayModifiableDBIDs S, int d, int n, int m, int r) {
+ private Cluster<SubspaceModel> runFastDOC(Relation<V> relation, ArrayModifiableDBIDs S, int d, int n, int m, int r) {
// Relevant attributes of highest cardinality.
- BitSet D = null;
+ long[] D = null;
// The seed point for the best dimensions.
DBIDVar dV = DBIDUtil.newVar();
@@ -357,57 +342,46 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
DBIDs randomSet = DBIDUtil.randomSample(S, Math.min(S.size(), r), random);
// Initialize cluster info.
- BitSet nD = new BitSet(d);
+ long[] nD = BitsUtil.zero(d);
// Test each dimension.
for(int k = 0; k < d; ++k) {
if(dimensionIsRelevant(k, relation, randomSet)) {
- nD.set(k);
+ BitsUtil.setI(nD, k);
}
}
- if(D == null || nD.cardinality() > D.cardinality()) {
+ if(D == null || BitsUtil.cardinality(nD) > BitsUtil.cardinality(D)) {
D = nD;
dV.set(iter);
- if(D.cardinality() >= d_zero) {
+ if(BitsUtil.cardinality(D) >= d_zero) {
if(iprogress != null) {
iprogress.setProcessed(iprogress.getTotal(), LOG);
}
break outer;
}
}
-
- if(iprogress != null) {
- iprogress.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(iprogress);
}
}
-
- if(iprogress != null) {
- iprogress.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(iprogress);
// If no relevant dimensions were found, skip it.
- if(D == null || D.cardinality() == 0) {
+ if(D == null || BitsUtil.cardinality(D) == 0) {
return null;
}
// Get all points in the box.
SubspaceMaximumDistanceFunction df = new SubspaceMaximumDistanceFunction(D);
- DistanceQuery<V, DoubleDistance> dq = relation.getDatabase().getDistanceQuery(relation, df);
- RangeQuery<V, DoubleDistance> rq = relation.getDatabase().getRangeQuery(dq, DatabaseQuery.HINT_SINGLE);
+ DistanceQuery<V> dq = relation.getDatabase().getDistanceQuery(relation, df);
+ RangeQuery<V> rq = relation.getDatabase().getRangeQuery(dq, DatabaseQuery.HINT_SINGLE);
// TODO: add filtering capabilities into query API!
- DBIDs C = DBIDUtil.intersection(S, rq.getRangeForDBID(dV, new DoubleDistance(w)));
+ DBIDs C = DBIDUtil.intersection(S, rq.getRangeForDBID(dV, w));
// If we have a non-empty cluster, return it.
- if(C.size() > 0) {
- return makeCluster(relation, C, D);
- }
- else {
- return null;
- }
+ return (C.size() > 0) ? makeCluster(relation, C, D) : null;
}
/**
@@ -421,12 +395,11 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
* @return <code>true</code> if the dimension is relevant.
*/
private boolean dimensionIsRelevant(int dimension, Relation<V> relation, DBIDs points) {
- double min = Double.POSITIVE_INFINITY;
- double max = Double.NEGATIVE_INFINITY;
+ double min = Double.POSITIVE_INFINITY, max = Double.NEGATIVE_INFINITY;
for(DBIDIter iter = points.iter(); iter.valid(); iter.advance()) {
- V xV = relation.get(iter);
- min = Math.min(min, xV.doubleValue(dimension));
- max = Math.max(max, xV.doubleValue(dimension));
+ double xV = relation.get(iter).doubleValue(dimension);
+ min = (xV < min) ? xV : min;
+ max = (xV > max) ? xV : max;
if(max - min > w) {
return false;
}
@@ -443,10 +416,10 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
* @param D the relevant dimensions.
* @return an object representing the subspace cluster.
*/
- private Cluster<SubspaceModel<V>> makeCluster(Relation<V> relation, DBIDs C, BitSet D) {
+ private Cluster<SubspaceModel> makeCluster(Relation<V> relation, DBIDs C, long[] D) {
DBIDs ids = DBIDUtil.newHashSet(C); // copy, also to lose distance values!
- Cluster<SubspaceModel<V>> cluster = new Cluster<>(ids);
- cluster.setModel(new SubspaceModel<>(new Subspace(D), Centroid.make(relation, ids).toVector(relation)));
+ Cluster<SubspaceModel> cluster = new Cluster<>(ids);
+ cluster.setModel(new SubspaceModel(new Subspace(D), Centroid.make(relation, ids)));
return cluster;
}
@@ -483,7 +456,7 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* Relative density threshold parameter Alpha.
*/
@@ -549,26 +522,26 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
super.makeOptions(config);
{
- DoubleParameter param = new DoubleParameter(ALPHA_ID, 0.2);
- param.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
- param.addConstraint(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
+ DoubleParameter param = new DoubleParameter(ALPHA_ID, 0.2) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE) //
+ .addConstraint(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
if(config.grab(param)) {
alpha = param.getValue();
}
}
{
- DoubleParameter param = new DoubleParameter(BETA_ID, 0.8);
- param.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
- param.addConstraint(CommonConstraints.LESS_THAN_ONE_DOUBLE);
+ DoubleParameter param = new DoubleParameter(BETA_ID, 0.8) //
+ .addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE) //
+ .addConstraint(CommonConstraints.LESS_THAN_ONE_DOUBLE);
if(config.grab(param)) {
beta = param.getValue();
}
}
{
- DoubleParameter param = new DoubleParameter(W_ID, 0.05);
- param.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ DoubleParameter param = new DoubleParameter(W_ID, 0.05) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
if(config.grab(param)) {
w = param.getValue();
}
@@ -582,8 +555,8 @@ public class DOC<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
}
if(heuristics) {
- IntParameter param = new IntParameter(D_ZERO_ID, 5);
- param.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ IntParameter param = new IntParameter(D_ZERO_ID, 5) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
if(config.grab(param)) {
d_zero = param.getValue();
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/DiSH.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/DiSH.java
index cd5e51b8..20849dd6 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/DiSH.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/DiSH.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.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,8 +23,10 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import gnu.trove.map.hash.TCustomHashMap;
+import gnu.trove.procedure.TObjectObjectProcedure;
+
import java.util.ArrayList;
-import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -34,7 +36,9 @@ import java.util.List;
import java.util.Map;
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICS;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderResult;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.CorrelationClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.GeneralizedOPTICS;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
@@ -42,26 +46,20 @@ import de.lmu.ifi.dbs.elki.data.Subspace;
import de.lmu.ifi.dbs.elki.data.model.SubspaceModel;
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.Database;
import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
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.DBIDUtil;
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.distancefunction.IndexBasedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.ProxyDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DiSHDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.AbstractDistance;
-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.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Centroid;
import de.lmu.ifi.dbs.elki.math.linearalgebra.ProjectedCentroid;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy;
import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy.Iter;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
@@ -73,7 +71,6 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraint
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.parameterization.TrackParameters;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
@@ -93,7 +90,6 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
* @author Elke Achtert
*
* @apiviz.uses DiSHPreferenceVectorIndex
- * @apiviz.uses DiSHDistanceFunction
* @apiviz.has SubspaceModel
*
* @param <V> the type of NumberVector handled by this Algorithm
@@ -101,94 +97,61 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
@Title("DiSH: Detecting Subspace cluster Hierarchies")
@Description("Algorithm to find hierarchical correlation clusters in subspaces.")
@Reference(authors = "E. Achtert, C. Böhm, H.-P. Kriegel, P. Kröger, I. Müller-Gorman, A. Zimek", title = "Detection and Visualization of Subspace Cluster Hierarchies", booktitle = "Proc. 12th International Conference on Database Systems for Advanced Applications (DASFAA), Bangkok, Thailand, 2007", url = "http://dx.doi.org/10.1007/978-3-540-71703-4_15")
-public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<SubspaceModel<V>>> implements SubspaceClusteringAlgorithm<SubspaceModel<V>> {
+public class DiSH<V extends NumberVector> extends AbstractAlgorithm<Clustering<SubspaceModel>> implements SubspaceClusteringAlgorithm<SubspaceModel> {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(DiSH.class);
/**
- * Parameter that specifies the maximum radius of the neighborhood to be
- * considered in each dimension for determination of the preference vector,
- * must be a double equal to or greater than 0.
- * <p>
- * Default value: {@code 0.001}
- * </p>
- * <p>
- * Key: {@code -dish.epsilon}
- * </p>
- */
- public static final OptionID EPSILON_ID = new OptionID("dish.epsilon", "The maximum radius of the neighborhood " + "to be considered in each dimension for determination of " + "the preference vector.");
-
- /**
- * Parameter that specifies the a minimum number of points as a smoothing
- * factor to avoid the single-link-effect, must be an integer greater than 0.
- * <p>
- * Default value: {@code 1}
- * </p>
- * <p>
- * Key: {@code -dish.mu}
- * </p>
- */
- public static final OptionID MU_ID = new OptionID("dish.mu", "The minimum number of points as a smoothing factor to avoid the single-link-effekt.");
-
- /**
- * Holds the value of {@link #EPSILON_ID}.
+ * Holds the value of {@link Parameterizer#EPSILON_ID}.
*/
private double epsilon;
/**
- * The distance function we use
+ * The DiSH preprocessor.
*/
- private DiSHDistanceFunction dishDistance;
+ private DiSHPreferenceVectorIndex.Factory<V> dishPreprocessor;
/**
- * Parameters that were given to OPTICS
+ * OPTICS minPts parameter.
*/
- private Collection<Pair<OptionID, Object>> opticsAlgorithmParameters;
+ private int mu;
/**
* Constructor.
*
* @param epsilon Epsilon value
- * @param dishDistance Distance function
- * @param opticsAlgorithmParameters OPTICS parameters
+ * @param mu Mu parameter (minPts)
+ * @param dishPreprocessor DiSH preprocessor
*/
- public DiSH(double epsilon, DiSHDistanceFunction dishDistance, Collection<Pair<OptionID, Object>> opticsAlgorithmParameters) {
+ public DiSH(double epsilon, int mu, DiSHPreferenceVectorIndex.Factory<V> dishPreprocessor) {
super();
this.epsilon = epsilon;
- this.dishDistance = dishDistance;
- this.opticsAlgorithmParameters = opticsAlgorithmParameters;
+ this.mu = mu;
+ this.dishPreprocessor = dishPreprocessor;
}
/**
* Performs the DiSH algorithm on the given database.
*
- * @param database Database to process
* @param relation Relation to process
*/
- public Clustering<SubspaceModel<V>> run(Database database, Relation<V> relation) {
- // Instantiate DiSH distance (and thus run the preprocessor)
+ public Clustering<SubspaceModel> run(Relation<V> relation) {
if(LOG.isVerbose()) {
- LOG.verbose("*** Run DiSH preprocessor.");
+ LOG.verbose("Running the DiSH preprocessor.");
}
- DiSHDistanceFunction.Instance<V> dishDistanceQuery = dishDistance.instantiate(relation);
- // Configure and run OPTICS.
+ DiSHPreferenceVectorIndex<V> indexinst = dishPreprocessor.instantiate(relation);
if(LOG.isVerbose()) {
- LOG.verbose("*** Run OPTICS algorithm.");
+ LOG.verbose("Running the OPTICS algorithm.");
}
- ListParameterization opticsconfig = new ListParameterization(opticsAlgorithmParameters);
- opticsconfig.addParameter(OPTICS.DISTANCE_FUNCTION_ID, ProxyDistanceFunction.proxy(dishDistanceQuery));
- Class<OPTICS<V, PreferenceVectorBasedCorrelationDistance>> cls = ClassGenericsUtil.uglyCastIntoSubclass(OPTICS.class);
- OPTICS<V, PreferenceVectorBasedCorrelationDistance> optics = null;
- optics = opticsconfig.tryInstantiate(cls);
- ClusterOrderResult<PreferenceVectorBasedCorrelationDistance> opticsResult = optics.run(database, relation);
+ ClusterOrderResult<DiSHClusterOrderEntry> opticsResult = new DiSHOPTICS(indexinst).run(relation);
if(LOG.isVerbose()) {
- LOG.verbose("*** Compute Clusters.");
+ LOG.verbose("Compute Clusters.");
}
- return computeClusters(relation, opticsResult, dishDistanceQuery);
+ return computeClusters(relation, opticsResult);
}
/**
@@ -196,58 +159,68 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
*
* @param database the database holding the objects
* @param clusterOrder the cluster order
- * @param distFunc Distance function
*/
- private Clustering<SubspaceModel<V>> computeClusters(Relation<V> database, ClusterOrderResult<PreferenceVectorBasedCorrelationDistance> clusterOrder, DiSHDistanceFunction.Instance<V> distFunc) {
- int dimensionality = RelationUtil.dimensionality(database);
- int minpts = dishDistance.getMinpts();
+ private Clustering<SubspaceModel> computeClusters(Relation<V> database, ClusterOrderResult<DiSHClusterOrderEntry> clusterOrder) {
+ final int dimensionality = RelationUtil.dimensionality(database);
// extract clusters
- Map<BitSet, List<Pair<BitSet, ArrayModifiableDBIDs>>> clustersMap = extractClusters(database, distFunc, clusterOrder);
+ TCustomHashMap<long[], List<ArrayModifiableDBIDs>> clustersMap = extractClusters(database, clusterOrder);
if(LOG.isVerbose()) {
- StringBuilder msg = new StringBuilder("Step 1: extract clusters");
- for(List<Pair<BitSet, ArrayModifiableDBIDs>> clusterList : clustersMap.values()) {
- for(Pair<BitSet, ArrayModifiableDBIDs> c : clusterList) {
- msg.append('\n').append(FormatUtil.format(dimensionality, c.first)).append(" ids ").append(c.second.size());
+ final StringBuilder msg = new StringBuilder("Step 1: extract clusters\n");
+ clustersMap.forEachEntry(new TObjectObjectProcedure<long[], List<ArrayModifiableDBIDs>>() {
+ @Override
+ public boolean execute(long[] key, List<ArrayModifiableDBIDs> clusters) {
+ msg.append(BitsUtil.toStringLow(key, dimensionality)).append(" sizes:");
+ for(ArrayModifiableDBIDs c : clusters) {
+ msg.append(' ').append(c.size());
+ }
+ msg.append('\n');
+ return true; // continue
}
- }
+ });
LOG.verbose(msg.toString());
}
// check if there are clusters < minpts
- checkClusters(database, distFunc, clustersMap, minpts);
+ checkClusters(database, clustersMap);
if(LOG.isVerbose()) {
- StringBuilder msg = new StringBuilder("Step 2: check clusters");
- for(List<Pair<BitSet, ArrayModifiableDBIDs>> clusterList : clustersMap.values()) {
- for(Pair<BitSet, ArrayModifiableDBIDs> c : clusterList) {
- msg.append('\n').append(FormatUtil.format(dimensionality, c.first)).append(" ids ").append(c.second.size());
+ final StringBuilder msg = new StringBuilder("Step 2: check clusters\n");
+ clustersMap.forEachEntry(new TObjectObjectProcedure<long[], List<ArrayModifiableDBIDs>>() {
+ @Override
+ public boolean execute(long[] key, List<ArrayModifiableDBIDs> clusters) {
+ msg.append(BitsUtil.toStringLow(key, dimensionality)).append(" sizes:");
+ for(ArrayModifiableDBIDs c : clusters) {
+ msg.append(' ').append(c.size());
+ }
+ msg.append('\n');
+ return true; // continue
}
- }
+ });
LOG.verbose(msg.toString());
}
// sort the clusters
- List<Cluster<SubspaceModel<V>>> clusters = sortClusters(database, clustersMap);
+ List<Cluster<SubspaceModel>> clusters = sortClusters(database, clustersMap);
if(LOG.isVerbose()) {
StringBuilder msg = new StringBuilder("Step 3: sort clusters");
- for(Cluster<SubspaceModel<V>> c : clusters) {
- msg.append('\n').append(FormatUtil.format(dimensionality, c.getModel().getSubspace().getDimensions())).append(" ids ").append(c.size());
+ for(Cluster<SubspaceModel> c : clusters) {
+ msg.append('\n').append(BitsUtil.toStringLow(c.getModel().getSubspace().getDimensions(), dimensionality)).append(" ids ").append(c.size());
}
LOG.verbose(msg.toString());
}
// build the hierarchy
- Clustering<SubspaceModel<V>> clustering = new Clustering<>("DiSH clustering", "dish-clustering");
- buildHierarchy(database, distFunc, clustering, clusters, dimensionality);
+ Clustering<SubspaceModel> clustering = new Clustering<>("DiSH clustering", "dish-clustering");
+ buildHierarchy(database, clustering, clusters, dimensionality);
if(LOG.isVerbose()) {
StringBuilder msg = new StringBuilder("Step 4: build hierarchy");
- for(Cluster<SubspaceModel<V>> c : clusters) {
- msg.append('\n').append(FormatUtil.format(dimensionality, c.getModel().getDimensions())).append(" ids ").append(c.size());
- for(Iter<Cluster<SubspaceModel<V>>> iter = clustering.getClusterHierarchy().iterParents(c); iter.valid(); iter.advance()) {
+ for(Cluster<SubspaceModel> c : clusters) {
+ msg.append('\n').append(BitsUtil.toStringLow(c.getModel().getSubspace().getDimensions(), dimensionality)).append(" ids ").append(c.size());
+ for(Iter<Cluster<SubspaceModel>> iter = clustering.getClusterHierarchy().iterParents(c); iter.valid(); iter.advance()) {
msg.append("\n parent ").append(iter.get());
}
- for(Iter<Cluster<SubspaceModel<V>>> iter = clustering.getClusterHierarchy().iterChildren(c); iter.valid(); iter.advance()) {
+ for(Iter<Cluster<SubspaceModel>> iter = clustering.getClusterHierarchy().iterChildren(c); iter.valid(); iter.advance()) {
msg.append("\n child ").append(iter.get());
}
}
@@ -255,7 +228,7 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
}
// build result
- for(Cluster<SubspaceModel<V>> c : clusters) {
+ for(Cluster<SubspaceModel> c : clusters) {
if(clustering.getClusterHierarchy().numParents(c) == 0) {
clustering.addToplevelCluster(c);
}
@@ -267,37 +240,38 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
* Extracts the clusters from the cluster order.
*
* @param database the database storing the objects
- * @param distFunc the distance function
* @param clusterOrder the cluster order to extract the clusters from
* @return the extracted clusters
*/
- private Map<BitSet, List<Pair<BitSet, ArrayModifiableDBIDs>>> extractClusters(Relation<V> database, DiSHDistanceFunction.Instance<V> distFunc, ClusterOrderResult<PreferenceVectorBasedCorrelationDistance> clusterOrder) {
+ private TCustomHashMap<long[], List<ArrayModifiableDBIDs>> extractClusters(Relation<V> database, ClusterOrderResult<DiSHClusterOrderEntry> clusterOrder) {
FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("Extract Clusters", database.size(), LOG) : null;
int processed = 0;
- Map<BitSet, List<Pair<BitSet, ArrayModifiableDBIDs>>> clustersMap = new HashMap<>();
- Map<DBID, ClusterOrderEntry<PreferenceVectorBasedCorrelationDistance>> entryMap = new HashMap<>();
- Map<DBID, Pair<BitSet, ArrayModifiableDBIDs>> entryToClusterMap = new HashMap<>();
- for(Iterator<ClusterOrderEntry<PreferenceVectorBasedCorrelationDistance>> it = clusterOrder.iterator(); it.hasNext();) {
- ClusterOrderEntry<PreferenceVectorBasedCorrelationDistance> entry = it.next();
+ TCustomHashMap<long[], List<ArrayModifiableDBIDs>> clustersMap = new TCustomHashMap<>(BitsUtil.TROVE_HASH_STRATEGY);
+ // Note clusterOrder currently contains DBID objects anyway.
+ Map<DBID, DiSHClusterOrderEntry> entryMap = new HashMap<>();
+ Map<DBID, Pair<long[], ArrayModifiableDBIDs>> entryToClusterMap = new HashMap<>();
+ for(Iterator<DiSHClusterOrderEntry> it = clusterOrder.iterator(); it.hasNext();) {
+ DiSHClusterOrderEntry entry = it.next();
entryMap.put(entry.getID(), entry);
V object = database.get(entry.getID());
- BitSet preferenceVector = entry.getReachability().getCommonPreferenceVector();
+ long[] preferenceVector = entry.getCommonPreferenceVector();
// get the list of (parallel) clusters for the preference vector
- List<Pair<BitSet, ArrayModifiableDBIDs>> parallelClusters = clustersMap.get(preferenceVector);
+ List<ArrayModifiableDBIDs> parallelClusters = clustersMap.get(preferenceVector);
if(parallelClusters == null) {
parallelClusters = new ArrayList<>();
clustersMap.put(preferenceVector, parallelClusters);
}
// look for the proper cluster
- Pair<BitSet, ArrayModifiableDBIDs> cluster = null;
- for(Pair<BitSet, ArrayModifiableDBIDs> c : parallelClusters) {
- V c_centroid = ProjectedCentroid.make(c.first, database, c.second).toVector(database);
- PreferenceVectorBasedCorrelationDistance dist = distFunc.correlationDistance(object, c_centroid, preferenceVector, preferenceVector);
- if(dist.getCorrelationValue() == entry.getReachability().getCorrelationValue()) {
- double d = distFunc.weightedDistance(object, c_centroid, dist.getCommonPreferenceVector());
+ ArrayModifiableDBIDs cluster = null;
+ for(ArrayModifiableDBIDs c : parallelClusters) {
+ Vector c_centroid = ProjectedCentroid.make(preferenceVector, database, c);
+ long[] commonPreferenceVector = BitsUtil.andCMin(preferenceVector, preferenceVector);
+ int subspaceDim = subspaceDimensionality(object, c_centroid, preferenceVector, preferenceVector, commonPreferenceVector);
+ if(subspaceDim == entry.getCorrelationValue()) {
+ double d = weightedDistance(object, c_centroid, commonPreferenceVector);
if(d <= 2 * epsilon) {
cluster = c;
break;
@@ -305,57 +279,56 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
}
}
if(cluster == null) {
- cluster = new Pair<>(preferenceVector, DBIDUtil.newArray());
+ cluster = DBIDUtil.newArray();
parallelClusters.add(cluster);
}
- cluster.second.add(entry.getID());
- entryToClusterMap.put(entry.getID(), cluster);
+ cluster.add(entry.getID());
+ entryToClusterMap.put(entry.getID(), new Pair<>(preferenceVector, cluster));
if(progress != null) {
progress.setProcessed(++processed, LOG);
}
}
- if(progress != null) {
- progress.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(progress);
if(LOG.isDebuggingFiner()) {
+ int dim = RelationUtil.dimensionality(database);
StringBuilder msg = new StringBuilder("Step 0");
- for(List<Pair<BitSet, ArrayModifiableDBIDs>> clusterList : clustersMap.values()) {
- for(Pair<BitSet, ArrayModifiableDBIDs> c : clusterList) {
- msg.append('\n').append(FormatUtil.format(RelationUtil.dimensionality(database), c.first)).append(" ids ").append(c.second.size());
+ for(Map.Entry<long[], List<ArrayModifiableDBIDs>> clusterList : clustersMap.entrySet()) {
+ for(ArrayModifiableDBIDs c : clusterList.getValue()) {
+ msg.append('\n').append(BitsUtil.toStringLow(clusterList.getKey(), dim)).append(" ids ").append(c.size());
}
}
LOG.debugFiner(msg.toString());
}
// add the predecessor to the cluster
- for(BitSet pv : clustersMap.keySet()) {
- List<Pair<BitSet, ArrayModifiableDBIDs>> parallelClusters = clustersMap.get(pv);
- for(Pair<BitSet, ArrayModifiableDBIDs> cluster : parallelClusters) {
- if(cluster.second.isEmpty()) {
+ for(long[] pv : clustersMap.keySet()) {
+ List<ArrayModifiableDBIDs> parallelClusters = clustersMap.get(pv);
+ for(ArrayModifiableDBIDs cluster : parallelClusters) {
+ if(cluster.isEmpty()) {
continue;
}
- DBID firstID = cluster.second.get(0);
- ClusterOrderEntry<PreferenceVectorBasedCorrelationDistance> entry = entryMap.get(firstID);
+ DBID firstID = cluster.get(0);
+ DiSHClusterOrderEntry entry = entryMap.get(firstID);
DBID predecessorID = entry.getPredecessorID();
if(predecessorID == null) {
continue;
}
- ClusterOrderEntry<PreferenceVectorBasedCorrelationDistance> predecessor = entryMap.get(predecessorID);
+ DiSHClusterOrderEntry predecessor = entryMap.get(predecessorID);
// parallel cluster
- if(predecessor.getReachability().getCommonPreferenceVector().equals(entry.getReachability().getCommonPreferenceVector())) {
+ if(BitsUtil.equal(predecessor.getCommonPreferenceVector(), entry.getCommonPreferenceVector())) {
continue;
}
- if(predecessor.getReachability().compareTo(entry.getReachability()) < 0) {
+ if(predecessor.compareTo(entry) < 0) {
continue;
}
- Pair<BitSet, ArrayModifiableDBIDs> oldCluster = entryToClusterMap.get(predecessorID);
+ Pair<long[], ArrayModifiableDBIDs> oldCluster = entryToClusterMap.get(predecessorID);
oldCluster.second.remove(predecessorID);
- cluster.second.add(predecessorID);
+ cluster.add(predecessorID);
entryToClusterMap.remove(predecessorID);
- entryToClusterMap.put(predecessorID, cluster);
+ entryToClusterMap.put(predecessorID, new Pair<>(pv, cluster));
}
}
@@ -366,21 +339,21 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
* Returns a sorted list of the clusters w.r.t. the subspace dimensionality in
* descending order.
*
- * @param database the database storing the objects
+ * @param relation the database storing the objects
* @param clustersMap the mapping of bits sets to clusters
* @return a sorted list of the clusters
*/
- private List<Cluster<SubspaceModel<V>>> sortClusters(Relation<V> database, Map<BitSet, List<Pair<BitSet, ArrayModifiableDBIDs>>> clustersMap) {
- final int db_dim = RelationUtil.dimensionality(database);
+ private List<Cluster<SubspaceModel>> sortClusters(Relation<V> relation, TCustomHashMap<long[], List<ArrayModifiableDBIDs>> clustersMap) {
+ final int db_dim = RelationUtil.dimensionality(relation);
// int num = 1;
- List<Cluster<SubspaceModel<V>>> clusters = new ArrayList<>();
- for(BitSet pv : clustersMap.keySet()) {
- List<Pair<BitSet, ArrayModifiableDBIDs>> parallelClusters = clustersMap.get(pv);
+ List<Cluster<SubspaceModel>> clusters = new ArrayList<>();
+ for(long[] pv : clustersMap.keySet()) {
+ List<ArrayModifiableDBIDs> parallelClusters = clustersMap.get(pv);
for(int i = 0; i < parallelClusters.size(); i++) {
- Pair<BitSet, ArrayModifiableDBIDs> c = parallelClusters.get(i);
- Cluster<SubspaceModel<V>> cluster = new Cluster<>(c.second);
- cluster.setModel(new SubspaceModel<>(new Subspace(c.first), Centroid.make(database, c.second).toVector(database)));
- String subspace = FormatUtil.format(cluster.getModel().getSubspace().getDimensions(), db_dim, "");
+ ArrayModifiableDBIDs c = parallelClusters.get(i);
+ Cluster<SubspaceModel> cluster = new Cluster<>(c);
+ cluster.setModel(new SubspaceModel(new Subspace(pv), Centroid.make(relation, c)));
+ String subspace = BitsUtil.toStringLow(cluster.getModel().getSubspace().getDimensions(), db_dim);
if(parallelClusters.size() > 1) {
cluster.setName("Cluster_" + subspace + "_" + i);
}
@@ -391,12 +364,11 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
}
}
// sort the clusters w.r.t. lambda
- Comparator<Cluster<SubspaceModel<V>>> comparator = new Comparator<Cluster<SubspaceModel<V>>>() {
+ Comparator<Cluster<SubspaceModel>> comparator = new Comparator<Cluster<SubspaceModel>>() {
@Override
- public int compare(Cluster<SubspaceModel<V>> c1, Cluster<SubspaceModel<V>> c2) {
+ public int compare(Cluster<SubspaceModel> c1, Cluster<SubspaceModel> c2) {
return c2.getModel().getSubspace().dimensionality() - c1.getModel().getSubspace().dimensionality();
}
-
};
Collections.sort(clusters, comparator);
return clusters;
@@ -406,32 +378,31 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
* Removes the clusters with size < minpts from the cluster map and adds them
* to their parents.
*
- * @param database the database storing the objects
- * @param distFunc the distance function
+ * @param relation the relation storing the objects
* @param clustersMap the map containing the clusters
- * @param minpts MinPts
*/
- private void checkClusters(Relation<V> database, DiSHDistanceFunction.Instance<V> distFunc, Map<BitSet, List<Pair<BitSet, ArrayModifiableDBIDs>>> clustersMap, int minpts) {
+ private void checkClusters(Relation<V> relation, TCustomHashMap<long[], List<ArrayModifiableDBIDs>> clustersMap) {
+ final int dimensionality = RelationUtil.dimensionality(relation);
// check if there are clusters < minpts
// and add them to not assigned
- List<Pair<BitSet, ArrayModifiableDBIDs>> notAssigned = new ArrayList<>();
- Map<BitSet, List<Pair<BitSet, ArrayModifiableDBIDs>>> newClustersMap = new HashMap<>();
- Pair<BitSet, ArrayModifiableDBIDs> noise = new Pair<>(new BitSet(), DBIDUtil.newArray());
- for(BitSet pv : clustersMap.keySet()) {
+ List<Pair<long[], ArrayModifiableDBIDs>> notAssigned = new ArrayList<>();
+ TCustomHashMap<long[], List<ArrayModifiableDBIDs>> newClustersMap = new TCustomHashMap<>(BitsUtil.TROVE_HASH_STRATEGY);
+ Pair<long[], ArrayModifiableDBIDs> noise = new Pair<>(BitsUtil.zero(dimensionality), DBIDUtil.newArray());
+ for(long[] pv : clustersMap.keySet()) {
// noise
- if(pv.cardinality() == 0) {
- List<Pair<BitSet, ArrayModifiableDBIDs>> parallelClusters = clustersMap.get(pv);
- for(Pair<BitSet, ArrayModifiableDBIDs> c : parallelClusters) {
- noise.second.addDBIDs(c.second);
+ if(BitsUtil.cardinality(pv) == 0) {
+ List<ArrayModifiableDBIDs> parallelClusters = clustersMap.get(pv);
+ for(ArrayModifiableDBIDs c : parallelClusters) {
+ noise.second.addDBIDs(c);
}
}
// clusters
else {
- List<Pair<BitSet, ArrayModifiableDBIDs>> parallelClusters = clustersMap.get(pv);
- List<Pair<BitSet, ArrayModifiableDBIDs>> newParallelClusters = new ArrayList<>(parallelClusters.size());
- for(Pair<BitSet, ArrayModifiableDBIDs> c : parallelClusters) {
- if(!pv.equals(new BitSet()) && c.second.size() < minpts) {
- notAssigned.add(c);
+ List<ArrayModifiableDBIDs> parallelClusters = clustersMap.get(pv);
+ List<ArrayModifiableDBIDs> newParallelClusters = new ArrayList<>(parallelClusters.size());
+ for(ArrayModifiableDBIDs c : parallelClusters) {
+ if(!BitsUtil.isZero(pv) && c.size() < mu) {
+ notAssigned.add(new Pair<>(pv, c));
}
else {
newParallelClusters.add(c);
@@ -444,11 +415,11 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
clustersMap.clear();
clustersMap.putAll(newClustersMap);
- for(Pair<BitSet, ArrayModifiableDBIDs> c : notAssigned) {
+ for(Pair<long[], ArrayModifiableDBIDs> c : notAssigned) {
if(c.second.isEmpty()) {
continue;
}
- Pair<BitSet, ArrayModifiableDBIDs> parent = findParent(database, distFunc, c, clustersMap);
+ Pair<long[], ArrayModifiableDBIDs> parent = findParent(relation, c, clustersMap);
if(parent != null) {
parent.second.addDBIDs(c.second);
}
@@ -457,30 +428,29 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
}
}
- List<Pair<BitSet, ArrayModifiableDBIDs>> noiseList = new ArrayList<>(1);
- noiseList.add(noise);
+ List<ArrayModifiableDBIDs> noiseList = new ArrayList<>(1);
+ noiseList.add(noise.second);
clustersMap.put(noise.first, noiseList);
}
/**
* Returns the parent of the specified cluster
*
- * @param database the database storing the objects
- * @param distFunc the distance function
+ * @param relation the relation storing the objects
* @param child the child to search the parent for
* @param clustersMap the map containing the clusters
* @return the parent of the specified cluster
*/
- private Pair<BitSet, ArrayModifiableDBIDs> findParent(Relation<V> database, DiSHDistanceFunction.Instance<V> distFunc, Pair<BitSet, ArrayModifiableDBIDs> child, Map<BitSet, List<Pair<BitSet, ArrayModifiableDBIDs>>> clustersMap) {
- V child_centroid = ProjectedCentroid.make(child.first, database, child.second).toVector(database);
+ private Pair<long[], ArrayModifiableDBIDs> findParent(Relation<V> relation, Pair<long[], ArrayModifiableDBIDs> child, TCustomHashMap<long[], List<ArrayModifiableDBIDs>> clustersMap) {
+ Vector child_centroid = ProjectedCentroid.make(child.first, relation, child.second);
- Pair<BitSet, ArrayModifiableDBIDs> result = null;
+ Pair<long[], ArrayModifiableDBIDs> result = null;
int resultCardinality = -1;
- BitSet childPV = child.first;
- int childCardinality = childPV.cardinality();
- for(BitSet parentPV : clustersMap.keySet()) {
- int parentCardinality = parentPV.cardinality();
+ long[] childPV = child.first;
+ int childCardinality = BitsUtil.cardinality(childPV);
+ for(long[] parentPV : clustersMap.keySet()) {
+ int parentCardinality = BitsUtil.cardinality(parentPV);
if(parentCardinality >= childCardinality) {
continue;
}
@@ -488,15 +458,14 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
continue;
}
- BitSet pv = (BitSet) childPV.clone();
- pv.and(parentPV);
+ long[] pv = BitsUtil.andCMin(childPV, parentPV);
if(pv.equals(parentPV)) {
- List<Pair<BitSet, ArrayModifiableDBIDs>> parentList = clustersMap.get(parentPV);
- for(Pair<BitSet, ArrayModifiableDBIDs> parent : parentList) {
- V parent_centroid = ProjectedCentroid.make(parentPV, database, parent.second).toVector(database);
- double d = distFunc.weightedDistance(child_centroid, parent_centroid, parentPV);
+ List<ArrayModifiableDBIDs> parentList = clustersMap.get(parentPV);
+ for(ArrayModifiableDBIDs parent : parentList) {
+ Vector parent_centroid = ProjectedCentroid.make(parentPV, relation, parent);
+ double d = weightedDistance(child_centroid, parent_centroid, parentPV);
if(d <= 2 * epsilon) {
- result = parent;
+ result = new Pair<>(parentPV, parent);
resultCardinality = parentCardinality;
break;
}
@@ -510,65 +479,70 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
/**
* Builds the cluster hierarchy.
*
- * @param distFunc the distance function
* @param clustering Clustering we process
* @param clusters the sorted list of clusters
* @param dimensionality the dimensionality of the data
* @param database the database containing the data objects
*/
- private void buildHierarchy(Relation<V> database, DiSHDistanceFunction.Instance<V> distFunc, Clustering<SubspaceModel<V>> clustering, List<Cluster<SubspaceModel<V>>> clusters, int dimensionality) {
- StringBuilder msg = new StringBuilder();
+ private void buildHierarchy(Relation<V> database, Clustering<SubspaceModel> clustering, List<Cluster<SubspaceModel>> clusters, int dimensionality) {
+ StringBuilder msg = LOG.isDebugging() ? new StringBuilder() : null;
final int db_dim = RelationUtil.dimensionality(database);
- Hierarchy<Cluster<SubspaceModel<V>>> hier = clustering.getClusterHierarchy();
+ Hierarchy<Cluster<SubspaceModel>> hier = clustering.getClusterHierarchy();
for(int i = 0; i < clusters.size() - 1; i++) {
- Cluster<SubspaceModel<V>> c_i = clusters.get(i);
- int subspaceDim_i = dimensionality - c_i.getModel().getSubspace().dimensionality();
- V ci_centroid = ProjectedCentroid.make(c_i.getModel().getDimensions(), database, c_i.getIDs()).toVector(database);
+ Cluster<SubspaceModel> c_i = clusters.get(i);
+ final Subspace s_i = c_i.getModel().getSubspace();
+ int subspaceDim_i = dimensionality - s_i.dimensionality();
+ Vector ci_centroid = ProjectedCentroid.make(s_i.getDimensions(), database, c_i.getIDs());
+ long[] pv1 = s_i.getDimensions();
for(int j = i + 1; j < clusters.size(); j++) {
- Cluster<SubspaceModel<V>> c_j = clusters.get(j);
- int subspaceDim_j = dimensionality - c_j.getModel().getSubspace().dimensionality();
+ Cluster<SubspaceModel> c_j = clusters.get(j);
+ final Subspace s_j = c_j.getModel().getSubspace();
+ int subspaceDim_j = dimensionality - s_j.dimensionality();
if(subspaceDim_i < subspaceDim_j) {
- if(LOG.isDebugging()) {
- msg.append("\n l_i=").append(subspaceDim_i).append(" pv_i=[").append(FormatUtil.format(db_dim, c_i.getModel().getSubspace().getDimensions())).append(']');
- msg.append("\n l_j=").append(subspaceDim_j).append(" pv_j=[").append(FormatUtil.format(db_dim, c_j.getModel().getSubspace().getDimensions())).append(']');
+ if(msg != null) {
+ msg.append("\n l_i=").append(subspaceDim_i).append(" pv_i=[").append(BitsUtil.toStringLow(s_i.getDimensions(), db_dim)).append(']');
+ msg.append("\n l_j=").append(subspaceDim_j).append(" pv_j=[").append(BitsUtil.toStringLow(s_j.getDimensions(), db_dim)).append(']');
}
// noise level reached
- if(c_j.getModel().getSubspace().dimensionality() == 0) {
+ if(s_j.dimensionality() == 0) {
// no parents exists -> parent is noise
if(hier.numParents(c_i) == 0) {
clustering.addChildCluster(c_j, c_i);
- if(LOG.isDebugging()) {
- msg.append("\n [").append(FormatUtil.format(db_dim, c_j.getModel().getSubspace().getDimensions()));
- msg.append("] is parent of [").append(FormatUtil.format(db_dim, c_i.getModel().getSubspace().getDimensions()));
+ if(msg != null) {
+ msg.append("\n [").append(BitsUtil.toStringLow(s_j.getDimensions(), db_dim));
+ msg.append("] is parent of [").append(BitsUtil.toStringLow(s_i.getDimensions(), db_dim));
msg.append(']');
}
}
}
else {
- V cj_centroid = ProjectedCentroid.make(c_j.getModel().getDimensions(), database, c_j.getIDs()).toVector(database);
- PreferenceVectorBasedCorrelationDistance distance = distFunc.correlationDistance(ci_centroid, cj_centroid, c_i.getModel().getSubspace().getDimensions(), c_j.getModel().getSubspace().getDimensions());
- double d = distFunc.weightedDistance(ci_centroid, cj_centroid, distance.getCommonPreferenceVector());
- if(LOG.isDebugging()) {
- msg.append("\n dist = ").append(distance.getCorrelationValue());
+ Vector cj_centroid = ProjectedCentroid.make(c_j.getModel().getDimensions(), database, c_j.getIDs());
+ long[] pv2 = s_j.getDimensions();
+ long[] commonPreferenceVector = BitsUtil.andCMin(pv1, pv2);
+ int subspaceDim = subspaceDimensionality(ci_centroid, cj_centroid, pv1, pv2, commonPreferenceVector);
+
+ double d = weightedDistance(ci_centroid, cj_centroid, commonPreferenceVector);
+ if(msg != null) {
+ msg.append("\n dist = ").append(subspaceDim);
}
- if(distance.getCorrelationValue() == subspaceDim_j) {
- if(LOG.isDebugging()) {
+ if(subspaceDim == subspaceDim_j) {
+ if(msg != null) {
msg.append("\n d = ").append(d);
}
if(d <= 2 * epsilon) {
// no parent exists or c_j is not a parent of the already
// existing parents
- if(hier.numParents(c_i) == 0 || !isParent(database, distFunc, c_j, hier.iterParents(c_i))) {
+ if(hier.numParents(c_i) == 0 || !isParent(database, c_j, hier.iterParents(c_i), db_dim)) {
clustering.addChildCluster(c_j, c_i);
- if(LOG.isDebugging()) {
- msg.append("\n [").append(FormatUtil.format(db_dim, c_j.getModel().getSubspace().getDimensions()));
+ if(msg != null) {
+ msg.append("\n [").append(BitsUtil.toStringLow(s_j.getDimensions(), db_dim));
msg.append("] is parent of [");
- msg.append(FormatUtil.format(db_dim, c_i.getModel().getSubspace().getDimensions()));
+ msg.append(BitsUtil.toStringLow(s_i.getDimensions(), db_dim));
msg.append(']');
}
}
@@ -581,7 +555,7 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
}
}
}
- if(LOG.isDebugging()) {
+ if(msg != null) {
LOG.debug(msg.toString());
}
}
@@ -590,31 +564,75 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
* Returns true, if the specified parent cluster is a parent of one child of
* the children clusters.
*
- * @param database the database containing the objects
- * @param distFunc the distance function for distance computation between the
- * clusters
+ * @param relation the database containing the objects
* @param parent the parent to be tested
* @param iter the list of children to be tested
+ * @param db_dim Database dimensionality
* @return true, if the specified parent cluster is a parent of one child of
* the children clusters, false otherwise
*/
- private boolean isParent(Relation<V> database, DiSHDistanceFunction.Instance<V> distFunc, Cluster<SubspaceModel<V>> parent, Iter<Cluster<SubspaceModel<V>>> iter) {
- V parent_centroid = ProjectedCentroid.make(parent.getModel().getDimensions(), database, parent.getIDs()).toVector(database);
- int dimensionality = RelationUtil.dimensionality(database);
- int subspaceDim_parent = dimensionality - parent.getModel().getSubspace().dimensionality();
+ private boolean isParent(Relation<V> relation, Cluster<SubspaceModel> parent, Iter<Cluster<SubspaceModel>> iter, int db_dim) {
+ Subspace s_p = parent.getModel().getSubspace();
+ Vector parent_centroid = ProjectedCentroid.make(s_p.getDimensions(), relation, parent.getIDs());
+ int subspaceDim_parent = db_dim - s_p.dimensionality();
for(; iter.valid(); iter.advance()) {
- Cluster<SubspaceModel<V>> child = iter.get();
- V child_centroid = ProjectedCentroid.make(child.getModel().getDimensions(), database, child.getIDs()).toVector(database);
- PreferenceVectorBasedCorrelationDistance distance = distFunc.correlationDistance(parent_centroid, child_centroid, parent.getModel().getSubspace().getDimensions(), child.getModel().getSubspace().getDimensions());
- if(distance.getCorrelationValue() == subspaceDim_parent) {
+ Cluster<SubspaceModel> child = iter.get();
+ Subspace s_c = child.getModel().getSubspace();
+ Vector child_centroid = ProjectedCentroid.make(s_c.getDimensions(), relation, child.getIDs());
+ long[] commonPreferenceVector = BitsUtil.andCMin(s_p.getDimensions(), s_c.getDimensions());
+ int subspaceDim = subspaceDimensionality(parent_centroid, child_centroid, s_p.getDimensions(), s_c.getDimensions(), commonPreferenceVector);
+ if(subspaceDim == subspaceDim_parent) {
return true;
}
}
-
return false;
}
+ /**
+ * Compute the common subspace dimensionality of two vectors.
+ *
+ * @param v1 First vector
+ * @param v2 Second vector
+ * @param pv1 First preference
+ * @param pv2 Second preference
+ * @param commonPreferenceVector Common preference
+ * @return Usually, v1.dim - commonPreference.cardinality, unless either pv1
+ * and pv2 are a subset of the other.
+ */
+ private int subspaceDimensionality(NumberVector v1, NumberVector v2, long[] pv1, long[] pv2, long[] commonPreferenceVector) {
+ // number of zero values in commonPreferenceVector
+ int subspaceDim = v1.getDimensionality() - BitsUtil.cardinality(commonPreferenceVector);
+
+ // special case: v1 and v2 are in parallel subspaces
+ if(BitsUtil.equal(commonPreferenceVector, pv1) || BitsUtil.equal(commonPreferenceVector, pv2)) {
+ double d = weightedDistance(v1, v2, commonPreferenceVector);
+ if(d > 2 * epsilon) {
+ subspaceDim++;
+ }
+ }
+ return subspaceDim;
+ }
+
+ /**
+ * 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
+ */
+ protected static double weightedDistance(NumberVector v1, NumberVector v2, long[] weightVector) {
+ double sqrDist = 0;
+ for(int i = BitsUtil.nextSetBit(weightVector, 0); i >= 0; i = BitsUtil.nextSetBit(weightVector, i + 1)) {
+ double manhattanI = v1.doubleValue(i) - v2.doubleValue(i);
+ sqrDist += manhattanI * manhattanI;
+ }
+ return Math.sqrt(sqrDist);
+ }
+
@Override
public TypeInformation[] getInputTypeRestriction() {
return TypeUtil.array(TypeUtil.NUMBER_VECTOR_FIELD);
@@ -626,20 +644,199 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
}
/**
+ * OPTICS variant used by DiSH internally.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public class DiSHOPTICS extends GeneralizedOPTICS<V, DiSHClusterOrderEntry> {
+ /**
+ * DiSH preprocessor instance.
+ */
+ private DiSHPreferenceVectorIndex<V> index;
+
+ /**
+ * Constructor.
+ *
+ * @param indexinst Preprocessor instance.
+ */
+ public DiSHOPTICS(DiSHPreferenceVectorIndex<V> indexinst) {
+ super(mu);
+ this.index = indexinst;
+ }
+
+ @Override
+ public Class<? super DiSHClusterOrderEntry> getEntryType() {
+ return DiSHClusterOrderEntry.class;
+ }
+
+ @Override
+ protected DiSHClusterOrderEntry makeSeedEntry(Relation<V> relation, DBID objectID) {
+ return new DiSHClusterOrderEntry(objectID, null, Integer.MAX_VALUE, Double.POSITIVE_INFINITY, new long[0]);
+ }
+
+ @Override
+ protected Collection<DiSHClusterOrderEntry> getNeighborsForDBID(Relation<V> relation, DBID id) {
+ DBID id1 = DBIDUtil.deref(id);
+ long[] pv1 = index.getPreferenceVector(id1);
+ V dv1 = relation.get(id1);
+ final int dim = dv1.getDimensionality();
+
+ long[] ones = BitsUtil.ones(dim);
+ long[] inverseCommonPreferenceVector = BitsUtil.ones(dim);
+
+ ArrayList<DiSHClusterOrderEntry> result = new ArrayList<>();
+ for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
+ long[] pv2 = index.getPreferenceVector(iter);
+ V dv2 = relation.get(iter);
+ // We need a copy of this for the distance.
+ long[] commonPreferenceVector = BitsUtil.andCMin(pv1, pv2);
+
+ // number of zero values in commonPreferenceVector
+ int subspaceDim = dim - BitsUtil.cardinality(commonPreferenceVector);
+
+ // special case: v1 and v2 are in parallel subspaces
+ if(BitsUtil.equal(commonPreferenceVector, pv1) || BitsUtil.equal(commonPreferenceVector, pv2)) {
+ double d = weightedDistance(dv1, dv2, commonPreferenceVector);
+ if(d > 2 * epsilon) {
+ subspaceDim++;
+ }
+ }
+
+ // flip commonPreferenceVector for distance computation in common
+ // subspace
+ System.arraycopy(ones, 0, inverseCommonPreferenceVector, 0, ones.length);
+ BitsUtil.xorI(inverseCommonPreferenceVector, commonPreferenceVector);
+
+ final double orthogonalDistance = weightedDistance(dv1, dv2, inverseCommonPreferenceVector);
+ result.add(new DiSHClusterOrderEntry(DBIDUtil.deref(iter), id1, subspaceDim, orthogonalDistance, commonPreferenceVector));
+ }
+ Collections.sort(result);
+ // This is a hack, but needed to enforce core-distance of OPTICS:
+ if(result.size() >= getMinPts()) {
+ DiSHClusterOrderEntry coredist = result.get(getMinPts() - 1);
+ for(int i = 0; i < getMinPts() - 1; i++) {
+ final DiSHClusterOrderEntry prev = result.get(i);
+ result.set(i, new DiSHClusterOrderEntry(prev.getID(), id1, coredist.getCorrelationValue(), coredist.getEuclideanValue(), coredist.commonPreferenceVector));
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(TypeUtil.DOUBLE_VECTOR_FIELD);
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+ }
+
+ /**
+ * Cluster order entry for DiSH.
+ *
+ * @author Elke Achtert
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class DiSHClusterOrderEntry extends CorrelationClusterOrderEntry<DiSHClusterOrderEntry> {
+ /**
+ * The common preference vector of the two objects defining this distance.
+ */
+ private long[] commonPreferenceVector;
+
+ /**
+ * Constructs a new CorrelationDistance object.
+ *
+ * @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 DiSHClusterOrderEntry(DBID objectID, DBID predecessorID, int correlationValue, double euclideanValue, long[] commonPreferenceVector) {
+ super(objectID, predecessorID, correlationValue, euclideanValue);
+ this.commonPreferenceVector = commonPreferenceVector;
+ }
+
+ /**
+ * Returns the common preference vector of the two objects defining this
+ * distance.
+ *
+ * @return the common preference vector
+ */
+ public long[] 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();
+ }
+
+ @Override
+ public int compareTo(DiSHClusterOrderEntry other) {
+ return super.compareTo(other);
+ }
+ }
+
+ /**
* Parameterization class.
*
* @author Erich Schubert
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * Parameter that specifies the maximum radius of the neighborhood to be
+ * considered in each dimension for determination of the preference vector,
+ * must be a double equal to or greater than 0.
+ * <p>
+ * Default value: {@code 0.001}
+ * </p>
+ * <p>
+ * Key: {@code -dish.epsilon}
+ * </p>
+ */
+ public static final OptionID EPSILON_ID = new OptionID("dish.epsilon", //
+ "The maximum radius of the neighborhood to be considered in each " //
+ + " dimension for determination of the preference vector.");
+
+ /**
+ * Parameter that specifies the a minimum number of points as a smoothing
+ * factor to avoid the single-link-effect, must be an integer greater than
+ * 0.
+ * <p>
+ * Default value: {@code 1}
+ * </p>
+ * <p>
+ * Key: {@code -dish.mu}
+ * </p>
+ */
+ public static final OptionID MU_ID = new OptionID("dish.mu", //
+ "The minimum number of points as a smoothing factor to avoid the single-link-effekt.");
+
protected double epsilon = 0.0;
protected int mu = 1;
- protected DiSHDistanceFunction dishDistance;
-
- protected Collection<Pair<OptionID, Object>> opticsO;
+ /**
+ * DiSH preprocessor.
+ */
+ protected DiSHPreferenceVectorIndex.Factory<V> dishPreprocessor;
@Override
protected void makeOptions(Parameterization config) {
@@ -657,53 +854,23 @@ public class DiSH<V extends NumberVector<?>> extends AbstractAlgorithm<Clusterin
mu = muP.intValue();
}
- configDiSHDistance(config, epsilon, mu);
-
- configOPTICS(config, mu, dishDistance);
+ configDiSHPreprocessor(config, epsilon, mu);
}
- public void configDiSHDistance(Parameterization config, double epsilon, int minpts) {
+ public void configDiSHPreprocessor(Parameterization config, double epsilon, int minpts) {
ListParameterization dishParameters = new ListParameterization();
- dishParameters.addParameter(DiSHDistanceFunction.EPSILON_ID, epsilon);
- dishParameters.addParameter(IndexBasedDistanceFunction.INDEX_ID, DiSHPreferenceVectorIndex.Factory.class);
- dishParameters.addParameter(DiSHPreferenceVectorIndex.Factory.EPSILON_ID, Double.toString(epsilon));
+ dishParameters.addParameter(DiSHPreferenceVectorIndex.Factory.EPSILON_ID, epsilon);
dishParameters.addParameter(DiSHPreferenceVectorIndex.Factory.MINPTS_ID, minpts);
ChainedParameterization dishchain = new ChainedParameterization(dishParameters, config);
dishchain.errorsTo(config);
- dishDistance = dishchain.tryInstantiate(DiSHDistanceFunction.class);
- }
-
- /**
- * Get the parameters for embedded OPTICS.
- *
- * @param config Parameterization
- * @param minpts MinPts value
- * @param dishDistance DiSH distance function
- */
- public void configOPTICS(Parameterization config, final int minpts, final DiSHDistanceFunction dishDistance) {
- // Configure OPTICS. Tracked parameters
- ListParameterization opticsParameters = new ListParameterization();
- opticsParameters.addParameter(OPTICS.EPSILON_ID, AbstractDistance.INFINITY_PATTERN);
- opticsParameters.addParameter(OPTICS.MINPTS_ID, minpts);
- // Configure OPTICS. Untracked parameters
- ListParameterization opticsUntrackedParameters = new ListParameterization();
- opticsUntrackedParameters.addParameter(OPTICS.DISTANCE_FUNCTION_ID, dishDistance);
- ChainedParameterization optchain = new ChainedParameterization(opticsParameters, config);
- TrackParameters trackpar = new TrackParameters(optchain);
-
- ChainedParameterization optchain2 = new ChainedParameterization(opticsUntrackedParameters, trackpar);
- optchain2.errorsTo(config);
-
- // Instantiate OPTICS for parameterization
- optchain2.tryInstantiate(OPTICS.class);
- // store parameters
- opticsO = trackpar.getGivenParameters();
+ final Class<DiSHPreferenceVectorIndex.Factory<V>> cls = ClassGenericsUtil.uglyCastIntoSubclass(DiSHPreferenceVectorIndex.Factory.class);
+ dishPreprocessor = dishchain.tryInstantiate(cls);
}
@Override
protected DiSH<V> makeInstance() {
- return new DiSH<>(epsilon, dishDistance, opticsO);
+ return new DiSH<>(epsilon, mu, dishPreprocessor);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/HiSC.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/HiSC.java
index 3f135564..b0ad5eff 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/HiSC.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/HiSC.java
@@ -1,39 +1,53 @@
package de.lmu.ifi.dbs.elki.algorithm.clustering.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.algorithm.clustering.OPTICS;
+
+/*
+ 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.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderResult;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.CorrelationClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.GeneralizedOPTICS;
import de.lmu.ifi.dbs.elki.data.NumberVector;
+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.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.IndexBasedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.HiSCDistanceFunction;
-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.HiSCPreferenceVectorIndex;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
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;
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.ChainedParameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
@@ -53,26 +67,135 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
* @author Elke Achtert
*
* @apiviz.uses HiSCPreferenceVectorIndex
- * @apiviz.uses HiSCDistanceFunction
*
* @param <V> the type of NumberVector handled by the algorithm
*/
@Title("Finding Hierarchies of Subspace Clusters")
@Description("Algorithm for detecting hierarchies of subspace clusters.")
@Reference(authors = "E. Achtert, C. Böhm, H.-P. Kriegel, P. Kröger, I. Müller-Gorman, A. Zimek", title = "Finding Hierarchies of Subspace Clusters", booktitle = "Proc. 10th Europ. Conf. on Principles and Practice of Knowledge Discovery in Databases (PKDD'06), Berlin, Germany, 2006", url = "http://www.dbs.ifi.lmu.de/Publikationen/Papers/PKDD06-HiSC.pdf")
-public class HiSC<V extends NumberVector<?>> extends OPTICS<V, PreferenceVectorBasedCorrelationDistance> {
+public class HiSC<V extends NumberVector> extends GeneralizedOPTICS<V, HiSC.HiSCClusterOrderEntry> {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(HiSC.class);
/**
+ * Factory to produce
+ */
+ private IndexFactory<V, HiSCPreferenceVectorIndex<NumberVector>> indexfactory;
+
+ /**
+ * Instantiated index.
+ */
+ private HiSCPreferenceVectorIndex<NumberVector> index;
+
+ /**
+ * Relation we are currently processing.
+ */
+ private Relation<V> relation;
+
+ /**
+ * Holds the maximum diversion allowed.
+ */
+ private double alpha;
+
+ /**
* Constructor.
- *
- * @param distanceFunction HiSC distance function used
+ *
+ * @param indexfactory HiSC index factory
+ */
+ public HiSC(IndexFactory<V, HiSCPreferenceVectorIndex<NumberVector>> indexfactory, double epsilon) {
+ super(2);
+ this.indexfactory = indexfactory;
+ this.alpha = epsilon;
+ }
+
+ @Override
+ public ClusterOrderResult<HiSCClusterOrderEntry> run(Relation<V> relation) {
+ assert (this.index == null && this.relation == null) : "Running algorithm instance multiple times in parallel is not supported.";
+ this.index = indexfactory.instantiate(relation);
+ this.relation = relation;
+ ClusterOrderResult<HiSCClusterOrderEntry> result = super.run(relation);
+ this.index = null;
+ this.relation = null;
+ return result;
+ }
+
+ @Override
+ protected HiSCClusterOrderEntry makeSeedEntry(Relation<V> relation, DBID objectID) {
+ return new HiSCClusterOrderEntry(objectID, null, Integer.MAX_VALUE, Double.POSITIVE_INFINITY, new long[0]);
+ }
+
+ @Override
+ protected Collection<HiSCClusterOrderEntry> getNeighborsForDBID(Relation<V> relation, DBID id) {
+ DBID id1 = DBIDUtil.deref(id);
+ long[] pv1 = index.getPreferenceVector(id1);
+ V v1 = relation.get(id1);
+ final int dim = v1.getDimensionality();
+
+ ArrayList<HiSCClusterOrderEntry> result = new ArrayList<>();
+ for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
+ long[] pv2 = index.getPreferenceVector(iter);
+ V v2 = relation.get(iter);
+ final long[] commonPreferenceVector = BitsUtil.andCMin(pv1, pv2);
+
+ // number of zero values in commonPreferenceVector
+ int subspaceDim = dim - BitsUtil.cardinality(commonPreferenceVector);
+
+ // 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) > alpha) {
+ subspaceDim++;
+ if(LOG.isDebugging()) {
+ StringBuilder msg = new StringBuilder();
+ msg.append("\ndist1 ").append(dist1);
+ msg.append("\ndist2 ").append(dist2);
+ msg.append("\nsubspaceDim ").append(subspaceDim);
+ msg.append("\ncommon pv ").append(BitsUtil.toStringLow(commonPreferenceVector, dim));
+ LOG.debugFine(msg.toString());
+ }
+ }
+
+ // flip commonPreferenceVector for distance computation in common subspace
+ long[] inverseCommonPreferenceVector = BitsUtil.ones(dim);
+ BitsUtil.xorI(inverseCommonPreferenceVector, commonPreferenceVector);
+
+ final double orthogonalDistance = weightedDistance(v1, v2, inverseCommonPreferenceVector);
+ result.add(new HiSCClusterOrderEntry(DBIDUtil.deref(iter), id1, subspaceDim, orthogonalDistance, commonPreferenceVector));
+ }
+ Collections.sort(result);
+ return result;
+ }
+
+ /**
+ * 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 HiSC(HiSCDistanceFunction<V> distanceFunction) {
- super(distanceFunction, distanceFunction.getDistanceFactory().infiniteDistance(), 2);
+ public double weightedDistance(V v1, V v2, long[] weightVector) {
+ double sqrDist = 0.;
+ for(int i = BitsUtil.nextSetBit(weightVector, 0); i >= 0; i = BitsUtil.nextSetBit(weightVector, i + 1)) {
+ double manhattanI = v1.doubleValue(i) - v2.doubleValue(i);
+ sqrDist += manhattanI * manhattanI;
+ }
+ return Math.sqrt(sqrDist);
+ }
+
+ @Override
+ public Class<? super HiSCClusterOrderEntry> getEntryType() {
+ return HiSCClusterOrderEntry.class;
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(indexfactory.getInputTypeRestriction());
}
@Override
@@ -81,22 +204,99 @@ public class HiSC<V extends NumberVector<?>> extends OPTICS<V, PreferenceVectorB
}
/**
+ * Cluster order entry for HiSC.
+ *
+ * @author Elke Achtert
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class HiSCClusterOrderEntry extends CorrelationClusterOrderEntry<HiSCClusterOrderEntry> {
+ /**
+ * The common preference vector of the two objects defining this distance.
+ */
+ private long[] commonPreferenceVector;
+
+ /**
+ * Constructs a new CorrelationDistance object.
+ *
+ * @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 HiSCClusterOrderEntry(DBID objectID, DBID predecessorID, int correlationValue, double euclideanValue, long[] commonPreferenceVector) {
+ super(objectID, predecessorID, correlationValue, euclideanValue);
+ this.commonPreferenceVector = commonPreferenceVector;
+ }
+
+ /**
+ * Returns the common preference vector of the two objects defining this
+ * distance.
+ *
+ * @return the common preference vector
+ */
+ public long[] 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();
+ }
+
+ @Override
+ public int compareTo(HiSCClusterOrderEntry other) {
+ return super.compareTo(other);
+ }
+ }
+
+ /**
* Parameterization class.
*
* @author Erich Schubert
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
- HiSCDistanceFunction<V> distanceFunction;
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * 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 -hisc.epsilon}
+ * </p>
+ */
+ public static final OptionID EPSILON_ID = new OptionID("hisc.epsilon", "The maximum distance between two vectors with equal preference vectors before considering them as parallel.");
+
+ /**
+ * Factory to produce the index.
+ */
+ private IndexFactory<V, HiSCPreferenceVectorIndex<NumberVector>> indexfactory;
+
+ /**
+ * Alpha parameter.
+ */
+ double alpha;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
DoubleParameter alphaP = new DoubleParameter(HiSCPreferenceVectorIndex.Factory.ALPHA_ID, HiSCPreferenceVectorIndex.Factory.DEFAULT_ALPHA);
- alphaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ alphaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
alphaP.addConstraint(CommonConstraints.LESS_THAN_ONE_DOUBLE);
- double alpha = 0.0;
if(config.grab(alphaP)) {
alpha = alphaP.doubleValue();
}
@@ -104,21 +304,19 @@ public class HiSC<V extends NumberVector<?>> extends OPTICS<V, PreferenceVectorB
// Configure HiSC distance function
ListParameterization opticsParameters = new ListParameterization();
- // distance function
- opticsParameters.addParameter(HiSCDistanceFunction.EPSILON_ID, alpha);
// preprocessor
opticsParameters.addParameter(IndexBasedDistanceFunction.INDEX_ID, HiSCPreferenceVectorIndex.Factory.class);
opticsParameters.addParameter(HiSCPreferenceVectorIndex.Factory.ALPHA_ID, alpha);
ChainedParameterization chain = new ChainedParameterization(opticsParameters, config);
chain.errorsTo(config);
- Class<HiSCDistanceFunction<V>> cls = ClassGenericsUtil.uglyCastIntoSubclass(HiSCDistanceFunction.class);
- distanceFunction = chain.tryInstantiate(cls);
+ final Class<? extends IndexFactory<V, HiSCPreferenceVectorIndex<NumberVector>>> cls = ClassGenericsUtil.uglyCrossCast(HiSCPreferenceVectorIndex.Factory.class, IndexFactory.class);
+ indexfactory = chain.tryInstantiate(cls);
}
@Override
protected HiSC<V> makeInstance() {
- return new HiSC<>(distanceFunction);
+ return new HiSC<>(indexfactory, alpha);
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/P3C.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/P3C.java
index 9d1ee94d..4e1de7c7 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/P3C.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/P3C.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.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
@@ -25,12 +25,13 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.BitSet;
import java.util.Iterator;
import java.util.List;
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.EM;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.em.EM;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.em.EMClusterModel;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.em.MultivariateGaussianModel;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
@@ -61,7 +62,6 @@ import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
import de.lmu.ifi.dbs.elki.math.linearalgebra.CovarianceMatrix;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
import de.lmu.ifi.dbs.elki.math.linearalgebra.VMath;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.math.statistics.distribution.ChiSquaredDistribution;
@@ -103,7 +103,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*/
@Title("P3C: A Robust Projected Clustering Algorithm.")
@Reference(authors = "Gabriela Moise, Jörg Sander, Martin Ester", title = "P3C: A Robust Projected Clustering Algorithm", booktitle = "Proc. Sixth International Conference on Data Mining (ICDM '06)", url = "http://dx.doi.org/10.1109/ICDM.2006.123")
-public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<SubspaceModel<V>>> implements SubspaceClusteringAlgorithm<SubspaceModel<V>> {
+public class P3C<V extends NumberVector> extends AbstractAlgorithm<Clustering<SubspaceModel>> implements SubspaceClusteringAlgorithm<SubspaceModel> {
/**
* The logger for this class.
*/
@@ -156,7 +156,7 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
/**
* Performs the P3C algorithm on the given Database.
*/
- public Clustering<SubspaceModel<V>> run(Database database, Relation<V> relation) {
+ public Clustering<SubspaceModel> run(Database database, Relation<V> relation) {
final int dim = RelationUtil.dimensionality(relation);
// Overall progress.
@@ -167,7 +167,7 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
}
// Desired number of bins, as per Sturge:
- final int binCount = (int) Math.ceil(1 + (Math.log(relation.size()) / MathUtil.LOG2));
+ final int binCount = (int) Math.ceil(1 + MathUtil.log2(relation.size()));
// Perform 1-dimensional projections, and split into bins.
SetDBIDs[][] partitions = partitionData(relation, binCount);
@@ -178,7 +178,6 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
// Set markers for each attribute until they're all deemed uniform.
final long[][] markers = new long[dim][];
- int numuniform = 0;
for(int d = 0; d < dim; d++) {
final SetDBIDs[] parts = partitions[d];
if(parts == null) {
@@ -191,7 +190,6 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
// previously marked.
int bestBin = chiSquaredUniformTest(parts, marked, card);
if(bestBin < 0) {
- numuniform++;
break; // Uniform
}
BitsUtil.setI(marked, bestBin);
@@ -224,9 +222,9 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
}
if(clusterCores.size() == 0) {
- stepProgress.setCompleted(LOG);
- Clustering<SubspaceModel<V>> c = new Clustering<>("P3C", "P3C");
- c.addToplevelCluster(new Cluster<SubspaceModel<V>>(relation.getDBIDs(), true));
+ LOG.setCompleted(stepProgress);
+ Clustering<SubspaceModel> c = new Clustering<>("P3C", "P3C");
+ c.addToplevelCluster(new Cluster<SubspaceModel>(relation.getDBIDs(), true));
return c;
}
@@ -238,26 +236,19 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
ModifiableDBIDs noise = DBIDUtil.newHashSet();
WritableDataStore<double[]> probClusterIGivenX = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_SORTED, double[].class);
int k = clusterCores.size();
- double[] clusterWeights = new double[k];
- computeFuzzyMembership(relation, clusterCores, noise, probClusterIGivenX, clusterWeights);
+ List<MultivariateGaussianModel> models = new ArrayList<>(k);
+ computeFuzzyMembership(relation, clusterCores, noise, probClusterIGivenX, models, dim);
// Initial estimate of covariances, to assign noise objects
- Vector[] means = new Vector[k];
- Matrix[] covarianceMatrices = new Matrix[k], invCovMatr = new Matrix[k];
- final double norm = MathUtil.powi(MathUtil.TWOPI, dim);
- double[] normDistrFactor = new double[k];
- Arrays.fill(normDistrFactor, 1. / Math.sqrt(norm));
- EM.recomputeCovarianceMatrices(relation, probClusterIGivenX, means, covarianceMatrices, dim);
- EM.computeInverseMatrixes(covarianceMatrices, invCovMatr, normDistrFactor, norm);
- assignUnassigned(relation, probClusterIGivenX, means, invCovMatr, clusterWeights, noise);
-
- double emNew = EM.assignProbabilitiesToInstances(relation, normDistrFactor, means, invCovMatr, clusterWeights, probClusterIGivenX);
+ EM.recomputeCovarianceMatrices(relation, probClusterIGivenX, models);
+ assignUnassigned(relation, probClusterIGivenX, models, noise);
+
+ double emNew = EM.assignProbabilitiesToInstances(relation, models, probClusterIGivenX);
for(int it = 1; it <= maxEmIterations || maxEmIterations < 0; it++) {
final double emOld = emNew;
- EM.recomputeCovarianceMatrices(relation, probClusterIGivenX, means, covarianceMatrices, dim);
- EM.computeInverseMatrixes(covarianceMatrices, invCovMatr, normDistrFactor, norm);
+ EM.recomputeCovarianceMatrices(relation, probClusterIGivenX, models);
// reassign probabilities
- emNew = EM.assignProbabilitiesToInstances(relation, normDistrFactor, means, invCovMatr, clusterWeights, probClusterIGivenX);
+ emNew = EM.assignProbabilitiesToInstances(relation, models, probClusterIGivenX);
if(LOG.isVerbose()) {
LOG.verbose("iteration " + it + " - expectation value: " + emNew);
@@ -283,7 +274,7 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
// Outlier detection. Remove points from clusters that have a Mahalanobis
// distance larger than the critical value of the ChiSquare distribution.
- findOutliers(relation, means, invCovMatr, clusterCandidates, dim - numuniform, noise);
+ findOutliers(relation, models, clusterCandidates, noise);
if(stepProgress != null) {
stepProgress.beginStep(8, "Removing empty clusters.", LOG);
@@ -312,20 +303,18 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
}
// Generate final output.
- Clustering<SubspaceModel<V>> result = new Clustering<>("P3C", "P3C");
+ Clustering<SubspaceModel> result = new Clustering<>("P3C", "P3C");
for(int cluster = 0; cluster < clusterCandidates.size(); ++cluster) {
ClusterCandidate candidate = clusterCandidates.get(cluster);
CovarianceMatrix cvm = CovarianceMatrix.make(relation, candidate.ids);
- result.addToplevelCluster(new Cluster<>(candidate.ids, new SubspaceModel<>(new Subspace(candidate.dimensions), cvm.getMeanVector(relation))));
+ result.addToplevelCluster(new Cluster<>(candidate.ids, new SubspaceModel(new Subspace(candidate.dimensions), cvm.getMeanVector())));
}
LOG.verbose("Noise size: " + noise.size());
if(noise.size() > 0) {
- result.addToplevelCluster(new Cluster<SubspaceModel<V>>(noise, true));
+ result.addToplevelCluster(new Cluster<SubspaceModel>(noise, true));
}
- if(stepProgress != null) {
- stepProgress.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(stepProgress);
return result;
}
@@ -500,7 +489,7 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
* @param parts Parts array
* @param start Array start index
* @param end Array end index (exclusive)
- * @return
+ * @return Union
*/
protected HashSetModifiableDBIDs unionDBIDs(final DBIDs[] parts, int start, int end) {
int sum = 0;
@@ -561,12 +550,15 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
* @param clusterCores the cluster cores.
* @param unassigned set to which to add unassigned points.
* @param probClusterIGivenX Membership probabilities.
- * @param clusterWeights Cluster weights
+ * @param models Cluster models.
+ * @param dim Dimensionality
*/
- private void computeFuzzyMembership(Relation<V> relation, ArrayList<Signature> clusterCores, ModifiableDBIDs unassigned, WritableDataStore<double[]> probClusterIGivenX, double[] clusterWeights) {
+ private void computeFuzzyMembership(Relation<V> relation, ArrayList<Signature> clusterCores, ModifiableDBIDs unassigned, WritableDataStore<double[]> probClusterIGivenX, List<MultivariateGaussianModel> models, int dim) {
final int n = relation.size();
+ final double pweight = 1. / n; // Weight of each point
final int k = clusterCores.size();
+ double[] clusterWeights = new double[k];
for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
int count = 0;
double[] weights = new double[k];
@@ -581,7 +573,7 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
if(count > 0) {
// Rescale.
VMath.timesEquals(weights, 1. / count);
- VMath.plusTimesEquals(clusterWeights, weights, 1. / n);
+ VMath.plusTimesEquals(clusterWeights, weights, pweight);
}
else {
// Does not match any cluster, mark it.
@@ -589,6 +581,10 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
}
probClusterIGivenX.put(iter, weights);
}
+ final double f = MathUtil.powi(MathUtil.TWOPI, dim); // Scaling coefficient
+ for(int i = 0; i < k; i++) {
+ models.add(new MultivariateGaussianModel(clusterWeights[i], new Vector(dim), f));
+ }
}
/**
@@ -597,36 +593,44 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
*
* @param relation Data relation
* @param probClusterIGivenX fuzzy membership matrix.
- * @param means Cluster means.
- * @param invCovMatr Cluster covariance matrices.
- * @param clusterWeights
- * @param assigned mapping of matrix row to DBID.
+ * @param models Cluster models.
* @param unassigned the list of points not yet assigned.
*/
- private void assignUnassigned(Relation<V> relation, WritableDataStore<double[]> probClusterIGivenX, Vector[] means, Matrix[] invCovMatr, double[] clusterWeights, ModifiableDBIDs unassigned) {
+ private void assignUnassigned(Relation<V> relation, WritableDataStore<double[]> probClusterIGivenX, List<MultivariateGaussianModel> models, ModifiableDBIDs unassigned) {
if(unassigned.size() == 0) {
return;
}
- final int k = means.length;
+ final int k = models.size();
double pweight = 1. / relation.size();
+ // Rescale weights, to take unassigned points into account:
+ for(EMClusterModel<?> m : models) {
+ m.setWeight(m.getWeight() * (relation.size() - unassigned.size()) * pweight);
+ }
+
+ // Assign noise objects, increase weights accordingly.
for(DBIDIter iter = unassigned.iter(); iter.valid(); iter.advance()) {
// Find the best matching known cluster core using the Mahalanobis
// distance.
- Vector v = relation.get(iter).getColumnVector();
+ V v = relation.get(iter);
int bestCluster = -1;
+ MultivariateGaussianModel bestModel = null;
double minDistance = Double.POSITIVE_INFINITY;
- for(int c = 0; c < k; ++c) {
- final double distance = MathUtil.mahalanobisDistance(invCovMatr[c], v.minus(means[c]));
+ int c = 0;
+ for(MultivariateGaussianModel model : models) {
+ final double distance = model.mahalanobisDistance(v);
if(distance < minDistance) {
minDistance = distance;
bestCluster = c;
+ bestModel = model;
}
+ c++;
}
// Assign to best core.
double[] weights = new double[k];
- weights[bestCluster] = 1.0;
- clusterWeights[bestCluster] += pweight;
+ weights[bestCluster] = 1.;
+
+ bestModel.setWeight(bestModel.getWeight() + pweight);
probClusterIGivenX.put(iter, weights);
}
@@ -675,28 +679,19 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
* attributes.
*
* @param relation Data relation
- * @param means Cluster means
- * @param invCovMatr Inverse covariance matrixes
+ * @param models Cluster models
* @param clusterCandidates the list of clusters to check.
- * @param nonUniformDimensionCount the number of dimensions to consider when
- * testing.
* @param noise the set to which to add points deemed outliers.
*/
- private void findOutliers(Relation<V> relation, Vector[] means, Matrix[] invCovMatr, ArrayList<ClusterCandidate> clusterCandidates, int nonUniformDimensionCount, ModifiableDBIDs noise) {
- final int k = clusterCandidates.size();
-
- for(int c = 0; c < k; ++c) {
+ private void findOutliers(Relation<V> relation, List<MultivariateGaussianModel> models, ArrayList<ClusterCandidate> clusterCandidates, ModifiableDBIDs noise) {
+ Iterator<MultivariateGaussianModel> it = models.iterator();
+ for(int c = 0; it.hasNext(); c++) {
+ MultivariateGaussianModel model = it.next();
final ClusterCandidate candidate = clusterCandidates.get(c);
- if(candidate.ids.size() < 2) {
- continue;
- }
- final int dof = candidate.dimensions.cardinality();
- final double threshold = ChiSquaredDistribution.quantile(1 - .001, dof);
+ final int dof = BitsUtil.cardinality(candidate.dimensions);
+ final double threshold = ChiSquaredDistribution.quantile(1 - alpha, dof);
for(DBIDMIter iter = candidate.ids.iter(); iter.valid(); iter.advance()) {
- final Vector mean = means[c];
- final Vector delta = relation.get(iter).getColumnVector().minusEquals(mean);
- final Matrix invCov = invCovMatr[c];
- final double distance = MathUtil.mahalanobisDistance(invCov, delta);
+ final double distance = model.mahalanobisDistance(relation.get(iter));
if(distance >= threshold) {
// Outlier, remove it and add it to the outlier set.
noise.add(iter);
@@ -851,7 +846,7 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
/**
* Selected dimensions
*/
- public final BitSet dimensions;
+ public final long[] dimensions;
/**
* Objects contained in cluster.
@@ -864,9 +859,9 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
* @param clusterCore Signature
*/
public ClusterCandidate(Signature clusterCore) {
- this.dimensions = new BitSet(clusterCore.spec.length >> 1);
+ this.dimensions = BitsUtil.zero(clusterCore.spec.length >> 1);
for(int i = 0; i < clusterCore.spec.length; i += 2) {
- this.dimensions.set(i >> 1);
+ BitsUtil.setI(this.dimensions, i >> 1);
}
this.ids = DBIDUtil.newArray(clusterCore.ids.size());
}
@@ -889,7 +884,7 @@ public class P3C<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* Parameter for the chi squared test threshold.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/PROCLUS.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/PROCLUS.java
index 03e9978f..805281b0 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/PROCLUS.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/PROCLUS.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.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
@@ -28,7 +28,6 @@ import gnu.trove.set.TIntSet;
import gnu.trove.set.hash.TIntHashSet;
import java.util.ArrayList;
-import java.util.BitSet;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -44,25 +43,32 @@ import de.lmu.ifi.dbs.elki.data.model.SubspaceModel;
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.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-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.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
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.distanceresultlist.DistanceDBIDResultUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
import de.lmu.ifi.dbs.elki.math.Mean;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Centroid;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
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;
@@ -71,13 +77,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraint
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.RandomParameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.CTriple;
import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* <p/>
- * Provides the PROCLUS algorithm, an algorithm to find subspace clusters in
- * high dimensional spaces.
+ * The PROCLUS algorithm, an algorithm to find subspace clusters in high
+ * dimensional spaces.
* </p>
* <p/>
* Reference: <br>
@@ -92,30 +97,20 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
*
* @param <V> the type of NumberVector handled by this Algorithm
*/
-// TODO: optimize by creating much less objects
@Title("PROCLUS: PROjected CLUStering")
@Description("Algorithm to find subspace clusters in high dimensional spaces.")
-@Reference(authors = "C. C. Aggarwal, C. Procopiuc, J. L. Wolf, P. S. Yu, J. S. Park", title = "Fast Algorithms for Projected Clustering", booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '99)", url = "http://dx.doi.org/10.1145/304181.304188")
-public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedClustering<Clustering<SubspaceModel<V>>, V> implements SubspaceClusteringAlgorithm<SubspaceModel<V>> {
+@Reference(authors = "C. C. Aggarwal, C. Procopiuc, J. L. Wolf, P. S. Yu, J. S. Park", //
+title = "Fast Algorithms for Projected Clustering", //
+booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '99)", //
+url = "http://dx.doi.org/10.1145/304181.304188")
+public class PROCLUS<V extends NumberVector> extends AbstractProjectedClustering<Clustering<SubspaceModel>, V> implements SubspaceClusteringAlgorithm<SubspaceModel> {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(PROCLUS.class);
/**
- * Parameter to specify the multiplier for the initial number of medoids, must
- * be an integer greater than 0.
- * <p>
- * Default value: {@code 10}
- * </p>
- * <p>
- * Key: {@code -proclus.mi}
- * </p>
- */
- public static final OptionID M_I_ID = new OptionID("proclus.mi", "The multiplier for the initial number of medoids.");
-
- /**
- * Holds the value of {@link #M_I_ID}.
+ * Multiplier for the initial number of medoids.
*/
private int m_i;
@@ -145,27 +140,27 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
* @param database Database to process
* @param relation Relation to process
*/
- public Clustering<SubspaceModel<V>> run(Database database, Relation<V> relation) {
- DistanceQuery<V, DoubleDistance> distFunc = this.getDistanceQuery(database);
- RangeQuery<V, DoubleDistance> rangeQuery = database.getRangeQuery(distFunc);
+ public Clustering<SubspaceModel> run(Database database, Relation<V> relation) {
+ DistanceQuery<V> distFunc = this.getDistanceQuery(database);
+ RangeQuery<V> rangeQuery = database.getRangeQuery(distFunc);
final Random random = rnd.getSingleThreadedRandom();
- if (RelationUtil.dimensionality(relation) < l) {
+ if(RelationUtil.dimensionality(relation) < l) {
throw new IllegalStateException("Dimensionality of data < parameter l! " + "(" + RelationUtil.dimensionality(relation) + " < " + l + ")");
}
// TODO: use a StepProgress!
// initialization phase
- if (LOG.isVerbose()) {
+ if(LOG.isVerbose()) {
LOG.verbose("1. Initialization phase...");
}
int sampleSize = Math.min(relation.size(), k_i * k);
DBIDs sampleSet = DBIDUtil.randomSample(relation.getDBIDs(), sampleSize, random.nextLong());
int medoidSize = Math.min(relation.size(), m_i * k);
- DBIDs medoids = greedy(distFunc, sampleSet, medoidSize, random);
+ ArrayDBIDs medoids = greedy(distFunc, sampleSet, medoidSize, random);
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
StringBuilder msg = new StringBuilder();
msg.append('\n');
msg.append("sampleSize ").append(sampleSize).append('\n');
@@ -176,15 +171,15 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
}
// iterative phase
- if (LOG.isVerbose()) {
+ if(LOG.isVerbose()) {
LOG.verbose("2. Iterative phase...");
}
double bestObjective = Double.POSITIVE_INFINITY;
- ModifiableDBIDs m_best = null;
- ModifiableDBIDs m_bad = null;
- ModifiableDBIDs m_current = initialSet(medoids, k, random);
+ ArrayDBIDs m_best = null;
+ DBIDs m_bad = null;
+ ArrayDBIDs m_current = initialSet(medoids, k, random);
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
StringBuilder msg = new StringBuilder();
msg.append('\n');
msg.append("m_c ").append(m_current).append('\n');
@@ -193,47 +188,44 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
IndefiniteProgress cprogress = LOG.isVerbose() ? new IndefiniteProgress("Current number of clusters:", LOG) : null;
- // TODO: Use DataStore and Trove for performance
- Map<DBID, PROCLUSCluster> clusters = null;
+ ArrayList<PROCLUSCluster> clusters = null;
int loops = 0;
- while (loops < 10) {
- Map<DBID, TIntSet> dimensions = findDimensions(m_current, relation, distFunc, rangeQuery);
- clusters = assignPoints(dimensions, relation);
+ while(loops < 10) {
+ TIntSet[] dimensions = findDimensions(m_current, relation, distFunc, rangeQuery);
+ clusters = assignPoints(m_current, dimensions, relation);
double objectiveFunction = evaluateClusters(clusters, dimensions, relation);
- if (objectiveFunction < bestObjective) {
+ if(objectiveFunction < bestObjective) {
// restart counting loops
loops = 0;
bestObjective = objectiveFunction;
m_best = m_current;
- m_bad = computeBadMedoids(clusters, (int) (relation.size() * 0.1 / k));
+ m_bad = computeBadMedoids(m_current, clusters, (int) (relation.size() * 0.1 / k));
}
m_current = computeM_current(medoids, m_best, m_bad, random);
loops++;
- if (cprogress != null) {
+ if(cprogress != null) {
cprogress.setProcessed(clusters.size(), LOG);
}
}
- if (cprogress != null) {
- cprogress.setCompleted(LOG);
- }
+ LOG.setCompleted(cprogress);
// refinement phase
- if (LOG.isVerbose()) {
+ if(LOG.isVerbose()) {
LOG.verbose("3. Refinement phase...");
}
- List<Pair<V, TIntSet>> dimensions = findDimensions(new ArrayList<>(clusters.values()), relation);
+ List<Pair<Vector, TIntSet>> dimensions = findDimensions(clusters, relation);
List<PROCLUSCluster> finalClusters = finalAssignment(dimensions, relation);
// build result
int numClusters = 1;
- Clustering<SubspaceModel<V>> result = new Clustering<>("ProClus clustering", "proclus-clustering");
- for (PROCLUSCluster c : finalClusters) {
- Cluster<SubspaceModel<V>> cluster = new Cluster<>(c.objectIDs);
- cluster.setModel(new SubspaceModel<>(new Subspace(c.getDimensions()), c.centroid));
+ Clustering<SubspaceModel> result = new Clustering<>("ProClus clustering", "proclus-clustering");
+ for(PROCLUSCluster c : finalClusters) {
+ Cluster<SubspaceModel> cluster = new Cluster<>(c.objectIDs);
+ cluster.setModel(new SubspaceModel(new Subspace(c.getDimensions()), c.centroid));
cluster.setName("cluster_" + numClusters++);
result.addToplevelCluster(cluster);
@@ -250,48 +242,64 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
* @param random random number generator
* @return a piercing set of m medoids from the specified sample set
*/
- private ModifiableDBIDs greedy(DistanceQuery<V, DoubleDistance> distFunc, DBIDs sampleSet, int m, Random random) {
+ private ArrayDBIDs greedy(DistanceQuery<V> distFunc, DBIDs sampleSet, int m, Random random) {
+ ArrayModifiableDBIDs medoids = DBIDUtil.newArray(m);
+
ArrayModifiableDBIDs s = DBIDUtil.newArray(sampleSet);
- ModifiableDBIDs medoids = DBIDUtil.newHashSet();
+ DBIDArrayIter iter = s.iter();
+ DBIDVar m_i = DBIDUtil.newVar();
+ int size = s.size();
// m_1 is random point of S
- DBID m_i = s.remove(random.nextInt(s.size()));
+ final int r = random.nextInt(size);
+ s.assignVar(r, m_i);
medoids.add(m_i);
- if (LOG.isDebugging()) {
- LOG.debugFiner("medoids " + medoids);
+ if(LOG.isDebugging()) {
+ LOG.debugFiner("medoids " + medoids.toString());
}
+ // Remove m_i from candidates, by moving to the end.
+ s.swap(r, size - 1);
+ --size;
+
+ // To track the current worst element:
+ int worst = -1;
+ double worstd = Double.NEGATIVE_INFINITY;
// compute distances between each point in S and m_i
- // FIXME: don't use maps, so we can work with DBIDRef
- Map<DBID, DistanceDBIDPair<DoubleDistance>> distances = new HashMap<>();
- for (DBIDIter iter = s.iter(); iter.valid(); iter.advance()) {
- DBID id = DBIDUtil.deref(iter);
- DoubleDistance dist = distFunc.distance(id, m_i);
- distances.put(id, DBIDUtil.newDistancePair(dist, id));
+ WritableDoubleDataStore distances = DataStoreUtil.makeDoubleStorage(s, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
+ for(iter.seek(0); iter.getOffset() < size; iter.advance()) {
+ final double dist = distFunc.distance(iter, m_i);
+ distances.putDouble(iter, dist);
+ if(dist > worstd) {
+ worstd = dist;
+ worst = iter.getOffset();
+ }
}
- for (int i = 1; i < m; i++) {
+ for(int i = 1; i < m; i++) {
// choose medoid m_i to be far from previous medoids
- List<DistanceDBIDPair<DoubleDistance>> d = new ArrayList<>(distances.values());
- DistanceDBIDResultUtil.sortByDistance(d);
-
- m_i = DBIDUtil.deref(d.get(d.size() - 1));
+ s.assignVar(worst, m_i);
medoids.add(m_i);
- s.remove(m_i);
- distances.remove(m_i);
-
- // compute distances of each point to closest medoid
- for (DBIDIter iter = s.iter(); iter.valid(); iter.advance()) {
- DBID id = DBIDUtil.deref(iter);
- DoubleDistance dist_new = distFunc.distance(id, m_i);
- DoubleDistance dist_old = distances.get(id).getDistance();
-
- DoubleDistance dist = dist_new.compareTo(dist_old) < 0 ? dist_new : dist_old;
- distances.put(id, DBIDUtil.newDistancePair(dist, id));
+ // Remove m_i from candidates, by moving to the end.
+ s.swap(worst, size - 1);
+ --size;
+
+ // compute distances of each point to closest medoid; track worst.
+ worst = -1;
+ worstd = Double.NEGATIVE_INFINITY;
+ for(iter.seek(0); iter.getOffset() < size; iter.advance()) {
+ double dist_new = distFunc.distance(iter, m_i);
+ double dist_old = distances.doubleValue(iter);
+ double dist = (dist_new < dist_old) ? dist_new : dist_old;
+ distances.putDouble(iter, dist);
+ if(dist > worstd) {
+ worstd = dist;
+ worst = iter.getOffset();
+ }
}
- if (LOG.isDebugging()) {
- LOG.debugFiner("medoids " + medoids);
+ if(LOG.isDebugging()) {
+ LOG.debugFiner("medoids " + medoids.toString());
}
}
@@ -306,14 +314,8 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
* @param random random number generator
* @return a set of k elements from the specified sample set
*/
- private ModifiableDBIDs initialSet(DBIDs sampleSet, int k, Random random) {
- ArrayModifiableDBIDs s = DBIDUtil.newArray(sampleSet);
- ModifiableDBIDs initialSet = DBIDUtil.newHashSet();
- while (initialSet.size() < k) {
- DBID next = s.remove(random.nextInt(s.size()));
- initialSet.add(next);
- }
- return initialSet;
+ private ArrayDBIDs initialSet(DBIDs sampleSet, int k, Random random) {
+ return DBIDUtil.ensureArray(DBIDUtil.randomSample(sampleSet, k, random));
}
/**
@@ -325,21 +327,21 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
* @param random random number generator
* @return m_current, the set of medoids in current iteration
*/
- private ModifiableDBIDs computeM_current(DBIDs m, DBIDs m_best, DBIDs m_bad, Random random) {
+ private ArrayDBIDs computeM_current(DBIDs m, DBIDs m_best, DBIDs m_bad, Random random) {
ArrayModifiableDBIDs m_list = DBIDUtil.newArray(m);
m_list.removeDBIDs(m_best);
- ModifiableDBIDs m_current = DBIDUtil.newHashSet();
- for (DBIDIter iter = m_best.iter(); iter.valid(); iter.advance()) {
- DBID m_i = DBIDUtil.deref(iter);
- if (m_bad.contains(m_i)) {
+ ArrayModifiableDBIDs m_current = DBIDUtil.newArray();
+ for(DBIDIter iter = m_best.iter(); iter.valid(); iter.advance()) {
+ if(m_bad.contains(iter)) {
int currentSize = m_current.size();
- while (m_current.size() == currentSize) {
+ while(m_current.size() == currentSize) {
DBID next = m_list.remove(random.nextInt(m_list.size()));
m_current.add(next);
}
- } else {
- m_current.add(m_i);
+ }
+ else {
+ m_current.add(iter);
}
}
@@ -357,29 +359,27 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
* @param distFunc the distance function
* @return a mapping of the medoid's id to its locality
*/
- private Map<DBID, DistanceDBIDList<DoubleDistance>> getLocalities(DBIDs medoids, Relation<V> database, DistanceQuery<V, DoubleDistance> distFunc, RangeQuery<V, DoubleDistance> rangeQuery) {
- Map<DBID, DistanceDBIDList<DoubleDistance>> result = new HashMap<>();
+ private DataStore<DoubleDBIDList> getLocalities(DBIDs medoids, Relation<V> database, DistanceQuery<V> distFunc, RangeQuery<V> rangeQuery) {
+ WritableDataStore<DoubleDBIDList> result = DataStoreUtil.makeStorage(medoids, DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, DoubleDBIDList.class);
- for (DBIDIter iter = medoids.iter(); iter.valid(); iter.advance()) {
- DBID m = DBIDUtil.deref(iter);
+ for(DBIDIter iter = medoids.iter(); iter.valid(); iter.advance()) {
// determine minimum distance between current medoid m and any other
// medoid m_i
- DoubleDistance minDist = null;
- for (DBIDIter iter2 = medoids.iter(); iter2.valid(); iter2.advance()) {
- DBID m_i = DBIDUtil.deref(iter2);
- if (DBIDUtil.equal(m_i, m)) {
+ double minDist = Double.POSITIVE_INFINITY;
+ for(DBIDIter iter2 = medoids.iter(); iter2.valid(); iter2.advance()) {
+ if(DBIDUtil.equal(iter, iter2)) {
continue;
}
- DoubleDistance currentDist = distFunc.distance(m, m_i);
- if (minDist == null || currentDist.compareTo(minDist) < 0) {
+ double currentDist = distFunc.distance(iter, iter2);
+ if(currentDist < minDist) {
minDist = currentDist;
}
}
// determine points in sphere centered at m with radius minDist
- assert minDist != null;
- DistanceDBIDList<DoubleDistance> qr = rangeQuery.getRangeForDBID(m, minDist);
- result.put(m, qr);
+ assert minDist != Double.POSITIVE_INFINITY;
+ DoubleDBIDList qr = rangeQuery.getRangeForDBID(iter, minDist);
+ result.put(iter, qr);
}
return result;
@@ -395,68 +395,67 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
* @return the set of correlated dimensions for each medoid in the specified
* medoid set
*/
- private Map<DBID, TIntSet> findDimensions(DBIDs medoids, Relation<V> database, DistanceQuery<V, DoubleDistance> distFunc, RangeQuery<V, DoubleDistance> rangeQuery) {
+ private TIntSet[] findDimensions(ArrayDBIDs medoids, Relation<V> database, DistanceQuery<V> distFunc, RangeQuery<V> rangeQuery) {
// get localities
- Map<DBID, DistanceDBIDList<DoubleDistance>> localities = getLocalities(medoids, database, distFunc, rangeQuery);
+ DataStore<DoubleDBIDList> localities = getLocalities(medoids, database, distFunc, rangeQuery);
// compute x_ij = avg distance from points in l_i to medoid m_i
int dim = RelationUtil.dimensionality(database);
- Map<DBID, double[]> averageDistances = new HashMap<>();
+ double[][] averageDistances = new double[medoids.size()][];
- for (DBIDIter iter = medoids.iter(); iter.valid(); iter.advance()) {
- DBID m_i = DBIDUtil.deref(iter);
- V medoid_i = database.get(m_i);
- DistanceDBIDList<DoubleDistance> l_i = localities.get(m_i);
+ int i = 0;
+ for(DBIDArrayIter iter = medoids.iter(); iter.valid(); iter.advance(), i++) {
+ V medoid_i = database.get(iter);
+ DoubleDBIDList l_i = localities.get(iter);
double[] x_i = new double[dim];
- for (DBIDIter qr = l_i.iter(); qr.valid(); qr.advance()) {
+ for(DBIDIter qr = l_i.iter(); qr.valid(); qr.advance()) {
V o = database.get(qr);
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
x_i[d] += Math.abs(medoid_i.doubleValue(d) - o.doubleValue(d));
}
}
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
x_i[d] /= l_i.size();
}
- averageDistances.put(m_i, x_i);
+ averageDistances[i] = x_i;
}
- Map<DBID, TIntSet> dimensionMap = new HashMap<>();
- List<CTriple<Double, DBID, Integer>> z_ijs = new ArrayList<>();
- for (DBIDIter iter = medoids.iter(); iter.valid(); iter.advance()) {
- DBID m_i = DBIDUtil.deref(iter);
+ TIntSet[] dimensionMap = new TIntSet[medoids.size()];
+ List<DoubleIntInt> z_ijs = new ArrayList<>();
+ for(i = 0; i < medoids.size(); i++) {
TIntSet dims_i = new TIntHashSet();
- dimensionMap.put(m_i, dims_i);
+ dimensionMap[i] = dims_i;
- double[] x_i = averageDistances.get(m_i);
+ double[] x_i = averageDistances[i];
// y_i
double y_i = 0;
- for (int j = 0; j < dim; j++) {
+ for(int j = 0; j < dim; j++) {
y_i += x_i[j];
}
y_i /= dim;
// sigma_i
double sigma_i = 0;
- for (int j = 0; j < dim; j++) {
+ for(int j = 0; j < dim; j++) {
double diff = x_i[j] - y_i;
sigma_i += diff * diff;
}
sigma_i /= (dim - 1);
sigma_i = Math.sqrt(sigma_i);
- for (int j = 0; j < dim; j++) {
- z_ijs.add(new CTriple<>((x_i[j] - y_i) / sigma_i, m_i, j));
+ for(int j = 0; j < dim; j++) {
+ z_ijs.add(new DoubleIntInt((x_i[j] - y_i) / sigma_i, i, j));
}
}
Collections.sort(z_ijs);
int max = Math.max(k * l, 2);
- for (int m = 0; m < max; m++) {
- CTriple<Double, DBID, Integer> z_ij = z_ijs.get(m);
- TIntSet dims_i = dimensionMap.get(z_ij.getSecond());
- dims_i.add(z_ij.getThird());
+ for(int m = 0; m < max; m++) {
+ DoubleIntInt z_ij = z_ijs.get(m);
+ TIntSet dims_i = dimensionMap[z_ij.dimi];
+ dims_i.add(z_ij.dimj);
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
StringBuilder msg = new StringBuilder();
msg.append('\n');
msg.append("z_ij ").append(z_ij).append('\n');
@@ -476,64 +475,65 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
* @return the set of correlated dimensions for each specified cluster
* centroid
*/
- private List<Pair<V, TIntSet>> findDimensions(List<PROCLUSCluster> clusters, Relation<V> database) {
+ private List<Pair<Vector, TIntSet>> findDimensions(ArrayList<PROCLUSCluster> clusters, Relation<V> database) {
// compute x_ij = avg distance from points in c_i to c_i.centroid
int dim = RelationUtil.dimensionality(database);
- Map<Integer, double[]> averageDistances = new HashMap<>();
+ final int numc = clusters.size();
+ double[][] averageDistances = new double[numc][];
- for (int i = 0; i < clusters.size(); i++) {
+ for(int i = 0; i < numc; i++) {
PROCLUSCluster c_i = clusters.get(i);
double[] x_i = new double[dim];
- for (DBIDIter iter = c_i.objectIDs.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = c_i.objectIDs.iter(); iter.valid(); iter.advance()) {
V o = database.get(iter);
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
x_i[d] += Math.abs(c_i.centroid.doubleValue(d) - o.doubleValue(d));
}
}
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
x_i[d] /= c_i.objectIDs.size();
}
- averageDistances.put(i, x_i);
+ averageDistances[i] = x_i;
}
- List<CTriple<Double, Integer, Integer>> z_ijs = new ArrayList<>();
- for (int i = 0; i < clusters.size(); i++) {
- double[] x_i = averageDistances.get(i);
+ List<DoubleIntInt> z_ijs = new ArrayList<>();
+ for(int i = 0; i < numc; i++) {
+ double[] x_i = averageDistances[i];
// y_i
double y_i = 0;
- for (int j = 0; j < dim; j++) {
+ for(int j = 0; j < dim; j++) {
y_i += x_i[j];
}
y_i /= dim;
// sigma_i
double sigma_i = 0;
- for (int j = 0; j < dim; j++) {
+ for(int j = 0; j < dim; j++) {
double diff = x_i[j] - y_i;
sigma_i += diff * diff;
}
sigma_i /= (dim - 1);
sigma_i = Math.sqrt(sigma_i);
- for (int j = 0; j < dim; j++) {
- z_ijs.add(new CTriple<>((x_i[j] - y_i) / sigma_i, i, j));
+ for(int j = 0; j < dim; j++) {
+ z_ijs.add(new DoubleIntInt((x_i[j] - y_i) / sigma_i, i, j));
}
}
Collections.sort(z_ijs);
// mapping cluster index -> dimensions
- Map<Integer, TIntSet> dimensionMap = new HashMap<>();
+ TIntSet[] dimensionMap = new TIntSet[numc];
int max = Math.max(k * l, 2);
- for (int m = 0; m < max; m++) {
- CTriple<Double, Integer, Integer> z_ij = z_ijs.get(m);
- TIntSet dims_i = dimensionMap.get(z_ij.getSecond());
- if (dims_i == null) {
+ for(int m = 0; m < max; m++) {
+ DoubleIntInt z_ij = z_ijs.get(m);
+ TIntSet dims_i = dimensionMap[z_ij.dimi];
+ if(dims_i == null) {
dims_i = new TIntHashSet();
- dimensionMap.put(z_ij.getSecond(), dims_i);
+ dimensionMap[z_ij.dimi] = dims_i;
}
- dims_i.add(z_ij.getThird());
+ dims_i.add(z_ij.dimj);
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
StringBuilder msg = new StringBuilder();
msg.append('\n');
msg.append("z_ij ").append(z_ij).append('\n');
@@ -543,9 +543,12 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
}
// mapping cluster -> dimensions
- List<Pair<V, TIntSet>> result = new ArrayList<>();
- for (int i : dimensionMap.keySet()) {
- TIntSet dims_i = dimensionMap.get(i);
+ List<Pair<Vector, TIntSet>> result = new ArrayList<>();
+ for(int i = 0; i < numc; i++) {
+ TIntSet dims_i = dimensionMap[i];
+ if(dims_i == null) {
+ continue;
+ }
PROCLUSCluster c_i = clusters.get(i);
result.add(new Pair<>(c_i.centroid, dims_i));
}
@@ -555,45 +558,51 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
/**
* Assigns the objects to the clusters.
*
+ * @param m_current Current centers
* @param dimensions set of correlated dimensions for each medoid of the
* cluster
* @param database the database containing the objects
* @return the assignments of the object to the clusters
*/
- private Map<DBID, PROCLUSCluster> assignPoints(Map<DBID, TIntSet> dimensions, Relation<V> database) {
- Map<DBID, ModifiableDBIDs> clusterIDs = new HashMap<>();
- for (DBID m_i : dimensions.keySet()) {
- clusterIDs.put(m_i, DBIDUtil.newHashSet());
- }
-
- for (DBIDIter it = database.iterDBIDs(); it.valid(); it.advance()) {
- DBID p_id = DBIDUtil.deref(it);
- V p = database.get(p_id);
- DistanceDBIDPair<DoubleDistance> minDist = null;
- for (DBID m_i : dimensions.keySet()) {
+ private ArrayList<PROCLUSCluster> assignPoints(ArrayDBIDs m_current, TIntSet[] dimensions, Relation<V> database) {
+ ModifiableDBIDs[] clusterIDs = new ModifiableDBIDs[dimensions.length];
+ for(int i = 0; i < m_current.size(); i++) {
+ clusterIDs[i] = DBIDUtil.newHashSet();
+ }
+
+ DBIDArrayIter m_i = m_current.iter();
+ for(DBIDIter it = database.iterDBIDs(); it.valid(); it.advance()) {
+ V p = database.get(it);
+ double minDist = Double.NaN;
+ int best = -1, i = 0;
+ for(m_i.seek(0); m_i.valid(); m_i.advance(), i++) {
V m = database.get(m_i);
- DistanceDBIDPair<DoubleDistance> currentDist = DBIDUtil.newDistancePair(manhattanSegmentalDistance(p, m, dimensions.get(m_i)), m_i);
- if (minDist == null || currentDist.compareByDistance(minDist) < 0) {
+ double currentDist = manhattanSegmentalDistance(p, m, dimensions[i]);
+ if(!(minDist <= currentDist)) {
minDist = currentDist;
+ best = i;
}
}
// add p to cluster with mindist
- assert minDist != null;
- ModifiableDBIDs ids = clusterIDs.get(DBIDUtil.deref(minDist));
- ids.add(p_id);
+ assert best >= 0;
+ ModifiableDBIDs ids = clusterIDs[best];
+ ids.add(it);
}
- Map<DBID, PROCLUSCluster> clusters = new HashMap<>();
- for (DBID m_i : dimensions.keySet()) {
- ModifiableDBIDs objectIDs = clusterIDs.get(m_i);
- if (!objectIDs.isEmpty()) {
- TIntSet clusterDimensions = dimensions.get(m_i);
- V centroid = Centroid.make(database, objectIDs).toVector(database);
- clusters.put(m_i, new PROCLUSCluster(objectIDs, clusterDimensions, centroid));
+ ArrayList<PROCLUSCluster> clusters = new ArrayList<>(m_current.size());
+ for(int i = 0; i < dimensions.length; i++) {
+ ModifiableDBIDs objectIDs = clusterIDs[i];
+ if(!objectIDs.isEmpty()) {
+ TIntSet clusterDimensions = dimensions[i];
+ Vector centroid = Centroid.make(database, objectIDs);
+ clusters.add(new PROCLUSCluster(objectIDs, clusterDimensions, centroid));
+ }
+ else {
+ clusters.add(null);
}
}
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
StringBuilder msg = new StringBuilder();
msg.append('\n');
msg.append("clusters ").append(clusters).append('\n');
@@ -610,42 +619,43 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
* @param database the database containing the objects
* @return the assignments of the object to the clusters
*/
- private List<PROCLUSCluster> finalAssignment(List<Pair<V, TIntSet>> dimensions, Relation<V> database) {
+ private List<PROCLUSCluster> finalAssignment(List<Pair<Vector, TIntSet>> dimensions, Relation<V> database) {
Map<Integer, ModifiableDBIDs> clusterIDs = new HashMap<>();
- for (int i = 0; i < dimensions.size(); i++) {
+ for(int i = 0; i < dimensions.size(); i++) {
clusterIDs.put(i, DBIDUtil.newHashSet());
}
- for (DBIDIter it = database.iterDBIDs(); it.valid(); it.advance()) {
- DBID p_id = DBIDUtil.deref(it);
- V p = database.get(p_id);
- Pair<DoubleDistance, Integer> minDist = null;
- for (int i = 0; i < dimensions.size(); i++) {
- Pair<V, TIntSet> pair_i = dimensions.get(i);
- V c_i = pair_i.first;
+ for(DBIDIter it = database.iterDBIDs(); it.valid(); it.advance()) {
+ V p = database.get(it);
+ double minDist = Double.POSITIVE_INFINITY;
+ int best = -1;
+ for(int i = 0; i < dimensions.size(); i++) {
+ Pair<Vector, TIntSet> pair_i = dimensions.get(i);
+ Vector c_i = pair_i.first;
TIntSet dimensions_i = pair_i.second;
- DoubleDistance currentDist = manhattanSegmentalDistance(p, c_i, dimensions_i);
- if (minDist == null || currentDist.compareTo(minDist.first) < 0) {
- minDist = new Pair<>(currentDist, i);
+ double currentDist = manhattanSegmentalDistance(p, c_i, dimensions_i);
+ if(best < 0 || currentDist < minDist) {
+ minDist = currentDist;
+ best = i;
}
}
// add p to cluster with mindist
- assert minDist != null;
- ModifiableDBIDs ids = clusterIDs.get(minDist.second);
- ids.add(p_id);
+ assert minDist >= 0.;
+ ModifiableDBIDs ids = clusterIDs.get(best);
+ ids.add(it);
}
List<PROCLUSCluster> clusters = new ArrayList<>();
- for (int i = 0; i < dimensions.size(); i++) {
+ for(int i = 0; i < dimensions.size(); i++) {
ModifiableDBIDs objectIDs = clusterIDs.get(i);
- if (!objectIDs.isEmpty()) {
+ if(!objectIDs.isEmpty()) {
TIntSet clusterDimensions = dimensions.get(i).second;
- V centroid = Centroid.make(database, objectIDs).toVector(database);
+ Vector centroid = Centroid.make(database, objectIDs);
clusters.add(new PROCLUSCluster(objectIDs, clusterDimensions, centroid));
}
}
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
StringBuilder msg = new StringBuilder();
msg.append('\n');
msg.append("clusters ").append(clusters).append('\n');
@@ -664,14 +674,14 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
* @return the Manhattan segmental distance between o1 and o2 relative to the
* specified dimensions
*/
- private DoubleDistance manhattanSegmentalDistance(V o1, V o2, TIntSet dimensions) {
+ private double manhattanSegmentalDistance(NumberVector o1, NumberVector o2, TIntSet dimensions) {
double result = 0;
- for (TIntIterator iter = dimensions.iterator(); iter.hasNext();) {
+ for(TIntIterator iter = dimensions.iterator(); iter.hasNext();) {
final int d = iter.next();
result += Math.abs(o1.doubleValue(d) - o2.doubleValue(d));
}
result /= dimensions.size();
- return new DoubleDistance(result);
+ return result;
}
/**
@@ -682,20 +692,20 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
* @param database the database holding the objects
* @return a measure for the cluster quality
*/
- private double evaluateClusters(Map<DBID, PROCLUSCluster> clusters, Map<DBID, TIntSet> dimensions, Relation<V> database) {
+ private double evaluateClusters(ArrayList<PROCLUSCluster> clusters, TIntSet[] dimensions, Relation<V> database) {
double result = 0;
- for (DBID m_i : clusters.keySet()) {
- PROCLUSCluster c_i = clusters.get(m_i);
- V centroid_i = c_i.centroid;
+ for(int i = 0; i < dimensions.length; i++) {
+ PROCLUSCluster c_i = clusters.get(i);
+ Vector centroid_i = c_i.centroid;
- TIntSet dims_i = dimensions.get(m_i);
+ TIntSet dims_i = dimensions[i];
double w_i = 0;
- for (TIntIterator iter = dims_i.iterator(); iter.hasNext();) {
+ for(TIntIterator iter = dims_i.iterator(); iter.hasNext();) {
final int j = iter.next();
w_i += avgDistance(centroid_i, c_i.objectIDs, database, j);
}
- w_i /= dimensions.keySet().size();
+ w_i /= dimensions.length;
result += c_i.objectIDs.size() * w_i;
}
@@ -713,9 +723,9 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
* @return the average distance of the objects to the centroid along the
* specified dimension
*/
- private double avgDistance(V centroid, DBIDs objectIDs, Relation<V> database, int dimension) {
+ private double avgDistance(Vector centroid, DBIDs objectIDs, Relation<V> database, int dimension) {
Mean avg = new Mean();
- for (DBIDIter iter = objectIDs.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = objectIDs.iter(); iter.valid(); iter.advance()) {
V o = database.get(iter);
avg.put(Math.abs(centroid.doubleValue(dimension) - o.doubleValue(dimension)));
}
@@ -726,16 +736,18 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
* Computes the bad medoids, where the medoid of a cluster with less than the
* specified threshold of objects is bad.
*
+ * @param m_current Current medoids
* @param clusters the clusters
* @param threshold the threshold
* @return the bad medoids
*/
- private ModifiableDBIDs computeBadMedoids(Map<DBID, PROCLUSCluster> clusters, int threshold) {
- ModifiableDBIDs badMedoids = DBIDUtil.newHashSet();
- for (DBID m_i : clusters.keySet()) {
- PROCLUSCluster c_i = clusters.get(m_i);
- if (c_i.objectIDs.size() < threshold) {
- badMedoids.add(m_i);
+ private DBIDs computeBadMedoids(ArrayDBIDs m_current, ArrayList<PROCLUSCluster> clusters, int threshold) {
+ ModifiableDBIDs badMedoids = DBIDUtil.newHashSet(m_current.size());
+ int i = 0;
+ for(DBIDIter it = m_current.iter(); it.valid(); it.advance(), i++) {
+ PROCLUSCluster c_i = clusters.get(i);
+ if(c_i == null || c_i.objectIDs.size() < threshold) {
+ badMedoids.add(it);
}
}
return badMedoids;
@@ -752,6 +764,36 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
}
/**
+ * Simple triple.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ private static class DoubleIntInt implements Comparable<DoubleIntInt> {
+ protected double first;
+
+ protected int dimi, dimj;
+
+ public DoubleIntInt(double first, int second, int third) {
+ this.first = first;
+ this.dimi = second;
+ this.dimj = third;
+ }
+
+ @Override
+ public int compareTo(DoubleIntInt o) {
+ if(this.first < o.first) {
+ return -1;
+ }
+ if(this.first > o.first) {
+ return +1;
+ }
+ return 0;
+ }
+ }
+
+ /**
* Encapsulates the attributes of a cluster.
*
* @apiviz.exclude
@@ -770,16 +812,16 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
/**
* The centroids of this cluster along each dimension.
*/
- V centroid;
+ Vector centroid;
/**
- * Provides a new cluster with the specified parameters.
+ * Constructor.
*
* @param objectIDs the ids of the objects belonging to this cluster
* @param dimensions the correlated dimensions of this cluster
* @param centroid the centroid of this cluster
*/
- public PROCLUSCluster(ModifiableDBIDs objectIDs, TIntSet dimensions, V centroid) {
+ public PROCLUSCluster(ModifiableDBIDs objectIDs, TIntSet dimensions, Vector centroid) {
this.objectIDs = objectIDs;
this.dimensions = dimensions;
this.centroid = centroid;
@@ -790,10 +832,11 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
StringBuilder result = new StringBuilder();
result.append("Dimensions: [");
boolean notFirst = false;
- for (TIntIterator iter = dimensions.iterator(); iter.hasNext();) {
- if (notFirst) {
+ for(TIntIterator iter = dimensions.iterator(); iter.hasNext();) {
+ if(notFirst) {
result.append(',');
- } else {
+ }
+ else {
notFirst = true;
}
result.append(iter.next());
@@ -809,10 +852,15 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
*
* @return the correlated dimensions of this cluster as BitSet
*/
- public BitSet getDimensions() {
- BitSet result = new BitSet();
- for (TIntIterator iter = dimensions.iterator(); iter.hasNext();) {
- result.set(iter.next());
+ public long[] getDimensions() {
+ int maxdim = 0;
+ for(TIntIterator iter = dimensions.iterator(); iter.hasNext();) {
+ int d = iter.next();
+ maxdim = (d > maxdim) ? d : maxdim;
+ }
+ long[] result = BitsUtil.zero(maxdim);
+ for(TIntIterator iter = dimensions.iterator(); iter.hasNext();) {
+ BitsUtil.setI(result, iter.next());
}
return result;
}
@@ -825,14 +873,32 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractProjectedClustering.Parameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractProjectedClustering.Parameterizer {
+ /**
+ * Parameter to specify the multiplier for the initial number of medoids,
+ * must be an integer greater than 0.
+ * <p>
+ * Default value: {@code 10}
+ * </p>
+ * <p>
+ * Key: {@code -proclus.mi}
+ * </p>
+ */
+ public static final OptionID M_I_ID = new OptionID("proclus.mi", "The multiplier for the initial number of medoids.");
+
/**
* Parameter to specify the random generator seed.
*/
public static final OptionID SEED_ID = new OptionID("proclus.seed", "The random number generator seed.");
+ /**
+ * Multiplier for the initial number of medoids.
+ */
protected int m_i = -1;
+ /**
+ * Random generator
+ */
protected RandomFactory rnd;
@Override
@@ -843,14 +909,14 @@ public class PROCLUS<V extends NumberVector<?>> extends AbstractProjectedCluster
configKI(config);
configL(config);
- IntParameter m_iP = new IntParameter(M_I_ID, 10);
- m_iP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
- if (config.grab(m_iP)) {
+ IntParameter m_iP = new IntParameter(M_I_ID, 10) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(m_iP)) {
m_i = m_iP.getValue();
}
RandomParameter rndP = new RandomParameter(SEED_ID);
- if (config.grab(rndP)) {
+ if(config.grab(rndP)) {
rnd = rndP.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/PreDeCon.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/PreDeCon.java
index 4e670974..a61935b0 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/PreDeCon.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/PreDeCon.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.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,42 +23,50 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.algorithm.clustering.AbstractProjectedDBSCAN;
-import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.GeneralizedDBSCAN;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.PreDeConCorePredicate;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.PreDeConNeighborPredicate;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.model.Model;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj.PreDeConSubspaceIndex;
import de.lmu.ifi.dbs.elki.logging.Logging;
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;
+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.DoubleParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
/**
- * <p/>
* PreDeCon computes clusters of subspace preference weighted connected points.
* The algorithm searches for local subgroups of a set of feature vectors having
* a low variance along one or more (but not all) attributes.
- * </p>
- * <p/>
- * Reference: <br>
- * C. Böhm, K. Kailing, H.-P. Kriegel, P. Kröger: Density Connected Clustering
- * with Local Subspace Preferences. <br>
+ *
+ * Reference:
+ * <p>
+ * C. Böhm, K. Kailing, H.-P. Kriegel, P. Kröger:<br />
+ * Density Connected Clustering with Local Subspace Preferences.<br />
* In Proc. 4th IEEE Int. Conf. on Data Mining (ICDM'04), Brighton, UK, 2004.
* </p>
*
* @author Peer Kröger
*
- * @apiviz.uses PreDeConSubspaceIndex
+ * @apiviz.has PreDeCon.Settings
+ * @apiviz.composedOf PreDeConNeighborPredicate
+ * @apiviz.composedOf PreDeConCorePredicate
*
* @param <V> the type of NumberVector handled by this Algorithm
*/
@Title("PreDeCon: Subspace Preference weighted Density Connected Clustering")
-@Description("PreDeCon computes clusters of subspace preference weighted connected points. " + "The algorithm searches for local subgroups of a set of feature vectors having " + "a low variance along one or more (but not all) attributes.")
-@Reference(authors = "C. Böhm, K. Kailing, H.-P. Kriegel, P. Kröger", title = "Density Connected Clustering with Local Subspace Preferences", booktitle = "Proc. 4th IEEE Int. Conf. on Data Mining (ICDM'04), Brighton, UK, 2004", url = "http://dx.doi.org/10.1109/ICDM.2004.10087")
-public class PreDeCon<V extends NumberVector<?>> extends AbstractProjectedDBSCAN<Clustering<Model>, V> {
+@Description("PreDeCon computes clusters of subspace preference weighted connected points. "//
+ + "The algorithm searches for local subgroups of a set of feature vectors having " + "a low variance along one or more (but not all) attributes.")
+@Reference(authors = "C. Böhm, K. Kailing, H.-P. Kriegel, P. Kröger", //
+title = "Density Connected Clustering with Local Subspace Preferences", //
+booktitle = "Proc. 4th IEEE Int. Conf. on Data Mining (ICDM'04), Brighton, UK, 2004", //
+url = "http://dx.doi.org/10.1109/ICDM.2004.10087")
+public class PreDeCon<V extends NumberVector> extends GeneralizedDBSCAN {
/**
* The logger for this class.
*/
@@ -67,28 +75,165 @@ public class PreDeCon<V extends NumberVector<?>> extends AbstractProjectedDBSCAN
/**
* Constructor.
*
- * @param epsilon Epsilon value
- * @param minpts MinPts value
- * @param distanceFunction outer distance function
- * @param lambda Lambda value
+ * @param settings PreDeCon settings.
*/
- public PreDeCon(DoubleDistance epsilon, int minpts, LocallyWeightedDistanceFunction<V> distanceFunction, int lambda) {
- super(epsilon, minpts, distanceFunction, lambda);
+ public PreDeCon(PreDeCon.Settings settings) {
+ super(new PreDeConNeighborPredicate<>(settings), new PreDeConCorePredicate(settings), false);
}
@Override
- public String getLongResultName() {
- return "PreDeCon Clustering";
+ protected Logging getLogger() {
+ return LOG;
}
- @Override
- public String getShortResultName() {
- return "predecon-clustering";
- }
+ /**
+ * Class containing all the PreDeCon settings.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Settings {
+ /**
+ * Query radius parameter epsilon.
+ */
+ public double epsilon;
- @Override
- protected Logging getLogger() {
- return LOG;
+ /**
+ * The threshold for small eigenvalues.
+ */
+ public double delta;
+
+ /**
+ * The kappa penality factor for deviations in preferred dimensions.
+ */
+ public double kappa = Parameterizer.KAPPA_DEFAULT;
+
+ /**
+ * DBSCAN Minpts parameter, aka "mu".
+ */
+ public int minpts;
+
+ /**
+ * Lambda: Maximum subspace dimensionality.
+ */
+ public int lambda = Integer.MAX_VALUE;
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Parameter Delta: maximum variance allowed
+ */
+ public static final OptionID DELTA_ID = new OptionID("predecon.delta", "A double specifying the variance threshold for small Eigenvalues.");
+
+ /**
+ * Parameter Kappa: penalty for deviations in preferred dimensions.
+ */
+ public static final OptionID KAPPA_ID = new OptionID("predecon.kappa", "Penalty factor for deviations in preferred (low-variance) dimensions.");
+
+ /**
+ * Default for kappa parameter.
+ */
+ public static final double KAPPA_DEFAULT = 20.;
+
+ /**
+ * Parameter Lambda: maximum dimensionality allowed.
+ */
+ public static final OptionID LAMBDA_ID = new OptionID("predecon.lambda", "Maximum dimensionality to consider for core points.");
+
+ /**
+ * Settings to build.
+ */
+ Settings settings;
+
+ @Override
+ public void makeOptions(Parameterization config) {
+ settings = new Settings();
+ configEpsilon(config);
+ configMinPts(config);
+ configDelta(config);
+ configKappa(config);
+ configLambda(config);
+ }
+
+ /**
+ * Configure the epsilon radius parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configEpsilon(Parameterization config) {
+ DoubleParameter epsilonP = new DoubleParameter(DBSCAN.Parameterizer.EPSILON_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ if(config.grab(epsilonP)) {
+ settings.epsilon = epsilonP.doubleValue();
+ }
+ }
+
+ /**
+ * Configure the minPts aka "mu" parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configMinPts(Parameterization config) {
+ IntParameter minptsP = new IntParameter(DBSCAN.Parameterizer.MINPTS_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(minptsP)) {
+ settings.minpts = minptsP.intValue();
+ }
+ }
+
+ /**
+ * Configure the delta parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configDelta(Parameterization config) {
+ DoubleParameter deltaP = new DoubleParameter(DELTA_ID) //
+ .addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ if(config.grab(deltaP)) {
+ settings.delta = deltaP.doubleValue();
+ }
+ }
+
+ /**
+ * Configure the kappa parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configKappa(Parameterization config) {
+ DoubleParameter kappaP = new DoubleParameter(KAPPA_ID) //
+ .addConstraint(CommonConstraints.GREATER_THAN_ONE_DOUBLE) //
+ .setDefaultValue(KAPPA_DEFAULT);
+ if(config.grab(kappaP)) {
+ settings.kappa = kappaP.doubleValue();
+ }
+ }
+
+ /**
+ * Configure the delta parameter.
+ *
+ * @param config Parameter source
+ */
+ protected void configLambda(Parameterization config) {
+ IntParameter lambdaP = new IntParameter(LAMBDA_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT) //
+ .setOptional(true);
+ if(config.grab(lambdaP)) {
+ settings.lambda = lambdaP.intValue();
+ }
+ }
+
+ @Override
+ public Settings makeInstance() {
+ return settings;
+ }
+ }
}
/**
@@ -98,20 +243,20 @@ public class PreDeCon<V extends NumberVector<?>> extends AbstractProjectedDBSCAN
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractProjectedDBSCAN.Parameterizer<V, DoubleDistance> {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * PreDeConSettings.
+ */
+ protected PreDeCon.Settings settings;
+
@Override
protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- configInnerDistance(config);
- configEpsilon(config, innerdist);
- configMinPts(config);
- configOuterDistance(config, epsilon, minpts, PreDeConSubspaceIndex.Factory.class, innerdist);
- configLambda(config);
+ settings = config.tryInstantiate(PreDeCon.Settings.class);
}
@Override
protected PreDeCon<V> makeInstance() {
- return new PreDeCon<>(epsilon, minpts, outerdist, lambda);
+ return new PreDeCon<>(settings);
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/SUBCLU.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/SUBCLU.java
index e6245f6e..d6cf40fd 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/SUBCLU.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/SUBCLU.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.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
@@ -24,7 +24,6 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace;
*/
import java.util.ArrayList;
-import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
import java.util.TreeMap;
@@ -45,10 +44,10 @@ 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.distancefunction.subspace.DimensionSelectingSubspaceDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Centroid;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
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;
@@ -56,7 +55,7 @@ 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.DistanceParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
@@ -69,8 +68,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* </p>
* <p>
* Reference: <br>
- * K. Kailing, H.-P. Kriegel, P. Kroeger: Density connected Subspace Clustering
- * for High Dimensional Data. <br>
+ * K. Kailing, H.-P. Kriegel, P. Kröger:<br />
+ * Density connected Subspace Clustering for High Dimensional Data<br />
* In Proc. SIAM Int. Conf. on Data Mining (SDM'04), Lake Buena Vista, FL, 2004.
* </p>
*
@@ -83,9 +82,14 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @param <V> the type of FeatureVector handled by this Algorithm
*/
@Title("SUBCLU: Density connected Subspace Clustering")
-@Description("Algorithm to detect arbitrarily shaped and positioned clusters in subspaces. SUBCLU delivers for each subspace the same clusters DBSCAN would have found, when applied to this subspace seperately.")
-@Reference(authors = "K. Kailing, H.-P. Kriegel, P. Kröger", title = "Density connected Subspace Clustering for High Dimensional Data. ", booktitle = "Proc. SIAM Int. Conf. on Data Mining (SDM'04), Lake Buena Vista, FL, 2004")
-public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Clustering<SubspaceModel<V>>> implements SubspaceClusteringAlgorithm<SubspaceModel<V>> {
+@Description("Algorithm to detect arbitrarily shaped and positioned clusters in subspaces. "//
+ + "SUBCLU delivers for each subspace the same clusters DBSCAN would have found, "//
+ + "when applied to this subspace seperately.")
+@Reference(authors = "K. Kailing, H.-P. Kriegel, P. Kröger", //
+title = "Density connected Subspace Clustering for High Dimensional Data", //
+booktitle = "Proc. SIAM Int. Conf. on Data Mining (SDM'04), Lake Buena Vista, FL, 2004", //
+url = "http://www.siam.org/meetings/sdm04/proceedings/sdm04_023.pdf")
+public class SUBCLU<V extends NumberVector> extends AbstractAlgorithm<Clustering<SubspaceModel>> implements SubspaceClusteringAlgorithm<SubspaceModel> {
/**
* The logger for this class.
*/
@@ -125,12 +129,12 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
* Holds the instance of the distance function specified by
* {@link #DISTANCE_FUNCTION_ID}.
*/
- private DimensionSelectingSubspaceDistanceFunction<V, DoubleDistance> distanceFunction;
+ private DimensionSelectingSubspaceDistanceFunction<V> distanceFunction;
/**
* Holds the value of {@link #EPSILON_ID}.
*/
- private DoubleDistance epsilon;
+ private double epsilon;
/**
* Holds the value of {@link #MINPTS_ID}.
@@ -140,7 +144,7 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
/**
* Holds the result;
*/
- private Clustering<SubspaceModel<V>> result;
+ private Clustering<SubspaceModel> result;
/**
* Constructor.
@@ -149,7 +153,7 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
* @param epsilon Epsilon value
* @param minpts Minpts value
*/
- public SUBCLU(DimensionSelectingSubspaceDistanceFunction<V, DoubleDistance> distanceFunction, DoubleDistance epsilon, int minpts) {
+ public SUBCLU(DimensionSelectingSubspaceDistanceFunction<V> distanceFunction, double epsilon, int minpts) {
super();
this.distanceFunction = distanceFunction;
this.epsilon = epsilon;
@@ -162,15 +166,13 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
* @param relation Relation to process
* @return Clustering result
*/
- public Clustering<SubspaceModel<V>> run(Relation<V> relation) {
+ public Clustering<SubspaceModel> run(Relation<V> relation) {
final int dimensionality = RelationUtil.dimensionality(relation);
StepProgress stepprog = LOG.isVerbose() ? new StepProgress(dimensionality) : null;
// Generate all 1-dimensional clusters
- if (stepprog != null) {
- stepprog.beginStep(1, "Generate all 1-dimensional clusters.", LOG);
- }
+ LOG.beginStep(stepprog, 1, "Generate all 1-dimensional clusters.");
// mapping of dimensionality to set of subspaces
HashMap<Integer, List<Subspace>> subspaceMap = new HashMap<>();
@@ -182,35 +184,35 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
// mapping of subspaces to list of clusters
TreeMap<Subspace, List<Cluster<Model>>> clusterMap = new TreeMap<>(new Subspace.DimensionComparator());
- for (int d = 0; d < dimensionality; d++) {
+ for(int d = 0; d < dimensionality; d++) {
Subspace currentSubspace = new Subspace(d);
List<Cluster<Model>> clusters = runDBSCAN(relation, null, currentSubspace);
- if (LOG.isDebuggingFiner()) {
+ if(LOG.isDebuggingFiner()) {
StringBuilder msg = new StringBuilder();
msg.append('\n').append(clusters.size()).append(" clusters in subspace ").append(currentSubspace.dimensonsToString()).append(": \n");
- for (Cluster<Model> cluster : clusters) {
+ for(Cluster<Model> cluster : clusters) {
msg.append(" " + cluster.getIDs() + "\n");
}
LOG.debugFiner(msg.toString());
}
- if (!clusters.isEmpty()) {
+ if(!clusters.isEmpty()) {
s_1.add(currentSubspace);
clusterMap.put(currentSubspace, clusters);
}
}
// Generate (d+1)-dimensional clusters from d-dimensional clusters
- for (int d = 0; d < dimensionality - 1; d++) {
- if (stepprog != null) {
+ for(int d = 0; d < dimensionality - 1; d++) {
+ if(stepprog != null) {
stepprog.beginStep(d + 2, "Generate " + (d + 2) + "-dimensional clusters from " + (d + 1) + "-dimensional clusters.", LOG);
}
List<Subspace> subspaces = subspaceMap.get(d);
- if (subspaces == null || subspaces.isEmpty()) {
- if (stepprog != null) {
- for (int dim = d + 1; dim < dimensionality - 1; dim++) {
+ if(subspaces == null || subspaces.isEmpty()) {
+ if(stepprog != null) {
+ for(int dim = d + 1; dim < dimensionality - 1; dim++) {
stepprog.beginStep(dim + 2, "Generation of" + (dim + 2) + "-dimensional clusters not applicable, because no more " + (d + 2) + "-dimensional subspaces found.", LOG);
}
}
@@ -220,37 +222,37 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
List<Subspace> candidates = generateSubspaceCandidates(subspaces);
List<Subspace> s_d = new ArrayList<>();
- for (Subspace candidate : candidates) {
+ for(Subspace candidate : candidates) {
Subspace bestSubspace = bestSubspace(subspaces, candidate, clusterMap);
- if (LOG.isDebuggingFine()) {
+ if(LOG.isDebuggingFine()) {
LOG.debugFine("best subspace of " + candidate.dimensonsToString() + ": " + bestSubspace.dimensonsToString());
}
List<Cluster<Model>> bestSubspaceClusters = clusterMap.get(bestSubspace);
List<Cluster<Model>> clusters = new ArrayList<>();
- for (Cluster<Model> cluster : bestSubspaceClusters) {
+ for(Cluster<Model> cluster : bestSubspaceClusters) {
List<Cluster<Model>> candidateClusters = runDBSCAN(relation, cluster.getIDs(), candidate);
- if (!candidateClusters.isEmpty()) {
+ if(!candidateClusters.isEmpty()) {
clusters.addAll(candidateClusters);
}
}
- if (LOG.isDebuggingFine()) {
+ if(LOG.isDebuggingFine()) {
StringBuilder msg = new StringBuilder();
msg.append(clusters.size() + " cluster(s) in subspace " + candidate + ": \n");
- for (Cluster<Model> c : clusters) {
+ for(Cluster<Model> c : clusters) {
msg.append(" " + c.getIDs() + "\n");
}
LOG.debugFine(msg.toString());
}
- if (!clusters.isEmpty()) {
+ if(!clusters.isEmpty()) {
s_d.add(candidate);
clusterMap.put(candidate, clusters);
}
}
- if (!s_d.isEmpty()) {
+ if(!s_d.isEmpty()) {
subspaceMap.put(d + 1, s_d);
}
}
@@ -258,19 +260,17 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
// build result
int numClusters = 1;
result = new Clustering<>("SUBCLU clustering", "subclu-clustering");
- for (Subspace subspace : clusterMap.descendingKeySet()) {
+ for(Subspace subspace : clusterMap.descendingKeySet()) {
List<Cluster<Model>> clusters = clusterMap.get(subspace);
- for (Cluster<Model> cluster : clusters) {
- Cluster<SubspaceModel<V>> newCluster = new Cluster<>(cluster.getIDs());
- newCluster.setModel(new SubspaceModel<>(subspace, Centroid.make(relation, cluster.getIDs()).toVector(relation)));
+ for(Cluster<Model> cluster : clusters) {
+ Cluster<SubspaceModel> newCluster = new Cluster<>(cluster.getIDs());
+ newCluster.setModel(new SubspaceModel(subspace, Centroid.make(relation, cluster.getIDs())));
newCluster.setName("cluster_" + numClusters++);
result.addToplevelCluster(newCluster);
}
}
- if (stepprog != null) {
- stepprog.setCompleted(LOG);
- }
+ LOG.setCompleted(stepprog);
return result;
}
@@ -279,7 +279,7 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
*
* @return the result of the algorithm
*/
- public Clustering<SubspaceModel<V>> getResult() {
+ public Clustering<SubspaceModel> getResult() {
return result;
}
@@ -300,7 +300,7 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
distanceFunction.setSelectedDimensions(subspace.getDimensions());
ProxyDatabase proxy;
- if (ids == null) {
+ if(ids == null) {
// TODO: in this case, we might want to use an index - the proxy below
// will prevent this!
ids = relation.getDBIDs();
@@ -308,9 +308,9 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
proxy = new ProxyDatabase(ids, relation);
- DBSCAN<V, DoubleDistance> dbscan = new DBSCAN<>(distanceFunction, epsilon, minpts);
+ DBSCAN<V> dbscan = new DBSCAN<>(distanceFunction, epsilon, minpts);
// run DBSCAN
- if (LOG.isVerbose()) {
+ if(LOG.isVerbose()) {
LOG.verbose("\nRun DBSCAN on subspace " + subspace.dimensonsToString());
}
Clustering<Model> dbsres = dbscan.run(proxy);
@@ -318,8 +318,8 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
// separate cluster and noise
List<Cluster<Model>> clusterAndNoise = dbsres.getAllClusters();
List<Cluster<Model>> clusters = new ArrayList<>();
- for (Cluster<Model> c : clusterAndNoise) {
- if (!c.isNoise()) {
+ for(Cluster<Model> c : clusterAndNoise) {
+ if(!c.isNoise()) {
clusters.add(c);
}
}
@@ -336,7 +336,7 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
private List<Subspace> generateSubspaceCandidates(List<Subspace> subspaces) {
List<Subspace> candidates = new ArrayList<>();
- if (subspaces.isEmpty()) {
+ if(subspaces.isEmpty()) {
return candidates;
}
@@ -344,46 +344,46 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
int d = subspaces.get(0).dimensionality();
StringBuilder msgFine = new StringBuilder("\n");
- if (LOG.isDebuggingFiner()) {
+ if(LOG.isDebuggingFiner()) {
msgFine.append("subspaces ").append(subspaces).append('\n');
}
- for (int i = 0; i < subspaces.size(); i++) {
+ for(int i = 0; i < subspaces.size(); i++) {
Subspace s1 = subspaces.get(i);
- for (int j = i + 1; j < subspaces.size(); j++) {
+ for(int j = i + 1; j < subspaces.size(); j++) {
Subspace s2 = subspaces.get(j);
Subspace candidate = s1.join(s2);
- if (candidate != null) {
- if (LOG.isDebuggingFiner()) {
+ if(candidate != null) {
+ if(LOG.isDebuggingFiner()) {
msgFine.append("candidate: ").append(candidate.dimensonsToString()).append('\n');
}
// prune irrelevant candidate subspaces
List<Subspace> lowerSubspaces = lowerSubspaces(candidate);
- if (LOG.isDebuggingFiner()) {
+ if(LOG.isDebuggingFiner()) {
msgFine.append("lowerSubspaces: ").append(lowerSubspaces).append('\n');
}
boolean irrelevantCandidate = false;
- for (Subspace s : lowerSubspaces) {
- if (!subspaces.contains(s)) {
+ for(Subspace s : lowerSubspaces) {
+ if(!subspaces.contains(s)) {
irrelevantCandidate = true;
break;
}
}
- if (!irrelevantCandidate) {
+ if(!irrelevantCandidate) {
candidates.add(candidate);
}
}
}
}
- if (LOG.isDebuggingFiner()) {
+ if(LOG.isDebuggingFiner()) {
LOG.debugFiner(msgFine.toString());
}
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
StringBuilder msg = new StringBuilder();
msg.append(d + 1).append("-dimensional candidate subspaces: ");
- for (Subspace candidate : candidates) {
+ for(Subspace candidate : candidates) {
msg.append(candidate.dimensonsToString()).append(' ');
}
LOG.debug(msg.toString());
@@ -401,16 +401,16 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
*/
private List<Subspace> lowerSubspaces(Subspace subspace) {
int dimensionality = subspace.dimensionality();
- if (dimensionality <= 1) {
+ if(dimensionality <= 1) {
return null;
}
// order result according to the dimensions
List<Subspace> result = new ArrayList<>();
- BitSet dimensions = subspace.getDimensions();
- for (int dim = dimensions.nextSetBit(0); dim >= 0; dim = dimensions.nextSetBit(dim + 1)) {
- BitSet newDimensions = (BitSet) dimensions.clone();
- newDimensions.set(dim, false);
+ long[] dimensions = subspace.getDimensions();
+ for(int dim = BitsUtil.nextSetBit(dimensions, 0); dim >= 0; dim = BitsUtil.nextSetBit(dimensions, dim + 1)) {
+ long[] newDimensions = dimensions.clone();
+ BitsUtil.clearI(newDimensions, dim);
result.add(new Subspace(newDimensions));
}
@@ -432,14 +432,14 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
private Subspace bestSubspace(List<Subspace> subspaces, Subspace candidate, TreeMap<Subspace, List<Cluster<Model>>> clusterMap) {
Subspace bestSubspace = null;
- for (Subspace subspace : subspaces) {
+ for(Subspace subspace : subspaces) {
int min = Integer.MAX_VALUE;
- if (subspace.isSubspace(candidate)) {
+ if(subspace.isSubspace(candidate)) {
List<Cluster<Model>> clusters = clusterMap.get(subspace);
- for (Cluster<Model> cluster : clusters) {
+ for(Cluster<Model> cluster : clusters) {
int clusterSize = cluster.size();
- if (clusterSize < min) {
+ if(clusterSize < min) {
min = clusterSize;
bestSubspace = subspace;
}
@@ -467,29 +467,29 @@ public class SUBCLU<V extends NumberVector<?>> extends AbstractAlgorithm<Cluster
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
protected int minpts = 0;
- protected DoubleDistance epsilon = null;
+ protected double epsilon;
- protected DimensionSelectingSubspaceDistanceFunction<V, DoubleDistance> distance = null;
+ protected DimensionSelectingSubspaceDistanceFunction<V> distance = null;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- ObjectParameter<DimensionSelectingSubspaceDistanceFunction<V, DoubleDistance>> param = new ObjectParameter<>(DISTANCE_FUNCTION_ID, DimensionSelectingSubspaceDistanceFunction.class, SubspaceEuclideanDistanceFunction.class);
- if (config.grab(param)) {
+ ObjectParameter<DimensionSelectingSubspaceDistanceFunction<V>> param = new ObjectParameter<>(DISTANCE_FUNCTION_ID, DimensionSelectingSubspaceDistanceFunction.class, SubspaceEuclideanDistanceFunction.class);
+ if(config.grab(param)) {
distance = param.instantiateClass(config);
}
- DistanceParameter<DoubleDistance> epsilonP = new DistanceParameter<>(EPSILON_ID, distance);
- if (config.grab(epsilonP)) {
+ DoubleParameter epsilonP = new DoubleParameter(EPSILON_ID);
+ if(config.grab(epsilonP)) {
epsilon = epsilonP.getValue();
}
IntParameter minptsP = new IntParameter(MINPTS_ID);
minptsP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
- if (config.grab(minptsP)) {
+ if(config.grab(minptsP)) {
minpts = minptsP.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/SubspaceClusteringAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/SubspaceClusteringAlgorithm.java
index 561816bd..c76c22b8 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/SubspaceClusteringAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/SubspaceClusteringAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.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
@@ -34,6 +34,6 @@ import de.lmu.ifi.dbs.elki.data.model.SubspaceModel;
*
* @param <M> Model type
*/
-public interface SubspaceClusteringAlgorithm<M extends SubspaceModel<?>> extends ClusteringAlgorithm<Clustering<M>> {
+public interface SubspaceClusteringAlgorithm<M extends SubspaceModel> extends ClusteringAlgorithm<Clustering<M>> {
// No additional constraints
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/Interval.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/CLIQUEInterval.java
index 978f9153..42f1eaa2 100644
--- a/src/de/lmu/ifi/dbs/elki/data/Interval.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/CLIQUEInterval.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.data;
+package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace.clique;
/*
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,7 +30,7 @@ import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
*
* @author Elke Achtert
*/
-public class Interval implements Comparable<Interval> {
+public class CLIQUEInterval implements Comparable<CLIQUEInterval> {
/**
* The dimension of this interval in the (original) data space.
*/
@@ -53,7 +53,7 @@ public class Interval implements Comparable<Interval> {
* @param min the minimum (left) value of the interval
* @param max the maximum (right) value of the interval
*/
- public Interval(int dimension, double min, double max) {
+ public CLIQUEInterval(int dimension, double min, double max) {
this.dimension = dimension;
this.min = min;
this.max = max;
@@ -94,7 +94,7 @@ public class Interval implements Comparable<Interval> {
*/
@Override
public String toString() {
- return "d" + (dimension + 1) + "-[" + FormatUtil.format(min, 2) + "; " + FormatUtil.format(max, 2) + "[";
+ return "d" + (dimension + 1) + "-[" + FormatUtil.NF2.format(min) + "; " + FormatUtil.NF2.format(max) + "[";
}
/**
@@ -109,7 +109,7 @@ public class Interval implements Comparable<Interval> {
* less than, equal to, or greater than the specified object.
*/
@Override
- public int compareTo(Interval other) {
+ public int compareTo(CLIQUEInterval other) {
if(dimension < other.dimension) {
return -1;
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/CLIQUESubspace.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/CLIQUESubspace.java
index 50e3fcd5..4df3e2a5 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/CLIQUESubspace.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/CLIQUESubspace.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace.clique;
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,16 +24,15 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace.clique;
*/
import java.util.ArrayList;
-import java.util.BitSet;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
-import de.lmu.ifi.dbs.elki.data.Interval;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.Subspace;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
@@ -46,7 +45,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
*
* @param <V> the type of NumberVector this subspace contains
*/
-public class CLIQUESubspace<V extends NumberVector<?>> extends Subspace {
+public class CLIQUESubspace<V extends NumberVector> extends Subspace {
/**
* The dense units belonging to this subspace.
*/
@@ -74,7 +73,7 @@ public class CLIQUESubspace<V extends NumberVector<?>> extends Subspace {
*
* @param dimensions the dimensions building this subspace
*/
- public CLIQUESubspace(BitSet dimensions) {
+ public CLIQUESubspace(long[] dimensions) {
super(dimensions);
denseUnits = new ArrayList<>();
coverage = 0;
@@ -86,9 +85,9 @@ public class CLIQUESubspace<V extends NumberVector<?>> extends Subspace {
* @param unit the unit to be added.
*/
public void addDenseUnit(CLIQUEUnit<V> unit) {
- Collection<Interval> intervals = unit.getIntervals();
- for(Interval interval : intervals) {
- if(!getDimensions().get(interval.getDimension())) {
+ Collection<CLIQUEInterval> intervals = unit.getIntervals();
+ for(CLIQUEInterval interval : intervals) {
+ if(!BitsUtil.get(getDimensions(), interval.getDimension())) {
throw new IllegalArgumentException("Unit " + unit + "cannot be added to this subspace, because of wrong dimensions!");
}
}
@@ -131,7 +130,8 @@ public class CLIQUESubspace<V extends NumberVector<?>> extends Subspace {
unit.markAsAssigned();
model.addDenseUnit(unit);
- for(int dim = getDimensions().nextSetBit(0); dim >= 0; dim = getDimensions().nextSetBit(dim + 1)) {
+ final long[] dims = getDimensions();
+ for(int dim = BitsUtil.nextSetBit(dims, 0); dim >= 0; dim = BitsUtil.nextSetBit(dims, dim + 1)) {
CLIQUEUnit<V> left = leftNeighbor(unit, dim);
if(left != null && !left.isAssigned()) {
dfs(left, cluster, model);
@@ -152,7 +152,7 @@ public class CLIQUESubspace<V extends NumberVector<?>> extends Subspace {
* @return the left neighbor of the given unit in the specified dimension
*/
public CLIQUEUnit<V> leftNeighbor(CLIQUEUnit<V> unit, int dim) {
- Interval i = unit.getInterval(Integer.valueOf(dim));
+ CLIQUEInterval i = unit.getInterval(dim);
for(CLIQUEUnit<V> u : getDenseUnits()) {
if(u.containsLeftNeighbor(i)) {
@@ -170,7 +170,7 @@ public class CLIQUESubspace<V extends NumberVector<?>> extends Subspace {
* @return the right neighbor of the given unit in the specified dimension
*/
public CLIQUEUnit<V> rightNeighbor(CLIQUEUnit<V> unit, Integer dim) {
- Interval i = unit.getInterval(dim);
+ CLIQUEInterval i = unit.getInterval(dim);
for(CLIQUEUnit<V> u : getDenseUnits()) {
if(u.containsRightNeighbor(i)) {
@@ -212,7 +212,7 @@ public class CLIQUESubspace<V extends NumberVector<?>> extends Subspace {
* @see de.lmu.ifi.dbs.elki.data.Subspace#joinLastDimensions
*/
public CLIQUESubspace<V> join(CLIQUESubspace<V> other, double all, double tau) {
- BitSet dimensions = joinLastDimensions(other);
+ long[] dimensions = joinLastDimensions(other);
if(dimensions == null) {
return null;
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/CLIQUEUnit.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/CLIQUEUnit.java
index a71b2b67..8e9f139c 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/CLIQUEUnit.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/CLIQUEUnit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace.clique;
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,6 @@ import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;
-import de.lmu.ifi.dbs.elki.data.Interval;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
@@ -42,21 +41,22 @@ import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
*
* @author Elke Achtert
*
+ * @apiviz.composedOf CLIQUEInterval
* @apiviz.composedOf ModifiableDBIDs
*
* @param <V> the type of NumberVector this unit contains
*/
-public class CLIQUEUnit<V extends NumberVector<?>> {
+public class CLIQUEUnit<V extends NumberVector> {
/**
* The one-dimensional intervals of which this unit is build.
*/
- private SortedSet<Interval> intervals;
+ private SortedSet<CLIQUEInterval> intervals;
/**
- * Provides a mapping of particular dimensions to the intervals of which this
- * unit is build.
+ * Mapping of particular dimensions to the intervals of which this unit is
+ * build.
*/
- private TIntObjectHashMap<Interval> dimensionToInterval;
+ private TIntObjectHashMap<CLIQUEInterval> dimensionToInterval;
/**
* The ids of the feature vectors this unit contains.
@@ -74,11 +74,11 @@ public class CLIQUEUnit<V extends NumberVector<?>> {
* @param intervals the intervals belonging to this unit
* @param ids the ids of the feature vectors belonging to this unit
*/
- public CLIQUEUnit(SortedSet<Interval> intervals, ModifiableDBIDs ids) {
+ public CLIQUEUnit(SortedSet<CLIQUEInterval> intervals, ModifiableDBIDs ids) {
this.intervals = intervals;
dimensionToInterval = new TIntObjectHashMap<>();
- for(Interval interval : intervals) {
+ for(CLIQUEInterval interval : intervals) {
dimensionToInterval.put(interval.getDimension(), interval);
}
@@ -92,7 +92,7 @@ public class CLIQUEUnit<V extends NumberVector<?>> {
*
* @param interval the interval belonging to this unit
*/
- public CLIQUEUnit(Interval interval) {
+ public CLIQUEUnit(CLIQUEInterval interval) {
intervals = new TreeSet<>();
intervals.add(interval);
@@ -113,7 +113,7 @@ public class CLIQUEUnit<V extends NumberVector<?>> {
* vector, false otherwise
*/
public boolean contains(V vector) {
- for(Interval interval : intervals) {
+ for(CLIQUEInterval interval : intervals) {
final double value = vector.doubleValue(interval.getDimension());
if(interval.getMin() > value || value >= interval.getMax()) {
return false;
@@ -164,7 +164,7 @@ public class CLIQUEUnit<V extends NumberVector<?>> {
*
* @return a sorted set of the intervals of which this unit is build
*/
- public SortedSet<Interval> getIntervals() {
+ public SortedSet<CLIQUEInterval> getIntervals() {
return intervals;
}
@@ -174,7 +174,7 @@ public class CLIQUEUnit<V extends NumberVector<?>> {
* @param dimension the dimension of the interval to be returned
* @return the interval of the specified dimension
*/
- public Interval getInterval(Integer dimension) {
+ public CLIQUEInterval getInterval(int dimension) {
return dimensionToInterval.get(dimension);
}
@@ -186,8 +186,8 @@ public class CLIQUEUnit<V extends NumberVector<?>> {
* @return true if this unit contains the left neighbor of the specified
* interval, false otherwise
*/
- public boolean containsLeftNeighbor(Interval i) {
- Interval interval = dimensionToInterval.get(i.getDimension());
+ public boolean containsLeftNeighbor(CLIQUEInterval i) {
+ CLIQUEInterval interval = dimensionToInterval.get(i.getDimension());
if(interval == null) {
return false;
}
@@ -202,8 +202,8 @@ public class CLIQUEUnit<V extends NumberVector<?>> {
* @return true if this unit contains the right neighbor of the specified
* interval, false otherwise
*/
- public boolean containsRightNeighbor(Interval i) {
- Interval interval = dimensionToInterval.get(i.getDimension());
+ public boolean containsRightNeighbor(CLIQUEInterval i) {
+ CLIQUEInterval interval = dimensionToInterval.get(i.getDimension());
if(interval == null) {
return false;
}
@@ -246,15 +246,15 @@ public class CLIQUEUnit<V extends NumberVector<?>> {
* greater than tau, null otherwise
*/
public CLIQUEUnit<V> join(CLIQUEUnit<V> other, double all, double tau) {
- Interval i1 = this.intervals.last();
- Interval i2 = other.intervals.last();
+ CLIQUEInterval i1 = this.intervals.last();
+ CLIQUEInterval i2 = other.intervals.last();
if(i1.getDimension() >= i2.getDimension()) {
return null;
}
- Iterator<Interval> it1 = this.intervals.iterator();
- Iterator<Interval> it2 = other.intervals.iterator();
- SortedSet<Interval> resultIntervals = new TreeSet<>();
+ Iterator<CLIQUEInterval> it1 = this.intervals.iterator();
+ Iterator<CLIQUEInterval> it2 = other.intervals.iterator();
+ SortedSet<CLIQUEInterval> resultIntervals = new TreeSet<>();
for(int i = 0; i < this.intervals.size() - 1; i++) {
i1 = it1.next();
i2 = it2.next();
@@ -285,7 +285,7 @@ public class CLIQUEUnit<V extends NumberVector<?>> {
@Override
public String toString() {
StringBuilder result = new StringBuilder();
- for(Interval interval : intervals) {
+ for(CLIQUEInterval interval : intervals) {
result.append(interval).append(' ');
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/package-info.java
index 7acd7572..87f435b4 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/clique/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/algorithm/clustering/subspace/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/package-info.java
index 2efa038d..6247de84 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/package-info.java
@@ -5,27 +5,30 @@
* subspace clustering algorithms according to the classical but somewhat obsolete classification schema
* of clustering algorithms for axis-parallel subspaces.
*
+ * @apiviz.exclude ^de.lmu.ifi.dbs.elki.algorithm.Abstract
+ * @apiviz.exclude ^de.lmu.ifi.dbs.elki.algorithm\.clustering\.subspace\.P3C\.(ClusterCandidate|Signature)
+ * @apiviz.exclude ^de.lmu.ifi.dbs.elki.algorithm\.clustering\.subspace\.clique\.
*/
/*
-This file is part of ELKI:
-Environment for Developing KDD-Applications Supported by Index-Structures
+ 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
+ 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 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.
+ 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/>.
-*/
+ 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.algorithm.clustering.subspace; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelClustering.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelClustering.java
index 3b5d0ec2..b9842bd5 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelClustering.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelClustering.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.trivial;
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/algorithm/clustering/trivial/ByLabelHierarchicalClustering.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelHierarchicalClustering.java
index 33101221..a01bd386 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelHierarchicalClustering.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelHierarchicalClustering.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.trivial;
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/algorithm/clustering/trivial/ByLabelOrAllInOneClustering.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelOrAllInOneClustering.java
index 76b024a2..a5a310c7 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelOrAllInOneClustering.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelOrAllInOneClustering.java
@@ -15,7 +15,7 @@ import de.lmu.ifi.dbs.elki.database.relation.Relation;
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/algorithm/clustering/trivial/ByModelClustering.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByModelClustering.java
index 73ad9880..c465c98a 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByModelClustering.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByModelClustering.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.trivial;
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/algorithm/clustering/trivial/TrivialAllInOne.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/TrivialAllInOne.java
index dae50c25..8a178371 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/TrivialAllInOne.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/TrivialAllInOne.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.trivial;
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
@@ -54,8 +54,7 @@ public class TrivialAllInOne extends AbstractAlgorithm<Clustering<Model>> implem
private static final Logging LOG = Logging.getLogger(TrivialAllInOne.class);
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public TrivialAllInOne() {
super();
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/TrivialAllNoise.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/TrivialAllNoise.java
index ecc7dbec..2d629377 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/TrivialAllNoise.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/TrivialAllNoise.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.clustering.trivial;
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
@@ -53,8 +53,7 @@ public class TrivialAllNoise extends AbstractAlgorithm<Clustering<Model>> implem
private static final Logging LOG = Logging.getLogger(TrivialAllNoise.class);
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public TrivialAllNoise() {
super();
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/package-info.java
index 6b7b50f5..81be8441 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/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/algorithm/itemsetmining/APRIORI.java b/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/APRIORI.java
new file mode 100644
index 00000000..31279b9b
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/APRIORI.java
@@ -0,0 +1,619 @@
+package de.lmu.ifi.dbs.elki.algorithm.itemsetmining;
+
+/*
+ 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 gnu.trove.iterator.TLongIntIterator;
+import gnu.trove.map.hash.TLongIntHashMap;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
+import de.lmu.ifi.dbs.elki.data.BitVector;
+import de.lmu.ifi.dbs.elki.data.SparseFeatureVector;
+import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
+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.ids.ArrayModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+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.database.relation.RelationUtil;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.statistics.Duration;
+import de.lmu.ifi.dbs.elki.logging.statistics.LongStatistic;
+import de.lmu.ifi.dbs.elki.result.AprioriResult;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
+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;
+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.constraints.CommonConstraints;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
+/**
+ * The APRIORI algorithm for Mining Association Rules.
+ *
+ * Reference:
+ * <p>
+ * R. Agrawal, R. Srikant:<br />
+ * Fast Algorithms for Mining Association Rules<br />
+ * In Proc. 20th Int. Conf. on Very Large Data Bases (VLDB '94), Santiago de
+ * Chile, Chile 1994.
+ * </p>
+ *
+ * This implementation uses some simple optimizations for 1- and 2-itemsets.
+ *
+ * Note: this algorithm scales well to a large number of transactions, but not
+ * so well to a large number of frequent itemsets (items). For best results, use
+ * domain-specific preprocessing to aggregate items into groups. Use statistics
+ * logging to keep track of candidate set sizes.
+ *
+ * @author Arthur Zimek
+ * @author Erich Schubert
+ *
+ * @apiviz.has Itemset
+ * @apiviz.uses BitVector
+ */
+@Title("APRIORI: Algorithm for Mining Association Rules")
+@Description("Searches for frequent itemsets")
+@Reference(authors = "R. Agrawal, R. Srikant", //
+title = "Fast Algorithms for Mining Association Rules", //
+booktitle = "Proc. 20th Int. Conf. on Very Large Data Bases (VLDB '94), Santiago de Chile, Chile 1994", //
+url = "http://www.vldb.org/conf/1994/P487.PDF")
+public class APRIORI extends AbstractAlgorithm<AprioriResult> {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(APRIORI.class);
+
+ /**
+ * Statistics logging prefix.
+ */
+ private final String STAT = this.getClass().getName() + ".";
+
+ /**
+ * Minimum support. If less than 1, considered to be a relative frequency,
+ * otherwise an absolute count.
+ */
+ private double minfreq;
+
+ /**
+ * Constructor with minimum frequency.
+ *
+ * @param minfreq Minimum frequency
+ */
+ public APRIORI(double minfreq) {
+ super();
+ this.minfreq = minfreq;
+ }
+
+ /**
+ * Performs the APRIORI algorithm on the given database.
+ *
+ * @param relation the Relation to process
+ * @return the AprioriResult learned by this APRIORI
+ */
+ public AprioriResult run(Relation<BitVector> relation) {
+ DBIDs ids = relation.getDBIDs();
+ List<Itemset> solution = new ArrayList<>();
+ final int size = ids.size();
+ final int needed = (int) ((minfreq < 1.) ? Math.ceil(minfreq * size) : minfreq);
+
+ // TODO: we don't strictly require a vector field.
+ // We could work with knowing just the maximum dimensionality beforehand.
+ VectorFieldTypeInformation<BitVector> meta = RelationUtil.assumeVectorField(relation);
+ if(size > 0) {
+ final int dim = meta.getDimensionality();
+ Duration timeone = LOG.newDuration(STAT + "1-items.time").begin();
+ List<OneItemset> oneitems = buildFrequentOneItemsets(relation, dim, needed);
+ LOG.statistics(timeone.end());
+ if(LOG.isStatistics()) {
+ LOG.statistics(new LongStatistic(STAT + "1-items.frequent", oneitems.size()));
+ LOG.statistics(new LongStatistic(STAT + "1-items.transactions", ids.size()));
+ }
+ if(LOG.isDebuggingFine()) {
+ LOG.debugFine(debugDumpCandidates(new StringBuilder(), oneitems, meta));
+ }
+ solution.addAll(oneitems);
+ if(oneitems.size() >= 2) {
+ Duration timetwo = LOG.newDuration(STAT + "2-items.time").begin();
+ ArrayModifiableDBIDs survivors = DBIDUtil.newArray(ids.size());
+ List<? extends Itemset> candidates = buildFrequentTwoItemsets(oneitems, relation, dim, needed, ids, survivors);
+ ids = survivors; // Continue with reduced set of transactions.
+ LOG.statistics(timetwo.end());
+ if(LOG.isStatistics()) {
+ LOG.statistics(new LongStatistic(STAT + "2-items.frequent", candidates.size()));
+ LOG.statistics(new LongStatistic(STAT + "2-items.transactions", ids.size()));
+ }
+ if(LOG.isDebuggingFine()) {
+ LOG.debugFine(debugDumpCandidates(new StringBuilder(), candidates, meta));
+ }
+ solution.addAll(candidates);
+ for(int length = 3; candidates.size() >= length; length++) {
+ Duration timel = LOG.newDuration(STAT + length + "-items.time").begin();
+ // Join to get the new candidates
+ candidates = aprioriGenerate(candidates, length, dim);
+ if(LOG.isDebuggingFinest()) {
+ LOG.debugFinest(debugDumpCandidates(new StringBuilder().append("Before pruning: "), candidates, meta));
+ }
+ survivors = DBIDUtil.newArray(ids.size());
+ candidates = frequentItemsets(candidates, relation, needed, ids, survivors, length);
+ ids = survivors; // Continue with reduced set of transactions.
+ LOG.statistics(timel.end());
+ if(LOG.isStatistics()) {
+ LOG.statistics(new LongStatistic(STAT + length + "-items.frequent", candidates.size()));
+ LOG.statistics(new LongStatistic(STAT + length + "-items.transactions", ids.size()));
+ }
+ if(LOG.isDebuggingFine()) {
+ LOG.debugFine(debugDumpCandidates(new StringBuilder(), candidates, meta));
+ }
+ solution.addAll(candidates);
+ }
+ }
+ }
+ return new AprioriResult("APRIORI", "apriori", solution, meta);
+ }
+
+ /**
+ * Build the 1-itemsets.
+ *
+ * @param relation Data relation
+ * @param dim Maximum dimensionality
+ * @param needed Minimum support needed
+ * @return 1-itemsets
+ */
+ protected List<OneItemset> buildFrequentOneItemsets(final Relation<? extends SparseFeatureVector<?>> relation, final int dim, final int needed) {
+ // TODO: use TIntList and prefill appropriately to avoid knowing "dim"
+ // beforehand?
+ int[] counts = new int[dim];
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ SparseFeatureVector<?> bv = relation.get(iditer);
+ for(int it = bv.iter(); bv.iterValid(it); it = bv.iterAdvance(it)) {
+ counts[bv.iterDim(it)]++;
+ }
+ }
+ if(LOG.isStatistics()) {
+ LOG.statistics(new LongStatistic(STAT + "1-items.candidates", dim));
+ }
+ // Generate initial candidates of length 1.
+ List<OneItemset> frequent = new ArrayList<>(dim);
+ for(int i = 0; i < dim; i++) {
+ if(counts[i] >= needed) {
+ frequent.add(new OneItemset(i, counts[i]));
+ }
+ }
+ return frequent;
+ }
+
+ /**
+ * Build the 2-itemsets.
+ *
+ * @param oneitems Frequent 1-itemsets
+ * @param relation Data relation
+ * @param dim Maximum dimensionality
+ * @param needed Minimum support needed
+ * @param ids Objects to process
+ * @param survivors Output: objects that had at least two 1-frequent items.
+ * @return Frequent 2-itemsets
+ */
+ protected List<SparseItemset> buildFrequentTwoItemsets(List<OneItemset> oneitems, final Relation<BitVector> relation, final int dim, final int needed, DBIDs ids, ArrayModifiableDBIDs survivors) {
+ int f1 = 0;
+ long[] mask = BitsUtil.zero(dim);
+ for(OneItemset supported : oneitems) {
+ BitsUtil.setI(mask, supported.item);
+ f1++;
+ }
+ if(LOG.isStatistics()) {
+ LOG.statistics(new LongStatistic(STAT + "2-items.candidates", f1 * (long) (f1 - 1)));
+ }
+ // We quite aggressively size the map, assuming that almost each combination
+ // is present somewhere. If this won't fit into memory, we're likely running
+ // OOM somewhere later anyway!
+ TLongIntHashMap map = new TLongIntHashMap((f1 * (f1 - 1)) >>> 1);
+ final long[] scratch = BitsUtil.zero(dim);
+ for(DBIDIter iditer = ids.iter(); iditer.valid(); iditer.advance()) {
+ BitsUtil.setI(scratch, mask);
+ relation.get(iditer).andOnto(scratch);
+ int lives = 0;
+ for(int i = BitsUtil.nextSetBit(scratch, 0); i >= 0; i = BitsUtil.nextSetBit(scratch, i + 1)) {
+ for(int j = BitsUtil.nextSetBit(scratch, i + 1); j >= 0; j = BitsUtil.nextSetBit(scratch, j + 1)) {
+ long key = (((long) i) << 32) | j;
+ map.put(key, 1 + map.get(key));
+ ++lives;
+ }
+ }
+ if(lives > 2) {
+ survivors.add(iditer);
+ }
+ }
+ // Generate candidates of length 2.
+ List<SparseItemset> frequent = new ArrayList<>(f1 * (int) Math.sqrt(f1));
+ for(TLongIntIterator iter = map.iterator(); iter.hasNext();) {
+ iter.advance(); // Trove style iterator - advance first.
+ if(iter.value() >= needed) {
+ int ii = (int) (iter.key() >>> 32);
+ int ij = (int) (iter.key() & -1L);
+ frequent.add(new SparseItemset(new int[] { ii, ij }, iter.value()));
+ }
+ }
+ // The hashmap may produce them out of order.
+ Collections.sort(frequent);
+ if(LOG.isStatistics()) {
+ LOG.statistics(new LongStatistic(STAT + "2-items.frequent", frequent.size()));
+ }
+ return frequent;
+ }
+
+ /**
+ * Prunes a given set of candidates to keep only those BitSets where all
+ * subsets of bits flipping one bit are frequent already.
+ *
+ * @param supported Support map
+ * @param length Itemset length
+ * @param dim Dimensionality
+ * @return itemsets that cannot be pruned by apriori
+ */
+ protected List<Itemset> aprioriGenerate(List<? extends Itemset> supported, int length, int dim) {
+ if(supported.size() < length) {
+ return Collections.emptyList();
+ }
+ long joined = 0L;
+ final int ssize = supported.size();
+ List<Itemset> candidateList = new ArrayList<>();
+
+ Itemset ref = supported.get(0);
+ if(ref instanceof SparseItemset) {
+ // TODO: we currently never switch to DenseItemSet. This may however be
+ // beneficial when we have few dimensions and many candidates.
+ // E.g. when length > 32 and dim < 100. But this needs benchmarking!
+ // For length < 5 and dim > 3000, SparseItemset unsurprisingly was faster
+
+ // Scratch item to use for searching.
+ SparseItemset scratch = new SparseItemset(new int[length - 1]);
+
+ for(int i = 0; i < ssize; i++) {
+ SparseItemset ii = (SparseItemset) supported.get(i);
+ prefix: for(int j = i + 1; j < ssize; j++) {
+ SparseItemset ij = (SparseItemset) supported.get(j);
+ if(!ii.prefixTest(ij)) {
+ break prefix; // Prefix doesn't match
+ }
+ joined++;
+ // Test subsets (re-) using scratch object
+ System.arraycopy(ii.indices, 1, scratch.indices, 0, length - 2);
+ scratch.indices[length - 2] = ij.indices[length - 2];
+ for(int k = length - 3; k >= 0; k--) {
+ scratch.indices[k] = ii.indices[k + 1];
+ int pos = Collections.binarySearch(supported, scratch);
+ if(pos < 0) {
+ // Prefix was okay, but one other subset was not frequent
+ continue prefix;
+ }
+ }
+ int[] items = new int[length];
+ System.arraycopy(ii.indices, 0, items, 0, length - 1);
+ items[length - 1] = ij.indices[length - 2];
+ candidateList.add(new SparseItemset(items));
+ }
+ }
+ }
+ else if(ref instanceof DenseItemset) {
+ // Scratch item to use for searching.
+ DenseItemset scratch = new DenseItemset(BitsUtil.zero(dim), length - 1);
+
+ for(int i = 0; i < ssize; i++) {
+ DenseItemset ii = (DenseItemset) supported.get(i);
+ prefix: for(int j = i + 1; j < ssize; j++) {
+ DenseItemset ij = (DenseItemset) supported.get(j);
+ // Prefix test via "|i1 ^ i2| = 2"
+ System.arraycopy(ii.items, 0, scratch.items, 0, ii.items.length);
+ BitsUtil.xorI(scratch.items, ij.items);
+ if(BitsUtil.cardinality(scratch.items) != 2) {
+ break prefix; // No prefix match; since sorted, no more can follow!
+ }
+ ++joined;
+ // Ensure that the first difference is the last item in ii:
+ int first = BitsUtil.nextSetBit(scratch.items, 0);
+ if(BitsUtil.nextSetBit(ii.items, first + 1) > -1) {
+ break prefix; // Different overlap by chance?
+ }
+ BitsUtil.orI(scratch.items, ij.items);
+
+ // Test subsets.
+ for(int l = length, b = BitsUtil.nextSetBit(scratch.items, 0); l > 2; l--, b = BitsUtil.nextSetBit(scratch.items, b + 1)) {
+ BitsUtil.clearI(scratch.items, b);
+ int pos = Collections.binarySearch(supported, scratch);
+ if(pos < 0) {
+ continue prefix;
+ }
+ BitsUtil.setI(scratch.items, b);
+ }
+ candidateList.add(new DenseItemset(scratch.items.clone(), length));
+ }
+ }
+ }
+ else {
+ throw new AbortException("Unexpected itemset type " + ref.getClass());
+ }
+ if(LOG.isStatistics()) {
+ // Naive pairwise approach
+ LOG.statistics(new LongStatistic(STAT + length + "-items.pairwise", (ssize * ((long) ssize - 1))));
+ LOG.statistics(new LongStatistic(STAT + length + "-items.joined", joined));
+ LOG.statistics(new LongStatistic(STAT + length + "-items.candidates", candidateList.size()));
+ }
+ // Note: candidates should have been generated in strictly ascending order
+ // So we do not need to sort here.
+ return candidateList;
+ }
+
+ /**
+ * Returns the frequent BitSets out of the given BitSets with respect to the
+ * given database.
+ *
+ * @param candidates the candidates to be evaluated
+ * @param relation the database to evaluate the candidates on
+ * @param needed Minimum support needed
+ * @param ids Objects to process
+ * @param survivors Output: objects that had at least two 1-frequent items.
+ * @param length Itemset length
+ * @return Itemsets with sufficient support
+ */
+ protected List<? extends Itemset> frequentItemsets(List<? extends Itemset> candidates, Relation<BitVector> relation, int needed, DBIDs ids, ArrayModifiableDBIDs survivors, int length) {
+ if(candidates.size() < 1) {
+ return Collections.emptyList();
+ }
+ Itemset first = candidates.get(0);
+ // We have an optimized codepath for large and sparse itemsets.
+ // It probably pays off when #cands >> (avlen choose length) but we do not
+ // currently have the average number of items. These thresholds yield
+ // 2700, 6400, 12500, ... and thus will almost always be met until the
+ // number of frequent itemsets is about to break down to 0.
+ if(candidates.size() > length * length * length * 100 && first instanceof SparseItemset) {
+ // Assume that all itemsets are sparse itemsets!
+ @SuppressWarnings("unchecked")
+ List<SparseItemset> sparsecand = (List<SparseItemset>) candidates;
+ return frequentItemsetsSparse(sparsecand, relation, needed, ids, survivors, length);
+ }
+ for(DBIDIter iditer = ids.iter(); iditer.valid(); iditer.advance()) {
+ BitVector bv = relation.get(iditer);
+ // TODO: exploit that the candidate set it sorted?
+ int lives = 0;
+ for(Itemset candidate : candidates) {
+ if(candidate.containedIn(bv)) {
+ candidate.increaseSupport();
+ ++lives;
+ }
+ }
+ if(lives > length) {
+ survivors.add(iditer);
+ }
+ }
+ // Retain only those with minimum support:
+ List<Itemset> frequent = new ArrayList<>(candidates.size());
+ for(Iterator<? extends Itemset> iter = candidates.iterator(); iter.hasNext();) {
+ final Itemset candidate = iter.next();
+ if(candidate.getSupport() >= needed) {
+ frequent.add(candidate);
+ }
+ }
+ return frequent;
+ }
+
+ /**
+ * Returns the frequent BitSets out of the given BitSets with respect to the
+ * given database. Optimized implementation for SparseItemset.
+ *
+ * @param candidates the candidates to be evaluated
+ * @param relation the database to evaluate the candidates on
+ * @param needed Minimum support needed
+ * @param ids Objects to process
+ * @param survivors Output: objects that had at least two 1-frequent items.
+ * @param length Itemset length
+ * @return Itemsets with sufficient support
+ */
+ protected List<SparseItemset> frequentItemsetsSparse(List<SparseItemset> candidates, Relation<BitVector> relation, int needed, DBIDs ids, ArrayModifiableDBIDs survivors, int length) {
+ // Current search interval:
+ int begin = 0, end = candidates.size();
+ int[] scratchi = new int[length], iters = new int[length];
+ SparseItemset scratch = new SparseItemset(scratchi);
+ for(DBIDIter iditer = ids.iter(); iditer.valid(); iditer.advance()) {
+ BitVector bv = relation.get(iditer);
+ if(!initializeSearchItemset(bv, scratchi, iters)) {
+ continue;
+ }
+ int lives = 0;
+ while(begin < end) {
+ begin = binarySearch(candidates, scratch, begin, end);
+ if(begin > 0) {
+ candidates.get(begin).increaseSupport();
+ ++lives;
+ }
+ else {
+ begin = (-begin) - 1;
+ }
+ if(begin >= end || !nextSearchItemset(bv, scratchi, iters)) {
+ break;
+ }
+ }
+ for(Itemset candidate : candidates) {
+ if(candidate.containedIn(bv)) {
+ candidate.increaseSupport();
+ ++lives;
+ }
+ }
+ if(lives > length) {
+ survivors.add(iditer);
+ }
+ }
+ // Retain only those with minimum support:
+ List<SparseItemset> frequent = new ArrayList<>(candidates.size());
+ for(Iterator<SparseItemset> iter = candidates.iterator(); iter.hasNext();) {
+ final SparseItemset candidate = iter.next();
+ if(candidate.getSupport() >= needed) {
+ frequent.add(candidate);
+ }
+ }
+ return frequent;
+ }
+
+ /**
+ * Initialize the scratch itemset.
+ *
+ * @param bv Bit vector data source
+ * @param scratchi Scratch itemset
+ * @param iters Iterator array
+ * @return {@code true} if the itemset had minimum length
+ */
+ private boolean initializeSearchItemset(BitVector bv, int[] scratchi, int[] iters) {
+ for(int i = 0; i < scratchi.length; i++) {
+ iters[i] = (i == 0) ? bv.iter() : bv.iterAdvance(iters[i - 1]);
+ if(iters[i] < 0) {
+ return false;
+ }
+ scratchi[i] = bv.iterDim(iters[i]);
+ }
+ return true;
+ }
+
+ /**
+ * Advance scratch itemset to the next.
+ *
+ * @param bv Bit vector data source
+ * @param scratchi Scratch itemset
+ * @param iters Iterator array
+ * @return {@code true} if the itemset had minimum length
+ */
+ private boolean nextSearchItemset(BitVector bv, int[] scratchi, int[] iters) {
+ final int last = scratchi.length - 1;
+ for(int j = last; j >= 0; j--) {
+ int n = bv.iterAdvance(iters[j]);
+ if(n >= 0 && (j == last || n != iters[j + 1])) {
+ iters[j] = n;
+ scratchi[j] = bv.iterDim(n);
+ return true; // Success
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Binary-search for the next-larger element.
+ *
+ * @param candidates Candidates to search for
+ * @param scratch Scratch space
+ * @param begin Search interval begin
+ * @param end Search interval end
+ * @return Position of first equal-or-larger element
+ */
+ private int binarySearch(List<SparseItemset> candidates, SparseItemset scratch, int begin, int end) {
+ --end;
+ while(begin < end) {
+ final int mid = (begin + end) >>> 1;
+ SparseItemset midVal = candidates.get(mid);
+ int cmp = midVal.compareTo(scratch);
+
+ if(cmp < 0) {
+ begin = mid + 1;
+ }
+ else if(cmp > 0) {
+ end = mid - 1;
+ }
+ else {
+ return mid; // key found
+ }
+ }
+ return -(begin + 1); // key not found, return next
+ }
+
+ /**
+ * Debug method: output all itemsets.
+ *
+ * @param msg Output buffer
+ * @param candidates Itemsets to dump
+ * @param meta Metadata for item labels
+ * @return Output buffer
+ */
+ private StringBuilder debugDumpCandidates(StringBuilder msg, List<? extends Itemset> candidates, VectorFieldTypeInformation<BitVector> meta) {
+ msg.append(':');
+ for(Itemset itemset : candidates) {
+ msg.append(" [");
+ itemset.appendTo(msg, meta);
+ msg.append(']');
+ }
+ return msg;
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(TypeUtil.BIT_VECTOR_FIELD);
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Parameter to specify the minimum support, in absolute or relative terms.
+ */
+ public static final OptionID MINSUPP_ID = new OptionID("apriori.minsupp", //
+ "Threshold for minimum support as minimally required number of transactions (if > 1) " //
+ + "or the minimum frequency (if <= 1).");
+
+ /**
+ * Parameter for minimum support.
+ */
+ protected double minsupp;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ DoubleParameter minsuppP = new DoubleParameter(MINSUPP_ID);
+ minsuppP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ if(config.grab(minsuppP)) {
+ minsupp = minsuppP.getValue();
+ }
+ }
+
+ @Override
+ protected APRIORI makeInstance() {
+ return new APRIORI(minsupp);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/DenseItemset.java b/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/DenseItemset.java
new file mode 100644
index 00000000..34f05376
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/DenseItemset.java
@@ -0,0 +1,129 @@
+package de.lmu.ifi.dbs.elki.algorithm.itemsetmining;
+
+/*
+ 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.type.VectorFieldTypeInformation;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
+
+/**
+ * APRIORI itemset.
+ *
+ * @author Erich Schubert
+ */
+public class DenseItemset extends Itemset {
+ /**
+ * Items, as a bitmask.
+ */
+ long[] items;
+
+ /**
+ * Itemset length.
+ */
+ int length;
+
+ /**
+ * Constructor.
+ *
+ * @param items Items
+ * @param length Length (Cardinality of itemset)
+ */
+ public DenseItemset(long[] items, int length) {
+ this.items = items;
+ this.length = length;
+ }
+
+ @Override
+ public int length() {
+ return length;
+ }
+
+ @Override
+ public boolean containedIn(BitVector bv) {
+ return bv.contains(items);
+ }
+
+ @Override
+ public long[] getItems() {
+ return items;
+ }
+
+ @Override
+ public int hashCode() {
+ return BitsUtil.hashCode(items);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(this == obj) {
+ return true;
+ }
+ if(obj == null) {
+ return false;
+ }
+ if(!(obj instanceof Itemset) || ((Itemset) obj).length() != 1) {
+ return false;
+ }
+ // TODO: allow comparison to DenseItemset?
+ if(getClass() != obj.getClass()) {
+ return false;
+ }
+ return BitsUtil.equal(items, ((DenseItemset) obj).items);
+ }
+
+ @Override
+ public int compareTo(Itemset o) {
+ int cmp = Integer.compare(length, o.length());
+ if(cmp != 0) {
+ return cmp;
+ }
+ DenseItemset other = (DenseItemset) o;
+ for(int i = 0; i < items.length; i++) {
+ if(items[i] != other.items[i]) {
+ return -Long.compare(Long.reverse(items[i]), Long.reverse(other.items[i]));
+ }
+ }
+ return 0;
+ }
+
+ @Override
+ public StringBuilder appendTo(StringBuilder buf, VectorFieldTypeInformation<BitVector> meta) {
+ int i = BitsUtil.nextSetBit(items, 0);
+ while(true) {
+ String lbl = (meta != null) ? meta.getLabel(i) : null;
+ if(lbl == null) {
+ buf.append(i);
+ }
+ else {
+ buf.append(lbl);
+ }
+ i = BitsUtil.nextSetBit(items, i + 1);
+ if(i < 0) {
+ break;
+ }
+ buf.append(", ");
+ }
+ buf.append(": ").append(support);
+ return buf;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/Itemset.java b/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/Itemset.java
new file mode 100644
index 00000000..17fbeefa
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/Itemset.java
@@ -0,0 +1,92 @@
+package de.lmu.ifi.dbs.elki.algorithm.itemsetmining;
+
+/*
+ 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.type.VectorFieldTypeInformation;
+
+/**
+ * APRIORI itemset.
+ *
+ * @author Erich Schubert
+ */
+public abstract class Itemset implements Comparable<Itemset> {
+ /**
+ * Support for this itemset.
+ */
+ int support;
+
+ /**
+ * Increase the support of the itemset.
+ *
+ * @return New support.
+ */
+ public int increaseSupport() {
+ return ++support;
+ }
+
+ /**
+ * Get item support.
+ *
+ * @return Support
+ */
+ public int getSupport() {
+ return support;
+ }
+
+ /**
+ * Test whether the itemset is contained in a bit vector.
+ *
+ * @param bv Bit vector
+ * @return {@code true} when the itemset is contained in this vector.
+ */
+ abstract public boolean containedIn(BitVector bv);
+
+ /**
+ * Itemset length.
+ *
+ * @return Itemset length
+ */
+ abstract public int length();
+
+ /**
+ * Get the items.
+ *
+ * @return Itemset contents.
+ */
+ abstract public long[] getItems();
+
+ @Override
+ public String toString() {
+ return appendTo(new StringBuilder(), null).toString();
+ }
+
+ /**
+ * Append to a string buffer.
+ *
+ * @param buf Buffer
+ * @param meta Relation metadata (for labels)
+ * @return String buffer for chaining.
+ */
+ abstract public StringBuilder appendTo(StringBuilder buf, VectorFieldTypeInformation<BitVector> meta);
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/OneItemset.java b/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/OneItemset.java
new file mode 100644
index 00000000..41f37686
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/OneItemset.java
@@ -0,0 +1,126 @@
+package de.lmu.ifi.dbs.elki.algorithm.itemsetmining;
+
+/*
+ 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.type.VectorFieldTypeInformation;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+
+/**
+ * APRIORI itemset.
+ *
+ * @author Erich Schubert
+ */
+public class OneItemset extends Itemset {
+ /**
+ * Trivial item.
+ */
+ int item;
+
+ /**
+ * Constructor of 1-itemset.
+ *
+ * @param item Item
+ */
+ public OneItemset(int item) {
+ this.item = item;
+ }
+
+ /**
+ * Constructor with initial support.
+ *
+ * @param item Item
+ * @param support Support
+ */
+ public OneItemset(int item, int support) {
+ this.item = item;
+ this.support = support;
+ }
+
+ @Override
+ public int length() {
+ return 1;
+ }
+
+ @Override
+ public boolean containedIn(BitVector bv) {
+ // TODO: add a booleanValue method to BitVector?
+ return bv.longValue(item) != 0L;
+ }
+
+ @Override
+ public long[] getItems() {
+ long[] bits = BitsUtil.zero(item);
+ BitsUtil.setI(bits, item);
+ return bits;
+ }
+
+ @Override
+ public int hashCode() {
+ return item;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(this == obj) {
+ return true;
+ }
+ if(obj == null) {
+ return false;
+ }
+ if(!(obj instanceof Itemset) || ((Itemset) obj).length() != 1) {
+ return false;
+ }
+ if(getClass() != obj.getClass()) {
+ return false;
+ }
+ OneItemset other = (OneItemset) obj;
+ return item == other.item;
+ }
+
+ @Override
+ public int compareTo(Itemset o) {
+ int cmp = Integer.compare(1, o.length());
+ if(cmp != 0) {
+ return cmp;
+ }
+ if(o instanceof OneItemset) {
+ return Integer.compare(item, ((OneItemset) o).item);
+ }
+ throw new AbortException("Itemset of length 1 not using OneItemset!");
+ }
+
+ @Override
+ public StringBuilder appendTo(StringBuilder buf, VectorFieldTypeInformation<BitVector> meta) {
+ String lbl = (meta != null) ? meta.getLabel(item) : null;
+ if(lbl == null) {
+ buf.append(item);
+ }
+ else {
+ buf.append(lbl);
+ }
+ return buf.append(": ").append(support);
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/SmallDenseItemset.java b/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/SmallDenseItemset.java
new file mode 100644
index 00000000..6128f731
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/SmallDenseItemset.java
@@ -0,0 +1,125 @@
+package de.lmu.ifi.dbs.elki.algorithm.itemsetmining;
+
+/*
+ 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.type.VectorFieldTypeInformation;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
+
+/**
+ * APRIORI itemset.
+ *
+ * @author Erich Schubert
+ */
+public class SmallDenseItemset extends Itemset {
+ /**
+ * Items, as a bitmask.
+ */
+ long items;
+
+ /**
+ * Itemset length.
+ */
+ int length;
+
+ /**
+ * Constructor.
+ *
+ * @param items Items
+ * @param length Length (Cardinality of itemset)
+ */
+ public SmallDenseItemset(long items, int length) {
+ this.items = items;
+ this.length = length;
+ }
+
+ @Override
+ public int length() {
+ return length;
+ }
+
+ @Override
+ public boolean containedIn(BitVector bv) {
+ return bv.contains(new long[] { items });
+ }
+
+ @Override
+ public long[] getItems() {
+ return new long[] { items };
+ }
+
+ @Override
+ public int hashCode() {
+ return BitsUtil.hashCode(items);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(this == obj) {
+ return true;
+ }
+ if(obj == null) {
+ return false;
+ }
+ if(!(obj instanceof Itemset) || ((Itemset) obj).length() != 1) {
+ return false;
+ }
+ // TODO: allow comparison to DenseItemset?
+ if(getClass() != obj.getClass()) {
+ return false;
+ }
+ return items == ((SmallDenseItemset) obj).items;
+ }
+
+ @Override
+ public int compareTo(Itemset o) {
+ int cmp = Integer.compare(length, o.length());
+ if(cmp != 0) {
+ return cmp;
+ }
+ SmallDenseItemset other = (SmallDenseItemset) o;
+ return -Long.compare(Long.reverse(items), Long.reverse(other.items));
+ }
+
+ @Override
+ public StringBuilder appendTo(StringBuilder buf, VectorFieldTypeInformation<BitVector> meta) {
+ int i = BitsUtil.nextSetBit(items, 0);
+ while(true) {
+ String lbl = (meta != null) ? meta.getLabel(i) : null;
+ if(lbl == null) {
+ buf.append(i);
+ }
+ else {
+ buf.append(lbl);
+ }
+ i = BitsUtil.nextSetBit(items, i + 1);
+ if(i < 0) {
+ break;
+ }
+ buf.append(", ");
+ }
+ buf.append(": ").append(support);
+ return buf;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/SparseItemset.java b/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/SparseItemset.java
new file mode 100644
index 00000000..fdde6dd6
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/SparseItemset.java
@@ -0,0 +1,175 @@
+package de.lmu.ifi.dbs.elki.algorithm.itemsetmining;
+
+/*
+ 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.BitVector;
+import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+
+/**
+ * APRIORI itemset.
+ *
+ * @author Erich Schubert
+ */
+public class SparseItemset extends Itemset {
+ /**
+ * Items, as indexes.
+ */
+ int[] indices;
+
+ /**
+ * Constructor.
+ *
+ * @param indices Items
+ */
+ public SparseItemset(int[] indices) {
+ this.indices = indices;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param indices Items
+ * @param support Support
+ */
+ public SparseItemset(int[] indices, int support) {
+ this.indices = indices;
+ this.support = support;
+ }
+
+ /**
+ * Constructor from existing itemsets.
+ *
+ * @param ii First 1-itemset
+ * @param ij Second 1-itemset
+ */
+ public SparseItemset(OneItemset ii, OneItemset ij) {
+ if(ii.item == ij.item) {
+ throw new AbortException("SparseItemset constructed from identical 1-itemsets.");
+ }
+ this.indices = (ii.item < ij.item) ? new int[] { ii.item, ij.item } : new int[] { ij.item, ii.item };
+ }
+
+ @Override
+ public int length() {
+ return indices.length;
+ }
+
+ @Override
+ public boolean containedIn(BitVector bv) {
+ for(int item : indices) {
+ if(!bv.booleanValue(item)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public long[] getItems() {
+ long[] bits = BitsUtil.zero(indices[indices.length - 1]);
+ for(int item : indices) {
+ BitsUtil.setI(bits, item);
+ }
+ return bits;
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(indices);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(this == obj) {
+ return true;
+ }
+ if(obj == null) {
+ return false;
+ }
+ if(!(obj instanceof Itemset) || ((Itemset) obj).length() != 1) {
+ return false;
+ }
+ // TODO: allow comparing to DenseItemset etc?
+ if(getClass() != obj.getClass()) {
+ return false;
+ }
+ return Arrays.equals(indices, ((SparseItemset) obj).indices);
+ }
+
+ @Override
+ public int compareTo(Itemset o) {
+ int cmp = Integer.compare(indices.length, o.length());
+ if(cmp != 0) {
+ return cmp;
+ }
+ SparseItemset other = (SparseItemset) o;
+ for(int i = 0; i < indices.length; i++) {
+ int c = Integer.compare(indices[i], other.indices[i]);
+ if(c != 0) {
+ return c;
+ }
+ }
+ return 0;
+ }
+
+ @Override
+ public StringBuilder appendTo(StringBuilder buf, VectorFieldTypeInformation<BitVector> meta) {
+ for(int j = 0; j < indices.length; j++) {
+ if(j > 0) {
+ buf.append(", ");
+ }
+ String lbl = (meta != null) ? meta.getLabel(indices[j]) : null;
+ if(lbl == null) {
+ buf.append(indices[j]);
+ }
+ else {
+ buf.append(lbl);
+ }
+ }
+ buf.append(": ").append(support);
+ return buf;
+ }
+
+ /**
+ * Perform the prefix test for sparse itemset.
+ *
+ * @param other Other itemset
+ * @return {@code true} iff the first n-1 items agree.
+ */
+ public boolean prefixTest(SparseItemset other) {
+ if(indices.length != other.indices.length) {
+ throw new AbortException("PrefixTest is only valid for itemsets of the same length!");
+ }
+ for(int k = indices.length - 2; k >= 0; k--) {
+ if(indices[k] != other.indices[k]) {
+ return false;
+ }
+ }
+ return true;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/package-info.java
new file mode 100644
index 00000000..26a2eb3d
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/itemsetmining/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Algorithms for frequent itemset mining such as APRIORI.
+ */
+
+/*
+ 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.algorithm.itemsetmining; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/COP.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/COP.java
index 190d14fe..1d723443 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/COP.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/COP.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier;
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
@@ -38,14 +38,15 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.KNNList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
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.distancefunction.DistanceFunction;
-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.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Centroid;
@@ -84,11 +85,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @author Erich Schubert
*
* @param <V> the type of NumberVector handled by this Algorithm
- * @param <D> Distance type
*/
@Title("COP: Correlation Outlier Probability")
@Reference(authors = "Hans-Peter Kriegel, Peer Kröger, Erich Schubert, Arthur Zimek", title = "Outlier Detection in Arbitrarily Oriented Subspaces", booktitle = "Proc. IEEE International Conference on Data Mining (ICDM 2012)")
-public class COP<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<V, D, OutlierResult> implements OutlierAlgorithm {
+public class COP<V extends NumberVector> extends AbstractDistanceBasedAlgorithm<V, OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -164,7 +164,7 @@ public class COP<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
/**
* Holds the PCA runner.
*/
- private PCARunner<V> pca;
+ private PCARunner pca;
/**
* Expected amount of outliers.
@@ -209,7 +209,7 @@ public class COP<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
* @param dist Distance distribution model (ChiSquared, Gamma)
* @param models Report models
*/
- public COP(DistanceFunction<? super V, D> distanceFunction, int k, PCARunner<V> pca, double expect, DistanceDist dist, boolean models) {
+ public COP(DistanceFunction<? super V> distanceFunction, int k, PCARunner pca, double expect, DistanceDist dist, boolean models) {
super(distanceFunction);
this.k = k;
this.pca = pca;
@@ -226,7 +226,7 @@ public class COP<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
*/
public OutlierResult run(Relation<V> relation) {
final DBIDs ids = relation.getDBIDs();
- KNNQuery<V, D> knnQuery = QueryUtil.getKNNQuery(relation, getDistanceFunction(), k + 1);
+ KNNQuery<V> knnQuery = QueryUtil.getKNNQuery(relation, getDistanceFunction(), k + 1);
final int dim = RelationUtil.dimensionality(relation);
if(k <= dim + 1) {
@@ -244,7 +244,7 @@ public class COP<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Correlation Outlier Probabilities", relation.size(), LOG) : null;
for(DBIDIter id = ids.iter(); id.valid(); id.advance()) {
- KNNList<D> neighbors = knnQuery.getKNNForDBID(id, k + 1);
+ KNNList neighbors = knnQuery.getKNNForDBID(id, k + 1);
ModifiableDBIDs nids = DBIDUtil.newHashSet(neighbors);
nids.remove(id); // Do not use query object
@@ -324,16 +324,12 @@ public class COP<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
cop_dim.putInt(id, dim + 1 - vdim);
}
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if(prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
// combine results.
- Relation<Double> scoreResult = new MaterializedRelation<>("Correlation Outlier Probabilities", COP_SCORES, TypeUtil.DOUBLE, cop_score, ids);
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Correlation Outlier Probabilities", COP_SCORES, cop_score, ids);
OutlierScoreMeta scoreMeta = new ProbabilisticOutlierScore();
OutlierResult result = new OutlierResult(scoreMeta, scoreResult);
if(models) {
@@ -360,7 +356,7 @@ public class COP<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<V, D> {
+ public static class Parameterizer<V extends NumberVector> extends AbstractDistanceBasedAlgorithm.Parameterizer<V> {
/**
* Parameter to specify the number of nearest neighbors of an object to be
* considered for computing its COP_SCORE, must be an integer greater than
@@ -415,7 +411,7 @@ public class COP<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
/**
* Holds the object performing the dependency derivation.
*/
- PCARunner<V> pca;
+ PCARunner pca;
/**
* Distance distributution assumption.
@@ -450,7 +446,7 @@ public class COP<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
if(config.grab(expectP)) {
expect = expectP.doubleValue();
}
- ObjectParameter<PCARunner<V>> pcaP = new ObjectParameter<>(PCARUNNER_ID, PCARunner.class, PCARunner.class);
+ ObjectParameter<PCARunner> pcaP = new ObjectParameter<>(PCARUNNER_ID, PCARunner.class, PCARunner.class);
if(config.grab(pcaP)) {
pca = pcaP.instantiateClass(config);
}
@@ -461,7 +457,7 @@ public class COP<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
}
@Override
- protected COP<V, D> makeInstance() {
+ protected COP<V> makeInstance() {
return new COP<>(distanceFunction, k, pca, expect, dist, models);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/DWOF.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/DWOF.java
index ef782390..3d484562 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/DWOF.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/DWOF.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier;
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
@@ -35,18 +35,18 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-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.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
@@ -92,13 +92,13 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* @author Omar Yousry
*
* @param <O> the type of DatabaseObjects handled by this Algorithm
- * @param <D> Distance type
*/
-
@Title("DWOF: Dynamic Window Outlier Factor")
@Description("Algorithm to compute dynamic-window outlier factors in a database based on the neighborhood size parameter 'k'")
-@Reference(authors = "R. Momtaz, N. Mohssen, M. A. Gowayyed", title = "DWOF: A Robust Density-Based OutlierDetection Approach", booktitle = "Pattern Recognition and Image Analysis, Proc. 6th Iberian Conference, IbPRIA 2013, Funchal, Madeira, Portugal, 2013.", url = "http://dx.doi.org/10.1007%2F978-3-642-38628-2_61")
-public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "R. Momtaz, N. Mohssen, M. A. Gowayyed", //
+title = "DWOF: A Robust Density-Based Outlier Detection Approach", //
+booktitle = "Pattern Recognition and Image Analysis, Proc. 6th Iberian Conference, IbPRIA 2013, Funchal, Madeira, Portugal, 2013.", url = "http://dx.doi.org/10.1007%2F978-3-642-38628-2_61")
+public class DWOF<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -122,7 +122,7 @@ public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
* @param k the value of k
* @param delta Radius increase factor
*/
- public DWOF(DistanceFunction<? super O, D> distanceFunction, int k, double delta) {
+ public DWOF(DistanceFunction<? super O> distanceFunction, int k, double delta) {
super(distanceFunction);
this.k = k + 1;
this.delta = delta;
@@ -138,10 +138,10 @@ public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
*/
public OutlierResult run(Database database, Relation<O> relation) {
final DBIDs ids = relation.getDBIDs();
- DistanceQuery<O, D> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
+ DistanceQuery<O> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
// Get k nearest neighbor and range query on the relation.
- KNNQuery<O, D> knnq = database.getKNNQuery(distFunc, k, DatabaseQuery.HINT_HEAVY_USE);
- RangeQuery<O, D> rnnQuery = database.getRangeQuery(distFunc, DatabaseQuery.HINT_HEAVY_USE);
+ KNNQuery<O> knnq = database.getKNNQuery(distFunc, k, DatabaseQuery.HINT_HEAVY_USE);
+ RangeQuery<O> rnnQuery = database.getRangeQuery(distFunc, DatabaseQuery.HINT_HEAVY_USE);
StepProgress stepProg = LOG.isVerbose() ? new StepProgress("DWOF", 2) : null;
// DWOF output score storage.
@@ -160,9 +160,7 @@ public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
}
IndefiniteProgress clusEvalProgress = LOG.isVerbose() ? new IndefiniteProgress("Evaluating DWOFs", LOG) : null;
while(countUnmerged > 0) {
- if(clusEvalProgress != null) {
- clusEvalProgress.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(clusEvalProgress);
// Increase radii
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
radii.putDouble(iter, radii.doubleValue(iter) * delta);
@@ -185,19 +183,15 @@ public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
dwofs.putDouble(iter, dwofs.doubleValue(iter) + newScore);
}
}
- if(clusEvalProgress != null) {
- clusEvalProgress.setCompleted(LOG);
- }
- if(stepProg != null) {
- stepProg.setCompleted(LOG);
- }
+ LOG.setCompleted(clusEvalProgress);
+ LOG.setCompleted(stepProg);
// Build result representation.
DoubleMinMax minmax = new DoubleMinMax();
for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
minmax.put(dwofs.doubleValue(iter));
}
OutlierScoreMeta meta = new InvertedOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY);
- Relation<Double> rel = new MaterializedRelation<>("Dynamic-Window Outlier Factors", "dwof-outlier", TypeUtil.DOUBLE, dwofs, ids);
+ DoubleRelation rel = new MaterializedDoubleRelation("Dynamic-Window Outlier Factors", "dwof-outlier", dwofs, ids);
return new OutlierResult(meta, rel);
}
@@ -213,7 +207,7 @@ public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
* @param knnq kNN search function
* @param radii WritableDoubleDataStore to store radii
*/
- private void initializeRadii(DBIDs ids, KNNQuery<O, D> knnq, DistanceQuery<O, D> distFunc, WritableDoubleDataStore radii) {
+ private void initializeRadii(DBIDs ids, KNNQuery<O> knnq, DistanceQuery<O> distFunc, WritableDoubleDataStore radii) {
FiniteProgress avgDistProgress = LOG.isVerbose() ? new FiniteProgress("Calculating average kNN distances-", ids.size(), LOG) : null;
double absoluteMinDist = Double.POSITIVE_INFINITY;
double minAvgDist = Double.POSITIVE_INFINITY;
@@ -221,7 +215,7 @@ public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
Mean mean = new Mean();
// Iterate over all objects
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- KNNList<D> iterNeighbors = knnq.getKNNForDBID(iter, k);
+ KNNList iterNeighbors = knnq.getKNNForDBID(iter, k);
// skip the point itself
mean.reset();
for(DBIDIter neighbor1 = iterNeighbors.iter(); neighbor1.valid(); neighbor1.advance()) {
@@ -232,7 +226,7 @@ public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
if(DBIDUtil.equal(neighbor1, neighbor2) || DBIDUtil.equal(neighbor2, iter)) {
continue;
}
- double distance = distFunc.distance(neighbor1, neighbor2).doubleValue();
+ double distance = distFunc.distance(neighbor1, neighbor2);
mean.put(distance);
if(distance > 0. && distance < absoluteMinDist) {
absoluteMinDist = distance;
@@ -244,13 +238,9 @@ public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
if(currentMean < minAvgDist) {
minAvgDist = currentMean;
}
- if(avgDistProgress != null) {
- avgDistProgress.incrementProcessed(LOG);
- }
- }
- if(avgDistProgress != null) {
- avgDistProgress.ensureCompleted(LOG);
+ LOG.incrementProcessed(avgDistProgress);
}
+ LOG.ensureCompleted(avgDistProgress);
// Initializing the radii of all objects.
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
@@ -272,7 +262,7 @@ public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
* @param radii Radii to cluster accordingly
* @param labels Label storage.
*/
- private void clusterData(DBIDs ids, RangeQuery<O, D> rnnQuery, WritableDoubleDataStore radii, WritableDataStore<ModifiableDBIDs> labels) {
+ private void clusterData(DBIDs ids, RangeQuery<O> rnnQuery, WritableDoubleDataStore radii, WritableDataStore<ModifiableDBIDs> labels) {
FiniteProgress clustProg = LOG.isVerbose() ? new FiniteProgress("Density-Based Clustering", ids.size(), LOG) : null;
// Iterate over all objects
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
@@ -282,18 +272,16 @@ public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
ModifiableDBIDs newCluster = DBIDUtil.newArray();
newCluster.add(iter);
labels.put(iter, newCluster);
- if(clustProg != null) {
- clustProg.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(clustProg);
// container of the points to be added and their radii neighbors to the
// cluster
ModifiableDBIDs nChain = DBIDUtil.newArray();
nChain.add(iter);
// iterate over nChain
for(DBIDIter toGetNeighbors = nChain.iter(); toGetNeighbors.valid(); toGetNeighbors.advance()) {
- D range = rnnQuery.getDistanceFactory().fromDouble(radii.doubleValue(toGetNeighbors));
- DistanceDBIDList<D> nNeighbors = rnnQuery.getRangeForDBID(toGetNeighbors, range);
- for(DistanceDBIDListIter<D> iter2 = nNeighbors.iter(); iter2.valid(); iter2.advance()) {
+ double range = radii.doubleValue(toGetNeighbors);
+ DoubleDBIDList nNeighbors = rnnQuery.getRangeForDBID(toGetNeighbors, range);
+ for(DoubleDBIDListIter iter2 = nNeighbors.iter(); iter2.valid(); iter2.advance()) {
if(DBIDUtil.equal(toGetNeighbors, iter2)) {
continue;
}
@@ -301,9 +289,7 @@ public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
newCluster.add(iter2);
labels.put(iter2, newCluster);
nChain.add(iter2);
- if(clustProg != null) {
- clustProg.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(clustProg);
}
else if(labels.get(iter2) != newCluster) {
ModifiableDBIDs toBeDeleted = labels.get(iter2);
@@ -316,9 +302,7 @@ public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
}
}
}
- if(clustProg != null) {
- clustProg.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(clustProg);
}
/**
@@ -360,8 +344,10 @@ public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
* @author Omar Yousry
*
* @apiviz.exclude
+ *
+ * @param <O> Object type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Option ID for the number of neighbors.
*/
@@ -400,7 +386,7 @@ public class DWOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
}
@Override
- protected DWOF<O, D> makeInstance() {
+ protected DWOF<O> makeInstance() {
return new DWOF<>(distanceFunction, k, delta);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/GaussianModel.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/GaussianModel.java
index 3f8bb484..2383824e 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/GaussianModel.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/GaussianModel.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier;
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,7 +30,8 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.logging.Logging;
@@ -60,7 +61,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
*/
@Title("Gaussian Model Outlier Detection")
@Description("Fit a multivariate gaussian model onto the data, and use the PDF to compute an outlier score.")
-public class GaussianModel<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
+public class GaussianModel<V extends NumberVector> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -136,7 +137,7 @@ public class GaussianModel<V extends NumberVector<?>> extends AbstractAlgorithm<
else {
meta = new InvertedOutlierScoreMeta(mm.getMin(), mm.getMax(), 0.0, Double.POSITIVE_INFINITY);
}
- Relation<Double> res = new MaterializedRelation<>("Gaussian Model Outlier Score", "gaussian-model-outlier", TypeUtil.DOUBLE, oscores, relation.getDBIDs());
+ DoubleRelation res = new MaterializedDoubleRelation("Gaussian Model Outlier Score", "gaussian-model-outlier", oscores, relation.getDBIDs());
return new OutlierResult(meta, res);
}
@@ -157,7 +158,7 @@ public class GaussianModel<V extends NumberVector<?>> extends AbstractAlgorithm<
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
protected boolean invert = false;
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/GaussianUniformMixture.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/GaussianUniformMixture.java
index e6659a8f..53e573e3 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/GaussianUniformMixture.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/GaussianUniformMixture.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier;
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
@@ -36,7 +36,8 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.generic.MaskedDBIDs;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.logging.Logging;
@@ -78,7 +79,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
@Title("Gaussian-Uniform Mixture Model Outlier Detection")
@Description("Fits a mixture model consisting of a Gaussian and a uniform distribution to the data.")
@Reference(prefix = "Generalization using the likelihood gain as outlier score of", authors = "Eskin, Eleazar", title = "Anomaly detection over noisy data using learned probability distributions", booktitle = "Proc. of the Seventeenth International Conference on Machine Learning (ICML-2000)")
-public class GaussianUniformMixture<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
+public class GaussianUniformMixture<V extends NumberVector> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -184,7 +185,7 @@ public class GaussianUniformMixture<V extends NumberVector<?>> extends AbstractA
}
OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 0.0);
- Relation<Double> res = new MaterializedRelation<>("Gaussian Mixture Outlier Score", "gaussian-mixture-outlier", TypeUtil.DOUBLE, oscores, relation.getDBIDs());
+ DoubleRelation res = new MaterializedDoubleRelation("Gaussian Mixture Outlier Score", "gaussian-mixture-outlier", oscores, relation.getDBIDs());
return new OutlierResult(meta, res);
}
@@ -247,7 +248,7 @@ public class GaussianUniformMixture<V extends NumberVector<?>> extends AbstractA
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
protected double l = 1E-7;
protected double c = 0;
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/KNNWeightOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/KNNWeightOutlier.java
deleted file mode 100644
index 88603f09..00000000
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/KNNWeightOutlier.java
+++ /dev/null
@@ -1,189 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2011
- 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.algorithm.AbstractDistanceBasedAlgorithm;
-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.Database;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
-import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-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.MaterializedRelation;
-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.NumberDistance;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
-import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
-import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
-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;
-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.IntParameter;
-
-/**
- * Outlier Detection based on the accumulated distances of a point to its k
- * nearest neighbors.
- *
- * Based on: F. Angiulli, C. Pizzuti: Fast Outlier Detection in High Dimensional
- * Spaces. In: Proc. European Conference on Principles of Knowledge Discovery
- * and Data Mining (PKDD'02), Helsinki, Finland, 2002.
- *
- * @author Lisa Reichert
- *
- * @apiviz.has KNNQuery
- *
- * @param <O> the type of DatabaseObjects handled by this Algorithm
- * @param <D> the type of Distance used by this Algorithm
- */
-@Title("KNNWeight outlier detection")
-@Description("Outlier Detection based on the distances of an object to its k nearest neighbors.")
-@Reference(authors = "F. Angiulli, C. Pizzuti", title = "Fast Outlier Detection in High Dimensional Spaces", booktitle = "Proc. European Conference on Principles of Knowledge Discovery and Data Mining (PKDD'02), Helsinki, Finland, 2002", url = "http://dx.doi.org/10.1007/3-540-45681-3_2")
-public class KNNWeightOutlier<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
- /**
- * The logger for this class.
- */
- private static final Logging LOG = Logging.getLogger(KNNWeightOutlier.class);
-
- /**
- * Parameter to specify the k nearest neighbor
- */
- public static final OptionID K_ID = new OptionID("knnwod.k", "k nearest neighbor");
-
- /**
- * The kNN query used.
- */
- public static final OptionID KNNQUERY_ID = new OptionID("knnwod.knnquery", "kNN query to use");
-
- /**
- * Holds the value of {@link #K_ID}.
- */
- private int k;
-
- /**
- * Constructor with parameters.
- *
- * @param distanceFunction Distance function
- * @param k k Parameter
- */
- public KNNWeightOutlier(DistanceFunction<? super O, D> distanceFunction, int k) {
- super(distanceFunction);
- this.k = k;
- }
-
- /**
- * Runs the algorithm in the timed evaluation part.
- */
- public OutlierResult run(Database database, Relation<O> relation) {
- final DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, getDistanceFunction());
- KNNQuery<O, D> knnQuery = database.getKNNQuery(distanceQuery, k);
-
- if(LOG.isVerbose()) {
- LOG.verbose("computing outlier degree(sum of the distances to the k nearest neighbors");
- }
- FiniteProgress progressKNNWeight = LOG.isVerbose() ? new FiniteProgress("KNNWOD_KNNWEIGHT for objects", relation.size(), LOG) : null;
-
- DoubleMinMax minmax = new DoubleMinMax();
-
- // compute distance to the k nearest neighbor. n objects with the highest
- // distance are flagged as outliers
- WritableDoubleDataStore knnw_score = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- // compute sum of the distances to the k nearest neighbors
-
- final KNNList<D> knn = knnQuery.getKNNForDBID(iditer, k);
- double skn = 0;
- if(knn instanceof DoubleDistanceKNNList) {
- for(DoubleDistanceDBIDListIter neighbor = ((DoubleDistanceKNNList) knn).iter(); neighbor.valid(); neighbor.advance()) {
- skn += neighbor.doubleDistance();
- }
- }
- else {
- for(DistanceDBIDListIter<D> neighbor = knn.iter(); neighbor.valid(); neighbor.advance()) {
- skn += neighbor.getDistance().doubleValue();
- }
- }
- knnw_score.putDouble(iditer, skn);
- minmax.put(skn);
-
- if(progressKNNWeight != null) {
- progressKNNWeight.incrementProcessed(LOG);
- }
- }
- if(progressKNNWeight != null) {
- progressKNNWeight.ensureCompleted(LOG);
- }
-
- Relation<Double> res = new MaterializedRelation<>("Weighted kNN Outlier Score", "knnw-outlier", TypeUtil.DOUBLE, knnw_score, relation.getDBIDs());
- OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 0.0);
- return new OutlierResult(meta, res);
- }
-
- @Override
- public TypeInformation[] getInputTypeRestriction() {
- return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
- }
-
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
- protected int k = 0;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- final IntParameter kP = new IntParameter(K_ID);
- if(config.grab(kP)) {
- k = kP.getValue();
- }
- }
-
- @Override
- protected KNNWeightOutlier<O, D> makeInstance() {
- return new KNNWeightOutlier<>(distanceFunction, k);
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/OPTICSOF.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/OPTICSOF.java
index b1ffae63..61d11935 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/OPTICSOF.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/OPTICSOF.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier;
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 java.util.ArrayList;
import java.util.List;
import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICS;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.OPTICS;
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.Database;
@@ -38,15 +38,15 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.query.range.RangeQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
@@ -60,8 +60,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
/**
- * OPTICSOF provides the Optics-of algorithm, an algorithm to find Local
- * Outliers in a database.
+ * Optics-OF outlier detection algorithm, an algorithm to find Local Outliers in
+ * a database based on ideas from {@link OPTICS} clustering.
* <p>
* Reference:<br>
* Markus M. Breunig, Hans-Peter Kriegel, Raymond T. N, Jörg Sander:<br />
@@ -79,8 +79,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*/
@Title("OPTICS-OF: Identifying Local Outliers")
@Description("Algorithm to compute density-based local outlier factors in a database based on the neighborhood size parameter 'minpts'")
-@Reference(authors = "M. M. Breunig, H.-P. Kriegel, R. Ng, and J. Sander", title = "OPTICS-OF: Identifying Local Outliers", booktitle = "Proc. of the 3rd European Conference on Principles of Knowledge Discovery and Data Mining (PKDD), Prague, Czech Republic", url = "http://springerlink.metapress.com/content/76bx6413gqb4tvta/")
-public class OPTICSOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "M. M. Breunig, H.-P. Kriegel, R. Ng, and J. Sander", //
+title = "OPTICS-OF: Identifying Local Outliers", //
+booktitle = "Proc. of the 3rd European Conference on Principles of Knowledge Discovery and Data Mining (PKDD), Prague, Czech Republic", //
+url = "http://springerlink.metapress.com/content/76bx6413gqb4tvta/")
+public class OPTICSOF<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -97,7 +100,7 @@ public class OPTICSOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanc
* @param distanceFunction distance function
* @param minpts minPts parameter
*/
- public OPTICSOF(DistanceFunction<? super O, D> distanceFunction, int minpts) {
+ public OPTICSOF(DistanceFunction<? super O> distanceFunction, int minpts) {
super(distanceFunction);
this.minpts = minpts;
}
@@ -110,13 +113,13 @@ public class OPTICSOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanc
* @return Outlier detection result
*/
public OutlierResult run(Database database, Relation<O> relation) {
- DistanceQuery<O, D> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
- KNNQuery<O, D> knnQuery = database.getKNNQuery(distQuery, minpts);
- RangeQuery<O, D> rangeQuery = database.getRangeQuery(distQuery);
+ DistanceQuery<O> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
+ KNNQuery<O> knnQuery = database.getKNNQuery(distQuery, minpts);
+ RangeQuery<O> rangeQuery = database.getRangeQuery(distQuery);
DBIDs ids = relation.getDBIDs();
// FIXME: implicit preprocessor.
- WritableDataStore<KNNList<D>> nMinPts = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, KNNList.class);
+ WritableDataStore<KNNList> nMinPts = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, KNNList.class);
WritableDoubleDataStore coreDistance = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
WritableIntegerDataStore minPtsNeighborhoodSize = DataStoreUtil.makeIntegerStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, -1);
@@ -124,10 +127,10 @@ public class OPTICSOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanc
// N_minpts(id) and core-distance(id)
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- KNNList<D> minptsNeighbours = knnQuery.getKNNForDBID(iditer, minpts);
- D d = minptsNeighbours.getKNNDistance();
+ KNNList minptsNeighbours = knnQuery.getKNNForDBID(iditer, minpts);
+ double d = minptsNeighbours.getKNNDistance();
nMinPts.put(iditer, minptsNeighbours);
- coreDistance.putDouble(iditer, d.doubleValue());
+ coreDistance.putDouble(iditer, d);
minPtsNeighborhoodSize.put(iditer, rangeQuery.getRangeForDBID(iditer, d).size());
}
@@ -138,9 +141,9 @@ public class OPTICSOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanc
List<Double> core = new ArrayList<>();
double lrd = 0;
// TODO: optimize for double distances
- for(DistanceDBIDListIter<D> neighbor = nMinPts.get(iditer).iter(); neighbor.valid(); neighbor.advance()) {
+ for(DoubleDBIDListIter neighbor = nMinPts.get(iditer).iter(); neighbor.valid(); neighbor.advance()) {
double coreDist = coreDistance.doubleValue(neighbor);
- double dist = distQuery.distance(iditer, neighbor).doubleValue();
+ double dist = distQuery.distance(iditer, neighbor);
double rd = Math.max(coreDist, dist);
lrd = rd + lrd;
core.add(rd);
@@ -166,7 +169,7 @@ public class OPTICSOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanc
ofminmax.put(of);
}
// Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("OPTICS Outlier Scores", "optics-outlier", TypeUtil.DOUBLE, ofs, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("OPTICS Outlier Scores", "optics-outlier", ofs, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(ofminmax.getMin(), ofminmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 1.0);
return new OutlierResult(scoreMeta, scoreResult);
}
@@ -188,13 +191,13 @@ public class OPTICSOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanc
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
protected int minpts = 0;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final IntParameter param = new IntParameter(OPTICS.MINPTS_ID);
+ final IntParameter param = new IntParameter(OPTICS.Parameterizer.MINPTS_ID);
param.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
if(config.grab(param)) {
minpts = param.getValue();
@@ -202,7 +205,7 @@ public class OPTICSOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanc
}
@Override
- protected OPTICSOF<O, D> makeInstance() {
+ protected OPTICSOF<O> makeInstance() {
return new OPTICSOF<>(distanceFunction, minpts);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/OutlierAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/OutlierAlgorithm.java
index f3ef5ab5..4e0662a1 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/OutlierAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/OutlierAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier;
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/algorithm/outlier/ReferenceBasedOutlierDetection.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/ReferenceBasedOutlierDetection.java
deleted file mode 100644
index d254c9a1..00000000
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/ReferenceBasedOutlierDetection.java
+++ /dev/null
@@ -1,337 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2011
- 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.Collection;
-import java.util.Iterator;
-
-import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-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.Database;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
-import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-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.generic.GenericDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
-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.NumberDistance;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.math.Mean;
-import de.lmu.ifi.dbs.elki.result.ReferencePointsResult;
-import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
-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;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
-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;
-import de.lmu.ifi.dbs.elki.utilities.referencepoints.GridBasedReferencePoints;
-import de.lmu.ifi.dbs.elki.utilities.referencepoints.ReferencePointsHeuristic;
-
-/**
- * <p>
- * provides the Reference-Based Outlier Detection algorithm, an algorithm that
- * computes kNN distances approximately, using reference points.
- * </p>
- * <p>
- * Reference:<br>
- * Y. Pei, O. R. Zaiane, Y. Gao: An Efficient Reference-Based Approach to
- * Outlier Detection in Large Datasets.</br> In: Proc. IEEE Int. Conf. on Data
- * Mining (ICDM'06), Hong Kong, China, 2006.
- * </p>
- *
- * @author Lisa Reichert
- * @author Erich Schubert
- *
- * @apiviz.composedOf ReferencePointsHeuristic
- *
- * @param <V> a type of {@link NumberVector} as a suitable data object for this
- * algorithm
- * @param <D> the distance type processed
- */
-@Title("An Efficient Reference-based Approach to Outlier Detection in Large Datasets")
-@Description("Computes kNN distances approximately, using reference points with various reference point strategies.")
-@Reference(authors = "Y. Pei, O.R. Zaiane, Y. Gao", title = "An Efficient Reference-based Approach to Outlier Detection in Large Datasets", booktitle = "Proc. 6th IEEE Int. Conf. on Data Mining (ICDM '06), Hong Kong, China, 2006", url = "http://dx.doi.org/10.1109/ICDM.2006.17")
-public class ReferenceBasedOutlierDetection<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
- /**
- * The logger for this class.
- */
- private static final Logging LOG = Logging.getLogger(ReferenceBasedOutlierDetection.class);
-
- /**
- * Parameter for the reference points heuristic.
- */
- public static final OptionID REFP_ID = new OptionID("refod.refp", "The heuristic for finding reference points.");
-
- /**
- * Parameter to specify the number of nearest neighbors of an object, to be
- * considered for computing its REFOD_SCORE, must be an integer greater than
- * 1.
- */
- public static final OptionID K_ID = new OptionID("refod.k", "The number of nearest neighbors");
-
- /**
- * Holds the value of {@link #K_ID}.
- */
- private int k;
-
- /**
- * Stores the reference point strategy
- */
- private ReferencePointsHeuristic<V> refp;
-
- /**
- * Distance function to use.
- */
- private DistanceFunction<V, D> distanceFunction;
-
- /**
- * Constructor with parameters.
- *
- * @param k k Parameter
- * @param distanceFunction distance function
- * @param refp Reference points heuristic
- */
- public ReferenceBasedOutlierDetection(int k, DistanceFunction<V, D> distanceFunction, ReferencePointsHeuristic<V> refp) {
- super();
- this.k = k;
- this.distanceFunction = distanceFunction;
- this.refp = refp;
- }
-
- /**
- * Run the algorithm on the given relation.
- *
- * @param database Database
- * @param relation Relation to process
- * @return Outlier result
- */
- public OutlierResult run(Database database, Relation<V> relation) {
- DistanceQuery<V, D> distFunc = database.getDistanceQuery(relation, distanceFunction);
- Collection<V> refPoints = refp.getReferencePoints(relation);
-
- DBIDs ids = relation.getDBIDs();
- // storage of distance/score values.
- WritableDoubleDataStore rbod_score = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC | DataStoreFactory.HINT_HOT);
-
- // Compute density estimation:
- {
- // compute density for one reference point, to initialize the first
- // density
- // value for each object, then update
- final Iterator<V> iter = refPoints.iterator();
- if(!iter.hasNext()) {
- throw new AbortException("Cannot compute ROS without reference points!");
- }
- V firstRef = iter.next();
- // compute distance vector for the first reference point
- DistanceDBIDList<D> firstReferenceDists = computeDistanceVector(firstRef, relation, distFunc);
- for(int l = 0; l < firstReferenceDists.size(); l++) {
- double density = computeDensity(firstReferenceDists, l);
- // Initial value
- rbod_score.putDouble(firstReferenceDists.get(l), density);
- }
- // compute density values for all remaining reference points
- while(iter.hasNext()) {
- V refPoint = iter.next();
- DistanceDBIDList<D> referenceDists = computeDistanceVector(refPoint, relation, distFunc);
- // compute density value for each object
- for(int l = 0; l < referenceDists.size(); l++) {
- double density = computeDensity(referenceDists, l);
- // Update minimum
- if(density < rbod_score.doubleValue(referenceDists.get(l))) {
- rbod_score.putDouble(referenceDists.get(l), density);
- }
- }
- }
- }
- // compute maximum density
- double maxDensity = 0.0;
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- double dens = rbod_score.doubleValue(iditer);
- if(dens > maxDensity) {
- maxDensity = dens;
- }
- }
- // compute ROS
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- double score = 1 - (rbod_score.doubleValue(iditer) / maxDensity);
- rbod_score.putDouble(iditer, score);
- }
-
- // adds reference points to the result. header information for the
- // visualizer to find the reference points in the result
- ReferencePointsResult<V> refp = new ReferencePointsResult<>("Reference points", "reference-points", refPoints);
-
- Relation<Double> scoreResult = new MaterializedRelation<>("Reference-points Outlier Scores", "reference-outlier", TypeUtil.DOUBLE, rbod_score, relation.getDBIDs());
- OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(0.0, 1.0, 0.0, 1.0, 0.0);
- OutlierResult result = new OutlierResult(scoreMeta, scoreResult);
- result.addChildResult(refp);
- return result;
- }
-
- /**
- * Computes for each object the distance to one reference point. (one
- * dimensional representation of the data set)
- *
- * @param refPoint Reference Point Feature Vector
- * @param database database to work on
- * @param distFunc Distance function to use
- * @return array containing the distance to one reference point for each
- * database object and the object id
- */
- protected DistanceDBIDList<D> computeDistanceVector(V refPoint, Relation<V> database, DistanceQuery<V, D> distFunc) {
- // TODO: optimize for double distances?
- GenericDistanceDBIDList<D> referenceDists = new GenericDistanceDBIDList<>(database.size());
- for(DBIDIter iditer = database.iterDBIDs(); iditer.valid(); iditer.advance()) {
- referenceDists.add(distFunc.distance(iditer, refPoint), iditer);
- }
- referenceDists.sort();
- return referenceDists;
- }
-
- /**
- * Computes the density of an object. The density of an object is the
- * distances to the k nearest neighbors. Neighbors and distances are computed
- * approximately. (approximation for kNN distance: instead of a normal NN
- * search the NN of an object are those objects that have a similar distance
- * to a reference point. The k- nearest neighbors of an object are those
- * objects that lay close to the object in the reference distance vector)
- *
- * @param referenceDists vector of the reference distances,
- * @param index index of the current object
- * @return density for one object and reference point
- */
- protected double computeDensity(DistanceDBIDList<D> referenceDists, int index) {
- final DistanceDBIDPair<D> x = referenceDists.get(index);
- final double xDist = x.getDistance().doubleValue();
-
- int lef = index - 1;
- int rig = index + 1;
- Mean mean = new Mean();
- double lef_d = (lef >= 0) ? referenceDists.get(lef).getDistance().doubleValue() : Double.NEGATIVE_INFINITY;
- double rig_d = (rig < referenceDists.size()) ? referenceDists.get(rig).getDistance().doubleValue() : Double.NEGATIVE_INFINITY;
- while(mean.getCount() < k) {
- if(lef >= 0 && rig < referenceDists.size()) {
- // Prefer n or m?
- if(Math.abs(lef_d - xDist) < Math.abs(rig_d - xDist)) {
- mean.put(Math.abs(lef_d - xDist));
- // Update n
- lef--;
- lef_d = (lef >= 0) ? referenceDists.get(lef).getDistance().doubleValue() : Double.NEGATIVE_INFINITY;
- }
- else {
- mean.put(Math.abs(rig_d - xDist));
- // Update right
- rig++;
- rig_d = (rig < referenceDists.size()) ? referenceDists.get(rig).getDistance().doubleValue() : Double.NEGATIVE_INFINITY;
- }
- }
- else {
- if(lef >= 0) {
- // Choose left, since right is not available.
- mean.put(Math.abs(lef_d - xDist));
- // update left
- lef--;
- lef_d = (lef >= 0) ? referenceDists.get(lef).getDistance().doubleValue() : Double.NEGATIVE_INFINITY;
- }
- else if(rig < referenceDists.size()) {
- // Choose right, since left is not available
- mean.put(Math.abs(rig_d - xDist));
- // Update right
- rig++;
- rig_d = (rig < referenceDists.size()) ? referenceDists.get(rig).getDistance().doubleValue() : Double.NEGATIVE_INFINITY;
- }
- else {
- // Not enough objects in database?
- throw new IndexOutOfBoundsException();
- }
- }
- }
-
- return 1.0 / mean.getMean();
- }
-
- @Override
- public TypeInformation[] getInputTypeRestriction() {
- return TypeUtil.array(TypeUtil.NUMBER_VECTOR_FIELD);
- }
-
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<V, D> {
- /**
- * Holds the value of {@link #K_ID}.
- */
- private int k;
-
- /**
- * Stores the reference point strategy
- */
- private ReferencePointsHeuristic<V> refp;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- final IntParameter pK = new IntParameter(K_ID);
- pK.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
- if(config.grab(pK)) {
- k = pK.getValue();
- }
- final ObjectParameter<ReferencePointsHeuristic<V>> refpP = new ObjectParameter<>(REFP_ID, ReferencePointsHeuristic.class, GridBasedReferencePoints.class);
- if(config.grab(refpP)) {
- refp = refpP.instantiateClass(config);
- }
- }
-
- @Override
- protected ReferenceBasedOutlierDetection<V, D> makeInstance() {
- return new ReferenceBasedOutlierDetection<>(k, distanceFunction, refp);
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/SimpleCOP.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/SimpleCOP.java
index 72a727a5..ef8f2192 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/SimpleCOP.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/SimpleCOP.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier;
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,13 +40,14 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.KNNList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
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.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
@@ -81,7 +82,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*/
@Title("Simple COP: Correlation Outlier Probability")
@Reference(authors = "Arthur Zimek", title = "Correlation Clustering. PhD thesis, Chapter 18", booktitle = "")
-public class SimpleCOP<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<V, D, OutlierResult> implements OutlierAlgorithm {
+public class SimpleCOP<V extends NumberVector> extends AbstractDistanceBasedAlgorithm<V, OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -95,7 +96,7 @@ public class SimpleCOP<V extends NumberVector<?>, D extends NumberDistance<D, ?>
/**
* Holds the object performing the dependency derivation
*/
- private DependencyDerivator<V, D> dependencyDerivator;
+ private DependencyDerivator<V> dependencyDerivator;
/**
* Constructor.
@@ -104,14 +105,14 @@ public class SimpleCOP<V extends NumberVector<?>, D extends NumberDistance<D, ?>
* @param k k Parameter
* @param pca PCA runner-
*/
- public SimpleCOP(DistanceFunction<? super V, D> distanceFunction, int k, PCAFilteredRunner<V> pca) {
+ public SimpleCOP(DistanceFunction<? super V> distanceFunction, int k, PCAFilteredRunner pca) {
super(distanceFunction);
this.k = k;
this.dependencyDerivator = new DependencyDerivator<>(null, FormatUtil.NF, pca, 0, false);
}
public OutlierResult run(Database database, Relation<V> data) throws IllegalStateException {
- KNNQuery<V, D> knnQuery = QueryUtil.getKNNQuery(data, getDistanceFunction(), k + 1);
+ KNNQuery<V> knnQuery = QueryUtil.getKNNQuery(data, getDistanceFunction(), k + 1);
DBIDs ids = data.getDBIDs();
@@ -124,7 +125,7 @@ public class SimpleCOP<V extends NumberVector<?>, D extends NumberDistance<D, ?>
FiniteProgress progressLocalPCA = LOG.isVerbose() ? new FiniteProgress("Correlation Outlier Probabilities", data.size(), LOG) : null;
double sqrt2 = Math.sqrt(2.0);
for(DBIDIter id = data.iterDBIDs(); id.valid(); id.advance()) {
- KNNList<D> neighbors = knnQuery.getKNNForDBID(id, k + 1);
+ KNNList neighbors = knnQuery.getKNNForDBID(id, k + 1);
ModifiableDBIDs nids = DBIDUtil.newArray(neighbors);
nids.remove(id);
@@ -147,16 +148,12 @@ public class SimpleCOP<V extends NumberVector<?>, D extends NumberDistance<D, ?>
cop_sol.put(id, depsol);
- if(progressLocalPCA != null) {
- progressLocalPCA.incrementProcessed(LOG);
- }
- }
- if(progressLocalPCA != null) {
- progressLocalPCA.ensureCompleted(LOG);
+ LOG.incrementProcessed(progressLocalPCA);
}
+ LOG.ensureCompleted(progressLocalPCA);
}
// combine results.
- Relation<Double> scoreResult = new MaterializedRelation<>("Original Correlation Outlier Probabilities", "origcop-outlier", TypeUtil.DOUBLE, cop_score, ids);
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Original Correlation Outlier Probabilities", "origcop-outlier", cop_score, ids);
OutlierScoreMeta scoreMeta = new ProbabilisticOutlierScore();
OutlierResult result = new OutlierResult(scoreMeta, scoreResult);
// extra results
@@ -184,7 +181,7 @@ public class SimpleCOP<V extends NumberVector<?>, D extends NumberDistance<D, ?>
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<V, D> {
+ public static class Parameterizer<V extends NumberVector> extends AbstractDistanceBasedAlgorithm.Parameterizer<V> {
/**
* Parameter to specify the number of nearest neighbors of an object to be
* considered for computing its COP_SCORE, must be an integer greater than
@@ -212,7 +209,7 @@ public class SimpleCOP<V extends NumberVector<?>, D extends NumberDistance<D, ?>
/**
* Holds the object performing the dependency derivation
*/
- protected PCAFilteredRunner<V> pca;
+ protected PCAFilteredRunner pca;
@Override
protected void makeOptions(Parameterization config) {
@@ -222,14 +219,14 @@ public class SimpleCOP<V extends NumberVector<?>, D extends NumberDistance<D, ?>
if(config.grab(kP)) {
k = kP.intValue();
}
- ObjectParameter<PCAFilteredRunner<V>> pcaP = new ObjectParameter<>(PCARUNNER_ID, PCAFilteredRunner.class, PCAFilteredRunner.class);
+ ObjectParameter<PCAFilteredRunner> pcaP = new ObjectParameter<>(PCARUNNER_ID, PCAFilteredRunner.class, PCAFilteredRunner.class);
if(config.grab(pcaP)) {
pca = pcaP.instantiateClass(config);
}
}
@Override
- protected SimpleCOP<V, D> makeInstance() {
+ protected SimpleCOP<V> makeInstance() {
return new SimpleCOP<>(distanceFunction, k, pca);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/ABOD.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/anglebased/ABOD.java
index 65447713..35dfb1ee 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/ABOD.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/anglebased/ABOD.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
+package de.lmu.ifi.dbs.elki.algorithm.outlier.anglebased;
/*
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,6 +24,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier;
*/
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
@@ -36,9 +37,9 @@ 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.query.similarity.SimilarityQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.KernelMatrix;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.PolynomialKernelFunction;
@@ -48,6 +49,7 @@ import de.lmu.ifi.dbs.elki.math.MeanVariance;
import de.lmu.ifi.dbs.elki.result.outlier.InvertedOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
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;
@@ -63,9 +65,13 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* dimensional data sets. Exact version, which has cubic runtime (see also
* {@link FastABOD} and {@link LBABOD} for faster versions).
*
- * H.-P. Kriegel, M. Schubert, and A. Zimek: Angle-Based Outlier Detection in
- * High-dimensional Data. In: Proc. 14th ACM SIGKDD Int. Conf. on Knowledge
- * Discovery and Data Mining (KDD '08), Las Vegas, NV, 2008.
+ * Reference:
+ * <p>
+ * H.-P. Kriegel, M. Schubert, and A. Zimek:<br />
+ * Angle-Based Outlier Detection in High-dimensional Data.<br />
+ * In: Proc. 14th ACM SIGKDD Int. Conf. on Knowledge Discovery and Data Mining
+ * (KDD '08), Las Vegas, NV, 2008.
+ * </p>
*
* @author Matthias Schubert (Original Code)
* @author Erich Schubert (ELKIfication)
@@ -74,8 +80,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*/
@Title("ABOD: Angle-Based Outlier Detection")
@Description("Outlier detection using variance analysis on angles, especially for high dimensional data sets.")
-@Reference(authors = "H.-P. Kriegel, M. Schubert, and A. Zimek", title = "Angle-Based Outlier Detection in High-dimensional Data", booktitle = "Proc. 14th ACM SIGKDD Int. Conf. on Knowledge Discovery and Data Mining (KDD '08), Las Vegas, NV, 2008", url = "http://dx.doi.org/10.1145/1401890.1401946")
-public class ABOD<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "H.-P. Kriegel, M. Schubert, A. Zimek", //
+title = "Angle-Based Outlier Detection in High-dimensional Data", //
+booktitle = "Proc. 14th ACM SIGKDD Int. Conf. on Knowledge Discovery and Data Mining (KDD '08), Las Vegas, NV, 2008", //
+url = "http://dx.doi.org/10.1145/1401890.1401946")
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.ABOD", "abod" })
+public class ABOD<V extends NumberVector> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -84,14 +94,14 @@ public class ABOD<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
/**
* Store the configured Kernel version.
*/
- protected SimilarityFunction<? super V, DoubleDistance> kernelFunction;
+ protected SimilarityFunction<? super V> kernelFunction;
/**
* Constructor for Angle-Based Outlier Detection (ABOD).
*
* @param kernelFunction kernel function to use
*/
- public ABOD(SimilarityFunction<? super V, DoubleDistance> kernelFunction) {
+ public ABOD(SimilarityFunction<? super V> kernelFunction) {
super();
this.kernelFunction = kernelFunction;
}
@@ -105,21 +115,21 @@ public class ABOD<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
public OutlierResult run(Database db, Relation<V> relation) {
DBIDs ids = relation.getDBIDs();
// Build a kernel matrix, to make O(n^3) slightly less bad.
- SimilarityQuery<V, DoubleDistance> sq = db.getSimilarityQuery(relation, kernelFunction);
+ SimilarityQuery<V> sq = db.getSimilarityQuery(relation, kernelFunction);
KernelMatrix kernelMatrix = new KernelMatrix(sq, relation, ids);
WritableDoubleDataStore abodvalues = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC);
DoubleMinMax minmaxabod = new DoubleMinMax();
MeanVariance s = new MeanVariance();
- for (DBIDIter pA = ids.iter(); pA.valid(); pA.advance()) {
+ for(DBIDIter pA = ids.iter(); pA.valid(); pA.advance()) {
final double abof = computeABOF(relation, kernelMatrix, pA, s);
minmaxabod.put(abof);
abodvalues.putDouble(pA, abof);
}
// Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("Angle-Based Outlier Degree", "abod-outlier", TypeUtil.DOUBLE, abodvalues, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Angle-Based Outlier Degree", "abod-outlier", abodvalues, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new InvertedOutlierScoreMeta(minmaxabod.getMin(), minmaxabod.getMax(), 0.0, Double.POSITIVE_INFINITY);
return new OutlierResult(scoreMeta, scoreResult);
}
@@ -137,24 +147,24 @@ public class ABOD<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
s.reset(); // Reused
double simAA = kernelMatrix.getSimilarity(pA, pA);
- for (DBIDIter nB = relation.iterDBIDs(); nB.valid(); nB.advance()) {
- if (DBIDUtil.equal(nB, pA)) {
+ for(DBIDIter nB = relation.iterDBIDs(); nB.valid(); nB.advance()) {
+ if(DBIDUtil.equal(nB, pA)) {
continue;
}
double simBB = kernelMatrix.getSimilarity(nB, nB);
double simAB = kernelMatrix.getSimilarity(pA, nB);
double sqdAB = simAA + simBB - simAB - simAB;
- if (!(sqdAB > 0.)) {
+ if(!(sqdAB > 0.)) {
continue;
}
- for (DBIDIter nC = relation.iterDBIDs(); nC.valid(); nC.advance()) {
- if (DBIDUtil.equal(nC, pA) || DBIDUtil.compare(nC, nB) < 0) {
+ for(DBIDIter nC = relation.iterDBIDs(); nC.valid(); nC.advance()) {
+ if(DBIDUtil.equal(nC, pA) || DBIDUtil.compare(nC, nB) < 0) {
continue;
}
double simCC = kernelMatrix.getSimilarity(nC, nC);
double simAC = kernelMatrix.getSimilarity(pA, nC);
double sqdAC = simAA + simCC - simAC;
- if (!(sqdAC > 0.)) {
+ if(!(sqdAC > 0.)) {
continue;
}
// Exploit bilinearity of scalar product:
@@ -190,7 +200,7 @@ public class ABOD<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* Parameter for the kernel function.
*/
@@ -199,13 +209,13 @@ public class ABOD<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
/**
* Distance function.
*/
- protected SimilarityFunction<V, DoubleDistance> kernelFunction = null;
+ protected SimilarityFunction<V> kernelFunction = null;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final ObjectParameter<SimilarityFunction<V, DoubleDistance>> param = new ObjectParameter<>(KERNEL_FUNCTION_ID, SimilarityFunction.class, PolynomialKernelFunction.class);
- if (config.grab(param)) {
+ final ObjectParameter<SimilarityFunction<V>> param = new ObjectParameter<>(KERNEL_FUNCTION_ID, SimilarityFunction.class, PolynomialKernelFunction.class);
+ if(config.grab(param)) {
kernelFunction = param.instantiateClass(config);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/FastABOD.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/anglebased/FastABOD.java
index ee6bd434..56bedaac 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/FastABOD.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/anglebased/FastABOD.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
+package de.lmu.ifi.dbs.elki.algorithm.outlier.anglebased;
/*
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
@@ -35,9 +35,9 @@ 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.DoubleDBIDPair;
import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.KernelMatrix;
import de.lmu.ifi.dbs.elki.logging.Logging;
@@ -46,6 +46,7 @@ import de.lmu.ifi.dbs.elki.math.MeanVariance;
import de.lmu.ifi.dbs.elki.result.outlier.InvertedOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMaxHeap;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ObjectHeap;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
@@ -60,9 +61,13 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*
* Fast-ABOD (approximateABOF) version.
*
- * H.-P. Kriegel, M. Schubert, and A. Zimek: Angle-Based Outlier Detection in
- * High-dimensional Data. In: Proc. 14th ACM SIGKDD Int. Conf. on Knowledge
- * Discovery and Data Mining (KDD '08), Las Vegas, NV, 2008.
+ * Reference:
+ * <p>
+ * H.-P. Kriegel, M. Schubert, and A. Zimek:<br />
+ * Angle-Based Outlier Detection in High-dimensional Data.<br />
+ * In: Proc. 14th ACM SIGKDD Int. Conf. on Knowledge Discovery and Data Mining
+ * (KDD '08), Las Vegas, NV, 2008.
+ * </p>
*
* @author Matthias Schubert (Original Code)
* @author Erich Schubert (ELKIfication)
@@ -71,8 +76,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*/
@Title("Approximate ABOD: Angle-Based Outlier Detection")
@Description("Outlier detection using variance analysis on angles, especially for high dimensional data sets.")
-@Reference(authors = "H.-P. Kriegel, M. Schubert, and A. Zimek", title = "Angle-Based Outlier Detection in High-dimensional Data", booktitle = "Proc. 14th ACM SIGKDD Int. Conf. on Knowledge Discovery and Data Mining (KDD '08), Las Vegas, NV, 2008", url = "http://dx.doi.org/10.1145/1401890.1401946")
-public class FastABOD<V extends NumberVector<?>> extends ABOD<V> {
+@Reference(authors = "H.-P. Kriegel, M. Schubert, A. Zimek", //
+title = "Angle-Based Outlier Detection in High-dimensional Data", //
+booktitle = "Proc. 14th ACM SIGKDD Int. Conf. on Knowledge Discovery and Data Mining (KDD '08), Las Vegas, NV, 2008", //
+url = "http://dx.doi.org/10.1145/1401890.1401946")
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.FastABOD", "fastabod" })
+public class FastABOD<V extends NumberVector> extends ABOD<V> {
/**
* The logger for this class.
*/
@@ -89,7 +98,7 @@ public class FastABOD<V extends NumberVector<?>> extends ABOD<V> {
* @param kernelFunction kernel function to use
* @param k Number of nearest neighbors
*/
- public FastABOD(SimilarityFunction<? super V, DoubleDistance> kernelFunction, int k) {
+ public FastABOD(SimilarityFunction<? super V> kernelFunction, int k) {
super(kernelFunction);
this.k = k;
}
@@ -104,51 +113,52 @@ public class FastABOD<V extends NumberVector<?>> extends ABOD<V> {
public OutlierResult run(Database db, Relation<V> relation) {
DBIDs ids = relation.getDBIDs();
// Build a kernel matrix, to make O(n^3) slightly less bad.
- SimilarityQuery<V, DoubleDistance> sq = db.getSimilarityQuery(relation, kernelFunction);
+ SimilarityQuery<V> sq = db.getSimilarityQuery(relation, kernelFunction);
KernelMatrix kernelMatrix = new KernelMatrix(sq, relation, ids);
WritableDoubleDataStore abodvalues = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC);
DoubleMinMax minmaxabod = new DoubleMinMax();
MeanVariance s = new MeanVariance();
- for (DBIDIter pA = ids.iter(); pA.valid(); pA.advance()) {
+ for(DBIDIter pA = ids.iter(); pA.valid(); pA.advance()) {
s.reset();
final double simAA = kernelMatrix.getSimilarity(pA, pA);
// Choose the k-min nearest
ComparableMaxHeap<DoubleDBIDPair> nn = new ComparableMaxHeap<>(k);
- for (DBIDIter nB = relation.iterDBIDs(); nB.valid(); nB.advance()) {
- if (DBIDUtil.equal(nB, pA)) {
+ for(DBIDIter nB = relation.iterDBIDs(); nB.valid(); nB.advance()) {
+ if(DBIDUtil.equal(nB, pA)) {
continue;
}
double simBB = kernelMatrix.getSimilarity(nB, nB);
double simAB = kernelMatrix.getSimilarity(pA, nB);
double sqdAB = simAA + simBB - simAB - simAB;
- if (!(sqdAB > 0.)) {
+ if(!(sqdAB > 0.)) {
continue;
}
- if (nn.size() < k) {
+ if(nn.size() < k) {
nn.add(DBIDUtil.newPair(sqdAB, nB));
- } else if (sqdAB < nn.peek().doubleValue()) {
+ }
+ else if(sqdAB < nn.peek().doubleValue()) {
nn.replaceTopElement(DBIDUtil.newPair(sqdAB, nB));
}
}
- for (ObjectHeap.UnsortedIter<DoubleDBIDPair> iB = nn.unsortedIter(); iB.valid(); iB.advance()) {
+ for(ObjectHeap.UnsortedIter<DoubleDBIDPair> iB = nn.unsortedIter(); iB.valid(); iB.advance()) {
DoubleDBIDPair nB = iB.get();
double sqdAB = nB.doubleValue();
double simAB = kernelMatrix.getSimilarity(pA, nB);
- if (!(sqdAB > 0.)) {
+ if(!(sqdAB > 0.)) {
continue;
}
- for (ObjectHeap.UnsortedIter<DoubleDBIDPair> iC = nn.unsortedIter(); iC.valid(); iC.advance()) {
+ for(ObjectHeap.UnsortedIter<DoubleDBIDPair> iC = nn.unsortedIter(); iC.valid(); iC.advance()) {
DoubleDBIDPair nC = iC.get();
- if (DBIDUtil.compare(nC, nB) < 0) {
+ if(DBIDUtil.compare(nC, nB) < 0) {
continue;
}
double sqdAC = nC.doubleValue();
double simAC = kernelMatrix.getSimilarity(pA, nC);
- if (!(sqdAC > 0.)) {
+ if(!(sqdAC > 0.)) {
continue;
}
// Exploit bilinearity of scalar product:
@@ -169,7 +179,7 @@ public class FastABOD<V extends NumberVector<?>> extends ABOD<V> {
}
// Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("Angle-Based Outlier Degree", "abod-outlier", TypeUtil.DOUBLE, abodvalues, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Angle-Based Outlier Degree", "abod-outlier", abodvalues, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new InvertedOutlierScoreMeta(minmaxabod.getMin(), minmaxabod.getMax(), 0.0, Double.POSITIVE_INFINITY);
return new OutlierResult(scoreMeta, scoreResult);
}
@@ -191,7 +201,7 @@ public class FastABOD<V extends NumberVector<?>> extends ABOD<V> {
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends ABOD.Parameterizer<V> {
+ public static class Parameterizer<V extends NumberVector> extends ABOD.Parameterizer<V> {
/**
* Parameter for the nearest neighbors.
*/
@@ -206,7 +216,7 @@ public class FastABOD<V extends NumberVector<?>> extends ABOD<V> {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
final IntParameter kP = new IntParameter(K_ID);
- if (config.grab(kP)) {
+ if(config.grab(kP)) {
k = kP.intValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/LBABOD.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/anglebased/LBABOD.java
index 37b4d050..0ef19a50 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/LBABOD.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/anglebased/LBABOD.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
+package de.lmu.ifi.dbs.elki.algorithm.outlier.anglebased;
/*
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
@@ -35,9 +35,9 @@ 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.DoubleDBIDPair;
import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.KernelMatrix;
import de.lmu.ifi.dbs.elki.logging.Logging;
@@ -49,6 +49,7 @@ import de.lmu.ifi.dbs.elki.math.MeanVariance;
import de.lmu.ifi.dbs.elki.result.outlier.InvertedOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMaxHeap;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.DoubleMinHeap;
@@ -70,9 +71,13 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* Outlier detection using variance analysis on angles, especially for high
* dimensional data sets.
*
- * H.-P. Kriegel, M. Schubert, and A. Zimek: Angle-Based Outlier Detection in
- * High-dimensional Data. In: Proc. 14th ACM SIGKDD Int. Conf. on Knowledge
- * Discovery and Data Mining (KDD '08), Las Vegas, NV, 2008.
+ * Reference:
+ * <p>
+ * H.-P. Kriegel, M. Schubert, and A. Zimek:<br />
+ * Angle-Based Outlier Detection in High-dimensional Data.<br />
+ * In: Proc. 14th ACM SIGKDD Int. Conf. on Knowledge Discovery and Data Mining
+ * (KDD '08), Las Vegas, NV, 2008.
+ * </p>
*
* @author Matthias Schubert (Original Code)
* @author Erich Schubert (ELKIfication)
@@ -81,8 +86,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*/
@Title("LB-ABOD: Lower Bounded Angle-Based Outlier Detection")
@Description("Outlier detection using variance analysis on angles, especially for high dimensional data sets.")
-@Reference(authors = "H.-P. Kriegel, M. Schubert, and A. Zimek", title = "Angle-Based Outlier Detection in High-dimensional Data", booktitle = "Proc. 14th ACM SIGKDD Int. Conf. on Knowledge Discovery and Data Mining (KDD '08), Las Vegas, NV, 2008", url = "http://dx.doi.org/10.1145/1401890.1401946")
-public class LBABOD<V extends NumberVector<?>> extends FastABOD<V> {
+@Reference(authors = "H.-P. Kriegel, M. Schubert, A. Zimek", //
+title = "Angle-Based Outlier Detection in High-dimensional Data", //
+booktitle = "Proc. 14th ACM SIGKDD Int. Conf. on Knowledge Discovery and Data Mining (KDD '08), Las Vegas, NV, 2008", //
+url = "http://dx.doi.org/10.1145/1401890.1401946")
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.LBABOD", "lb-abod" })
+public class LBABOD<V extends NumberVector> extends FastABOD<V> {
/**
* The logger for this class.
*/
@@ -100,7 +109,7 @@ public class LBABOD<V extends NumberVector<?>> extends FastABOD<V> {
* @param k k parameter
* @param l Number of outliers to find exact
*/
- public LBABOD(SimilarityFunction<? super V, DoubleDistance> kernelFunction, int k, int l) {
+ public LBABOD(SimilarityFunction<? super V> kernelFunction, int k, int l) {
super(kernelFunction, k);
this.l = l;
}
@@ -114,7 +123,7 @@ public class LBABOD<V extends NumberVector<?>> extends FastABOD<V> {
@Override
public OutlierResult run(Database db, Relation<V> relation) {
DBIDs ids = relation.getDBIDs();
- SimilarityQuery<V, DoubleDistance> sq = relation.getDatabase().getSimilarityQuery(relation, kernelFunction);
+ SimilarityQuery<V> sq = db.getSimilarityQuery(relation, kernelFunction);
KernelMatrix kernelMatrix = new KernelMatrix(sq, relation, ids);
// Output storage.
@@ -237,7 +246,7 @@ public class LBABOD<V extends NumberVector<?>> extends FastABOD<V> {
LOG.statistics(new LongStatistic("lb-abod.refinements", refinements));
}
// Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("Angle-based Outlier Detection", "abod-outlier", TypeUtil.DOUBLE, abodvalues, ids);
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Angle-based Outlier Detection", "abod-outlier", abodvalues, ids);
OutlierScoreMeta scoreMeta = new InvertedOutlierScoreMeta(minmaxabod.getMin(), minmaxabod.getMax(), 0.0, Double.POSITIVE_INFINITY);
return new OutlierResult(scoreMeta, scoreResult);
}
@@ -259,7 +268,7 @@ public class LBABOD<V extends NumberVector<?>> extends FastABOD<V> {
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends FastABOD.Parameterizer<V> {
+ public static class Parameterizer<V extends NumberVector> extends FastABOD.Parameterizer<V> {
/**
* Parameter to specify the number of outliers to compute exactly.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/anglebased/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/anglebased/package-info.java
new file mode 100644
index 00000000..f729559f
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/anglebased/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Angle-based outlier detection algorithms.
+ */
+
+/*
+ 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.algorithm.outlier.anglebased; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/EMOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/EMOutlier.java
index 76191cf2..5a02fb56 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/EMOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/EMOutlier.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
+package de.lmu.ifi.dbs.elki.algorithm.outlier.clustering;
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,10 +24,10 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier;
*/
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.EM;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.em.EM;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.model.EMModel;
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.Database;
@@ -35,7 +35,8 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.result.Result;
@@ -64,7 +65,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
// TODO: re-use an existing EM when present?
@Title("EM Outlier: Outlier Detection based on the generic EM clustering")
@Description("The outlier score assigned is based on the highest cluster probability obtained from EM clustering.")
-public class EMOutlier<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
+public class EMOutlier<V extends NumberVector> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -73,14 +74,14 @@ public class EMOutlier<V extends NumberVector<?>> extends AbstractAlgorithm<Outl
/**
* Inner algorithm.
*/
- private EM<V> emClustering;
+ private EM<V, ?> emClustering;
/**
* Constructor with an existing em clustering algorithm.
*
* @param emClustering EM clustering algorithm to use.
*/
- public EMOutlier(EM<V> emClustering) {
+ public EMOutlier(EM<V, ?> emClustering) {
super();
this.emClustering = emClustering;
}
@@ -94,13 +95,13 @@ public class EMOutlier<V extends NumberVector<?>> extends AbstractAlgorithm<Outl
*/
public OutlierResult run(Database database, Relation<V> relation) {
emClustering.setSoft(true);
- Clustering<EMModel<V>> emresult = emClustering.run(database, relation);
+ Clustering<?> emresult = emClustering.run(database, relation);
Relation<double[]> soft = null;
- for (Iter<Result> iter = emresult.getHierarchy().iterChildren(emresult); iter.valid(); iter.advance()) {
- if (!(iter.get() instanceof Relation)) {
+ for(Iter<Result> iter = emresult.getHierarchy().iterChildren(emresult); iter.valid(); iter.advance()) {
+ if(!(iter.get() instanceof Relation)) {
continue;
}
- if (((Relation<?>) iter.get()).getDataTypeInformation() == EM.SOFT_TYPE) {
+ if(((Relation<?>) iter.get()).getDataTypeInformation() == EM.SOFT_TYPE) {
@SuppressWarnings("unchecked")
Relation<double[]> rel = (Relation<double[]>) iter.get();
soft = rel;
@@ -109,16 +110,16 @@ public class EMOutlier<V extends NumberVector<?>> extends AbstractAlgorithm<Outl
double globmax = 0.0;
WritableDoubleDataStore emo_score = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT);
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
double maxProb = Double.POSITIVE_INFINITY;
double[] probs = soft.get(iditer);
- for (double prob : probs) {
+ for(double prob : probs) {
maxProb = Math.min(1. - prob, maxProb);
}
emo_score.putDouble(iditer, maxProb);
globmax = Math.max(maxProb, globmax);
}
- Relation<Double> scoreres = new MaterializedRelation<>("EM outlier scores", "em-outlier", TypeUtil.DOUBLE, emo_score, relation.getDBIDs());
+ DoubleRelation scoreres = new MaterializedDoubleRelation("EM outlier scores", "em-outlier", emo_score, relation.getDBIDs());
OutlierScoreMeta meta = new ProbabilisticOutlierScore(0.0, globmax);
// combine results.
OutlierResult result = new OutlierResult(meta, scoreres);
@@ -144,13 +145,16 @@ public class EMOutlier<V extends NumberVector<?>> extends AbstractAlgorithm<Outl
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
- protected EM<V> em = null;
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * EM clustering algorithm to run.
+ */
+ protected EM<V, ?> em;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- Class<EM<V>> cls = ClassGenericsUtil.uglyCastIntoSubclass(EM.class);
+ Class<EM<V, ?>> cls = ClassGenericsUtil.uglyCastIntoSubclass(EM.class);
em = config.tryInstantiate(cls);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/KMeansOutlierDetection.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/KMeansOutlierDetection.java
new file mode 100644
index 00000000..c6155527
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/KMeansOutlierDetection.java
@@ -0,0 +1,178 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.clustering;
+
+/*
+ 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.List;
+
+import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeans;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansLloyd;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.ModelUtil;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
+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.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+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;
+
+/**
+ * Outlier detection by using k-means clustering.
+ *
+ * The scores are assigned by the objects distance to the nearest center.
+ *
+ * We don't have a clear reference for this approach, but it seems to be a best
+ * practise in some areas to remove objects that have the largest distance from
+ * their center. If you need to cite this approach, please cite the ELKI version
+ * you used (use the <a href="http://elki.dbs.ifi.lmu.de/wiki/Publications">ELKI
+ * publication list</a> for citation information and BibTeX templates).
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has KMeans
+ *
+ * @param <O> Object type
+ */
+public class KMeansOutlierDetection<O extends NumberVector> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(KMeansOutlierDetection.class);
+
+ /**
+ * Clustering algorithm to use
+ */
+ KMeans<O, ?> clusterer;
+
+ /**
+ * Constructor.
+ *
+ * @param clusterer Clustering algorithm
+ */
+ public KMeansOutlierDetection(KMeans<O, ?> clusterer) {
+ super();
+ this.clusterer = clusterer;
+ }
+
+ /**
+ * Run the outlier detection algorithm.
+ *
+ * @param database Database
+ * @param relation Relation
+ * @return Outlier detection result
+ */
+ public OutlierResult run(Database database, Relation<O> relation) {
+ DistanceFunction<? super O> df = clusterer.getDistanceFunction();
+ DistanceQuery<O> dq = database.getDistanceQuery(relation, df);
+
+ // TODO: improve ELKI api to ensure we're using the same DBIDs!
+ Clustering<?> c = clusterer.run(database, relation);
+
+ WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_DB);
+ DoubleMinMax mm = new DoubleMinMax();
+
+ @SuppressWarnings("unchecked")
+ NumberVector.Factory<O> factory = (NumberVector.Factory<O>) RelationUtil.assumeVectorField(relation).getFactory();
+ List<? extends Cluster<?>> clusters = c.getAllClusters();
+ for(Cluster<?> cluster : clusters) {
+ // FIXME: use a primitive distance function on number vectors instead.
+ O mean = factory.newNumberVector(ModelUtil.getPrototype(cluster.getModel(), relation));
+ for(DBIDIter iter = cluster.getIDs().iter(); iter.valid(); iter.advance()) {
+ double dist = dq.distance(mean, iter);
+ scores.put(iter, dist);
+ mm.put(dist);
+ }
+ }
+
+ // Build result representation.
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("KMeans outlier scores", "kmeans-outlier", scores, relation.getDBIDs());
+ OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(mm.getMin(), mm.getMax(), 0., Double.POSITIVE_INFINITY, 0.);
+ return new OutlierResult(scoreMeta, scoreResult);
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(clusterer.getDistanceFunction().getInputTypeRestriction());
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterizer.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <O> Object type
+ */
+ public static class Parameterizer<O extends NumberVector> extends AbstractParameterizer {
+ /**
+ * Parameter for choosing the clustering algorithm.
+ */
+ public static final OptionID CLUSTERING_ID = new OptionID("kmeans.algorithm", //
+ "Clustering algorithm to use for detecting outliers.");
+
+ /**
+ * Clustering algorithm to use
+ */
+ KMeans<O, ?> clusterer;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ ObjectParameter<KMeans<O, ?>> clusterP = new ObjectParameter<>(CLUSTERING_ID, KMeans.class, KMeansLloyd.class);
+ if(config.grab(clusterP)) {
+ clusterer = clusterP.instantiateClass(config);
+ }
+ }
+
+ @Override
+ protected KMeansOutlierDetection<O> makeInstance() {
+ return new KMeansOutlierDetection<>(clusterer);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/SilhouetteOutlierDetection.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/SilhouetteOutlierDetection.java
new file mode 100644
index 00000000..3bd9cf8b
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/SilhouetteOutlierDetection.java
@@ -0,0 +1,253 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.clustering;
+
+/*
+ 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.List;
+
+import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.ClusteringAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+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.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.evaluation.clustering.internal.EvaluateSilhouette;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.result.outlier.InvertedOutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+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.Flag;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
+
+/**
+ * Outlier detection by using the Silhouette Coefficients.
+ *
+ * Silhouette values are computed as in:
+ * <p>
+ * P. J. Rousseeuw<br />
+ * Silhouettes: A graphical aid to the interpretation and validation of cluster
+ * analysis<br />
+ * In: Journal of Computational and Applied Mathematics Volume 20, November 1987
+ * </p>
+ *
+ * but then used as outlier scores. To cite this outlier detection approach,
+ * please cite the ELKI version you used (use the <a
+ * href="http://elki.dbs.ifi.lmu.de/wiki/Publications">ELKI publication list</a>
+ * for citation information and BibTeX templates).
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has ClusteringAlgorithm
+ *
+ * @param <O> Object type
+ */
+@Reference(authors = "P. J. Rousseeuw", //
+title = "Silhouettes: A graphical aid to the interpretation and validation of cluster analysis", //
+booktitle = "Journal of Computational and Applied Mathematics, Volume 20", //
+url = "http://dx.doi.org/10.1016%2F0377-0427%2887%2990125-7")
+public class SilhouetteOutlierDetection<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(SilhouetteOutlierDetection.class);
+
+ /**
+ * Clustering algorithm to use
+ */
+ ClusteringAlgorithm<?> clusterer;
+
+ /**
+ * Keep noise "clusters" merged, instead of breaking them into singletons.
+ */
+ private boolean mergenoise = false;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function
+ * @param clusterer Clustering algorithm
+ * @param mergenoise Flag to keep "noise" clusters merged, instead of breaking
+ * them into singletons.
+ */
+ public SilhouetteOutlierDetection(DistanceFunction<? super O> distanceFunction, ClusteringAlgorithm<?> clusterer, boolean mergenoise) {
+ super(distanceFunction);
+ this.clusterer = clusterer;
+ this.mergenoise = mergenoise;
+ }
+
+ @Override
+ public OutlierResult run(Database database) {
+ Relation<O> relation = database.getRelation(getDistanceFunction().getInputTypeRestriction());
+ DistanceQuery<O> dq = database.getDistanceQuery(relation, getDistanceFunction());
+
+ // TODO: improve ELKI api to ensure we're using the same DBIDs!
+ Clustering<?> c = clusterer.run(database);
+
+ WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_DB);
+ DoubleMinMax mm = new DoubleMinMax();
+
+ List<? extends Cluster<?>> clusters = c.getAllClusters();
+ for(Cluster<?> cluster : clusters) {
+ if(cluster.size() <= 1 || (!mergenoise && cluster.isNoise())) {
+ // As suggested in Rousseeuw, we use 0 for singletons.
+ for(DBIDIter iter = cluster.getIDs().iter(); iter.valid(); iter.advance()) {
+ scores.put(iter, 0.);
+ }
+ mm.put(0.);
+ continue;
+ }
+ ArrayDBIDs ids = DBIDUtil.ensureArray(cluster.getIDs());
+ double[] as = new double[ids.size()]; // temporary storage.
+ DBIDArrayIter it1 = ids.iter(), it2 = ids.iter();
+ for(it1.seek(0); it1.valid(); it1.advance()) {
+ // a: In-cluster distances
+ double a = as[it1.getOffset()]; // Already computed distances
+ for(it2.seek(it1.getOffset() + 1); it2.valid(); it2.advance()) {
+ final double dist = dq.distance(it1, it2);
+ a += dist;
+ as[it2.getOffset()] += dist;
+ }
+ a /= (ids.size() - 1);
+ // b: other clusters:
+ double min = Double.POSITIVE_INFINITY;
+ for(Cluster<?> ocluster : clusters) {
+ if(ocluster == /* yes, reference identity */cluster) {
+ continue;
+ }
+ if(!mergenoise && ocluster.isNoise()) {
+ // Treat noise cluster as singletons:
+ for(DBIDIter it3 = ocluster.getIDs().iter(); it3.valid(); it3.advance()) {
+ double dist = dq.distance(it1, it3);
+ if(dist < min) {
+ min = dist;
+ }
+ }
+ continue;
+ }
+ final DBIDs oids = ocluster.getIDs();
+ double b = 0.;
+ for(DBIDIter it3 = oids.iter(); it3.valid(); it3.advance()) {
+ b += dq.distance(it1, it3);
+ }
+ b /= oids.size();
+ if(b < min) {
+ min = b;
+ }
+ }
+ final double score = (min - a) / Math.max(min, a);
+ scores.put(it1, score);
+ mm.put(score);
+ }
+ }
+
+ // Build result representation.
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Silhouette Coefficients", "silhouette-outlier", scores, relation.getDBIDs());
+ OutlierScoreMeta scoreMeta = new InvertedOutlierScoreMeta(mm.getMin(), mm.getMax(), -1., 1., .5);
+ return new OutlierResult(scoreMeta, scoreResult);
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ final TypeInformation dt = getDistanceFunction().getInputTypeRestriction();
+ TypeInformation[] t = clusterer.getInputTypeRestriction();
+ for(TypeInformation i : t) {
+ if(dt.isAssignableFromType(i)) {
+ return t;
+ }
+ }
+ // Prepend distance type:
+ TypeInformation[] t2 = new TypeInformation[t.length + 1];
+ t2[0] = dt;
+ System.arraycopy(t, 0, t2, 1, t.length);
+ return t2;
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterizer.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <O> Object type
+ */
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * Parameter for choosing the clustering algorithm
+ */
+ public static final OptionID CLUSTERING_ID = new OptionID("silhouette.clustering", //
+ "Clustering algorithm to use for the silhouette coefficients.");
+
+ /**
+ * Clustering algorithm to use
+ */
+ ClusteringAlgorithm<?> clusterer;
+
+ /**
+ * Keep noise "clusters" merged, instead of breaking them into singletons.
+ */
+ private boolean mergenoise = false;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ ObjectParameter<ClusteringAlgorithm<?>> clusterP = new ObjectParameter<>(CLUSTERING_ID, ClusteringAlgorithm.class);
+ if(config.grab(clusterP)) {
+ clusterer = clusterP.instantiateClass(config);
+ }
+
+ Flag noiseP = new Flag(EvaluateSilhouette.Parameterizer.MERGENOISE_ID);
+ if(config.grab(noiseP)) {
+ mergenoise = noiseP.isTrue();
+ }
+ }
+
+ @Override
+ protected SilhouetteOutlierDetection<O> makeInstance() {
+ return new SilhouetteOutlierDetection<>(distanceFunction, clusterer, mergenoise);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/package-info.java
new file mode 100644
index 00000000..15ee771e
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/clustering/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Clustering based outlier detection.
+ */
+
+/*
+ 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.algorithm.outlier.clustering; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/AbstractDBOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/AbstractDBOutlier.java
index 5cafe04d..1fa43ff6 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/AbstractDBOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/AbstractDBOutlier.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
+package de.lmu.ifi.dbs.elki.algorithm.outlier.distance;
/*
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,52 +24,54 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier;
*/
import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
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.Database;
import de.lmu.ifi.dbs.elki.database.datastore.DoubleDataStore;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.Distance;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.ProbabilisticOutlierScore;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
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.DistanceParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
* Simple distance based outlier detection algorithms.
*
+ * Reference:
* <p>
- * Reference: E.M. Knorr, R. T. Ng: Algorithms for Mining Distance-Based
- * Outliers in Large Datasets, In: Procs Int. Conf. on Very Large Databases
- * (VLDB'98), New York, USA, 1998.
+ * E.M. Knorr, R. T. Ng:<br />
+ * Algorithms for Mining Distance-Based Outliers in Large Datasets,<br />
+ * In: Procs Int. Conf. on Very Large Databases (VLDB'98), New York, USA, 1998.
+ * </p>
*
* @author Lisa Reichert
*
* @param <O> the type of DatabaseObjects handled by this Algorithm
- * @param <D> the type of Distance used by this Algorithm
*/
-public abstract class AbstractDBOutlier<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "E.M. Knorr, R. T. Ng", //
+title = "Algorithms for Mining Distance-Based Outliers in Large Datasets", //
+booktitle = "Procs Int. Conf. on Very Large Databases (VLDB'98), New York, USA, 1998")
+public abstract class AbstractDBOutlier<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
- * Parameter to specify the size of the D-neighborhood
+ * Radius parameter d.
*/
- public static final OptionID D_ID = new OptionID("dbod.d", "size of the D-neighborhood");
-
- /**
- * Holds the value of {@link #D_ID}.
- */
- private D d;
+ private double d;
/**
* Constructor with actual parameters.
*
* @param distanceFunction distance function to use
- * @param d d value
+ * @param d radius d value
*/
- public AbstractDBOutlier(DistanceFunction<? super O, D> distanceFunction, D d) {
+ public AbstractDBOutlier(DistanceFunction<? super O> distanceFunction, double d) {
super(distanceFunction);
this.d = d;
}
@@ -86,7 +88,7 @@ public abstract class AbstractDBOutlier<O, D extends Distance<D>> extends Abstra
DoubleDataStore dbodscore = computeOutlierScores(database, relation, d);
// Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("Density-Based Outlier Detection", "db-outlier", TypeUtil.DOUBLE, dbodscore, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Density-Based Outlier Detection", "db-outlier", dbodscore, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new ProbabilisticOutlierScore();
return new OutlierResult(scoreMeta, scoreResult);
}
@@ -99,7 +101,7 @@ public abstract class AbstractDBOutlier<O, D extends Distance<D>> extends Abstra
* @param d distance
* @return computed scores
*/
- protected abstract DoubleDataStore computeOutlierScores(Database database, Relation<O> relation, D d);
+ protected abstract DoubleDataStore computeOutlierScores(Database database, Relation<O> relation, double d);
@Override
public TypeInformation[] getInputTypeRestriction() {
@@ -113,11 +115,16 @@ public abstract class AbstractDBOutlier<O, D extends Distance<D>> extends Abstra
*
* @apiviz.exclude
*/
- public abstract static class Parameterizer<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public abstract static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * Parameter to specify the size of the D-neighborhood
+ */
+ public static final OptionID D_ID = new OptionID("dbod.d", "size of the D-neighborhood");
+
/**
* Query radius
*/
- protected D d = null;
+ protected double d;
@Override
protected void makeOptions(Parameterization config) {
@@ -130,9 +137,9 @@ public abstract class AbstractDBOutlier<O, D extends Distance<D>> extends Abstra
*
* @param config Parameterization
*/
- protected void configD(Parameterization config, DistanceFunction<?, D> distanceFunction) {
- final D distanceFactory = (distanceFunction != null) ? distanceFunction.getDistanceFactory() : null;
- final DistanceParameter<D> param = new DistanceParameter<>(D_ID, distanceFactory);
+ protected void configD(Parameterization config, DistanceFunction<?> distanceFunction) {
+ final DoubleParameter param = new DoubleParameter(D_ID) //
+ .addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
if(config.grab(param)) {
d = param.getValue();
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/DBOutlierDetection.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/DBOutlierDetection.java
index 4f4d12bf..62e26830 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/DBOutlierDetection.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/DBOutlierDetection.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
+package de.lmu.ifi.dbs.elki.algorithm.outlier.distance;
/*
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
@@ -29,15 +29,15 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.DoubleDataStore;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
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;
@@ -49,10 +49,13 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
* Simple distanced based outlier detection algorithm. User has to specify two
* parameters An object is flagged as an outlier if at least a fraction p of all
* data objects has a distance above d from c
+ *
+ * Reference:
* <p>
- * Reference: E.M. Knorr, R. T. Ng: Algorithms for Mining Distance-Based
- * Outliers in Large Datasets, In: Procs Int. Conf. on Very Large Databases
- * (VLDB'98), New York, USA, 1998.
+ * E.M. Knorr, R. T. Ng:<br />
+ * Algorithms for Mining Distance-Based Outliers in Large Datasets,<br />
+ * In: Procs Int. Conf. on Very Large Databases (VLDB'98), New York, USA, 1998.
+ * </p>
*
* This paper presents several Distance Based Outlier Detection algorithms.
* Implemented here is a simple index based algorithm as presented in section
@@ -63,25 +66,21 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
* @apiviz.has KNNQuery
*
* @param <O> the type of DatabaseObjects handled by this Algorithm
- * @param <D> the type of Distance used by this Algorithm
*/
@Title("DBOD: Distance Based Outlier Detection")
@Description("If the D-neighborhood of an object contains only very few objects (less than (1-p) percent of the data) this object is flagged as an outlier")
-@Reference(authors = "E.M. Knorr, R. T. Ng", title = "Algorithms for Mining Distance-Based Outliers in Large Datasets", booktitle = "Procs Int. Conf. on Very Large Databases (VLDB'98), New York, USA, 1998")
-public class DBOutlierDetection<O, D extends Distance<D>> extends AbstractDBOutlier<O, D> {
+@Reference(authors = "E.M. Knorr, R. T. Ng", //
+title = "Algorithms for Mining Distance-Based Outliers in Large Datasets", //
+booktitle = "Procs Int. Conf. on Very Large Databases (VLDB'98), New York, USA, 1998")
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.DBOutlierDetection" })
+public class DBOutlierDetection<O> extends AbstractDBOutlier<O> {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(DBOutlierDetection.class);
/**
- * Parameter to specify the minimum fraction of objects that must be outside
- * the D- neighborhood of an outlier
- */
- public static final OptionID P_ID = new OptionID("dbod.p", "minimum fraction of objects that must be outside the D-neighborhood of an outlier");
-
- /**
- * Holds the value of {@link #P_ID}.
+ * Density threshold percentage p.
*/
private double p;
@@ -92,15 +91,15 @@ public class DBOutlierDetection<O, D extends Distance<D>> extends AbstractDBOutl
* @param d distance query radius
* @param p percentage parameter
*/
- public DBOutlierDetection(DistanceFunction<O, D> distanceFunction, D d, double p) {
+ public DBOutlierDetection(DistanceFunction<O> distanceFunction, double d, double p) {
super(distanceFunction, d);
this.p = p;
}
@Override
- protected DoubleDataStore computeOutlierScores(Database database, Relation<O> relation, D neighborhoodSize) {
- DistanceQuery<O, D> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
- KNNQuery<O, D> knnQuery = database.getKNNQuery(distFunc, DatabaseQuery.HINT_OPTIMIZED_ONLY);
+ protected DoubleDataStore computeOutlierScores(Database database, Relation<O> relation, double neighborhoodSize) {
+ DistanceQuery<O> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
+ KNNQuery<O> knnQuery = database.getKNNQuery(distFunc, DatabaseQuery.HINT_OPTIMIZED_ONLY);
// maximum number of objects in the D-neighborhood of an outlier
int m = (int) ((distFunc.getRelation().size()) * (1 - p));
@@ -115,13 +114,13 @@ public class DBOutlierDetection<O, D extends Distance<D>> extends AbstractDBOutl
// if index exists, kNN query. if the distance to the mth nearest neighbor
// is more than d -> object is outlier
if(knnQuery != null) {
- for(DBIDIter iditer = distFunc.getRelation().iterDBIDs(); iditer.valid(); iditer.advance()) {
+ for(DBIDIter iditer = distFunc.getRelation().iterDBIDs(); iditer.valid(); iditer.advance()) {
counter++;
- final KNNList<D> knns = knnQuery.getKNNForDBID(iditer, m);
+ final KNNList knns = knnQuery.getKNNForDBID(iditer, m);
if(LOG.isDebugging()) {
LOG.debugFine("distance to mth nearest neighbour" + knns.toString());
}
- if(knns.get(Math.min(m, knns.size()) - 1).getDistance().compareTo(neighborhoodSize) <= 0) {
+ if(knns.get(Math.min(m, knns.size()) - 1).doubleValue() <= neighborhoodSize) {
// flag as outlier
scores.putDouble(iditer, 1.0);
}
@@ -136,12 +135,12 @@ public class DBOutlierDetection<O, D extends Distance<D>> extends AbstractDBOutl
}
else {
// range query for each object. stop if m objects are found
- for(DBIDIter iditer = distFunc.getRelation().iterDBIDs(); iditer.valid(); iditer.advance()) {
+ for(DBIDIter iditer = distFunc.getRelation().iterDBIDs(); iditer.valid(); iditer.advance()) {
counter++;
int count = 0;
- for (DBIDIter iterator = distFunc.getRelation().iterDBIDs(); iterator.valid() && count < m; iterator.advance()) {
- D currentDistance = distFunc.distance(iditer, iterator);
- if(currentDistance.compareTo(neighborhoodSize) <= 0) {
+ for(DBIDIter iterator = distFunc.getRelation().iterDBIDs(); iterator.valid() && count < m; iterator.advance()) {
+ double currentDistance = distFunc.distance(iditer, iterator);
+ if(currentDistance <= neighborhoodSize) {
count++;
}
}
@@ -152,9 +151,7 @@ public class DBOutlierDetection<O, D extends Distance<D>> extends AbstractDBOutl
progressOFlags.setProcessed(counter, LOG);
}
}
- if(progressOFlags != null) {
- progressOFlags.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(progressOFlags);
return scores;
}
@@ -170,7 +167,16 @@ public class DBOutlierDetection<O, D extends Distance<D>> extends AbstractDBOutl
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractDBOutlier.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDBOutlier.Parameterizer<O> {
+ /**
+ * Parameter to specify the minimum fraction of objects that must be outside
+ * the D- neighborhood of an outlier
+ */
+ public static final OptionID P_ID = new OptionID("dbod.p", "minimum fraction of objects that must be outside the D-neighborhood of an outlier");
+
+ /**
+ * Density threshold p.
+ */
protected double p = 0.0;
@Override
@@ -183,7 +189,7 @@ public class DBOutlierDetection<O, D extends Distance<D>> extends AbstractDBOutl
}
@Override
- protected DBOutlierDetection<O, D> makeInstance() {
+ protected DBOutlierDetection<O> makeInstance() {
return new DBOutlierDetection<>(distanceFunction, d, p);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/DBOutlierScore.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/DBOutlierScore.java
index d6528682..ac097d75 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/DBOutlierScore.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/DBOutlierScore.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
+package de.lmu.ifi.dbs.elki.algorithm.outlier.distance;
/*
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
@@ -33,8 +33,8 @@ import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
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.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
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;
@@ -46,17 +46,28 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
* score thus eliminating this parameter and turning the method into a ranking
* method instead of a labelling one.
*
+ * Reference:
+ * <p>
+ * E.M. Knorr, R. T. Ng:<br />
+ * Algorithms for Mining Distance-Based Outliers in Large Datasets,<br />
+ * In: Procs Int. Conf. on Very Large Databases (VLDB'98), New York, USA, 1998.
+ * </p>
+ *
* @author Lisa Reichert
*
* @apiviz.has RangeQuery
*
* @param <O> Database object type
- * @param <D> Distance type
*/
@Title("Distance based outlier score")
-@Description("Generalization of the original DB-Outlier approach to a ranking method, by turning the fraction parameter into the output value.")
-@Reference(prefix = "Generalization of a method proposed in", authors = "E.M. Knorr, R. T. Ng", title = "Algorithms for Mining Distance-Based Outliers in Large Datasets", booktitle = "Procs Int. Conf. on Very Large Databases (VLDB'98), New York, USA, 1998")
-public class DBOutlierScore<O, D extends Distance<D>> extends AbstractDBOutlier<O, D> {
+@Description("Generalization of the original DB-Outlier approach to a ranking method, "//
+ + "by turning the fraction parameter into the output value.")
+@Reference(prefix = "Generalization of a method proposed in", //
+authors = "E.M. Knorr, R. T. Ng", //
+title = "Algorithms for Mining Distance-Based Outliers in Large Datasets", //
+booktitle = "Procs Int. Conf. on Very Large Databases (VLDB'98), New York, USA, 1998")
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.DBOutlierScore" })
+public class DBOutlierScore<O> extends AbstractDBOutlier<O> {
/**
* The logger for this class.
*/
@@ -68,19 +79,19 @@ public class DBOutlierScore<O, D extends Distance<D>> extends AbstractDBOutlier<
* @param distanceFunction Distance function
* @param d distance radius parameter
*/
- public DBOutlierScore(DistanceFunction<O, D> distanceFunction, D d) {
+ public DBOutlierScore(DistanceFunction<O> distanceFunction, double d) {
super(distanceFunction, d);
}
@Override
- protected DoubleDataStore computeOutlierScores(Database database, Relation<O> relation, D d) {
- DistanceQuery<O, D> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
- RangeQuery<O, D> rangeQuery = database.getRangeQuery(distFunc);
+ protected DoubleDataStore computeOutlierScores(Database database, Relation<O> relation, double d) {
+ DistanceQuery<O> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
+ RangeQuery<O> rangeQuery = database.getRangeQuery(distFunc);
final double size = distFunc.getRelation().size();
WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(distFunc.getRelation().getDBIDs(), DataStoreFactory.HINT_STATIC);
// TODO: use bulk when implemented.
- for(DBIDIter iditer = distFunc.getRelation().iterDBIDs(); iditer.valid(); iditer.advance()) {
+ for(DBIDIter iditer = distFunc.getRelation().iterDBIDs(); iditer.valid(); iditer.advance()) {
// compute percentage of neighbors in the given neighborhood with size d
double n = (rangeQuery.getRangeForDBID(iditer, d).size()) / size;
scores.putDouble(iditer, 1.0 - n);
@@ -100,9 +111,9 @@ public class DBOutlierScore<O, D extends Distance<D>> extends AbstractDBOutlier<
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractDBOutlier.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDBOutlier.Parameterizer<O> {
@Override
- protected DBOutlierScore<O, D> makeInstance() {
+ protected DBOutlierScore<O> makeInstance() {
return new DBOutlierScore<>(distanceFunction, d);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/HilOut.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/HilOut.java
index e0cdd0c5..6eac9e95 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/HilOut.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/HilOut.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
+package de.lmu.ifi.dbs.elki.algorithm.outlier.distance;
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -28,6 +28,7 @@ import java.util.HashSet;
import java.util.Set;
import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
@@ -36,20 +37,17 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.distancefunction.minkowski.EuclideanDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distanceresultlist.DistanceDBIDResultUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
@@ -57,9 +55,9 @@ import de.lmu.ifi.dbs.elki.math.spacefillingcurves.HilbertSpatialSorter;
import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
-import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparatorMaxHeap;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMaxHeap;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparatorMinHeap;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ObjectHeap;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
@@ -71,7 +69,6 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.EnumParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Fast Outlier Detection in High Dimensional Spaces
@@ -96,8 +93,12 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
*/
@Title("Fast Outlier Detection in High Dimensional Spaces")
@Description("Algorithm to compute outliers using Hilbert space filling curves")
-@Reference(authors = "F. Angiulli, C. Pizzuti", title = "Fast Outlier Detection in High Dimensional Spaces", booktitle = "Proc. European Conference on Principles of Knowledge Discovery and Data Mining (PKDD'02)", url = "http://dx.doi.org/10.1145/375663.375668")
-public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgorithm<O, DoubleDistance, OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "F. Angiulli, C. Pizzuti", //
+title = "Fast Outlier Detection in High Dimensional Spaces", //
+booktitle = "Proc. European Conference on Principles of Knowledge Discovery and Data Mining (PKDD'02)", //
+url = "http://dx.doi.org/10.1145/375663.375668")
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.HilOut" })
+public class HilOut<O extends NumberVector> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -131,7 +132,7 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
/**
* Distance query
*/
- private DistanceQuery<O, DoubleDistance> distq;
+ private DistanceQuery<O> distq;
/**
* Set sizes, total and current iteration
@@ -143,13 +144,6 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
*/
private double omega_star;
- // public int distcomp = 1;
-
- /**
- * Comparator for sorting the heaps.
- */
- private static final Comparator<? super DistanceDBIDPair<?>> COMPARATOR = DistanceDBIDResultUtil.distanceComparator();
-
/**
* Type of output: all scores (upper bounds) or top n only
*
@@ -190,21 +184,19 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
double[] min;
double diameter = 0; // Actually "length of edge"
{
- Pair<O, O> hbbs = DatabaseUtil.computeMinMax(relation);
- min = new double[d];
- double[] max = new double[d];
- for (int i = 0; i < d; i++) {
- min[i] = hbbs.first.doubleValue(i);
- max[i] = hbbs.second.doubleValue(i);
+ double[][] hbbs = RelationUtil.computeMinMax(relation);
+ min = hbbs[0];
+ double[] max = hbbs[1];
+ for(int i = 0; i < d; i++) {
diameter = Math.max(diameter, max[i] - min[i]);
}
// Enlarge bounding box to have equal lengths.
- for (int i = 0; i < d; i++) {
+ for(int i = 0; i < d; i++) {
double diff = (diameter - (max[i] - min[i])) * .5;
min[i] -= diff;
max[i] += diff;
}
- if (LOG.isVerbose()) {
+ if(LOG.isVerbose()) {
LOG.verbose("Rescaling dataset by " + (1 / diameter) + " to fit the unit cube.");
}
}
@@ -216,7 +208,7 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
FiniteProgress progressHilOut = LOG.isVerbose() ? new FiniteProgress("HilOut iterations", d + 1, LOG) : null;
FiniteProgress progressTrueOut = LOG.isVerbose() ? new FiniteProgress("True outliers found", n, LOG) : null;
// Main part: 1. Phase max. d+1 loops
- for (int j = 0; j <= d && n_star < n; j++) {
+ for(int j = 0; j <= d && n_star < n; j++) {
// initialize (clear) out and wlb - not 100% clear in the paper
h.out.clear();
h.wlb.clear();
@@ -226,51 +218,49 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
scan(h, (int) (k * capital_n / (double) capital_n_star));
// determine the true outliers (n_star)
trueOutliers(h);
- if (progressTrueOut != null) {
+ if(progressTrueOut != null) {
progressTrueOut.setProcessed(n_star, LOG);
}
// Build the top Set as out + wlb
h.top.clear();
HashSetModifiableDBIDs top_keys = DBIDUtil.newHashSet(h.out.size());
- for (ObjectHeap.UnsortedIter<HilFeature> iter = h.out.unsortedIter(); iter.valid(); iter.advance()) {
+ for(ObjectHeap.UnsortedIter<HilFeature> iter = h.out.unsortedIter(); iter.valid(); iter.advance()) {
HilFeature entry = iter.get();
top_keys.add(entry.id);
h.top.add(entry);
}
- for (ObjectHeap.UnsortedIter<HilFeature> iter = h.wlb.unsortedIter(); iter.valid(); iter.advance()) {
+ for(ObjectHeap.UnsortedIter<HilFeature> iter = h.wlb.unsortedIter(); iter.valid(); iter.advance()) {
HilFeature entry = iter.get();
- if (!top_keys.contains(entry.id)) {
+ if(!top_keys.contains(entry.id)) {
// No need to update top_keys - discarded
h.top.add(entry);
}
}
- if (progressHilOut != null) {
- progressHilOut.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(progressHilOut);
}
// 2. Phase: Additional Scan if less than n true outliers determined
- if (n_star < n) {
+ if(n_star < n) {
h.out.clear();
h.wlb.clear();
// TODO: reinitialize shift to 0?
scan(h, capital_n);
}
- if (progressHilOut != null) {
+ if(progressHilOut != null) {
progressHilOut.setProcessed(d, LOG);
progressHilOut.ensureCompleted(LOG);
}
- if (progressTrueOut != null) {
+ if(progressTrueOut != null) {
progressTrueOut.setProcessed(n, LOG);
progressTrueOut.ensureCompleted(LOG);
}
DoubleMinMax minmax = new DoubleMinMax();
// Return weights in out
- if (tn == ScoreType.TopN) {
+ if(tn == ScoreType.TopN) {
minmax.put(0.0);
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
hilout_weight.putDouble(iditer, 0.0);
}
- for (ObjectHeap.UnsortedIter<HilFeature> iter = h.out.unsortedIter(); iter.valid(); iter.advance()) {
+ for(ObjectHeap.UnsortedIter<HilFeature> iter = h.out.unsortedIter(); iter.valid(); iter.advance()) {
HilFeature ent = iter.get();
minmax.put(ent.ubound);
hilout_weight.putDouble(ent.id, ent.ubound);
@@ -278,12 +268,12 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
}
// Return all weights in pf
else {
- for (HilFeature ent : h.pf) {
+ for(HilFeature ent : h.pf) {
minmax.put(ent.ubound);
hilout_weight.putDouble(ent.id, ent.ubound);
}
}
- Relation<Double> scoreResult = new MaterializedRelation<>("HilOut weight", "hilout-weight", TypeUtil.DOUBLE, hilout_weight, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("HilOut weight", "hilout-weight", hilout_weight, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY);
OutlierResult result = new OutlierResult(scoreMeta, scoreResult);
return result;
@@ -297,35 +287,37 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
*/
private void scan(HilbertFeatures hf, int k0) {
final int mink0 = Math.min(2 * k0, capital_n - 1);
- if (LOG.isDebuggingFine()) {
+ if(LOG.isDebuggingFine()) {
LOG.debugFine("Scanning with k0=" + k0 + " (" + mink0 + ")" + " N*=" + capital_n_star);
}
- for (int i = 0; i < hf.pf.length; i++) {
- if (hf.pf[i].ubound < omega_star) {
+ for(int i = 0; i < hf.pf.length; i++) {
+ if(hf.pf[i].ubound < omega_star) {
continue;
}
- if (hf.pf[i].lbound < hf.pf[i].ubound) {
+ if(hf.pf[i].lbound < hf.pf[i].ubound) {
double omega = hf.fastUpperBound(i);
- if (omega < omega_star) {
+ if(omega < omega_star) {
hf.pf[i].ubound = omega;
- } else {
+ }
+ else {
int maxcount;
// capital_n-1 instead of capital_n: all, except self
- if (hf.top.contains(hf.pf[i])) {
+ if(hf.top.contains(hf.pf[i])) {
maxcount = capital_n - 1;
- } else {
+ }
+ else {
maxcount = mink0;
}
innerScan(hf, i, maxcount);
}
}
- if (hf.pf[i].ubound > 0) {
+ if(hf.pf[i].ubound > 0) {
hf.updateOUT(i);
}
- if (hf.pf[i].lbound > 0) {
+ if(hf.pf[i].lbound > 0) {
hf.updateWLB(i);
}
- if (hf.wlb.size() >= n) {
+ if(hf.wlb.size() >= n) {
omega_star = Math.max(omega_star, hf.wlb.peek().lbound);
}
}
@@ -344,40 +336,43 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
int a = i, b = i;
int level = h, levela = h, levelb = h;
// Explore up to "maxcount" neighbors in this pass
- for (int count = 0; count < maxcount; count++) {
+ for(int count = 0; count < maxcount; count++) {
final int c; // Neighbor to explore
- if (a == 0) { // At left end, explore right
+ if(a == 0) { // At left end, explore right
// assert (b < capital_n - 1);
levelb = Math.min(levelb, hf.pf[b].level);
b++;
c = b;
- } else if (b >= capital_n - 1) { // At right end, explore left
+ }
+ else if(b >= capital_n - 1) { // At right end, explore left
// assert (a > 0);
a--;
levela = Math.min(levela, hf.pf[a].level);
c = a;
- } else if (hf.pf[a - 1].level >= hf.pf[b].level) { // Prefer higher level
+ }
+ else if(hf.pf[a - 1].level >= hf.pf[b].level) { // Prefer higher level
a--;
levela = Math.min(levela, hf.pf[a].level);
c = a;
- } else {
+ }
+ else {
// assert (b < capital_n - 1);
levelb = Math.min(levelb, hf.pf[b].level);
b++;
c = b;
}
- if (!hf.pf[i].nn_keys.contains(hf.pf[c].id)) {
+ if(!hf.pf[i].nn_keys.contains(hf.pf[c].id)) {
// hf.distcomp ++;
- hf.pf[i].insert(hf.pf[c].id, distq.distance(p, hf.pf[c].id).doubleValue(), k);
- if (hf.pf[i].nn.size() == k) {
- if (hf.pf[i].sum_nn < omega_star) {
+ hf.pf[i].insert(hf.pf[c].id, distq.distance(p, hf.pf[c].id), k);
+ if(hf.pf[i].nn.size() == k) {
+ if(hf.pf[i].sum_nn < omega_star) {
break; // stop = true
}
final int mlevel = Math.max(levela, levelb);
- if (mlevel < level) {
+ if(mlevel < level) {
level = mlevel;
final double delta = hf.minDistLevel(hf.pf[i].id, level);
- if (delta >= hf.pf[i].nn.peek().doubleDistance()) {
+ if(delta >= hf.pf[i].nn.peek().doubleValue()) {
break; // stop = true
}
}
@@ -387,17 +382,17 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
double br = hf.boxRadius(i, a - 1, b + 1);
double newlb = 0.0;
double newub = 0.0;
- for (ObjectHeap.UnsortedIter<DoubleDistanceDBIDPair> iter = hf.pf[i].nn.unsortedIter(); iter.valid(); iter.advance()) {
- DoubleDistanceDBIDPair entry = iter.get();
- newub += entry.doubleDistance();
- if (entry.doubleDistance() <= br) {
- newlb += entry.doubleDistance();
+ for(ObjectHeap.UnsortedIter<DoubleDBIDPair> iter = hf.pf[i].nn.unsortedIter(); iter.valid(); iter.advance()) {
+ DoubleDBIDPair entry = iter.get();
+ newub += entry.doubleValue();
+ if(entry.doubleValue() <= br) {
+ newlb += entry.doubleValue();
}
}
- if (newlb > hf.pf[i].lbound) {
+ if(newlb > hf.pf[i].lbound) {
hf.pf[i].lbound = newlb;
}
- if (newub < hf.pf[i].ubound) {
+ if(newub < hf.pf[i].ubound) {
hf.pf[i].ubound = newub;
}
}
@@ -411,9 +406,9 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
private void trueOutliers(HilbertFeatures h) {
n_star = 0;
- for (ObjectHeap.UnsortedIter<HilFeature> iter = h.out.unsortedIter(); iter.valid(); iter.advance()) {
+ for(ObjectHeap.UnsortedIter<HilFeature> iter = h.out.unsortedIter(); iter.valid(); iter.advance()) {
HilFeature entry = iter.get();
- if (entry.ubound >= omega_star && (entry.ubound - entry.lbound < 1E-10)) {
+ if(entry.ubound >= omega_star && (entry.ubound - entry.lbound < 1E-10)) {
n_star++;
}
}
@@ -494,8 +489,8 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
this.pf = new HilFeature[relation.size()];
int pos = 0;
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- pf[pos++] = new HilFeature(DBIDUtil.deref(iditer), new ComparatorMaxHeap<DoubleDistanceDBIDPair>(k, COMPARATOR));
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ pf[pos++] = new HilFeature(DBIDUtil.deref(iditer), new ComparableMaxHeap<DoubleDBIDPair>(k));
}
this.out = new ComparatorMinHeap<>(n, new Comparator<HilFeature>() {
@Override
@@ -523,42 +518,45 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
// FIXME: 64 bit mode untested - sign bit is tricky to handle correctly
// with the rescaling. 63 bit should be fine. The sign bit probably needs
// to be handled differently, or at least needs careful testing of the API
- if (h >= 32) { // 32 to 63 bit
+ if(h >= 32) { // 32 to 63 bit
final long scale = Long.MAX_VALUE; // = 63 bits
- for (int i = 0; i < pf.length; i++) {
- NumberVector<?> obj = relation.get(pf[i].id);
+ for(int i = 0; i < pf.length; i++) {
+ NumberVector obj = relation.get(pf[i].id);
long[] coord = new long[d];
- for (int dim = 0; dim < d; dim++) {
+ for(int dim = 0; dim < d; dim++) {
coord[dim] = (long) (getDimForObject(obj, dim) * .5 * scale);
}
pf[i].hilbert = HilbertSpatialSorter.coordinatesToHilbert(coord, h, 1);
}
- } else if (h >= 16) { // 16-31 bit
+ }
+ else if(h >= 16) { // 16-31 bit
final int scale = ~1 >>> 1;
- for (int i = 0; i < pf.length; i++) {
- NumberVector<?> obj = relation.get(pf[i].id);
+ for(int i = 0; i < pf.length; i++) {
+ NumberVector obj = relation.get(pf[i].id);
int[] coord = new int[d];
- for (int dim = 0; dim < d; dim++) {
+ for(int dim = 0; dim < d; dim++) {
coord[dim] = (int) (getDimForObject(obj, dim) * .5 * scale);
}
pf[i].hilbert = HilbertSpatialSorter.coordinatesToHilbert(coord, h, 1);
}
- } else if (h >= 8) { // 8-15 bit
+ }
+ else if(h >= 8) { // 8-15 bit
final int scale = ~1 >>> 16;
- for (int i = 0; i < pf.length; i++) {
- NumberVector<?> obj = relation.get(pf[i].id);
+ for(int i = 0; i < pf.length; i++) {
+ NumberVector obj = relation.get(pf[i].id);
short[] coord = new short[d];
- for (int dim = 0; dim < d; dim++) {
+ for(int dim = 0; dim < d; dim++) {
coord[dim] = (short) (getDimForObject(obj, dim) * .5 * scale);
}
pf[i].hilbert = HilbertSpatialSorter.coordinatesToHilbert(coord, h, 16);
}
- } else { // 1-7 bit
+ }
+ else { // 1-7 bit
final int scale = ~1 >>> 8;
- for (int i = 0; i < pf.length; i++) {
- NumberVector<?> obj = relation.get(pf[i].id);
+ for(int i = 0; i < pf.length; i++) {
+ NumberVector obj = relation.get(pf[i].id);
byte[] coord = new byte[d];
- for (int dim = 0; dim < d; dim++) {
+ for(int dim = 0; dim < d; dim++) {
coord[dim] = (byte) (getDimForObject(obj, dim) * .5 * scale);
}
pf[i].hilbert = HilbertSpatialSorter.coordinatesToHilbert(coord, h, 24);
@@ -566,13 +564,13 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
}
java.util.Arrays.sort(pf);
// Update levels
- for (int i = 0; i < pf.length - 1; i++) {
+ for(int i = 0; i < pf.length - 1; i++) {
pf[i].level = minRegLevel(i, i + 1);
}
// Count candidates
capital_n_star = 0;
- for (int i = 0; i < pf.length; i++) {
- if (pf[i].ubound >= omega_star) {
+ for(int i = 0; i < pf.length; i++) {
+ if(pf[i].ubound >= omega_star) {
capital_n_star++;
}
}
@@ -584,11 +582,12 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
* @param i position in pf of the feature to be inserted
*/
private void updateOUT(int i) {
- if (out.size() < n) {
+ if(out.size() < n) {
out.add(pf[i]);
- } else {
+ }
+ else {
HilFeature head = out.peek();
- if (pf[i].ubound > head.ubound) {
+ if(pf[i].ubound > head.ubound) {
// replace smallest
out.replaceTopElement(pf[i]);
}
@@ -601,11 +600,12 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
* @param i position in pf of the feature to be inserted
*/
private void updateWLB(int i) {
- if (wlb.size() < n) {
+ if(wlb.size() < n) {
wlb.add(pf[i]);
- } else {
+ }
+ else {
HilFeature head = wlb.peek();
- if (pf[i].lbound > head.lbound) {
+ if(pf[i].lbound > head.lbound) {
// replace smallest
wlb.replaceTopElement(pf[i]);
}
@@ -622,12 +622,13 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
private double fastUpperBound(int i) {
int pre = i;
int post = i;
- while (post - pre < k) {
+ while(post - pre < k) {
int pre_level = (pre - 1 >= 0) ? pf[pre - 1].level : -2;
int post_level = (post < capital_n - 1) ? pf[post].level : -2;
- if (post_level >= pre_level) {
+ if(post_level >= pre_level) {
post++;
- } else {
+ }
+ else {
pre--;
}
}
@@ -642,12 +643,12 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
* @param level Level of the corresponding r-region
*/
private double minDistLevel(DBID id, int level) {
- final NumberVector<?> obj = relation.get(id);
+ final NumberVector obj = relation.get(id);
// level 1 is supposed to have r=1 as in the original publication
// 2 ^ - (level - 1)
final double r = 1.0 / (1 << (level - 1));
double dist = Double.POSITIVE_INFINITY;
- for (int dim = 0; dim < d; dim++) {
+ for(int dim = 0; dim < d; dim++) {
final double p_m_r = getDimForObject(obj, dim) % r;
dist = Math.min(dist, Math.min(p_m_r, r - p_m_r));
}
@@ -662,36 +663,39 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
* @param level Level of the corresponding r-region
*/
private double maxDistLevel(DBID id, int level) {
- final NumberVector<?> obj = relation.get(id);
+ final NumberVector obj = relation.get(id);
// level 1 is supposed to have r=1 as in the original publication
final double r = 1.0 / (1 << (level - 1));
double dist;
- if (t == 1.0) {
+ if(t == 1.0) {
dist = 0.0;
- for (int dim = 0; dim < d; dim++) {
+ for(int dim = 0; dim < d; dim++) {
final double p_m_r = getDimForObject(obj, dim) % r;
// assert (p_m_r >= 0);
dist += Math.max(p_m_r, r - p_m_r);
}
- } else if (t == 2.0) {
+ }
+ else if(t == 2.0) {
dist = 0.0;
- for (int dim = 0; dim < d; dim++) {
+ for(int dim = 0; dim < d; dim++) {
final double p_m_r = getDimForObject(obj, dim) % r;
// assert (p_m_r >= 0);
double a = Math.max(p_m_r, r - p_m_r);
dist += a * a;
}
dist = Math.sqrt(dist);
- } else if (!Double.isInfinite(t)) {
+ }
+ else if(!Double.isInfinite(t)) {
dist = 0.0;
- for (int dim = 0; dim < d; dim++) {
+ for(int dim = 0; dim < d; dim++) {
final double p_m_r = getDimForObject(obj, dim) % r;
dist += Math.pow(Math.max(p_m_r, r - p_m_r), t);
}
dist = Math.pow(dist, 1.0 / t);
- } else {
+ }
+ else {
dist = Double.NEGATIVE_INFINITY;
- for (int dim = 0; dim < d; dim++) {
+ for(int dim = 0; dim < d; dim++) {
final double p_m_r = getDimForObject(obj, dim) % r;
dist = Math.max(dist, Math.max(p_m_r, r - p_m_r));
}
@@ -707,9 +711,9 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
* @return Number of level shared
*/
private int numberSharedLevels(long[] a, long[] b) {
- for (int i = 0, j = a.length - 1; i < a.length; i++, j--) {
+ for(int i = 0, j = a.length - 1; i < a.length; i++, j--) {
final long diff = a[j] ^ b[j];
- if (diff != 0) {
+ if(diff != 0) {
// expected unused = available - used
final int expected = (a.length * Long.SIZE) - (d * h);
return ((BitsUtil.numberOfLeadingZeros(diff) + i * Long.SIZE) - expected) / d;
@@ -758,14 +762,16 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
private double boxRadius(int i, int a, int b) {
// level are inversely ordered to box sizes. min -> max
final int level;
- if (a < 0) {
- if (b >= pf.length) {
+ if(a < 0) {
+ if(b >= pf.length) {
return Double.POSITIVE_INFINITY;
}
level = maxRegLevel(i, b);
- } else if (b >= pf.length) {
+ }
+ else if(b >= pf.length) {
level = maxRegLevel(i, a);
- } else {
+ }
+ else {
level = Math.max(maxRegLevel(i, a), maxRegLevel(i, b));
}
return minDistLevel(pf[i].id, level);
@@ -778,7 +784,7 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
* @param dim Dimension
* @return Projected and shifted position
*/
- private double getDimForObject(NumberVector<?> obj, int dim) {
+ private double getDimForObject(NumberVector obj, int dim) {
return (obj.doubleValue(dim) - min[dim]) / diameter + shift;
}
}
@@ -822,7 +828,7 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
/**
* Heap with the nearest known neighbors
*/
- public ObjectHeap<DoubleDistanceDBIDPair> nn;
+ public ObjectHeap<DoubleDBIDPair> nn;
/**
* Set representation of the nearest neighbors for faster lookups
@@ -840,7 +846,7 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
* @param id Object ID
* @param nn Heap for neighbors
*/
- public HilFeature(DBID id, ObjectHeap<DoubleDistanceDBIDPair> nn) {
+ public HilFeature(DBID id, ObjectHeap<DoubleDBIDPair> nn) {
super();
this.id = id;
this.nn = nn;
@@ -861,21 +867,22 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
*/
protected void insert(DBID id, double dt, int k) {
// assert (!nn_keys.contains(id));
- if (nn.size() < k) {
- DoubleDistanceDBIDPair entry = DBIDFactory.FACTORY.newDistancePair(dt, id);
+ if(nn.size() < k) {
+ DoubleDBIDPair entry = DBIDUtil.newPair(dt, id);
nn.add(entry);
nn_keys.add(id);
sum_nn += dt;
- } else {
- DoubleDistanceDBIDPair head = nn.peek();
- if (dt < head.doubleDistance()) {
+ }
+ else {
+ DoubleDBIDPair head = nn.peek();
+ if(dt < head.doubleValue()) {
head = nn.poll(); // Remove worst
- sum_nn -= head.doubleDistance();
+ sum_nn -= head.doubleValue();
nn_keys.remove(head);
// assert (nn.peek().doubleDistance() <= head.doubleDistance());
- DoubleDistanceDBIDPair entry = DBIDFactory.FACTORY.newDistancePair(dt, id);
+ DoubleDBIDPair entry = DBIDUtil.newPair(dt, id);
nn.add(entry);
nn_keys.add(id);
sum_nn += dt;
@@ -893,7 +900,7 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
*
* @param <O> Vector type
*/
- public static class Parameterizer<O extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<O extends NumberVector> extends AbstractParameterizer {
/**
* Parameter to specify how many next neighbors should be used in the
* computation
@@ -951,27 +958,27 @@ public class HilOut<O extends NumberVector<?>> extends AbstractDistanceBasedAlgo
super.makeOptions(config);
final IntParameter kP = new IntParameter(K_ID, 5);
- if (config.grab(kP)) {
+ if(config.grab(kP)) {
k = kP.getValue();
}
final IntParameter nP = new IntParameter(N_ID, 10);
- if (config.grab(nP)) {
+ if(config.grab(nP)) {
n = nP.getValue();
}
final IntParameter hP = new IntParameter(H_ID, 32);
- if (config.grab(hP)) {
+ if(config.grab(hP)) {
h = hP.getValue();
}
ObjectParameter<LPNormDistanceFunction> distP = AbstractDistanceBasedAlgorithm.makeParameterDistanceFunction(EuclideanDistanceFunction.class, LPNormDistanceFunction.class);
- if (config.grab(distP)) {
+ if(config.grab(distP)) {
distfunc = distP.instantiateClass(config);
}
final EnumParameter<ScoreType> tnP = new EnumParameter<>(TN_ID, ScoreType.class, ScoreType.TopN);
- if (config.grab(tnP)) {
+ if(config.grab(tnP)) {
tn = tnP.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/KNNOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/KNNOutlier.java
index 503487c8..97970f0a 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/KNNOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/KNNOutlier.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
+package de.lmu.ifi.dbs.elki.algorithm.outlier.distance;
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ 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.algorithm.outlier;
*/
import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
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.Database;
@@ -31,24 +32,25 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
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;
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;
@@ -56,11 +58,19 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* Outlier Detection based on the distance of an object to its k nearest
* neighbor.
*
+ * This implementation differs from the original pseudocode: the k nearest
+ * neighbors do not exclude the point that is currently evaluated. I.e. for k=1
+ * the resulting score is the distance to the 1-nearest neighbor that is not the
+ * query point and therefore should match k=2 in the exact pseudocode - a value
+ * of k=1 in the original code does not make sense, as the 1NN distance will be
+ * 0 for every point in the database. If you for any reason want to use the
+ * original algorithm, subtract 1 from the k parameter.
+ *
+ * Reference:
* <p>
- * Reference:<br>
- * S. Ramaswamy, R. Rastogi, K. Shim: Efficient Algorithms for Mining Outliers
- * from Large Data Sets.</br> In: Proc. of the Int. Conf. on Management of Data,
- * Dallas, Texas, 2000.
+ * S. Ramaswamy, R. Rastogi, K. Shim:<br />
+ * Efficient Algorithms for Mining Outliers from Large Data Sets.<br />
+ * In: Proc. of the Int. Conf. on Management of Data, Dallas, Texas, 2000.
* </p>
*
* @author Lisa Reichert
@@ -68,24 +78,22 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* @apiviz.has KNNQuery
*
* @param <O> the type of DatabaseObjects handled by this Algorithm
- * @param <D> the type of Distance used by this Algorithm
*/
@Title("KNN outlier: Efficient Algorithms for Mining Outliers from Large Data Sets")
@Description("Outlier Detection based on the distance of an object to its k nearest neighbor.")
-@Reference(authors = "S. Ramaswamy, R. Rastogi, K. Shim", title = "Efficient Algorithms for Mining Outliers from Large Data Sets", booktitle = "Proc. of the Int. Conf. on Management of Data, Dallas, Texas, 2000", url = "http://dx.doi.org/10.1145/342009.335437")
-public class KNNOutlier<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "S. Ramaswamy, R. Rastogi, K. Shim", //
+title = "Efficient Algorithms for Mining Outliers from Large Data Sets", //
+booktitle = "Proc. of the Int. Conf. on Management of Data, Dallas, Texas, 2000", //
+url = "http://dx.doi.org/10.1145/342009.335437")
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.KNNOutlier", "knno" })
+public class KNNOutlier<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(KNNOutlier.class);
/**
- * Parameter to specify the k nearest neighbor
- */
- public static final OptionID K_ID = new OptionID("knno.k", "k nearest neighbor");
-
- /**
- * The parameter k
+ * The parameter k (including query point!)
*/
private int k;
@@ -93,9 +101,9 @@ public class KNNOutlier<O, D extends NumberDistance<D, ?>> extends AbstractDista
* Constructor for a single kNN query.
*
* @param distanceFunction distance function to use
- * @param k Value of k
+ * @param k Value of k (including query point!)
*/
- public KNNOutlier(DistanceFunction<? super O, D> distanceFunction, int k) {
+ public KNNOutlier(DistanceFunction<? super O> distanceFunction, int k) {
super(distanceFunction);
this.k = k;
}
@@ -104,39 +112,27 @@ public class KNNOutlier<O, D extends NumberDistance<D, ?>> extends AbstractDista
* Runs the algorithm in the timed evaluation part.
*/
public OutlierResult run(Database database, Relation<O> relation) {
- final DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, getDistanceFunction());
- KNNQuery<O, D> knnQuery = database.getKNNQuery(distanceQuery, k);
+ final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, getDistanceFunction());
+ final KNNQuery<O> knnQuery = database.getKNNQuery(distanceQuery, k + 1);
- if(LOG.isVerbose()) {
- LOG.verbose("Computing the kNN outlier degree (distance to the k nearest neighbor)");
- }
- FiniteProgress progressKNNDistance = LOG.isVerbose() ? new FiniteProgress("kNN distance for objects", relation.size(), LOG) : null;
+ FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("kNN distance for objects", relation.size(), LOG) : null;
DoubleMinMax minmax = new DoubleMinMax();
WritableDoubleDataStore knno_score = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
// compute distance to the k nearest neighbor.
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
// distance to the kth nearest neighbor
- final KNNList<D> knns = knnQuery.getKNNForDBID(iditer, k);
- final double dkn;
- if(knns instanceof DoubleDistanceKNNList) {
- dkn = ((DoubleDistanceKNNList) knns).doubleKNNDistance();
- }
- else {
- dkn = knns.getKNNDistance().doubleValue();
- }
+ // (assuming the query point is always included, with distance 0)
+ final KNNList knns = knnQuery.getKNNForDBID(iditer, k + 1);
+ final double dkn = knns.getKNNDistance();
knno_score.putDouble(iditer, dkn);
minmax.put(dkn);
- if(progressKNNDistance != null) {
- progressKNNDistance.incrementProcessed(LOG);
- }
- }
- if(progressKNNDistance != null) {
- progressKNNDistance.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
- Relation<Double> scoreres = new MaterializedRelation<>("kNN Outlier Score", "knn-outlier", TypeUtil.DOUBLE, knno_score, relation.getDBIDs());
+ LOG.ensureCompleted(prog);
+ DoubleRelation scoreres = new MaterializedDoubleRelation("kNN Outlier Score", "knn-outlier", knno_score, relation.getDBIDs());
OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 0.0);
return new OutlierResult(meta, scoreres);
}
@@ -158,20 +154,31 @@ public class KNNOutlier<O, D extends NumberDistance<D, ?>> extends AbstractDista
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * Parameter to specify the k nearest neighbor
+ */
+ public static final OptionID K_ID = new OptionID("knno.k", //
+ "The k nearest neighbor, excluding the query point "//
+ + "(i.e. query point is the 0-nearest-neighbor)");
+
+ /**
+ * k parameter
+ */
protected int k = 0;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final IntParameter kP = new IntParameter(K_ID);
+ final IntParameter kP = new IntParameter(K_ID)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
if(config.grab(kP)) {
k = kP.getValue();
}
}
@Override
- protected KNNOutlier<O, D> makeInstance() {
+ protected KNNOutlier<O> makeInstance() {
return new KNNOutlier<>(distanceFunction, k);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/KNNWeightOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/KNNWeightOutlier.java
new file mode 100644
index 00000000..b09f7480
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/KNNWeightOutlier.java
@@ -0,0 +1,205 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.distance;
+
+/*
+ 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.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+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.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
+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;
+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;
+
+/**
+ * Outlier Detection based on the accumulated distances of a point to its k
+ * nearest neighbors.
+ *
+ * As in the original publication (as far as we could tell from the pseudocode
+ * included), the current point is not included in the nearest neighbors (see
+ * figures in the publication). This matches the intuition common in nearest
+ * neighbor classification, where the evaluated instances are not part of the
+ * training set; but it contrasts to the pseudocode of the kNN outlier method
+ * and the database interpretation (which returns all objects stored in the
+ * database).
+ *
+ * Furthermore, we report the sum of the k distances (called "weight" in the
+ * original publication). Other implementations may return the average distance
+ * instead, and therefore yield different results.
+ *
+ * Reference:
+ * <p>
+ * F. Angiulli, C. Pizzuti:<br />
+ * Fast Outlier Detection in High Dimensional Spaces.<br />
+ * In: Proc. European Conference on Principles of Knowledge Discovery and Data
+ * Mining (PKDD'02), Helsinki, Finland, 2002.
+ * </p>
+ *
+ * @author Lisa Reichert
+ *
+ * @apiviz.has KNNQuery
+ *
+ * @param <O> the type of DatabaseObjects handled by this Algorithm
+ */
+@Title("KNNWeight outlier detection")
+@Description("Outlier detection based on the sum of distances of an object to its k nearest neighbors.")
+@Reference(authors = "F. Angiulli, C. Pizzuti", //
+title = "Fast Outlier Detection in High Dimensional Spaces", //
+booktitle = "Proc. European Conference on Principles of Knowledge Discovery and Data Mining (PKDD'02), Helsinki, Finland, 2002", //
+url = "http://dx.doi.org/10.1007/3-540-45681-3_2")
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.KNNWeightOutlier", "knnw" })
+public class KNNWeightOutlier<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(KNNWeightOutlier.class);
+
+ /**
+ * Holds the number of nearest neighbors to query (including query point!)
+ */
+ private int k;
+
+ /**
+ * Constructor with parameters.
+ *
+ * @param distanceFunction Distance function
+ * @param k k Parameter (not including query point!)
+ */
+ public KNNWeightOutlier(DistanceFunction<? super O> distanceFunction, int k) {
+ super(distanceFunction);
+ this.k = k;
+ }
+
+ /**
+ * Runs the algorithm in the timed evaluation part.
+ *
+ * @param database Database context
+ * @param relation Data relation
+ */
+ public OutlierResult run(Database database, Relation<O> relation) {
+ final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, getDistanceFunction());
+ KNNQuery<O> knnQuery = database.getKNNQuery(distanceQuery, k + 1);
+
+ FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Compute kNN weights.", relation.size(), LOG) : null;
+
+ DoubleMinMax minmax = new DoubleMinMax();
+ WritableDoubleDataStore knnw_score = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ final KNNList knn = knnQuery.getKNNForDBID(iditer, k + 1);
+ double skn = 0; // sum of the distances to the k nearest neighbors
+ int i = 0; // number of neighbors so far
+ for(DoubleDBIDListIter neighbor = knn.iter(); i < k && neighbor.valid(); neighbor.advance()) {
+ if(DBIDUtil.equal(iditer, neighbor)) {
+ continue;
+ }
+ skn += neighbor.doubleValue();
+ ++i;
+ }
+ if(i < k) {
+ // Less than k neighbors found
+ // Approximative index, or k > data set size!
+ skn = Double.POSITIVE_INFINITY;
+ }
+ knnw_score.putDouble(iditer, skn);
+ minmax.put(skn);
+
+ LOG.incrementProcessed(prog);
+ }
+ LOG.ensureCompleted(prog);
+
+ DoubleRelation res = new MaterializedDoubleRelation("kNN weight Outlier Score", "knnw-outlier", knnw_score, relation.getDBIDs());
+ OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0., Double.POSITIVE_INFINITY, 0.);
+ return new OutlierResult(meta, res);
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * Parameter to specify the k nearest neighbor.
+ */
+ public static final OptionID K_ID = new OptionID("knnwod.k", //
+ "The k nearest neighbor, excluding the query point "//
+ + "(i.e. query point is the 0-nearest-neighbor)");
+
+ /**
+ * k parameter
+ */
+ protected int k = 0;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ final IntParameter kP = new IntParameter(K_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(kP)) {
+ k = kP.getValue();
+ }
+ }
+
+ @Override
+ protected KNNWeightOutlier<O> makeInstance() {
+ return new KNNWeightOutlier<>(distanceFunction, k);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/ODIN.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/ODIN.java
index a5b39146..67380335 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/ODIN.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/ODIN.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
+package de.lmu.ifi.dbs.elki.algorithm.outlier.distance;
/*
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,6 +23,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
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.Database;
@@ -32,17 +33,17 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.distance.KNNList;
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.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.result.outlier.InvertedOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+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.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -60,16 +61,19 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* <p>
* V. Hautamäki and I. Kärkkäinen and P Fränti<br />
* Outlier detection using k-nearest neighbour graph<br />
- * Proc. 17th Int. Conf. Pattern Recognition, ICPR 2004 <br />
+ * Proc. 17th Int. Conf. Pattern Recognition, ICPR 2004
* </p>
*
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
-@Reference(authors = "V. Hautamäki and I. Kärkkäinen and P Fränti", title = "Outlier detection using k-nearest neighbour graph", booktitle = "Proc. 17th Int. Conf. Pattern Recognition, ICPR 2004", url = "http://dx.doi.org/10.1109/ICPR.2004.1334558")
-public class ODIN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "V. Hautamäki and I. Kärkkäinen and P Fränti", //
+title = "Outlier detection using k-nearest neighbour graph", //
+booktitle = "Proc. 17th Int. Conf. Pattern Recognition, ICPR 2004", //
+url = "http://dx.doi.org/10.1109/ICPR.2004.1334558")
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.ODIN" })
+public class ODIN<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
* Class logger.
*/
@@ -86,7 +90,7 @@ public class ODIN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorit
* @param distanceFunction Distance function
* @param k k parameter
*/
- public ODIN(DistanceFunction<? super O, D> distanceFunction, int k) {
+ public ODIN(DistanceFunction<? super O> distanceFunction, int k) {
super(distanceFunction);
this.k = k;
}
@@ -100,8 +104,8 @@ public class ODIN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorit
*/
public OutlierResult run(Database database, Relation<O> relation) {
// Get the query functions:
- DistanceQuery<O, D> dq = database.getDistanceQuery(relation, getDistanceFunction());
- KNNQuery<O, D> knnq = database.getKNNQuery(dq, k);
+ DistanceQuery<O> dq = database.getDistanceQuery(relation, getDistanceFunction());
+ KNNQuery<O> knnq = database.getKNNQuery(dq, k);
// Get the objects to process, and a data storage for counting and output:
DBIDs ids = relation.getDBIDs();
@@ -112,7 +116,7 @@ public class ODIN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorit
// Process all objects
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
// Find the nearest neighbors (using an index, if available!)
- KNNList<D> neighbors = knnq.getKNNForDBID(iter, k);
+ DBIDs neighbors = knnq.getKNNForDBID(iter, k);
// For each neighbor, except ourselves, increase the in-degree:
for(DBIDIter nei = neighbors.iter(); nei.valid(); nei.advance()) {
if(DBIDUtil.equal(iter, nei)) {
@@ -131,7 +135,7 @@ public class ODIN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorit
// Wrap the result and add metadata.
OutlierScoreMeta meta = new InvertedOutlierScoreMeta(min, max, 0., inc * (ids.size() - 1), 1);
- Relation<Double> rel = new MaterializedRelation<>("ODIN In-Degree", "odin", TypeUtil.DOUBLE, scores, ids);
+ DoubleRelation rel = new MaterializedDoubleRelation("ODIN In-Degree", "odin", scores, ids);
return new OutlierResult(meta, rel);
}
@@ -153,9 +157,8 @@ public class ODIN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorit
* @apiviz.exclude
*
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Parameter for the number of nearest neighbors:
*
@@ -185,7 +188,7 @@ public class ODIN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorit
}
@Override
- protected ODIN<O, D> makeInstance() {
+ protected ODIN<O> makeInstance() {
return new ODIN<>(distanceFunction, k);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/ReferenceBasedOutlierDetection.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/ReferenceBasedOutlierDetection.java
new file mode 100644
index 00000000..e1407679
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/ReferenceBasedOutlierDetection.java
@@ -0,0 +1,325 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.distance;
+
+/*
+ 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.Collection;
+
+import de.lmu.ifi.dbs.elki.algorithm.AbstractPrimitiveDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+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.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceQuery;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.result.ReferencePointsResult;
+import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
+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;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+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;
+import de.lmu.ifi.dbs.elki.utilities.referencepoints.GridBasedReferencePoints;
+import de.lmu.ifi.dbs.elki.utilities.referencepoints.ReferencePointsHeuristic;
+
+/**
+ * Reference-Based Outlier Detection algorithm, an algorithm that computes kNN
+ * distances approximately, using reference points.
+ *
+ * kNN distances are approximated by the difference in distance from a reference
+ * point. For this approximation to be of high quality, triangle inequality is
+ * required; but the algorithm can also process non-metric distances.
+ *
+ * Reference:
+ * <p>
+ * Y. Pei, O. R. Zaiane, Y. Gao<br />
+ * An Efficient Reference-Based Approach to Outlier Detection in Large Datasets<br />
+ * In: Proc. IEEE Int. Conf. on Data Mining (ICDM'06), Hong Kong, China, 2006
+ * </p>
+ *
+ * @author Lisa Reichert
+ * @author Erich Schubert
+ *
+ * @apiviz.composedOf ReferencePointsHeuristic
+ */
+@Title("An Efficient Reference-based Approach to Outlier Detection in Large Datasets")
+@Description("Computes kNN distances approximately, using reference points with various reference point strategies.")
+@Reference(authors = "Y. Pei, O.R. Zaiane, Y. Gao", //
+title = "An Efficient Reference-based Approach to Outlier Detection in Large Datasets", //
+booktitle = "Proc. 6th IEEE Int. Conf. on Data Mining (ICDM '06)", //
+url = "http://dx.doi.org/10.1109/ICDM.2006.17")
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.ReferenceBasedOutlierDetection" })
+public class ReferenceBasedOutlierDetection extends AbstractPrimitiveDistanceBasedAlgorithm<NumberVector, OutlierResult> implements OutlierAlgorithm {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(ReferenceBasedOutlierDetection.class);
+
+ /**
+ * Holds the number of neighbors to use for density estimation.
+ */
+ private int k;
+
+ /**
+ * Stores the reference point strategy.
+ */
+ private ReferencePointsHeuristic refp;
+
+ /**
+ * Constructor with parameters.
+ *
+ * @param k k Parameter
+ * @param distanceFunction distance function
+ * @param refp Reference points heuristic
+ */
+ public ReferenceBasedOutlierDetection(int k, PrimitiveDistanceFunction<? super NumberVector> distanceFunction, ReferencePointsHeuristic refp) {
+ super(distanceFunction);
+ this.k = k;
+ this.refp = refp;
+ }
+
+ /**
+ * Run the algorithm on the given relation.
+ *
+ * @param database Database
+ * @param relation Relation to process
+ * @return Outlier result
+ */
+ public OutlierResult run(Database database, Relation<? extends NumberVector> relation) {
+ @SuppressWarnings("unchecked")
+ PrimitiveDistanceQuery<? super NumberVector> distq = (PrimitiveDistanceQuery<? super NumberVector>) database.getDistanceQuery(relation, distanceFunction);
+ Collection<? extends NumberVector> refPoints = refp.getReferencePoints(relation);
+ if(refPoints.size() < 1) {
+ throw new AbortException("Cannot compute ROS without reference points!");
+ }
+
+ DBIDs ids = relation.getDBIDs();
+ if(k >= ids.size()) {
+ throw new AbortException("k must not be chosen larger than the database size!");
+ }
+ // storage of distance/score values.
+ WritableDoubleDataStore rbod_score = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC | DataStoreFactory.HINT_HOT, Double.NaN);
+
+ // Compute density estimation:
+ for(NumberVector refPoint : refPoints) {
+ DoubleDBIDList referenceDists = computeDistanceVector(refPoint, relation, distq);
+ updateDensities(rbod_score, referenceDists);
+ }
+ // compute maximum density
+ DoubleMinMax mm = new DoubleMinMax();
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ mm.put(rbod_score.doubleValue(iditer));
+ }
+ // compute ROS
+ double scale = mm.getMax() > 0. ? 1. / mm.getMax() : 1.;
+ mm.reset(); // Reuse
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ double score = 1 - (rbod_score.doubleValue(iditer) * scale);
+ mm.put(score);
+ rbod_score.putDouble(iditer, score);
+ }
+
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Reference-points Outlier Scores", "reference-outlier", rbod_score, relation.getDBIDs());
+ OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(mm.getMin(), mm.getMax(), 0., 1., 0.);
+ OutlierResult result = new OutlierResult(scoreMeta, scoreResult);
+ // adds reference points to the result. header information for the
+ // visualizer to find the reference points in the result
+ result.addChildResult(new ReferencePointsResult<>("Reference points", "reference-points", refPoints));
+ return result;
+ }
+
+ /**
+ * Computes for each object the distance to one reference point. (one
+ * dimensional representation of the data set)
+ *
+ * @param refPoint Reference Point Feature Vector
+ * @param database database to work on
+ * @param distFunc Distance function to use
+ * @return array containing the distance to one reference point for each
+ * database object and the object id
+ */
+ protected DoubleDBIDList computeDistanceVector(NumberVector refPoint, Relation<? extends NumberVector> database, PrimitiveDistanceQuery<? super NumberVector> distFunc) {
+ ModifiableDoubleDBIDList referenceDists = DBIDUtil.newDistanceDBIDList(database.size());
+ for(DBIDIter iditer = database.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ referenceDists.add(distFunc.distance(iditer, refPoint), iditer);
+ }
+ referenceDists.sort();
+ return referenceDists;
+ }
+
+ /**
+ * Update the density estimates for each object.
+ *
+ * @param rbod_score Density storage
+ * @param referenceDists Distances from current reference point
+ */
+ protected void updateDensities(WritableDoubleDataStore rbod_score, DoubleDBIDList referenceDists) {
+ DoubleDBIDListIter it = referenceDists.iter();
+ for(int l = 0; l < referenceDists.size(); l++) {
+ double density = computeDensity(referenceDists, it, l);
+ // computeDensity modified the iterator, reset:
+ it.seek(l);
+ // NaN indicates the first run.
+ if(!(density > rbod_score.doubleValue(it))) {
+ rbod_score.putDouble(it, density);
+ }
+ }
+ }
+
+ /**
+ * Computes the density of an object. The density of an object is the
+ * distances to the k nearest neighbors. Neighbors and distances are computed
+ * approximately. (approximation for kNN distance: instead of a normal NN
+ * search the NN of an object are those objects that have a similar distance
+ * to a reference point. The k- nearest neighbors of an object are those
+ * objects that lay close to the object in the reference distance vector)
+ *
+ * @param referenceDists vector of the reference distances
+ * @param iter Iterator to this list (will be reused)
+ * @param index index of the current object
+ * @return density for one object and reference point
+ */
+ protected double computeDensity(DoubleDBIDList referenceDists, DoubleDBIDListIter iter, int index) {
+ final int size = referenceDists.size();
+ final double xDist = iter.seek(index).doubleValue();
+
+ int lef = index, rig = index;
+ double sum = 0.;
+ double lef_d = (--lef >= 0) ? xDist - iter.seek(lef).doubleValue() : Double.POSITIVE_INFINITY;
+ double rig_d = (++rig < size) ? iter.seek(rig).doubleValue() - xDist : Double.POSITIVE_INFINITY;
+ for(int i = 0; i < k; ++i) {
+ if(lef >= 0 && rig < size) {
+ // Prefer n or m?
+ if(lef_d < rig_d) {
+ sum += lef_d;
+ // Update left
+ lef_d = (--lef >= 0) ? xDist - iter.seek(lef).doubleValue() : Double.POSITIVE_INFINITY;
+ }
+ else {
+ sum += rig_d;
+ // Update right
+ rig_d = (++rig < size) ? iter.seek(rig).doubleValue() - xDist : Double.POSITIVE_INFINITY;
+ }
+ }
+ else if(lef >= 0) {
+ // Choose left, since right is not available.
+ sum += lef_d;
+ // update left
+ lef_d = (--lef >= 0) ? xDist - iter.seek(lef).doubleValue() : Double.POSITIVE_INFINITY;
+ }
+ else if(rig < size) {
+ // Choose right, since left is not available
+ sum += rig_d;
+ // Update right
+ rig_d = (++rig < size) ? iter.seek(rig).doubleValue() - xDist : Double.POSITIVE_INFINITY;
+ }
+ else {
+ // Not enough objects in database?
+ throw new IndexOutOfBoundsException("Less than k objects?");
+ }
+ }
+ return k / sum;
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(distanceFunction.getInputTypeRestriction());
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractPrimitiveDistanceBasedAlgorithm.Parameterizer<NumberVector> {
+ /**
+ * Parameter for the reference points heuristic.
+ */
+ public static final OptionID REFP_ID = new OptionID("refod.refp", "The heuristic for finding reference points.");
+
+ /**
+ * Parameter to specify the number of nearest neighbors of an object, to be
+ * considered for computing its REFOD_SCORE, must be an integer greater than
+ * 1.
+ */
+ public static final OptionID K_ID = new OptionID("refod.k", "The number of nearest neighbors");
+
+ /**
+ * Holds the value of {@link #K_ID}.
+ */
+ private int k;
+
+ /**
+ * Stores the reference point strategy
+ */
+ private ReferencePointsHeuristic refp;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ final IntParameter pK = new IntParameter(K_ID) //
+ .addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
+ if(config.grab(pK)) {
+ k = pK.getValue();
+ }
+ final ObjectParameter<ReferencePointsHeuristic> refpP = new ObjectParameter<>(REFP_ID, ReferencePointsHeuristic.class, GridBasedReferencePoints.class);
+ if(config.grab(refpP)) {
+ refp = refpP.instantiateClass(config);
+ }
+ }
+
+ @Override
+ protected ReferenceBasedOutlierDetection makeInstance() {
+ return new ReferenceBasedOutlierDetection(k, distanceFunction, refp);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/package-info.java
new file mode 100644
index 00000000..ac292a01
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/package-info.java
@@ -0,0 +1,30 @@
+/**
+ * Distance-based outlier detection algorithms, such as DBOutlier and kNN.
+ *
+ * For methods based on <em>local</em> density, see package
+ * {@link de.lmu.ifi.dbs.elki.algorithm.outlier.lof} instead.
+ */
+
+/*
+ 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.algorithm.outlier.distance; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/KNNWeightProcessor.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/KNNWeightProcessor.java
new file mode 100644
index 00000000..a26a7505
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/KNNWeightProcessor.java
@@ -0,0 +1,118 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.distance.parallel;
+
+/*
+ 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.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.parallel.Executor;
+import de.lmu.ifi.dbs.elki.parallel.processor.AbstractDoubleProcessor;
+import de.lmu.ifi.dbs.elki.parallel.processor.KNNProcessor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedDouble;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedObject;
+
+/**
+ * Compute the kNN weight score, used by {@link ParallelKNNWeightOutlier}.
+ *
+ * Needs the k nearest neighbors as input, for example from {@link KNNProcessor}
+ *
+ * @author Erich Schubert
+ */
+public class KNNWeightProcessor extends AbstractDoubleProcessor {
+ /**
+ * K parameter
+ */
+ int k;
+
+ /**
+ * Constructor.
+ *
+ * @param k K parameter
+ */
+ public KNNWeightProcessor(int k) {
+ super();
+ this.k = k;
+ }
+
+ /**
+ * KNN query object
+ */
+ SharedObject<? extends KNNList> input;
+
+ /**
+ * Connect the input channel.
+ *
+ * @param input Input channel
+ */
+ public void connectKNNInput(SharedObject<? extends KNNList> input) {
+ this.input = input;
+ }
+
+ @Override
+ public Instance instantiate(Executor executor) {
+ return new Instance(k, executor.getInstance(input), executor.getInstance(output));
+ }
+
+ /**
+ * Instance for precomputing the kNN.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ private static class Instance extends AbstractDoubleProcessor.Instance {
+ /**
+ * k Parameter
+ */
+ int k;
+
+ /**
+ * kNN query
+ */
+ SharedObject.Instance<? extends KNNList> input;
+
+ /**
+ * Constructor.
+ *
+ * @param k K parameter
+ * @param input kNN list input
+ * @param store Datastore to write to
+ */
+ protected Instance(int k, SharedObject.Instance<? extends KNNList> input, SharedDouble.Instance store) {
+ super(store);
+ this.k = k;
+ this.input = input;
+ }
+
+ @Override
+ public void map(DBIDRef id) {
+ final KNNList list = input.get();
+ int i = 0;
+ double sum = 0;
+ for(DoubleDBIDListIter iter = list.iter(); iter.valid() && i < k; iter.advance(), ++i) {
+ sum += iter.doubleValue();
+ }
+ output.set(sum);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/ParallelKNNOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/ParallelKNNOutlier.java
new file mode 100644
index 00000000..b7b43765
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/ParallelKNNOutlier.java
@@ -0,0 +1,181 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.distance.parallel;
+
+/*
+ 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.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.distance.KNNOutlier;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+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.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.parallel.ParallelExecutor;
+import de.lmu.ifi.dbs.elki.parallel.processor.DoubleMinMaxProcessor;
+import de.lmu.ifi.dbs.elki.parallel.processor.KDistanceProcessor;
+import de.lmu.ifi.dbs.elki.parallel.processor.KNNProcessor;
+import de.lmu.ifi.dbs.elki.parallel.processor.WriteDoubleDataStoreProcessor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedDouble;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedObject;
+import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+
+/**
+ * Parallel implementation of KNN Outlier detection.
+ *
+ * Reference:
+ * <p>
+ * S. Ramaswamy, R. Rastogi, K. Shim:<br />
+ * Efficient Algorithms for Mining Outliers from Large Data Sets.<br />
+ * In: Proc. of the Int. Conf. on Management of Data, Dallas, Texas, 2000.
+ * </p>
+ *
+ * This parallelized implementation is based on the easy-to-parallelize
+ * generalized pattern discussed in
+ * <p>
+ * Erich Schubert, Arthur Zimek, Hans-Peter Kriegel<br />
+ * Local Outlier Detection Reconsidered: a Generalized View on Locality with
+ * Applications to Spatial, Video, and Network Outlier Detection<br />
+ * Data Mining and Knowledge Discovery, 28(1): 190–237, 2014.
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.composedOf KNNProcessor
+ * @apiviz.composedOf KDistanceProcessor
+ *
+ * @param <O> Object type
+ */
+@Reference(authors = "E. Schubert, A. Zimek, H.-P. Kriegel", //
+title = "Local Outlier Detection Reconsidered: a Generalized View on Locality with Applications to Spatial, Video, and Network Outlier Detection", //
+booktitle = "Data Mining and Knowledge Discovery, 28(1): 190–237, 2014.", //
+url = "http://dx.doi.org/10.1007/s10618-012-0300-z")
+public class ParallelKNNOutlier<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
+ /**
+ * Parameter k
+ */
+ private int k;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function
+ * @param k K parameter
+ */
+ public ParallelKNNOutlier(DistanceFunction<? super O> distanceFunction, int k) {
+ super(distanceFunction);
+ this.k = k;
+ }
+
+ /**
+ * Class logger
+ */
+ private static final Logging LOG = Logging.getLogger(ParallelKNNOutlier.class);
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
+ }
+
+ public OutlierResult run(Database database, Relation<O> relation) {
+ DBIDs ids = relation.getDBIDs();
+ WritableDoubleDataStore store = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_DB);
+ DistanceQuery<O> distq = database.getDistanceQuery(relation, getDistanceFunction());
+ KNNQuery<O> knnq = database.getKNNQuery(distq, k + 1);
+
+ // Compute the kNN
+ KNNProcessor<O> knnm = new KNNProcessor<>(k + 1, knnq);
+ SharedObject<KNNList> knnv = new SharedObject<>();
+ knnm.connectKNNOutput(knnv);
+ // Extract the k-distance
+ KDistanceProcessor kdistm = new KDistanceProcessor(k + 1);
+ SharedDouble kdistv = new SharedDouble();
+ kdistm.connectKNNInput(knnv);
+ kdistm.connectOutput(kdistv);
+ // Store in outlier scores
+ WriteDoubleDataStoreProcessor storem = new WriteDoubleDataStoreProcessor(store);
+ storem.connectInput(kdistv);
+ // Gather statistics
+ DoubleMinMaxProcessor mmm = new DoubleMinMaxProcessor();
+ mmm.connectInput(kdistv);
+
+ ParallelExecutor.run(ids, knnm, kdistm, storem, mmm);
+
+ DoubleMinMax minmax = mmm.getMinMax();
+ DoubleRelation scoreres = new MaterializedDoubleRelation("kNN Outlier Score", "knn-outlier", store, ids);
+ OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 0.0);
+ return new OutlierResult(meta, scoreres);
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <O> Object type
+ */
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * K parameter
+ */
+ int k;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ IntParameter kP = new IntParameter(KNNOutlier.Parameterizer.K_ID);
+ if(config.grab(kP)) {
+ k = kP.getValue();
+ }
+ }
+
+ @Override
+ protected ParallelKNNOutlier<O> makeInstance() {
+ return new ParallelKNNOutlier<>(distanceFunction, k);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/ParallelKNNWeightOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/ParallelKNNWeightOutlier.java
new file mode 100644
index 00000000..40639ec5
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/ParallelKNNWeightOutlier.java
@@ -0,0 +1,187 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.distance.parallel;
+
+/*
+ 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.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.distance.KNNWeightOutlier;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+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.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.parallel.ParallelExecutor;
+import de.lmu.ifi.dbs.elki.parallel.processor.DoubleMinMaxProcessor;
+import de.lmu.ifi.dbs.elki.parallel.processor.KNNProcessor;
+import de.lmu.ifi.dbs.elki.parallel.processor.WriteDoubleDataStoreProcessor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedDouble;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedObject;
+import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+
+/**
+ * Parallel implementation of KNN Weight Outlier detection.
+ *
+ * Reference:
+ * <p>
+ * F. Angiulli, C. Pizzuti:<br />
+ * Fast Outlier Detection in High Dimensional Spaces.<br />
+ * In: Proc. European Conference on Principles of Knowledge Discovery and Data
+ * Mining (PKDD'02), Helsinki, Finland, 2002.
+ * </p>
+ *
+ * This parallelized implementation is based on the easy-to-parallelize
+ * generalized pattern discussed in
+ * <p>
+ * Erich Schubert, Arthur Zimek, Hans-Peter Kriegel<br />
+ * Local Outlier Detection Reconsidered: a Generalized View on Locality with
+ * Applications to Spatial, Video, and Network Outlier Detection<br />
+ * Data Mining and Knowledge Discovery, 28(1): 190–237, 2014.
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.composedOf KNNWeightProcessor
+ *
+ * @param <O> Object type
+ */
+@Reference(authors = "E. Schubert, A. Zimek, H.-P. Kriegel", //
+title = "Local Outlier Detection Reconsidered: a Generalized View on Locality with Applications to Spatial, Video, and Network Outlier Detection", //
+booktitle = "Data Mining and Knowledge Discovery, 28(1): 190–237, 2014.", //
+url = "http://dx.doi.org/10.1007/s10618-012-0300-z")
+public class ParallelKNNWeightOutlier<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
+ /**
+ * Parameter k
+ */
+ private int k;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function
+ * @param k K parameter
+ */
+ public ParallelKNNWeightOutlier(DistanceFunction<? super O> distanceFunction, int k) {
+ super(distanceFunction);
+ this.k = k;
+ }
+
+ /**
+ * Class logger
+ */
+ private static final Logging LOG = Logging.getLogger(ParallelKNNWeightOutlier.class);
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
+ }
+
+ /**
+ * Run the parallel kNN weight outlier detector.
+ *
+ * @param database Database to process
+ * @param relation Relation to analyze
+ * @return Outlier detection result
+ */
+ public OutlierResult run(Database database, Relation<O> relation) {
+ DBIDs ids = relation.getDBIDs();
+ WritableDoubleDataStore store = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_DB);
+ DistanceQuery<O> distq = database.getDistanceQuery(relation, getDistanceFunction());
+ KNNQuery<O> knnq = database.getKNNQuery(distq, k + 1);
+
+ // Find kNN
+ KNNProcessor<O> knnm = new KNNProcessor<>(k + 1, knnq);
+ SharedObject<KNNList> knnv = new SharedObject<>();
+ knnm.connectKNNOutput(knnv);
+ // Extract outlier score
+ KNNWeightProcessor kdistm = new KNNWeightProcessor(k + 1);
+ SharedDouble kdistv = new SharedDouble();
+ kdistm.connectKNNInput(knnv);
+ kdistm.connectOutput(kdistv);
+ // Store in output result
+ WriteDoubleDataStoreProcessor storem = new WriteDoubleDataStoreProcessor(store);
+ storem.connectInput(kdistv);
+ // And gather statistics for metadata
+ DoubleMinMaxProcessor mmm = new DoubleMinMaxProcessor();
+ mmm.connectInput(kdistv);
+
+ ParallelExecutor.run(ids, knnm, kdistm, storem, mmm);
+
+ DoubleMinMax minmax = mmm.getMinMax();
+ DoubleRelation scoreres = new MaterializedDoubleRelation("kNN weight Outlier Score", "knnw-outlier", store, ids);
+ OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0., Double.POSITIVE_INFINITY, 0.);
+ return new OutlierResult(meta, scoreres);
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <O> Object type
+ */
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * K parameter
+ */
+ int k;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ IntParameter kP = new IntParameter(KNNWeightOutlier.Parameterizer.K_ID);
+ if(config.grab(kP)) {
+ k = kP.getValue();
+ }
+ }
+
+ @Override
+ protected ParallelKNNWeightOutlier<O> makeInstance() {
+ return new ParallelKNNWeightOutlier<>(distanceFunction, k);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/package-info.java
new file mode 100644
index 00000000..58090507
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/distance/parallel/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Parallel implementations of distance-based outlier detectors.
+ */
+
+/*
+ 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.algorithm.outlier.distance.parallel; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/ALOCI.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/ALOCI.java
index f978365e..60e2ff00 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/ALOCI.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/ALOCI.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -40,21 +40,20 @@ import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.distancefunction.NumberVectorDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
-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.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.QuotientOutlierScoreMeta;
-import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
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;
@@ -64,7 +63,6 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Fast Outlier Detection Using the "approximate Local Correlation Integral".
@@ -85,12 +83,11 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
* @apiviz.composedOf ALOCIQuadTree
*
* @param <O> Object type
- * @param <D> Distance type
*/
@Title("LOCI: Fast Outlier Detection Using the Local Correlation Integral")
@Description("Algorithm to compute outliers based on the Local Correlation Integral")
@Reference(authors = "S. Papadimitriou, H. Kitagawa, P. B. Gibbons, C. Faloutsos", title = "LOCI: Fast Outlier Detection Using the Local Correlation Integral", booktitle = "Proc. 19th IEEE Int. Conf. on Data Engineering (ICDE '03), Bangalore, India, 2003", url = "http://dx.doi.org/10.1109/ICDE.2003.1260802")
-public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
+public class ALOCI<O extends NumberVector> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -119,7 +116,7 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
/**
* Distance function
*/
- private NumberVectorDistanceFunction<D> distFunc;
+ private NumberVectorDistanceFunction<?> distFunc;
/**
* Constructor.
@@ -130,7 +127,7 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
* @param g Number of grids to use
* @param rnd Random generator.
*/
- public ALOCI(NumberVectorDistanceFunction<D> distanceFunction, int nmin, int alpha, int g, RandomFactory rnd) {
+ public ALOCI(NumberVectorDistanceFunction<?> distanceFunction, int nmin, int alpha, int g, RandomFactory rnd) {
super();
this.distFunc = distanceFunction;
this.nmin = nmin;
@@ -147,13 +144,11 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
// Compute extend of dataset.
double[] min, max;
{
- Pair<O, O> hbbs = DatabaseUtil.computeMinMax(relation);
+ double[][] hbbs = RelationUtil.computeMinMax(relation);
+ min = hbbs[0];
+ max = hbbs[1];
double maxd = 0;
- min = new double[dim];
- max = new double[dim];
for(int i = 0; i < dim; i++) {
- min[i] = hbbs.first.doubleValue(i);
- max[i] = hbbs.second.doubleValue(i);
maxd = Math.max(maxd, max[i] - min[i]);
}
// Enlarge bounding box to have equal lengths.
@@ -169,9 +164,7 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
double[] nshift = new double[dim];
ALOCIQuadTree qt = new ALOCIQuadTree(min, max, nshift, nmin, relation);
qts.add(qt);
- if(progressPreproc != null) {
- progressPreproc.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(progressPreproc);
/*
* create the remaining g-1 shifted QuadTrees. This not clearly described in
* the paper and therefore implemented in a way that achieves good results
@@ -184,13 +177,9 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
}
qt = new ALOCIQuadTree(min, max, svec, nmin, relation);
qts.add(qt);
- if(progressPreproc != null) {
- progressPreproc.incrementProcessed(LOG);
- }
- }
- if(progressPreproc != null) {
- progressPreproc.ensureCompleted(LOG);
+ LOG.incrementProcessed(progressPreproc);
}
+ LOG.ensureCompleted(progressPreproc);
// aLOCI main loop: evaluate
FiniteProgress progressLOCI = LOG.isVerbose() ? new FiniteProgress("Compute aLOCI scores", relation.size(), LOG) : null;
@@ -211,7 +200,7 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
continue;
}
// TODO: always use manhattan?
- if(ci == null || distFunc.distance(ci.getCenter(), obj).compareTo(distFunc.distance(ci2.getCenter(), obj)) > 0) {
+ if(ci == null || distFunc.distance(ci.getCenter(), obj) > distFunc.distance(ci2.getCenter(), obj)) {
ci = ci2;
}
}
@@ -229,7 +218,7 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
continue;
}
// TODO: always use manhattan?
- if(cj == null || distFunc.distance(cj.getCenter(), ci.getCenter()).compareTo(distFunc.distance(cj2.getCenter(), ci.getCenter())) > 0) {
+ if(cj == null || distFunc.distance(cj.getCenter(), ci.getCenter()) > distFunc.distance(cj2.getCenter(), ci.getCenter())) {
cj = cj2;
}
}
@@ -245,14 +234,10 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
// Store results
mdef_norm.putDouble(iditer, maxmdefnorm);
minmax.put(maxmdefnorm);
- if(progressLOCI != null) {
- progressLOCI.incrementProcessed(LOG);
- }
- }
- if(progressLOCI != null) {
- progressLOCI.ensureCompleted(LOG);
+ LOG.incrementProcessed(progressLOCI);
}
- Relation<Double> scoreResult = new MaterializedRelation<>("aLOCI normalized MDEF", "aloci-mdef-outlier", TypeUtil.DOUBLE, mdef_norm, relation.getDBIDs());
+ LOG.ensureCompleted(progressLOCI);
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("aLOCI normalized MDEF", "aloci-mdef-outlier", mdef_norm, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY);
OutlierResult result = new OutlierResult(scoreMeta, scoreResult);
return result;
@@ -336,7 +321,7 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
/**
* Relation indexed.
*/
- private Relation<? extends NumberVector<?>> relation;
+ private Relation<? extends NumberVector> relation;
/**
* Constructor.
@@ -347,7 +332,7 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
* @param nmin Maximum size for a page to split
* @param relation Relation to index
*/
- public ALOCIQuadTree(double[] min, double[] max, double[] shift, int nmin, Relation<? extends NumberVector<?>> relation) {
+ public ALOCIQuadTree(double[] min, double[] max, double[] shift, int nmin, Relation<? extends NumberVector> relation) {
super();
assert (min.length <= 32) : "Quadtrees are only supported for up to 32 dimensions";
this.shift = shift;
@@ -395,11 +380,11 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
if(dim == 0) {
DBIDArrayIter iter = ids.iter();
iter.seek(start);
- NumberVector<?> first = relation.get(iter);
+ NumberVector first = relation.get(iter);
iter.advance();
boolean degenerate = true;
loop: for(; iter.getOffset() < end; iter.advance()) {
- NumberVector<?> other = relation.get(iter);
+ NumberVector other = relation.get(iter);
for(int d = 0; d < lmin.length; d++) {
if(Math.abs(first.doubleValue(d) - other.doubleValue(d)) > 1E-15) {
degenerate = false;
@@ -481,7 +466,7 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
* @param level Level (controls scaling/wraping!)
* @return Shifted position
*/
- private double getShiftedDim(NumberVector<?> obj, int dim, int level) {
+ private double getShiftedDim(NumberVector obj, int dim, int level) {
double pos = obj.doubleValue(dim) + shift[dim];
pos = (pos - min[dim]) / width[dim] * (1 + level);
return pos - Math.floor(pos);
@@ -495,7 +480,7 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
* @param tlevel Target level
* @return Node
*/
- public Node findClosestNode(NumberVector<?> vec, int tlevel) {
+ public Node findClosestNode(NumberVector vec, int tlevel) {
Node cur = root;
for(int level = 0; level <= tlevel; level++) {
if(cur.children == null) {
@@ -650,7 +635,7 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
*
* @apiviz.exclude
*/
- public static class Parameterizer<O extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractParameterizer {
+ public static class Parameterizer<O extends NumberVector> extends AbstractParameterizer {
/**
* Parameter to specify the minimum neighborhood size
*/
@@ -694,13 +679,13 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
/**
* The distance function
*/
- private NumberVectorDistanceFunction<D> distanceFunction;
+ private NumberVectorDistanceFunction<?> distanceFunction;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- ObjectParameter<NumberVectorDistanceFunction<D>> distanceFunctionP = makeParameterDistanceFunction(EuclideanDistanceFunction.class, NumberVectorDistanceFunction.class);
+ ObjectParameter<NumberVectorDistanceFunction<?>> distanceFunctionP = makeParameterDistanceFunction(EuclideanDistanceFunction.class, NumberVectorDistanceFunction.class);
if(config.grab(distanceFunctionP)) {
distanceFunction = distanceFunctionP.instantiateClass(config);
}
@@ -730,7 +715,7 @@ public class ALOCI<O extends NumberVector<?>, D extends NumberDistance<D, ?>> ex
}
@Override
- protected ALOCI<O, D> makeInstance() {
+ protected ALOCI<O> makeInstance() {
return new ALOCI<>(distanceFunction, nmin, alpha, g, rnd);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/COF.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/COF.java
new file mode 100644
index 00000000..09b5d8b8
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/COF.java
@@ -0,0 +1,276 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
+
+/*
+ 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.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.DoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+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.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+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.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
+import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.result.outlier.QuotientOutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+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;
+
+/**
+ * Connectivity-based outlier factor (COF).
+ *
+ * Reference:
+ * <p>
+ * J. Tang, Z. Chen, A. W. C. Fu, D. W. Cheung<br />
+ * Enhancing effectiveness of outlier detections for low density patterns.<br />
+ * In Advances in Knowledge Discovery and Data Mining.
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Object type
+ */
+@Reference(authors = "J. Tang, Z. Chen, A. W. C. Fu, D. W. Cheung", //
+title = "Enhancing effectiveness of outlier detections for low density patterns", //
+booktitle = "In Advances in Knowledge Discovery and Data Mining", //
+url = "http://dx.doi.org/10.1007/3-540-47887-6_53")
+public class COF<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(COF.class);
+
+ /**
+ * The number of neighbors to query (including the query point!)
+ */
+ protected int k;
+
+ /**
+ * Constructor.
+ *
+ * @param k the number of neighbors to use for comparison (excluding the query
+ * point)
+ * @param distanceFunction the neighborhood distance function
+ */
+ public COF(int k, DistanceFunction<? super O> distanceFunction) {
+ super(distanceFunction);
+ this.k = k + 1;
+ }
+
+ /**
+ * Runs the COF algorithm on the given database.
+ *
+ * @param database Database to query
+ * @param relation Data to process
+ * @return COF outlier result
+ */
+ public OutlierResult run(Database database, Relation<O> relation) {
+ StepProgress stepprog = LOG.isVerbose() ? new StepProgress("COF", 3) : null;
+ DistanceQuery<O> dq = database.getDistanceQuery(relation, getDistanceFunction());
+ LOG.beginStep(stepprog, 1, "Materializing COF neighborhoods.");
+ KNNQuery<O> knnq = DatabaseUtil.precomputedKNNQuery(database, relation, dq, k);
+ DBIDs ids = relation.getDBIDs();
+
+ LOG.beginStep(stepprog, 2, "Computing Average Chaining Distances.");
+ WritableDoubleDataStore acds = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
+ computeAverageChainingDistances(knnq, dq, ids, acds);
+
+ // compute COF_SCORE of each db object
+ LOG.beginStep(stepprog, 3, "Computing Connectivity-based Outlier Factors.");
+ WritableDoubleDataStore cofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_DB);
+ // track the maximum value for normalization.
+ DoubleMinMax cofminmax = new DoubleMinMax();
+ computeCOFScores(knnq, ids, acds, cofs, cofminmax);
+
+ LOG.setCompleted(stepprog);
+
+ // Build result representation.
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Connectivity-Based Outlier Factor", "cof-outlier", cofs, ids);
+ OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(cofminmax.getMin(), cofminmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 1.0);
+ return new OutlierResult(scoreMeta, scoreResult);
+ }
+
+ /**
+ * Computes the average chaining distance, the average length of a path
+ * through the given set of points to each target. The authors of COF decided
+ * to approximate this value using a weighted mean that assumes every object
+ * is reached from the previous point (but actually every point could be best
+ * reachable from the first, in which case this does not make much sense.)
+ *
+ * TODO: can we accelerate this by using the kNN of the neighbors?
+ *
+ * @param knnq KNN query
+ * @param dq Distance query
+ * @param ids IDs to process
+ * @param acds Storage for average chaining distances
+ */
+ protected void computeAverageChainingDistances(KNNQuery<O> knnq, DistanceQuery<O> dq, DBIDs ids, WritableDoubleDataStore acds) {
+ FiniteProgress lrdsProgress = LOG.isVerbose() ? new FiniteProgress("Computing average chaining distances", ids.size(), LOG) : null;
+
+ // Compute the chaining distances.
+ // We do <i>not</i> bother to materialize the chaining order.
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ final KNNList neighbors = knnq.getKNNForDBID(iter, k);
+ final int r = neighbors.size();
+ DoubleDBIDListIter it1 = neighbors.iter(), it2 = neighbors.iter();
+ // Store the current lowest reachability.
+ final double[] mindists = new double[r];
+ for(int i = 0; it1.valid(); it1.advance(), ++i) {
+ mindists[i] = DBIDUtil.equal(it1, iter) ? Double.NaN : it1.doubleValue();
+ }
+
+ double acsum = 0.;
+ for(int j = ((r < k) ? r : k) - 1; j > 0; --j) {
+ // Find the minimum:
+ int minpos = -1;
+ double mindist = Double.NaN;
+ for(int i = 0; i < mindists.length; ++i) {
+ double curdist = mindists[i];
+ // Both values could be NaN, deliberately.
+ if(curdist == curdist && !(curdist > mindist)) {
+ minpos = i;
+ mindist = curdist;
+ }
+ }
+ acsum += mindist * j; // Weighted sum, decreasing weights
+ mindists[minpos] = Double.NaN;
+ it1.seek(minpos);
+ // Update distances
+ it2.seek(0);
+ for(int i = 0; it2.valid(); it2.advance(), ++i) {
+ final double curdist = mindists[i];
+ if(curdist != curdist) {
+ continue; // NaN = processed!
+ }
+ double newdist = dq.distance(it1, it2);
+ if(newdist < curdist) {
+ mindists[i] = newdist;
+ }
+ }
+ }
+ acds.putDouble(iter, acsum / (r * 0.5 * (r - 1.)));
+ LOG.incrementProcessed(lrdsProgress);
+ }
+ LOG.ensureCompleted(lrdsProgress);
+ }
+
+ /**
+ * Compute Connectivity outlier factors.
+ *
+ * @param knnq KNN query
+ * @param ids IDs to process
+ * @param acds Average chaining distances
+ * @param cofs Connectivity outlier factor storage
+ * @param cofminmax Score minimum/maximum tracker
+ */
+ private void computeCOFScores(KNNQuery<O> knnq, DBIDs ids, DoubleDataStore acds, WritableDoubleDataStore cofs, DoubleMinMax cofminmax) {
+ FiniteProgress progressCOFs = LOG.isVerbose() ? new FiniteProgress("COF for objects", ids.size(), LOG) : null;
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ final KNNList neighbors = knnq.getKNNForDBID(iter, k);
+ // Aggregate the average chaining distances of all neighbors:
+ double sum = 0.;
+ for(DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ // skip the point itself
+ if(DBIDUtil.equal(neighbor, iter)) {
+ continue;
+ }
+ sum += acds.doubleValue(neighbor);
+ }
+ final double cof = (sum > 0.) ? (acds.doubleValue(iter) * k / sum) : (acds.doubleValue(iter) > 0. ? Double.POSITIVE_INFINITY : 1.);
+ cofs.putDouble(iter, cof);
+ // update minimum and maximum
+ cofminmax.put(cof);
+
+ LOG.incrementProcessed(progressCOFs);
+ }
+ LOG.ensureCompleted(progressCOFs);
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <O> Object type
+ */
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * Parameter to specify the neighborhood size for COF. This does not include
+ * the query object.
+ */
+ public static final OptionID K_ID = new OptionID("cof.k", "The number of neighbors (not including the query object) to use for computing the COF score.");
+
+ /**
+ * The neighborhood size to use.
+ */
+ protected int k = 2;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ final IntParameter pK = new IntParameter(K_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(pK)) {
+ k = pK.intValue();
+ }
+ }
+
+ @Override
+ protected COF<O> makeInstance() {
+ return new COF<>(k, distanceFunction);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/FlexibleLOF.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/FlexibleLOF.java
index 2508b6b0..372bf68c 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/FlexibleLOF.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/FlexibleLOF.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
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
@@ -38,20 +38,16 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
-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.query.knn.PreprocessorKNNQuery;
import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.NumberDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNPreprocessor;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
@@ -59,6 +55,7 @@ import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.QuotientOutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
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;
@@ -113,12 +110,14 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
* @apiviz.has KNNQuery
*
* @param <O> the type of DatabaseObjects handled by this Algorithm
- * @param <D> Distance type
*/
@Title("LOF: Local Outlier Factor")
@Description("Algorithm to compute density-based local outlier factors in a database based on the neighborhood size parameter 'k'")
-@Reference(authors = "M. M. Breunig, H.-P. Kriegel, R. Ng, and J. Sander", title = "LOF: Identifying Density-Based Local Outliers", booktitle = "Proc. 2nd ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '00), Dallas, TX, 2000", url = "http://dx.doi.org/10.1145/342009.335388")
-public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "M. M. Breunig, H.-P. Kriegel, R. Ng, J. Sander", //
+title = "LOF: Identifying Density-Based Local Outliers", //
+booktitle = "Proc. 2nd ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '00), Dallas, TX, 2000", //
+url = "http://dx.doi.org/10.1145/342009.335388")
+public class FlexibleLOF<O> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -137,20 +136,12 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
/**
* Neighborhood distance function.
*/
- protected DistanceFunction<? super O, D> referenceDistanceFunction;
+ protected DistanceFunction<? super O> referenceDistanceFunction;
/**
* Reachability distance function.
*/
- protected DistanceFunction<? super O, D> reachabilityDistanceFunction;
-
- /**
- * 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.
- */
- private static boolean objectIsInKNN = false;
+ protected DistanceFunction<? super O> reachabilityDistanceFunction;
/**
* Constructor.
@@ -160,10 +151,10 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
* @param neighborhoodDistanceFunction the neighborhood distance function
* @param reachabilityDistanceFunction the reachability distance function
*/
- public FlexibleLOF(int krefer, int kreach, DistanceFunction<? super O, D> neighborhoodDistanceFunction, DistanceFunction<? super O, D> reachabilityDistanceFunction) {
+ public FlexibleLOF(int krefer, int kreach, DistanceFunction<? super O> neighborhoodDistanceFunction, DistanceFunction<? super O> reachabilityDistanceFunction) {
super();
- this.krefer = krefer + (objectIsInKNN ? 0 : 1);
- this.kreach = kreach + (objectIsInKNN ? 0 : 1);
+ this.krefer = krefer + 1;
+ this.kreach = kreach + 1;
this.referenceDistanceFunction = neighborhoodDistanceFunction;
this.reachabilityDistanceFunction = reachabilityDistanceFunction;
}
@@ -178,9 +169,9 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*/
public OutlierResult run(Database database, Relation<O> relation) {
StepProgress stepprog = LOG.isVerbose() ? new StepProgress("LOF", 3) : null;
- Pair<KNNQuery<O, D>, KNNQuery<O, D>> pair = getKNNQueries(database, relation, stepprog);
- KNNQuery<O, D> kNNRefer = pair.getFirst();
- KNNQuery<O, D> kNNReach = pair.getSecond();
+ Pair<KNNQuery<O>, KNNQuery<O>> pair = getKNNQueries(database, relation, stepprog);
+ KNNQuery<O> kNNRefer = pair.getFirst();
+ KNNQuery<O> kNNReach = pair.getSecond();
return doRunInTime(relation.getDBIDs(), kNNRefer, kNNReach, stepprog).getResult();
}
@@ -191,30 +182,29 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
* @param stepprog the progress logger
* @return the kNN queries for the algorithm
*/
- private Pair<KNNQuery<O, D>, KNNQuery<O, D>> getKNNQueries(Database database, Relation<O> relation, StepProgress stepprog) {
+ private Pair<KNNQuery<O>, KNNQuery<O>> getKNNQueries(Database database, Relation<O> relation, StepProgress stepprog) {
// "HEAVY" flag for knnReach since it is used more than once
- KNNQuery<O, D> knnReach = QueryUtil.getKNNQuery(relation, reachabilityDistanceFunction, kreach, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
+ KNNQuery<O> knnReach = QueryUtil.getKNNQuery(relation, reachabilityDistanceFunction, kreach, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
// No optimized kNN query - use a preprocessor!
- if (!(knnReach instanceof PreprocessorKNNQuery)) {
- if (stepprog != null) {
- if (referenceDistanceFunction.equals(reachabilityDistanceFunction)) {
+ if(!(knnReach instanceof PreprocessorKNNQuery)) {
+ if(stepprog != null) {
+ if(referenceDistanceFunction.equals(reachabilityDistanceFunction)) {
stepprog.beginStep(1, "Materializing neighborhoods w.r.t. reference neighborhood distance function.", LOG);
- } else {
+ }
+ else {
stepprog.beginStep(1, "Not materializing neighborhoods w.r.t. reference neighborhood distance function, but materializing neighborhoods w.r.t. reachability distance function.", LOG);
}
}
int kpreproc = (referenceDistanceFunction.equals(reachabilityDistanceFunction)) ? Math.max(kreach, krefer) : kreach;
- MaterializeKNNPreprocessor<O, D> preproc = new MaterializeKNNPreprocessor<>(relation, reachabilityDistanceFunction, kpreproc);
- database.addIndex(preproc);
- DistanceQuery<O, D> rdq = database.getDistanceQuery(relation, reachabilityDistanceFunction);
- knnReach = preproc.getKNNQuery(rdq, kreach);
+ knnReach = DatabaseUtil.precomputedKNNQuery(database, relation, reachabilityDistanceFunction, kpreproc);
}
// knnReach is only used once
- KNNQuery<O, D> knnRefer;
- if (referenceDistanceFunction == reachabilityDistanceFunction || referenceDistanceFunction.equals(reachabilityDistanceFunction)) {
+ KNNQuery<O> knnRefer;
+ if(referenceDistanceFunction == reachabilityDistanceFunction || referenceDistanceFunction.equals(reachabilityDistanceFunction)) {
knnRefer = knnReach;
- } else {
+ }
+ else {
// do not materialize the first neighborhood, since it is used only once
knnRefer = QueryUtil.getKNNQuery(relation, referenceDistanceFunction, krefer);
}
@@ -234,149 +224,118 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
* @param stepprog Progress logger
* @return LOF result
*/
- protected LOFResult<O, D> doRunInTime(DBIDs ids, KNNQuery<O, D> kNNRefer, KNNQuery<O, D> kNNReach, StepProgress stepprog) {
+ protected LOFResult<O> doRunInTime(DBIDs ids, KNNQuery<O> kNNRefer, KNNQuery<O> kNNReach, StepProgress stepprog) {
// Assert we got something
- if (kNNRefer == null) {
+ if(kNNRefer == null) {
throw new AbortException("No kNN queries supported by database for reference neighborhood distance function.");
}
- if (kNNReach == null) {
+ if(kNNReach == null) {
throw new AbortException("No kNN queries supported by database for reachability distance function.");
}
// Compute LRDs
- if (stepprog != null) {
- stepprog.beginStep(2, "Computing LRDs.", LOG);
- }
- WritableDoubleDataStore lrds = computeLRDs(ids, kNNReach);
+ LOG.beginStep(stepprog, 2, "Computing LRDs.");
+ WritableDoubleDataStore lrds = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
+ computeLRDs(kNNReach, ids, lrds);
// compute LOF_SCORE of each db object
- if (stepprog != null) {
- stepprog.beginStep(3, "Computing LOFs.", LOG);
- }
- Pair<WritableDoubleDataStore, DoubleMinMax> lofsAndMax = computeLOFs(ids, lrds, kNNRefer);
- WritableDoubleDataStore lofs = lofsAndMax.getFirst();
+ LOG.beginStep(stepprog, 3, "Computing LOFs.");
+ WritableDoubleDataStore lofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC);
// track the maximum value for normalization.
- DoubleMinMax lofminmax = lofsAndMax.getSecond();
+ DoubleMinMax lofminmax = new DoubleMinMax();
+ computeLOFs(kNNRefer, ids, lrds, lofs, lofminmax);
- if (stepprog != null) {
- stepprog.setCompleted(LOG);
- }
+ LOG.setCompleted(stepprog);
// Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("Local Outlier Factor", "lof-outlier", TypeUtil.DOUBLE, lofs, ids);
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Local Outlier Factor", "lof-outlier", lofs, ids);
OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(lofminmax.getMin(), lofminmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 1.0);
OutlierResult result = new OutlierResult(scoreMeta, scoreResult);
-
return new LOFResult<>(result, kNNRefer, kNNReach, lrds, lofs);
}
/**
* Computes the local reachability density (LRD) of the specified objects.
*
- * @param ids the ids of the objects
- * @param knnReach the precomputed neighborhood of the objects w.r.t. the
+ * @param knnq the precomputed neighborhood of the objects w.r.t. the
* reachability distance
- * @return the LRDs of the objects
+ * @param ids the ids of the objects
+ * @param lrds Reachability storage
*/
- protected WritableDoubleDataStore computeLRDs(DBIDs ids, KNNQuery<O, D> knnReach) {
- WritableDoubleDataStore lrds = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
+ protected void computeLRDs(KNNQuery<O> knnq, DBIDs ids, WritableDoubleDataStore lrds) {
FiniteProgress lrdsProgress = LOG.isVerbose() ? new FiniteProgress("LRD", ids.size(), LOG) : null;
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- final KNNList<D> neighbors = knnReach.getKNNForDBID(iter, kreach);
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ final KNNList neighbors = knnq.getKNNForDBID(iter, kreach);
double sum = 0.0;
int count = 0;
- if (neighbors instanceof DoubleDistanceKNNList) {
- // Fast version for double distances
- for (DoubleDistanceDBIDListIter neighbor = ((DoubleDistanceKNNList) neighbors).iter(); neighbor.valid(); neighbor.advance()) {
- if (objectIsInKNN || !DBIDUtil.equal(neighbor, iter)) {
- KNNList<D> neighborsNeighbors = knnReach.getKNNForDBID(neighbor, kreach);
- final double nkdist;
- if (neighborsNeighbors instanceof DoubleDistanceKNNList) {
- nkdist = ((DoubleDistanceKNNList) neighborsNeighbors).doubleKNNDistance();
- } else {
- nkdist = neighborsNeighbors.getKNNDistance().doubleValue();
- }
- sum += Math.max(neighbor.doubleDistance(), nkdist);
- count++;
- }
- }
- } else {
- for (DistanceDBIDListIter<D> neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
- if (objectIsInKNN || !DBIDUtil.equal(neighbor, iter)) {
- KNNList<D> neighborsNeighbors = knnReach.getKNNForDBID(neighbor, kreach);
- sum += Math.max(neighbor.getDistance().doubleValue(), neighborsNeighbors.getKNNDistance().doubleValue());
- count++;
- }
+ for(DoubleDBIDListIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ if(DBIDUtil.equal(neighbor, iter)) {
+ continue;
}
+ KNNList neighborsNeighbors = knnq.getKNNForDBID(neighbor, kreach);
+ sum += Math.max(neighbor.doubleValue(), neighborsNeighbors.getKNNDistance());
+ count++;
}
// Avoid division by 0
final double lrd = (sum > 0) ? (count / sum) : Double.POSITIVE_INFINITY;
lrds.putDouble(iter, lrd);
- if (lrdsProgress != null) {
- lrdsProgress.incrementProcessed(LOG);
- }
- }
- if (lrdsProgress != null) {
- lrdsProgress.ensureCompleted(LOG);
+ LOG.incrementProcessed(lrdsProgress);
}
- return lrds;
+ LOG.ensureCompleted(lrdsProgress);
}
/**
* Computes the Local outlier factor (LOF) of the specified objects.
*
- * @param ids the ids of the objects
- * @param lrds the LRDs of the objects
- * @param knnRefer the precomputed neighborhood of the objects w.r.t. the
+ * @param knnq the precomputed neighborhood of the objects w.r.t. the
* reference distance
- * @return the LOFs of the objects and the maximum LOF
+ * @param ids IDs to process
+ * @param lrds Local reachability distances
+ * @param lofs Local outlier factor storage
+ * @param lofminmax Score minimum/maximum tracker
*/
- protected Pair<WritableDoubleDataStore, DoubleMinMax> computeLOFs(DBIDs ids, DoubleDataStore lrds, KNNQuery<O, D> knnRefer) {
- WritableDoubleDataStore lofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC);
- // track the maximum value for normalization.
- DoubleMinMax lofminmax = new DoubleMinMax();
-
+ protected void computeLOFs(KNNQuery<O> knnq, DBIDs ids, DoubleDataStore lrds, WritableDoubleDataStore lofs, DoubleMinMax lofminmax) {
FiniteProgress progressLOFs = LOG.isVerbose() ? new FiniteProgress("LOF_SCORE for objects", ids.size(), LOG) : null;
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- final double lrdp = lrds.doubleValue(iter);
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
final double lof;
- if (lrdp > 0 && !Double.isInfinite(lrdp)) {
- final KNNList<D> neighbors = knnRefer.getKNNForDBID(iter, krefer);
- double sum = 0.0;
+ final double lrdp = lrds.doubleValue(iter);
+ final KNNList neighbors = knnq.getKNNForDBID(iter, krefer);
+ if(!Double.isInfinite(lrdp)) {
+ double sum = 0.;
int count = 0;
- for (DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ for(DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
// skip the point itself
- if (objectIsInKNN || !DBIDUtil.equal(neighbor, iter)) {
- sum += lrds.doubleValue(neighbor);
- count++;
+ if(DBIDUtil.equal(neighbor, iter)) {
+ continue;
+ }
+ final double val = lrds.doubleValue(neighbor);
+ sum += val;
+ count++;
+ if(Double.isInfinite(val)) {
+ break;
}
}
- lof = sum / (count * lrdp);
- } else {
+ lof = sum / (lrdp * count);
+ }
+ else {
lof = 1.0;
}
lofs.putDouble(iter, lof);
// update minimum and maximum
- if (!Double.isInfinite(lof)) {
- lofminmax.put(lof);
- }
+ lofminmax.put(lof);
- if (progressLOFs != null) {
- progressLOFs.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(progressLOFs);
}
- if (progressLOFs != null) {
- progressLOFs.ensureCompleted(LOG);
- }
- return new Pair<>(lofs, lofminmax);
+ LOG.ensureCompleted(progressLOFs);
}
@Override
public TypeInformation[] getInputTypeRestriction() {
final TypeInformation type;
- if (reachabilityDistanceFunction.equals(referenceDistanceFunction)) {
+ if(reachabilityDistanceFunction.equals(referenceDistanceFunction)) {
type = reachabilityDistanceFunction.getInputTypeRestriction();
- } else {
+ }
+ else {
type = new CombinedTypeInformation(referenceDistanceFunction.getInputTypeRestriction(), reachabilityDistanceFunction.getInputTypeRestriction());
}
return TypeUtil.array(type);
@@ -393,7 +352,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @author Elke Achtert
*/
- public static class LOFResult<O, D extends NumberDistance<D, ?>> {
+ public static class LOFResult<O> {
/**
* The result of the run of the {@link FlexibleLOF} algorithm.
*/
@@ -402,22 +361,22 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
/**
* The kNN query w.r.t. the reference neighborhood distance.
*/
- private final KNNQuery<O, D> kNNRefer;
+ private final KNNQuery<O> kNNRefer;
/**
* The kNN query w.r.t. the reachability distance.
*/
- private final KNNQuery<O, D> kNNReach;
+ private final KNNQuery<O> kNNReach;
/**
* The RkNN query w.r.t. the reference neighborhood distance.
*/
- private RKNNQuery<O, D> rkNNRefer;
+ private RKNNQuery<O> rkNNRefer;
/**
* The rkNN query w.r.t. the reachability distance.
*/
- private RKNNQuery<O, D> rkNNReach;
+ private RKNNQuery<O> rkNNReach;
/**
* The LRD values of the objects.
@@ -439,7 +398,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
* @param lrds the LRD values of the objects
* @param lofs the LOF values of the objects
*/
- public LOFResult(OutlierResult result, KNNQuery<O, D> kNNRefer, KNNQuery<O, D> kNNReach, WritableDoubleDataStore lrds, WritableDoubleDataStore lofs) {
+ public LOFResult(OutlierResult result, KNNQuery<O> kNNRefer, KNNQuery<O> kNNReach, WritableDoubleDataStore lrds, WritableDoubleDataStore lofs) {
this.result = result;
this.kNNRefer = kNNRefer;
this.kNNReach = kNNReach;
@@ -452,7 +411,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @return the kNN query w.r.t. the reference neighborhood distance
*/
- public KNNQuery<O, D> getKNNRefer() {
+ public KNNQuery<O> getKNNRefer() {
return kNNRefer;
}
@@ -461,7 +420,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @return the kNN query w.r.t. the reachability distance
*/
- public KNNQuery<O, D> getKNNReach() {
+ public KNNQuery<O> getKNNReach() {
return kNNReach;
}
@@ -497,7 +456,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @param rkNNRefer the query to set
*/
- public void setRkNNRefer(RKNNQuery<O, D> rkNNRefer) {
+ public void setRkNNRefer(RKNNQuery<O> rkNNRefer) {
this.rkNNRefer = rkNNRefer;
}
@@ -506,7 +465,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @return the RkNN query w.r.t. the reference neighborhood distance
*/
- public RKNNQuery<O, D> getRkNNRefer() {
+ public RKNNQuery<O> getRkNNRefer() {
return rkNNRefer;
}
@@ -515,7 +474,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @return the RkNN query w.r.t. the reachability distance
*/
- public RKNNQuery<O, D> getRkNNReach() {
+ public RKNNQuery<O> getRkNNReach() {
return rkNNReach;
}
@@ -524,7 +483,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @param rkNNReach the query to set
*/
- public void setRkNNReach(RKNNQuery<O, D> rkNNReach) {
+ public void setRkNNReach(RKNNQuery<O> rkNNReach) {
this.rkNNReach = rkNNReach;
}
}
@@ -536,7 +495,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* The distance function to determine the reachability distance between
* database objects.
@@ -545,16 +504,16 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
/**
* Parameter to specify the number of nearest neighbors of an object to be
- * considered for computing its LOF_SCORE, must be an integer greater than
- * 1.
+ * considered for computing its LOF score, must be an integer greater or
+ * equal to 1.
*/
- public static final OptionID KREF_ID = new OptionID("lof.krefer", "The number of nearest neighbors of an object to be considered for computing its LOF_SCORE.");
+ public static final OptionID KREF_ID = new OptionID("lof.krefer", "The number of nearest neighbors of an object to be considered for computing its LOF score.");
/**
* Parameter to specify the number of nearest neighbors of an object to be
* considered for computing its reachability distance.
*/
- public static final OptionID KREACH_ID = new OptionID("lof.kreach", "The number of nearest neighbors of an object to be considered for computing its LOF_SCORE.");
+ public static final OptionID KREACH_ID = new OptionID("lof.kreach", "The number of nearest neighbors of an object to be considered for computing its LOF score.");
/**
* The reference set size to use.
@@ -569,43 +528,45 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
/**
* Neighborhood distance function.
*/
- protected DistanceFunction<O, D> neighborhoodDistanceFunction = null;
+ protected DistanceFunction<O> neighborhoodDistanceFunction = null;
/**
* Reachability distance function.
*/
- protected DistanceFunction<O, D> reachabilityDistanceFunction = null;
+ protected DistanceFunction<O> reachabilityDistanceFunction = null;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
final IntParameter pK = new IntParameter(KREF_ID);
- pK.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
- if (config.grab(pK)) {
+ pK.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(pK)) {
krefer = pK.intValue();
}
final IntParameter pK2 = new IntParameter(KREACH_ID);
pK2.setOptional(true);
- pK2.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
- if (config.grab(pK2)) {
+ pK2.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(pK2)) {
kreach = pK2.intValue();
- } else {
+ }
+ else {
kreach = krefer;
}
- final ObjectParameter<DistanceFunction<O, D>> reachDistP = new ObjectParameter<>(REACHABILITY_DISTANCE_FUNCTION_ID, DistanceFunction.class);
+ final ObjectParameter<DistanceFunction<O>> reachDistP = new ObjectParameter<>(REACHABILITY_DISTANCE_FUNCTION_ID, DistanceFunction.class);
reachDistP.setOptional(true);
- if (config.grab(reachDistP)) {
+ if(config.grab(reachDistP)) {
reachabilityDistanceFunction = reachDistP.instantiateClass(config);
- } else {
+ }
+ else {
reachabilityDistanceFunction = distanceFunction;
}
}
@Override
- protected FlexibleLOF<O, D> makeInstance() {
+ protected FlexibleLOF<O> makeInstance() {
return new FlexibleLOF<>(kreach, krefer, distanceFunction, reachabilityDistanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/INFLO.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/INFLO.java
index 28fcf01b..611701ab 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/INFLO.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/INFLO.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -34,15 +34,16 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.KNNList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-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.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.math.Mean;
@@ -59,18 +60,19 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
/**
- * INFLO provides the Mining Algorithms (Two-way Search Method) for Influence
- * Outliers using Symmetric Relationship
- * <p>
+ * Influence Outliers using Symmetric Relationship (INFLO) using two-way search,
+ * is an outlier detection method based on LOF; but also using the reverse kNN.
+ *
* Reference: <br>
* <p>
- * Jin, W., Tung, A., Han, J., and Wang, W. 2006<br/>
- * Ranking outliers using symmetric neighborhood relationship<br/>
- * In Proc. Pacific-Asia Conf. on Knowledge Discovery and Data Mining (PAKDD),
- * Singapore
+ * W. Jin, A. Tung, J. Han, and W. Wang<br />
+ * Ranking outliers using symmetric neighborhood relationship<br />
+ * Proc. 10th Pacific-Asia conference on Advances in Knowledge Discovery and
+ * Data Mining, 2006.
* </p>
*
* @author Ahmed Hettab
+ * @author Erich Schubert
*
* @apiviz.has KNNQuery
*
@@ -78,35 +80,23 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*/
@Title("INFLO: Influenced Outlierness Factor")
@Description("Ranking Outliers Using Symmetric Neigborhood Relationship")
-@Reference(authors = "Jin, W., Tung, A., Han, J., and Wang, W", title = "Ranking outliers using symmetric neighborhood relationship", booktitle = "Proc. Pacific-Asia Conf. on Knowledge Discovery and Data Mining (PAKDD), Singapore, 2006", url = "http://dx.doi.org/10.1007/11731139_68")
-public class INFLO<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "W. Jin, A. Tung, J. Han, and W. Wang", //
+title = "Ranking outliers using symmetric neighborhood relationship", //
+booktitle = "Proc. 10th Pacific-Asia conference on Advances in Knowledge Discovery and Data Mining", //
+url = "http://dx.doi.org/10.1007/11731139_68")
+public class INFLO<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(INFLO.class);
/**
- * Parameter to specify if any object is a Core Object must be a double
- * greater than 0.0
- * <p>
- * see paper "Two-way search method" 3.2
- */
- public static final OptionID M_ID = new OptionID("inflo.m", "The threshold");
-
- /**
- * Holds the value of {@link #M_ID}.
+ * Pruning threshold m.
*/
private double m;
/**
- * Parameter to specify the number of nearest neighbors of an object to be
- * considered for computing its INFLO_SCORE. must be an integer greater than
- * 1.
- */
- public static final OptionID K_ID = new OptionID("inflo.k", "The number of nearest neighbors of an object to be considered for computing its INFLO_SCORE.");
-
- /**
- * Holds the value of {@link #K_ID}.
+ * Number of neighbors to use.
*/
private int k;
@@ -117,7 +107,7 @@ public class INFLO<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBa
* @param m m Parameter
* @param k k Parameter
*/
- public INFLO(DistanceFunction<? super O, D> distanceFunction, double m, int k) {
+ public INFLO(DistanceFunction<? super O> distanceFunction, double m, int k) {
super(distanceFunction);
this.m = m;
this.k = k;
@@ -131,9 +121,9 @@ public class INFLO<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBa
* @return Outlier result
*/
public OutlierResult run(Database database, Relation<O> relation) {
- DistanceQuery<O, D> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
+ DistanceQuery<O> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
+ KNNQuery<O> knnQuery = database.getKNNQuery(distFunc, k + 1, DatabaseQuery.HINT_HEAVY_USE);
- ModifiableDBIDs processedIDs = DBIDUtil.newHashSet(relation.size());
ModifiableDBIDs pruned = DBIDUtil.newHashSet();
// KNNS
WritableDataStore<ModifiableDBIDs> knns = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, ModifiableDBIDs.class);
@@ -147,72 +137,112 @@ public class INFLO<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBa
rnns.put(iditer, DBIDUtil.newArray());
}
- // TODO: use kNN preprocessor?
- KNNQuery<O, D> knnQuery = database.getKNNQuery(distFunc, k, DatabaseQuery.HINT_HEAVY_USE);
+ computeNeighborhoods(relation, knnQuery, pruned, knns, rnns, density);
- for(DBIDIter id = relation.iterDBIDs(); id.valid(); id.advance()) {
- // if not visited count=0
- int count = rnns.get(id).size();
- if(!processedIDs.contains(id)) {
- // TODO: use exactly k neighbors?
- KNNList<D> list = knnQuery.getKNNForDBID(id, k);
- knns.get(id).addDBIDs(list);
- processedIDs.add(id);
- density.putDouble(id, 1 / list.getKNNDistance().doubleValue());
+ // Calculate INFLO for any Object
+ DoubleMinMax inflominmax = new DoubleMinMax();
+ WritableDoubleDataStore inflos = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
+ // Note: this modifies knns, by adding rknns!
+ computeINFLO(relation, pruned, knns, rnns, density, inflos, inflominmax);
- }
- ModifiableDBIDs s = knns.get(id);
- for(DBIDIter q = knns.get(id).iter(); q.valid(); q.advance()) {
- if(!processedIDs.contains(q)) {
- // TODO: use exactly k neighbors?
- KNNList<D> listQ = knnQuery.getKNNForDBID(q, k);
- knns.get(q).addDBIDs(listQ);
- density.putDouble(q, 1 / listQ.getKNNDistance().doubleValue());
- processedIDs.add(q);
- }
+ // Build result representation.
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Influence Outlier Score", "inflo-outlier", inflos, relation.getDBIDs());
+ OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(inflominmax.getMin(), inflominmax.getMax(), 0., Double.POSITIVE_INFINITY, 1.);
+ return new OutlierResult(scoreMeta, scoreResult);
+ }
- if(knns.get(q).contains(id)) {
- rnns.get(q).add(id);
- rnns.get(id).add(q);
+ /**
+ * Compute neighborhoods
+ *
+ * @param relation
+ * @param knnQuery
+ * @param pruned
+ * @param knns
+ * @param rnns
+ * @param density
+ */
+ protected void computeNeighborhoods(Relation<O> relation, KNNQuery<O> knnQuery, ModifiableDBIDs pruned, WritableDataStore<ModifiableDBIDs> knns, WritableDataStore<ModifiableDBIDs> rnns, WritableDoubleDataStore density) {
+ for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
+ // if not visited count=0
+ int count = rnns.get(iter).size();
+ DBIDs knn = getKNN(iter, knnQuery, knns, density);
+ for(DBIDIter niter = knn.iter(); niter.valid(); niter.advance()) {
+ // Ignore the query point itself.
+ if(DBIDUtil.equal(iter, niter)) {
+ continue;
+ }
+ if(getKNN(niter, knnQuery, knns, density).contains(iter)) {
+ rnns.get(niter).add(iter);
+ rnns.get(iter).add(niter);
count++;
}
}
- if(count >= s.size() * m) {
- pruned.add(id);
+ if(count >= knn.size() * m) {
+ pruned.add(iter);
}
}
+ }
- // Calculate INFLO for any Object
- // IF Object is pruned INFLO=1.0
- DoubleMinMax inflominmax = new DoubleMinMax();
- WritableDoubleDataStore inflos = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
- for(DBIDIter id = relation.iterDBIDs(); id.valid(); id.advance()) {
- if(!pruned.contains(id)) {
- ModifiableDBIDs knn = knns.get(id);
- ModifiableDBIDs rnn = rnns.get(id);
-
- double denP = density.doubleValue(id);
- knn.addDBIDs(rnn);
- Mean mean = new Mean();
- for(DBIDIter iter = knn.iter(); iter.valid(); iter.advance()) {
- mean.put(density.doubleValue(iter));
+ /**
+ * Compute the final INFLO scores.
+ *
+ * @param relation Data relation
+ * @param pruned Pruned objects
+ * @param knns kNN storage
+ * @param rnns reverse kNN storage
+ * @param density Density estimation
+ * @param inflos Inflo score storage
+ * @param inflominmax Output of minimum and maximum
+ */
+ protected void computeINFLO(Relation<O> relation, ModifiableDBIDs pruned, WritableDataStore<ModifiableDBIDs> knns, WritableDataStore<ModifiableDBIDs> rnns, WritableDoubleDataStore density, WritableDoubleDataStore inflos, DoubleMinMax inflominmax) {
+ Mean mean = new Mean();
+ for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
+ if(pruned.contains(iter)) {
+ inflos.putDouble(iter, 1.);
+ inflominmax.put(1.);
+ continue;
+ }
+ ModifiableDBIDs knn = knns.get(iter), rnn = rnns.get(iter);
+ knn.addDBIDs(rnn);
+ // Compute mean density of NN \cup RNN
+ mean.reset();
+ for(DBIDIter niter = knn.iter(); niter.valid(); niter.advance()) {
+ if(DBIDUtil.equal(iter, niter)) {
+ continue;
}
- double den = mean.getMean() / denP;
- inflos.putDouble(id, den);
- // update minimum and maximum
- inflominmax.put(den);
-
+ mean.put(density.doubleValue(niter));
}
- if(pruned.contains(id)) {
- inflos.putDouble(id, 1.0);
- inflominmax.put(1.0);
+ double denP = density.doubleValue(iter);
+ double den;
+ if(denP > 0.) {
+ den = mean.getMean() / denP;
}
+ else {
+ den = mean.getMean() == 0 ? 1. : Double.POSITIVE_INFINITY;
+ }
+ inflos.putDouble(iter, den);
+ // update minimum and maximum
+ inflominmax.put(den);
}
+ }
- // Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("Influence Outlier Score", "inflo-outlier", TypeUtil.DOUBLE, inflos, relation.getDBIDs());
- OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(inflominmax.getMin(), inflominmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 1.0);
- return new OutlierResult(scoreMeta, scoreResult);
+ /**
+ * Get the (forward only) kNN of an object, including the query point
+ *
+ * @param q Query point
+ * @param knnQuery Query function
+ * @param knns kNN storage
+ * @param density Density storage
+ * @return Neighbor list
+ */
+ protected DBIDs getKNN(DBIDIter q, KNNQuery<O> knnQuery, WritableDataStore<ModifiableDBIDs> knns, WritableDoubleDataStore density) {
+ ModifiableDBIDs s = knns.get(q);
+ if(s.size() == 0) {
+ KNNList listQ = knnQuery.getKNNForDBID(q, k + 1);
+ s.addDBIDs(listQ);
+ density.putDouble(q, 1. / listQ.getKNNDistance());
+ }
+ return s;
}
@Override
@@ -232,29 +262,49 @@ public class INFLO<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBa
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * Parameter to specify if any object is a Core Object must be a double
+ * greater than 0.0
+ *
+ * see paper "Two-way search method" 3.2
+ */
+ public static final OptionID M_ID = new OptionID("inflo.m", "The pruning threshold");
+
+ /**
+ * Parameter to specify the number of nearest neighbors of an object to be
+ * considered for computing its INFLO score.
+ */
+ public static final OptionID K_ID = new OptionID("inflo.k", "The number of nearest neighbors of an object to be considered for computing its INFLO score.");
+
+ /**
+ * M parameter
+ */
protected double m = 1.0;
+ /**
+ * Number of neighbors to use.
+ */
protected int k = 0;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final DoubleParameter mP = new DoubleParameter(M_ID, 1.0);
- mP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ final DoubleParameter mP = new DoubleParameter(M_ID, 1.0)//
+ .addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
if(config.grab(mP)) {
m = mP.doubleValue();
}
- final IntParameter kP = new IntParameter(K_ID);
- kP.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
+ final IntParameter kP = new IntParameter(K_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
if(config.grab(kP)) {
k = kP.intValue();
}
}
@Override
- protected INFLO<O, D> makeInstance() {
+ protected INFLO<O> makeInstance() {
return new INFLO<>(distanceFunction, m, k);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/KDEOS.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/KDEOS.java
new file mode 100644
index 00000000..2183872f
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/KDEOS.java
@@ -0,0 +1,445 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
+
+/*
+ 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.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
+import de.lmu.ifi.dbs.elki.data.FeatureVector;
+import de.lmu.ifi.dbs.elki.data.type.CombinedTypeInformation;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
+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.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.MeanVariance;
+import de.lmu.ifi.dbs.elki.math.statistics.distribution.NormalDistribution;
+import de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions.GaussianKernelDensityFunction;
+import de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions.KernelDensityFunction;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.result.outlier.ProbabilisticOutlierScore;
+import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+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.constraints.LessEqualGlobalConstraint;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
+
+/**
+ * Generalized Outlier Detection with Flexible Kernel Density Estimates.
+ *
+ * This is an outlier detection inspired by LOF, but using kernel density
+ * estimation (KDE) from statistics. Unfortunately, for higher dimensional data,
+ * kernel density estimation itself becomes difficult. At this point, the
+ * <tt>kdeos.idim</tt> parameter can become useful, which allows to either
+ * disable dimensionality adjustment completely (<tt>0</tt>) or to set it to a
+ * lower dimensionality than the data representation. This may sound like a hack
+ * at first, but real data is often of lower intrinsic dimensionality, and
+ * embedded into a higher data representation. Adjusting the kernel to account
+ * for the representation seems to yield worse results than using a lower,
+ * intrinsic, dimensionality.
+ *
+ * If your data set has many duplicates, the <tt>kdeos.kernel.minbw</tt>
+ * parameter sets a minimum kernel bandwidth, which may improve results in these
+ * cases, as it prevents kernels from degenerating to single points.
+ *
+ * Reference:
+ * <p>
+ * Erich Schubert, Arthur Zimek, Hans-Peter Kriegel<br />
+ * Generalized Outlier Detection with Flexible Kernel Density Estimates<br />
+ * In Proceedings of the 14th SIAM International Conference on Data Mining
+ * (SDM), Philadelphia, PA, 2014.
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has KNNQuery
+ * @apiviz.has KernelDensityFunction
+ *
+ * @param <O> Object type
+ */
+@Reference(authors = "Erich Schubert, Arthur Zimek, Hans-Peter Kriegel", //
+title = "Generalized Outlier Detection with Flexible Kernel Density Estimates", //
+booktitle = "Proc. 14th SIAM International Conference on Data Mining (SDM), Philadelphia, PA, 2014", //
+url = "http://dx.doi.org/10.1137/1.9781611973440.63")
+public class KDEOS<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(KDEOS.class);
+
+ /**
+ * Kernel function to use for density estimation.
+ */
+ KernelDensityFunction kernel;
+
+ /**
+ * Minimum and maximum number of neighbors to use.
+ */
+ int kmin, kmax;
+
+ /**
+ * Kernel scaling parameter.
+ */
+ double scale;
+
+ /**
+ * Kernel minimum bandwidth.
+ */
+ double minBandwidth = 1e-6;
+
+ /**
+ * Intrinsic dimensionality.
+ */
+ int idim = -1;
+
+ /**
+ * Significance cutoff when computing kernel density.
+ */
+ final static double CUTOFF = 1e-20;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function
+ * @param kmin Minimum number of neighbors
+ * @param kmax Maximum number of neighbors
+ * @param kernel Kernel function
+ * @param scale Kernel scaling parameter
+ * @param idim Intrinsic dimensionality (use 0 to use real dimensionality)
+ */
+ public KDEOS(DistanceFunction<? super O> distanceFunction, int kmin, int kmax, KernelDensityFunction kernel, double minBandwidth, double scale, int idim) {
+ super(distanceFunction);
+ this.kmin = kmin;
+ this.kmax = kmax;
+ this.kernel = kernel;
+ this.minBandwidth = minBandwidth;
+ this.scale = scale;
+ this.idim = idim;
+ }
+
+ /**
+ * Run the KDEOS outlier detection algorithm.
+ *
+ * @param database Database to query
+ * @param rel Relation to process
+ * @return Outlier detection result
+ */
+ public OutlierResult run(Database database, Relation<O> rel) {
+ final DBIDs ids = rel.getDBIDs();
+
+ LOG.verbose("Running kNN preprocessor.");
+ KNNQuery<O> knnq = DatabaseUtil.precomputedKNNQuery(database, rel, getDistanceFunction(), kmax + 1);
+
+ // Initialize store for densities
+ WritableDataStore<double[]> densities = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, double[].class);
+ estimateDensities(rel, knnq, ids, densities);
+
+ // Compute scores:
+ WritableDoubleDataStore kofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_DB);
+ DoubleMinMax minmax = new DoubleMinMax();
+ computeOutlierScores(knnq, ids, densities, kofs, minmax);
+
+ DoubleRelation scoreres = new MaterializedDoubleRelation("Kernel Density Estimation Outlier Scores", "kdeos-outlier", kofs, ids);
+ OutlierScoreMeta meta = new ProbabilisticOutlierScore(minmax.getMin(), minmax.getMax());
+ return new OutlierResult(meta, scoreres);
+ }
+
+ /**
+ * Perform the kernel density estimation step.
+ *
+ * @param rel Relation to query
+ * @param knnq kNN query
+ * @param ids IDs to process
+ * @param densities Density storage
+ */
+ protected void estimateDensities(Relation<O> rel, KNNQuery<O> knnq, final DBIDs ids, WritableDataStore<double[]> densities) {
+ final int dim = dimensionality(rel);
+ final int knum = kmax + 1 - kmin;
+ // Initialize storage:
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ densities.put(iter, new double[knum]);
+ }
+ // Distribute densities:
+ FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Computing densities.", ids.size(), LOG) : null;
+ double iminbw = (minBandwidth > 0.) ? 1. / (minBandwidth * scale) : Double.POSITIVE_INFINITY;
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ KNNList neighbors = knnq.getKNNForDBID(iter, kmax + 1);
+ int k = 1, idx = 0;
+ double sum = 0.;
+ for(DoubleDBIDListIter kneighbor = neighbors.iter(); k <= kmax && kneighbor.valid(); kneighbor.advance(), k++) {
+ sum += kneighbor.doubleValue();
+ if(k < kmin) {
+ continue;
+ }
+ final double ibw = Math.min(k / (sum * scale), iminbw);
+ final double sca = MathUtil.powi(ibw, dim);
+ for(DoubleDBIDListIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ final double dens;
+ if(sca < Double.POSITIVE_INFINITY) { // NaNs with duplicate points!
+ dens = sca * kernel.density(neighbor.doubleValue() * ibw);
+ }
+ else {
+ dens = neighbor.doubleValue() == 0. ? 1. : 0.;
+ }
+ densities.get(neighbor)[idx] += dens;
+ if(dens < CUTOFF) {
+ break;
+ }
+ }
+ ++idx; // Only if k >= kmin
+ }
+ LOG.incrementProcessed(prog);
+ }
+ LOG.ensureCompleted(prog);
+ }
+
+ /**
+ * Ugly hack to allow using this implementation without having a well-defined
+ * dimensionality.
+ *
+ * @param rel Data relation
+ * @return Dimensionality
+ */
+ private int dimensionality(Relation<O> rel) {
+ // Explicit:
+ if(idim >= 0) {
+ return idim;
+ }
+ // Cast to vector field relation.
+ @SuppressWarnings("unchecked")
+ final Relation<FeatureVector<?>> frel = (Relation<FeatureVector<?>>) rel;
+ int dim = RelationUtil.dimensionality(frel);
+ if(dim < 0) {
+ throw new AbortException("When using KDEOS with non-vectorspace data, the intrinsic dimensionality parameter must be set!");
+ }
+ return dim;
+ }
+
+ /**
+ * Compute the final KDEOS scores.
+ *
+ * @param knnq kNN query
+ * @param ids IDs to process
+ * @param densities Density estimates
+ * @param kdeos Score outputs
+ * @param minmax Minimum and maximum scores
+ */
+ protected void computeOutlierScores(KNNQuery<O> knnq, final DBIDs ids, WritableDataStore<double[]> densities, WritableDoubleDataStore kdeos, DoubleMinMax minmax) {
+ final int knum = kmax + 1 - kmin;
+ FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Computing KDEOS scores.", ids.size(), LOG) : null;
+
+ double[][] scratch = new double[knum][kmax + 5];
+ MeanVariance mv = new MeanVariance();
+
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ double[] dens = densities.get(iter);
+ KNNList neighbors = knnq.getKNNForDBID(iter, kmax);
+ if(scratch[0].length < neighbors.size()) {
+ // Resize scratch. Add some extra margin again.
+ scratch = new double[knum][neighbors.size() + 5];
+ }
+ { // Store density matrix of neighbors
+ int i = 0;
+ for(DoubleDBIDListIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance(), i++) {
+ double[] ndens = densities.get(neighbor);
+ for(int k = 0; k < knum; k++) {
+ scratch[k][i] = ndens[k];
+ }
+ }
+ assert (i == neighbors.size());
+ }
+ // Compute means and stddevs for each k
+ double score = 0.;
+ for(int i = 0; i < knum; i++) {
+ mv.reset();
+ for(int j = 0; j < neighbors.size(); j++) {
+ mv.put(scratch[i][j]);
+ }
+ final double mean = mv.getMean(), stddev = mv.getSampleStddev();
+ if(stddev > 0.) {
+ score += (mean - dens[i]) / stddev;
+ }
+ }
+ score /= knum; // average
+ score = NormalDistribution.standardNormalCDF(score);
+ minmax.put(score);
+ kdeos.put(iter, score);
+ LOG.incrementProcessed(prog);
+ }
+ LOG.ensureCompleted(prog);
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ TypeInformation res = getDistanceFunction().getInputTypeRestriction();
+ if(idim < 0) {
+ res = new CombinedTypeInformation(TypeUtil.NUMBER_VECTOR_FIELD, res);
+ }
+ return TypeUtil.array(res);
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <O> Object type
+ */
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * Parameter to specify the kernel density function.
+ */
+ private static final OptionID KERNEL_ID = new OptionID("kdeos.kernel", "Kernel density function to use.");
+
+ /**
+ * Parameter to specify the minimum bandwidth.
+ */
+ private static final OptionID KERNEL_MIN_ID = new OptionID("kdeos.kernel.minbw", "Minimum bandwidth for kernel density estimation.");
+
+ /**
+ * Parameter to specify the kernel scaling factor.
+ */
+ private static final OptionID KERNEL_SCALE_ID = new OptionID("kdeos.kernel.scale", "Scaling factor for the kernel function.");
+
+ /**
+ * Minimum value of k to analyze.
+ */
+ private static final OptionID KMIN_ID = new OptionID("kdeos.k.min", "Minimum value of k to analyze.");
+
+ /**
+ * Maximum value of k to analyze.
+ */
+ private static final OptionID KMAX_ID = new OptionID("kdeos.k.max", "Maximum value of k to analyze.");
+
+ /**
+ * Intrinsic dimensionality.
+ */
+ private static final OptionID IDIM_ID = new OptionID("kdeos.idim", "Intrinsic dimensionality of this data set. Use -1 for using the true data dimensionality, but values such as 0-2 often offer better performance.");
+
+ /**
+ * Kernel function to use for density estimation.
+ */
+ KernelDensityFunction kernel;
+
+ /**
+ * Minimum and maximum number of neighbors to use.
+ */
+ int kmin;
+
+ /**
+ * Minimum and maximum number of neighbors to use.
+ */
+ int kmax;
+
+ /**
+ * Kernel scaling parameter.
+ */
+ double scale;
+
+ /**
+ * Kernel minimum bandwidth.
+ */
+ double minBandwidth = 0.;
+
+ /**
+ * Intrinsic dimensionality.
+ */
+ int idim = -1;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ ObjectParameter<KernelDensityFunction> kernelP = new ObjectParameter<>(KERNEL_ID, KernelDensityFunction.class, GaussianKernelDensityFunction.class);
+ if(config.grab(kernelP)) {
+ kernel = kernelP.instantiateClass(config);
+ }
+
+ IntParameter kminP = new IntParameter(KMIN_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(kminP)) {
+ kmin = kminP.intValue();
+ }
+
+ IntParameter kmaxP = new IntParameter(KMAX_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(kmaxP)) {
+ kmax = kmaxP.intValue();
+ }
+ config.checkConstraint(new LessEqualGlobalConstraint<>(kminP, kmaxP));
+
+ DoubleParameter scaleP = new DoubleParameter(KERNEL_SCALE_ID)//
+ .addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE) //
+ .setDefaultValue(.5);
+ if(config.grab(scaleP)) {
+ // For simpler parameterization, scale kernels by their canonical
+ // bandwidth, when the kernel is configured.
+ scale = scaleP.doubleValue() * ((kernel != null) ? kernel.canonicalBandwidth() : 1.);
+ }
+ DoubleParameter minbwP = new DoubleParameter(KERNEL_MIN_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE) //
+ .setOptional(true);
+ if(config.grab(minbwP)) {
+ minBandwidth = minbwP.doubleValue();
+ }
+ IntParameter idimP = new IntParameter(IDIM_ID, -1);
+ if(config.grab(idimP)) {
+ idim = idimP.intValue();
+ }
+ }
+
+ @Override
+ protected KDEOS<O> makeInstance() {
+ return new KDEOS<>(distanceFunction, kmin, kmax, kernel, minBandwidth, scale, idim);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LDF.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LDF.java
index e5049877..c2e29f54 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LDF.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LDF.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
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,27 +30,20 @@ import de.lmu.ifi.dbs.elki.data.type.CombinedTypeInformation;
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.Database;
-import de.lmu.ifi.dbs.elki.database.QueryUtil;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-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.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
-import de.lmu.ifi.dbs.elki.database.query.knn.PreprocessorKNNQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNPreprocessor;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
@@ -61,6 +54,7 @@ import de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions.KernelDensityFunction
import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -88,10 +82,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.has KernelDensityFunction
*
* @param <O> the type of objects handled by this Algorithm
- * @param <D> Distance type
*/
-@Reference(authors = "L. J. Latecki, A. Lazarevic, D. Pokrajac", title = "Outlier Detection with Kernel Density Functions", booktitle = "Machine Learning and Data Mining in Pattern Recognition", url = "http://dx.doi.org/10.1007/978-3-540-73499-4_6")
-public class LDF<O extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "L. J. Latecki, A. Lazarevic, D. Pokrajac", //
+title = "Outlier Detection with Kernel Density Functions", //
+booktitle = "Machine Learning and Data Mining in Pattern Recognition", //
+url = "http://dx.doi.org/10.1007/978-3-540-73499-4_6")
+public class LDF<O extends NumberVector> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -125,7 +121,7 @@ public class LDF<O extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
* @param h Kernel bandwidth scaling
* @param c Score scaling parameter
*/
- public LDF(int k, DistanceFunction<? super O, D> distance, KernelDensityFunction kernel, double h, double c) {
+ public LDF(int k, DistanceFunction<? super O> distance, KernelDensityFunction kernel, double h, double c) {
super(distance);
this.k = k + 1;
this.kernel = kernel;
@@ -142,84 +138,42 @@ public class LDF<O extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
*/
public OutlierResult run(Database database, Relation<O> relation) {
StepProgress stepprog = LOG.isVerbose() ? new StepProgress("LDF", 3) : null;
-
final int dim = RelationUtil.dimensionality(relation);
-
DBIDs ids = relation.getDBIDs();
- // "HEAVY" flag for KNN Query since it is used more than once
- KNNQuery<O, D> knnq = QueryUtil.getKNNQuery(relation, getDistanceFunction(), k, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
- // No optimized kNN query - use a preprocessor!
- if(!(knnq instanceof PreprocessorKNNQuery)) {
- if(stepprog != null) {
- stepprog.beginStep(1, "Materializing neighborhoods w.r.t. distance function.", LOG);
- }
- MaterializeKNNPreprocessor<O, D> preproc = new MaterializeKNNPreprocessor<>(relation, getDistanceFunction(), k);
- database.addIndex(preproc);
- DistanceQuery<O, D> rdq = database.getDistanceQuery(relation, getDistanceFunction());
- knnq = preproc.getKNNQuery(rdq, k);
- }
+ LOG.beginStep(stepprog, 1, "Materializing neighborhoods w.r.t. distance function.");
+ KNNQuery<O> knnq = DatabaseUtil.precomputedKNNQuery(database, relation, getDistanceFunction(), k);
// Compute LDEs
- if(stepprog != null) {
- stepprog.beginStep(2, "Computing LDEs.", LOG);
- }
+ LOG.beginStep(stepprog, 2, "Computing LDEs.");
WritableDoubleDataStore ldes = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
FiniteProgress densProgress = LOG.isVerbose() ? new FiniteProgress("Densities", ids.size(), LOG) : null;
for(DBIDIter it = ids.iter(); it.valid(); it.advance()) {
- final KNNList<D> neighbors = knnq.getKNNForDBID(it, k);
+ final KNNList neighbors = knnq.getKNNForDBID(it, k);
double sum = 0.0;
int count = 0;
- if(neighbors instanceof DoubleDistanceKNNList) {
- // Fast version for double distances
- for(DoubleDistanceDBIDListIter neighbor = ((DoubleDistanceKNNList) neighbors).iter(); neighbor.valid(); neighbor.advance()) {
- if(DBIDUtil.equal(neighbor, it)) {
- continue;
- }
- final double nkdist = ((DoubleDistanceKNNList) knnq.getKNNForDBID(neighbor, k)).doubleKNNDistance();
- if(nkdist > 0.) {
- final double v = Math.max(nkdist, neighbor.doubleDistance()) / (h * nkdist);
- sum += kernel.density(v) / MathUtil.powi(h * nkdist, dim);
- count++;
- }
- else {
- sum = Double.POSITIVE_INFINITY;
- count++;
- break;
- }
+ // Fast version for double distances
+ for(DoubleDBIDListIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ if(DBIDUtil.equal(neighbor, it)) {
+ continue;
}
- }
- else {
- for(DistanceDBIDListIter<D> neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
- if(DBIDUtil.equal(neighbor, it)) {
- continue;
- }
- final double nkdist = knnq.getKNNForDBID(neighbor, k).getKNNDistance().doubleValue();
- if(nkdist > 0.) {
- final double v = Math.max(nkdist, neighbor.getDistance().doubleValue()) / (h * nkdist);
- sum += kernel.density(v) / MathUtil.powi(h * nkdist, dim);
- count++;
- }
- else {
- sum = Double.POSITIVE_INFINITY;
- count++;
- break;
- }
+ final double nkdist = knnq.getKNNForDBID(neighbor, k).getKNNDistance();
+ if(!(nkdist > 0.)) {
+ sum = Double.POSITIVE_INFINITY;
+ count++;
+ break;
}
+ final double v = Math.max(nkdist, neighbor.doubleValue()) / (h * nkdist);
+ sum += kernel.density(v) / MathUtil.powi(h * nkdist, dim);
+ count++;
}
ldes.putDouble(it, sum / count);
- if(densProgress != null) {
- densProgress.incrementProcessed(LOG);
- }
- }
- if(densProgress != null) {
- densProgress.ensureCompleted(LOG);
+ LOG.incrementProcessed(densProgress);
}
+ LOG.ensureCompleted(densProgress);
// Compute local density factors.
- if(stepprog != null) {
- stepprog.beginStep(3, "Computing LDFs.", LOG);
- }
+ LOG.beginStep(stepprog, 3, "Computing LDFs.");
WritableDoubleDataStore ldfs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC);
// track the maximum value for normalization.
DoubleMinMax lofminmax = new DoubleMinMax();
@@ -227,7 +181,7 @@ public class LDF<O extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
FiniteProgress progressLOFs = LOG.isVerbose() ? new FiniteProgress("Local Density Factors", ids.size(), LOG) : null;
for(DBIDIter it = ids.iter(); it.valid(); it.advance()) {
final double lrdp = ldes.doubleValue(it);
- final KNNList<D> neighbors = knnq.getKNNForDBID(it, k);
+ final KNNList neighbors = knnq.getKNNForDBID(it, k);
double sum = 0.0;
int count = 0;
for(DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
@@ -245,20 +199,14 @@ public class LDF<O extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
// update minimum and maximum
lofminmax.put(ldf);
- if(progressLOFs != null) {
- progressLOFs.incrementProcessed(LOG);
- }
- }
- if(progressLOFs != null) {
- progressLOFs.ensureCompleted(LOG);
+ LOG.incrementProcessed(progressLOFs);
}
+ LOG.ensureCompleted(progressLOFs);
- if(stepprog != null) {
- stepprog.setCompleted(LOG);
- }
+ LOG.setCompleted(stepprog);
// Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("Local Density Factor", "ldf-outlier", TypeUtil.DOUBLE, ldfs, ids);
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Local Density Factor", "ldf-outlier", ldfs, ids);
OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(lofminmax.getMin(), lofminmax.getMax(), 0.0, 1. / c, 1 / (1 + c));
OutlierResult result = new OutlierResult(scoreMeta, scoreResult);
@@ -283,9 +231,8 @@ public class LDF<O extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
* @apiviz.exclude
*
* @param <O> vector type
- * @param <D> distance type
*/
- public static class Parameterizer<O extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O extends NumberVector> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Option ID for kernel.
*/
@@ -353,7 +300,7 @@ public class LDF<O extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
}
@Override
- protected LDF<O, D> makeInstance() {
+ protected LDF<O> makeInstance() {
return new LDF<>(k, distanceFunction, kernel, h, c);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LDOF.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LDOF.java
index 36c70b48..479b0bab 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LDOF.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LDOF.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
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
@@ -33,14 +33,14 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
@@ -79,9 +79,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*/
@Title("LDOF: Local Distance-Based Outlier Factor")
@Description("Local outlier detection appraoch suitable for scattered data by averaging the kNN distance over all k nearest neighbors")
-@Reference(authors = "K. Zhang, M. Hutter, H. Jin", title = "A New Local Distance-Based Outlier Detection Approach for Scattered Real-World Data", booktitle = "Proc. 13th Pacific-Asia Conference on Advances in Knowledge Discovery and Data Mining (PAKDD 2009), Bangkok, Thailand, 2009", url = "http://dx.doi.org/10.1007/978-3-642-01307-2_84")
+@Reference(authors = "K. Zhang, M. Hutter, H. Jin", //
+title = "A New Local Distance-Based Outlier Detection Approach for Scattered Real-World Data", //
+booktitle = "Proc. 13th Pacific-Asia Conference on Advances in Knowledge Discovery and Data Mining (PAKDD 2009), Bangkok, Thailand, 2009", //
+url = "http://dx.doi.org/10.1007/978-3-642-01307-2_84")
@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.LDOF" })
-public class LDOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
+public class LDOF<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -110,7 +113,7 @@ public class LDOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
* @param distanceFunction distance function
* @param k k Parameter
*/
- public LDOF(DistanceFunction<? super O, D> distanceFunction, int k) {
+ public LDOF(DistanceFunction<? super O> distanceFunction, int k) {
super(distanceFunction);
this.k = k;
}
@@ -123,8 +126,8 @@ public class LDOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
* @return Outlier result
*/
public OutlierResult run(Database database, Relation<O> relation) {
- DistanceQuery<O, D> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
- KNNQuery<O, D> knnQuery = database.getKNNQuery(distFunc, k);
+ DistanceQuery<O> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
+ KNNQuery<O> knnQuery = database.getKNNQuery(distFunc, k + 1);
// track the maximum value for normalization
DoubleMinMax ldofminmax = new DoubleMinMax();
@@ -135,23 +138,26 @@ public class LDOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
if(LOG.isVerbose()) {
LOG.verbose("Computing LDOFs");
}
- FiniteProgress progressLDOFs = LOG.isVerbose() ? new FiniteProgress("LDOF_SCORE for objects", relation.size(), LOG) : null;
+ FiniteProgress progressLDOFs = LOG.isVerbose() ? new FiniteProgress("LDOF for objects", relation.size(), LOG) : null;
Mean dxp = new Mean(), Dxp = new Mean();
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- KNNList<D> neighbors = knnQuery.getKNNForDBID(iditer, k);
- // skip the point itself
+ KNNList neighbors = knnQuery.getKNNForDBID(iditer, k + 1);
dxp.reset();
Dxp.reset();
- // TODO: optimize for double distances
- for(DistanceDBIDListIter<D> neighbor1 = neighbors.iter(); neighbor1.valid(); neighbor1.advance()) {
- if(!DBIDUtil.equal(neighbor1, iditer)) {
- dxp.put(neighbor1.getDistance().doubleValue());
- for(DistanceDBIDListIter<D> neighbor2 = neighbors.iter(); neighbor2.valid(); neighbor2.advance()) {
- if(!DBIDUtil.equal(neighbor1, neighbor2) && !DBIDUtil.equal(neighbor2, iditer)) {
- Dxp.put(distFunc.distance(neighbor1, neighbor2).doubleValue());
- }
+ DoubleDBIDListIter neighbor1 = neighbors.iter(), neighbor2 = neighbors.iter();
+ for(; neighbor1.valid(); neighbor1.advance()) {
+ // skip the point itself
+ if(DBIDUtil.equal(neighbor1, iditer)) {
+ continue;
+ }
+ dxp.put(neighbor1.doubleValue());
+ for(neighbor2.seek(neighbor1.getOffset() + 1); neighbor2.valid(); neighbor2.advance()) {
+ // skip the point itself
+ if(DBIDUtil.equal(neighbor2, iditer)) {
+ continue;
}
+ Dxp.put(distFunc.distance(neighbor1, neighbor2));
}
}
double ldof = dxp.getMean() / Dxp.getMean();
@@ -162,16 +168,12 @@ public class LDOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
// update maximum
ldofminmax.put(ldof);
- if(progressLDOFs != null) {
- progressLDOFs.incrementProcessed(LOG);
- }
- }
- if(progressLDOFs != null) {
- progressLDOFs.ensureCompleted(LOG);
+ LOG.incrementProcessed(progressLDOFs);
}
+ LOG.ensureCompleted(progressLDOFs);
// Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("LDOF Outlier Score", "ldof-outlier", TypeUtil.DOUBLE, ldofs, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("LDOF Outlier Score", "ldof-outlier", ldofs, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(ldofminmax.getMin(), ldofminmax.getMax(), 0.0, Double.POSITIVE_INFINITY, LDOF_BASELINE);
return new OutlierResult(scoreMeta, scoreResult);
}
@@ -193,21 +195,21 @@ public class LDOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
protected 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);
+ kP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
if(config.grab(kP)) {
k = kP.getValue();
}
}
@Override
- protected LDOF<O, D> makeInstance() {
+ protected LDOF<O> makeInstance() {
return new LDOF<>(distanceFunction, k);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LOCI.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LOCI.java
index e76c6034..8d371d4c 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LOCI.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LOCI.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
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,9 +23,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.Arrays;
import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
@@ -37,15 +35,15 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-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.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
@@ -54,23 +52,24 @@ import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.QuotientOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.DoubleIntegerArrayQuickSort;
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;
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.DistanceParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
/**
* Fast Outlier Detection Using the "Local Correlation Integral".
*
- * Exact implementation only, not aLOCI. See {@link ALOCI}
+ * Exact implementation only, not aLOCI. See {@link ALOCI}.
*
* Outlier detection using multiple epsilon neighborhoods.
*
+ * This implementation has O(n<sup>3</sup> log n) runtime complexity!
+ *
* Based on: S. Papadimitriou, H. Kitagawa, P. B. Gibbons and C. Faloutsos:
* LOCI: Fast Outlier Detection Using the Local Correlation Integral. In: Proc.
* 19th IEEE Int. Conf. on Data Engineering (ICDE '03), Bangalore, India, 2003.
@@ -80,13 +79,12 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
* @apiviz.has RangeQuery
*
* @param <O> Object type
- * @param <D> Distance type
*/
@Title("LOCI: Fast Outlier Detection Using the Local Correlation Integral")
@Description("Algorithm to compute outliers based on the Local Correlation Integral")
@Reference(authors = "S. Papadimitriou, H. Kitagawa, P. B. Gibbons, C. Faloutsos", title = "LOCI: Fast Outlier Detection Using the Local Correlation Integral", booktitle = "Proc. 19th IEEE Int. Conf. on Data Engineering (ICDE '03), Bangalore, India, 2003", url = "http://dx.doi.org/10.1109/ICDE.2003.1260802")
-@Alias({"de.lmu.ifi.dbs.elki.algorithm.outlier.LOCI"})
-public class LOCI<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.LOCI" })
+public class LOCI<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -111,7 +109,7 @@ public class LOCI<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
/**
* Holds the value of {@link #RMAX_ID}.
*/
- private D rmax;
+ private double rmax;
/**
* Holds the value of {@link #NMIN_ID}.
@@ -131,7 +129,7 @@ public class LOCI<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
* @param nmin Minimum neighborhood size
* @param alpha Alpha value
*/
- public LOCI(DistanceFunction<? super O, D> distanceFunction, D rmax, int nmin, double alpha) {
+ public LOCI(DistanceFunction<? super O> distanceFunction, double rmax, int nmin, double alpha) {
super(distanceFunction);
this.rmax = rmax;
this.nmin = nmin;
@@ -146,96 +144,62 @@ public class LOCI<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
* @return Outlier result
*/
public OutlierResult run(Database database, Relation<O> relation) {
- DistanceQuery<O, D> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
- RangeQuery<O, D> rangeQuery = database.getRangeQuery(distFunc);
+ DistanceQuery<O> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
+ RangeQuery<O> rangeQuery = database.getRangeQuery(distFunc);
+ DBIDs ids = relation.getDBIDs();
- FiniteProgress progressPreproc = LOG.isVerbose() ? new FiniteProgress("LOCI preprocessing", relation.size(), LOG) : null;
// LOCI preprocessing step
- WritableDataStore<ArrayList<DoubleIntPair>> interestingDistances = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_SORTED, ArrayList.class);
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- DistanceDBIDList<D> neighbors = rangeQuery.getRangeForDBID(iditer, rmax);
- // build list of critical distances
- ArrayList<DoubleIntPair> cdist = new ArrayList<>(neighbors.size() << 1);
- {
- for(int i = 0; i < neighbors.size(); i++) {
- DistanceDBIDPair<D> r = neighbors.get(i);
- if(i + 1 < neighbors.size() && r.getDistance().compareTo(neighbors.get(i + 1).getDistance()) == 0) {
- continue;
- }
- cdist.add(new DoubleIntPair(r.getDistance().doubleValue(), i));
- final double ri = r.getDistance().doubleValue() / alpha;
- if(ri <= rmax.doubleValue()) {
- cdist.add(new DoubleIntPair(ri, Integer.MIN_VALUE));
- }
- }
- }
- Collections.sort(cdist);
- // fill the gaps to have fast lookups of number of neighbors at a given
- // distance.
- int lastk = 0;
- for(DoubleIntPair c : cdist) {
- if(c.second == Integer.MIN_VALUE) {
- c.second = lastk;
- }
- else {
- lastk = c.second;
- }
- }
-
- interestingDistances.put(iditer, cdist);
- if(progressPreproc != null) {
- progressPreproc.incrementProcessed(LOG);
- }
- }
- if(progressPreproc != null) {
- progressPreproc.ensureCompleted(LOG);
- }
+ WritableDataStore<DoubleIntArrayList> interestingDistances = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_SORTED, DoubleIntArrayList.class);
+ precomputeInterestingRadii(ids, rangeQuery, interestingDistances);
// LOCI main step
FiniteProgress progressLOCI = LOG.isVerbose() ? new FiniteProgress("LOCI scores", relation.size(), LOG) : null;
WritableDoubleDataStore mdef_norm = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
WritableDoubleDataStore mdef_radius = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
DoubleMinMax minmax = new DoubleMinMax();
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- final List<DoubleIntPair> cdist = interestingDistances.get(iditer);
- final double maxdist = cdist.get(cdist.size() - 1).first;
- final int maxneig = cdist.get(cdist.size() - 1).second;
+ // Shared instance, to save allocations.
+ MeanVariance mv_n_r_alpha = new MeanVariance();
+
+ for(DBIDIter iditer = ids.iter(); iditer.valid(); iditer.advance()) {
+ final DoubleIntArrayList cdist = interestingDistances.get(iditer);
+ final double maxdist = cdist.getDouble(cdist.size() - 1);
+ final int maxneig = cdist.getInt(cdist.size() - 1);
double maxmdefnorm = 0.0;
double maxnormr = 0;
if(maxneig >= nmin) {
- D range = distFunc.getDistanceFactory().fromDouble(maxdist);
// Compute the largest neighborhood we will need.
- DistanceDBIDList<D> maxneighbors = rangeQuery.getRangeForDBID(iditer, range);
- // TODO: Ensure the set is sorted. Should be a no-op with most indexes.
+ DoubleDBIDList maxneighbors = rangeQuery.getRangeForDBID(iditer, maxdist);
+ // TODO: Ensure the result is sorted. This is currently implied.
+
// For any critical distance, compute the normalized MDEF score.
- for(DoubleIntPair c : cdist) {
+ for(int i = 0, size = cdist.size(); i < size; i++) {
// Only start when minimum size is fulfilled
- if (c.second < nmin) {
+ if(cdist.getInt(i) < nmin) {
continue;
}
- final double r = c.first;
+ final double r = cdist.getDouble(i);
final double alpha_r = alpha * r;
- // compute n(p_i, \alpha * r) from list (note: alpha_r is different from c!)
- final int n_alphar = elementsAtRadius(cdist, alpha_r);
+ // compute n(p_i, \alpha * r) from list (note: alpha_r is not cdist!)
+ final int n_alphar = cdist.getInt(cdist.find(alpha_r));
// compute \hat{n}(p_i, r, \alpha) and the corresponding \simga_{MDEF}
- MeanVariance mv_n_r_alpha = new MeanVariance();
- // TODO: optimize for double distances
- for (DistanceDBIDListIter<D> neighbor = maxneighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ mv_n_r_alpha.reset();
+ for(DoubleDBIDListIter neighbor = maxneighbors.iter(); neighbor.valid(); neighbor.advance()) {
// Stop at radius r
- if(neighbor.getDistance().doubleValue() > r) {
+ if(neighbor.doubleValue() > r) {
break;
}
- int rn_alphar = elementsAtRadius(interestingDistances.get(neighbor), alpha_r);
+ DoubleIntArrayList cdist2 = interestingDistances.get(neighbor);
+ int rn_alphar = cdist2.getInt(cdist2.find(alpha_r));
mv_n_r_alpha.put(rn_alphar);
}
// We only use the average and standard deviation
final double nhat_r_alpha = mv_n_r_alpha.getMean();
final double sigma_nhat_r_alpha = mv_n_r_alpha.getNaiveStddev();
- // Redundant divisions removed.
- final double mdef = (nhat_r_alpha - n_alphar); // / nhat_r_alpha;
- final double sigmamdef = sigma_nhat_r_alpha; // / nhat_r_alpha;
+ // Redundant divisions by nhat_r_alpha removed.
+ final double mdef = nhat_r_alpha - n_alphar;
+ final double sigmamdef = sigma_nhat_r_alpha;
final double mdefnorm = mdef / sigmamdef;
if(mdefnorm > maxmdefnorm) {
@@ -246,46 +210,194 @@ public class LOCI<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
}
else {
// FIXME: when nmin was not fulfilled - what is the proper value then?
- maxmdefnorm = 1.0;
+ maxmdefnorm = Double.POSITIVE_INFINITY;
maxnormr = maxdist;
}
mdef_norm.putDouble(iditer, maxmdefnorm);
mdef_radius.putDouble(iditer, maxnormr);
minmax.put(maxmdefnorm);
- if(progressLOCI != null) {
- progressLOCI.incrementProcessed(LOG);
- }
- }
- if(progressLOCI != null) {
- progressLOCI.ensureCompleted(LOG);
+ LOG.incrementProcessed(progressLOCI);
}
- Relation<Double> scoreResult = new MaterializedRelation<>("LOCI normalized MDEF", "loci-mdef-outlier", TypeUtil.DOUBLE, mdef_norm, relation.getDBIDs());
+ LOG.ensureCompleted(progressLOCI);
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("LOCI normalized MDEF", "loci-mdef-outlier", mdef_norm, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 0.0);
OutlierResult result = new OutlierResult(scoreMeta, scoreResult);
- result.addChildResult(new MaterializedRelation<>("LOCI MDEF Radius", "loci-critical-radius", TypeUtil.DOUBLE, mdef_radius, relation.getDBIDs()));
+ result.addChildResult(new MaterializedDoubleRelation("LOCI MDEF Radius", "loci-critical-radius", mdef_radius, relation.getDBIDs()));
return result;
}
/**
- * Get the number of objects for a given radius, from the list of critical
- * distances, storing (radius, count) pairs.
+ * Preprocessing step: determine the radii of interest for each point.
*
- * @param criticalDistances
- * @param radius
- * @return Number of elements at the given radius
+ * @param ids IDs to process
+ * @param rangeQuery Range query
+ * @param interestingDistances Distances of interest
*/
- protected int elementsAtRadius(List<DoubleIntPair> criticalDistances, final double radius) {
- int n_r = 0;
- for(DoubleIntPair c2 : criticalDistances) {
- if(c2.first > radius) {
- break;
+ protected void precomputeInterestingRadii(DBIDs ids, RangeQuery<O> rangeQuery, WritableDataStore<DoubleIntArrayList> interestingDistances) {
+ FiniteProgress progressPreproc = LOG.isVerbose() ? new FiniteProgress("LOCI preprocessing", ids.size(), LOG) : null;
+ for(DBIDIter iditer = ids.iter(); iditer.valid(); iditer.advance()) {
+ DoubleDBIDList neighbors = rangeQuery.getRangeForDBID(iditer, rmax);
+ // build list of critical distances
+ DoubleIntArrayList cdist = new DoubleIntArrayList(neighbors.size() << 1);
+ {
+ int i = 0;
+ DoubleDBIDListIter ni = neighbors.iter();
+ while(ni.valid()) {
+ final double curdist = ni.doubleValue();
+ ++i;
+ ni.advance();
+ // Skip, if tied to the next object:
+ if(ni.valid() && curdist == ni.doubleValue()) {
+ continue;
+ }
+ cdist.append(curdist, i);
+ // Scale radius, and reinsert
+ if(alpha != 1.) {
+ final double ri = curdist / alpha;
+ if(ri <= rmax) {
+ cdist.append(ri, Integer.MIN_VALUE);
+ }
+ }
+ }
}
- if(c2.second != Integer.MIN_VALUE) {
- // Update
- n_r = c2.second;
+ cdist.sort();
+
+ // fill the gaps to have fast lookups of number of neighbors at a given
+ // distance.
+ int lastk = 0;
+ for(int i = 0, size = cdist.size(); i < size; i++) {
+ final int k = cdist.getInt(i);
+ if(k == Integer.MIN_VALUE) {
+ cdist.setValue(i, lastk);
+ }
+ else {
+ lastk = k;
+ }
}
+ // TODO: shrink the list, removing duplicate radii?
+
+ interestingDistances.put(iditer, cdist);
+ LOG.incrementProcessed(progressPreproc);
+ }
+ LOG.ensureCompleted(progressPreproc);
+ }
+
+ /**
+ * Array of double-int values.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ protected static class DoubleIntArrayList {
+ /**
+ * Double keys
+ */
+ double[] keys;
+
+ /**
+ * Integer values
+ */
+ int[] vals;
+
+ /**
+ * Used size
+ */
+ int size = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param alloc Initial allocation.
+ */
+ public DoubleIntArrayList(int alloc) {
+ keys = new double[alloc];
+ vals = new int[alloc];
+ size = 0;
+ }
+
+ /**
+ * Collection size.
+ *
+ * @return Size
+ */
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Get the key at the given position.
+ *
+ * @param i Position
+ * @return Key
+ */
+ public double getDouble(int i) {
+ return keys[i];
+ }
+
+ /**
+ * Get the value at the given position.
+ *
+ * @param i Position
+ * @return Value
+ */
+ public int getInt(int i) {
+ return vals[i];
+ }
+
+ /**
+ * Get the value at the given position.
+ *
+ * @param i Position
+ * @param val New value
+ */
+ public void setValue(int i, int val) {
+ vals[i] = val;
+ }
+
+ /**
+ * Append a key-value pair.
+ *
+ * @param key Key to append
+ * @param val Value to append.
+ */
+ public void append(double key, int val) {
+ if(size == keys.length) {
+ keys = Arrays.copyOf(keys, size << 1);
+ vals = Arrays.copyOf(vals, size << 1);
+ }
+ keys[size] = key;
+ vals[size] = val;
+ ++size;
+ }
+
+ /**
+ * Find the last position with a smaller or equal key.
+ *
+ * @param search Key
+ * @return Position
+ */
+ public int find(final double search) {
+ int a = 0, b = size - 1;
+ while(a <= b) {
+ final int mid = (a + b) >>> 1;
+ final double cur = keys[mid];
+ if(cur > search) {
+ b = mid - 1;
+ }
+ else { // less or equal!
+ a = mid + 1;
+ }
+ }
+ return b;
+ }
+
+ /**
+ * Sort the array list.
+ */
+ public void sort() {
+ DoubleIntegerArrayQuickSort.sort(keys, vals, size);
}
- return n_r;
}
@Override
@@ -304,9 +416,11 @@ public class LOCI<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
* @author Erich Schubert
*
* @apiviz.exclude
+ *
+ * @param <O> Object type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
- protected D rmax = null;
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ protected double rmax;
protected int nmin = 0;
@@ -315,15 +429,14 @@ public class LOCI<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final D distanceFactory = (distanceFunction != null) ? distanceFunction.getDistanceFactory() : null;
- final DistanceParameter<D> rmaxP = new DistanceParameter<>(RMAX_ID, distanceFactory);
+ final DoubleParameter rmaxP = new DoubleParameter(RMAX_ID);
if(config.grab(rmaxP)) {
- rmax = rmaxP.getValue();
+ rmax = rmaxP.doubleValue();
}
final IntParameter nminP = new IntParameter(NMIN_ID, 20);
if(config.grab(nminP)) {
- nmin = nminP.getValue();
+ nmin = nminP.intValue();
}
final DoubleParameter alphaP = new DoubleParameter(ALPHA_ID, 0.5);
@@ -333,7 +446,7 @@ public class LOCI<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBas
}
@Override
- protected LOCI<O, D> makeInstance() {
+ protected LOCI<O> makeInstance() {
return new LOCI<>(distanceFunction, rmax, nmin, alpha);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LOF.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LOF.java
index 28166c75..ff5529f5 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LOF.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LOF.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
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
@@ -35,19 +35,13 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-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.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
-import de.lmu.ifi.dbs.elki.database.query.knn.PreprocessorKNNQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.NumberDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNPreprocessor;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
@@ -56,6 +50,7 @@ import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.QuotientOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
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;
@@ -75,10 +70,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* within ELKI we have renamed this parameter to &quot;k&quot;.
* </p>
*
+ * Reference:
* <p>
- * Reference: <br>
- * M. M. Breunig, H.-P. Kriegel, R. Ng, J. Sander: LOF: Identifying
- * Density-Based Local Outliers. <br>
+ * M. M. Breunig, H.-P. Kriegel, R. Ng, J. Sander:<br />
+ * LOF: Identifying Density-Based Local Outliers.<br />
* In: Proc. 2nd ACM SIGMOD Int. Conf. on Management of Data (SIGMOD'00),
* Dallas, TX, 2000.
* </p>
@@ -88,37 +83,40 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*
* @apiviz.has KNNQuery
*
- * @param <O> the type of DatabaseObjects handled by this Algorithm
- * @param <D> Distance type
+ * @param <O> the type of data objects handled by this algorithm
*/
@Title("LOF: Local Outlier Factor")
@Description("Algorithm to compute density-based local outlier factors in a database based on the neighborhood size parameter 'k'")
-@Reference(authors = "M. M. Breunig, H.-P. Kriegel, R. Ng, and J. Sander", title = "LOF: Identifying Density-Based Local Outliers", booktitle = "Proc. 2nd ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '00), Dallas, TX, 2000", url = "http://dx.doi.org/10.1145/342009.335388")
-@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.LOF", "outlier.LOF", "LOF" })
-public class LOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "M. M. Breunig, H.-P. Kriegel, R. Ng, and J. Sander",//
+title = "LOF: Identifying Density-Based Local Outliers", //
+booktitle = "Proc. 2nd ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '00), Dallas, TX, 2000", //
+url = "http://dx.doi.org/10.1145/342009.335388")
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.LOF", "LOF" })
+public class LOF<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(LOF.class);
/**
- * Holds the value of {@link Parameterizer#K_ID}.
+ * The number of neighbors to query (including the query point!)
*/
protected int k = 2;
/**
* Constructor.
*
- * @param k the value of k
+ * @param k the number of neighbors to use for comparison (excluding the query
+ * point)
* @param distanceFunction the neighborhood distance function
*/
- public LOF(int k, DistanceFunction<? super O, D> distanceFunction) {
+ public LOF(int k, DistanceFunction<? super O> distanceFunction) {
super(distanceFunction);
this.k = k + 1;
}
/**
- * Performs the Generalized LOF_SCORE algorithm on the given database.
+ * Runs the LOF algorithm on the given database.
*
* @param database Database to query
* @param relation Data to process
@@ -126,42 +124,27 @@ public class LOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBase
*/
public OutlierResult run(Database database, Relation<O> relation) {
StepProgress stepprog = LOG.isVerbose() ? new StepProgress("LOF", 3) : null;
- DistanceQuery<O, D> dq = database.getDistanceQuery(relation, getDistanceFunction());
- // "HEAVY" flag for knn query since it is used more than once
- KNNQuery<O, D> knnq = database.getKNNQuery(dq, k, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
- // No optimized kNN query - use a preprocessor!
- if(!(knnq instanceof PreprocessorKNNQuery)) {
- if(stepprog != null) {
- stepprog.beginStep(1, "Materializing LOF neighborhoods.", LOG);
- }
- MaterializeKNNPreprocessor<O, D> preproc = new MaterializeKNNPreprocessor<>(relation, getDistanceFunction(), k);
- knnq = preproc.getKNNQuery(dq, k);
- }
DBIDs ids = relation.getDBIDs();
+ LOG.beginStep(stepprog, 1, "Materializing LOF neighborhoods.");
+ KNNQuery<O> knnq = DatabaseUtil.precomputedKNNQuery(database, relation, getDistanceFunction(), k);
+
// Compute LRDs
- if(stepprog != null) {
- stepprog.beginStep(2, "Computing LRDs.", LOG);
- }
+ LOG.beginStep(stepprog, 2, "Computing LRDs.");
WritableDoubleDataStore lrds = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
computeLRDs(knnq, ids, lrds);
// compute LOF_SCORE of each db object
- if(stepprog != null) {
- stepprog.beginStep(3, "Computing LOFs.", LOG);
- }
- DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC);
+ LOG.beginStep(stepprog, 3, "Computing LOFs.");
WritableDoubleDataStore lofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_DB);
// track the maximum value for normalization.
DoubleMinMax lofminmax = new DoubleMinMax();
computeLOFScores(knnq, ids, lrds, lofs, lofminmax);
- if(stepprog != null) {
- stepprog.setCompleted(LOG);
- }
+ LOG.setCompleted(stepprog);
// Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("Local Outlier Factor", "lof-outlier", TypeUtil.DOUBLE, lofs, ids);
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Local Outlier Factor", "lof-outlier", lofs, ids);
OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(lofminmax.getMin(), lofminmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 1.0);
return new OutlierResult(scoreMeta, scoreResult);
}
@@ -173,50 +156,26 @@ public class LOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBase
* @param ids IDs to process
* @param lrds Reachability storage
*/
- private void computeLRDs(KNNQuery<O, D> knnq, DBIDs ids, WritableDoubleDataStore lrds) {
+ private void computeLRDs(KNNQuery<O> knnq, DBIDs ids, WritableDoubleDataStore lrds) {
FiniteProgress lrdsProgress = LOG.isVerbose() ? new FiniteProgress("LRD", ids.size(), LOG) : null;
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- final KNNList<D> neighbors = knnq.getKNNForDBID(iter, k);
+ final KNNList neighbors = knnq.getKNNForDBID(iter, k);
double sum = 0.0;
int count = 0;
- if(neighbors instanceof DoubleDistanceKNNList) {
- // Fast version for double distances
- for(DoubleDistanceDBIDListIter neighbor = ((DoubleDistanceKNNList) neighbors).iter(); neighbor.valid(); neighbor.advance()) {
- if(DBIDUtil.equal(neighbor, iter)) {
- continue;
- }
- KNNList<D> neighborsNeighbors = knnq.getKNNForDBID(neighbor, k);
- final double nkdist;
- if(neighborsNeighbors instanceof DoubleDistanceKNNList) {
- nkdist = ((DoubleDistanceKNNList) neighborsNeighbors).doubleKNNDistance();
- }
- else {
- nkdist = neighborsNeighbors.getKNNDistance().doubleValue();
- }
- sum += Math.max(neighbor.doubleDistance(), nkdist);
- count++;
- }
- }
- else {
- for(DistanceDBIDListIter<D> neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
- if(DBIDUtil.equal(neighbor, iter)) {
- continue;
- }
- KNNList<D> neighborsNeighbors = knnq.getKNNForDBID(neighbor, k);
- sum += Math.max(neighbor.getDistance().doubleValue(), neighborsNeighbors.getKNNDistance().doubleValue());
- count++;
+ for(DoubleDBIDListIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ if(DBIDUtil.equal(neighbor, iter)) {
+ continue;
}
+ KNNList neighborsNeighbors = knnq.getKNNForDBID(neighbor, k);
+ sum += Math.max(neighbor.doubleValue(), neighborsNeighbors.getKNNDistance());
+ count++;
}
// Avoid division by 0
final double lrd = (sum > 0) ? (count / sum) : Double.POSITIVE_INFINITY;
lrds.putDouble(iter, lrd);
- if(lrdsProgress != null) {
- lrdsProgress.incrementProcessed(LOG);
- }
- }
- if(lrdsProgress != null) {
- lrdsProgress.ensureCompleted(LOG);
+ LOG.incrementProcessed(lrdsProgress);
}
+ LOG.ensureCompleted(lrdsProgress);
}
/**
@@ -228,14 +187,14 @@ public class LOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBase
* @param lofs Local outlier factor storage
* @param lofminmax Score minimum/maximum tracker
*/
- private void computeLOFScores(KNNQuery<O, D> knnq, DBIDs ids, DoubleDataStore lrds, WritableDoubleDataStore lofs, DoubleMinMax lofminmax) {
+ private void computeLOFScores(KNNQuery<O> knnq, DBIDs ids, DoubleDataStore lrds, WritableDoubleDataStore lofs, DoubleMinMax lofminmax) {
FiniteProgress progressLOFs = LOG.isVerbose() ? new FiniteProgress("LOF_SCORE for objects", ids.size(), LOG) : null;
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
final double lof;
final double lrdp = lrds.doubleValue(iter);
- final KNNList<D> neighbors = knnq.getKNNForDBID(iter, k);
+ final KNNList neighbors = knnq.getKNNForDBID(iter, k);
if(!Double.isInfinite(lrdp)) {
- double sum = 0.0;
+ double sum = 0.;
int count = 0;
for(DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
// skip the point itself
@@ -258,13 +217,9 @@ public class LOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBase
// update minimum and maximum
lofminmax.put(lof);
- if(progressLOFs != null) {
- progressLOFs.incrementProcessed(LOG);
- }
- }
- if(progressLOFs != null) {
- progressLOFs.ensureCompleted(LOG);
+ LOG.incrementProcessed(progressLOFs);
}
+ LOG.ensureCompleted(progressLOFs);
}
@Override
@@ -283,14 +238,16 @@ public class LOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBase
* @author Erich Schubert
*
* @apiviz.exclude
+ *
+ * @param <O> Object type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Parameter to specify the number of nearest neighbors of an object to be
- * considered for computing its LOF_SCORE, must be an integer greater than
- * 1.
+ * considered for computing its LOF score, must be an integer greater than
+ * or equal to 1.
*/
- public static final OptionID K_ID = new OptionID("lof.k", "The number of nearest neighbors of an object to be considered for computing its LOF_SCORE.");
+ public static final OptionID K_ID = new OptionID("lof.k", "The number of nearest neighbors of an object to be considered for computing its LOF score.");
/**
* The neighborhood size to use.
@@ -302,14 +259,14 @@ public class LOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBase
super.makeOptions(config);
final IntParameter pK = new IntParameter(K_ID);
- pK.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
+ pK.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
if(config.grab(pK)) {
- k = pK.getValue();
+ k = pK.intValue();
}
}
@Override
- protected LOF<O, D> makeInstance() {
+ protected LOF<O> makeInstance() {
return new LOF<>(k, distanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LoOP.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LoOP.java
index 525d45f2..6278880f 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LoOP.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/LoOP.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
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
@@ -35,29 +35,26 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-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.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNPreprocessor;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
+import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.Mean;
-import de.lmu.ifi.dbs.elki.math.MeanVariance;
import de.lmu.ifi.dbs.elki.math.statistics.distribution.NormalDistribution;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.ProbabilisticOutlierScore;
import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
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;
@@ -77,82 +74,65 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
* Distance/density based algorithm similar to LOF to detect outliers, but with
* statistical methods to achieve better result stability.
*
+ * Reference:
+ * <p>
+ * Hans-Peter Kriegel, Peer Kröger, Erich Schubert, Arthur Zimek:<br />
+ * LoOP: Local Outlier Probabilities< br />
+ * In Proceedings of the 18th International Conference on Information and
+ * Knowledge Management (CIKM), Hong Kong, China, 2009
+ * </p>
+ *
+ * Implementation notes:
+ * <ul>
+ * <li>The lambda parameter was removed from the pdist term, because it cancels
+ * out.</li>
+ * <li>In ELKI 0.7.0, the {@code k} parameters have changed by 1 to make them
+ * similar to other methods and more intuitive.</li>
+ * </ul>
+ *
* @author Erich Schubert
*
* @apiviz.has KNNQuery
*
* @param <O> type of objects handled by this algorithm
- * @param <D> type of distances used
*/
@Title("LoOP: Local Outlier Probabilities")
@Description("Variant of the LOF algorithm normalized using statistical values.")
-@Reference(authors = "H.-P. Kriegel, P. Kröger, E. Schubert, A. Zimek", title = "LoOP: Local Outlier Probabilities", booktitle = "Proceedings of the 18th International Conference on Information and Knowledge Management (CIKM), Hong Kong, China, 2009", url = "http://dx.doi.org/10.1145/1645953.1646195")
-@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.LoOP", "LoOP", "outlier.LoOP" })
-public class LoOP<O, D extends NumberDistance<D, ?>> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "H.-P. Kriegel, P. Kröger, E. Schubert, A. Zimek", //
+title = "LoOP: Local Outlier Probabilities", //
+booktitle = "Proceedings of the 18th International Conference on Information and Knowledge Management (CIKM), Hong Kong, China, 2009", //
+url = "http://dx.doi.org/10.1145/1645953.1646195")
+@Alias({ "de.lmu.ifi.dbs.elki.algorithm.outlier.LoOP", "LoOP" })
+public class LoOP<O> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(LoOP.class);
/**
- * The distance function to determine the reachability distance between
- * database objects.
- */
- public static final OptionID REACHABILITY_DISTANCE_FUNCTION_ID = new OptionID("loop.referencedistfunction", "Distance function to determine the density of an object.");
-
- /**
- * The distance function to determine the reachability distance between
- * database objects.
- */
- public static final OptionID COMPARISON_DISTANCE_FUNCTION_ID = new OptionID("loop.comparedistfunction", "Distance function to determine the reference set of an object.");
-
- /**
- * Parameter to specify the number of nearest neighbors of an object to be
- * considered for computing its LOOP_SCORE, must be an integer greater than 1.
- */
- public static final OptionID KREACH_ID = new OptionID("loop.kref", "The number of nearest neighbors of an object to be used for the PRD value.");
-
- /**
- * Parameter to specify the number of nearest neighbors of an object to be
- * considered for computing its LOOP_SCORE, must be an integer greater than 1.
- */
- public static final OptionID KCOMP_ID = new OptionID("loop.kcomp", "The number of nearest neighbors of an object to be considered for computing its LOOP_SCORE.");
-
- /**
- * Parameter to specify the number of nearest neighbors of an object to be
- * considered for computing its LOOP_SCORE, must be an integer greater than 1.
- */
- public static final OptionID LAMBDA_ID = new OptionID("loop.lambda", "The number of standard deviations to consider for density computation.");
-
- /**
- * Holds the value of {@link #KREACH_ID}.
+ * Reachability neighborhood size.
*/
int kreach;
/**
- * Holds the value of {@link #KCOMP_ID}.
+ * Comparison neighborhood size.
*/
int kcomp;
/**
- * Hold the value of {@link #LAMBDA_ID}.
+ * Lambda parameter.
*/
double lambda;
/**
- * Preprocessor Step 1.
+ * Distance function for reachability.
*/
- protected DistanceFunction<? super O, D> reachabilityDistanceFunction;
+ protected DistanceFunction<? super O> reachabilityDistanceFunction;
/**
- * Preprocessor Step 2.
+ * Distance function for comparison set.
*/
- protected DistanceFunction<? super O, D> comparisonDistanceFunction;
-
- /**
- * Include object itself in kNN neighborhood.
- */
- static boolean objectIsInKNN = false;
+ protected DistanceFunction<? super O> comparisonDistanceFunction;
/**
* Constructor with parameters.
@@ -163,7 +143,7 @@ public class LoOP<O, D extends NumberDistance<D, ?>> extends AbstractAlgorithm<O
* @param comparisonDistanceFunction distance function for comparison
* @param lambda Lambda parameter
*/
- public LoOP(int kreach, int kcomp, DistanceFunction<? super O, D> reachabilityDistanceFunction, DistanceFunction<? super O, D> comparisonDistanceFunction, double lambda) {
+ public LoOP(int kreach, int kcomp, DistanceFunction<? super O> reachabilityDistanceFunction, DistanceFunction<? super O> comparisonDistanceFunction, double lambda) {
super();
this.kreach = kreach;
this.kcomp = kcomp;
@@ -180,35 +160,17 @@ public class LoOP<O, D extends NumberDistance<D, ?>> extends AbstractAlgorithm<O
* @param stepprog Progress logger, may be {@code null}
* @return result
*/
- protected Pair<KNNQuery<O, D>, KNNQuery<O, D>> getKNNQueries(Database database, Relation<O> relation, StepProgress stepprog) {
- KNNQuery<O, D> knnComp;
- KNNQuery<O, D> knnReach;
+ protected Pair<KNNQuery<O>, KNNQuery<O>> getKNNQueries(Database database, Relation<O> relation, StepProgress stepprog) {
+ KNNQuery<O> knnComp, knnReach;
if(comparisonDistanceFunction == reachabilityDistanceFunction || comparisonDistanceFunction.equals(reachabilityDistanceFunction)) {
- // We need each neighborhood twice - use "HEAVY" flag.
- knnComp = QueryUtil.getKNNQuery(relation, comparisonDistanceFunction, Math.max(kreach, kcomp), DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
- // No optimized kNN query - use a preprocessor!
- if(knnComp == null) {
- if(stepprog != null) {
- stepprog.beginStep(1, "Materializing neighborhoods with respect to reference neighborhood distance function.", LOG);
- }
- MaterializeKNNPreprocessor<O, D> preproc = new MaterializeKNNPreprocessor<>(relation, comparisonDistanceFunction, kcomp);
- database.addIndex(preproc);
- DistanceQuery<O, D> cdq = database.getDistanceQuery(relation, comparisonDistanceFunction);
- knnComp = preproc.getKNNQuery(cdq, kreach, DatabaseQuery.HINT_HEAVY_USE);
- }
- else {
- if(stepprog != null) {
- stepprog.beginStep(1, "Optimized neighborhoods provided by database.", LOG);
- }
- }
+ LOG.beginStep(stepprog, 1, "Materializing neighborhoods with respect to reference neighborhood distance function.");
+ knnComp = DatabaseUtil.precomputedKNNQuery(database, relation, comparisonDistanceFunction, kcomp + 1);
knnReach = knnComp;
}
else {
- if(stepprog != null) {
- stepprog.beginStep(1, "Not materializing distance functions, since we request each DBID once only.", LOG);
- }
- knnComp = QueryUtil.getKNNQuery(relation, comparisonDistanceFunction, kreach);
- knnReach = QueryUtil.getKNNQuery(relation, reachabilityDistanceFunction, kcomp);
+ LOG.beginStep(stepprog, 1, "Not materializing distance functions, since we request each DBID once only.");
+ knnComp = QueryUtil.getKNNQuery(relation, comparisonDistanceFunction, kreach + 1);
+ knnReach = QueryUtil.getKNNQuery(relation, reachabilityDistanceFunction, kcomp + 1);
}
return new Pair<>(knnComp, knnReach);
}
@@ -221,13 +183,11 @@ public class LoOP<O, D extends NumberDistance<D, ?>> extends AbstractAlgorithm<O
* @return Outlier result
*/
public OutlierResult run(Database database, Relation<O> relation) {
- final double sqrt2 = Math.sqrt(2.0);
-
StepProgress stepprog = LOG.isVerbose() ? new StepProgress(5) : null;
- Pair<KNNQuery<O, D>, KNNQuery<O, D>> pair = getKNNQueries(database, relation, stepprog);
- KNNQuery<O, D> knnComp = pair.getFirst();
- KNNQuery<O, D> knnReach = pair.getSecond();
+ Pair<KNNQuery<O>, KNNQuery<O>> pair = getKNNQueries(database, relation, stepprog);
+ KNNQuery<O> knnComp = pair.getFirst();
+ KNNQuery<O> knnReach = pair.getSecond();
// Assert we got something
if(knnComp == null) {
@@ -237,118 +197,111 @@ public class LoOP<O, D extends NumberDistance<D, ?>> extends AbstractAlgorithm<O
throw new AbortException("No kNN queries supported by database for density estimation distance function.");
}
+ // FIXME: tie handling!
+
// Probabilistic distances
- WritableDoubleDataStore pdists = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
- Mean mean = new Mean();
- {// computing PRDs
- if(stepprog != null) {
- stepprog.beginStep(3, "Computing pdists", LOG);
- }
- FiniteProgress prdsProgress = LOG.isVerbose() ? new FiniteProgress("pdists", relation.size(), LOG) : null;
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- final KNNList<D> neighbors = knnReach.getKNNForDBID(iditer, kreach);
- mean.reset();
- // use first kref neighbors as reference set
- int ks = 0;
- // TODO: optimize for double distances
- if(neighbors instanceof DoubleDistanceKNNList) {
- for(DoubleDistanceDBIDListIter neighbor = ((DoubleDistanceKNNList) neighbors).iter(); neighbor.valid(); neighbor.advance()) {
- if(objectIsInKNN || !DBIDUtil.equal(neighbor, iditer)) {
- final double d = neighbor.doubleDistance();
- mean.put(d * d);
- ks++;
- if(ks >= kreach) {
- break;
- }
- }
- }
- }
- else {
- for(DistanceDBIDListIter<D> neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
- if(objectIsInKNN || !DBIDUtil.equal(neighbor, iditer)) {
- double d = neighbor.getDistance().doubleValue();
- mean.put(d * d);
- ks++;
- if(ks >= kreach) {
- break;
- }
- }
- }
- }
- double pdist = lambda * Math.sqrt(mean.getMean());
- pdists.putDouble(iditer, pdist);
- if(prdsProgress != null) {
- prdsProgress.incrementProcessed(LOG);
- }
- }
- }
+ WritableDoubleDataStore pdists = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_DB);
+ LOG.beginStep(stepprog, 3, "Computing pdists");
+ computePDists(relation, knnReach, pdists);
// Compute PLOF values.
WritableDoubleDataStore plofs = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
- MeanVariance mvplof = new MeanVariance();
+ LOG.beginStep(stepprog, 4, "Computing PLOF");
+ double nplof = computePLOFs(relation, knnComp, pdists, plofs);
+
+ // Normalize the outlier scores.
+ DoubleMinMax mm = new DoubleMinMax();
{// compute LOOP_SCORE of each db object
- if(stepprog != null) {
- stepprog.beginStep(4, "Computing PLOF", LOG);
- }
+ LOG.beginStep(stepprog, 5, "Computing LoOP scores");
- FiniteProgress progressPLOFs = LOG.isVerbose() ? new FiniteProgress("PLOFs for objects", relation.size(), LOG) : null;
- MeanVariance mv = new MeanVariance();
+ FiniteProgress progressLOOPs = LOG.isVerbose() ? new FiniteProgress("LoOP for objects", relation.size(), LOG) : null;
+ final double norm = 1. / (nplof * MathUtil.SQRT2);
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- final KNNList<D> neighbors = knnComp.getKNNForDBID(iditer, kcomp);
- mv.reset();
- // use first kref neighbors as comparison set.
- int ks = 0;
- for(DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
- if(objectIsInKNN || !DBIDUtil.equal(neighbor, iditer)) {
- mv.put(pdists.doubleValue(neighbor));
- ks++;
- if(ks >= kcomp) {
- break;
- }
- }
- }
- double plof = Math.max(pdists.doubleValue(iditer) / mv.getMean(), 1.0);
- if(Double.isNaN(plof) || Double.isInfinite(plof)) {
- plof = 1.0;
- }
- plofs.putDouble(iditer, plof);
- mvplof.put((plof - 1.0) * (plof - 1.0));
-
- if(progressPLOFs != null) {
- progressPLOFs.incrementProcessed(LOG);
- }
+ double loop = NormalDistribution.erf((plofs.doubleValue(iditer) - 1.) * norm);
+ plofs.putDouble(iditer, loop);
+ mm.put(loop);
+ LOG.incrementProcessed(progressLOOPs);
}
+ LOG.ensureCompleted(progressLOOPs);
}
- double nplof = lambda * Math.sqrt(mvplof.getMean());
- if(LOG.isDebugging()) {
- LOG.verbose("nplof normalization factor is " + nplof + " " + mvplof.getMean() + " " + mvplof.getSampleStddev());
- }
-
- // Compute final LoOP values.
- WritableDoubleDataStore loops = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
- {// compute LOOP_SCORE of each db object
- if(stepprog != null) {
- stepprog.beginStep(5, "Computing LoOP scores", LOG);
- }
+ LOG.setCompleted(stepprog);
- FiniteProgress progressLOOPs = LOG.isVerbose() ? new FiniteProgress("LoOP for objects", relation.size(), LOG) : null;
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- loops.putDouble(iditer, NormalDistribution.erf((plofs.doubleValue(iditer) - 1) / (nplof * sqrt2)));
+ // Build result representation.
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Local Outlier Probabilities", "loop-outlier", plofs, relation.getDBIDs());
+ OutlierScoreMeta scoreMeta = new ProbabilisticOutlierScore(mm.getMin(), mm.getMax(), 0.);
+ return new OutlierResult(scoreMeta, scoreResult);
+ }
- if(progressLOOPs != null) {
- progressLOOPs.incrementProcessed(LOG);
+ /**
+ * Compute the probabilistic distances used by LoOP.
+ *
+ * @param relation Data relation
+ * @param knn kNN query
+ * @param pdists Storage for distances
+ */
+ protected void computePDists(Relation<O> relation, KNNQuery<O> knn, WritableDoubleDataStore pdists) {
+ // computing PRDs
+ FiniteProgress prdsProgress = LOG.isVerbose() ? new FiniteProgress("pdists", relation.size(), LOG) : null;
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ final KNNList neighbors = knn.getKNNForDBID(iditer, kreach + 1);
+ // use first kref neighbors as reference set
+ int ks = 0;
+ double ssum = 0.;
+ for(DoubleDBIDListIter neighbor = neighbors.iter(); neighbor.valid() && ks < kreach; neighbor.advance()) {
+ if(DBIDUtil.equal(neighbor, iditer)) {
+ continue;
}
+ final double d = neighbor.doubleValue();
+ ssum += d * d;
+ ks++;
}
+ double pdist = ks > 0 ? Math.sqrt(ssum / ks) : 0.;
+ pdists.putDouble(iditer, pdist);
+ LOG.incrementProcessed(prdsProgress);
}
+ LOG.ensureCompleted(prdsProgress);
+ }
+
+ /**
+ * Compute the LOF values, using the pdist distances.
+ *
+ * @param relation Data relation
+ * @param knn kNN query
+ * @param pdists Precomputed distances
+ * @param plofs Storage for PLOFs.
+ * @return Normalization factor.
+ */
+ protected double computePLOFs(Relation<O> relation, KNNQuery<O> knn, WritableDoubleDataStore pdists, WritableDoubleDataStore plofs) {
+ FiniteProgress progressPLOFs = LOG.isVerbose() ? new FiniteProgress("PLOFs for objects", relation.size(), LOG) : null;
+ Mean mvplof = new Mean();
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ final KNNList neighbors = knn.getKNNForDBID(iditer, kcomp + 1);
+ // use first kref neighbors as comparison set.
+ int ks = 0;
+ double sum = 0.;
+ for(DBIDIter neighbor = neighbors.iter(); neighbor.valid() && ks < kcomp; neighbor.advance()) {
+ if(DBIDUtil.equal(neighbor, iditer)) {
+ continue;
+ }
+ sum += pdists.doubleValue(neighbor);
+ ks++;
+ }
+ double plof = Math.max(pdists.doubleValue(iditer) * ks / sum, 1.0);
+ if(Double.isNaN(plof) || Double.isInfinite(plof)) {
+ plof = 1.0;
+ }
+ plofs.putDouble(iditer, plof);
+ mvplof.put((plof - 1.0) * (plof - 1.0));
- if(stepprog != null) {
- stepprog.setCompleted(LOG);
+ LOG.incrementProcessed(progressPLOFs);
}
+ LOG.ensureCompleted(progressPLOFs);
- // Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("Local Outlier Probabilities", "loop-outlier", TypeUtil.DOUBLE, loops, relation.getDBIDs());
- OutlierScoreMeta scoreMeta = new ProbabilisticOutlierScore();
- return new OutlierResult(scoreMeta, scoreResult);
+ double nplof = lambda * Math.sqrt(mvplof.getMean());
+ if(LOG.isDebugging()) {
+ LOG.verbose("nplof normalization factor is " + nplof + " " + mvplof.getMean());
+ }
+ return nplof;
}
@Override
@@ -374,8 +327,43 @@ public class LoOP<O, D extends NumberDistance<D, ?>> extends AbstractAlgorithm<O
* @author Erich Schubert
*
* @apiviz.exclude
+ *
+ * @param <O> Object type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractParameterizer {
+ public static class Parameterizer<O> extends AbstractParameterizer {
+ /**
+ * The distance function to determine the reachability distance between
+ * database objects.
+ */
+ public static final OptionID REACHABILITY_DISTANCE_FUNCTION_ID = new OptionID("loop.referencedistfunction", "Distance function to determine the density of an object.");
+
+ /**
+ * The distance function to determine the reachability distance between
+ * database objects.
+ */
+ public static final OptionID COMPARISON_DISTANCE_FUNCTION_ID = new OptionID("loop.comparedistfunction", "Distance function to determine the reference set of an object.");
+
+ /**
+ * Parameter to specify the number of nearest neighbors of an object to be
+ * considered for computing its LOOP_SCORE, must be an integer greater than
+ * 1.
+ */
+ public static final OptionID KREACH_ID = new OptionID("loop.kref", "The number of nearest neighbors of an object to be used for the PRD value.");
+
+ /**
+ * Parameter to specify the number of nearest neighbors of an object to be
+ * considered for computing its LOOP_SCORE, must be an integer greater than
+ * 1.
+ */
+ public static final OptionID KCOMP_ID = new OptionID("loop.kcomp", "The number of nearest neighbors of an object to be considered for computing its LOOP_SCORE.");
+
+ /**
+ * Parameter to specify the number of nearest neighbors of an object to be
+ * considered for computing its LOOP_SCORE, must be an integer greater than
+ * 1.
+ */
+ public static final OptionID LAMBDA_ID = new OptionID("loop.lambda", "The number of standard deviations to consider for density computation.");
+
/**
* Holds the value of {@link #KREACH_ID}.
*/
@@ -394,29 +382,29 @@ public class LoOP<O, D extends NumberDistance<D, ?>> extends AbstractAlgorithm<O
/**
* Preprocessor Step 1.
*/
- protected DistanceFunction<O, D> reachabilityDistanceFunction = null;
+ protected DistanceFunction<O> reachabilityDistanceFunction = null;
/**
* Preprocessor Step 2.
*/
- protected DistanceFunction<O, D> comparisonDistanceFunction = null;
+ protected DistanceFunction<O> comparisonDistanceFunction = null;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
final IntParameter kcompP = new IntParameter(KCOMP_ID);
- kcompP.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
+ kcompP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
if(config.grab(kcompP)) {
kcomp = kcompP.intValue();
}
- final ObjectParameter<DistanceFunction<O, D>> compDistP = new ObjectParameter<>(COMPARISON_DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
+ final ObjectParameter<DistanceFunction<O>> compDistP = new ObjectParameter<>(COMPARISON_DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
if(config.grab(compDistP)) {
comparisonDistanceFunction = compDistP.instantiateClass(config);
}
final IntParameter kreachP = new IntParameter(KREACH_ID);
- kreachP.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
+ kreachP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
kreachP.setOptional(true);
if(config.grab(kreachP)) {
kreach = kreachP.intValue();
@@ -425,7 +413,7 @@ public class LoOP<O, D extends NumberDistance<D, ?>> extends AbstractAlgorithm<O
kreach = kcomp;
}
- final ObjectParameter<DistanceFunction<O, D>> reachDistP = new ObjectParameter<>(REACHABILITY_DISTANCE_FUNCTION_ID, DistanceFunction.class, true);
+ final ObjectParameter<DistanceFunction<O>> reachDistP = new ObjectParameter<>(REACHABILITY_DISTANCE_FUNCTION_ID, DistanceFunction.class, true);
if(config.grab(reachDistP)) {
reachabilityDistanceFunction = reachDistP.instantiateClass(config);
}
@@ -439,8 +427,8 @@ public class LoOP<O, D extends NumberDistance<D, ?>> extends AbstractAlgorithm<O
}
@Override
- protected LoOP<O, D> makeInstance() {
- DistanceFunction<O, D> realreach = (reachabilityDistanceFunction != null) ? reachabilityDistanceFunction : comparisonDistanceFunction;
+ protected LoOP<O> makeInstance() {
+ DistanceFunction<O> realreach = (reachabilityDistanceFunction != null) ? reachabilityDistanceFunction : comparisonDistanceFunction;
return new LoOP<>(kreach, kcomp, realreach, comparisonDistanceFunction, lambda);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/OnlineLOF.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/OnlineLOF.java
index c01c914f..6033ae3e 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/OnlineLOF.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/OnlineLOF.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
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,16 @@ import java.util.List;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.QueryUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.DoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-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.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
@@ -43,7 +44,6 @@ import de.lmu.ifi.dbs.elki.database.query.knn.PreprocessorKNNQuery;
import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery;
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.NumberDistance;
import de.lmu.ifi.dbs.elki.index.preprocessed.knn.AbstractMaterializeKNNPreprocessor;
import de.lmu.ifi.dbs.elki.index.preprocessed.knn.KNNChangeEvent;
import de.lmu.ifi.dbs.elki.index.preprocessed.knn.KNNListener;
@@ -66,7 +66,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
* @apiviz.has FlexibleLOF.LOFResult oneway - - updates
*/
// TODO: related to publication?
-public class OnlineLOF<O, D extends NumberDistance<D, ?>> extends FlexibleLOF<O, D> {
+public class OnlineLOF<O> extends FlexibleLOF<O> {
/**
* The logger for this class.
*/
@@ -80,7 +80,7 @@ public class OnlineLOF<O, D extends NumberDistance<D, ?>> extends FlexibleLOF<O,
* @param neighborhoodDistanceFunction the neighborhood distance function
* @param reachabilityDistanceFunction the reachability distance function
*/
- public OnlineLOF(int krefer, int kreach, DistanceFunction<? super O, D> neighborhoodDistanceFunction, DistanceFunction<? super O, D> reachabilityDistanceFunction) {
+ public OnlineLOF(int krefer, int kreach, DistanceFunction<? super O> neighborhoodDistanceFunction, DistanceFunction<? super O> reachabilityDistanceFunction) {
super(krefer, kreach, neighborhoodDistanceFunction, reachabilityDistanceFunction);
}
@@ -93,20 +93,20 @@ public class OnlineLOF<O, D extends NumberDistance<D, ?>> extends FlexibleLOF<O,
public OutlierResult run(Database database, Relation<O> relation) {
StepProgress stepprog = LOG.isVerbose() ? new StepProgress("OnlineLOF", 3) : null;
- Pair<Pair<KNNQuery<O, D>, KNNQuery<O, D>>, Pair<RKNNQuery<O, D>, RKNNQuery<O, D>>> queries = getKNNAndRkNNQueries(database, relation, stepprog);
- KNNQuery<O, D> kNNRefer = queries.getFirst().getFirst();
- KNNQuery<O, D> kNNReach = queries.getFirst().getSecond();
- RKNNQuery<O, D> rkNNRefer = queries.getSecond().getFirst();
- RKNNQuery<O, D> rkNNReach = queries.getSecond().getSecond();
+ Pair<Pair<KNNQuery<O>, KNNQuery<O>>, Pair<RKNNQuery<O>, RKNNQuery<O>>> queries = getKNNAndRkNNQueries(database, relation, stepprog);
+ KNNQuery<O> kNNRefer = queries.getFirst().getFirst();
+ KNNQuery<O> kNNReach = queries.getFirst().getSecond();
+ RKNNQuery<O> rkNNRefer = queries.getSecond().getFirst();
+ RKNNQuery<O> rkNNReach = queries.getSecond().getSecond();
- LOFResult<O, D> lofResult = super.doRunInTime(relation.getDBIDs(), kNNRefer, kNNReach, stepprog);
+ LOFResult<O> lofResult = super.doRunInTime(relation.getDBIDs(), kNNRefer, kNNReach, stepprog);
lofResult.setRkNNRefer(rkNNRefer);
lofResult.setRkNNReach(rkNNReach);
// add listener
KNNListener l = new LOFKNNListener(lofResult);
- ((MaterializeKNNPreprocessor<O, D>) ((PreprocessorKNNQuery<O, D, ? extends KNNList<D>>) lofResult.getKNNRefer()).getPreprocessor()).addKNNListener(l);
- ((MaterializeKNNPreprocessor<O, D>) ((PreprocessorKNNQuery<O, D, ? extends KNNList<D>>) lofResult.getKNNReach()).getPreprocessor()).addKNNListener(l);
+ ((MaterializeKNNPreprocessor<O>) ((PreprocessorKNNQuery<O>) lofResult.getKNNRefer()).getPreprocessor()).addKNNListener(l);
+ ((MaterializeKNNPreprocessor<O>) ((PreprocessorKNNQuery<O>) lofResult.getKNNReach()).getPreprocessor()).addKNNListener(l);
return lofResult.getResult();
}
@@ -118,47 +118,48 @@ public class OnlineLOF<O, D extends NumberDistance<D, ?>> extends FlexibleLOF<O,
* @param stepprog Progress logger
* @return the kNN and rkNN queries
*/
- private Pair<Pair<KNNQuery<O, D>, KNNQuery<O, D>>, Pair<RKNNQuery<O, D>, RKNNQuery<O, D>>> getKNNAndRkNNQueries(Database database, Relation<O> relation, StepProgress stepprog) {
+ private Pair<Pair<KNNQuery<O>, KNNQuery<O>>, Pair<RKNNQuery<O>, RKNNQuery<O>>> getKNNAndRkNNQueries(Database database, Relation<O> relation, StepProgress stepprog) {
// Use "HEAVY" flag, since this is an online algorithm
- KNNQuery<O, D> kNNRefer = QueryUtil.getKNNQuery(relation, referenceDistanceFunction, krefer, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
- RKNNQuery<O, D> rkNNRefer = QueryUtil.getRKNNQuery(relation, referenceDistanceFunction, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
+ KNNQuery<O> kNNRefer = QueryUtil.getKNNQuery(relation, referenceDistanceFunction, krefer, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
+ RKNNQuery<O> rkNNRefer = QueryUtil.getRKNNQuery(relation, referenceDistanceFunction, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
// No optimized kNN query or RkNN query - use a preprocessor!
- if (kNNRefer == null || rkNNRefer == null) {
- if (stepprog != null) {
+ if(kNNRefer == null || rkNNRefer == null) {
+ if(stepprog != null) {
stepprog.beginStep(1, "Materializing neighborhood w.r.t. reference neighborhood distance function.", LOG);
}
- MaterializeKNNAndRKNNPreprocessor<O, D> preproc = new MaterializeKNNAndRKNNPreprocessor<>(relation, referenceDistanceFunction, krefer);
- DistanceQuery<O, D> ndq = database.getDistanceQuery(relation, referenceDistanceFunction);
+ MaterializeKNNAndRKNNPreprocessor<O> preproc = new MaterializeKNNAndRKNNPreprocessor<>(relation, referenceDistanceFunction, krefer);
+ DistanceQuery<O> ndq = database.getDistanceQuery(relation, referenceDistanceFunction);
kNNRefer = preproc.getKNNQuery(ndq, krefer, DatabaseQuery.HINT_HEAVY_USE);
rkNNRefer = preproc.getRKNNQuery(ndq, krefer, DatabaseQuery.HINT_HEAVY_USE);
// add as index
- relation.getDatabase().addIndex(preproc);
- } else {
- if (stepprog != null) {
+ database.addIndex(preproc);
+ }
+ else {
+ if(stepprog != null) {
stepprog.beginStep(1, "Optimized neighborhood w.r.t. reference neighborhood distance function provided by database.", LOG);
}
}
- KNNQuery<O, D> kNNReach = QueryUtil.getKNNQuery(relation, reachabilityDistanceFunction, kreach, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
- RKNNQuery<O, D> rkNNReach = QueryUtil.getRKNNQuery(relation, reachabilityDistanceFunction, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
- if (kNNReach == null || rkNNReach == null) {
- if (stepprog != null) {
+ KNNQuery<O> kNNReach = QueryUtil.getKNNQuery(relation, reachabilityDistanceFunction, kreach, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
+ RKNNQuery<O> rkNNReach = QueryUtil.getRKNNQuery(relation, reachabilityDistanceFunction, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
+ if(kNNReach == null || rkNNReach == null) {
+ if(stepprog != null) {
stepprog.beginStep(2, "Materializing neighborhood w.r.t. reachability distance function.", LOG);
}
ListParameterization config = new ListParameterization();
config.addParameter(AbstractMaterializeKNNPreprocessor.Factory.DISTANCE_FUNCTION_ID, reachabilityDistanceFunction);
config.addParameter(AbstractMaterializeKNNPreprocessor.Factory.K_ID, kreach);
- MaterializeKNNAndRKNNPreprocessor<O, D> preproc = new MaterializeKNNAndRKNNPreprocessor<>(relation, reachabilityDistanceFunction, kreach);
- DistanceQuery<O, D> rdq = database.getDistanceQuery(relation, reachabilityDistanceFunction);
+ MaterializeKNNAndRKNNPreprocessor<O> preproc = new MaterializeKNNAndRKNNPreprocessor<>(relation, reachabilityDistanceFunction, kreach);
+ DistanceQuery<O> rdq = database.getDistanceQuery(relation, reachabilityDistanceFunction);
kNNReach = preproc.getKNNQuery(rdq, kreach, DatabaseQuery.HINT_HEAVY_USE);
rkNNReach = preproc.getRKNNQuery(rdq, kreach, DatabaseQuery.HINT_HEAVY_USE);
// add as index
relation.getDatabase().addIndex(preproc);
}
- Pair<KNNQuery<O, D>, KNNQuery<O, D>> kNNPair = new Pair<>(kNNRefer, kNNReach);
- Pair<RKNNQuery<O, D>, RKNNQuery<O, D>> rkNNPair = new Pair<>(rkNNRefer, rkNNReach);
+ Pair<KNNQuery<O>, KNNQuery<O>> kNNPair = new Pair<>(kNNRefer, kNNReach);
+ Pair<RKNNQuery<O>, RKNNQuery<O>> rkNNPair = new Pair<>(rkNNRefer, rkNNReach);
return new Pair<>(kNNPair, rkNNPair);
}
@@ -182,36 +183,40 @@ public class OnlineLOF<O, D extends NumberDistance<D, ?>> extends FlexibleLOF<O,
/**
* Holds the result of a former run of the LOF algorithm.
*/
- private LOFResult<O, D> lofResult;
+ private LOFResult<O> lofResult;
/**
* Constructs a listener for the LOF algorithm.
*
* @param lofResult the result of a former run of the LOF algorithm
*/
- public LOFKNNListener(LOFResult<O, D> lofResult) {
+ public LOFKNNListener(LOFResult<O> lofResult) {
this.lofResult = lofResult;
}
@Override
public void kNNsChanged(KNNChangeEvent e) {
- AbstractMaterializeKNNPreprocessor<O, D, ?> p1 = ((PreprocessorKNNQuery<O, D, ?>) lofResult.getKNNRefer()).getPreprocessor();
- AbstractMaterializeKNNPreprocessor<O, D, ?> p2 = ((PreprocessorKNNQuery<O, D, ?>) lofResult.getKNNReach()).getPreprocessor();
+ AbstractMaterializeKNNPreprocessor<O> p1 = ((PreprocessorKNNQuery<O>) lofResult.getKNNRefer()).getPreprocessor();
+ AbstractMaterializeKNNPreprocessor<O> p2 = ((PreprocessorKNNQuery<O>) lofResult.getKNNReach()).getPreprocessor();
- if (firstEventReceived == null) {
- if (e.getSource().equals(p1) && e.getSource().equals(p2)) {
+ if(firstEventReceived == null) {
+ if(e.getSource().equals(p1) && e.getSource().equals(p2)) {
kNNsChanged(e, e);
- } else {
+ }
+ else {
firstEventReceived = e;
}
- } else {
- if (e.getSource().equals(p1) && firstEventReceived.getSource().equals(p2)) {
+ }
+ else {
+ if(e.getSource().equals(p1) && firstEventReceived.getSource().equals(p2)) {
kNNsChanged(e, firstEventReceived);
firstEventReceived = null;
- } else if (e.getSource().equals(p2) && firstEventReceived.getSource().equals(p1)) {
+ }
+ else if(e.getSource().equals(p2) && firstEventReceived.getSource().equals(p1)) {
kNNsChanged(firstEventReceived, e);
firstEventReceived = null;
- } else {
+ }
+ else {
throw new UnsupportedOperationException("Event sources do not fit!");
}
}
@@ -225,18 +230,20 @@ public class OnlineLOF<O, D extends NumberDistance<D, ?>> extends FlexibleLOF<O,
* @param e2 the change event of the second preprocessor
*/
private void kNNsChanged(KNNChangeEvent e1, KNNChangeEvent e2) {
- if (!e1.getType().equals(e2.getType())) {
+ if(!e1.getType().equals(e2.getType())) {
throw new UnsupportedOperationException("Event types do not fit: " + e1.getType() + " != " + e2.getType());
}
- if (!e1.getObjects().equals(e2.getObjects())) {
+ if(!e1.getObjects().equals(e2.getObjects())) {
throw new UnsupportedOperationException("Objects do not fit: " + e1.getObjects() + " != " + e2.getObjects());
}
- if (e1.getType().equals(KNNChangeEvent.Type.DELETE)) {
+ if(e1.getType().equals(KNNChangeEvent.Type.DELETE)) {
kNNsRemoved(e1.getObjects(), e1.getUpdates(), e2.getUpdates(), lofResult);
- } else if (e1.getType().equals(KNNChangeEvent.Type.INSERT)) {
+ }
+ else if(e1.getType().equals(KNNChangeEvent.Type.INSERT)) {
kNNsInserted(e1.getObjects(), e1.getUpdates(), e2.getUpdates(), lofResult);
- } else {
+ }
+ else {
throw new UnsupportedOperationException("Unsupported event type: " + e1.getType());
}
}
@@ -251,44 +258,43 @@ public class OnlineLOF<O, D extends NumberDistance<D, ?>> extends FlexibleLOF<O,
* reachability distance function
* @param lofResult the result of the former LOF run
*/
- private void kNNsInserted(DBIDs insertions, DBIDs updates1, DBIDs updates2, LOFResult<O, D> lofResult) {
+ private void kNNsInserted(DBIDs insertions, DBIDs updates1, DBIDs updates2, LOFResult<O> lofResult) {
StepProgress stepprog = LOG.isVerbose() ? new StepProgress(3) : null;
// recompute lrds
- if (stepprog != null) {
+ if(stepprog != null) {
stepprog.beginStep(1, "Recompute LRDs.", LOG);
}
ArrayDBIDs lrd_ids = DBIDUtil.ensureArray(DBIDUtil.union(insertions, updates2));
- List<? extends DistanceDBIDList<D>> reachDistRKNNs = lofResult.getRkNNReach().getRKNNForBulkDBIDs(lrd_ids, kreach);
+ List<? extends DoubleDBIDList> reachDistRKNNs = lofResult.getRkNNReach().getRKNNForBulkDBIDs(lrd_ids, kreach);
ArrayDBIDs affected_lrd_id_candidates = mergeIDs(reachDistRKNNs, lrd_ids);
ArrayModifiableDBIDs affected_lrd_ids = DBIDUtil.newArray(affected_lrd_id_candidates.size());
- WritableDoubleDataStore new_lrds = computeLRDs(affected_lrd_id_candidates, lofResult.getKNNReach());
- for (DBIDIter iter = affected_lrd_id_candidates.iter(); iter.valid(); iter.advance()) {
+ WritableDoubleDataStore new_lrds = DataStoreUtil.makeDoubleStorage(affected_lrd_id_candidates, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
+ computeLRDs(lofResult.getKNNReach(), affected_lrd_id_candidates, new_lrds);
+ for(DBIDIter iter = affected_lrd_id_candidates.iter(); iter.valid(); iter.advance()) {
double new_lrd = new_lrds.doubleValue(iter);
double old_lrd = lofResult.getLrds().doubleValue(iter);
- if (Double.isNaN(old_lrd) || old_lrd != new_lrd) {
+ if(Double.isNaN(old_lrd) || old_lrd != new_lrd) {
lofResult.getLrds().putDouble(iter, new_lrd);
affected_lrd_ids.add(iter);
}
}
// recompute lofs
- if (stepprog != null) {
+ if(stepprog != null) {
stepprog.beginStep(2, "Recompute LOFS.", LOG);
}
- List<? extends DistanceDBIDList<D>> primDistRKNNs = lofResult.getRkNNRefer().getRKNNForBulkDBIDs(affected_lrd_ids, krefer);
+ List<? extends DoubleDBIDList> primDistRKNNs = lofResult.getRkNNRefer().getRKNNForBulkDBIDs(affected_lrd_ids, krefer);
ArrayDBIDs affected_lof_ids = mergeIDs(primDistRKNNs, affected_lrd_ids, insertions, updates1);
recomputeLOFs(affected_lof_ids, lofResult);
// fire result changed
- if (stepprog != null) {
+ if(stepprog != null) {
stepprog.beginStep(3, "Inform listeners.", LOG);
}
lofResult.getResult().getHierarchy().resultChanged(lofResult.getResult());
- if (stepprog != null) {
- stepprog.setCompleted(LOG);
- }
+ LOG.setCompleted(stepprog);
}
/**
@@ -301,53 +307,52 @@ public class OnlineLOF<O, D extends NumberDistance<D, ?>> extends FlexibleLOF<O,
* reachability distance function
* @param lofResult the result of the former LOF run
*/
- private void kNNsRemoved(DBIDs deletions, DBIDs updates1, DBIDs updates2, LOFResult<O, D> lofResult) {
+ private void kNNsRemoved(DBIDs deletions, DBIDs updates1, DBIDs updates2, LOFResult<O> lofResult) {
StepProgress stepprog = LOG.isVerbose() ? new StepProgress(4) : null;
// delete lrds and lofs
- if (stepprog != null) {
+ if(stepprog != null) {
stepprog.beginStep(1, "Delete old LRDs and LOFs.", LOG);
}
- for (DBIDIter iter = deletions.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = deletions.iter(); iter.valid(); iter.advance()) {
lofResult.getLrds().delete(iter);
lofResult.getLofs().delete(iter);
}
// recompute lrds
- if (stepprog != null) {
+ if(stepprog != null) {
stepprog.beginStep(2, "Recompute LRDs.", LOG);
}
ArrayDBIDs lrd_ids = DBIDUtil.ensureArray(updates2);
- List<? extends DistanceDBIDList<D>> reachDistRKNNs = lofResult.getRkNNReach().getRKNNForBulkDBIDs(lrd_ids, kreach);
+ List<? extends DoubleDBIDList> reachDistRKNNs = lofResult.getRkNNReach().getRKNNForBulkDBIDs(lrd_ids, kreach);
ArrayDBIDs affected_lrd_id_candidates = mergeIDs(reachDistRKNNs, lrd_ids);
ArrayModifiableDBIDs affected_lrd_ids = DBIDUtil.newArray(affected_lrd_id_candidates.size());
- WritableDoubleDataStore new_lrds = computeLRDs(affected_lrd_id_candidates, lofResult.getKNNReach());
- for (DBIDIter iter = affected_lrd_id_candidates.iter(); iter.valid(); iter.advance()) {
+ WritableDoubleDataStore new_lrds = DataStoreUtil.makeDoubleStorage(affected_lrd_id_candidates, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
+ computeLRDs(lofResult.getKNNReach(), affected_lrd_id_candidates, new_lrds);
+ for(DBIDIter iter = affected_lrd_id_candidates.iter(); iter.valid(); iter.advance()) {
double new_lrd = new_lrds.doubleValue(iter);
double old_lrd = lofResult.getLrds().doubleValue(iter);
- if (old_lrd != new_lrd) {
+ if(old_lrd != new_lrd) {
lofResult.getLrds().putDouble(iter, new_lrd);
affected_lrd_ids.add(iter);
}
}
// recompute lofs
- if (stepprog != null) {
+ if(stepprog != null) {
stepprog.beginStep(3, "Recompute LOFS.", LOG);
}
- List<? extends DistanceDBIDList<D>> primDistRKNNs = lofResult.getRkNNRefer().getRKNNForBulkDBIDs(affected_lrd_ids, krefer);
+ List<? extends DoubleDBIDList> primDistRKNNs = lofResult.getRkNNRefer().getRKNNForBulkDBIDs(affected_lrd_ids, krefer);
ArrayDBIDs affected_lof_ids = mergeIDs(primDistRKNNs, affected_lrd_ids, updates1);
recomputeLOFs(affected_lof_ids, lofResult);
// fire result changed
- if (stepprog != null) {
+ if(stepprog != null) {
stepprog.beginStep(4, "Inform listeners.", LOG);
}
lofResult.getResult().getHierarchy().resultChanged(lofResult.getResult());
- if (stepprog != null) {
- stepprog.setCompleted(LOG);
- }
+ LOG.setCompleted(stepprog);
}
/**
@@ -358,12 +363,12 @@ public class OnlineLOF<O, D extends NumberDistance<D, ?>> extends FlexibleLOF<O,
* @return a set containing the ids of the query result and the specified
* ids
*/
- private ArrayModifiableDBIDs mergeIDs(List<? extends DistanceDBIDList<D>> queryResults, DBIDs... ids) {
+ private ArrayModifiableDBIDs mergeIDs(List<? extends DoubleDBIDList> queryResults, DBIDs... ids) {
ModifiableDBIDs result = DBIDUtil.newHashSet();
- for (DBIDs dbids : ids) {
+ for(DBIDs dbids : ids) {
result.addDBIDs(dbids);
}
- for (DistanceDBIDList<D> queryResult : queryResults) {
+ for(DoubleDBIDList queryResult : queryResults) {
result.addDBIDs(queryResult);
}
return DBIDUtil.newArray(result);
@@ -375,24 +380,23 @@ public class OnlineLOF<O, D extends NumberDistance<D, ?>> extends FlexibleLOF<O,
* @param ids the ids of the lofs to be recomputed
* @param lofResult the result of the former LOF run
*/
- private void recomputeLOFs(DBIDs ids, LOFResult<O, D> lofResult) {
- Pair<WritableDoubleDataStore, DoubleMinMax> lofsAndMax = computeLOFs(ids, lofResult.getLrds(), lofResult.getKNNRefer());
- WritableDoubleDataStore new_lofs = lofsAndMax.getFirst();
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ private void recomputeLOFs(DBIDs ids, LOFResult<O> lofResult) {
+ WritableDoubleDataStore new_lofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
+ DoubleMinMax new_lofminmax = new DoubleMinMax();
+ computeLOFs(lofResult.getKNNRefer(), ids, lofResult.getLrds(), new_lofs, new_lofminmax);
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
lofResult.getLofs().putDouble(iter, new_lofs.doubleValue(iter));
}
- // track the maximum value for normalization.
- DoubleMinMax new_lofminmax = lofsAndMax.getSecond();
-
// Actualize meta info
- if (new_lofminmax.isValid() && lofResult.getResult().getOutlierMeta().getActualMaximum() < new_lofminmax.getMax()) {
- BasicOutlierScoreMeta scoreMeta = (BasicOutlierScoreMeta) lofResult.getResult().getOutlierMeta();
- scoreMeta.setActualMaximum(new_lofminmax.getMax());
- }
-
- if (new_lofminmax.isValid() && lofResult.getResult().getOutlierMeta().getActualMinimum() > new_lofminmax.getMin()) {
- BasicOutlierScoreMeta scoreMeta = (BasicOutlierScoreMeta) lofResult.getResult().getOutlierMeta();
- scoreMeta.setActualMinimum(new_lofminmax.getMin());
+ if(new_lofminmax.isValid()) {
+ if(lofResult.getResult().getOutlierMeta().getActualMaximum() < new_lofminmax.getMax()) {
+ BasicOutlierScoreMeta scoreMeta = (BasicOutlierScoreMeta) lofResult.getResult().getOutlierMeta();
+ scoreMeta.setActualMaximum(new_lofminmax.getMax());
+ }
+ if(lofResult.getResult().getOutlierMeta().getActualMinimum() > new_lofminmax.getMin()) {
+ BasicOutlierScoreMeta scoreMeta = (BasicOutlierScoreMeta) lofResult.getResult().getOutlierMeta();
+ scoreMeta.setActualMinimum(new_lofminmax.getMin());
+ }
}
}
}
@@ -409,9 +413,9 @@ public class OnlineLOF<O, D extends NumberDistance<D, ?>> extends FlexibleLOF<O,
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends FlexibleLOF.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends FlexibleLOF.Parameterizer<O> {
@Override
- protected OnlineLOF<O, D> makeInstance() {
+ protected OnlineLOF<O> makeInstance() {
return new OnlineLOF<>(kreach, krefer, distanceFunction, reachabilityDistanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/SimpleKernelDensityLOF.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/SimpleKernelDensityLOF.java
index b990ef35..3ba56b16 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/SimpleKernelDensityLOF.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/SimpleKernelDensityLOF.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
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,27 +30,20 @@ import de.lmu.ifi.dbs.elki.data.type.CombinedTypeInformation;
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.Database;
-import de.lmu.ifi.dbs.elki.database.QueryUtil;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-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.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
-import de.lmu.ifi.dbs.elki.database.query.knn.PreprocessorKNNQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNPreprocessor;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
@@ -61,6 +54,7 @@ import de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions.KernelDensityFunction
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.QuotientOutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
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;
@@ -77,9 +71,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.has KernelDensityFunction
*
* @param <O> the type of objects handled by this Algorithm
- * @param <D> Distance type
*/
-public class SimpleKernelDensityLOF<O extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
+public class SimpleKernelDensityLOF<O extends NumberVector> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -101,7 +94,7 @@ public class SimpleKernelDensityLOF<O extends NumberVector<?>, D extends NumberD
* @param k the value of k
* @param kernel Kernel function
*/
- public SimpleKernelDensityLOF(int k, DistanceFunction<? super O, D> distance, KernelDensityFunction kernel) {
+ public SimpleKernelDensityLOF(int k, DistanceFunction<? super O> distance, KernelDensityFunction kernel) {
super(distance);
this.k = k + 1;
this.kernel = kernel;
@@ -116,112 +109,75 @@ public class SimpleKernelDensityLOF<O extends NumberVector<?>, D extends NumberD
*/
public OutlierResult run(Database database, Relation<O> relation) {
StepProgress stepprog = LOG.isVerbose() ? new StepProgress("KernelDensityLOF", 3) : null;
-
final int dim = RelationUtil.dimensionality(relation);
-
DBIDs ids = relation.getDBIDs();
- // "HEAVY" flag for KNN Query since it is used more than once
- KNNQuery<O, D> knnq = QueryUtil.getKNNQuery(relation, getDistanceFunction(), k, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
- // No optimized kNN query - use a preprocessor!
- if (!(knnq instanceof PreprocessorKNNQuery)) {
- if (stepprog != null) {
- stepprog.beginStep(1, "Materializing neighborhoods w.r.t. distance function.", LOG);
- }
- MaterializeKNNPreprocessor<O, D> preproc = new MaterializeKNNPreprocessor<>(relation, getDistanceFunction(), k);
- database.addIndex(preproc);
- DistanceQuery<O, D> rdq = database.getDistanceQuery(relation, getDistanceFunction());
- knnq = preproc.getKNNQuery(rdq, k);
- }
+ LOG.beginStep(stepprog, 1, "Materializing neighborhoods w.r.t. distance function.");
+ KNNQuery<O> knnq = DatabaseUtil.precomputedKNNQuery(database, relation, getDistanceFunction(), k);
// Compute LRDs
- if (stepprog != null) {
- stepprog.beginStep(2, "Computing densities.", LOG);
- }
+ LOG.beginStep(stepprog, 2, "Computing densities.");
WritableDoubleDataStore dens = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
FiniteProgress densProgress = LOG.isVerbose() ? new FiniteProgress("Densities", ids.size(), LOG) : null;
- for (DBIDIter it = ids.iter(); it.valid(); it.advance()) {
- final KNNList<D> neighbors = knnq.getKNNForDBID(it, k);
+ for(DBIDIter it = ids.iter(); it.valid(); it.advance()) {
+ final KNNList neighbors = knnq.getKNNForDBID(it, k);
int count = 0;
double sum = 0.0;
- if (neighbors instanceof DoubleDistanceKNNList) {
- // Fast version for double distances
- for (DoubleDistanceDBIDListIter neighbor = ((DoubleDistanceKNNList) neighbors).iter(); neighbor.valid(); neighbor.advance()) {
- if (DBIDUtil.equal(neighbor, it)) {
- continue;
- }
- double max = ((DoubleDistanceKNNList)knnq.getKNNForDBID(neighbor, k)).doubleKNNDistance();
- final double v = neighbor.doubleDistance() / max;
- sum += kernel.density(v) / MathUtil.powi(max, dim);
- count++;
- }
- } else {
- for (DistanceDBIDListIter<D> neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
- if (DBIDUtil.equal(neighbor, it)) {
- continue;
- }
- double max = knnq.getKNNForDBID(neighbor, k).getKNNDistance().doubleValue();
- final double v = neighbor.getDistance().doubleValue() / max;
- sum += kernel.density(v) / MathUtil.powi(max, dim);
- count++;
+ // Fast version for double distances
+ for(DoubleDBIDListIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ if(DBIDUtil.equal(neighbor, it)) {
+ continue;
}
+ double max = knnq.getKNNForDBID(neighbor, k).getKNNDistance();
+ final double v = neighbor.doubleValue() / max;
+ sum += kernel.density(v) / MathUtil.powi(max, dim);
+ count++;
}
final double density = sum / count;
dens.putDouble(it, density);
- if (densProgress != null) {
- densProgress.incrementProcessed(LOG);
- }
- }
- if (densProgress != null) {
- densProgress.ensureCompleted(LOG);
+ LOG.incrementProcessed(densProgress);
}
+ LOG.ensureCompleted(densProgress);
// compute LOF_SCORE of each db object
- if (stepprog != null) {
- stepprog.beginStep(3, "Computing KLOFs.", LOG);
- }
+ LOG.beginStep(stepprog, 3, "Computing KLOFs.");
WritableDoubleDataStore lofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC);
// track the maximum value for normalization.
DoubleMinMax lofminmax = new DoubleMinMax();
FiniteProgress progressLOFs = LOG.isVerbose() ? new FiniteProgress("KLOF_SCORE for objects", ids.size(), LOG) : null;
- for (DBIDIter it = ids.iter(); it.valid(); it.advance()) {
+ for(DBIDIter it = ids.iter(); it.valid(); it.advance()) {
final double lrdp = dens.doubleValue(it);
final double lof;
- if (lrdp > 0) {
- final KNNList<D> neighbors = knnq.getKNNForDBID(it, k);
+ if(lrdp > 0) {
+ final KNNList neighbors = knnq.getKNNForDBID(it, k);
double sum = 0.0;
int count = 0;
- for (DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ for(DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
// skip the point itself
- if (DBIDUtil.equal(neighbor, it)) {
+ if(DBIDUtil.equal(neighbor, it)) {
continue;
}
sum += dens.doubleValue(neighbor);
count++;
}
lof = sum / (count * lrdp);
- } else {
+ }
+ else {
lof = 1.0;
}
lofs.putDouble(it, lof);
// update minimum and maximum
lofminmax.put(lof);
- if (progressLOFs != null) {
- progressLOFs.incrementProcessed(LOG);
- }
- }
- if (progressLOFs != null) {
- progressLOFs.ensureCompleted(LOG);
+ LOG.incrementProcessed(progressLOFs);
}
+ LOG.ensureCompleted(progressLOFs);
- if (stepprog != null) {
- stepprog.setCompleted(LOG);
- }
+ LOG.setCompleted(stepprog);
// Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("Kernel Density Local Outlier Factor", "kernel-density-slof-outlier", TypeUtil.DOUBLE, lofs, ids);
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Kernel Density Local Outlier Factor", "kernel-density-slof-outlier", lofs, ids);
OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(lofminmax.getMin(), lofminmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 1.0);
OutlierResult result = new OutlierResult(scoreMeta, scoreResult);
@@ -246,9 +202,8 @@ public class SimpleKernelDensityLOF<O extends NumberVector<?>, D extends NumberD
* @apiviz.exclude
*
* @param <O> vector type
- * @param <D> distance type
*/
- public static class Parameterizer<O extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O extends NumberVector> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Option ID for kernel density LOF kernel.
*/
@@ -270,18 +225,18 @@ public class SimpleKernelDensityLOF<O extends NumberVector<?>, D extends NumberD
final IntParameter pK = new IntParameter(LOF.Parameterizer.K_ID);
pK.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
- if (config.grab(pK)) {
+ if(config.grab(pK)) {
k = pK.getValue();
}
ObjectParameter<KernelDensityFunction> kernelP = new ObjectParameter<>(KERNEL_ID, KernelDensityFunction.class, EpanechnikovKernelDensityFunction.class);
- if (config.grab(kernelP)) {
+ if(config.grab(kernelP)) {
kernel = kernelP.instantiateClass(config);
}
}
@Override
- protected SimpleKernelDensityLOF<O, D> makeInstance() {
+ protected SimpleKernelDensityLOF<O> makeInstance() {
return new SimpleKernelDensityLOF<>(k, distanceFunction, kernel);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/SimplifiedLOF.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/SimplifiedLOF.java
index d54b053f..8fce6503 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/SimplifiedLOF.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/SimplifiedLOF.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
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,26 +28,19 @@ import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
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.Database;
-import de.lmu.ifi.dbs.elki.database.QueryUtil;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-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.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
-import de.lmu.ifi.dbs.elki.database.query.knn.PreprocessorKNNQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.NumberDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNPreprocessor;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
@@ -56,6 +49,7 @@ import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.QuotientOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -68,28 +62,30 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* Reference:
* <p>
* Erich Schubert, Arthur Zimek, Hans-Peter Kriegel<br />
- * Local outlier detection reconsidered: a generalized view on locality with
- * applications to spatial, video, and network outlier detection<br />
- * In: Data Mining and Knowledge Discovery
+ * Local Outlier Detection Reconsidered: a Generalized View on Locality with
+ * Applications to Spatial, Video, and Network Outlier Detection<br />
+ * Data Mining and Knowledge Discovery, 28(1): 190–237, 2014.
* </p>
*
* @author Erich Schubert
*
* @apiviz.has KNNQuery
*
- * @param <O> the type of DatabaseObjects handled by this Algorithm
- * @param <D> Distance type
+ * @param <O> the type of data objects handled by this algorithm
*/
-@Reference(authors = "Erich Schubert, Arthur Zimek, Hans-Peter Kriegel", title = "Local outlier detection reconsidered: a generalized view on locality with applications to spatial, video, and network outlier detection", booktitle = "Data Mining and Knowledge Discovery", url = "http://dx.doi.org/10.1007/s10618-012-0300-z")
-@Alias({ "SimpleLOF", "outlier.SimpleLOF", "de.lmu.ifi.dbs.elki.algorithm.outlier.SimpleLOF" })
-public class SimplifiedLOF<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "E. Schubert, A. Zimek, H.-P. Kriegel", //
+title = "Local Outlier Detection Reconsidered: a Generalized View on Locality with Applications to Spatial, Video, and Network Outlier Detection", //
+booktitle = "Data Mining and Knowledge Discovery, 28(1): 190–237, 2014.", //
+url = "http://dx.doi.org/10.1007/s10618-012-0300-z")
+@Alias({ "SimplifiedLOF", "outlier.SimplifiedLOF", "de.lmu.ifi.dbs.elki.algorithm.outlier.SimplifiedLOF" })
+public class SimplifiedLOF<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
private static final Logging LOG = Logging.getLogger(SimplifiedLOF.class);
/**
- * Parameter k.
+ * The number of neighbors to query, excluding the query point.
*/
protected int k;
@@ -98,7 +94,7 @@ public class SimplifiedLOF<O, D extends NumberDistance<D, ?>> extends AbstractDi
*
* @param k the value of k
*/
- public SimplifiedLOF(int k, DistanceFunction<? super O, D> distance) {
+ public SimplifiedLOF(int k, DistanceFunction<? super O> distance) {
super(distance);
this.k = k + 1;
}
@@ -111,114 +107,103 @@ public class SimplifiedLOF<O, D extends NumberDistance<D, ?>> extends AbstractDi
* @return LOF outlier result
*/
public OutlierResult run(Database database, Relation<O> relation) {
- StepProgress stepprog = LOG.isVerbose() ? new StepProgress("SimpleLOF", 3) : null;
-
+ StepProgress stepprog = LOG.isVerbose() ? new StepProgress("Simplified LOF", 3) : null;
DBIDs ids = relation.getDBIDs();
- // "HEAVY" flag for KNN Query since it is used more than once
- KNNQuery<O, D> knnq = QueryUtil.getKNNQuery(relation, getDistanceFunction(), k, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
- // No optimized kNN query - use a preprocessor!
- if(!(knnq instanceof PreprocessorKNNQuery)) {
- if(stepprog != null) {
- stepprog.beginStep(1, "Materializing neighborhoods w.r.t. distance function.", LOG);
- }
- MaterializeKNNPreprocessor<O, D> preproc = new MaterializeKNNPreprocessor<>(relation, getDistanceFunction(), k);
- database.addIndex(preproc);
- DistanceQuery<O, D> rdq = database.getDistanceQuery(relation, getDistanceFunction());
- knnq = preproc.getKNNQuery(rdq, k);
- }
+ LOG.beginStep(stepprog, 1, "Materializing neighborhoods w.r.t. distance function.");
+ KNNQuery<O> knnq = DatabaseUtil.precomputedKNNQuery(database, relation, getDistanceFunction(), k);
// Compute LRDs
- if(stepprog != null) {
- stepprog.beginStep(2, "Computing densities.", LOG);
- }
+ LOG.beginStep(stepprog, 2, "Computing densities.");
WritableDoubleDataStore dens = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
- FiniteProgress densProgress = LOG.isVerbose() ? new FiniteProgress("Densities", ids.size(), LOG) : null;
- for(DBIDIter it = ids.iter(); it.valid(); it.advance()) {
- final KNNList<D> neighbors = knnq.getKNNForDBID(it, k);
+ computeSimplifiedLRDs(ids, knnq, dens);
+
+ // compute LOF_SCORE of each db object
+ LOG.beginStep(stepprog, 3, "Computing SLOFs.");
+ WritableDoubleDataStore lofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC);
+ DoubleMinMax lofminmax = new DoubleMinMax();
+ computeSimplifiedLOFs(ids, knnq, dens, lofs, lofminmax);
+
+ LOG.setCompleted(stepprog);
+
+ // Build result representation.
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Simplified Local Outlier Factor", "simplified-lof-outlier", lofs, ids);
+ OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(lofminmax.getMin(), lofminmax.getMax(), 0., Double.POSITIVE_INFINITY, 1.);
+ OutlierResult result = new OutlierResult(scoreMeta, scoreResult);
+
+ return result;
+ }
+
+ /**
+ * Compute the simplified reachability densities.
+ *
+ * @param ids IDs to process
+ * @param knnq kNN query class
+ * @param lrds Density output
+ */
+ private void computeSimplifiedLRDs(DBIDs ids, KNNQuery<O> knnq, WritableDoubleDataStore lrds) {
+ FiniteProgress lrdsProgress = LOG.isVerbose() ? new FiniteProgress("Densities", ids.size(), LOG) : null;
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ final KNNList neighbors = knnq.getKNNForDBID(iter, k);
double sum = 0.0;
int count = 0;
- if(neighbors instanceof DoubleDistanceKNNList) {
- // Fast version for double distances
- for(DoubleDistanceDBIDListIter neighbor = ((DoubleDistanceKNNList) neighbors).iter(); neighbor.valid(); neighbor.advance()) {
- if(DBIDUtil.equal(neighbor, it)) {
- continue;
- }
- sum += neighbor.doubleDistance();
- count++;
- }
- }
- else {
- for(DistanceDBIDListIter<D> neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
- if(DBIDUtil.equal(neighbor, it)) {
- continue;
- }
- sum += neighbor.getDistance().doubleValue();
- count++;
+ for(DoubleDBIDListIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ if(DBIDUtil.equal(neighbor, iter)) {
+ continue;
}
+ sum += neighbor.doubleValue();
+ count++;
}
// Avoid division by 0
- final double lrd = (sum > 0) ? (count / sum) : 0;
- dens.putDouble(it, lrd);
- if(densProgress != null) {
- densProgress.incrementProcessed(LOG);
- }
- }
- if(densProgress != null) {
- densProgress.ensureCompleted(LOG);
- }
-
- // compute LOF_SCORE of each db object
- if(stepprog != null) {
- stepprog.beginStep(3, "Computing SLOFs.", LOG);
+ final double lrd = (sum > 0) ? (count / sum) : Double.POSITIVE_INFINITY;
+ lrds.putDouble(iter, lrd);
+ LOG.incrementProcessed(lrdsProgress);
}
- WritableDoubleDataStore lofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC);
- // track the maximum value for normalization.
- DoubleMinMax lofminmax = new DoubleMinMax();
+ LOG.ensureCompleted(lrdsProgress);
+ }
- FiniteProgress progressLOFs = LOG.isVerbose() ? new FiniteProgress("Simple LOF scores.", ids.size(), LOG) : null;
- for(DBIDIter it = ids.iter(); it.valid(); it.advance()) {
- final double lrdp = dens.doubleValue(it);
+ /**
+ * Compute the simplified LOF factors.
+ *
+ * @param ids IDs to compute for
+ * @param knnq kNN query class
+ * @param slrds Object densities
+ * @param lofs SLOF output storage
+ * @param lofminmax Minimum and maximum scores
+ */
+ private void computeSimplifiedLOFs(DBIDs ids, KNNQuery<O> knnq, WritableDoubleDataStore slrds, WritableDoubleDataStore lofs, DoubleMinMax lofminmax) {
+ FiniteProgress progressLOFs = LOG.isVerbose() ? new FiniteProgress("Simplified LOF scores.", ids.size(), LOG) : null;
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
final double lof;
- if(lrdp > 0) {
- final KNNList<D> neighbors = knnq.getKNNForDBID(it, k);
- double sum = 0.0;
+ final double lrdp = slrds.doubleValue(iter);
+ final KNNList neighbors = knnq.getKNNForDBID(iter, k);
+ if(!Double.isInfinite(lrdp)) {
+ double sum = 0.;
int count = 0;
for(DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
// skip the point itself
- if(DBIDUtil.equal(neighbor, it)) {
+ if(DBIDUtil.equal(neighbor, iter)) {
continue;
}
- sum += dens.doubleValue(neighbor);
+ final double val = slrds.doubleValue(neighbor);
+ sum += val;
count++;
+ if(Double.isInfinite(val)) {
+ break;
+ }
}
- lof = sum / (count * lrdp);
+ lof = sum / (lrdp * count);
}
else {
lof = 1.0;
}
- lofs.putDouble(it, lof);
+ lofs.putDouble(iter, lof);
// update minimum and maximum
lofminmax.put(lof);
- if(progressLOFs != null) {
- progressLOFs.incrementProcessed(LOG);
- }
- }
- if(progressLOFs != null) {
- progressLOFs.ensureCompleted(LOG);
- }
-
- if(stepprog != null) {
- stepprog.setCompleted(LOG);
+ LOG.incrementProcessed(progressLOFs);
}
-
- // Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("Simple Local Outlier Factor", "simple-lof-outlier", TypeUtil.DOUBLE, lofs, ids);
- OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(lofminmax.getMin(), lofminmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 1.0);
- OutlierResult result = new OutlierResult(scoreMeta, scoreResult);
-
- return result;
+ LOG.ensureCompleted(progressLOFs);
}
@Override
@@ -238,10 +223,9 @@ public class SimplifiedLOF<O, D extends NumberDistance<D, ?>> extends AbstractDi
*
* @apiviz.exclude
*
- * @param <O> vector type
- * @param <D> distance type
+ * @param <O> Object type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* The neighborhood size to use.
*/
@@ -252,14 +236,14 @@ public class SimplifiedLOF<O, D extends NumberDistance<D, ?>> extends AbstractDi
super.makeOptions(config);
final IntParameter pK = new IntParameter(LOF.Parameterizer.K_ID);
- pK.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
+ pK.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
if(config.grab(pK)) {
k = pK.getValue();
}
}
@Override
- protected SimplifiedLOF<O, D> makeInstance() {
+ protected SimplifiedLOF<O> makeInstance() {
return new SimplifiedLOF<>(k, distanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/package-info.java
index 48d4b16a..090e89da 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/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/algorithm/outlier/lof/parallel/LOFProcessor.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/LOFProcessor.java
new file mode 100644
index 00000000..3c0bf4c8
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/LOFProcessor.java
@@ -0,0 +1,119 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.lof.parallel;
+
+/*
+ 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.database.datastore.DataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.DoubleDataStore;
+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.KNNList;
+import de.lmu.ifi.dbs.elki.parallel.Executor;
+import de.lmu.ifi.dbs.elki.parallel.processor.AbstractDoubleProcessor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedDouble;
+
+/**
+ * Processor for computing the LOF.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has Instance
+ */
+public class LOFProcessor extends AbstractDoubleProcessor {
+ /**
+ * KNN store
+ */
+ private DataStore<? extends KNNList> knns;
+
+ /**
+ * LRD store
+ */
+ private DoubleDataStore lrds;
+
+ /**
+ * Exclude object itself from computation.
+ */
+ private boolean noself;
+
+ /**
+ * Constructor.
+ *
+ * @param knns k nearest neighbors
+ * @param lrds Local reachability distances
+ * @param noself Exclude self from neighbors
+ */
+ public LOFProcessor(DataStore<? extends KNNList> knns, DoubleDataStore lrds, boolean noself) {
+ super();
+ this.knns = knns;
+ this.lrds = lrds;
+ this.noself = noself;
+ }
+
+ @Override
+ public Instance instantiate(Executor master) {
+ return new Instance(master.getInstance(output));
+ }
+
+ /**
+ * Instance
+ *
+ * @author Erich Schubert
+ */
+ private class Instance extends AbstractDoubleProcessor.Instance {
+ /**
+ * Constructor.
+ *
+ * @param output Output variable
+ */
+ protected Instance(SharedDouble.Instance output) {
+ super(output);
+ }
+
+ @Override
+ public void map(DBIDRef id) {
+ // Own density
+ final double lrdp = lrds.doubleValue(id);
+ if (Double.isInfinite(lrdp)) {
+ output.set(1.0);
+ return;
+ }
+ // Compute average neighbor density:
+ KNNList knn = knns.get(id);
+ double avlrd = 0.0;
+ int cnt = 0;
+ for (DBIDIter n = knn.iter(); n.valid(); n.advance()) {
+ if (noself && DBIDUtil.equal(n, id)) {
+ continue;
+ }
+ avlrd += lrds.doubleValue(n);
+ cnt++;
+ if (Double.isInfinite(avlrd)) {
+ break;
+ }
+ }
+ avlrd = (cnt > 0) ? (avlrd / cnt) : 0;
+ output.set(avlrd / lrdp);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/LRDProcessor.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/LRDProcessor.java
new file mode 100644
index 00000000..1b62320a
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/LRDProcessor.java
@@ -0,0 +1,103 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.lof.parallel;
+
+/*
+ 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.database.datastore.DataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.DoubleDataStore;
+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.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.parallel.Executor;
+import de.lmu.ifi.dbs.elki.parallel.processor.AbstractDoubleProcessor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedDouble;
+
+/**
+ * Processor for the "local reachability density" of LOF.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has Instance
+ */
+public class LRDProcessor extends AbstractDoubleProcessor {
+ /**
+ * KNN store
+ */
+ private DataStore<? extends KNNList> knns;
+
+ /**
+ * k-distance store
+ */
+ private DoubleDataStore kdists;
+
+ /**
+ * Constructor.
+ *
+ * @param knns k nearest neighbors
+ * @param kdists k distances
+ */
+ public LRDProcessor(DataStore<? extends KNNList> knns, DoubleDataStore kdists) {
+ super();
+ this.knns = knns;
+ this.kdists = kdists;
+ }
+
+ @Override
+ public Instance instantiate(Executor master) {
+ return new Instance(master.getInstance(output));
+ }
+
+ /**
+ * Instance
+ *
+ * @author Erich Schubert
+ */
+ private class Instance extends AbstractDoubleProcessor.Instance {
+ /**
+ * Constructor.
+ *
+ * @param output Output variable
+ */
+ protected Instance(SharedDouble.Instance output) {
+ super(output);
+ }
+
+ @Override
+ public void map(DBIDRef id) {
+ KNNList knn = knns.get(id);
+ double lrd = 0.0;
+ int size = 0;
+ for(DoubleDBIDListIter n = knn.iter(); n.valid(); n.advance()) {
+ // Do not include the query object
+ if(DBIDUtil.equal(n, id)) {
+ continue;
+ }
+ lrd += Math.max(kdists.doubleValue(n), n.doubleValue());
+ size += 1;
+ }
+ // Avoid division by 0:
+ output.set(lrd > 0 ? size / lrd : Double.POSITIVE_INFINITY);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/ParallelLOF.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/ParallelLOF.java
new file mode 100644
index 00000000..fa851401
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/ParallelLOF.java
@@ -0,0 +1,208 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.lof.parallel;
+
+/*
+ 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.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOF;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+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.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.parallel.ParallelExecutor;
+import de.lmu.ifi.dbs.elki.parallel.processor.DoubleMinMaxProcessor;
+import de.lmu.ifi.dbs.elki.parallel.processor.KDistanceProcessor;
+import de.lmu.ifi.dbs.elki.parallel.processor.KNNProcessor;
+import de.lmu.ifi.dbs.elki.parallel.processor.WriteDataStoreProcessor;
+import de.lmu.ifi.dbs.elki.parallel.processor.WriteDoubleDataStoreProcessor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedDouble;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedObject;
+import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+
+/**
+ * Parallel implementation of Local Outlier Factor using processors.
+ *
+ * This parallelized implementation is based on the easy-to-parallelize
+ * generalized pattern discussed in
+ * <p>
+ * Erich Schubert, Arthur Zimek, Hans-Peter Kriegel<br />
+ * Local Outlier Detection Reconsidered: a Generalized View on Locality with
+ * Applications to Spatial, Video, and Network Outlier Detection<br />
+ * Data Mining and Knowledge Discovery, 28(1): 190–237, 2014.
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has LRDProcessor
+ * @apiviz.has LOFProcessor
+ *
+ * @param <O> Object type
+ */
+@Reference(authors = "E. Schubert, A. Zimek, H.-P. Kriegel", //
+title = "Local Outlier Detection Reconsidered: a Generalized View on Locality with Applications to Spatial, Video, and Network Outlier Detection", //
+booktitle = "Data Mining and Knowledge Discovery, 28(1): 190–237, 2014.", //
+url = "http://dx.doi.org/10.1007/s10618-012-0300-z")
+public class ParallelLOF<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
+ /**
+ * Parameter k
+ */
+ private int k;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function
+ * @param k K parameter
+ */
+ public ParallelLOF(DistanceFunction<? super O> distanceFunction, int k) {
+ super(distanceFunction);
+ this.k = k;
+ }
+
+ /**
+ * Class logger
+ */
+ private static final Logging LOG = Logging.getLogger(ParallelLOF.class);
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
+ }
+
+ public OutlierResult run(Database database, Relation<O> relation) {
+ DBIDs ids = relation.getDBIDs();
+ DistanceQuery<O> distq = database.getDistanceQuery(relation, getDistanceFunction());
+ KNNQuery<O> knnq = database.getKNNQuery(distq, k + 1);
+
+ // Phase one: KNN and k-dist
+ WritableDoubleDataStore kdists = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_DB);
+ WritableDataStore<KNNList> knns = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_DB, KNNList.class);
+ {
+ // Compute kNN
+ KNNProcessor<O> knnm = new KNNProcessor<>(k + 1, knnq);
+ SharedObject<KNNList> knnv = new SharedObject<>();
+ WriteDataStoreProcessor<KNNList> storek = new WriteDataStoreProcessor<>(knns);
+ knnm.connectKNNOutput(knnv);
+ storek.connectInput(knnv);
+ // Compute k-dist
+ KDistanceProcessor kdistm = new KDistanceProcessor(k + 1);
+ SharedDouble kdistv = new SharedDouble();
+ WriteDoubleDataStoreProcessor storem = new WriteDoubleDataStoreProcessor(kdists);
+ kdistm.connectKNNInput(knnv);
+ kdistm.connectOutput(kdistv);
+ storem.connectInput(kdistv);
+
+ ParallelExecutor.run(ids, knnm, storek, kdistm, storem);
+ }
+
+ // Phase two: lrd
+ WritableDoubleDataStore lrds = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_DB);
+ {
+ LRDProcessor lrdm = new LRDProcessor(knns, kdists);
+ SharedDouble lrdv = new SharedDouble();
+ WriteDoubleDataStoreProcessor storelrd = new WriteDoubleDataStoreProcessor(lrds);
+
+ lrdm.connectOutput(lrdv);
+ storelrd.connectInput(lrdv);
+ ParallelExecutor.run(ids, lrdm, storelrd);
+ }
+ kdists.destroy(); // No longer needed.
+ kdists = null;
+
+ // Phase three: LOF
+ WritableDoubleDataStore lofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_DB);
+ DoubleMinMax minmax;
+ {
+ LOFProcessor lofm = new LOFProcessor(knns, lrds, true);
+ SharedDouble lofv = new SharedDouble();
+ DoubleMinMaxProcessor mmm = new DoubleMinMaxProcessor();
+ WriteDoubleDataStoreProcessor storelof = new WriteDoubleDataStoreProcessor(lofs);
+
+ lofm.connectOutput(lofv);
+ mmm.connectInput(lofv);
+ storelof.connectInput(lofv);
+ ParallelExecutor.run(ids, lofm, storelof, mmm);
+
+ minmax = mmm.getMinMax();
+ }
+
+ DoubleRelation scoreres = new MaterializedDoubleRelation("Local Outlier Factor", "lof-outlier", lofs, ids);
+ OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 1.0);
+ return new OutlierResult(meta, scoreres);
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <O> Object type
+ */
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * K parameter
+ */
+ int k;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ IntParameter kP = new IntParameter(LOF.Parameterizer.K_ID);
+ if(config.grab(kP)) {
+ k = kP.intValue();
+ }
+ }
+
+ @Override
+ protected ParallelLOF<O> makeInstance() {
+ return new ParallelLOF<>(distanceFunction, k);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/ParallelSimplifiedLOF.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/ParallelSimplifiedLOF.java
new file mode 100644
index 00000000..ef67023e
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/ParallelSimplifiedLOF.java
@@ -0,0 +1,197 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.lof.parallel;
+
+/*
+ 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.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOF;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+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.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.parallel.ParallelExecutor;
+import de.lmu.ifi.dbs.elki.parallel.processor.DoubleMinMaxProcessor;
+import de.lmu.ifi.dbs.elki.parallel.processor.KNNProcessor;
+import de.lmu.ifi.dbs.elki.parallel.processor.WriteDataStoreProcessor;
+import de.lmu.ifi.dbs.elki.parallel.processor.WriteDoubleDataStoreProcessor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedDouble;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedObject;
+import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+
+/**
+ * Parallel implementation of Simplified-LOF Outlier detection using processors.
+ *
+ * This parallelized implementation is based on the easy-to-parallelize
+ * generalized pattern discussed in
+ * <p>
+ * Erich Schubert, Arthur Zimek, Hans-Peter Kriegel<br />
+ * Local Outlier Detection Reconsidered: a Generalized View on Locality with
+ * Applications to Spatial, Video, and Network Outlier Detection<br />
+ * Data Mining and Knowledge Discovery, 28(1): 190–237, 2014.
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has SimplifiedLRDProcessor
+ * @apiviz.has LOFProcessor
+ *
+ * @param <O> Object type
+ */
+@Reference(authors = "E. Schubert, A. Zimek, H.-P. Kriegel", //
+title = "Local Outlier Detection Reconsidered: a Generalized View on Locality with Applications to Spatial, Video, and Network Outlier Detection", //
+booktitle = "Data Mining and Knowledge Discovery, 28(1): 190–237, 2014.", //
+url = "http://dx.doi.org/10.1007/s10618-012-0300-z")
+public class ParallelSimplifiedLOF<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
+ /**
+ * Parameter k
+ */
+ private int k;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function
+ * @param k K parameter
+ */
+ public ParallelSimplifiedLOF(DistanceFunction<? super O> distanceFunction, int k) {
+ super(distanceFunction);
+ this.k = k;
+ }
+
+ /**
+ * Class logger
+ */
+ private static final Logging LOG = Logging.getLogger(ParallelSimplifiedLOF.class);
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(getDistanceFunction().getInputTypeRestriction());
+ }
+
+ public OutlierResult run(Database database, Relation<O> relation) {
+ DBIDs ids = relation.getDBIDs();
+ DistanceQuery<O> distq = database.getDistanceQuery(relation, getDistanceFunction());
+ KNNQuery<O> knnq = database.getKNNQuery(distq, k + 1);
+
+ // Phase one: KNN and k-dist
+ WritableDataStore<KNNList> knns = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_DB, KNNList.class);
+ {
+ // Compute kNN
+ KNNProcessor<O> knnm = new KNNProcessor<>(k + 1, knnq);
+ SharedObject<KNNList> knnv = new SharedObject<>();
+ WriteDataStoreProcessor<KNNList> storek = new WriteDataStoreProcessor<>(knns);
+ knnm.connectKNNOutput(knnv);
+ storek.connectInput(knnv);
+
+ ParallelExecutor.run(ids, knnm, storek);
+ }
+
+ // Phase two: simplified-lrd
+ WritableDoubleDataStore lrds = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_DB);
+ {
+ SimplifiedLRDProcessor lrdm = new SimplifiedLRDProcessor(knns);
+ SharedDouble lrdv = new SharedDouble();
+ WriteDoubleDataStoreProcessor storelrd = new WriteDoubleDataStoreProcessor(lrds);
+
+ lrdm.connectOutput(lrdv);
+ storelrd.connectInput(lrdv);
+ ParallelExecutor.run(ids, lrdm, storelrd);
+ }
+
+ // Phase three: Simplified-LOF
+ WritableDoubleDataStore lofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_DB);
+ DoubleMinMax minmax;
+ {
+ LOFProcessor lofm = new LOFProcessor(knns, lrds, true);
+ SharedDouble lofv = new SharedDouble();
+ DoubleMinMaxProcessor mmm = new DoubleMinMaxProcessor();
+ WriteDoubleDataStoreProcessor storelof = new WriteDoubleDataStoreProcessor(lofs);
+
+ lofm.connectOutput(lofv);
+ mmm.connectInput(lofv);
+ storelof.connectInput(lofv);
+ ParallelExecutor.run(ids, lofm, storelof, mmm);
+
+ minmax = mmm.getMinMax();
+ }
+
+ DoubleRelation scoreres = new MaterializedDoubleRelation("Simplified Local Outlier Factor", "simplified-lof-outlier", lofs, ids);
+ OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 1.0);
+ return new OutlierResult(meta, scoreres);
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <O> Object type
+ */
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * K parameter
+ */
+ int k;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ IntParameter kP = new IntParameter(LOF.Parameterizer.K_ID);
+ if(config.grab(kP)) {
+ k = kP.getValue();
+ }
+ }
+
+ @Override
+ protected ParallelSimplifiedLOF<O> makeInstance() {
+ return new ParallelSimplifiedLOF<>(distanceFunction, k);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/SimplifiedLRDProcessor.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/SimplifiedLRDProcessor.java
new file mode 100644
index 00000000..4698ae6a
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/SimplifiedLRDProcessor.java
@@ -0,0 +1,97 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.lof.parallel;
+
+/*
+ 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.database.datastore.DataStore;
+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.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.parallel.Executor;
+import de.lmu.ifi.dbs.elki.parallel.processor.AbstractDoubleProcessor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedDouble;
+
+/**
+ * Processor for the "local reachability density" of LOF.
+ *
+ * Note: we compute 1/lrd, the local reachability distance.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has Instance
+ */
+public class SimplifiedLRDProcessor extends AbstractDoubleProcessor {
+ /**
+ * KNN store
+ */
+ private DataStore<? extends KNNList> knns;
+
+ /**
+ * Constructor.
+ *
+ * @param knns k nearest neighbors
+ */
+ public SimplifiedLRDProcessor(DataStore<? extends KNNList> knns) {
+ super();
+ this.knns = knns;
+ }
+
+ @Override
+ public Instance instantiate(Executor master) {
+ return new Instance(master.getInstance(output));
+ }
+
+ /**
+ * Instance
+ *
+ * @author Erich Schubert
+ */
+ private class Instance extends AbstractDoubleProcessor.Instance {
+ /**
+ * Constructor.
+ *
+ * @param output Output variable
+ */
+ public Instance(SharedDouble.Instance output) {
+ super(output);
+ }
+
+ @Override
+ public void map(DBIDRef id) {
+ KNNList knn = knns.get(id);
+ double lrd = 0.0;
+ int size = 0;
+ for(DoubleDBIDListIter n = knn.iter(); n.valid(); n.advance()) {
+ // Do not include the query object
+ if(DBIDUtil.equal(n, id)) {
+ continue;
+ }
+ lrd += n.doubleValue();
+ size++;
+ }
+ // Avoid division by zero.
+ output.set(lrd > 0 ? size / lrd : 0);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/package-info.java
new file mode 100644
index 00000000..3d708b4c
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/parallel/package-info.java
@@ -0,0 +1,44 @@
+/**
+ * Parallelized variants of LOF.
+ *
+ * This parallelization is based on the generalization of outlier detection published in:
+ *
+ * Reference:
+ * <p>
+ * Erich Schubert, Arthur Zimek, Hans-Peter Kriegel<br />
+ * Local Outlier Detection Reconsidered: a Generalized View on Locality with
+ * Applications to Spatial, Video, and Network Outlier Detection<br />
+ * Data Mining and Knowledge Discovery, 28(1): 190–237, 2014.
+ * </p>
+ */
+/*
+ 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/>.
+ */
+
+@Reference(authors = "E. Schubert, A. Zimek, H.-P. Kriegel", //
+title = "Local Outlier Detection Reconsidered: a Generalized View on Locality with Applications to Spatial, Video, and Network Outlier Detection", //
+booktitle = "Data Mining and Knowledge Discovery, 28(1): 190–237, 2014.", //
+url = "http://dx.doi.org/10.1007/s10618-012-0300-z")
+package de.lmu.ifi.dbs.elki.algorithm.outlier.lof.parallel;
+
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/ExternalDoubleOutlierScore.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/ExternalDoubleOutlierScore.java
index 757b80ad..f0ada6a8 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/ExternalDoubleOutlierScore.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/ExternalDoubleOutlierScore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.meta;
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
@@ -42,7 +42,8 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.datasource.parser.AbstractParser;
import de.lmu.ifi.dbs.elki.logging.Logging;
@@ -203,7 +204,7 @@ public class ExternalDoubleOutlierScore extends AbstractAlgorithm<OutlierResult>
else {
meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax());
}
- Relation<Double> scoresult = new MaterializedRelation<>("External Outlier", "external-outlier", TypeUtil.DOUBLE, scores, relation.getDBIDs());
+ DoubleRelation scoresult = new MaterializedDoubleRelation("External Outlier", "external-outlier", scores, relation.getDBIDs());
OutlierResult or = new OutlierResult(meta, scoresult);
// Apply scaling
@@ -212,7 +213,7 @@ public class ExternalDoubleOutlierScore extends AbstractAlgorithm<OutlierResult>
}
DoubleMinMax mm = new DoubleMinMax();
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- double val = scoresult.get(iditer);
+ double val = scoresult.doubleValue(iditer);
val = scaling.getScaled(val);
scores.putDouble(iditer, val);
mm.put(val);
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/FeatureBagging.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/FeatureBagging.java
index 5b681106..a5eb0c7a 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/FeatureBagging.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/FeatureBagging.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.meta;
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.algorithm.outlier.meta;
*/
import java.util.ArrayList;
-import java.util.BitSet;
import java.util.Random;
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
@@ -38,18 +37,19 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.distancefunction.subspace.SubspaceEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
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;
@@ -131,7 +131,7 @@ public class FeatureBagging extends AbstractAlgorithm<OutlierResult> implements
* @param relation Relation to use
* @return Outlier detection result
*/
- public OutlierResult run(Database database, Relation<NumberVector<?>> relation) {
+ public OutlierResult run(Database database, Relation<NumberVector> relation) {
final int dbdim = RelationUtil.dimensionality(relation);
final int mindim = dbdim >> 1;
final int maxdim = dbdim - 1;
@@ -141,34 +141,30 @@ public class FeatureBagging extends AbstractAlgorithm<OutlierResult> implements
{
FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("LOF iterations", num, LOG) : null;
for(int i = 0; i < num; i++) {
- BitSet dimset = randomSubspace(dbdim, mindim, maxdim, rand);
+ long[] dimset = randomSubspace(dbdim, mindim, maxdim, rand);
SubspaceEuclideanDistanceFunction df = new SubspaceEuclideanDistanceFunction(dimset);
- LOF<NumberVector<?>, DoubleDistance> lof = new LOF<>(k, df);
+ LOF<NumberVector> lof = new LOF<>(k, df);
// run LOF and collect the result
OutlierResult result = lof.run(database, relation);
results.add(result);
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if(prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
}
WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
DoubleMinMax minmax = new DoubleMinMax();
if(breadth) {
FiniteProgress cprog = LOG.isVerbose() ? new FiniteProgress("Combining results", relation.size(), LOG) : null;
- Pair<DBIDIter, Relation<Double>>[] IDVectorOntoScoreVector = Pair.newPairArray(results.size());
+ Pair<DBIDIter, DoubleRelation>[] IDVectorOntoScoreVector = Pair.newPairArray(results.size());
// Mapping score-sorted DBID-Iterators onto their corresponding scores.
// We need to initialize them now be able to iterate them "in parallel".
{
int i = 0;
for(OutlierResult r : results) {
- IDVectorOntoScoreVector[i] = new Pair<DBIDIter, Relation<Double>>(r.getOrdering().iter(relation.getDBIDs()).iter(), r.getScores());
+ IDVectorOntoScoreVector[i] = new Pair<DBIDIter, DoubleRelation>(r.getOrdering().iter(relation.getDBIDs()).iter(), r.getScores());
i++;
}
}
@@ -176,12 +172,12 @@ public class FeatureBagging extends AbstractAlgorithm<OutlierResult> implements
// Iterating over the *lines* of the AS_t(i)-matrix.
for(int i = 0; i < relation.size(); i++) {
// Iterating over the elements of a line (breadth-first).
- for(Pair<DBIDIter, Relation<Double>> pair : IDVectorOntoScoreVector) {
+ for(Pair<DBIDIter, DoubleRelation> pair : IDVectorOntoScoreVector) {
DBIDIter iter = pair.first;
// Always true if every algorithm returns a complete result (one score
// for every DBID).
if(iter.valid()) {
- double score = pair.second.get(iter);
+ double score = pair.second.doubleValue(iter);
if(Double.isNaN(scores.doubleValue(iter))) {
scores.putDouble(iter, score);
minmax.put(score);
@@ -193,36 +189,28 @@ public class FeatureBagging extends AbstractAlgorithm<OutlierResult> implements
}
}
// Progress does not take the initial mapping into account.
- if(cprog != null) {
- cprog.incrementProcessed(LOG);
- }
- }
- if(cprog != null) {
- cprog.ensureCompleted(LOG);
+ LOG.incrementProcessed(cprog);
}
+ LOG.ensureCompleted(cprog);
}
else {
FiniteProgress cprog = LOG.isVerbose() ? new FiniteProgress("Combining results", relation.size(), LOG) : null;
for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
double sum = 0.0;
for(OutlierResult r : results) {
- final Double s = r.getScores().get(iter);
- if(s != null && !Double.isNaN(s)) {
+ final double s = r.getScores().doubleValue(iter);
+ if(!Double.isNaN(s)) {
sum += s;
}
}
scores.putDouble(iter, sum);
minmax.put(sum);
- if(cprog != null) {
- cprog.incrementProcessed(LOG);
- }
- }
- if(cprog != null) {
- cprog.ensureCompleted(LOG);
+ LOG.incrementProcessed(cprog);
}
+ LOG.ensureCompleted(cprog);
}
OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax());
- Relation<Double> scoreres = new MaterializedRelation<>("Feature bagging", "fb-outlier", TypeUtil.DOUBLE, scores, relation.getDBIDs());
+ DoubleRelation scoreres = new MaterializedDoubleRelation("Feature bagging", "fb-outlier", scores, relation.getDBIDs());
return new OutlierResult(meta, scoreres);
}
@@ -234,8 +222,8 @@ public class FeatureBagging extends AbstractAlgorithm<OutlierResult> implements
* @param maxdim Maximum number to choose
* @return Subspace as bits.
*/
- private BitSet randomSubspace(final int alldim, final int mindim, final int maxdim, final Random rand) {
- BitSet dimset = new BitSet();
+ private long[] randomSubspace(final int alldim, final int mindim, final int maxdim, final Random rand) {
+ long[] dimset = BitsUtil.zero(alldim);
// Fill with all dimensions
int[] dims = new int[alldim];
for(int d = 0; d < alldim; d++) {
@@ -246,7 +234,7 @@ public class FeatureBagging extends AbstractAlgorithm<OutlierResult> implements
// Shrink the subspace to the destination size
for(int d = 0; d < alldim - subdim; d++) {
int s = rand.nextInt(alldim - d);
- dimset.set(dims[s]);
+ BitsUtil.setI(dimset, dims[s]);
dims[s] = dims[alldim - d - 1];
}
return dimset;
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/HiCS.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/HiCS.java
index f92a8b80..4858e0df 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/HiCS.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/HiCS.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.meta;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -51,7 +51,8 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.ProjectedView;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
@@ -59,12 +60,12 @@ import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.math.statistics.tests.GoodnessOfFitTest;
import de.lmu.ifi.dbs.elki.math.statistics.tests.KolmogorovSmirnovTest;
import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.TopBoundedHeap;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
@@ -102,7 +103,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
@Title("HiCS: High Contrast Subspaces for Density-Based Outlier Ranking")
@Description("Algorithm to compute High Contrast Subspaces in a database as a pre-processing step for for density-based outlier ranking methods.")
@Reference(authors = "Fabian Keller, Emmanuel Müller, Klemens Böhm", title = "HiCS: High Contrast Subspaces for Density-Based Outlier Ranking", booktitle = "Proc. IEEE 28th International Conference on Data Engineering (ICDE 2012)", url = "http://dx.doi.org/10.1109/ICDE.2012.88")
-public class HiCS<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
+public class HiCS<V extends NumberVector> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
/**
* The Logger for this class.
*/
@@ -179,7 +180,7 @@ public class HiCS<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
if(LOG.isVerbose()) {
LOG.verbose("Number of high-contrast subspaces: " + subspaces.size());
}
- List<Relation<Double>> results = new ArrayList<>();
+ List<DoubleRelation> results = new ArrayList<>();
FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Calculating Outlier scores for high Contrast subspaces", subspaces.size(), LOG) : null;
// run outlier detection and collect the result
@@ -196,22 +197,18 @@ public class HiCS<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
// run LOF and collect the result
OutlierResult result = outlierAlgorithm.run(pdb);
results.add(result.getScores());
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if(prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
DoubleMinMax minmax = new DoubleMinMax();
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
double sum = 0.0;
- for(Relation<Double> r : results) {
- final Double s = r.get(iditer);
- if(s != null && !Double.isNaN(s)) {
+ for(DoubleRelation r : results) {
+ final double s = r.doubleValue(iditer);
+ if(!Double.isNaN(s)) {
sum += s;
}
}
@@ -219,7 +216,7 @@ public class HiCS<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
minmax.put(sum);
}
OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax());
- Relation<Double> scoreres = new MaterializedRelation<>("HiCS", "HiCS-outlier", TypeUtil.DOUBLE, scores, relation.getDBIDs());
+ DoubleRelation scoreres = new MaterializedDoubleRelation("HiCS", "HiCS-outlier", scores, relation.getDBIDs());
return new OutlierResult(meta, scoreres);
}
@@ -232,7 +229,7 @@ public class HiCS<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
* @param relation Relation to index
* @return List of sorted objects
*/
- private ArrayList<ArrayDBIDs> buildOneDimIndexes(Relation<? extends NumberVector<?>> relation) {
+ private ArrayList<ArrayDBIDs> buildOneDimIndexes(Relation<? extends NumberVector> relation) {
final int dim = RelationUtil.dimensionality(relation);
ArrayList<ArrayDBIDs> subspaceIndex = new ArrayList<>(dim + 1);
@@ -254,7 +251,7 @@ public class HiCS<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
* @param subspaceIndex Subspace indexes
* @return a set of high contrast subspaces
*/
- private Set<HiCSSubspace> calculateSubspaces(Relation<? extends NumberVector<?>> relation, ArrayList<ArrayDBIDs> subspaceIndex, Random random) {
+ private Set<HiCSSubspace> calculateSubspaces(Relation<? extends NumberVector> relation, ArrayList<ArrayDBIDs> subspaceIndex, Random random) {
final int dbdim = RelationUtil.dimensionality(relation);
FiniteProgress dprog = LOG.isVerbose() ? new FiniteProgress("Subspace dimensionality", dbdim, LOG) : null;
@@ -273,14 +270,10 @@ public class HiCS<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
ts.set(j);
calculateContrast(relation, ts, subspaceIndex, random);
dDimensionalList.add(ts);
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
}
}
- if(prog != null) {
- prog.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(prog);
IndefiniteProgress qprog = LOG.isVerbose() ? new IndefiniteProgress("Testing subspace candidates", LOG) : null;
for(int d = 3; !dDimensionalList.isEmpty(); d++) {
@@ -313,9 +306,7 @@ public class HiCS<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
calculateContrast(relation, joinedSet, subspaceIndex, random);
dDimensionalList.add(joinedSet);
- if(qprog != null) {
- qprog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(qprog);
}
}
// Prune
@@ -328,9 +319,7 @@ public class HiCS<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
}
}
}
- if(qprog != null) {
- qprog.setCompleted(LOG);
- }
+ LOG.setCompleted(qprog);
if(dprog != null) {
dprog.setProcessed(dbdim, LOG);
dprog.ensureCompleted(LOG);
@@ -345,7 +334,7 @@ public class HiCS<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
* @param subspace Subspace
* @param subspaceIndex Subspace indexes
*/
- private void calculateContrast(Relation<? extends NumberVector<?>> relation, HiCSSubspace subspace, ArrayList<ArrayDBIDs> subspaceIndex, Random random) {
+ private void calculateContrast(Relation<? extends NumberVector> relation, HiCSSubspace subspace, ArrayList<ArrayDBIDs> subspaceIndex, Random random) {
final int card = subspace.cardinality();
final double alpha1 = Math.pow(alpha, (1.0 / card));
final int windowsize = (int) (relation.size() * alpha1);
@@ -415,13 +404,9 @@ public class HiCS<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
continue;
}
deviationSum += contrast;
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if(prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
subspace.contrast = deviationSum / m;
}
@@ -530,7 +515,7 @@ public class HiCS<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierRe
*
* @param <V> vector type
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* Parameter that specifies the number of iterations in the Monte-Carlo
* process of identifying high contrast subspaces.
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/RescaleMetaOutlierAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/RescaleMetaOutlierAlgorithm.java
index 8ebdc27a..885ef1df 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/RescaleMetaOutlierAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/RescaleMetaOutlierAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.meta;
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,14 +29,13 @@ import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.Algorithm;
import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
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.Database;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.result.Result;
@@ -100,7 +99,7 @@ public class RescaleMetaOutlierAlgorithm extends AbstractAlgorithm<OutlierResult
Result innerresult = algorithm.run(database);
OutlierResult or = getOutlierResult(innerresult);
- final Relation<Double> scores = or.getScores();
+ final DoubleRelation scores = or.getScores();
if(scaling instanceof OutlierScalingFunction) {
((OutlierScalingFunction) scaling).prepare(or);
}
@@ -109,13 +108,13 @@ public class RescaleMetaOutlierAlgorithm extends AbstractAlgorithm<OutlierResult
DoubleMinMax minmax = new DoubleMinMax();
for(DBIDIter iditer = scores.iterDBIDs(); iditer.valid(); iditer.advance()) {
- double val = scaling.getScaled(scores.get(iditer));
+ double val = scaling.getScaled(scores.doubleValue(iditer));
scaledscores.putDouble(iditer, val);
minmax.put(val);
}
OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), scaling.getMin(), scaling.getMax());
- Relation<Double> scoresult = new MaterializedRelation<>("Scaled Outlier", "scaled-outlier", TypeUtil.DOUBLE, scaledscores, scores.getDBIDs());
+ DoubleRelation scoresult = new MaterializedDoubleRelation("Scaled Outlier", "scaled-outlier", scaledscores, scores.getDBIDs());
OutlierResult result = new OutlierResult(meta, scoresult);
result.addChildResult(innerresult);
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/SimpleOutlierEnsemble.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/SimpleOutlierEnsemble.java
index d40af384..c255a8b0 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/SimpleOutlierEnsemble.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/SimpleOutlierEnsemble.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.meta;
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,8 +40,8 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
@@ -111,13 +111,9 @@ public class SimpleOutlierEnsemble extends AbstractAlgorithm<OutlierResult> impl
results.add(or);
ids.addDBIDs(or.getScores().getDBIDs());
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if (prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
}
// Combine
WritableDoubleDataStore sumscore = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC);
@@ -128,8 +124,8 @@ public class SimpleOutlierEnsemble extends AbstractAlgorithm<OutlierResult> impl
double[] scores = new double[num];
int i = 0;
for (OutlierResult r : results) {
- Double score = r.getScores().get(id);
- if (score != null) {
+ double score = r.getScores().doubleValue(id);
+ if (!Double.isNaN(score)) {
scores[i] = score;
i++;
} else {
@@ -147,16 +143,12 @@ public class SimpleOutlierEnsemble extends AbstractAlgorithm<OutlierResult> impl
} else {
LOG.warning("DBID " + id + " was not given any score at all.");
}
- if (cprog != null) {
- cprog.incrementProcessed(LOG);
- }
- }
- if (cprog != null) {
- cprog.ensureCompleted(LOG);
+ LOG.incrementProcessed(cprog);
}
+ LOG.ensureCompleted(cprog);
}
OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax());
- Relation<Double> scores = new MaterializedRelation<>("Simple Outlier Ensemble", "ensemble-outlier", TypeUtil.DOUBLE, sumscore, ids);
+ DoubleRelation scores = new MaterializedDoubleRelation("Simple Outlier Ensemble", "ensemble-outlier", sumscore, ids);
return new OutlierResult(meta, scores);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/package-info.java
index f28f8db3..2e9743b9 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/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/algorithm/outlier/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/package-info.java
index 0ce6f9b5..aa6da5cf 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/package-info.java
@@ -14,7 +14,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/algorithm/outlier/spatial/AbstractDistanceBasedSpatialOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/AbstractDistanceBasedSpatialOutlier.java
index e059c16c..a501e00f 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/AbstractDistanceBasedSpatialOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/AbstractDistanceBasedSpatialOutlier.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial;
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.algorithm.outlier.spatial.neighborhood.NeighborSetPre
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
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;
@@ -39,9 +38,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @param <N> Object type for neighborhood
* @param <O> Non-spatial object type
- * @param <D> Distance value type
*/
-public abstract class AbstractDistanceBasedSpatialOutlier<N, O, D extends NumberDistance<D, ?>> extends AbstractNeighborhoodOutlier<N> {
+public abstract class AbstractDistanceBasedSpatialOutlier<N, O> extends AbstractNeighborhoodOutlier<N> {
/**
* Parameter to specify the non spatial distance function to use
*/
@@ -50,7 +48,7 @@ public abstract class AbstractDistanceBasedSpatialOutlier<N, O, D extends Number
/**
* The distance function to use
*/
- private DistanceFunction<O, D> nonSpatialDistanceFunction;
+ private DistanceFunction<O> nonSpatialDistanceFunction;
/**
* Constructor.
@@ -59,7 +57,7 @@ public abstract class AbstractDistanceBasedSpatialOutlier<N, O, D extends Number
* @param nonSpatialDistanceFunction Distance function to use on the
* non-spatial attributes.
*/
- public AbstractDistanceBasedSpatialOutlier(NeighborSetPredicate.Factory<N> npredf, DistanceFunction<O, D> nonSpatialDistanceFunction) {
+ public AbstractDistanceBasedSpatialOutlier(NeighborSetPredicate.Factory<N> npredf, DistanceFunction<O> nonSpatialDistanceFunction) {
super(npredf);
this.nonSpatialDistanceFunction = nonSpatialDistanceFunction;
}
@@ -69,7 +67,7 @@ public abstract class AbstractDistanceBasedSpatialOutlier<N, O, D extends Number
*
* @return the distance function to use on the non-spatial attributes
*/
- protected DistanceFunction<O, D> getNonSpatialDistanceFunction() {
+ protected DistanceFunction<O> getNonSpatialDistanceFunction() {
return nonSpatialDistanceFunction;
}
@@ -82,18 +80,17 @@ public abstract class AbstractDistanceBasedSpatialOutlier<N, O, D extends Number
*
* @param <N> Object type for neighborhood
* @param <O> Non-spatial object type
- * @param <D> Distance value type
*/
- public abstract static class Parameterizer<N, O, D extends NumberDistance<D, ?>> extends AbstractNeighborhoodOutlier.Parameterizer<N> {
+ public abstract static class Parameterizer<N, O> extends AbstractNeighborhoodOutlier.Parameterizer<N> {
/**
* The distance function to use on the non-spatial attributes.
*/
- protected PrimitiveDistanceFunction<O, D> distanceFunction = null;
+ protected PrimitiveDistanceFunction<O> distanceFunction = null;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- ObjectParameter<PrimitiveDistanceFunction<O, D>> distanceFunctionP = makeParameterDistanceFunction(EuclideanDistanceFunction.class, PrimitiveDistanceFunction.class);
+ ObjectParameter<PrimitiveDistanceFunction<O>> distanceFunctionP = makeParameterDistanceFunction(EuclideanDistanceFunction.class, PrimitiveDistanceFunction.class);
if(config.grab(distanceFunctionP)) {
distanceFunction = distanceFunctionP.instantiateClass(config);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/AbstractNeighborhoodOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/AbstractNeighborhoodOutlier.java
index 3b3e71b3..95516a99 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/AbstractNeighborhoodOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/AbstractNeighborhoodOutlier.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial;
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/algorithm/outlier/spatial/CTLuGLSBackwardSearchAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuGLSBackwardSearchAlgorithm.java
index 5035cf6f..debf0ee2 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuGLSBackwardSearchAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuGLSBackwardSearchAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial;
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
@@ -37,15 +37,15 @@ import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.ProxyView;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
@@ -81,11 +81,10 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
* @author Ahmed Hettab
*
* @param <V> Vector type to use for distances
- * @param <D> Distance function to use
*/
@Title("GLS-Backward Search")
@Reference(authors = "F. Chen and C.-T. Lu and A. P. Boedihardjo", title = "GLS-SOD: A Generalized Local Statistical Approach for Spatial Outlier Detection", booktitle = "Proc. 16th ACM SIGKDD international conference on Knowledge discovery and data mining", url = "http://dx.doi.org/10.1145/1835804.1835939")
-public class CTLuGLSBackwardSearchAlgorithm<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<V, D, OutlierResult> implements OutlierAlgorithm {
+public class CTLuGLSBackwardSearchAlgorithm<V extends NumberVector> extends AbstractDistanceBasedAlgorithm<V, OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -108,7 +107,7 @@ public class CTLuGLSBackwardSearchAlgorithm<V extends NumberVector<?>, D extends
* @param k number of nearest neighbors to use
* @param alpha Significance niveau
*/
- public CTLuGLSBackwardSearchAlgorithm(DistanceFunction<V, D> distanceFunction, int k, double alpha) {
+ public CTLuGLSBackwardSearchAlgorithm(DistanceFunction<V> distanceFunction, int k, double alpha) {
super(distanceFunction);
this.alpha = alpha;
this.k = k;
@@ -122,7 +121,7 @@ public class CTLuGLSBackwardSearchAlgorithm<V extends NumberVector<?>, D extends
* @param relationy Attribute relation
* @return Algorithm result
*/
- public OutlierResult run(Database database, Relation<V> relationx, Relation<? extends NumberVector<?>> relationy) {
+ public OutlierResult run(Database database, Relation<V> relationx, Relation<? extends NumberVector> relationy) {
WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relationx.getDBIDs(), DataStoreFactory.HINT_STATIC);
DoubleMinMax mm = new DoubleMinMax(0.0, 0.0);
@@ -151,7 +150,7 @@ public class CTLuGLSBackwardSearchAlgorithm<V extends NumberVector<?>, D extends
}
}
- Relation<Double> scoreResult = new MaterializedRelation<>("GLSSODBackward", "GLSSODbackward-outlier", TypeUtil.DOUBLE, scores, relationx.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("GLSSODBackward", "GLSSODbackward-outlier", scores, relationx.getDBIDs());
OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(mm.getMin(), mm.getMax(), 0, Double.POSITIVE_INFINITY, 0);
return new OutlierResult(scoreMeta, scoreResult);
}
@@ -163,11 +162,11 @@ public class CTLuGLSBackwardSearchAlgorithm<V extends NumberVector<?>, D extends
* @param relationy Attribute relation
* @return Top outlier and associated score
*/
- private Pair<DBIDVar, Double> singleIteration(Relation<V> relationx, Relation<? extends NumberVector<?>> relationy) {
+ private Pair<DBIDVar, Double> singleIteration(Relation<V> relationx, Relation<? extends NumberVector> relationy) {
final int dim = RelationUtil.dimensionality(relationx);
final int dimy = RelationUtil.dimensionality(relationy);
assert (dim == 2);
- KNNQuery<V, D> knnQuery = QueryUtil.getKNNQuery(relationx, getDistanceFunction(), k + 1);
+ KNNQuery<V> knnQuery = QueryUtil.getKNNQuery(relationx, getDistanceFunction(), k + 1);
// We need stable indexed DBIDs
ArrayModifiableDBIDs ids = DBIDUtil.newArray(relationx.getDBIDs());
@@ -196,7 +195,7 @@ public class CTLuGLSBackwardSearchAlgorithm<V extends NumberVector<?>, D extends
}
{
- final NumberVector<?> vecy = relationy.get(id);
+ final NumberVector vecy = relationy.get(id);
for(int d = 0; d < dimy; d++) {
double idy = vecy.doubleValue(d);
Y.set(i, d, idy);
@@ -205,7 +204,7 @@ public class CTLuGLSBackwardSearchAlgorithm<V extends NumberVector<?>, D extends
// Fill the neighborhood matrix F:
{
- KNNList<D> neighbors = knnQuery.getKNNForDBID(id, k + 1);
+ KNNList neighbors = knnQuery.getKNNForDBID(id, k + 1);
ModifiableDBIDs neighborhood = DBIDUtil.newArray(neighbors.size());
for(DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
if(DBIDUtil.equal(id, neighbor)) {
@@ -272,9 +271,8 @@ public class CTLuGLSBackwardSearchAlgorithm<V extends NumberVector<?>, D extends
* @apiviz.exclude
*
* @param <V> Input vector type
- * @param <D> Distance type
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<V, D> {
+ public static class Parameterizer<V extends NumberVector> extends AbstractDistanceBasedAlgorithm.Parameterizer<V> {
/**
* Holds the alpha value - significance niveau
*/
@@ -303,7 +301,7 @@ public class CTLuGLSBackwardSearchAlgorithm<V extends NumberVector<?>, D extends
}
@Override
- protected CTLuGLSBackwardSearchAlgorithm<V, D> makeInstance() {
+ protected CTLuGLSBackwardSearchAlgorithm<V> makeInstance() {
return new CTLuGLSBackwardSearchAlgorithm<>(distanceFunction, k, alpha);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMeanMultipleAttributes.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMeanMultipleAttributes.java
index 1712dd4f..151fe129 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMeanMultipleAttributes.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMeanMultipleAttributes.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial;
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
@@ -33,11 +33,13 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Centroid;
import de.lmu.ifi.dbs.elki.math.linearalgebra.CovarianceMatrix;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
@@ -61,7 +63,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* <p>
* Implementation note: attribute standardization is not used; this is
* equivalent to using the
- * {@link de.lmu.ifi.dbs.elki.datasource.filter.normalization.AttributeWiseVarianceNormalization
+ * {@link de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise.AttributeWiseVarianceNormalization
* AttributeWiseVarianceNormalization} filter.
* </p>
*
@@ -71,7 +73,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* @param <O> Attribute Vector
*/
@Reference(authors = "Chang-Tien Lu and Dechang Chen and Yufeng Kou", title = "Detecting Spatial Outliers with Multiple Attributes", booktitle = "Proc. 15th IEEE International Conference on Tools with Artificial Intelligence, 2003", url = "http://dx.doi.org/10.1109/TAI.2003.1250179")
-public class CTLuMeanMultipleAttributes<N, O extends NumberVector<?>> extends AbstractNeighborhoodOutlier<N> {
+public class CTLuMeanMultipleAttributes<N, O extends NumberVector> extends AbstractNeighborhoodOutlier<N> {
/**
* logger
*/
@@ -118,13 +120,12 @@ public class CTLuMeanMultipleAttributes<N, O extends NumberVector<?>> extends Ab
DoubleMinMax minmax = new DoubleMinMax();
WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(attributes.getDBIDs(), DataStoreFactory.HINT_STATIC);
for(DBIDIter iditer = attributes.iterDBIDs(); iditer.valid(); iditer.advance()) {
- Vector temp = deltas.get(iditer).minus(mean);
- final double score = temp.transposeTimesTimes(cmati, temp);
+ final double score = MathUtil.mahalanobisDistance(cmati, deltas.get(iditer), mean);
minmax.put(score);
scores.putDouble(iditer, score);
}
- Relation<Double> scoreResult = new MaterializedRelation<>("mean multiple attributes spatial outlier", "mean-multipleattributes-outlier", TypeUtil.DOUBLE, scores, attributes.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("mean multiple attributes spatial outlier", "mean-multipleattributes-outlier", scores, attributes.getDBIDs());
OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 0);
OutlierResult or = new OutlierResult(scoreMeta, scoreResult);
or.addChildResult(npred);
@@ -146,7 +147,7 @@ public class CTLuMeanMultipleAttributes<N, O extends NumberVector<?>> extends Ab
* @param <N> Neighborhood type
* @param <O> Attribute object type
*/
- public static class Parameterizer<N, O extends NumberVector<?>> extends AbstractNeighborhoodOutlier.Parameterizer<N> {
+ public static class Parameterizer<N, O extends NumberVector> extends AbstractNeighborhoodOutlier.Parameterizer<N> {
@Override
protected CTLuMeanMultipleAttributes<N, O> makeInstance() {
return new CTLuMeanMultipleAttributes<>(npredf);
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMedianAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMedianAlgorithm.java
index 9848d664..4d5afdd0 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMedianAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMedianAlgorithm.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -27,14 +27,14 @@ import de.lmu.ifi.dbs.elki.algorithm.outlier.spatial.neighborhood.NeighborSetPre
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
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.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
@@ -91,7 +91,7 @@ public class CTLuMedianAlgorithm<N> extends AbstractNeighborhoodOutlier<N> {
* @param relation Data relation (1d!)
* @return Outlier detection result
*/
- public OutlierResult run(Relation<N> nrel, Relation<? extends NumberVector<?>> relation) {
+ public OutlierResult run(Relation<N> nrel, Relation<? extends NumberVector> relation) {
final NeighborSetPredicate npred = getNeighborSetPredicateFactory().instantiate(nrel);
WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
@@ -132,7 +132,7 @@ public class CTLuMedianAlgorithm<N> extends AbstractNeighborhoodOutlier<N> {
scores.putDouble(iditer, score);
}
- Relation<Double> scoreResult = new MaterializedRelation<>("MO", "Median-outlier", TypeUtil.DOUBLE, scores, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("MO", "Median-outlier", scores, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 0);
OutlierResult or = new OutlierResult(scoreMeta, scoreResult);
or.addChildResult(npred);
@@ -146,7 +146,7 @@ public class CTLuMedianAlgorithm<N> extends AbstractNeighborhoodOutlier<N> {
@Override
public TypeInformation[] getInputTypeRestriction() {
- return TypeUtil.array(getNeighborSetPredicateFactory().getInputTypeRestriction(), new VectorFieldTypeInformation<NumberVector<?>>(NumberVector.class, 1));
+ return TypeUtil.array(getNeighborSetPredicateFactory().getInputTypeRestriction(), TypeUtil.NUMBER_VECTOR_FIELD_1D);
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMedianMultipleAttributes.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMedianMultipleAttributes.java
index 583958fe..4e993a97 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMedianMultipleAttributes.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMedianMultipleAttributes.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial;
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
@@ -33,11 +33,13 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.linearalgebra.CovarianceMatrix;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
@@ -62,7 +64,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* <p>
* Implementation note: attribute standardization is not used; this is
* equivalent to using the
- * {@link de.lmu.ifi.dbs.elki.datasource.filter.normalization.AttributeWiseVarianceNormalization
+ * {@link de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise.AttributeWiseVarianceNormalization
* AttributeWiseVarianceNormalization} filter.
* </p>
*
@@ -72,7 +74,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* @param <O> Non Spatial Vector
*/
@Reference(authors = "Chang-Tien Lu and Dechang Chen and Yufeng Kou", title = "Detecting Spatial Outliers with Multiple Attributes", booktitle = "Proc. 15th IEEE International Conference on Tools with Artificial Intelligence, 2003", url = "http://dx.doi.org/10.1109/TAI.2003.1250179")
-public class CTLuMedianMultipleAttributes<N, O extends NumberVector<?>> extends AbstractNeighborhoodOutlier<N> {
+public class CTLuMedianMultipleAttributes<N, O extends NumberVector> extends AbstractNeighborhoodOutlier<N> {
/**
* logger
*/
@@ -144,13 +146,12 @@ public class CTLuMedianMultipleAttributes<N, O extends NumberVector<?>> extends
DoubleMinMax minmax = new DoubleMinMax();
WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(attributes.getDBIDs(), DataStoreFactory.HINT_STATIC);
for(DBIDIter iditer = attributes.iterDBIDs(); iditer.valid(); iditer.advance()) {
- Vector temp = deltas.get(iditer).minus(mean);
- final double score = temp.transposeTimesTimes(cmati, temp);
+ final double score = MathUtil.mahalanobisDistance(cmati, deltas.get(iditer), mean);
minmax.put(score);
scores.putDouble(iditer, score);
}
- Relation<Double> scoreResult = new MaterializedRelation<>("Median multiple attributes outlier", "median-outlier", TypeUtil.DOUBLE, scores, attributes.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Median multiple attributes outlier", "median-outlier", scores, attributes.getDBIDs());
OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 0);
OutlierResult or = new OutlierResult(scoreMeta, scoreResult);
or.addChildResult(npred);
@@ -172,7 +173,7 @@ public class CTLuMedianMultipleAttributes<N, O extends NumberVector<?>> extends
* @param <N> Neighborhood type
* @param <O> Attributes vector type
*/
- public static class Parameterizer<N, O extends NumberVector<?>> extends AbstractNeighborhoodOutlier.Parameterizer<N> {
+ public static class Parameterizer<N, O extends NumberVector> extends AbstractNeighborhoodOutlier.Parameterizer<N> {
@Override
protected CTLuMedianMultipleAttributes<N, O> makeInstance() {
return new CTLuMedianMultipleAttributes<>(npredf);
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMoranScatterplotOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMoranScatterplotOutlier.java
index da527af0..1b59b79b 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMoranScatterplotOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuMoranScatterplotOutlier.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial;
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,13 +28,13 @@ import de.lmu.ifi.dbs.elki.algorithm.outlier.spatial.neighborhood.NeighborSetPre
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
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.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
@@ -94,7 +94,7 @@ public class CTLuMoranScatterplotOutlier<N> extends AbstractNeighborhoodOutlier<
* @param relation Data relation (1d!)
* @return Outlier detection result
*/
- public OutlierResult run(Relation<N> nrel, Relation<? extends NumberVector<?>> relation) {
+ public OutlierResult run(Relation<N> nrel, Relation<? extends NumberVector> relation) {
final NeighborSetPredicate npred = getNeighborSetPredicateFactory().instantiate(nrel);
// Compute the global mean and variance
@@ -136,7 +136,7 @@ public class CTLuMoranScatterplotOutlier<N> extends AbstractNeighborhoodOutlier<
scores.putDouble(iditer, score);
}
- Relation<Double> scoreResult = new MaterializedRelation<>("MoranOutlier", "Moran Scatterplot Outlier", TypeUtil.DOUBLE, scores, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("MoranOutlier", "Moran Scatterplot Outlier", scores, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 0);
OutlierResult or = new OutlierResult(scoreMeta, scoreResult);
or.addChildResult(npred);
@@ -145,7 +145,7 @@ public class CTLuMoranScatterplotOutlier<N> extends AbstractNeighborhoodOutlier<
@Override
public TypeInformation[] getInputTypeRestriction() {
- return TypeUtil.array(getNeighborSetPredicateFactory().getInputTypeRestriction(), new VectorFieldTypeInformation<NumberVector<?>>(NumberVector.class, 1));
+ return TypeUtil.array(getNeighborSetPredicateFactory().getInputTypeRestriction(), TypeUtil.NUMBER_VECTOR_FIELD_1D);
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuRandomWalkEC.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuRandomWalkEC.java
index 85524b4e..e11785af 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuRandomWalkEC.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuRandomWalkEC.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ 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.algorithm.outlier.OutlierAlgorithm;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
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.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
@@ -37,13 +36,13 @@ 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.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.math.MathUtil;
@@ -78,12 +77,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* @author Ahmed Hettab
*
* @param <N> Spatial Vector type
- * @param <D> Distance to use
*/
@Title("Random Walk on Exhaustive Combination")
@Description("Spatial Outlier Detection using Random Walk on Exhaustive Combination")
@Reference(authors = "X. Liu and C.-T. Lu and F. Chen", title = "Spatial outlier detection: random walk based approaches", booktitle = "Proc. 18th SIGSPATIAL International Conference on Advances in Geographic Information Systems, 2010", url = "http://dx.doi.org/10.1145/1869790.1869841")
-public class CTLuRandomWalkEC<N, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<N, D, OutlierResult> implements OutlierAlgorithm {
+public class CTLuRandomWalkEC<N> extends AbstractDistanceBasedAlgorithm<N, OutlierResult> implements OutlierAlgorithm {
/**
* Logger.
*/
@@ -112,7 +110,7 @@ public class CTLuRandomWalkEC<N, D extends NumberDistance<D, ?>> extends Abstrac
* @param c C parameter
* @param k Number of neighbors
*/
- public CTLuRandomWalkEC(DistanceFunction<N, D> distanceFunction, double alpha, double c, int k) {
+ public CTLuRandomWalkEC(DistanceFunction<N> distanceFunction, double alpha, double c, int k) {
super(distanceFunction);
this.alpha = alpha;
this.c = c;
@@ -126,8 +124,8 @@ public class CTLuRandomWalkEC<N, D extends NumberDistance<D, ?>> extends Abstrac
* @param relation Attribute value relation
* @return Outlier result
*/
- public OutlierResult run(Relation<N> spatial, Relation<? extends NumberVector<?>> relation) {
- DistanceQuery<N, D> distFunc = getDistanceFunction().instantiate(spatial);
+ public OutlierResult run(Relation<N> spatial, Relation<? extends NumberVector> relation) {
+ DistanceQuery<N> distFunc = getDistanceFunction().instantiate(spatial);
WritableDataStore<Vector> similarityVectors = DataStoreUtil.makeStorage(spatial.getDBIDs(), DataStoreFactory.HINT_TEMP, Vector.class);
WritableDataStore<DBIDs> neighbors = DataStoreUtil.makeStorage(spatial.getDBIDs(), DataStoreFactory.HINT_TEMP, DBIDs.class);
@@ -136,7 +134,7 @@ public class CTLuRandomWalkEC<N, D extends NumberDistance<D, ?>> extends Abstrac
// construct the relation Matrix of the ec-graph
Matrix E = new Matrix(ids.size(), ids.size());
- KNNHeap<D> heap = DBIDUtil.newHeap(distFunc.getDistanceFactory(), k);
+ KNNHeap heap = DBIDUtil.newHeap(k);
{
int i = 0;
for(DBIDIter id = ids.iter(); id.valid(); id.advance(), i++) {
@@ -148,10 +146,9 @@ public class CTLuRandomWalkEC<N, D extends NumberDistance<D, ?>> extends Abstrac
continue;
}
final double e;
- final D distance = distFunc.distance(id, n);
+ final double distance = distFunc.distance(id, n);
heap.insert(distance, n);
- double dist = distance.doubleValue();
- if(dist == 0) {
+ if(distance == 0) {
LOG.warning("Zero distances are not supported - skipping: " + DBIDUtil.toString(id) + " " + DBIDUtil.toString(n));
e = 0;
}
@@ -160,7 +157,7 @@ public class CTLuRandomWalkEC<N, D extends NumberDistance<D, ?>> extends Abstrac
double exp = Math.exp(Math.pow(diff, alpha));
// Implementation note: not inverting exp worked a lot better.
// Therefore we diverge from the article here.
- e = exp / dist;
+ e = exp / distance;
}
E.set(j, i, e);
}
@@ -225,14 +222,14 @@ public class CTLuRandomWalkEC<N, D extends NumberDistance<D, ?>> extends Abstrac
scores.putDouble(id, score);
}
- Relation<Double> scoreResult = new MaterializedRelation<>("randomwalkec", "RandomWalkEC", TypeUtil.DOUBLE, scores, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("randomwalkec", "RandomWalkEC", scores, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 0.0);
return new OutlierResult(scoreMeta, scoreResult);
}
@Override
public TypeInformation[] getInputTypeRestriction() {
- return TypeUtil.array(getDistanceFunction().getInputTypeRestriction(), new VectorFieldTypeInformation<NumberVector<?>>(NumberVector.class, 1));
+ return TypeUtil.array(getDistanceFunction().getInputTypeRestriction(), TypeUtil.NUMBER_VECTOR_FIELD_1D);
}
@Override
@@ -248,9 +245,8 @@ public class CTLuRandomWalkEC<N, D extends NumberDistance<D, ?>> extends Abstrac
* @apiviz.exclude
*
* @param <N> Vector type
- * @param <D> Distance type
*/
- public static class Parameterizer<N, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<N, D> {
+ public static class Parameterizer<N> extends AbstractDistanceBasedAlgorithm.Parameterizer<N> {
/**
* Parameter to specify the number of neighbors.
*/
@@ -327,7 +323,7 @@ public class CTLuRandomWalkEC<N, D extends NumberDistance<D, ?>> extends Abstrac
}
@Override
- protected CTLuRandomWalkEC<N, D> makeInstance() {
+ protected CTLuRandomWalkEC<N> makeInstance() {
return new CTLuRandomWalkEC<>(distanceFunction, alpha, c, k);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuScatterplotOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuScatterplotOutlier.java
index bcbbfd2a..6feb08f6 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuScatterplotOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuScatterplotOutlier.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial;
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,14 +27,14 @@ import de.lmu.ifi.dbs.elki.algorithm.outlier.spatial.neighborhood.NeighborSetPre
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
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.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
@@ -96,7 +96,7 @@ public class CTLuScatterplotOutlier<N> extends AbstractNeighborhoodOutlier<N> {
* @param relation Data relation (1d!)
* @return Outlier detection result
*/
- public OutlierResult run(Relation<N> nrel, Relation<? extends NumberVector<?>> relation) {
+ public OutlierResult run(Relation<N> nrel, Relation<? extends NumberVector> relation) {
final NeighborSetPredicate npred = getNeighborSetPredicateFactory().instantiate(nrel);
WritableDoubleDataStore means = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP);
@@ -160,7 +160,7 @@ public class CTLuScatterplotOutlier<N> extends AbstractNeighborhoodOutlier<N> {
}
}
// build representation
- Relation<Double> scoreResult = new MaterializedRelation<>("SPO", "Scatterplot-Outlier", TypeUtil.DOUBLE, scores, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("SPO", "Scatterplot-Outlier", scores, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 0);
OutlierResult or = new OutlierResult(scoreMeta, scoreResult);
or.addChildResult(npred);
@@ -174,7 +174,7 @@ public class CTLuScatterplotOutlier<N> extends AbstractNeighborhoodOutlier<N> {
@Override
public TypeInformation[] getInputTypeRestriction() {
- return TypeUtil.array(getNeighborSetPredicateFactory().getInputTypeRestriction(), new VectorFieldTypeInformation<NumberVector<?>>(NumberVector.class, 1));
+ return TypeUtil.array(getNeighborSetPredicateFactory().getInputTypeRestriction(), TypeUtil.NUMBER_VECTOR_FIELD_1D);
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuZTestOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuZTestOutlier.java
index d6cb5a50..b973109a 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuZTestOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/CTLuZTestOutlier.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial;
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.algorithm.outlier.spatial.neighborhood.NeighborSetPre
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
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.Database;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
@@ -35,7 +34,8 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
@@ -98,7 +98,7 @@ public class CTLuZTestOutlier<N> extends AbstractNeighborhoodOutlier<N> {
* @param relation Data relation (1d!)
* @return Outlier detection result
*/
- public OutlierResult run(Database database, Relation<N> nrel, Relation<? extends NumberVector<?>> relation) {
+ public OutlierResult run(Database database, Relation<N> nrel, Relation<? extends NumberVector> relation) {
final NeighborSetPredicate npred = getNeighborSetPredicateFactory().instantiate(nrel);
WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
@@ -133,7 +133,7 @@ public class CTLuZTestOutlier<N> extends AbstractNeighborhoodOutlier<N> {
}
// Wrap result
- Relation<Double> scoreResult = new MaterializedRelation<>("ZTest", "Z Test score", TypeUtil.DOUBLE, scores, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("ZTest", "Z Test score", scores, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 0);
OutlierResult or = new OutlierResult(scoreMeta, scoreResult);
or.addChildResult(npred);
@@ -147,7 +147,7 @@ public class CTLuZTestOutlier<N> extends AbstractNeighborhoodOutlier<N> {
@Override
public TypeInformation[] getInputTypeRestriction() {
- return TypeUtil.array(getNeighborSetPredicateFactory().getInputTypeRestriction(), new VectorFieldTypeInformation<NumberVector<?>>(NumberVector.class, 1));
+ return TypeUtil.array(getNeighborSetPredicateFactory().getInputTypeRestriction(), TypeUtil.NUMBER_VECTOR_FIELD_1D);
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/SLOM.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/SLOM.java
index 08c3e29b..7fbb8486 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/SLOM.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/SLOM.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial;
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,10 +34,10 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
@@ -65,12 +65,11 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
*
* @param <N> the type the spatial neighborhood is defined over
* @param <O> the type of objects handled by the algorithm
- * @param <D> the type of Distance used for non spatial attributes
*/
@Title("SLOM: a new measure for local spatial outliers")
@Description("Spatial local outlier measure (SLOM), which captures the local behaviour of datum in their spatial neighbourhood")
@Reference(authors = "Sanjay Chawla and Pei Sun", title = "SLOM: a new measure for local spatial outliers", booktitle = "Knowledge and Information Systems 9(4), 412-429, 2006", url = "http://dx.doi.org/10.1007/s10115-005-0200-2")
-public class SLOM<N, O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedSpatialOutlier<N, O, D> {
+public class SLOM<N, O> extends AbstractDistanceBasedSpatialOutlier<N, O> {
/**
* The logger for this class.
*/
@@ -83,7 +82,7 @@ public class SLOM<N, O, D extends NumberDistance<D, ?>> extends AbstractDistance
* @param nonSpatialDistanceFunction Distance function to use on the
* non-spatial attributes
*/
- public SLOM(NeighborSetPredicate.Factory<N> npred, PrimitiveDistanceFunction<O, D> nonSpatialDistanceFunction) {
+ public SLOM(NeighborSetPredicate.Factory<N> npred, PrimitiveDistanceFunction<O> nonSpatialDistanceFunction) {
super(npred, nonSpatialDistanceFunction);
}
@@ -95,7 +94,7 @@ public class SLOM<N, O, D extends NumberDistance<D, ?>> extends AbstractDistance
*/
public OutlierResult run(Database database, Relation<N> spatial, Relation<O> relation) {
final NeighborSetPredicate npred = getNeighborSetPredicateFactory().instantiate(spatial);
- DistanceQuery<O, D> distFunc = getNonSpatialDistanceFunction().instantiate(relation);
+ DistanceQuery<O> distFunc = getNonSpatialDistanceFunction().instantiate(relation);
WritableDoubleDataStore modifiedDistance = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
// calculate D-Tilde
@@ -109,7 +108,7 @@ public class SLOM<N, O, D extends NumberDistance<D, ?>> extends AbstractDistance
if(DBIDUtil.equal(iditer, iter)) {
continue;
}
- double dist = distFunc.distance(iditer, iter).doubleValue();
+ double dist = distFunc.distance(iditer, iter);
sum += dist;
cnt++;
maxDist = Math.max(maxDist, dist);
@@ -187,7 +186,7 @@ public class SLOM<N, O, D extends NumberDistance<D, ?>> extends AbstractDistance
slomminmax.put(slom);
}
- Relation<Double> scoreResult = new MaterializedRelation<>("SLOM", "slom-outlier", TypeUtil.DOUBLE, sloms, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("SLOM", "slom-outlier", sloms, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(slomminmax.getMin(), slomminmax.getMax(), 0.0, Double.POSITIVE_INFINITY);
OutlierResult or = new OutlierResult(scoreMeta, scoreResult);
or.addChildResult(npred);
@@ -213,11 +212,10 @@ public class SLOM<N, O, D extends NumberDistance<D, ?>> extends AbstractDistance
*
* @param <N> Neighborhood type
* @param <O> Data Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<N, O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedSpatialOutlier.Parameterizer<N, O, D> {
+ public static class Parameterizer<N, O> extends AbstractDistanceBasedSpatialOutlier.Parameterizer<N, O> {
@Override
- protected SLOM<N, O, D> makeInstance() {
+ protected SLOM<N, O> makeInstance() {
return new SLOM<>(npredf, distanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/SOF.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/SOF.java
index a2605f39..f9823e56 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/SOF.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/SOF.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial;
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,10 +32,10 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
@@ -65,11 +65,10 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
*
* @param <N> Neighborhood object type
* @param <O> Attribute object type
- * @param <D> Distance type
*/
@Title("Spatial Outlier Factor")
@Reference(authors = "Huang, T., Qin, X.", title = "Detecting outliers in spatial database", booktitle = "Proc. 3rd International Conference on Image and Graphics", url = "http://dx.doi.org/10.1109/ICIG.2004.53")
-public class SOF<N, O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedSpatialOutlier<N, O, D> {
+public class SOF<N, O> extends AbstractDistanceBasedSpatialOutlier<N, O> {
/**
* The logger for this class.
*/
@@ -82,7 +81,7 @@ public class SOF<N, O, D extends NumberDistance<D, ?>> extends AbstractDistanceB
* @param nonSpatialDistanceFunction Distance function on non-spatial
* attributes
*/
- public SOF(NeighborSetPredicate.Factory<N> npred, PrimitiveDistanceFunction<O, D> nonSpatialDistanceFunction) {
+ public SOF(NeighborSetPredicate.Factory<N> npred, PrimitiveDistanceFunction<O> nonSpatialDistanceFunction) {
super(npred, nonSpatialDistanceFunction);
}
@@ -101,7 +100,7 @@ public class SOF<N, O, D extends NumberDistance<D, ?>> extends AbstractDistanceB
*/
public OutlierResult run(Database database, Relation<N> spatial, Relation<O> relation) {
final NeighborSetPredicate npred = getNeighborSetPredicateFactory().instantiate(spatial);
- DistanceQuery<O, D> distFunc = getNonSpatialDistanceFunction().instantiate(relation);
+ DistanceQuery<O> distFunc = getNonSpatialDistanceFunction().instantiate(relation);
WritableDoubleDataStore lrds = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT);
WritableDoubleDataStore lofs = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
@@ -112,7 +111,7 @@ public class SOF<N, O, D extends NumberDistance<D, ?>> extends AbstractDistanceB
DBIDs neighbors = npred.getNeighborDBIDs(iditer);
double avg = 0;
for(DBIDIter iter = neighbors.iter(); iter.valid(); iter.advance()) {
- avg += distFunc.distance(iditer, iter).doubleValue();
+ avg += distFunc.distance(iditer, iter);
}
double lrd = 1 / (avg / neighbors.size());
if (Double.isNaN(lrd)) {
@@ -138,7 +137,7 @@ public class SOF<N, O, D extends NumberDistance<D, ?>> extends AbstractDistanceB
}
// Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("Spatial Outlier Factor", "sof-outlier", TypeUtil.DOUBLE, lofs, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Spatial Outlier Factor", "sof-outlier", lofs, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(lofminmax.getMin(), lofminmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 1.0);
OutlierResult or = new OutlierResult(scoreMeta, scoreResult);
or.addChildResult(npred);
@@ -159,11 +158,10 @@ public class SOF<N, O, D extends NumberDistance<D, ?>> extends AbstractDistanceB
*
* @param <N> Neighborhood type
* @param <O> Attribute object type
- * @param <D> Distance type
*/
- public static class Parameterizer<N, O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedSpatialOutlier.Parameterizer<N, O, D> {
+ public static class Parameterizer<N, O> extends AbstractDistanceBasedSpatialOutlier.Parameterizer<N, O> {
@Override
- protected SOF<N, O, D> makeInstance() {
+ protected SOF<N, O> makeInstance() {
return new SOF<>(npredf, distanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/TrimmedMeanApproach.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/TrimmedMeanApproach.java
index 1a1f9a82..e46976ab 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/TrimmedMeanApproach.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/TrimmedMeanApproach.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial;
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,14 +29,14 @@ import de.lmu.ifi.dbs.elki.algorithm.outlier.spatial.neighborhood.NeighborSetPre
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
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.Database;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.logging.Logging;
@@ -109,7 +109,7 @@ public class TrimmedMeanApproach<N> extends AbstractNeighborhoodOutlier<N> {
* @param relation Data Relation (1 dimensional!)
* @return Outlier detection result
*/
- public OutlierResult run(Database database, Relation<N> nrel, Relation<? extends NumberVector<?>> relation) {
+ public OutlierResult run(Database database, Relation<N> nrel, Relation<? extends NumberVector> relation) {
assert (RelationUtil.dimensionality(relation) == 1) : "TrimmedMean can only process one-dimensional data sets.";
final NeighborSetPredicate npred = getNeighborSetPredicateFactory().instantiate(nrel);
@@ -145,13 +145,9 @@ public class TrimmedMeanApproach<N> extends AbstractNeighborhoodOutlier<N> {
// Error: deviation from trimmed mean
errors.putDouble(iditer, relation.get(iditer).doubleValue(0) - tm);
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
- }
- if(progress != null) {
- progress.ensureCompleted(LOG);
+ LOG.incrementProcessed(progress);
}
+ LOG.ensureCompleted(progress);
if(LOG.isVerbose()) {
LOG.verbose("Computing median error.");
@@ -187,7 +183,7 @@ public class TrimmedMeanApproach<N> extends AbstractNeighborhoodOutlier<N> {
minmax.put(score);
}
//
- Relation<Double> scoreResult = new MaterializedRelation<>("TrimmedMean", "Trimmed Mean Score", TypeUtil.DOUBLE, scores, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("TrimmedMean", "Trimmed Mean Score", scores, relation.getDBIDs());
OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 0);
OutlierResult or = new OutlierResult(scoreMeta, scoreResult);
or.addChildResult(npred);
@@ -202,7 +198,7 @@ public class TrimmedMeanApproach<N> extends AbstractNeighborhoodOutlier<N> {
@Override
public TypeInformation[] getInputTypeRestriction() {
// Get one dimensional attribute for analysis.
- return TypeUtil.array(getNeighborSetPredicateFactory().getInputTypeRestriction(), new VectorFieldTypeInformation<NumberVector<?>>(NumberVector.class, 1));
+ return TypeUtil.array(getNeighborSetPredicateFactory().getInputTypeRestriction(), TypeUtil.NUMBER_VECTOR_FIELD_1D);
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/AbstractPrecomputedNeighborhood.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/AbstractPrecomputedNeighborhood.java
index ef237928..506c722a 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/AbstractPrecomputedNeighborhood.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/AbstractPrecomputedNeighborhood.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial.neighborhood;
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/algorithm/outlier/spatial/neighborhood/ExtendedNeighborhood.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/ExtendedNeighborhood.java
index c93b10cb..145aecb1 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/ExtendedNeighborhood.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/ExtendedNeighborhood.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial.neighborhood;
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
@@ -156,13 +156,9 @@ public class ExtendedNeighborhood extends AbstractPrecomputedNeighborhood {
todo = ntodo;
}
store.put(iter, res);
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
- }
- if(progress != null) {
- progress.ensureCompleted(LOG);
+ LOG.incrementProcessed(progress);
}
+ LOG.ensureCompleted(progress);
return store;
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/ExternalNeighborhood.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/ExternalNeighborhood.java
index 33b5010a..5bdd05bf 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/ExternalNeighborhood.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/ExternalNeighborhood.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial.neighborhood;
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
@@ -169,13 +169,11 @@ public class ExternalNeighborhood extends AbstractPrecomputedNeighborhood {
}
}
- try {
- if(LOG.isDebugging()) {
- LOG.verbose("Loading neighborhood file.");
- }
- InputStream in = new FileInputStream(file);
- in = FileUtil.tryGzipInput(in);
- BufferedReader br = new BufferedReader(new InputStreamReader(in));
+ if(LOG.isDebugging()) {
+ LOG.verbose("Loading neighborhood file.");
+ }
+ try(InputStream in = FileUtil.tryGzipInput(new FileInputStream(file));
+ BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
for(String line; (line = br.readLine()) != null;) {
ArrayModifiableDBIDs neighbours = DBIDUtil.newArray();
String[] entries = line.split(" ");
@@ -200,9 +198,6 @@ public class ExternalNeighborhood extends AbstractPrecomputedNeighborhood {
}
}
}
- br.close();
- in.close();
-
return store;
}
catch(IOException e) {
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/NeighborSetPredicate.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/NeighborSetPredicate.java
index 25283d5c..5d35aff8 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/NeighborSetPredicate.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/NeighborSetPredicate.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial.neighborhood;
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.DBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.result.Result;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Predicate to obtain the neighbors of a reference object as set.
@@ -54,7 +53,7 @@ public interface NeighborSetPredicate extends Result {
*
* @param <O> Input relation object type restriction
*/
- public static interface Factory<O> extends Parameterizable {
+ public static interface Factory<O> {
/**
* Instantiation method.
*
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/PrecomputedKNearestNeighborNeighborhood.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/PrecomputedKNearestNeighborNeighborhood.java
index c43ebba7..18ab30d7 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/PrecomputedKNearestNeighborNeighborhood.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/PrecomputedKNearestNeighborNeighborhood.java
@@ -1,26 +1,27 @@
package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial.neighborhood;
-/*
-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/>.
-*/
+
+/*
+ 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.type.TypeInformation;
import de.lmu.ifi.dbs.elki.database.QueryUtil;
@@ -32,11 +33,10 @@ import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -48,10 +48,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* Neighborhoods based on k nearest neighbors.
*
* @author Ahmed Hettab
- *
- * @param <D> Distance to use
*/
-public class PrecomputedKNearestNeighborNeighborhood<D extends Distance<D>> extends AbstractPrecomputedNeighborhood {
+public class PrecomputedKNearestNeighborNeighborhood extends AbstractPrecomputedNeighborhood {
/**
* Logger
*/
@@ -88,11 +86,10 @@ public class PrecomputedKNearestNeighborNeighborhood<D extends Distance<D>> exte
*
* @apiviz.stereotype factory
* @apiviz.has PrecomputedKNearestNeighborNeighborhood
- *
+ *
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Factory<O, D extends Distance<D>> implements NeighborSetPredicate.Factory<O> {
+ public static class Factory<O> implements NeighborSetPredicate.Factory<O> {
/**
* parameter k
*/
@@ -101,12 +98,12 @@ public class PrecomputedKNearestNeighborNeighborhood<D extends Distance<D>> exte
/**
* distance function to use
*/
- private DistanceFunction<? super O, D> distFunc;
+ private DistanceFunction<? super O> distFunc;
/**
* Factory Constructor
*/
- public Factory(int k, DistanceFunction<? super O, D> distFunc) {
+ public Factory(int k, DistanceFunction<? super O> distFunc) {
super();
this.k = k;
this.distFunc = distFunc;
@@ -114,19 +111,19 @@ public class PrecomputedKNearestNeighborNeighborhood<D extends Distance<D>> exte
@Override
public NeighborSetPredicate instantiate(Relation<? extends O> relation) {
- KNNQuery<?, D> knnQuery = QueryUtil.getKNNQuery(relation, distFunc);
+ KNNQuery<?> knnQuery = QueryUtil.getKNNQuery(relation, distFunc);
// TODO: use bulk?
WritableDataStore<DBIDs> s = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_STATIC, DBIDs.class);
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- KNNList<D> neighbors = knnQuery.getKNNForDBID(iditer, k);
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ KNNList neighbors = knnQuery.getKNNForDBID(iditer, k);
ArrayModifiableDBIDs neighbours = DBIDUtil.newArray(neighbors.size());
- for (DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ for(DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
neighbours.add(neighbor);
}
s.put(iditer, neighbours);
}
- return new PrecomputedKNearestNeighborNeighborhood<D>(s);
+ return new PrecomputedKNearestNeighborNeighborhood(s);
}
@Override
@@ -142,9 +139,8 @@ public class PrecomputedKNearestNeighborNeighborhood<D extends Distance<D>> exte
* @apiviz.exclude
*
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractParameterizer {
+ public static class Parameterizer<O> extends AbstractParameterizer {
/**
* Parameter k
*/
@@ -163,7 +159,7 @@ public class PrecomputedKNearestNeighborNeighborhood<D extends Distance<D>> exte
/**
* Distance function
*/
- DistanceFunction<? super O, D> distFunc;
+ DistanceFunction<? super O> distFunc;
@Override
protected void makeOptions(Parameterization config) {
@@ -172,14 +168,14 @@ public class PrecomputedKNearestNeighborNeighborhood<D extends Distance<D>> exte
if(config.grab(kP)) {
k = kP.getValue();
}
- final ObjectParameter<DistanceFunction<? super O, D>> distP = new ObjectParameter<>(DISTANCEFUNCTION_ID, DistanceFunction.class);
+ final ObjectParameter<DistanceFunction<? super O>> distP = new ObjectParameter<>(DISTANCEFUNCTION_ID, DistanceFunction.class);
if(config.grab(distP)) {
distFunc = distP.instantiateClass(config);
}
}
@Override
- protected PrecomputedKNearestNeighborNeighborhood.Factory<O, D> makeInstance() {
+ protected PrecomputedKNearestNeighborNeighborhood.Factory<O> makeInstance() {
return new PrecomputedKNearestNeighborNeighborhood.Factory<>(k, distFunc);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/package-info.java
index fd51ca22..6199412c 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/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/algorithm/outlier/spatial/neighborhood/weighted/LinearWeightedExtendedNeighborhood.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/LinearWeightedExtendedNeighborhood.java
index 4d6ec635..e1abc23c 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/LinearWeightedExtendedNeighborhood.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/LinearWeightedExtendedNeighborhood.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial.neighborhood.weighted;
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/algorithm/outlier/spatial/neighborhood/weighted/UnweightedNeighborhoodAdapter.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/UnweightedNeighborhoodAdapter.java
index 9bdb7d51..6c2fa7c1 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/UnweightedNeighborhoodAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/UnweightedNeighborhoodAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial.neighborhood.weighted;
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/algorithm/outlier/spatial/neighborhood/weighted/WeightedNeighborSetPredicate.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/WeightedNeighborSetPredicate.java
index ca0fa620..74ffaaa4 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/WeightedNeighborSetPredicate.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/WeightedNeighborSetPredicate.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.spatial.neighborhood.weighted;
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,6 @@ import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Neighbor predicate with weight support.
@@ -55,7 +54,7 @@ public interface WeightedNeighborSetPredicate {
*
* @param <O> Input relation object type restriction
*/
- public static interface Factory<O> extends Parameterizable {
+ public static interface Factory<O> {
/**
* Instantiation method.
*
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/package-info.java
index d7c7a797..c09fdf19 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/neighborhood/weighted/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/algorithm/outlier/spatial/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/package-info.java
index 5a65d8c1..e1325935 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/spatial/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/algorithm/outlier/AbstractAggarwalYuOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/AbstractAggarwalYuOutlier.java
index 2b12b306..8ee5e2cd 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/AbstractAggarwalYuOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/AbstractAggarwalYuOutlier.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
+package de.lmu.ifi.dbs.elki.algorithm.outlier.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
@@ -24,17 +24,17 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier;
*/
import java.util.ArrayList;
-import java.util.Collections;
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.VectorUtil.SortDBIDsBySingleDimension;
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.ArrayModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
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.DoubleDBIDPair;
import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
@@ -52,8 +52,8 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.IntIntPair;
* Abstract base class for the sparse-grid-cell based outlier detection of
* Aggarwal and Yu.
*
+ * Reference:
* <p>
- * Reference: <br />
* Outlier detection for high dimensional data<br />
* C.C. Aggarwal, P. S. Yu<br />
* International Conference on Management of Data Proceedings of the 2001 ACM
@@ -66,15 +66,20 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.IntIntPair;
*
* @param <V> Vector type
*/
-@Reference(authors = "C.C. Aggarwal, P. S. Yu", title = "Outlier detection for high dimensional data", booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD 2001), Santa Barbara, CA, 2001", url = "http://dx.doi.org/10.1145/375663.375668")
-public abstract class AbstractAggarwalYuOutlier<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "C.C. Aggarwal, P. S. Yu", //
+title = "Outlier detection for high dimensional data", //
+booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD 2001), Santa Barbara, CA, 2001", //
+url = "http://dx.doi.org/10.1145/375663.375668")
+public abstract class AbstractAggarwalYuOutlier<V extends NumberVector> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
/**
* Symbolic value for subspaces not in use.
- *
- * Note: in some places, the implementations may rely on this having the value
- * 0 currently!
*/
- public static final int DONT_CARE = 0;
+ public static final short DONT_CARE = -1;
+
+ /**
+ * The first bucket.
+ */
+ public static final short GENE_OFFSET = DONT_CARE + 1;
/**
* The number of partitions for each dimension.
@@ -109,38 +114,23 @@ public abstract class AbstractAggarwalYuOutlier<V extends NumberVector<?>> exten
protected ArrayList<ArrayList<DBIDs>> buildRanges(Relation<V> relation) {
final int dim = RelationUtil.dimensionality(relation);
final int size = relation.size();
- final DBIDs allids = relation.getDBIDs();
final ArrayList<ArrayList<DBIDs>> ranges = new ArrayList<>();
- // Temporary projection storage of the database
- final ArrayList<ArrayList<DoubleDBIDPair>> dbAxis = new ArrayList<>(dim);
- for(int i = 0; i < dim; i++) {
- ArrayList<DoubleDBIDPair> axis = new ArrayList<>(size);
- dbAxis.add(i, axis);
- }
- // Project
- for(DBIDIter iter = allids.iter(); iter.valid(); iter.advance()) {
- final V obj = relation.get(iter);
- for(int d = 0; d < dim; d++) {
- dbAxis.get(d).add(DBIDUtil.newPair(obj.doubleValue(d), iter));
- }
- }
+ ArrayModifiableDBIDs ids = DBIDUtil.newArray(relation.getDBIDs());
+ SortDBIDsBySingleDimension sorter = new SortDBIDsBySingleDimension(relation);
// Split into cells
final double part = size * 1.0 / phi;
for(int d = 0; d < dim; d++) {
- ArrayList<DoubleDBIDPair> axis = dbAxis.get(d);
- Collections.sort(axis);
+ sorter.setDimension(d);
+ ids.sort(sorter);
ArrayList<DBIDs> dimranges = new ArrayList<>(phi + 1);
- dimranges.add(allids);
int start = 0;
- for(int r = 0; r < phi; r++) {
- int end = (int) (part * r);
- if(r == phi - 1) {
- end = size;
- }
- ArrayModifiableDBIDs currange = DBIDUtil.newArray(phi + 1);
- for(int i = start; i < end; i++) {
- currange.add(axis.get(i));
+ DBIDArrayIter iter = ids.iter();
+ for(int r = 1; r <= phi; r++) {
+ int end = (r < phi) ? (int) (part * r) : size;
+ ArrayModifiableDBIDs currange = DBIDUtil.newArray(end - start);
+ for(iter.seek(start); iter.getOffset() < end; iter.advance()) {
+ currange.add(iter);
}
start = end;
dimranges.add(currange);
@@ -178,7 +168,7 @@ public abstract class AbstractAggarwalYuOutlier<V extends NumberVector<?>> exten
HashSetModifiableDBIDs ids = DBIDUtil.newHashSet(ranges.get(subspace.get(0).first).get(subspace.get(0).second));
// intersect all selected dimensions
for(int i = 1; i < subspace.size(); i++) {
- DBIDs current = ranges.get(subspace.get(i).first).get(subspace.get(i).second);
+ DBIDs current = ranges.get(subspace.get(i).first).get(subspace.get(i).second - GENE_OFFSET);
ids.retainAll(current);
if(ids.size() == 0) {
break;
@@ -194,15 +184,21 @@ public abstract class AbstractAggarwalYuOutlier<V extends NumberVector<?>> exten
* @param ranges Database ranges
* @return resulting DBIDs
*/
- protected DBIDs computeSubspaceForGene(int[] gene, ArrayList<ArrayList<DBIDs>> ranges) {
- HashSetModifiableDBIDs m = DBIDUtil.newHashSet(ranges.get(0).get(gene[0]));
- // intersect
- for(int i = 1; i < gene.length; i++) {
+ protected DBIDs computeSubspaceForGene(short[] gene, ArrayList<ArrayList<DBIDs>> ranges) {
+ HashSetModifiableDBIDs m = null;
+ // intersect all present restrictions
+ for(int i = 0; i < gene.length; i++) {
if(gene[i] != DONT_CARE) {
- DBIDs current = ranges.get(i).get(gene[i]);
- m.retainAll(current);
+ DBIDs current = ranges.get(i).get(gene[i] - GENE_OFFSET);
+ if(m == null) {
+ m = DBIDUtil.newHashSet(current);
+ }
+ else {
+ m.retainAll(current);
+ }
}
}
+ assert (m != null) : "All genes set to '*', should not happen!";
return m;
}
@@ -242,13 +238,13 @@ public abstract class AbstractAggarwalYuOutlier<V extends NumberVector<?>> exten
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final IntParameter kP = new IntParameter(K_ID);
- kP.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
+ final IntParameter kP = new IntParameter(K_ID)//
+ .addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
if(config.grab(kP)) {
k = kP.getValue();
}
- final IntParameter phiP = new IntParameter(PHI_ID);
- phiP.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
+ final IntParameter phiP = new IntParameter(PHI_ID)//
+ .addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
if(config.grab(phiP)) {
phi = phiP.getValue();
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/AggarwalYuEvolutionary.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/AggarwalYuEvolutionary.java
index c4e5cc5d..b32e5124 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/AggarwalYuEvolutionary.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/AggarwalYuEvolutionary.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
+package de.lmu.ifi.dbs.elki.algorithm.outlier.subspace;
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,49 +23,48 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import gnu.trove.iterator.TIntIterator;
+import gnu.trove.list.array.TIntArrayList;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.Iterator;
import java.util.Random;
-import java.util.TreeSet;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.result.outlier.InvertedOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.TopBoundedHeap;
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;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
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.RandomParameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.FCPair;
import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
- * EAFOD provides the evolutionary outlier detection algorithm, an algorithm to
- * detect outliers for high dimensional data.
+ * Evolutionary variant (EAFOD) of the high-dimensional outlier detection
+ * algorithm by Aggarwal and Yu.
* <p>
* Reference: <br />
* Outlier detection for high dimensional data<br />
@@ -86,7 +85,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
@Title("EAFOD: the evolutionary outlier detection algorithm")
@Description("Outlier detection for high dimensional data")
@Reference(authors = "C.C. Aggarwal, P. S. Yu", title = "Outlier detection for high dimensional data", booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD 2001), Santa Barbara, CA, 2001", url = "http://dx.doi.org/10.1145/375663.375668")
-public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractAggarwalYuOutlier<V> {
+public class AggarwalYuEvolutionary<V extends NumberVector> extends AbstractAggarwalYuOutlier<V> {
/**
* The logger for this class.
*/
@@ -98,6 +97,11 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
protected final static int MAX_ITERATIONS = 1000;
/**
+ * At which gene homogenity do we have convergence?
+ */
+ protected final static double CONVERGENCE = .85;
+
+ /**
* Holds the value of {@link Parameterizer#M_ID}.
*/
private int m;
@@ -155,7 +159,7 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
}
minmax.put(val);
}
- Relation<Double> scoreResult = new MaterializedRelation<>("AggarwalYuEvolutionary", "aggarwal-yu-outlier", TypeUtil.DOUBLE, outlierScore, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("AggarwalYuEvolutionary", "aggarwal-yu-outlier", outlierScore, relation.getDBIDs());
OutlierScoreMeta meta = new InvertedOutlierScoreMeta(minmax.getMin(), minmax.getMax(), Double.NEGATIVE_INFINITY, 0.0);
return new OutlierResult(meta, scoreResult);
}
@@ -223,14 +227,16 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
bestSol.add(ind);
}
+ IndefiniteProgress prog = LOG.isVerbose() ? new IndefiniteProgress("Evolutionary search iterations", LOG) : null;
int iterations = 0;
while(!checkConvergence(pop)) {
Collections.sort(pop);
+ // Fitter members are more likely to survive
pop = rouletteRankSelection(pop);
- // Crossover
+ // Crossover survivors
pop = crossoverOptimized(pop);
// Mutation with probability 0.25 , 0.25
- pop = mutation(pop, 0.5, 0.5);
+ pop = mutation(pop, 0.25, 0.25);
// Avoid duplicates
ind: for(Individuum ind : pop) {
for(Heap<Individuum>.UnorderedIter it = bestSol.unorderedIter(); it.valid(); it.advance()) {
@@ -253,11 +259,15 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
LOG.debugFinest(buf.toString());
}
iterations++;
+ LOG.incrementProcessed(prog);
if(iterations > MAX_ITERATIONS) {
LOG.warning("Maximum iterations reached.");
break;
}
}
+ if(prog != null) {
+ prog.setCompleted(LOG);
+ }
return bestSol.unorderedIter();
}
@@ -276,25 +286,28 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
int[][] occur = new int[dim][phi + 1];
// Count gene occurrences
for(Individuum ind : pop) {
- int[] gene = ind.getGene();
+ short[] gene = ind.getGene();
for(int d = 0; d < dim; d++) {
- int val = gene[d] + DONT_CARE;
- if(val < 0 || val >= phi + 1) {
+ if(gene[d] == DONT_CARE) {
+ occur[d][0] += 1;
+ continue;
+ }
+ int val = gene[d] - GENE_OFFSET;
+ if(val < 0 || val >= phi) {
LOG.warning("Invalid gene value encountered: " + val + " in " + ind.toString());
continue;
}
- occur[d][val] += 1;
+ occur[d][val + 1] += 1;
}
}
- int conv = (int) (pop.size() * 0.95);
+ int conv = (int) Math.floor(pop.size() * CONVERGENCE);
if(LOG.isDebuggingFine()) {
LOG.debugFine("Convergence at " + conv + " of " + pop.size() + " individuums.");
}
for(int d = 0; d < dim; d++) {
boolean converged = false;
-
- for(int val = 0; val < phi + 1; val++) {
+ for(int val = 0; val <= phi; val++) {
if(occur[d][val] >= conv) {
converged = true;
break;
@@ -320,24 +333,23 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
// fill population
for(int i = 0; i < popsize; i++) {
// Random Individual
- int[] gene = new int[dim];
+ short[] gene = new short[dim];
// fill don't care ( any dimension == don't care)
- for(int j = 0; j < dim; j++) {
- gene[j] = DONT_CARE;
- }
+ Arrays.fill(gene, DONT_CARE);
// count of don't care positions
int countDim = k;
// fill non don't care positions of the Individual
while(countDim > 0) {
int z = random.nextInt(dim);
- if(gene[z] == DONT_CARE) {
- gene[z] = random.nextInt(phi) + 1;
- countDim--;
+ if(gene[z] != DONT_CARE) {
+ continue;
}
+ gene[z] = (short) (random.nextInt(phi) + GENE_OFFSET);
+ countDim--;
}
population.add(makeIndividuum(gene));
}
- Collections.sort(population);
+ // Collections.sort(population);
return population;
}
@@ -363,94 +375,56 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
// position of selection
for(int i = 0; i < popsize; i++) {
int z = random.nextInt(totalweight);
- for(int j = 0; j < popsize; j++) {
- if(z < popsize - j) {
- // TODO: need clone?
+ for(int j = 0, rank = popsize; j < popsize; ++j, --rank) {
+ if(z < rank) {
survivors.add(population.get(j));
break;
}
- else {
- // decrement
- z -= (popsize - j);
- }
+ z -= rank;
}
}
- if(survivors.size() != popsize) {
- throw new AbortException("Selection step failed - implementation error?");
- }
- // Don't sort, to avoid biasing the crossover!
- // Collections.sort(survivors);
+ assert (survivors.size() == popsize) : "Selection step failed - implementation error?";
return survivors;
}
/**
- * Apply the mutation alogrithm.
+ * Apply the mutation algorithm.
*/
private ArrayList<Individuum> mutation(ArrayList<Individuum> population, double perc1, double perc2) {
// the Mutations
ArrayList<Individuum> mutations = new ArrayList<>();
- // Set of Positions which are don't care in the String
- TreeSet<Integer> Q = new TreeSet<>();
- // Set of Positions which are not don't care in the String
- TreeSet<Integer> R = new TreeSet<>();
+ int[] QR = new int[dim];
// for each individuum
for(int j = 0; j < population.size(); j++) {
- // clear the Sets
- Q.clear();
- R.clear();
- // Fill the Sets with the Positions
+ short[] gene = population.get(j).getGene().clone();
+ // Fill position array for mutation process
+ int q = 0, r = dim;
for(int i = 0; i < dim; i++) {
- if(population.get(j).getGene()[i] == DONT_CARE) {
- Q.add(i);
- }
- else {
- R.add(i);
- }
+ QR[(gene[i] == DONT_CARE) ? (q++) : (--r)] = i;
}
- //
- double r1 = random.nextDouble();
- if(Q.size() != 0) {
- // Mutation Variant 1
- if(r1 <= perc1) {
- // calc Mutation Spot
- Integer[] pos = new Integer[Q.size()];
- pos = Q.toArray(pos);
- int position = random.nextInt(pos.length);
- int depth = pos[position];
- // Mutate don't care into 1....phi
- population.get(j).getGene()[depth] = random.nextInt(phi) + 1;
- // update Sets
- Q.remove(depth);
- R.add(depth);
- // calc new Mutation Spot
- pos = new Integer[R.size()];
- pos = R.toArray(pos);
- position = random.nextInt(pos.length);
- depth = pos[position];
- // Mutate non don't care into don't care
- population.get(j).getGene()[depth] = DONT_CARE;
- // update Sets
- Q.add(depth);
- R.remove(depth);
- }
+ // Mutation variant 1
+ if(q > 0 && r < dim && random.nextDouble() <= perc1) {
+ // Random mutation spots:
+ int rq = random.nextInt(q), rr = random.nextInt(dim - r) + r;
+ int pq = QR[rq], pr = QR[rr];
+ // Mutate don't care (position pq) into 1....phi
+ gene[pq] = (short) (random.nextInt(phi) + GENE_OFFSET);
+ // Mutate non don't care (position pr) into don't care
+ gene[pr] = DONT_CARE;
+ // update sets, by swapping the position vlaues
+ QR[rq] = pr;
+ QR[rr] = pq;
}
- r1 = random.nextDouble();
// Mutation Variant 2
- if(r1 <= perc2) {
+ if(random.nextDouble() <= perc2) {
// calc Mutation Spot
- Integer[] pos = new Integer[R.size()];
- pos = R.toArray(pos);
- int position = random.nextInt(pos.length);
- int depth = pos[position];
+ int pr = random.nextInt(dim - r) + r;
// Mutate 1...phi into another 1...phi
- population.get(j).getGene()[depth] = random.nextInt(phi) + 1;
+ gene[QR[pr]] = (short) (random.nextInt(phi) + GENE_OFFSET);
}
- int[] gene = population.get(j).getGene();
mutations.add(makeIndividuum(gene));
-
}
- Collections.sort(mutations);
return mutations;
}
@@ -460,7 +434,7 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
* @param gene Gene to evaluate
* @return new individuum
*/
- private Individuum makeIndividuum(int[] gene) {
+ private Individuum makeIndividuum(short[] gene) {
final DBIDs ids = computeSubspaceForGene(gene, ranges);
final double fitness = (ids.size() > 0) ? sparsity(ids.size(), dbsize, k, phi) : Double.MAX_VALUE;
return new Individuum(fitness, gene);
@@ -483,7 +457,6 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
if(population.size() % 2 == 1) {
crossover.add(population.get(population.size() - 1));
}
- // Collections.sort(crossover);
return crossover;
}
@@ -497,9 +470,9 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
private Pair<Individuum, Individuum> recombineOptimized(Individuum parent1, Individuum parent2) {
Pair<Individuum, Individuum> recombinePair;
// Set of Positions in which either s1 or s2 are don't care
- ArrayList<Integer> Q = new ArrayList<>(dim);
+ TIntArrayList Q = new TIntArrayList(dim);
// Set of Positions in which neither s1 or s2 is don't care
- ArrayList<Integer> R = new ArrayList<>(dim);
+ TIntArrayList R = new TIntArrayList(dim);
for(int i = 0; i < dim; i++) {
if((parent1.getGene()[i] == DONT_CARE) && (parent2.getGene()[i] != DONT_CARE)) {
@@ -516,21 +489,21 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
Individuum best = combineRecursive(R, 0, Individuum.nullIndividuum(dim).getGene(), parent1, parent2);
// Extends gene greedily
- int[] b = best.getGene();
+ short[] b = best.getGene();
int count = k - R.size();
- Iterator<Integer> q = Q.iterator();
+ TIntIterator q = Q.iterator();
while(count > 0) {
- int[] l1 = b.clone();
- int[] l2 = b.clone();
+ short[] l1 = b.clone();
+ short[] l2 = b.clone();
while(q.hasNext()) {
int next = q.next();
// pos = next;
{
- boolean s1Null = (parent1.getGene()[next] == 0);
- boolean s2Null = (parent1.getGene()[next] == 0);
+ boolean s1Null = (parent1.getGene()[next] == DONT_CARE);
+ boolean s2Null = (parent1.getGene()[next] == DONT_CARE);
l1[next] = parent1.getGene()[next];
l2[next] = parent2.getGene()[next];
@@ -556,7 +529,7 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
}
// create the complementary String
- int[] comp = new int[dim];
+ short[] comp = new short[dim];
for(int i = 0; i < dim; i++) {
if(b[i] == parent1.getGene()[i]) {
@@ -584,26 +557,21 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
* @param parent2 Second parent
* @return best gene combination
*/
- private Individuum combineRecursive(ArrayList<Integer> r, int i, int[] current, Individuum parent1, Individuum parent2) {
+ private Individuum combineRecursive(TIntArrayList r, int i, short[] current, Individuum parent1, Individuum parent2) {
if(i == r.size()) {
return makeIndividuum(current);
}
// Position to modify
int pos = r.get(i);
// Build genes
- int[] gene1 = current.clone();
- int[] gene2 = current; // .clone();
+ short[] gene1 = current.clone();
+ short[] gene2 = current; // .clone();
gene1[pos] = parent1.getGene()[pos];
gene2[pos] = parent2.getGene()[pos];
Individuum i1 = combineRecursive(r, i + 1, gene1, parent1, parent2);
Individuum i2 = combineRecursive(r, i + 1, gene2, parent1, parent2);
// Return the better result.
- if(i1.getFitness() < i2.getFitness()) {
- return i1;
- }
- else {
- return i2;
- }
+ return (i1.getFitness() < i2.getFitness()) ? i1 : i2;
}
}
@@ -611,18 +579,21 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
* Individuum for the evolutionary search.
*
* @author Erich Schubert
- *
- * @apiviz.exclude de.lmu.ifi.dbs.elki.utilities.pairs.FCPair
*/
- private static class Individuum extends FCPair<Double, int[]> {
+ private static class Individuum implements Comparable<Individuum> {
+ double fitness;
+
+ short[] gene;
+
/**
* Constructor
*
* @param fitness Fitness
* @param gene Gene information
*/
- public Individuum(double fitness, int[] gene) {
- super(fitness, gene);
+ public Individuum(double fitness, short[] gene) {
+ this.fitness = fitness;
+ this.gene = gene;
}
/**
@@ -630,8 +601,8 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
*
* @return the gene information
*/
- public int[] getGene() {
- return second;
+ public short[] getGene() {
+ return gene;
}
/**
@@ -640,7 +611,7 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
* @return fitness
*/
public double getFitness() {
- return first;
+ return fitness;
}
/**
@@ -650,14 +621,29 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
* @return new individuum
*/
public static Individuum nullIndividuum(int dim) {
- int[] gene = new int[dim];
+ short[] gene = new short[dim];
Arrays.fill(gene, DONT_CARE);
return new Individuum(0.0, gene);
}
@Override
public String toString() {
- return "I(f=" + first + ",g=" + FormatUtil.format(second) + ")";
+ StringBuilder buf = new StringBuilder();
+ buf.append("I(f=").append(fitness);
+ buf.append(",g=");
+ for(int i = 0; i < gene.length; i++) {
+ if(i > 0) {
+ buf.append(",");
+ }
+ if(gene[i] == DONT_CARE) {
+ buf.append("*");
+ }
+ else {
+ buf.append(gene[i]);
+ }
+ }
+ buf.append(")");
+ return buf.toString();
}
@Override
@@ -666,16 +652,21 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
return false;
}
Individuum other = (Individuum) obj;
- if(other.second.length != this.second.length) {
+ if(other.gene.length != this.gene.length) {
return false;
}
- for(int i = 0; i < this.second.length; i++) {
- if(other.second[i] != this.second[i]) {
+ for(int i = 0; i < this.gene.length; i++) {
+ if(other.gene[i] != this.gene[i]) {
return false;
}
}
return true;
}
+
+ @Override
+ public int compareTo(Individuum o) {
+ return Double.compare(this.fitness, o.fitness);
+ }
}
/**
@@ -685,7 +676,7 @@ public class AggarwalYuEvolutionary<V extends NumberVector<?>> extends AbstractA
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractAggarwalYuOutlier.Parameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractAggarwalYuOutlier.Parameterizer {
/**
* Parameter to specify the number of solutions must be an integer greater
* than 1.
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/AggarwalYuNaive.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/AggarwalYuNaive.java
index 1816c3a3..4ee1969b 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/AggarwalYuNaive.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/AggarwalYuNaive.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
+package de.lmu.ifi.dbs.elki.algorithm.outlier.subspace;
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -26,13 +26,13 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier;
import java.util.ArrayList;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.logging.Logging;
@@ -46,12 +46,12 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
import de.lmu.ifi.dbs.elki.utilities.pairs.IntIntPair;
/**
- * BruteForce provides a naive brute force algorithm in which all k-subsets of
- * dimensions are examined and calculates the sparsity coefficient to find
- * outliers.
+ * BruteForce variant of the high-dimensional outlier detection algorithm by
+ * Aggarwal and Yu.
*
* The evolutionary approach is implemented as
- * {@link de.lmu.ifi.dbs.elki.algorithm.outlier.AggarwalYuEvolutionary}.
+ * {@link de.lmu.ifi.dbs.elki.algorithm.outlier.subspace.AggarwalYuEvolutionary}
+ * .
*
* <p>
* Reference: <br />
@@ -71,7 +71,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.IntIntPair;
@Title("BruteForce: Outlier detection for high dimensional data")
@Description("Examines all possible sets of k dimensional projections")
@Reference(authors = "C.C. Aggarwal, P. S. Yu", title = "Outlier detection for high dimensional data", booktitle = "Proc. ACM SIGMOD Int. Conf. on Management of Data (SIGMOD 2001), Santa Barbara, CA, 2001", url = "http://dx.doi.org/10.1145/375663.375668")
-public class AggarwalYuNaive<V extends NumberVector<?>> extends AbstractAggarwalYuOutlier<V> {
+public class AggarwalYuNaive<V extends NumberVector> extends AbstractAggarwalYuOutlier<V> {
/**
* The logger for this class.
*/
@@ -106,7 +106,7 @@ public class AggarwalYuNaive<V extends NumberVector<?>> extends AbstractAggarwal
// Set of all dim*phi ranges
ArrayList<IntIntPair> q = new ArrayList<>();
for(int i = 0; i < dimensionality; i++) {
- for(int j = 1; j <= phi; j++) {
+ for(int j = 0; j < phi; j++) {
IntIntPair s = new IntIntPair(i, j);
q.add(s);
// Add to first Rk
@@ -148,7 +148,7 @@ public class AggarwalYuNaive<V extends NumberVector<?>> extends AbstractAggarwal
final double sparsityC = sparsity(ids.size(), size, k, phi);
if(sparsityC < 0) {
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
double prev = sparsity.doubleValue(iter);
if(Double.isNaN(prev) || sparsityC < prev) {
sparsity.putDouble(iter, sparsityC);
@@ -157,7 +157,7 @@ public class AggarwalYuNaive<V extends NumberVector<?>> extends AbstractAggarwal
}
}
DoubleMinMax minmax = new DoubleMinMax();
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
double val = sparsity.doubleValue(iditer);
if(Double.isNaN(val)) {
sparsity.putDouble(iditer, 0.0);
@@ -165,7 +165,7 @@ public class AggarwalYuNaive<V extends NumberVector<?>> extends AbstractAggarwal
}
minmax.put(val);
}
- Relation<Double> scoreResult = new MaterializedRelation<>("AggarwalYuNaive", "aggarwal-yu-outlier", TypeUtil.DOUBLE, sparsity, relation.getDBIDs());
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("AggarwalYuNaive", "aggarwal-yu-outlier", sparsity, relation.getDBIDs());
OutlierScoreMeta meta = new InvertedOutlierScoreMeta(minmax.getMin(), minmax.getMax(), Double.NEGATIVE_INFINITY, 0.0);
return new OutlierResult(meta, scoreResult);
}
@@ -182,7 +182,7 @@ public class AggarwalYuNaive<V extends NumberVector<?>> extends AbstractAggarwal
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractAggarwalYuOutlier.Parameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractAggarwalYuOutlier.Parameterizer {
@Override
protected AggarwalYuNaive<V> makeInstance() {
return new AggarwalYuNaive<>(k, phi);
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/OUTRES.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/OUTRES.java
index c21542da..b3a03ba6 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/OUTRES.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/OUTRES.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.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
@@ -24,7 +24,6 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.subspace;
*/
import java.util.Arrays;
-import java.util.BitSet;
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
@@ -37,21 +36,17 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
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.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.database.ids.distance.DoubleDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPairList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDoubleDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.distancefunction.PrimitiveDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
@@ -63,6 +58,7 @@ import de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions.KernelDensityFunction
import de.lmu.ifi.dbs.elki.result.outlier.InvertedOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -93,7 +89,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
* @param <V> vector type
*/
@Reference(authors = "E. Müller, M. Schiffer, T. Seidl", title = "Adaptive outlierness for subspace outlier ranking", booktitle = "Proc. 19th ACM International Conference on Information and knowledge management")
-public class OUTRES<V extends NumberVector<?>> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
+public class OUTRES<V extends NumberVector> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -130,25 +126,21 @@ public class OUTRES<V extends NumberVector<?>> extends AbstractAlgorithm<Outlier
DoubleMinMax minmax = new DoubleMinMax();
KernelDensityEstimator kernel = new KernelDensityEstimator(relation);
- BitSet subspace = new BitSet(kernel.dim);
+ long[] subspace = BitsUtil.zero(kernel.dim);
FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("OUTRES scores", relation.size(), LOG) : null;
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- subspace.clear();
+ BitsUtil.zeroI(subspace);
double score = outresScore(0, subspace, iditer, kernel);
ranks.putDouble(iditer, score);
minmax.put(score);
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
- }
- if(progress != null) {
- progress.ensureCompleted(LOG);
+ LOG.incrementProcessed(progress);
}
+ LOG.ensureCompleted(progress);
OutlierScoreMeta meta = new InvertedOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0., 1., 1.);
- OutlierResult outresResult = new OutlierResult(meta, new MaterializedRelation<>("OUTRES", "outres-score", TypeUtil.DOUBLE, ranks, relation.getDBIDs()));
+ OutlierResult outresResult = new OutlierResult(meta, new MaterializedDoubleRelation("OUTRES", "outres-score", ranks, relation.getDBIDs()));
return outresResult;
}
@@ -161,33 +153,34 @@ public class OUTRES<V extends NumberVector<?>> extends AbstractAlgorithm<Outlier
* @param kernel Kernel
* @return Score
*/
- public double outresScore(final int s, BitSet subspace, DBIDRef id, KernelDensityEstimator kernel) {
+ public double outresScore(final int s, long[] subspace, DBIDRef id, KernelDensityEstimator kernel) {
double score = 1.0; // Initial score is 1.0
final SubspaceEuclideanDistanceFunction df = new SubspaceEuclideanDistanceFunction(subspace);
MeanVariance meanv = new MeanVariance();
for(int i = s; i < kernel.dim; i++) {
- if(subspace.get(i)) { // TODO: needed? Or should we always start with i=0?
+ if(BitsUtil.get(subspace, i)) { // TODO: needed? Or should we always start
+ // with i=0?
continue;
}
- subspace.set(i);
+ BitsUtil.setI(subspace, i);
df.setSelectedDimensions(subspace);
final double adjustedEps = kernel.adjustedEps(kernel.dim);
// Query with a larger window, to also get neighbors of neighbors
// Subspace euclidean is metric!
- final DoubleDistance range = new DoubleDistance(adjustedEps * 2.);
- RangeQuery<V, DoubleDistance> rq = QueryUtil.getRangeQuery(kernel.relation, df, range);
+ final double range = adjustedEps * 2.;
+ RangeQuery<V> rq = QueryUtil.getRangeQuery(kernel.relation, df, range);
- DistanceDBIDList<DoubleDistance> neighc = rq.getRangeForDBID(id, range);
- DoubleDistanceDBIDList neigh = refineRange(neighc, adjustedEps);
+ DoubleDBIDList neighc = rq.getRangeForDBID(id, range);
+ DoubleDBIDList neigh = refineRange(neighc, adjustedEps);
if(neigh.size() > 2) {
// Relevance test
if(relevantSubspace(subspace, neigh, kernel)) {
final double density = kernel.subspaceDensity(subspace, neigh);
// Compute mean and standard deviation for densities of neighbors.
meanv.reset();
- for (DoubleDistanceDBIDListIter neighbor = neigh.iter(); neighbor.valid(); neighbor.advance()) {
- DoubleDistanceDBIDList n2 = subsetNeighborhoodQuery(neighc, neighbor, df, adjustedEps, kernel);
+ for(DoubleDBIDListIter neighbor = neigh.iter(); neighbor.valid(); neighbor.advance()) {
+ DoubleDBIDList n2 = subsetNeighborhoodQuery(neighc, neighbor, df, adjustedEps, kernel);
meanv.put(kernel.subspaceDensity(subspace, n2));
}
final double deviation = (meanv.getMean() - density) / (2. * meanv.getSampleStddev());
@@ -199,7 +192,7 @@ public class OUTRES<V extends NumberVector<?>> extends AbstractAlgorithm<Outlier
score *= outresScore(i + 1, subspace, id, kernel);
}
}
- subspace.clear(i);
+ BitsUtil.clearI(subspace, i);
}
return score;
}
@@ -211,21 +204,14 @@ public class OUTRES<V extends NumberVector<?>> extends AbstractAlgorithm<Outlier
* @param adjustedEps New epsilon
* @return refined list
*/
- private DoubleDistanceDBIDList refineRange(DistanceDBIDList<DoubleDistance> neighc, double adjustedEps) {
- ModifiableDoubleDistanceDBIDList n = new DoubleDistanceDBIDPairList(neighc.size());
+ private DoubleDBIDList refineRange(DoubleDBIDList neighc, double adjustedEps) {
+ ModifiableDoubleDBIDList n = DBIDUtil.newDistanceDBIDList(neighc.size());
// We don't have a guarantee for this list to be sorted
- for (DistanceDBIDListIter<DoubleDistance> neighbor = neighc.iter(); neighbor.valid(); neighbor.advance()) {
- DistanceDBIDPair<DoubleDistance> p = neighbor.getDistancePair();
- if(p instanceof DoubleDistanceDBIDPair) {
- if(((DoubleDistanceDBIDPair) p).doubleDistance() <= adjustedEps) {
- n.add((DoubleDistanceDBIDPair) p);
- }
- }
- else {
- double dist = p.getDistance().doubleValue();
- if(dist <= adjustedEps) {
- n.add(dist, p);
- }
+ for(DoubleDBIDListIter neighbor = neighc.iter(); neighbor.valid(); neighbor.advance()) {
+ DoubleDBIDPair p = neighbor.getPair();
+ double dist = p.doubleValue();
+ if(dist <= adjustedEps) {
+ n.add(dist, p);
}
}
return n;
@@ -241,12 +227,12 @@ public class OUTRES<V extends NumberVector<?>> extends AbstractAlgorithm<Outlier
* @param kernel Kernel
* @return Neighbors of neighbor object
*/
- private DoubleDistanceDBIDList subsetNeighborhoodQuery(DistanceDBIDList<DoubleDistance> neighc, DBIDRef dbid, PrimitiveDoubleDistanceFunction<? super V> df, double adjustedEps, KernelDensityEstimator kernel) {
- ModifiableDoubleDistanceDBIDList n = new DoubleDistanceDBIDPairList(neighc.size());
+ private DoubleDBIDList subsetNeighborhoodQuery(DoubleDBIDList neighc, DBIDRef dbid, PrimitiveDistanceFunction<? super V> df, double adjustedEps, KernelDensityEstimator kernel) {
+ ModifiableDoubleDBIDList n = DBIDUtil.newDistanceDBIDList(neighc.size());
V query = kernel.relation.get(dbid);
- for (DistanceDBIDListIter<DoubleDistance> neighbor = neighc.iter(); neighbor.valid(); neighbor.advance()) {
- DistanceDBIDPair<DoubleDistance> p = neighbor.getDistancePair();
- double dist = df.doubleDistance(query, kernel.relation.get(p));
+ for(DoubleDBIDListIter neighbor = neighc.iter(); neighbor.valid(); neighbor.advance()) {
+ DoubleDBIDPair p = neighbor.getPair();
+ double dist = df.distance(query, kernel.relation.get(p));
if(dist <= adjustedEps) {
n.add(dist, p);
}
@@ -262,16 +248,16 @@ public class OUTRES<V extends NumberVector<?>> extends AbstractAlgorithm<Outlier
* @param kernel Kernel density estimator
* @return relevance test result
*/
- protected boolean relevantSubspace(BitSet subspace, DoubleDistanceDBIDList neigh, KernelDensityEstimator kernel) {
+ protected boolean relevantSubspace(long[] subspace, DoubleDBIDList neigh, KernelDensityEstimator kernel) {
Relation<V> relation = kernel.relation;
final double crit = K_S_CRITICAL001 / Math.sqrt(neigh.size());
- for(int dim = subspace.nextSetBit(0); dim > 0; dim = subspace.nextSetBit(dim + 1)) {
+ for(int dim = BitsUtil.nextSetBit(subspace, 0); dim > 0; dim = BitsUtil.nextSetBit(subspace, dim + 1)) {
// TODO: can we save this copy somehow?
double[] data = new double[neigh.size()];
{
int count = 0;
- for (DBIDIter neighbor = neigh.iter(); neighbor.valid(); neighbor.advance()) {
+ for(DBIDIter neighbor = neigh.iter(); neighbor.valid(); neighbor.advance()) {
V vector = relation.get(neighbor);
data[count] = vector.doubleValue(dim);
count++;
@@ -347,12 +333,12 @@ public class OUTRES<V extends NumberVector<?>> extends AbstractAlgorithm<Outlier
* @param neighbors Neighbor distance list
* @return Density
*/
- protected double subspaceDensity(BitSet subspace, DoubleDistanceDBIDList neighbors) {
- final double bandwidth = optimalBandwidth(subspace.cardinality());
+ protected double subspaceDensity(long[] subspace, DoubleDBIDList neighbors) {
+ final double bandwidth = optimalBandwidth(BitsUtil.cardinality(subspace));
double density = 0;
- for (DoubleDistanceDBIDListIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
- double v = neighbor.doubleDistance() / bandwidth;
+ for(DoubleDBIDListIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ double v = neighbor.doubleValue() / bandwidth;
if(v < 1) {
density += 1 - (v * v);
}
@@ -407,7 +393,7 @@ public class OUTRES<V extends NumberVector<?>> extends AbstractAlgorithm<Outlier
*
* @apiviz.exclude
*/
- public static class Parameterizer<O extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<O extends NumberVector> extends AbstractParameterizer {
/**
* Option ID for Epsilon parameter
*/
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/OutRankS1.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/OutRankS1.java
index 3e248bfa..a87515e5 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/OutRankS1.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/OutRankS1.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.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
@@ -37,13 +37,14 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.result.outlier.InvertedOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
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;
@@ -83,7 +84,7 @@ public class OutRankS1 extends AbstractAlgorithm<OutlierResult> implements Outli
/**
* Clustering algorithm to run.
*/
- protected SubspaceClusteringAlgorithm<? extends SubspaceModel<?>> clusteralg;
+ protected SubspaceClusteringAlgorithm<? extends SubspaceModel> clusteralg;
/**
* Weighting parameter of size vs. dimensionality score.
@@ -97,7 +98,7 @@ public class OutRankS1 extends AbstractAlgorithm<OutlierResult> implements Outli
* {@link SubspaceClusteringAlgorithm}!)
* @param alpha Alpha parameter to balance size and dimensionality.
*/
- public OutRankS1(SubspaceClusteringAlgorithm<? extends SubspaceModel<?>> clusteralg, double alpha) {
+ public OutRankS1(SubspaceClusteringAlgorithm<? extends SubspaceModel> clusteralg, double alpha) {
super();
this.clusteralg = clusteralg;
this.alpha = alpha;
@@ -105,35 +106,35 @@ public class OutRankS1 extends AbstractAlgorithm<OutlierResult> implements Outli
@Override
public OutlierResult run(Database database) {
- DBIDs ids = database.getRelation(TypeUtil.DBID).getDBIDs();
+ DBIDs ids = database.getRelation(TypeUtil.ANY).getDBIDs();
// Run the primary algorithm
- Clustering<? extends SubspaceModel<?>> clustering = clusteralg.run(database);
+ Clustering<? extends SubspaceModel> clustering = clusteralg.run(database);
WritableDoubleDataStore score = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT);
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
score.putDouble(iter, 0);
}
int maxdim = 0, maxsize = 0;
// Find maximum dimensionality and cluster size
- for (Cluster<? extends SubspaceModel<?>> cluster : clustering.getAllClusters()) {
+ for(Cluster<? extends SubspaceModel> cluster : clustering.getAllClusters()) {
maxsize = Math.max(maxsize, cluster.size());
- maxdim = Math.max(maxdim, cluster.getModel().getDimensions().cardinality());
+ maxdim = Math.max(maxdim, BitsUtil.cardinality(cluster.getModel().getDimensions()));
}
// Iterate over all clusters:
DoubleMinMax minmax = new DoubleMinMax();
- for (Cluster<? extends SubspaceModel<?>> cluster : clustering.getAllClusters()) {
+ for(Cluster<? extends SubspaceModel> cluster : clustering.getAllClusters()) {
double relsize = cluster.size() / (double) maxsize;
- double reldim = cluster.getModel().getDimensions().cardinality() / (double) maxdim;
+ double reldim = BitsUtil.cardinality(cluster.getModel().getDimensions()) / (double) maxdim;
// Process objects in the cluster
- for (DBIDIter iter = cluster.getIDs().iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = cluster.getIDs().iter(); iter.valid(); iter.advance()) {
double newscore = score.doubleValue(iter) + alpha * relsize + (1 - alpha) * reldim;
score.putDouble(iter, newscore);
minmax.put(newscore);
}
}
- Relation<Double> scoreResult = new MaterializedRelation<>("OutRank-S1", "OUTRANK_S1", TypeUtil.DOUBLE, score, ids);
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("OutRank-S1", "OUTRANK_S1", score, ids);
OutlierScoreMeta meta = new InvertedOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0, Double.POSITIVE_INFINITY);
OutlierResult res = new OutlierResult(meta, scoreResult);
res.addChildResult(clustering);
@@ -171,7 +172,7 @@ public class OutRankS1 extends AbstractAlgorithm<OutlierResult> implements Outli
/**
* Clustering algorithm to run.
*/
- protected SubspaceClusteringAlgorithm<? extends SubspaceModel<?>> algorithm = null;
+ protected SubspaceClusteringAlgorithm<? extends SubspaceModel> algorithm = null;
/**
* Alpha parameter to balance parameters
@@ -181,13 +182,13 @@ public class OutRankS1 extends AbstractAlgorithm<OutlierResult> implements Outli
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- ObjectParameter<SubspaceClusteringAlgorithm<? extends SubspaceModel<?>>> algP = new ObjectParameter<>(ALGORITHM_ID, SubspaceClusteringAlgorithm.class);
- if (config.grab(algP)) {
+ ObjectParameter<SubspaceClusteringAlgorithm<? extends SubspaceModel>> algP = new ObjectParameter<>(ALGORITHM_ID, SubspaceClusteringAlgorithm.class);
+ if(config.grab(algP)) {
algorithm = algP.instantiateClass(config);
}
DoubleParameter alphaP = new DoubleParameter(ALPHA_ID, 0.25);
alphaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
- if (config.grab(alphaP)) {
+ if(config.grab(alphaP)) {
alpha = alphaP.doubleValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/SOD.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/SOD.java
index 489f811b..b8372884 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/SOD.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/SOD.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.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,8 +23,6 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.subspace;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.BitSet;
-
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
import de.lmu.ifi.dbs.elki.data.NumberVector;
@@ -42,10 +40,10 @@ 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.DoubleDBIDPair;
import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.SharedNearestNeighborSimilarityFunction;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction;
import de.lmu.ifi.dbs.elki.logging.Logging;
@@ -59,6 +57,7 @@ import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable;
import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.TiedTopBoundedHeap;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
@@ -91,12 +90,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.has SharedNearestNeighborSimilarityFunction
*
* @param <V> the type of NumberVector handled by this Algorithm
- * @param <D> distance type
*/
@Title("SOD: Subspace outlier degree")
@Description("Outlier Detection in Axis-Parallel Subspaces of High Dimensional Data")
@Reference(authors = "H.-P. Kriegel, P. Kröger, E. Schubert, A. Zimek", title = "Outlier Detection in Axis-Parallel Subspaces of High Dimensional Data", booktitle = "Proceedings of the 13th Pacific-Asia Conference on Knowledge Discovery and Data Mining (PAKDD), Bangkok, Thailand, 2009", url = "http://dx.doi.org/10.1007/978-3-642-01307-2")
-public class SOD<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
+public class SOD<V extends NumberVector> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -115,7 +113,7 @@ public class SOD<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
/**
* Similarity function to use.
*/
- private SimilarityFunction<V, D> similarityFunction;
+ private SimilarityFunction<V> similarityFunction;
/**
* Report models.
@@ -130,7 +128,7 @@ public class SOD<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
* @param similarityFunction Shared nearest neighbor similarity function
* @param models Report generated models
*/
- public SOD(int knn, double alpha, SimilarityFunction<V, D> similarityFunction, boolean models) {
+ public SOD(int knn, double alpha, SimilarityFunction<V> similarityFunction, boolean models) {
super();
this.knn = knn;
this.alpha = alpha;
@@ -145,54 +143,51 @@ public class SOD<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
* @return Outlier result
*/
public OutlierResult run(Relation<V> relation) {
- SimilarityQuery<V, D> snnInstance = similarityFunction.instantiate(relation);
+ SimilarityQuery<V> snnInstance = similarityFunction.instantiate(relation);
FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("Assigning Subspace Outlier Degree", relation.size(), LOG) : null;
final WritableDoubleDataStore sod_scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
WritableDataStore<SODModel> sod_models = null;
- if (models) { // Models requested
+ if(models) { // Models requested
sod_models = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC, SODModel.class);
}
DoubleMinMax minmax = new DoubleMinMax();
- for (DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
- if (progress != null) {
- progress.incrementProcessed(LOG);
- }
+ for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
+ LOG.incrementProcessed(progress);
DBIDs neighborhood = getNearestNeighbors(relation, snnInstance, iter);
Vector center;
- BitSet weightVector;
+ long[] weightVector;
double sod;
- if (neighborhood.size() > 0) {
+ if(neighborhood.size() > 0) {
center = Centroid.make(relation, neighborhood);
// Note: per-dimension variances; no covariances.
double[] variances = computePerDimensionVariances(relation, center, neighborhood);
double expectationOfVariance = Mean.of(variances);
- weightVector = new BitSet(variances.length);
- for (int d = 0; d < variances.length; d++) {
- if (variances[d] < alpha * expectationOfVariance) {
- weightVector.set(d, true);
+ weightVector = BitsUtil.zero(variances.length);
+ for(int d = 0; d < variances.length; d++) {
+ if(variances[d] < alpha * expectationOfVariance) {
+ BitsUtil.setI(weightVector, d);
}
}
sod = subspaceOutlierDegree(relation.get(iter), center, weightVector);
- } else {
+ }
+ else {
center = relation.get(iter).getColumnVector();
weightVector = null;
sod = 0.;
}
- if (sod_models != null) {
+ if(sod_models != null) {
sod_models.put(iter, new SODModel(center, weightVector));
}
sod_scores.putDouble(iter, sod);
minmax.put(sod);
}
- if (progress != null) {
- progress.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(progress);
// combine results.
OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax());
- OutlierResult sodResult = new OutlierResult(meta, new MaterializedRelation<>("Subspace Outlier Degree", "sod-outlier", TypeUtil.DOUBLE, sod_scores, relation.getDBIDs()));
- if (sod_models != null) {
+ OutlierResult sodResult = new OutlierResult(meta, new MaterializedDoubleRelation("Subspace Outlier Degree", "sod-outlier", sod_scores, relation.getDBIDs()));
+ if(sod_models != null) {
Relation<SODModel> models = new MaterializedRelation<>("Subspace Outlier Model", "sod-outlier", new SimpleTypeInformation<>(SODModel.class), sod_models, relation.getDBIDs());
sodResult.addChildResult(models);
}
@@ -200,9 +195,9 @@ public class SOD<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
}
/**
- * Provides the k nearest neighbors in terms of the shared nearest neighbor
+ * Get the k nearest neighbors in terms of the shared nearest neighbor
* distance.
- * <p/>
+ *
* The query object is excluded from the knn list.
*
* FIXME: move this to the database layer.
@@ -213,20 +208,20 @@ public class SOD<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
* @return the k nearest neighbors in terms of the shared nearest neighbor
* distance without the query object
*/
- private DBIDs getNearestNeighbors(Relation<V> relation, SimilarityQuery<V, D> simQ, DBIDRef queryObject) {
+ private DBIDs getNearestNeighbors(Relation<V> relation, SimilarityQuery<V> simQ, DBIDRef queryObject) {
Heap<DoubleDBIDPair> nearestNeighbors = new TiedTopBoundedHeap<>(knn);
- for (DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
- if (DBIDUtil.equal(iter, queryObject)) {
+ for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
+ if(DBIDUtil.equal(iter, queryObject)) {
continue;
}
- double sim = simQ.similarity(queryObject, iter).doubleValue();
- if (sim > 0.) {
+ double sim = simQ.similarity(queryObject, iter);
+ if(sim > 0.) {
nearestNeighbors.add(DBIDUtil.newPair(sim, iter));
}
}
// Collect DBIDs
ArrayModifiableDBIDs dbids = DBIDUtil.newArray(nearestNeighbors.size());
- while (nearestNeighbors.size() > 0) {
+ while(nearestNeighbors.size() > 0) {
dbids.add(nearestNeighbors.poll());
}
return dbids;
@@ -240,17 +235,17 @@ public class SOD<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
* @param neighborhood Neighbors
* @return Per-dimension variances.
*/
- private static double[] computePerDimensionVariances(Relation<? extends NumberVector<?>> relation, Vector center, DBIDs neighborhood) {
+ private static double[] computePerDimensionVariances(Relation<? extends NumberVector> relation, Vector center, DBIDs neighborhood) {
double[] c = center.getArrayRef();
double[] variances = new double[c.length];
- for (DBIDIter iter = neighborhood.iter(); iter.valid(); iter.advance()) {
- NumberVector<?> databaseObject = relation.get(iter);
- for (int d = 0; d < c.length; d++) {
+ for(DBIDIter iter = neighborhood.iter(); iter.valid(); iter.advance()) {
+ NumberVector databaseObject = relation.get(iter);
+ for(int d = 0; d < c.length; d++) {
final double deviation = databaseObject.doubleValue(d) - c[d];
variances[d] += deviation * deviation;
}
}
- for (int d = 0; d < variances.length; d++) {
+ for(int d = 0; d < variances.length; d++) {
variances[d] /= neighborhood.size();
}
return variances;
@@ -264,15 +259,15 @@ public class SOD<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
* @param weightVector Weight vector
* @return sod score
*/
- private double subspaceOutlierDegree(V queryObject, Vector center, BitSet weightVector) {
- final int card = weightVector.cardinality();
- if (card == 0) {
+ private double subspaceOutlierDegree(V queryObject, Vector center, long[] weightVector) {
+ final int card = BitsUtil.cardinality(weightVector);
+ if(card == 0) {
return 0;
}
final SubspaceEuclideanDistanceFunction df = new SubspaceEuclideanDistanceFunction(weightVector);
- double distance = df.distance(queryObject, center).doubleValue();
- distance /= card; // FIXME: defined as card, should be sqrt(card),
- // unfortunately
+ double distance = df.distance(queryObject, center);
+ distance /= card; // FIXME: defined and published as card, should be
+ // sqrt(card), unfortunately
return distance;
}
@@ -300,7 +295,7 @@ public class SOD<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
/**
* Relevant dimensions.
*/
- private BitSet weightVector;
+ private long[] weightVector;
/**
* Initialize SOD Model
@@ -308,7 +303,7 @@ public class SOD<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
* @param center Center vector
* @param weightVector Selected dimensions
*/
- public SODModel(Vector center, BitSet weightVector) {
+ public SODModel(Vector center, long[] weightVector) {
this.center = center;
this.weightVector = weightVector;
}
@@ -316,7 +311,7 @@ public class SOD<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
@Override
public void writeToText(TextWriterStream out, String label) {
out.commentPrintLn(this.getClass().getSimpleName() + ":");
- out.commentPrintLn("relevant attributes (counting starts with 0): " + this.weightVector.toString());
+ out.commentPrintLn("relevant attributes (starting with 0): " + BitsUtil.toString(weightVector, ", ", 0));
out.commentPrintLn("center of neighborhood: " + out.normalizationRestore(center).toString());
out.commentPrintSeparator();
}
@@ -329,7 +324,7 @@ public class SOD<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* Parameter to specify the number of shared nearest neighbors to be
* considered for learning the subspace properties., must be an integer
@@ -366,7 +361,7 @@ public class SOD<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
/**
* The similarity function.
*/
- private SimilarityFunction<V, D> similarityFunction;
+ private SimilarityFunction<V> similarityFunction;
/**
* Track models.
@@ -376,31 +371,31 @@ public class SOD<V extends NumberVector<?>, D extends NumberDistance<D, ?>> exte
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final ObjectParameter<SimilarityFunction<V, D>> simP = new ObjectParameter<>(SIM_ID, SimilarityFunction.class, SharedNearestNeighborSimilarityFunction.class);
- if (config.grab(simP)) {
+ final ObjectParameter<SimilarityFunction<V>> simP = new ObjectParameter<>(SIM_ID, SimilarityFunction.class, SharedNearestNeighborSimilarityFunction.class);
+ if(config.grab(simP)) {
similarityFunction = simP.instantiateClass(config);
}
final IntParameter knnP = new IntParameter(KNN_ID);
knnP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
- if (config.grab(knnP)) {
+ if(config.grab(knnP)) {
knn = knnP.getValue();
}
final DoubleParameter alphaP = new DoubleParameter(ALPHA_ID, 1.1);
alphaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
- if (config.grab(alphaP)) {
+ if(config.grab(alphaP)) {
alpha = alphaP.doubleValue();
}
final Flag modelsF = new Flag(MODELS_ID);
- if (config.grab(modelsF)) {
+ if(config.grab(modelsF)) {
models = modelsF.isTrue();
}
}
@Override
- protected SOD<V, D> makeInstance() {
+ protected SOD<V> makeInstance() {
return new SOD<>(knn, alpha, similarityFunction, models);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/package-info.java
index c3951821..471d9b8d 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/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/algorithm/outlier/svm/LibSVMOneClassOutlierDetection.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/svm/LibSVMOneClassOutlierDetection.java
new file mode 100644
index 00000000..25b9cb30
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/svm/LibSVMOneClassOutlierDetection.java
@@ -0,0 +1,279 @@
+package de.lmu.ifi.dbs.elki.algorithm.outlier.svm;
+
+/*
+ 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 libsvm.svm;
+import libsvm.svm_model;
+import libsvm.svm_node;
+import libsvm.svm_parameter;
+import libsvm.svm_print_interface;
+import libsvm.svm_problem;
+import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+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.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+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.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+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.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.EnumParameter;
+
+/**
+ * Outlier-detection using one-class support vector machines.
+ *
+ * Important note: from literature, the one-class SVM is trained as if 0 was the
+ * only counterexample. Outliers will only be detected when they are close to
+ * the origin!
+ *
+ * <p>
+ * Reference:<br />
+ * B. Schölkopf, J. C. Platt, J. Shawe-Taylor, A. J. Smola, R. C. Williamson<br />
+ * Estimating the support of a high-dimensional distribution<br />
+ * Neural computation 13.7
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @param V vector type
+ */
+@Reference(authors = "B. Schölkopf, J. C. Platt, J. Shawe-Taylor, A. J. Smola, R. C. Williamson", //
+title = "Estimating the support of a high-dimensional distribution", //
+booktitle = "Neural computation 13.7")
+public class LibSVMOneClassOutlierDetection<V extends NumberVector> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(LibSVMOneClassOutlierDetection.class);
+
+ /**
+ * Kernel functions. Expose as enum for convenience.
+ *
+ * @apiviz.exclude
+ */
+ public static enum SVMKernel { //
+ LINEAR, // Linear
+ QUADRATIC, // Quadratic
+ CUBIC, // Cubic
+ RBF, // Radial basis functions
+ SIGMOID, // Sigmoid
+ }
+
+ /**
+ * Kernel function in use.
+ */
+ protected SVMKernel kernel = SVMKernel.RBF;
+
+ /**
+ * Constructor.
+ *
+ * @param kernel Kernel to use with SVM.
+ */
+ public LibSVMOneClassOutlierDetection(SVMKernel kernel) {
+ super();
+ this.kernel = kernel;
+ }
+
+ /**
+ * Run one-class SVM.
+ *
+ * @param relation Data relation
+ * @return Outlier result.
+ */
+ public OutlierResult run(Relation<V> relation) {
+ final int dim = RelationUtil.dimensionality(relation);
+ final ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs());
+
+ svm.svm_set_print_string_function(LOG_HELPER);
+
+ svm_parameter param = new svm_parameter();
+ param.svm_type = svm_parameter.ONE_CLASS;
+ param.kernel_type = svm_parameter.LINEAR;
+ param.degree = 3;
+ switch(kernel){
+ case LINEAR:
+ param.kernel_type = svm_parameter.LINEAR;
+ break;
+ case QUADRATIC:
+ param.kernel_type = svm_parameter.POLY;
+ param.degree = 2;
+ break;
+ case CUBIC:
+ param.kernel_type = svm_parameter.POLY;
+ param.degree = 3;
+ break;
+ case RBF:
+ param.kernel_type = svm_parameter.RBF;
+ break;
+ case SIGMOID:
+ param.kernel_type = svm_parameter.SIGMOID;
+ break;
+ default:
+ throw new AbortException("Invalid kernel parameter: " + kernel);
+ }
+ // TODO: expose additional parameters to the end user!
+ param.nu = 0.05;
+ param.coef0 = 0.;
+ param.cache_size = 100;
+ param.C = 1e2;
+ param.eps = 1e-4; // not used by one-class?
+ param.p = 0.1; // not used by one-class?
+ param.shrinking = 0;
+ param.probability = 0;
+ param.nr_weight = 0;
+ param.weight_label = new int[0];
+ param.weight = new double[0];
+ param.gamma = 1e-4 / dim;
+
+ // Transform data:
+ svm_problem prob = new svm_problem();
+ prob.l = relation.size();
+ prob.x = new svm_node[prob.l][];
+ prob.y = new double[prob.l];
+ {
+ DBIDIter iter = ids.iter();
+ for(int i = 0; i < prob.l && iter.valid(); iter.advance(), i++) {
+ V vec = relation.get(iter);
+ // TODO: support compact sparse vectors, too!
+ svm_node[] x = new svm_node[dim];
+ for(int d = 0; d < dim; d++) {
+ x[d] = new svm_node();
+ x[d].index = d + 1;
+ x[d].value = vec.doubleValue(d);
+ }
+ prob.x[i] = x;
+ prob.y[i] = +1;
+ }
+ }
+
+ if(LOG.isVerbose()) {
+ LOG.verbose("Training one-class SVM...");
+ }
+ String err = svm.svm_check_parameter(prob, param);
+ if(err != null) {
+ LOG.warning("svm_check_parameter: " + err);
+ }
+ svm_model model = svm.svm_train(prob, param);
+
+ if(LOG.isVerbose()) {
+ LOG.verbose("Predicting...");
+ }
+ WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_DB);
+ DoubleMinMax mm = new DoubleMinMax();
+ {
+ DBIDIter iter = ids.iter();
+ double[] buf = new double[svm.svm_get_nr_class(model)];
+ for(int i = 0; i < prob.l && iter.valid(); iter.advance(), i++) {
+ V vec = relation.get(iter);
+ svm_node[] x = new svm_node[dim];
+ for(int d = 0; d < dim; d++) {
+ x[d] = new svm_node();
+ x[d].index = d + 1;
+ x[d].value = vec.doubleValue(d);
+ }
+ svm.svm_predict_values(model, x, buf);
+ double score = -buf[0] / param.gamma; // Heuristic rescaling, sorry.
+ // Unfortunately, libsvm one-class currently yields a binary decision.
+ scores.putDouble(iter, score);
+ mm.put(score);
+ }
+ }
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("One-Class SVM Decision", "svm-outlier", scores, ids);
+ OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta(mm.getMin(), mm.getMax(), Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 0.);
+ return new OutlierResult(scoreMeta, scoreResult);
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(TypeUtil.NUMBER_VECTOR_FIELD);
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Setup logging helper for SVM.
+ */
+ static final svm_print_interface LOG_HELPER = new svm_print_interface() {
+ @Override
+ public void print(String arg0) {
+ if(LOG.isVerbose()) {
+ LOG.verbose(arg0);
+ }
+ }
+ };
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <V> Vector type
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * Parameter for kernel function.
+ */
+ private static final OptionID KERNEL_ID = new OptionID("svm.kernel", "Kernel to use with SVM.");
+
+ /**
+ * Kernel in use.
+ */
+ protected SVMKernel kernel = SVMKernel.RBF;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ EnumParameter<SVMKernel> kernelP = new EnumParameter<>(KERNEL_ID, SVMKernel.class, SVMKernel.RBF);
+ if(config.grab(kernelP)) {
+ kernel = kernelP.getValue();
+ }
+ }
+
+ @Override
+ protected LibSVMOneClassOutlierDetection<V> makeInstance() {
+ return new LibSVMOneClassOutlierDetection<>(kernel);
+ }
+ }
+}
diff --git a/test/de/lmu/ifi/dbs/elki/JUnit4Test.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/svm/package-info.java
index fc44d409..2afbbaf1 100644
--- a/test/de/lmu/ifi/dbs/elki/JUnit4Test.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/svm/package-info.java
@@ -1,10 +1,14 @@
-package de.lmu.ifi.dbs.elki;
+/**
+ * Support-Vector-Machines for outlier detection.
+ *
+ * @author Erich Schubert
+ */
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -22,16 +26,4 @@ package de.lmu.ifi.dbs.elki;
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 org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * This interface is used for test-discovery by the {@link AllTests} TestSuite.
- *
- * @author Erich Schubert
- */
-@RunWith(JUnit4.class)
-public interface JUnit4Test {
- // empty marker interface
-} \ No newline at end of file
+package de.lmu.ifi.dbs.elki.algorithm.outlier.svm; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/ByLabelOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/ByLabelOutlier.java
index d10eaef8..f8b4eb3e 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/ByLabelOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/ByLabelOutlier.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.trivial;
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
@@ -36,7 +36,8 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
@@ -117,7 +118,7 @@ public class ByLabelOutlier extends AbstractAlgorithm<OutlierResult> implements
final double score = (pattern.matcher(label).matches()) ? 1 : 0;
scores.putDouble(iditer, score);
}
- Relation<Double> scoreres = new MaterializedRelation<>("By label outlier scores", "label-outlier", TypeUtil.DOUBLE, scores, relation.getDBIDs());
+ DoubleRelation scoreres = new MaterializedDoubleRelation("By label outlier scores", "label-outlier", scores, relation.getDBIDs());
OutlierScoreMeta meta = new ProbabilisticOutlierScore();
return new OutlierResult(meta, scoreres);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialAllOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialAllOutlier.java
index 44a7975f..c8920617 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialAllOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialAllOutlier.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.trivial;
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,7 +31,8 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
@@ -73,7 +74,7 @@ public class TrivialAllOutlier extends AbstractAlgorithm<OutlierResult> implemen
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
scores.putDouble(iditer, 1.0);
}
- Relation<Double> scoreres = new MaterializedRelation<>("Trivial all-outlier score", "all-outlier", TypeUtil.DOUBLE, scores, relation.getDBIDs());
+ DoubleRelation scoreres = new MaterializedDoubleRelation("Trivial all-outlier score", "all-outlier", scores, relation.getDBIDs());
OutlierScoreMeta meta = new ProbabilisticOutlierScore();
return new OutlierResult(meta, scoreres);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialAverageCoordinateOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialAverageCoordinateOutlier.java
index 6f2f2f38..dbf338f1 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialAverageCoordinateOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialAverageCoordinateOutlier.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.trivial;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -32,7 +32,8 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
@@ -72,13 +73,13 @@ public class TrivialAverageCoordinateOutlier extends AbstractAlgorithm<OutlierRe
* @param relation Relation
* @return Result
*/
- public OutlierResult run(Relation<? extends NumberVector<?>> relation) {
+ public OutlierResult run(Relation<? extends NumberVector> relation) {
WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT);
DoubleMinMax minmax = new DoubleMinMax();
Mean m = new Mean();
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
m.reset();
- NumberVector<?> nv = relation.get(iditer);
+ NumberVector nv = relation.get(iditer);
for (int i = 0; i < nv.getDimensionality(); i++) {
m.put(nv.doubleValue(i));
}
@@ -86,7 +87,7 @@ public class TrivialAverageCoordinateOutlier extends AbstractAlgorithm<OutlierRe
scores.putDouble(iditer, score);
minmax.put(score);
}
- Relation<Double> scoreres = new MaterializedRelation<>("Trivial mean score", "mean-outlier", TypeUtil.DOUBLE, scores, relation.getDBIDs());
+ DoubleRelation scoreres = new MaterializedDoubleRelation("Trivial mean score", "mean-outlier", scores, relation.getDBIDs());
OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax());
return new OutlierResult(meta, scoreres);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialGeneratedOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialGeneratedOutlier.java
index 2e952b5f..adaf9431 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialGeneratedOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialGeneratedOutlier.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.trivial;
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
@@ -39,7 +39,8 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
@@ -99,7 +100,7 @@ public class TrivialGeneratedOutlier extends AbstractAlgorithm<OutlierResult> im
@Override
public OutlierResult run(Database database) {
- Relation<NumberVector<?>> vecs = database.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
+ Relation<NumberVector> vecs = database.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
Relation<Model> models = database.getRelation(new SimpleTypeInformation<>(Model.class));
// Prefer a true class label
try {
@@ -120,7 +121,7 @@ public class TrivialGeneratedOutlier extends AbstractAlgorithm<OutlierResult> im
* @param labels Label relation
* @return Outlier result
*/
- public OutlierResult run(Relation<Model> models, Relation<NumberVector<?>> vecs, Relation<?> labels) {
+ public OutlierResult run(Relation<Model> models, Relation<NumberVector> vecs, Relation<?> labels) {
WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(models.getDBIDs(), DataStoreFactory.HINT_HOT);
HashSet<GeneratorSingleCluster> generators = new HashSet<>();
@@ -180,7 +181,7 @@ public class TrivialGeneratedOutlier extends AbstractAlgorithm<OutlierResult> im
}
scores.putDouble(iditer, score);
}
- Relation<Double> scoreres = new MaterializedRelation<>("Model outlier scores", "model-outlier", TypeUtil.DOUBLE, scores, models.getDBIDs());
+ DoubleRelation scoreres = new MaterializedDoubleRelation("Model outlier scores", "model-outlier", scores, models.getDBIDs());
OutlierScoreMeta meta = new ProbabilisticOutlierScore(0., 1.);
return new OutlierResult(meta, scoreres);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialNoOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialNoOutlier.java
index ff3d0296..0a3e27b4 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialNoOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/TrivialNoOutlier.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.trivial;
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,7 +31,8 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
@@ -73,7 +74,7 @@ public class TrivialNoOutlier extends AbstractAlgorithm<OutlierResult> implement
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
scores.putDouble(iditer, 0.0);
}
- Relation<Double> scoreres = new MaterializedRelation<>("Trivial no-outlier score", "no-outlier", TypeUtil.DOUBLE, scores, relation.getDBIDs());
+ DoubleRelation scoreres = new MaterializedDoubleRelation("Trivial no-outlier score", "no-outlier", scores, relation.getDBIDs());
OutlierScoreMeta meta = new ProbabilisticOutlierScore();
return new OutlierResult(meta, scoreres);
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/package-info.java
index c927cae4..a6ea3186 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/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/algorithm/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/package-info.java
index ba8a7b56..c5e53631 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/package-info.java
@@ -13,7 +13,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/algorithm/statistics/AddSingleScale.java b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/AddSingleScale.java
index 8bd5f057..b321378b 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/statistics/AddSingleScale.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/AddSingleScale.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.statistics;
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
@@ -73,7 +73,7 @@ public class AddSingleScale implements Algorithm {
public Result run(Database database) {
for(Relation<?> rel : database.getRelations()) {
if(TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(rel.getDataTypeInformation())) {
- ScalesResult res = run((Relation<? extends NumberVector<?>>) rel);
+ ScalesResult res = run((Relation<? extends NumberVector>) rel);
ResultUtil.addChildResult(rel, res);
}
}
@@ -86,13 +86,13 @@ public class AddSingleScale implements Algorithm {
* @param rel Relation
* @return Scales
*/
- private ScalesResult run(Relation<? extends NumberVector<?>> rel) {
+ private ScalesResult run(Relation<? extends NumberVector> rel) {
final int dim = RelationUtil.dimensionality(rel);
LinearScale[] scales = new LinearScale[dim];
if(minmax == null) {
DoubleMinMax mm = new DoubleMinMax();
for(DBIDIter iditer = rel.iterDBIDs(); iditer.valid(); iditer.advance()) {
- NumberVector<?> vec = rel.get(iditer);
+ NumberVector vec = rel.get(iditer);
for(int d = 0; d < dim; d++) {
final double val = vec.doubleValue(d);
if(val != val) {
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/statistics/AveragePrecisionAtK.java b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/AveragePrecisionAtK.java
index 490f8ba6..b7b39491 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/statistics/AveragePrecisionAtK.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/AveragePrecisionAtK.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.statistics;
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,24 +27,24 @@ import java.util.ArrayList;
import java.util.Collection;
import de.lmu.ifi.dbs.elki.algorithm.AbstractDistanceBasedAlgorithm;
-import de.lmu.ifi.dbs.elki.data.ClassLabel;
import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.LabelList;
+import de.lmu.ifi.dbs.elki.data.type.AlternativeTypeInformation;
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.Database;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.distancefunction.DistanceFunction;
-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.FiniteProgress;
-import de.lmu.ifi.dbs.elki.math.MeanVariance;
+import de.lmu.ifi.dbs.elki.math.MeanVarianceMinMax;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.result.CollectionResult;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -52,7 +52,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.LongParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
/**
* Evaluate a distance functions performance by computing the average precision
@@ -60,10 +60,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.LongParameter;
*
* @author Erich Schubert
*
- * @param <V> Vector type
- * @param <D> Distance type
+ * @param <O> Object type
*/
-public class AveragePrecisionAtK<V extends Object, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<V, D, CollectionResult<DoubleVector>> {
+public class AveragePrecisionAtK<O> extends AbstractDistanceBasedAlgorithm<O, CollectionResult<DoubleVector>> {
/**
* The logger for this class.
*/
@@ -82,7 +81,7 @@ public class AveragePrecisionAtK<V extends Object, D extends NumberDistance<D, ?
/**
* Random sampling seed.
*/
- private Long seed = null;
+ private RandomFactory random = null;
/**
* Include query object in evaluation.
@@ -95,14 +94,14 @@ public class AveragePrecisionAtK<V extends Object, D extends NumberDistance<D, ?
* @param distanceFunction Distance function
* @param k K parameter
* @param sampling Sampling rate
- * @param seed Random sampling seed (may be null)
+ * @param random Random sampling generator
* @param includeSelf Include query object in evaluation
*/
- public AveragePrecisionAtK(DistanceFunction<? super V, D> distanceFunction, int k, double sampling, Long seed, boolean includeSelf) {
+ public AveragePrecisionAtK(DistanceFunction<? super O> distanceFunction, int k, double sampling, RandomFactory random, boolean includeSelf) {
super(distanceFunction);
this.k = k;
this.sampling = sampling;
- this.seed = seed;
+ this.random = random;
this.includeSelf = includeSelf;
}
@@ -114,72 +113,99 @@ public class AveragePrecisionAtK<V extends Object, D extends NumberDistance<D, ?
* @param lrelation Relation for class label comparison
* @return Vectors containing mean and standard deviation.
*/
- public CollectionResult<DoubleVector> run(Database database, Relation<V> relation, Relation<ClassLabel> lrelation) {
- final DistanceQuery<V, D> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
+ public CollectionResult<DoubleVector> run(Database database, Relation<O> relation, Relation<?> lrelation) {
+ final DistanceQuery<O> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
final int qk = k + (includeSelf ? 0 : 1);
- final KNNQuery<V, D> knnQuery = database.getKNNQuery(distQuery, qk);
+ final KNNQuery<O> knnQuery = database.getKNNQuery(distQuery, qk);
- MeanVariance[] mvs = MeanVariance.newArray(k);
+ MeanVarianceMinMax[] mvs = MeanVarianceMinMax.newArray(k);
final DBIDs ids;
- if(sampling < 1.0) {
+ if(sampling < 1.) {
int size = Math.max(1, (int) (sampling * relation.size()));
- ids = DBIDUtil.randomSample(relation.getDBIDs(), size, seed);
+ ids = DBIDUtil.randomSample(relation.getDBIDs(), size, random);
+ }
+ else if(sampling > 1.) {
+ ids = DBIDUtil.randomSample(relation.getDBIDs(), (int) sampling, random);
}
else {
ids = relation.getDBIDs();
}
- if(LOG.isVerbose()) {
- LOG.verbose("Processing points...");
- }
FiniteProgress objloop = LOG.isVerbose() ? new FiniteProgress("Computing nearest neighbors", ids.size(), LOG) : null;
// sort neighbors
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- KNNList<D> knn = knnQuery.getKNNForDBID(iter, qk);
+ KNNList knn = knnQuery.getKNNForDBID(iter, qk);
Object label = lrelation.get(iter);
int positive = 0, i = 0;
for(DBIDIter ri = knn.iter(); i < k && ri.valid(); ri.advance()) {
if(!includeSelf && DBIDUtil.equal(iter, ri)) {
+ // Do not increment i.
continue;
}
- Object olabel = lrelation.get(ri);
- if(label == null) {
- if(olabel == null) {
- positive += 1;
- }
- }
- else {
- if(label.equals(olabel)) {
- positive += 1;
- }
- }
+ positive += match(label, lrelation.get(ri)) ? 1 : 0;
final double precision = positive / (double) (i + 1);
mvs[i].put(precision);
i++;
}
- if(objloop != null) {
- objloop.incrementProcessed(LOG);
- }
- }
- if(objloop != null) {
- objloop.ensureCompleted(LOG);
+ LOG.incrementProcessed(objloop);
}
- // Collections.sort(results);
+ LOG.ensureCompleted(objloop);
// Transform Histogram into a Double Vector array.
Collection<DoubleVector> res = new ArrayList<>(k);
for(int i = 0; i < k; i++) {
- DoubleVector row = new DoubleVector(new double[] { mvs[i].getMean(), mvs[i].getSampleStddev() });
+ final MeanVarianceMinMax mv = mvs[i];
+ final double std = mv.getCount() > 1. ? mv.getSampleStddev() : 0.;
+ DoubleVector row = new DoubleVector(new double[] { i + 1, mv.getMean(), std, mv.getMin(), mv.getMax(), mv.getCount() });
res.add(row);
}
return new CollectionResult<>("Average Precision", "average-precision", res);
}
+ /**
+ * Test whether two relation agree.
+ *
+ * @param ref Reference object
+ * @param test Test object
+ * @return {@code true} if the objects match
+ */
+ protected static boolean match(Object ref, Object test) {
+ if(ref == null) {
+ return false;
+ }
+ // Cheap and fast, may hold for class labels!
+ if(ref == test) {
+ return true;
+ }
+ if(ref instanceof LabelList && test instanceof LabelList) {
+ final LabelList lref = (LabelList) ref;
+ final LabelList ltest = (LabelList) test;
+ final int s1 = lref.size(), s2 = ltest.size();
+ if(s1 == 0 || s2 == 0) {
+ return false;
+ }
+ for(int i = 0; i < s1; i++) {
+ String l1 = lref.get(i);
+ if(l1 == null) {
+ continue;
+ }
+ for(int j = 0; j < s2; j++) {
+ if(l1.equals(ltest.get(j))) {
+ return true;
+ }
+ }
+ }
+ }
+ // Fallback to equality, e.g. on class labels
+ return ref.equals(test);
+ }
+
@Override
public TypeInformation[] getInputTypeRestriction() {
- return TypeUtil.array(getDistanceFunction().getInputTypeRestriction(), TypeUtil.CLASSLABEL);
+ TypeInformation cls = new AlternativeTypeInformation(TypeUtil.CLASSLABEL, TypeUtil.LABELLIST);
+ return TypeUtil.array(getDistanceFunction().getInputTypeRestriction(), cls);
}
@Override
@@ -193,8 +219,10 @@ public class AveragePrecisionAtK<V extends Object, D extends NumberDistance<D, ?
* @author Erich Schubert
*
* @apiviz.exclude
+ *
+ * @param <O> Object type
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<V, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Parameter k to compute the average precision at.
*/
@@ -228,7 +256,7 @@ public class AveragePrecisionAtK<V extends Object, D extends NumberDistance<D, ?
/**
* Random sampling seed.
*/
- protected Long seed = null;
+ protected RandomFactory seed = null;
/**
* Include query object in evaluation.
@@ -250,7 +278,7 @@ public class AveragePrecisionAtK<V extends Object, D extends NumberDistance<D, ?
if(config.grab(samplingP)) {
sampling = samplingP.getValue();
}
- final LongParameter rndP = new LongParameter(SEED_ID);
+ final RandomParameter rndP = new RandomParameter(SEED_ID);
rndP.setOptional(true);
if(config.grab(rndP)) {
seed = rndP.getValue();
@@ -262,7 +290,7 @@ public class AveragePrecisionAtK<V extends Object, D extends NumberDistance<D, ?
}
@Override
- protected AveragePrecisionAtK<V, D> makeInstance() {
+ protected AveragePrecisionAtK<O> makeInstance() {
return new AveragePrecisionAtK<>(distanceFunction, k, sampling, seed, includeSelf);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/statistics/DistanceStatisticsWithClasses.java b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/DistanceStatisticsWithClasses.java
index 244af0ca..e2cbfc1a 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/statistics/DistanceStatisticsWithClasses.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/DistanceStatisticsWithClasses.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.statistics;
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
@@ -47,7 +47,6 @@ import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
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.distancefunction.DistanceFunction;
-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.FiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
@@ -76,12 +75,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
-// TODO: optimize for double distances.
@Title("Distance Histogram")
@Description("Computes a histogram over the distances occurring in the data set.")
-public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, CollectionResult<DoubleVector>> {
+public class DistanceStatisticsWithClasses<O> extends AbstractDistanceBasedAlgorithm<O, CollectionResult<DoubleVector>> {
/**
* The logger for this class.
*/
@@ -125,7 +122,7 @@ public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> ex
* @param exact Exactness flag
* @param sampling Sampling flag
*/
- public DistanceStatisticsWithClasses(DistanceFunction<? super O, D> distanceFunction, int numbins, boolean exact, boolean sampling) {
+ public DistanceStatisticsWithClasses(DistanceFunction<? super O> distanceFunction, int numbins, boolean exact, boolean sampling) {
super(distanceFunction);
this.numbin = numbins;
this.exact = exact;
@@ -135,7 +132,7 @@ public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> ex
@Override
public HistogramResult<DoubleVector> run(Database database) {
final Relation<O> relation = database.getRelation(getInputTypeRestriction()[0]);
- final DistanceQuery<O, D> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
+ final DistanceQuery<O> distFunc = database.getDistanceQuery(relation, getDistanceFunction());
final StepProgress stepprog = LOG.isVerbose() ? new StepProgress("Distance statistics", 2) : null;
@@ -159,9 +156,7 @@ public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> ex
MeanVariance modif = new MeanVariance();
// Histogram
final ObjHistogram<long[]> histogram;
- if(stepprog != null) {
- stepprog.beginStep(1, "Prepare histogram.", LOG);
- }
+ LOG.beginStep(stepprog, 1, "Prepare histogram.");
if(exact) {
gminmax = exactMinMax(relation, distFunc);
histogram = new LongArrayStaticHistogram(numbin, gminmax.getMin(), gminmax.getMax(), 2);
@@ -206,9 +201,7 @@ public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> ex
};
}
- if(stepprog != null) {
- stepprog.beginStep(2, "Build histogram.", LOG);
- }
+ LOG.beginStep(stepprog, 2, "Build histogram.");
final FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("Distance computations", relation.size(), LOG) : null;
// iterate per cluster
final long[] incFirst = new long[] { 1L, 0L };
@@ -222,7 +215,7 @@ public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> ex
if(DBIDUtil.equal(id1, iter2)) {
continue;
}
- double d = distFunc.distance(id1, iter2).doubleValue();
+ double d = distFunc.distance(id1, iter2);
histogram.putData(d, incFirst);
@@ -247,7 +240,7 @@ public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> ex
if(DBIDUtil.equal(id1, iter2)) {
continue;
}
- double d = distFunc.distance(id1, iter2).doubleValue();
+ double d = distFunc.distance(id1, iter2);
histogram.putData(d, incSecond);
@@ -261,21 +254,15 @@ public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> ex
// min/max
gominmax.put(ominmax.getMin());
gominmax.put(ominmax.getMax());
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(progress);
}
}
- if(progress != null) {
- progress.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(progress);
// Update values (only needed for sampling case).
gminmax.setFirst(Math.min(giminmax.getMin(), gominmax.getMin()));
gminmax.setSecond(Math.max(giminmax.getMax(), gominmax.getMax()));
- if(stepprog != null) {
- stepprog.setCompleted(LOG);
- }
+ LOG.setCompleted(stepprog);
// count the number of samples we have in the data
long inum = 0;
@@ -316,7 +303,7 @@ public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> ex
* @param distFunc Distance function to use
* @return Minimum and maximum
*/
- private DoubleMinMax sampleMinMax(Relation<O> relation, DistanceQuery<O, D> distFunc) {
+ private DoubleMinMax sampleMinMax(Relation<O> relation, DistanceQuery<O> distFunc) {
int size = relation.size();
Random rnd = new Random();
// estimate minimum and maximum.
@@ -344,12 +331,12 @@ public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> ex
if(DBIDUtil.equal(iter, pair)) {
continue;
}
- double d = distFunc.distance(iter, pair).doubleValue();
+ double d = distFunc.distance(iter, pair);
np.add(DBIDUtil.newPair(d, iter));
np.add(DBIDUtil.newPair(d, pair));
}
for(DBIDIter iter2 = randomset.iter(); iter2.valid(); iter2.advance()) {
- double d = distFunc.distance(iter, iter2).doubleValue();
+ double d = distFunc.distance(iter, iter2);
np.add(DBIDUtil.newPair(d, iter));
np.add(DBIDUtil.newPair(d, iter2));
}
@@ -363,12 +350,12 @@ public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> ex
if(DBIDUtil.equal(iter, pair)) {
continue;
}
- double d = distFunc.distance(iter, pair).doubleValue();
+ double d = distFunc.distance(iter, pair);
np2.add(DBIDUtil.newPair(d, iter));
np2.add(DBIDUtil.newPair(d, pair));
}
for(DBIDIter iter2 = randomset.iter(); iter2.valid(); iter2.advance()) {
- double d = distFunc.distance(iter, iter2).doubleValue();
+ double d = distFunc.distance(iter, iter2);
np.add(DBIDUtil.newPair(d, iter));
np.add(DBIDUtil.newPair(d, iter2));
}
@@ -393,7 +380,8 @@ public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> ex
* @param distFunc Distance function
* @return Exact maximum and minimum
*/
- private DoubleMinMax exactMinMax(Relation<O> relation, DistanceQuery<O, D> distFunc) {
+ private DoubleMinMax exactMinMax(Relation<O> relation, DistanceQuery<O> distFunc) {
+ final FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("Exact fitting distance computations", relation.size(), LOG) : null;
DoubleMinMax minmax = new DoubleMinMax();
// find exact minimum and maximum first.
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
@@ -402,10 +390,12 @@ public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> ex
if(DBIDUtil.equal(iditer, iditer2)) {
continue;
}
- double d = distFunc.distance(iditer, iditer2).doubleValue();
+ double d = distFunc.distance(iditer, iditer2);
minmax.put(d);
}
+ LOG.incrementProcessed(progress);
}
+ LOG.ensureCompleted(progress);
return minmax;
}
@@ -447,8 +437,10 @@ public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> ex
* @author Erich Schubert
*
* @apiviz.exclude
+ *
+ * @param <O> Object type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Number of bins to use in sampling.
*/
@@ -490,7 +482,7 @@ public class DistanceStatisticsWithClasses<O, D extends NumberDistance<D, ?>> ex
}
@Override
- protected DistanceStatisticsWithClasses<O, D> makeInstance() {
+ protected DistanceStatisticsWithClasses<O> makeInstance() {
return new DistanceStatisticsWithClasses<>(distanceFunction, numbin, exact, sampling);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/statistics/EvaluateRankingQuality.java b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/EvaluateRankingQuality.java
index d5d8e407..7987804a 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/statistics/EvaluateRankingQuality.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/EvaluateRankingQuality.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.statistics;
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
@@ -41,13 +41,12 @@ import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
-import de.lmu.ifi.dbs.elki.evaluation.roc.ROC;
+import de.lmu.ifi.dbs.elki.evaluation.scores.ROCEvaluation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.MathUtil;
@@ -84,11 +83,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*
* @author Erich Schubert
* @param <V> Vector type
- * @param <D> Distance type
*/
@Title("Evaluate Ranking Quality")
@Description("Evaluates the effectiveness of a distance function via the obtained rankings.")
-public class EvaluateRankingQuality<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<V, D, CollectionResult<DoubleVector>> {
+public class EvaluateRankingQuality<V extends NumberVector> extends AbstractDistanceBasedAlgorithm<V, CollectionResult<DoubleVector>> {
/**
* The logger for this class.
*/
@@ -105,7 +103,7 @@ public class EvaluateRankingQuality<V extends NumberVector<?>, D extends NumberD
* @param distanceFunction Distance function
* @param numbins Number of bins
*/
- public EvaluateRankingQuality(DistanceFunction<? super V, D> distanceFunction, int numbins) {
+ public EvaluateRankingQuality(DistanceFunction<? super V> distanceFunction, int numbins) {
super(distanceFunction);
this.numbins = numbins;
}
@@ -118,8 +116,8 @@ public class EvaluateRankingQuality<V extends NumberVector<?>, D extends NumberD
@Override
public HistogramResult<DoubleVector> run(Database database) {
final Relation<V> relation = database.getRelation(getInputTypeRestriction()[0]);
- final DistanceQuery<V, D> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
- final KNNQuery<V, D> knnQuery = database.getKNNQuery(distQuery, relation.size());
+ final DistanceQuery<V> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
+ final KNNQuery<V> knnQuery = database.getKNNQuery(distQuery, relation.size());
if(LOG.isVerbose()) {
LOG.verbose("Preprocessing clusters...");
@@ -156,19 +154,15 @@ public class EvaluateRankingQuality<V extends NumberVector<?>, D extends NumberD
Collections.sort(cmem);
for(int ind = 0; ind < cmem.size(); ind++) {
- KNNList<D> knn = knnQuery.getKNNForDBID(cmem.get(ind), relation.size());
- double result = ROC.computeROCAUCDistanceResult(relation.size(), clus, knn);
+ KNNList knn = knnQuery.getKNNForDBID(cmem.get(ind), relation.size());
+ double result = new ROCEvaluation().evaluate(clus, knn);
hist.put(((double) ind) / clus.size(), result);
- if(rocloop != null) {
- rocloop.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(rocloop);
}
}
- if(rocloop != null) {
- rocloop.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(rocloop);
// Collections.sort(results);
// Transform Histogram into a Double Vector array.
@@ -196,8 +190,10 @@ public class EvaluateRankingQuality<V extends NumberVector<?>, D extends NumberD
* @author Erich Schubert
*
* @apiviz.exclude
+ *
+ * @param <V> Vector type
*/
- public static class Parameterizer<V extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<V, D> {
+ public static class Parameterizer<V extends NumberVector> extends AbstractDistanceBasedAlgorithm.Parameterizer<V> {
/**
* Number of bins to use.
*/
@@ -214,7 +210,7 @@ public class EvaluateRankingQuality<V extends NumberVector<?>, D extends NumberD
}
@Override
- protected EvaluateRankingQuality<V, D> makeInstance() {
+ protected EvaluateRankingQuality<V> makeInstance() {
return new EvaluateRankingQuality<>(distanceFunction, numbins);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/statistics/HopkinsStatisticClusteringTendency.java b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/HopkinsStatisticClusteringTendency.java
new file mode 100644
index 00000000..9def1bee
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/HopkinsStatisticClusteringTendency.java
@@ -0,0 +1,416 @@
+package de.lmu.ifi.dbs.elki.algorithm.statistics;
+/*
+ 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 java.util.Random;
+
+import de.lmu.ifi.dbs.elki.algorithm.AbstractPrimitiveDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
+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.database.relation.RelationUtil;
+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.distancefunction.minkowski.EuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.Logging.Level;
+import de.lmu.ifi.dbs.elki.logging.statistics.DoubleStatistic;
+import de.lmu.ifi.dbs.elki.logging.statistics.LongStatistic;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.MeanVariance;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.statistics.distribution.BetaDistribution;
+import de.lmu.ifi.dbs.elki.result.Result;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.AllOrNoneMustBeSetGlobalConstraint;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.EqualSizeGlobalConstraint;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleListParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
+
+/**
+ * The Hopkins Statistic of Clustering Tendency measures the probability that a
+ * data set is generated by a uniform data distribution.
+ *
+ * The statistic compares the ratio of the 1NN distance for objects from the
+ * data set compared to the 1NN distances of uniform distributed objects.
+ *
+ * Reference:
+ * <p>
+ * B. Hopkins and J. G. Skellam<br />
+ * A new method for determining the type of distribution of plant individuals<br />
+ * Annals of Botany, 18(2), 213-227.
+ * </p>
+ *
+ * @author Lisa Reichert
+ * @author Erich Schubert
+ */
+// TODO: allow using more than one k
+@Reference(authors = "B. Hopkins and J. G. Skellam", //
+title = "A new method for determining the type of distribution of plant individuals", //
+booktitle = "Annals of Botany, 18(2), 213-227", //
+url = "http://aob.oxfordjournals.org/content/18/2/213.short")
+public class HopkinsStatisticClusteringTendency extends AbstractPrimitiveDistanceBasedAlgorithm<NumberVector, Result> {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(HopkinsStatisticClusteringTendency.class);
+
+ /**
+ * The parameter sampleSizes
+ */
+ private int sampleSize;
+
+ /**
+ * Number of repetitions
+ */
+ private int rep;
+
+ /**
+ * Nearest neighbor to use.
+ */
+ private int k;
+
+ /**
+ * Random generator seeding.
+ */
+ private RandomFactory random;
+
+ /**
+ * Stores the maximum in each dimension.
+ */
+ private double[] maxima = new double[0];
+
+ /**
+ * Stores the minimum in each dimension.
+ */
+ private double[] minima = new double[0];
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function
+ * @param samplesize Sample size
+ * @param random Random generator
+ * @param rep Number of repetitions
+ * @param k Nearest neighbor to use
+ * @param minima Data space minima, may be {@code null} (get from data).
+ * @param maxima Data space minima, may be {@code null} (get from data).
+ */
+ public HopkinsStatisticClusteringTendency(NumberVectorDistanceFunction<? super NumberVector> distanceFunction, int samplesize, RandomFactory random, int rep, int k, double[] minima, double[] maxima) {
+ super(distanceFunction);
+ this.sampleSize = samplesize;
+ this.random = random;
+ this.rep = rep;
+ this.k = k;
+ this.minima = minima;
+ this.maxima = maxima;
+ }
+
+ /**
+ * Runs the algorithm in the timed evaluation part.
+ *
+ * @param database Database context
+ * @param relation Relation to analyze
+ */
+ public Result run(Database database, Relation<NumberVector> relation) {
+ final int dim = RelationUtil.dimensionality(relation);
+ final DistanceQuery<NumberVector> distanceQuery = database.getDistanceQuery(relation, getDistanceFunction());
+ final KNNQuery<NumberVector> knnQuery = database.getKNNQuery(distanceQuery, k + 1);
+
+ final double[] min = new double[dim], extend = new double[dim];
+ initializeDataExtends(relation, dim, min, extend);
+
+ if(!LOG.isStatistics()) {
+ LOG.warning("This algorithm must be used with at least logging level " + Level.STATISTICS);
+ }
+
+ MeanVariance hmean = new MeanVariance(), umean = new MeanVariance(), wmean = new MeanVariance();
+ // compute the hopkins value several times and use the average value for a
+ // more stable result
+ for(int j = 0; j < this.rep; j++) {
+ // Compute NN distances for random objects from within the database
+ double w = computeNNForRealData(knnQuery, relation, dim);
+ // Compute NN distances for randomly created new uniform objects
+ double u = computeNNForUniformData(knnQuery, min, extend);
+ // compute hopkins statistik
+ double h = u / (u + w); // = a / (1+a)
+ hmean.put(h);
+ umean.put(u);
+ wmean.put(w);
+ }
+ final String prefix = this.getClass().getName();
+ LOG.statistics(new LongStatistic(prefix + ".samplesize", sampleSize));
+ LOG.statistics(new LongStatistic(prefix + ".dim", dim));
+ LOG.statistics(new LongStatistic(prefix + ".hopkins.nearest-neighbor", k));
+ LOG.statistics(new DoubleStatistic(prefix + ".hopkins.h.mean", hmean.getMean()));
+ LOG.statistics(new DoubleStatistic(prefix + ".hopkins.u.mean", umean.getMean()));
+ LOG.statistics(new DoubleStatistic(prefix + ".hopkins.w.mean", wmean.getMean()));
+ if(rep > 1) {
+ LOG.statistics(new DoubleStatistic(prefix + ".hopkins.h.std", hmean.getSampleStddev()));
+ LOG.statistics(new DoubleStatistic(prefix + ".hopkins.u.std", umean.getSampleStddev()));
+ LOG.statistics(new DoubleStatistic(prefix + ".hopkins.w.std", wmean.getSampleStddev()));
+ }
+ // Evaluate:
+ double x = hmean.getMean();
+ // See Hopkins for a proof that x is supposedly Beta distributed.
+ double ix = BetaDistribution.regularizedIncBeta(x, sampleSize, sampleSize);
+ double p = (x > .5) ? (1. - ix) : ix;
+ LOG.statistics(new DoubleStatistic(prefix + ".hopkins.p", p));
+ return null;
+ }
+
+ /**
+ * Search nearest neighbors for <em>real</em> data members.
+ *
+ * @param knnQuery KNN query
+ * @param relation Data relation
+ * @return Aggregated 1NN distances
+ */
+ protected double computeNNForRealData(final KNNQuery<NumberVector> knnQuery, Relation<NumberVector> relation, final int dim) {
+ double w = 0.;
+ ModifiableDBIDs dataSampleIds = DBIDUtil.randomSample(relation.getDBIDs(), sampleSize, random);
+ for(DBIDIter iter = dataSampleIds.iter(); iter.valid(); iter.advance()) {
+ final double kdist = knnQuery.getKNNForDBID(iter, k + 1).getKNNDistance();
+ w += MathUtil.powi(kdist, dim);
+ }
+ return w;
+ }
+
+ /**
+ * Search nearest neighbors for <em>artificial, uniform</em> data.
+ *
+ * @param knnQuery KNN query
+ * @param min Data minima
+ * @param extend Data extend
+ * @return Aggregated 1NN distances
+ */
+ protected double computeNNForUniformData(final KNNQuery<NumberVector> knnQuery, final double[] min, final double[] extend) {
+ final Random rand = random.getSingleThreadedRandom();
+ final int dim = min.length;
+
+ Vector vec = new Vector(dim);
+ double[] buf = vec.getArrayRef(); // Reference!
+
+ double u = 0.;
+ for(int i = 0; i < sampleSize; i++) {
+ // New random vector
+ for(int d = 0; d < buf.length; d++) {
+ buf[d] = min[d] + (rand.nextDouble() * extend[d]);
+ }
+ final double kdist = knnQuery.getKNNForObject(vec, k).getKNNDistance();
+ u += MathUtil.powi(kdist, dim);
+ }
+ return u;
+ }
+
+ /**
+ * Initialize the uniform sampling area.
+ *
+ * @param relation Data relation
+ * @param dim Dimensionality
+ * @param min Minima output array (preallocated!)
+ * @param extend Data extend output array (preallocated!)
+ */
+ protected void initializeDataExtends(Relation<NumberVector> relation, int dim, double[] min, double[] extend) {
+ assert (min.length == dim && extend.length == dim);
+ // if no parameter for min max compute min max values for each dimension
+ // from dataset
+ if(minima == null || maxima == null || minima.length == 0 || maxima.length == 0) {
+ double[][] minmax = RelationUtil.computeMinMax(relation);
+ final double[] dmin = minmax[0], dmax = minmax[1];
+ for(int d = 0; d < dim; d++) {
+ min[d] = dmin[d];
+ extend[d] = dmax[d] - dmin[d];
+ }
+ return;
+ }
+ if(minima.length == dim) {
+ System.arraycopy(minima, 0, min, 0, dim);
+ }
+ else if(minima.length == 1) {
+ Arrays.fill(min, minima[0]);
+ }
+ else {
+ throw new AbortException("Invalid minima specified: expected " + dim + " got minima dimensionality: " + minima.length);
+ }
+ if(maxima.length == dim) {
+ for(int d = 0; d < dim; d++) {
+ extend[d] = maxima[d] - min[d];
+ }
+ return;
+ }
+ else if(maxima.length == 1) {
+ for(int d = 0; d < dim; d++) {
+ extend[d] = maxima[0] - min[d];
+ }
+ return;
+ }
+ else {
+ throw new AbortException("Invalid maxima specified: expected " + dim + " got maxima dimensionality: " + maxima.length);
+ }
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ return TypeUtil.array(TypeUtil.NUMBER_VECTOR_FIELD);
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Lisa Reichert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractPrimitiveDistanceBasedAlgorithm.Parameterizer<NumberVector> {
+ /**
+ * Sample size.
+ */
+ public static final OptionID SAMPLESIZE_ID = new OptionID("hopkins.samplesize", "Number of object / random samples to analyze.");
+
+ /**
+ * Parameter to specify the number of repetitions of computing the hopkins
+ * value.
+ */
+ public static final OptionID REP_ID = new OptionID("hopkins.rep", "The number of times to repeat the experiment (default: 1)");
+
+ /**
+ * Parameter to specify the random generator seed.
+ */
+ public static final OptionID SEED_ID = new OptionID("hopkins.seed", "The random number generator.");
+
+ /**
+ * Parameter for minimum.
+ */
+ public static final OptionID MINIMA_ID = new OptionID("hopkins.min", "Minimum values in each dimension. If no value is specified, the minimum value in each dimension will be used. If only one value is specified, this value will be used for all dimensions.");
+
+ /**
+ * Parameter for maximum.
+ */
+ public static final OptionID MAXIMA_ID = new OptionID("hopkins.max", "Maximum values in each dimension. If no value is specified, the maximum value in each dimension will be used. If only one value is specified, this value will be used for all dimensions.");
+
+ /**
+ * Parameter for k.
+ */
+ public static final OptionID K_ID = new OptionID("hopkins.k", "Nearest neighbor to use for the statistic");
+
+ /**
+ * Sample size.
+ */
+ protected int sampleSize = 0;
+
+ /**
+ * Number of repetitions.
+ */
+ protected int rep = 1;
+
+ /**
+ * Nearest neighbor number.
+ */
+ protected int k = 1;
+
+ /**
+ * Random source.
+ */
+ protected RandomFactory random;
+
+ /**
+ * Stores the maximum in each dimension.
+ */
+ private double[] maxima = null;
+
+ /**
+ * Stores the minimum in each dimension.
+ */
+ private double[] minima = null;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ ObjectParameter<PrimitiveDistanceFunction<NumberVector>> distanceFunctionP = makeParameterDistanceFunction(EuclideanDistanceFunction.class, NumberVectorDistanceFunction.class);
+ if(config.grab(distanceFunctionP)) {
+ distanceFunction = distanceFunctionP.instantiateClass(config);
+ }
+
+ IntParameter sampleP = new IntParameter(SAMPLESIZE_ID);
+ if(config.grab(sampleP)) {
+ sampleSize = sampleP.getValue();
+ }
+
+ IntParameter repP = new IntParameter(REP_ID, 1) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(repP)) {
+ rep = repP.getValue();
+ }
+
+ IntParameter kP = new IntParameter(K_ID, 1) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(kP)) {
+ k = kP.getValue();
+ }
+
+ final RandomParameter randomP = new RandomParameter(SEED_ID);
+ if(config.grab(randomP)) {
+ random = randomP.getValue();
+ }
+ DoubleListParameter minimaP = new DoubleListParameter(MINIMA_ID)//
+ .setOptional(true);
+ if(config.grab(minimaP)) {
+ minima = ArrayLikeUtil.toPrimitiveDoubleArray(minimaP.getValue());
+ }
+ DoubleListParameter maximaP = new DoubleListParameter(MAXIMA_ID)//
+ .setOptional(true);
+ if(config.grab(maximaP)) {
+ maxima = ArrayLikeUtil.toPrimitiveDoubleArray(maximaP.getValue());
+ }
+
+ config.checkConstraint(new AllOrNoneMustBeSetGlobalConstraint(minimaP, maximaP));
+ config.checkConstraint(new EqualSizeGlobalConstraint(minimaP, maximaP));
+ }
+
+ @Override
+ protected HopkinsStatisticClusteringTendency makeInstance() {
+ return new HopkinsStatisticClusteringTendency((NumberVectorDistanceFunction<? super NumberVector>) distanceFunction, sampleSize, random, rep, k, minima, maxima);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/statistics/MeanAveragePrecisionForDistance.java b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/MeanAveragePrecisionForDistance.java
new file mode 100644
index 00000000..20a4bdac
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/MeanAveragePrecisionForDistance.java
@@ -0,0 +1,388 @@
+package de.lmu.ifi.dbs.elki.algorithm.statistics;
+
+/*
+ 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.algorithm.AbstractDistanceBasedAlgorithm;
+import de.lmu.ifi.dbs.elki.data.LabelList;
+import de.lmu.ifi.dbs.elki.data.type.AlternativeTypeInformation;
+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.Database;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+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.ModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
+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.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.evaluation.scores.AveragePrecisionEvaluation;
+import de.lmu.ifi.dbs.elki.evaluation.scores.ROCEvaluation;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.math.Mean;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+import de.lmu.ifi.dbs.elki.result.Result;
+import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable;
+import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+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;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
+
+/**
+ * Evaluate a distance functions performance by computing the mean average
+ * precision, when ranking the objects by distance.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has MAPResult
+ *
+ * @param <O> Object type
+ */
+public class MeanAveragePrecisionForDistance<O> extends AbstractDistanceBasedAlgorithm<O, MeanAveragePrecisionForDistance.MAPResult> {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(MeanAveragePrecisionForDistance.class);
+
+ /**
+ * Relative number of object to use in sampling.
+ */
+ private double sampling = 1.0;
+
+ /**
+ * Random sampling seed.
+ */
+ private RandomFactory random = null;
+
+ /**
+ * Include query object in evaluation.
+ */
+ private boolean includeSelf;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function
+ * @param sampling Sampling rate
+ * @param random Random sampling generator
+ * @param includeSelf Include query object in evaluation
+ */
+ public MeanAveragePrecisionForDistance(DistanceFunction<? super O> distanceFunction, double sampling, RandomFactory random, boolean includeSelf) {
+ super(distanceFunction);
+ this.sampling = sampling;
+ this.random = random;
+ this.includeSelf = includeSelf;
+ }
+
+ /**
+ * Run the algorithm
+ *
+ * @param database Database to run on (for kNN queries)
+ * @param relation Relation for distance computations
+ * @param lrelation Relation for class label comparison
+ * @return Vectors containing mean and standard deviation.
+ */
+ public MAPResult run(Database database, Relation<O> relation, Relation<?> lrelation) {
+ final DistanceQuery<O> distQuery = database.getDistanceQuery(relation, getDistanceFunction());
+
+ final DBIDs ids;
+ if(sampling < 1.) {
+ int size = Math.max(1, (int) (sampling * relation.size()));
+ ids = DBIDUtil.randomSample(relation.getDBIDs(), size, random);
+ }
+ else if(sampling > 1.) {
+ ids = DBIDUtil.randomSample(relation.getDBIDs(), (int) sampling, random);
+ }
+ else {
+ ids = relation.getDBIDs();
+ }
+
+ // For storing the positive neighbors.
+ ModifiableDBIDs posn = DBIDUtil.newHashSet();
+ // Distance storage.
+ ModifiableDoubleDBIDList nlist = DBIDUtil.newDistanceDBIDList(relation.size());
+
+ // Statistics tracking
+ Mean map = new Mean(), mroc = new Mean();
+
+ FiniteProgress objloop = LOG.isVerbose() ? new FiniteProgress("Processing query objects", ids.size(), LOG) : null;
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ Object label = lrelation.get(iter);
+ findMatches(posn, lrelation, label);
+ if(posn.size() > 0) {
+ computeDistances(nlist, iter, distQuery, relation);
+ if(nlist.size() != relation.size() - (includeSelf ? 0 : 1)) {
+ LOG.warning("Neighbor list does not have the desired size: " + nlist.size());
+ }
+ map.put(new AveragePrecisionEvaluation().evaluate(posn, nlist));
+ // We may as well compute ROC AUC while we're at it.
+ mroc.put(new ROCEvaluation().evaluate(posn, nlist));
+ }
+ LOG.incrementProcessed(objloop);
+ }
+ LOG.ensureCompleted(objloop);
+ if(map.getCount() < 1) {
+ throw new AbortException("No object matched - are labels parsed correctly?");
+ }
+ if(!(map.getMean() >= 0) || !(mroc.getMean() >= 0)) {
+ throw new AbortException("NaN in MAP/ROC.");
+ }
+
+ return new MAPResult(map.getMean(), mroc.getMean(), ids.size());
+ }
+
+ /**
+ * Test whether two relation agree.
+ *
+ * @param ref Reference object
+ * @param test Test object
+ * @return {@code true} if the objects match
+ */
+ protected static boolean match(Object ref, Object test) {
+ if(ref == null) {
+ return false;
+ }
+ // Cheap and fast, may hold for class labels!
+ if(ref == test) {
+ return true;
+ }
+ if(ref instanceof LabelList && test instanceof LabelList) {
+ final LabelList lref = (LabelList) ref;
+ final LabelList ltest = (LabelList) test;
+ final int s1 = lref.size(), s2 = ltest.size();
+ if(s1 == 0 || s2 == 0) {
+ return false;
+ }
+ for(int i = 0; i < s1; i++) {
+ String l1 = lref.get(i);
+ if(l1 == null) {
+ continue;
+ }
+ for(int j = 0; j < s2; j++) {
+ if(l1.equals(ltest.get(j))) {
+ return true;
+ }
+ }
+ }
+ }
+ // Fallback to equality, e.g. on class labels
+ return ref.equals(test);
+ }
+
+ /**
+ * Find all matching objects.
+ *
+ * @param posn Output set.
+ * @param lrelation Label relation
+ * @param label Query object label
+ */
+ private void findMatches(ModifiableDBIDs posn, Relation<?> lrelation, Object label) {
+ posn.clear();
+ for(DBIDIter ri = lrelation.iterDBIDs(); ri.valid(); ri.advance()) {
+ if(match(label, lrelation.get(ri))) {
+ posn.add(ri);
+ }
+ }
+ }
+
+ /**
+ * Compute the distances to the neighbor objects.
+ *
+ * @param nlist Neighbor list (output)
+ * @param query Query object
+ * @param distQuery Distance function
+ * @param relation Data relation
+ */
+ private void computeDistances(ModifiableDoubleDBIDList nlist, DBIDIter query, final DistanceQuery<O> distQuery, Relation<O> relation) {
+ nlist.clear();
+ O qo = relation.get(query);
+ for(DBIDIter ri = relation.iterDBIDs(); ri.valid(); ri.advance()) {
+ if(!includeSelf && DBIDUtil.equal(ri, query)) {
+ continue;
+ }
+ double dist = distQuery.distance(qo, ri);
+ if(dist != dist) { /* NaN */
+ dist = Double.POSITIVE_INFINITY;
+ }
+ nlist.add(dist, ri);
+ }
+ nlist.sort();
+ }
+
+ @Override
+ public TypeInformation[] getInputTypeRestriction() {
+ TypeInformation cls = new AlternativeTypeInformation(TypeUtil.CLASSLABEL, TypeUtil.LABELLIST);
+ return TypeUtil.array(getDistanceFunction().getInputTypeRestriction(), cls);
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Result object for MAP scores.
+ *
+ * @author Erich Schubert
+ */
+ public static class MAPResult implements Result, TextWriteable {
+ /**
+ * MAP value
+ */
+ private double map;
+
+ /**
+ * ROC AUC value
+ */
+ private double rocauc;
+
+ /**
+ * Sample size
+ */
+ private int samplesize;
+
+ /**
+ * Constructor.
+ *
+ * @param map MAP value
+ * @param rocauc ROC AUC value
+ * @param samplesize Sample size
+ */
+ public MAPResult(double map, double rocauc, int samplesize) {
+ super();
+ this.map = map;
+ this.rocauc = rocauc;
+ this.samplesize = samplesize;
+ }
+
+ /**
+ * @return the area under curve
+ */
+ public double getROCAUC() {
+ return rocauc;
+ }
+
+ /**
+ * @return the medium average precision
+ */
+ public double getMAP() {
+ return map;
+ }
+
+ @Override
+ public String getLongName() {
+ return "MAP score";
+ }
+
+ @Override
+ public String getShortName() {
+ return "map-score";
+ }
+
+ @Override
+ public void writeToText(TextWriterStream out, String label) {
+ out.inlinePrintNoQuotes("MAP");
+ out.inlinePrint(map);
+ out.flush();
+ out.inlinePrintNoQuotes("ROCAUC");
+ out.inlinePrint(rocauc);
+ out.flush();
+ out.inlinePrintNoQuotes("Samplesize");
+ out.inlinePrint(samplesize);
+ out.flush();
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <O> Object type
+ */
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
+ /**
+ * Parameter to enable sampling.
+ */
+ public static final OptionID SAMPLING_ID = new OptionID("map.sampling", "Relative amount of object to sample.");
+
+ /**
+ * Parameter to control the sampling random seed.
+ */
+ public static final OptionID SEED_ID = new OptionID("map.sampling-seed", "Random seed for deterministic sampling.");
+
+ /**
+ * Parameter to include the query object.
+ */
+ public static final OptionID INCLUDESELF_ID = new OptionID("map.includeself", "Include the query object in the evaluation.");
+
+ /**
+ * Relative amount of data to sample.
+ */
+ protected double sampling = 1.0;
+
+ /**
+ * Random sampling seed.
+ */
+ protected RandomFactory seed = null;
+
+ /**
+ * Include query object in evaluation.
+ */
+ protected boolean includeSelf;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ final DoubleParameter samplingP = new DoubleParameter(SAMPLING_ID);
+ samplingP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ samplingP.addConstraint(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
+ samplingP.setOptional(true);
+ if(config.grab(samplingP)) {
+ sampling = samplingP.getValue();
+ }
+ final RandomParameter rndP = new RandomParameter(SEED_ID);
+ rndP.setOptional(true);
+ if(config.grab(rndP)) {
+ seed = rndP.getValue();
+ }
+ final Flag includeP = new Flag(INCLUDESELF_ID);
+ if(config.grab(includeP)) {
+ includeSelf = includeP.isTrue();
+ }
+ }
+
+ @Override
+ protected MeanAveragePrecisionForDistance<O> makeInstance() {
+ return new MeanAveragePrecisionForDistance<>(distanceFunction, sampling, seed, includeSelf);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/statistics/RankingQualityHistogram.java b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/RankingQualityHistogram.java
index 7d0f1bb2..5b44d52b 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/statistics/RankingQualityHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/RankingQualityHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.statistics;
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
@@ -35,13 +35,12 @@ 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.Database;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
-import de.lmu.ifi.dbs.elki.evaluation.roc.ROC;
+import de.lmu.ifi.dbs.elki.evaluation.scores.ROCEvaluation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
@@ -67,11 +66,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*
* @author Erich Schubert
* @param <O> Object type
- * @param <D> Distance type
*/
@Title("Ranking Quality Histogram")
@Description("Evaluates the effectiveness of a distance function via the obtained rankings.")
-public class RankingQualityHistogram<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, CollectionResult<DoubleVector>> {
+public class RankingQualityHistogram<O> extends AbstractDistanceBasedAlgorithm<O, CollectionResult<DoubleVector>> {
/**
* The logger for this class.
*/
@@ -93,7 +91,7 @@ public class RankingQualityHistogram<O, D extends NumberDistance<D, ?>> extends
* @param distanceFunction Distance function to evaluate
* @param numbins Number of bins
*/
- public RankingQualityHistogram(DistanceFunction<? super O, D> distanceFunction, int numbins) {
+ public RankingQualityHistogram(DistanceFunction<? super O> distanceFunction, int numbins) {
super(distanceFunction);
this.numbins = numbins;
}
@@ -106,8 +104,8 @@ public class RankingQualityHistogram<O, D extends NumberDistance<D, ?>> extends
* @return Histogram of ranking qualities
*/
public HistogramResult<DoubleVector> run(Database database, Relation<O> relation) {
- final DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, getDistanceFunction());
- final KNNQuery<O, D> knnQuery = database.getKNNQuery(distanceQuery, relation.size());
+ final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, getDistanceFunction());
+ final KNNQuery<O> knnQuery = database.getKNNQuery(distanceQuery, relation.size());
if(LOG.isVerbose()) {
LOG.verbose("Preprocessing clusters...");
@@ -126,20 +124,16 @@ public class RankingQualityHistogram<O, D extends NumberDistance<D, ?>> extends
// sort neighbors
for(Cluster<?> clus : split) {
for(DBIDIter iter = clus.getIDs().iter(); iter.valid(); iter.advance()) {
- KNNList<D> knn = knnQuery.getKNNForDBID(iter, relation.size());
- double result = ROC.computeROCAUCDistanceResult(relation.size(), clus, knn);
+ KNNList knn = knnQuery.getKNNForDBID(iter, relation.size());
+ double result = new ROCEvaluation().evaluate(clus, knn);
mv.put(result);
hist.increment(result, 1. / relation.size());
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(progress);
}
}
- if(progress != null) {
- progress.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(progress);
// Transform Histogram into a Double Vector array.
Collection<DoubleVector> res = new ArrayList<>(relation.size());
@@ -168,8 +162,10 @@ public class RankingQualityHistogram<O, D extends NumberDistance<D, ?>> extends
* @author Erich Schubert
*
* @apiviz.exclude
+ *
+ * @param <O> Object type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Number of bins.
*/
@@ -186,7 +182,7 @@ public class RankingQualityHistogram<O, D extends NumberDistance<D, ?>> extends
}
@Override
- protected RankingQualityHistogram<O, D> makeInstance() {
+ protected RankingQualityHistogram<O> makeInstance() {
return new RankingQualityHistogram<>(distanceFunction, numbins);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/statistics/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/package-info.java
index 8e566101..fbfb292c 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/statistics/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/statistics/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/application/AbstractApplication.java b/src/de/lmu/ifi/dbs/elki/application/AbstractApplication.java
index dabf5224..3770bbc4 100644
--- a/src/de/lmu/ifi/dbs/elki/application/AbstractApplication.java
+++ b/src/de/lmu/ifi/dbs/elki/application/AbstractApplication.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application;
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
@@ -38,17 +38,15 @@ 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.OptionUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.UnspecifiedParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.SerializedParameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackedParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.StringParameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* AbstractApplication sets the values for flags verbose and help.
@@ -63,7 +61,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
* @apiviz.uses LoggingConfiguration oneway
* @apiviz.excludeSubtypes
*/
-public abstract class AbstractApplication implements Parameterizable {
+public abstract class AbstractApplication {
/**
* We need a static logger in this class, for code used in "main" methods.
*/
@@ -177,7 +175,7 @@ public abstract class AbstractApplication implements Parameterizable {
* @param options Options to show in usage.
* @return a usage message explaining all known options
*/
- public static String usage(Collection<Pair<Object, Parameter<?>>> options) {
+ public static String usage(Collection<TrackedParameter> options) {
StringBuilder usage = new StringBuilder();
usage.append(INFORMATION);
diff --git a/src/de/lmu/ifi/dbs/elki/application/ClassifierHoldoutEvaluationTask.java b/src/de/lmu/ifi/dbs/elki/application/ClassifierHoldoutEvaluationTask.java
new file mode 100644
index 00000000..c4e364e6
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/application/ClassifierHoldoutEvaluationTask.java
@@ -0,0 +1,253 @@
+package de.lmu.ifi.dbs.elki.application;
+
+/*
+ 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.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import de.lmu.ifi.dbs.elki.algorithm.classification.Classifier;
+import de.lmu.ifi.dbs.elki.data.ClassLabel;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.database.AbstractDatabase;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.StaticArrayDatabase;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.datasource.DatabaseConnection;
+import de.lmu.ifi.dbs.elki.datasource.FileBasedDatabaseConnection;
+import de.lmu.ifi.dbs.elki.datasource.MultipleObjectsBundleDatabaseConnection;
+import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.evaluation.classification.ConfusionMatrix;
+import de.lmu.ifi.dbs.elki.evaluation.classification.holdout.AbstractHoldout;
+import de.lmu.ifi.dbs.elki.evaluation.classification.holdout.Holdout;
+import de.lmu.ifi.dbs.elki.evaluation.classification.holdout.StratifiedCrossValidation;
+import de.lmu.ifi.dbs.elki.evaluation.classification.holdout.TrainingAndTestSet;
+import de.lmu.ifi.dbs.elki.index.IndexFactory;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.statistics.Duration;
+/*
+ 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.utilities.exceptions.UnableToComplyException;
+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.ObjectListParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
+import de.lmu.ifi.dbs.elki.workflow.AlgorithmStep;
+
+/**
+ * Evaluate a classifier.
+ *
+ * TODO: split into application and task.
+ *
+ * TODO: add support for predefined test and training pairs!
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Object type
+ */
+public class ClassifierHoldoutEvaluationTask<O> extends AbstractApplication {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(ClassifierHoldoutEvaluationTask.class);
+
+ /**
+ * Holds the database connection to get the initial data from.
+ */
+ protected DatabaseConnection databaseConnection = null;
+
+ /**
+ * Indexes to add.
+ */
+ protected Collection<IndexFactory<?, ?>> indexFactories;
+
+ /**
+ * Classifier to evaluate.
+ */
+ protected Classifier<O> algorithm;
+
+ /**
+ * Holds the holdout.
+ */
+ protected Holdout holdout;
+
+ /**
+ * Constructor.
+ *
+ * @param databaseConnection Data source
+ * @param indexFactories Data indexes
+ * @param algorithm Classification algorithm
+ * @param holdout Evaluation holdout
+ */
+ public ClassifierHoldoutEvaluationTask(DatabaseConnection databaseConnection, Collection<IndexFactory<?, ?>> indexFactories, Classifier<O> algorithm, Holdout holdout) {
+ this.databaseConnection = databaseConnection;
+ this.indexFactories = indexFactories;
+ this.algorithm = algorithm;
+ this.holdout = holdout;
+ }
+
+ @Override
+ public void run() throws UnableToComplyException {
+ Duration ptime = LOG.newDuration("evaluation.time.load").begin();
+ MultipleObjectsBundle allData = databaseConnection.loadData();
+ holdout.initialize(allData);
+ LOG.statistics(ptime.end());
+
+ Duration time = LOG.newDuration("evaluation.time.total").begin();
+ ArrayList<ClassLabel> labels = holdout.getLabels();
+ int[][] confusion = new int[labels.size()][labels.size()];
+ for(int p = 0; p < holdout.numberOfPartitions(); p++) {
+ TrainingAndTestSet partition = holdout.nextPartitioning();
+ // Load the data set into a database structure (for indexing)
+ Duration dur = LOG.newDuration(this.getClass().getName() + ".fold-" + (p + 1) + ".init.time").begin();
+ Database db = new StaticArrayDatabase(new MultipleObjectsBundleDatabaseConnection(partition.getTraining()), indexFactories);
+ db.initialize();
+ LOG.statistics(dur.end());
+ // Train the classifier
+ dur = LOG.newDuration(this.getClass().getName() + ".fold-" + (p + 1) + ".train.time").begin();
+ Relation<ClassLabel> lrel = db.getRelation(TypeUtil.CLASSLABEL);
+ algorithm.buildClassifier(db, lrel);
+ LOG.statistics(dur.end());
+ // Evaluate the test set
+ dur = LOG.newDuration(this.getClass().getName() + ".fold-" + (p + 1) + ".evaluation.time").begin();
+ // FIXME: this part is still a big hack, unfortunately!
+ MultipleObjectsBundle test = partition.getTest();
+ int lcol = AbstractHoldout.findClassLabelColumn(test);
+ int tcol = (lcol == 0) ? 1 : 0;
+ for(int i = 0, l = test.dataLength(); i < l; ++i) {
+ @SuppressWarnings("unchecked")
+ O obj = (O) test.data(i, tcol);
+ ClassLabel truelbl = (ClassLabel) test.data(i, lcol);
+ ClassLabel predlbl = algorithm.classify(obj);
+ int pred = Collections.binarySearch(labels, predlbl);
+ int real = Collections.binarySearch(labels, truelbl);
+ confusion[pred][real]++;
+ }
+ LOG.statistics(dur.end());
+ }
+ LOG.statistics(time.end());
+ ConfusionMatrix m = new ConfusionMatrix(labels, confusion);
+ LOG.statistics(m.toString());
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<O> extends AbstractApplication.Parameterizer {
+ /**
+ * Parameter to specify the holdout for evaluation, must extend
+ * {@link de.lmu.ifi.dbs.elki.evaluation.classification.holdout.Holdout}.
+ * <p>
+ * Key: {@code -classifier.holdout}
+ * </p>
+ * <p>
+ * Default value: {@link StratifiedCrossValidation}
+ * </p>
+ */
+ public static final OptionID HOLDOUT_ID = new OptionID("evaluation.holdout", "Holdout class used in evaluation.");
+
+ /**
+ * Holds the database connection to get the initial data from.
+ */
+ protected DatabaseConnection databaseConnection = null;
+
+ /**
+ * Indexes to add.
+ */
+ protected Collection<IndexFactory<?, ?>> indexFactories;
+
+ /**
+ * Classifier to evaluate.
+ */
+ protected Classifier<O> algorithm;
+
+ /**
+ * Holds the holdout.
+ */
+ protected Holdout holdout;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ // Get database connection.
+ final ObjectParameter<DatabaseConnection> dbcP = new ObjectParameter<>(AbstractDatabase.Parameterizer.DATABASE_CONNECTION_ID, DatabaseConnection.class, FileBasedDatabaseConnection.class);
+ if(config.grab(dbcP)) {
+ databaseConnection = dbcP.instantiateClass(config);
+ }
+ // Get indexes.
+ final ObjectListParameter<IndexFactory<?, ?>> indexFactoryP = new ObjectListParameter<>(AbstractDatabase.Parameterizer.INDEX_ID, IndexFactory.class, true);
+ if(config.grab(indexFactoryP)) {
+ indexFactories = indexFactoryP.instantiateClasses(config);
+ }
+ ObjectParameter<Classifier<O>> algorithmP = new ObjectParameter<>(AlgorithmStep.Parameterizer.ALGORITHM_ID, Classifier.class);
+ if(config.grab(algorithmP)) {
+ algorithm = algorithmP.instantiateClass(config);
+ }
+
+ ObjectParameter<Holdout> holdoutP = new ObjectParameter<>(HOLDOUT_ID, Holdout.class, StratifiedCrossValidation.class);
+ if(config.grab(holdoutP)) {
+ holdout = holdoutP.instantiateClass(config);
+ }
+ }
+
+ @Override
+ protected ClassifierHoldoutEvaluationTask<O> makeInstance() {
+ return new ClassifierHoldoutEvaluationTask<O>(databaseConnection, indexFactories, algorithm, holdout);
+ }
+ }
+
+ /**
+ * Runs the classifier evaluation task accordingly to the specified
+ * parameters.
+ *
+ * @param args parameter list according to description
+ */
+ public static void main(String[] args) {
+ runCLIApplication(ClassifierHoldoutEvaluationTask.class, args);
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/application/ComputeSingleColorHistogram.java b/src/de/lmu/ifi/dbs/elki/application/ComputeSingleColorHistogram.java
deleted file mode 100644
index b2c8afff..00000000
--- a/src/de/lmu/ifi/dbs/elki/application/ComputeSingleColorHistogram.java
+++ /dev/null
@@ -1,166 +0,0 @@
-package de.lmu.ifi.dbs.elki.application;
-
-/*
- 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.File;
-import java.io.IOException;
-
-import de.lmu.ifi.dbs.elki.data.images.ComputeColorHistogram;
-import de.lmu.ifi.dbs.elki.data.images.ComputeNaiveRGBColorHistogram;
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
-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.FileParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
-
-/**
- * Application that computes the color histogram vector for a single image.
- *
- * @author Erich Schubert
- *
- * @apiviz.composedOf ComputeColorHistogram
- * @apiviz.has File
- */
-public class ComputeSingleColorHistogram extends AbstractApplication {
- /**
- * Class parameter for computing the color histogram.
- * <p>
- * Key: {@code -colorhist.generator}
- * </p>
- */
- public static OptionID COLORHIST_ID = new OptionID("colorhist.generator", "Class that is used to generate a color histogram.");
-
- /**
- * Parameter that specifies the name of the input file.
- * <p>
- * Key: {@code -colorhist.in}
- * </p>
- */
- public static final OptionID INPUT_ID = new OptionID("colorhist.in", "Input image file for color histogram.");
-
- /**
- * Parameter that specifies the name of the mask input file.
- * <p>
- * Key: {@code -colorhist.mask}
- * </p>
- */
- public static final OptionID MASK_ID = new OptionID("colorhist.mask", "Input mask image file.");
-
- /**
- * Class that will compute the actual histogram
- */
- private ComputeColorHistogram histogrammaker;
-
- /**
- * Input file.
- */
- private File inputFile;
-
- /**
- * Mask file.
- */
- private File maskFile;
-
- /**
- * Constructor.
- *
- * @param histogrammaker Class to compute histograms with
- * @param inputFile Input file
- * @param maskFile Mask file
- */
- public ComputeSingleColorHistogram(ComputeColorHistogram histogrammaker, File inputFile, File maskFile) {
- super();
- this.histogrammaker = histogrammaker;
- this.inputFile = inputFile;
- this.maskFile = maskFile;
- }
-
- @Override
- public void run() throws UnableToComplyException {
- double[] hist;
- try {
- hist = histogrammaker.computeColorHistogram(inputFile, maskFile);
- }
- catch(IOException e) {
- throw new UnableToComplyException(e);
- }
- System.out.println(FormatUtil.format(hist, " "));
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer extends AbstractApplication.Parameterizer {
- /**
- * Class that will compute the actual histogram
- */
- private ComputeColorHistogram histogrammaker;
-
- /**
- * Input file.
- */
- private File inputFile;
-
- /**
- * Mask file.
- */
- private File maskFile;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- final ObjectParameter<ComputeColorHistogram> colorhistP = new ObjectParameter<>(COLORHIST_ID, ComputeColorHistogram.class, ComputeNaiveRGBColorHistogram.class);
- if(config.grab(colorhistP)) {
- histogrammaker = colorhistP.instantiateClass(config);
- }
- final FileParameter inputP = new FileParameter(INPUT_ID, FileParameter.FileType.INPUT_FILE);
- if(config.grab(inputP)) {
- inputFile = inputP.getValue();
- }
- final FileParameter maskP = new FileParameter(MASK_ID, FileParameter.FileType.INPUT_FILE, true);
- if(config.grab(maskP)) {
- maskFile = maskP.getValue();
- }
- }
-
- @Override
- protected ComputeSingleColorHistogram makeInstance() {
- return new ComputeSingleColorHistogram(histogrammaker, inputFile, maskFile);
- }
- }
-
- /**
- * Main method to run this application.
- *
- * @param args the arguments to run this application
- */
- public static void main(String[] args) {
- runCLIApplication(ComputeSingleColorHistogram.class, args);
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/application/ConvertToBundleApplication.java b/src/de/lmu/ifi/dbs/elki/application/ConvertToBundleApplication.java
index 8b177691..ac140abb 100644
--- a/src/de/lmu/ifi/dbs/elki/application/ConvertToBundleApplication.java
+++ b/src/de/lmu/ifi/dbs/elki/application/ConvertToBundleApplication.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application;
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
@@ -33,7 +33,6 @@ import de.lmu.ifi.dbs.elki.datasource.DatabaseConnection;
import de.lmu.ifi.dbs.elki.datasource.FileBasedDatabaseConnection;
import de.lmu.ifi.dbs.elki.datasource.bundle.BundleWriter;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
-import de.lmu.ifi.dbs.elki.datasource.bundle.StreamFromBundle;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -86,7 +85,7 @@ public class ConvertToBundleApplication extends AbstractApplication {
try {
FileOutputStream fos = new FileOutputStream(outfile);
FileChannel channel = fos.getChannel();
- writer.writeBundleStream(new StreamFromBundle(bundle), channel);
+ writer.writeBundleStream(bundle.asStream(), channel);
channel.close();
fos.close();
}
diff --git a/src/de/lmu/ifi/dbs/elki/application/ELKILauncher.java b/src/de/lmu/ifi/dbs/elki/application/ELKILauncher.java
index 5c969157..5a3eac39 100644
--- a/src/de/lmu/ifi/dbs/elki/application/ELKILauncher.java
+++ b/src/de/lmu/ifi/dbs/elki/application/ELKILauncher.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application;
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,6 +23,7 @@ package de.lmu.ifi.dbs.elki.application;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
@@ -50,25 +51,31 @@ public class ELKILauncher {
* @param args Command line arguments.
*/
public static void main(String[] args) {
- if (args.length > 0 && args[0].charAt(0) != '-') {
+ if(args.length > 0 && args[0].charAt(0) != '-') {
try {
Class<?> cls = findMainClass(args[0]);
Method m = cls.getMethod("main", String[].class);
Object a = Arrays.copyOfRange(args, 1, args.length);
try {
m.invoke(null, a);
- } catch (Exception e) {
+ }
+ catch(InvocationTargetException e) {
+ LoggingUtil.exception(e.getCause());
+ }
+ catch(Exception e) {
LoggingUtil.exception(e);
}
return;
- } catch (Exception e) {
+ }
+ catch(Exception e) {
// Ignore
}
}
try {
Method m = DEFAULT_APPLICATION.getMethod("main", String[].class);
m.invoke(null, (Object) args);
- } catch (Exception e) {
+ }
+ catch(Exception e) {
LoggingUtil.exception(e);
}
}
@@ -80,23 +87,26 @@ public class ELKILauncher {
* @return Class
* @throws ClassNotFoundException
*/
- private static Class<?> findMainClass(String name) throws ClassNotFoundException {
+ public static Class<? extends AbstractApplication> findMainClass(String name) throws ClassNotFoundException {
try {
- return Class.forName(name);
- } catch (ClassNotFoundException e) {
+ return Class.forName(name).asSubclass(AbstractApplication.class);
+ }
+ catch(ClassNotFoundException | ClassCastException e) {
// pass
}
try {
- return Class.forName(AbstractApplication.class.getPackage().getName() + '.' + name);
- } catch (ClassNotFoundException e) {
+ return Class.forName(AbstractApplication.class.getPackage().getName() + '.' + name)//
+ .asSubclass(AbstractApplication.class);
+ }
+ catch(ClassNotFoundException | ClassCastException e) {
// pass
}
- for (Class<?> c : InspectionUtil.cachedFindAllImplementations(AbstractApplication.class)) {
- if (c.isAnnotationPresent(Alias.class)) {
+ for(Class<?> c : InspectionUtil.cachedFindAllImplementations(AbstractApplication.class)) {
+ if(c.isAnnotationPresent(Alias.class)) {
Alias aliases = c.getAnnotation(Alias.class);
- for (String alias : aliases.value()) {
- if (alias.equalsIgnoreCase(name)) {
- return c;
+ for(String alias : aliases.value()) {
+ if(alias.equalsIgnoreCase(name)) {
+ return c.asSubclass(AbstractApplication.class);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/application/GeneratorXMLSpec.java b/src/de/lmu/ifi/dbs/elki/application/GeneratorXMLSpec.java
index 50f97d87..da86a150 100644
--- a/src/de/lmu/ifi/dbs/elki/application/GeneratorXMLSpec.java
+++ b/src/de/lmu/ifi/dbs/elki/application/GeneratorXMLSpec.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application;
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/application/KDDCLIApplication.java b/src/de/lmu/ifi/dbs/elki/application/KDDCLIApplication.java
index 7e072989..7d9cd016 100644
--- a/src/de/lmu/ifi/dbs/elki/application/KDDCLIApplication.java
+++ b/src/de/lmu/ifi/dbs/elki/application/KDDCLIApplication.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application;
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,10 +30,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.workflow.OutputStep;
/**
- * Provides a KDDCLIApplication that can be used to perform any algorithm
- * implementing {@link Algorithm Algorithm} using any DatabaseConnection
- * implementing {@link de.lmu.ifi.dbs.elki.datasource.DatabaseConnection
- * DatabaseConnection}.
+ * Basic command line application for Knowledge Discovery in Databases use
+ * cases. It allows running unsupervised {@link Algorithm}s to run on any
+ * {@link de.lmu.ifi.dbs.elki.datasource.DatabaseConnection DatabaseConnection}.
*
* @author Arthur Zimek
*
diff --git a/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceInOnDiskMatrix.java b/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceInOnDiskMatrix.java
index 6a28282c..02290ced 100644
--- a/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceInOnDiskMatrix.java
+++ b/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceInOnDiskMatrix.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.cache;
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,17 +28,17 @@ import java.io.IOException;
import de.lmu.ifi.dbs.elki.application.AbstractApplication;
import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRange;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
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.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.external.DiskCacheBasedDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.persistent.OnDiskUpperTriangleMatrix;
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.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
@@ -54,9 +54,8 @@ import de.lmu.ifi.dbs.elki.workflow.InputStep;
* @apiviz.has DistanceFunction
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class CacheDoubleDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>> extends AbstractApplication {
+public class CacheDoubleDistanceInOnDiskMatrix<O> extends AbstractApplication {
/**
* The logger for this class.
*/
@@ -75,7 +74,7 @@ public class CacheDoubleDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>
/**
* Distance function that is to be cached.
*/
- private DistanceFunction<O, D> distance;
+ private DistanceFunction<O> distance;
/**
* Output file.
@@ -89,7 +88,7 @@ public class CacheDoubleDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>
* @param distance Distance function
* @param out Matrix output file
*/
- public CacheDoubleDistanceInOnDiskMatrix(InputStep input, DistanceFunction<O, D> distance, File out) {
+ public CacheDoubleDistanceInOnDiskMatrix(InputStep input, DistanceFunction<O> distance, File out) {
super();
this.input = input;
this.distance = distance;
@@ -100,40 +99,35 @@ public class CacheDoubleDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>
public void run() {
Database database = input.getDatabase();
Relation<O> relation = database.getRelation(distance.getInputTypeRestriction());
- DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, distance);
-
- int matrixsize = 0;
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- int intid = DBIDUtil.asInteger(iditer);
- matrixsize = Math.max(matrixsize, intid + 1);
- if (intid < 0) {
- throw new AbortException("OnDiskMatrixCache does not allow negative DBIDs.");
- }
- }
+ DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distance);
+
+ DBIDRange ids = DBIDUtil.assertRange(relation.getDBIDs());
+ int matrixsize = ids.size();
OnDiskUpperTriangleMatrix matrix;
try {
- matrix = new OnDiskUpperTriangleMatrix(out, DiskCacheBasedDoubleDistanceFunction.DOUBLE_CACHE_MAGIC, 0, 8, matrixsize);
- } catch (IOException e) {
+ matrix = new OnDiskUpperTriangleMatrix(out, DiskCacheBasedDoubleDistanceFunction.DOUBLE_CACHE_MAGIC, 0, ByteArrayUtil.SIZE_DOUBLE, matrixsize);
+ }
+ catch(IOException e) {
throw new AbortException("Error creating output matrix.", e);
}
- for (DBIDIter id1 = relation.iterDBIDs(); id1.valid(); id1.advance()) {
- for (DBIDIter id2 = relation.iterDBIDs(); id2.valid(); id2.advance()) {
- if (DBIDUtil.asInteger(id2) >= DBIDUtil.asInteger(id1)) {
- double d = distanceQuery.distance(id1, id2).doubleValue();
- if (debugExtraCheckSymmetry) {
- double d2 = distanceQuery.distance(id2, id1).doubleValue();
- if (Math.abs(d - d2) > 0.0000001) {
- LOG.warning("Distance function doesn't appear to be symmetric!");
- }
- }
- try {
- matrix.getRecordBuffer(DBIDUtil.asInteger(id1), DBIDUtil.asInteger(id2)).putDouble(d);
- } catch (IOException e) {
- throw new AbortException("Error writing distance record " + DBIDFactory.FACTORY.toString(id1) + "," + DBIDFactory.FACTORY.toString(id2) + " to matrix.", e);
+ DBIDArrayIter id1 = ids.iter(), id2 = ids.iter();
+ for(; id1.valid(); id1.advance()) {
+ for(id2.seek(id1.getOffset()); id2.valid(); id2.advance()) {
+ double d = distanceQuery.distance(id1, id2);
+ if(debugExtraCheckSymmetry) {
+ double d2 = distanceQuery.distance(id2, id1);
+ if(Math.abs(d - d2) > 0.0000001) {
+ LOG.warning("Distance function doesn't appear to be symmetric!");
}
}
+ try {
+ matrix.getRecordBuffer(id1.getOffset(), id2.getOffset()).putDouble(d);
+ }
+ catch(IOException e) {
+ throw new AbortException("Error writing distance record " + DBIDUtil.toString(id1) + "," + DBIDUtil.toString(id2) + " to matrix.", e);
+ }
}
}
}
@@ -145,7 +139,7 @@ public class CacheDoubleDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractApplication.Parameterizer {
+ public static class Parameterizer<O> extends AbstractApplication.Parameterizer {
/**
* Parameter that specifies the name of the directory to be re-parsed.
* <p>
@@ -170,7 +164,7 @@ public class CacheDoubleDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>
/**
* Distance function that is to be cached.
*/
- private DistanceFunction<O, D> distance = null;
+ private DistanceFunction<O> distance = null;
/**
* Output file.
@@ -182,19 +176,19 @@ public class CacheDoubleDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>
super.makeOptions(config);
input = config.tryInstantiate(InputStep.class);
// Distance function parameter
- final ObjectParameter<DistanceFunction<O, D>> dpar = new ObjectParameter<>(DISTANCE_ID, DistanceFunction.class);
- if (config.grab(dpar)) {
+ final ObjectParameter<DistanceFunction<O>> dpar = new ObjectParameter<>(DISTANCE_ID, DistanceFunction.class);
+ if(config.grab(dpar)) {
distance = dpar.instantiateClass(config);
}
// Output file parameter
final FileParameter cpar = new FileParameter(CACHE_ID, FileParameter.FileType.OUTPUT_FILE);
- if (config.grab(cpar)) {
+ if(config.grab(cpar)) {
out = cpar.getValue();
}
}
@Override
- protected CacheDoubleDistanceInOnDiskMatrix<O, D> makeInstance() {
+ protected CacheDoubleDistanceInOnDiskMatrix<O> makeInstance() {
return new CacheDoubleDistanceInOnDiskMatrix<>(input, distance, out);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceKNNLists.java b/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceKNNLists.java
index d8ddbf17..1361620f 100644
--- a/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceKNNLists.java
+++ b/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceKNNLists.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.cache;
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
@@ -33,20 +33,17 @@ import java.nio.channels.FileLock;
import de.lmu.ifi.dbs.elki.application.AbstractApplication;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
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.distancefunction.DistanceFunction;
-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.FiniteProgress;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
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.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -63,9 +60,8 @@ import de.lmu.ifi.dbs.elki.workflow.InputStep;
* @apiviz.has DistanceFunction
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class CacheDoubleDistanceKNNLists<O, D extends NumberDistance<D, ?>> extends AbstractApplication {
+public class CacheDoubleDistanceKNNLists<O> extends AbstractApplication {
/**
* The logger for this class.
*/
@@ -79,7 +75,7 @@ public class CacheDoubleDistanceKNNLists<O, D extends NumberDistance<D, ?>> exte
/**
* Distance function that is to be cached.
*/
- private DistanceFunction<O, D> distance;
+ private DistanceFunction<O> distance;
/**
* Number of neighbors to precompute.
@@ -107,7 +103,7 @@ public class CacheDoubleDistanceKNNLists<O, D extends NumberDistance<D, ?>> exte
* @param k Number of nearest neighbors
* @param out Matrix output file
*/
- public CacheDoubleDistanceKNNLists(InputStep input, DistanceFunction<O, D> distance, int k, File out) {
+ public CacheDoubleDistanceKNNLists(InputStep input, DistanceFunction<O> distance, int k, File out) {
super();
this.input = input;
this.distance = distance;
@@ -119,8 +115,8 @@ public class CacheDoubleDistanceKNNLists<O, D extends NumberDistance<D, ?>> exte
public void run() {
Database database = input.getDatabase();
Relation<O> relation = database.getRelation(distance.getInputTypeRestriction());
- DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, distance);
- KNNQuery<O, D> knnQ = database.getKNNQuery(distanceQuery, DatabaseQuery.HINT_HEAVY_USE);
+ DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distance);
+ KNNQuery<O> knnQ = database.getKNNQuery(distanceQuery, DatabaseQuery.HINT_HEAVY_USE);
// open file.
try (RandomAccessFile file = new RandomAccessFile(out, "rw");
@@ -136,7 +132,7 @@ public class CacheDoubleDistanceKNNLists<O, D extends NumberDistance<D, ?>> exte
FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Computing kNN", relation.size(), LOG) : null;
for(DBIDIter it = relation.iterDBIDs(); it.valid(); it.advance()) {
- final KNNList<D> nn = knnQ.getKNNForDBID(it, k);
+ final KNNList nn = knnQ.getKNNForDBID(it, k);
final int nnsize = nn.size();
// Grow the buffer when needed:
@@ -151,17 +147,9 @@ public class CacheDoubleDistanceKNNLists<O, D extends NumberDistance<D, ?>> exte
ByteArrayUtil.writeUnsignedVarint(buffer, it.internalGetIndex());
ByteArrayUtil.writeUnsignedVarint(buffer, nnsize);
int c = 0;
- if(nn instanceof DoubleDistanceDBIDList) {
- for(DoubleDistanceDBIDListIter ni = ((DoubleDistanceDBIDList) nn).iter(); ni.valid(); ni.advance(), c++) {
- ByteArrayUtil.writeUnsignedVarint(buffer, ni.internalGetIndex());
- buffer.putDouble(ni.doubleDistance());
- }
- }
- else {
- for(DistanceDBIDListIter<D> ni = nn.iter(); ni.valid(); ni.advance(), c++) {
- ByteArrayUtil.writeUnsignedVarint(buffer, ni.internalGetIndex());
- buffer.putDouble(ni.getDistance().doubleValue());
- }
+ for(DoubleDBIDListIter ni = nn.iter(); ni.valid(); ni.advance(), c++) {
+ ByteArrayUtil.writeUnsignedVarint(buffer, ni.internalGetIndex());
+ buffer.putDouble(ni.doubleValue());
}
if(c != nn.size()) {
throw new AbortException("Sizes did not agree. Cache is invalid.");
@@ -169,13 +157,9 @@ public class CacheDoubleDistanceKNNLists<O, D extends NumberDistance<D, ?>> exte
buffer.flip();
channel.write(buffer);
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if(prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
lock.release();
}
catch(IOException e) {
@@ -191,7 +175,7 @@ public class CacheDoubleDistanceKNNLists<O, D extends NumberDistance<D, ?>> exte
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractApplication.Parameterizer {
+ public static class Parameterizer<O> extends AbstractApplication.Parameterizer {
/**
* Parameter that specifies the name of the directory to be re-parsed.
* <p>
@@ -224,7 +208,7 @@ public class CacheDoubleDistanceKNNLists<O, D extends NumberDistance<D, ?>> exte
/**
* Distance function that is to be cached.
*/
- private DistanceFunction<O, D> distance = null;
+ private DistanceFunction<O> distance = null;
/**
* Number of neighbors to precompute.
@@ -241,7 +225,7 @@ public class CacheDoubleDistanceKNNLists<O, D extends NumberDistance<D, ?>> exte
super.makeOptions(config);
input = config.tryInstantiate(InputStep.class);
// Distance function parameter
- final ObjectParameter<DistanceFunction<O, D>> dpar = new ObjectParameter<>(DISTANCE_ID, DistanceFunction.class);
+ final ObjectParameter<DistanceFunction<O>> dpar = new ObjectParameter<>(DISTANCE_ID, DistanceFunction.class);
if(config.grab(dpar)) {
distance = dpar.instantiateClass(config);
}
@@ -258,7 +242,7 @@ public class CacheDoubleDistanceKNNLists<O, D extends NumberDistance<D, ?>> exte
}
@Override
- protected CacheDoubleDistanceKNNLists<O, D> makeInstance() {
+ protected CacheDoubleDistanceKNNLists<O> makeInstance() {
return new CacheDoubleDistanceKNNLists<>(input, distance, k, out);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceRangeQueries.java b/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceRangeQueries.java
index f61874dd..bf9ecdb0 100644
--- a/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceRangeQueries.java
+++ b/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceRangeQueries.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.cache;
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
@@ -33,20 +33,17 @@ import java.nio.channels.FileLock;
import de.lmu.ifi.dbs.elki.application.AbstractApplication;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
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.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
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.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -78,7 +75,7 @@ public class CacheDoubleDistanceRangeQueries<O> extends AbstractApplication {
/**
* Distance function that is to be cached.
*/
- private DistanceFunction<O, DoubleDistance> distance;
+ private DistanceFunction<O> distance;
/**
* Query radius.
@@ -106,7 +103,7 @@ public class CacheDoubleDistanceRangeQueries<O> extends AbstractApplication {
* @param radius Query radius
* @param out Matrix output file
*/
- public CacheDoubleDistanceRangeQueries(InputStep input, DistanceFunction<O, DoubleDistance> distance, double radius, File out) {
+ public CacheDoubleDistanceRangeQueries(InputStep input, DistanceFunction<O> distance, double radius, File out) {
super();
this.input = input;
this.distance = distance;
@@ -118,11 +115,10 @@ public class CacheDoubleDistanceRangeQueries<O> extends AbstractApplication {
public void run() {
Database database = input.getDatabase();
Relation<O> relation = database.getRelation(distance.getInputTypeRestriction());
- DistanceQuery<O, DoubleDistance> distanceQuery = database.getDistanceQuery(relation, distance);
- DoubleDistance rad = new DoubleDistance(radius);
- RangeQuery<O, DoubleDistance> rangeQ = database.getRangeQuery(distanceQuery, rad, DatabaseQuery.HINT_HEAVY_USE);
+ DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distance);
+ RangeQuery<O> rangeQ = database.getRangeQuery(distanceQuery, radius, DatabaseQuery.HINT_HEAVY_USE);
- LOG.verbose("Performing range queries with radius " + rad);
+ LOG.verbose("Performing range queries with radius " + radius);
// open file.
try (RandomAccessFile file = new RandomAccessFile(out, "rw");
@@ -139,16 +135,16 @@ public class CacheDoubleDistanceRangeQueries<O> extends AbstractApplication {
FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Computing range queries", relation.size(), LOG) : null;
- for (DBIDIter it = relation.iterDBIDs(); it.valid(); it.advance()) {
- final DistanceDBIDList<DoubleDistance> nn = rangeQ.getRangeForDBID(it, rad);
+ for(DBIDIter it = relation.iterDBIDs(); it.valid(); it.advance()) {
+ final DoubleDBIDList nn = rangeQ.getRangeForDBID(it, radius);
final int nnsize = nn.size();
// Grow the buffer when needed:
- if (nnsize * 12 + 10 > bufsize) {
- while (nnsize * 12 + 10 > bufsize) {
+ if(nnsize * 12 + 10 > bufsize) {
+ while(nnsize * 12 + 10 > bufsize) {
bufsize <<= 1;
}
- LOG.verbose("Resizing buffer to "+bufsize+" to store "+nnsize+" results:");
+ LOG.verbose("Resizing buffer to " + bufsize + " to store " + nnsize + " results:");
buffer = ByteBuffer.allocateDirect(bufsize);
}
@@ -156,32 +152,22 @@ public class CacheDoubleDistanceRangeQueries<O> extends AbstractApplication {
ByteArrayUtil.writeUnsignedVarint(buffer, it.internalGetIndex());
ByteArrayUtil.writeUnsignedVarint(buffer, nnsize);
int c = 0;
- if (nn instanceof DoubleDistanceDBIDList) {
- for (DoubleDistanceDBIDListIter ni = ((DoubleDistanceDBIDList) nn).iter(); ni.valid(); ni.advance(), c++) {
- ByteArrayUtil.writeUnsignedVarint(buffer, ni.internalGetIndex());
- buffer.putDouble(ni.doubleDistance());
- }
- } else {
- for (DistanceDBIDListIter<DoubleDistance> ni = nn.iter(); ni.valid(); ni.advance(), c++) {
- ByteArrayUtil.writeUnsignedVarint(buffer, ni.internalGetIndex());
- buffer.putDouble(ni.getDistance().doubleValue());
- }
+ for(DoubleDBIDListIter ni = nn.iter(); ni.valid(); ni.advance(), c++) {
+ ByteArrayUtil.writeUnsignedVarint(buffer, ni.internalGetIndex());
+ buffer.putDouble(ni.doubleValue());
}
- if (c != nn.size()) {
+ if(c != nn.size()) {
throw new AbortException("Sizes did not agree. Cache is invalid.");
}
buffer.flip();
channel.write(buffer);
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if (prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
lock.release();
- } catch (IOException e) {
+ }
+ catch(IOException e) {
LOG.exception(e);
}
// FIXME: close!
@@ -227,7 +213,7 @@ public class CacheDoubleDistanceRangeQueries<O> extends AbstractApplication {
/**
* Distance function that is to be cached.
*/
- private DistanceFunction<O, DoubleDistance> distance = null;
+ private DistanceFunction<O> distance = null;
/**
* Number of neighbors to precompute.
@@ -244,18 +230,18 @@ public class CacheDoubleDistanceRangeQueries<O> extends AbstractApplication {
super.makeOptions(config);
input = config.tryInstantiate(InputStep.class);
// Distance function parameter
- final ObjectParameter<DistanceFunction<O, DoubleDistance>> dpar = new ObjectParameter<>(DISTANCE_ID, DistanceFunction.class);
- if (config.grab(dpar)) {
+ final ObjectParameter<DistanceFunction<O>> dpar = new ObjectParameter<>(DISTANCE_ID, DistanceFunction.class);
+ if(config.grab(dpar)) {
distance = dpar.instantiateClass(config);
}
final DoubleParameter kpar = new DoubleParameter(RADIUS_ID);
kpar.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
- if (config.grab(kpar)) {
+ if(config.grab(kpar)) {
radius = kpar.doubleValue();
}
// Output file parameter
final FileParameter cpar = new FileParameter(CACHE_ID, FileParameter.FileType.OUTPUT_FILE);
- if (config.grab(cpar)) {
+ if(config.grab(cpar)) {
out = cpar.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/application/cache/CacheFloatDistanceInOnDiskMatrix.java b/src/de/lmu/ifi/dbs/elki/application/cache/CacheFloatDistanceInOnDiskMatrix.java
index 5499415b..e4865a6b 100644
--- a/src/de/lmu/ifi/dbs/elki/application/cache/CacheFloatDistanceInOnDiskMatrix.java
+++ b/src/de/lmu/ifi/dbs/elki/application/cache/CacheFloatDistanceInOnDiskMatrix.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.cache;
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,23 +28,24 @@ import java.io.IOException;
import de.lmu.ifi.dbs.elki.application.AbstractApplication;
import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRange;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
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.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.external.DiskCacheBasedFloatDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.persistent.OnDiskUpperTriangleMatrix;
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.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
import de.lmu.ifi.dbs.elki.workflow.InputStep;
/**
- * Precompute an on-disk distance matrix, using double precision.
+ * Precompute an on-disk distance matrix, using float precision.
*
* @author Erich Schubert
*
@@ -52,9 +53,8 @@ import de.lmu.ifi.dbs.elki.workflow.InputStep;
* @apiviz.has DistanceFunction
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class CacheFloatDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>> extends AbstractApplication {
+public class CacheFloatDistanceInOnDiskMatrix<O> extends AbstractApplication {
/**
* The logger for this class.
*/
@@ -66,11 +66,6 @@ public class CacheFloatDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>>
private static final boolean debugExtraCheckSymmetry = false;
/**
- * Storage size: 4 bytes floats
- */
- private static final int FLOAT_SIZE = 4;
-
- /**
* Data source to process.
*/
private InputStep input;
@@ -78,7 +73,7 @@ public class CacheFloatDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>>
/**
* Distance function that is to be cached.
*/
- private DistanceFunction<O, D> distance;
+ private DistanceFunction<O> distance;
/**
* Output file.
@@ -92,7 +87,7 @@ public class CacheFloatDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>>
* @param distance Distance function
* @param out Matrix output file
*/
- public CacheFloatDistanceInOnDiskMatrix(InputStep input, DistanceFunction<O, D> distance, File out) {
+ public CacheFloatDistanceInOnDiskMatrix(InputStep input, DistanceFunction<O> distance, File out) {
super();
this.input = input;
this.distance = distance;
@@ -103,40 +98,35 @@ public class CacheFloatDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>>
public void run() {
Database database = input.getDatabase();
Relation<O> relation = database.getRelation(distance.getInputTypeRestriction());
- DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, distance);
-
- int matrixsize = 0;
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- final int intid = DBIDUtil.asInteger(iditer);
- matrixsize = Math.max(matrixsize, intid + 1);
- if (intid < 0) {
- throw new AbortException("OnDiskMatrixCache does not allow negative DBIDs.");
- }
- }
+ DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distance);
+
+ DBIDRange ids = DBIDUtil.assertRange(relation.getDBIDs());
+ int matrixsize = ids.size();
OnDiskUpperTriangleMatrix matrix;
try {
- matrix = new OnDiskUpperTriangleMatrix(out, DiskCacheBasedFloatDistanceFunction.FLOAT_CACHE_MAGIC, 0, FLOAT_SIZE, matrixsize);
- } catch (IOException e) {
+ matrix = new OnDiskUpperTriangleMatrix(out, DiskCacheBasedFloatDistanceFunction.FLOAT_CACHE_MAGIC, 0, ByteArrayUtil.SIZE_FLOAT, matrixsize);
+ }
+ catch(IOException e) {
throw new AbortException("Error creating output matrix.", e);
}
- for (DBIDIter id1 = relation.iterDBIDs(); id1.valid(); id1.advance()) {
- for (DBIDIter id2 = relation.iterDBIDs(); id2.valid(); id2.advance()) {
- if (DBIDUtil.asInteger(id2) >= DBIDUtil.asInteger(id1)) {
- float d = distanceQuery.distance(id1, id2).floatValue();
- if (debugExtraCheckSymmetry) {
- float d2 = distanceQuery.distance(id2, id1).floatValue();
- if (Math.abs(d - d2) > 0.0000001) {
- LOG.warning("Distance function doesn't appear to be symmetric!");
- }
- }
- try {
- matrix.getRecordBuffer(DBIDUtil.asInteger(id1), DBIDUtil.asInteger(id2)).putFloat(d);
- } catch (IOException e) {
- throw new AbortException("Error writing distance record " + id1 + "," + id2 + " to matrix.", e);
+ DBIDArrayIter id1 = ids.iter(), id2 = ids.iter();
+ for(; id1.valid(); id1.advance()) {
+ for(id2.seek(id1.getOffset()); id2.valid(); id2.advance()) {
+ float d = (float) distanceQuery.distance(id1, id2);
+ if(debugExtraCheckSymmetry) {
+ float d2 = (float) distanceQuery.distance(id2, id1);
+ if(Math.abs(d - d2) > 0.0000001) {
+ LOG.warning("Distance function doesn't appear to be symmetric!");
}
}
+ try {
+ matrix.getRecordBuffer(id1.getOffset(), id2.getOffset()).putFloat(d);
+ }
+ catch(IOException e) {
+ throw new AbortException("Error writing distance record " + DBIDUtil.toString(id1) + "," + DBIDUtil.toString(id2) + " to matrix.", e);
+ }
}
}
}
@@ -148,7 +138,7 @@ public class CacheFloatDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>>
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractApplication.Parameterizer {
+ public static class Parameterizer<O> extends AbstractApplication.Parameterizer {
/**
* Data source to process.
*/
@@ -157,7 +147,7 @@ public class CacheFloatDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>>
/**
* Distance function that is to be cached.
*/
- private DistanceFunction<O, D> distance = null;
+ private DistanceFunction<O> distance = null;
/**
* Output file.
@@ -169,19 +159,19 @@ public class CacheFloatDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>>
super.makeOptions(config);
input = config.tryInstantiate(InputStep.class);
// Distance function parameter
- final ObjectParameter<DistanceFunction<O, D>> dpar = new ObjectParameter<>(CacheDoubleDistanceInOnDiskMatrix.Parameterizer.DISTANCE_ID, DistanceFunction.class);
- if (config.grab(dpar)) {
+ final ObjectParameter<DistanceFunction<O>> dpar = new ObjectParameter<>(CacheDoubleDistanceInOnDiskMatrix.Parameterizer.DISTANCE_ID, DistanceFunction.class);
+ if(config.grab(dpar)) {
distance = dpar.instantiateClass(config);
}
// Output file parameter
final FileParameter cpar = new FileParameter(CacheDoubleDistanceInOnDiskMatrix.Parameterizer.CACHE_ID, FileParameter.FileType.OUTPUT_FILE);
- if (config.grab(cpar)) {
+ if(config.grab(cpar)) {
out = cpar.getValue();
}
}
@Override
- protected CacheFloatDistanceInOnDiskMatrix<O, D> makeInstance() {
+ protected CacheFloatDistanceInOnDiskMatrix<O> makeInstance() {
return new CacheFloatDistanceInOnDiskMatrix<>(input, distance, out);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/application/cache/package-info.java b/src/de/lmu/ifi/dbs/elki/application/cache/package-info.java
index 78a93a07..3327947b 100644
--- a/src/de/lmu/ifi/dbs/elki/application/cache/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/application/cache/package-info.java
@@ -11,7 +11,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/application/geo/VisualizeGeodesicDistances.java b/src/de/lmu/ifi/dbs/elki/application/geo/VisualizeGeodesicDistances.java
index 75770ba7..dfeb0349 100644
--- a/src/de/lmu/ifi/dbs/elki/application/geo/VisualizeGeodesicDistances.java
+++ b/src/de/lmu/ifi/dbs/elki/application/geo/VisualizeGeodesicDistances.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.geo;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -175,13 +175,9 @@ public class VisualizeGeodesicDistances extends AbstractApplication {
}
}
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if (prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
try {
ImageIO.write(img, "png", out);
diff --git a/src/de/lmu/ifi/dbs/elki/application/geo/package-info.java b/src/de/lmu/ifi/dbs/elki/application/geo/package-info.java
index 3c60474d..3e067d67 100644
--- a/src/de/lmu/ifi/dbs/elki/application/geo/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/application/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/application/greedyensemble/ComputeKNNOutlierScores.java b/src/de/lmu/ifi/dbs/elki/application/greedyensemble/ComputeKNNOutlierScores.java
index a890172c..6ddcfa84 100644
--- a/src/de/lmu/ifi/dbs/elki/application/greedyensemble/ComputeKNNOutlierScores.java
+++ b/src/de/lmu/ifi/dbs/elki/application/greedyensemble/ComputeKNNOutlierScores.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.greedyensemble;
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,9 +29,11 @@ import java.io.PrintStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import javax.xml.bind.DatatypeConverter;
+
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
-import de.lmu.ifi.dbs.elki.algorithm.outlier.KNNOutlier;
-import de.lmu.ifi.dbs.elki.algorithm.outlier.KNNWeightOutlier;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.distance.KNNOutlier;
+import de.lmu.ifi.dbs.elki.algorithm.outlier.distance.KNNWeightOutlier;
import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LDF;
import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LDOF;
import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOF;
@@ -49,15 +51,14 @@ 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.knn.KNNQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.PreprocessorKNNQuery;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
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.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNPreprocessor;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions.GaussianKernelDensityFunction;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.Base64;
+import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
@@ -85,9 +86,11 @@ import de.lmu.ifi.dbs.elki.workflow.InputStep;
* </p>
*
* @author Erich Schubert
+ *
+ * @param <O> Vector type
*/
@Reference(authors = "E. Schubert, R. Wojdanowski, A. Zimek, H.-P. Kriegel", title = "On Evaluation of Outlier Rankings and Outlier Scores", booktitle = "Proc. 12th SIAM International Conference on Data Mining (SDM), Anaheim, CA, 2012.")
-public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractApplication {
+public class ComputeKNNOutlierScores<O extends NumberVector> extends AbstractApplication {
/**
* Our logger class.
*/
@@ -101,7 +104,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
/**
* Distance function to use
*/
- final DistanceFunction<? super O, D> distf;
+ final DistanceFunction<? super O> distf;
/**
* Starting value of k.
@@ -145,7 +148,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
* @param outfile Output file
* @param scaling Scaling function
*/
- public ComputeKNNOutlierScores(InputStep inputstep, DistanceFunction<? super O, D> distf, int startk, int stepk, int maxk, ByLabelOutlier bylabel, File outfile, ScalingFunction scaling) {
+ public ComputeKNNOutlierScores(InputStep inputstep, DistanceFunction<? super O> distf, int startk, int stepk, int maxk, ByLabelOutlier bylabel, File outfile, ScalingFunction scaling) {
super();
this.distf = distf;
this.startk = startk;
@@ -163,12 +166,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
final Relation<O> relation = database.getRelation(distf.getInputTypeRestriction());
// If there is no kNN preprocessor already, then precompute.
- KNNQuery<O, D> knnq = QueryUtil.getKNNQuery(relation, distf, maxk + 2);
- if(!(knnq instanceof PreprocessorKNNQuery)) {
- LOG.verbose("Running preprocessor ...");
- MaterializeKNNPreprocessor<O, D> preproc = new MaterializeKNNPreprocessor<>(relation, distf, maxk + 2);
- database.addIndex(preproc);
- }
+ KNNQuery<O> knnq = DatabaseUtil.precomputedKNNQuery(database, relation, distf, maxk + 2);
// Test that we now get a proper index query
knnq = QueryUtil.getKNNQuery(relation, distf, maxk + 2);
@@ -194,7 +192,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
md.update(DBIDUtil.toString(iter).getBytes());
}
fout.append("# DBID-series MD5:");
- fout.append(Base64.encodeBase64(md.digest()));
+ fout.append(DatatypeConverter.printBase64Binary(md.digest()));
fout.append(FormatUtil.NEWLINE);
}
catch(NoSuchAlgorithmException e) {
@@ -221,7 +219,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
runForEachK(new AlgRunner() {
@Override
public void run(int k, String kstr) {
- KNNOutlier<O, D> knn = new KNNOutlier<>(distf, k);
+ KNNOutlier<O> knn = new KNNOutlier<>(distf, k);
OutlierResult knnresult = knn.run(database, relation);
writeResult(fout, ids, knnresult, scaling, "KNN-" + kstr);
database.getHierarchy().removeSubtree(knnresult);
@@ -232,7 +230,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
runForEachK(new AlgRunner() {
@Override
public void run(int k, String kstr) {
- KNNWeightOutlier<O, D> knnw = new KNNWeightOutlier<>(distf, k);
+ KNNWeightOutlier<O> knnw = new KNNWeightOutlier<>(distf, k);
OutlierResult knnresult = knnw.run(database, relation);
writeResult(fout, ids, knnresult, scaling, "KNNW-" + kstr);
database.getHierarchy().removeSubtree(knnresult);
@@ -243,7 +241,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
runForEachK(new AlgRunner() {
@Override
public void run(int k, String kstr) {
- LOF<O, D> lof = new LOF<>(k, distf);
+ LOF<O> lof = new LOF<>(k, distf);
OutlierResult lofresult = lof.run(database, relation);
writeResult(fout, ids, lofresult, scaling, "LOF-" + kstr);
database.getHierarchy().removeSubtree(lofresult);
@@ -254,7 +252,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
runForEachK(new AlgRunner() {
@Override
public void run(int k, String kstr) {
- SimplifiedLOF<O, D> lof = new SimplifiedLOF<>(k, distf);
+ SimplifiedLOF<O> lof = new SimplifiedLOF<>(k, distf);
OutlierResult lofresult = lof.run(database, relation);
writeResult(fout, ids, lofresult, scaling, "Simplified-LOF-" + kstr);
database.getHierarchy().removeSubtree(lofresult);
@@ -265,7 +263,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
runForEachK(new AlgRunner() {
@Override
public void run(int k, String kstr) {
- LoOP<O, D> loop = new LoOP<>(k, k, distf, distf, 1.0);
+ LoOP<O> loop = new LoOP<>(k, k, distf, distf, 1.0);
OutlierResult loopresult = loop.run(database, relation);
writeResult(fout, ids, loopresult, scaling, "LOOP-" + kstr);
database.getHierarchy().removeSubtree(loopresult);
@@ -278,7 +276,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
runForEachK(new AlgRunner() {
@Override
public void run(int k, String kstr) {
- LDOF<O, D> ldof = new LDOF<>(distf, k + 1);
+ LDOF<O> ldof = new LDOF<>(distf, k);
OutlierResult ldofresult = ldof.run(database, relation);
writeResult(fout, ids, ldofresult, scaling, "LDOF-" + kstr);
database.getHierarchy().removeSubtree(ldofresult);
@@ -290,7 +288,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
runForEachK(new AlgRunner() {
@Override
public void run(int k, String kstr) {
- LDF<O, D> ldf = new LDF<>(k, distf, GaussianKernelDensityFunction.KERNEL, 2, .1);
+ LDF<O> ldf = new LDF<>(k, distf, GaussianKernelDensityFunction.KERNEL, 2, .1);
OutlierResult ldfresult = ldf.run(database, relation);
writeResult(fout, ids, ldfresult, scaling, "LDF-" + kstr);
database.getHierarchy().removeSubtree(ldfresult);
@@ -312,13 +310,13 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
((OutlierScalingFunction) scaling).prepare(result);
}
out.append(label);
- Relation<Double> scores = result.getScores();
+ DoubleRelation scores = result.getScores();
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- double value = scores.get(iter);
+ double value = scores.doubleValue(iter);
if(scaling != null) {
value = scaling.getScaled(value);
}
- out.append(' ').append(FormatUtil.NF.format(value));
+ out.append(' ').append(Double.toString(value));
}
out.append(FormatUtil.NEWLINE);
}
@@ -355,7 +353,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
*
* @apiviz.exclude
*/
- public static class Parameterizer<O extends NumberVector<?>, D extends NumberDistance<D, ?>> extends AbstractApplication.Parameterizer {
+ public static class Parameterizer<O extends NumberVector> extends AbstractApplication.Parameterizer {
/**
* Option ID for k step size.
*/
@@ -399,7 +397,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
/**
* Distance function to use
*/
- DistanceFunction<? super O, D> distf;
+ DistanceFunction<? super O> distf;
/**
* By label outlier -- reference
@@ -422,7 +420,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
// Data input
inputstep = config.tryInstantiate(InputStep.class);
// Distance function
- ObjectParameter<DistanceFunction<? super O, D>> distP = AbstractAlgorithm.makeParameterDistanceFunction(EuclideanDistanceFunction.class, DistanceFunction.class);
+ ObjectParameter<DistanceFunction<? super O>> distP = AbstractAlgorithm.makeParameterDistanceFunction(EuclideanDistanceFunction.class, DistanceFunction.class);
if(config.grab(distP)) {
distf = distP.instantiateClass(config);
}
@@ -457,7 +455,7 @@ public class ComputeKNNOutlierScores<O extends NumberVector<?>, D extends Number
}
@Override
- protected ComputeKNNOutlierScores<O, D> makeInstance() {
+ protected ComputeKNNOutlierScores<O> makeInstance() {
return new ComputeKNNOutlierScores<>(inputstep, distf, startk, stepk, maxk, bylabel, outfile, scaling);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/application/greedyensemble/GreedyEnsembleExperiment.java b/src/de/lmu/ifi/dbs/elki/application/greedyensemble/GreedyEnsembleExperiment.java
index ab4bf001..147b4d28 100644
--- a/src/de/lmu/ifi/dbs/elki/application/greedyensemble/GreedyEnsembleExperiment.java
+++ b/src/de/lmu/ifi/dbs/elki/application/greedyensemble/GreedyEnsembleExperiment.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.greedyensemble;
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
@@ -45,15 +45,16 @@ import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
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.distancefunction.PrimitiveDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.WeightedPearsonCorrelationDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedEuclideanDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedManhattanDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.WeightedSquaredEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.evaluation.roc.ROC;
+import de.lmu.ifi.dbs.elki.evaluation.scores.ROCEvaluation;
+import de.lmu.ifi.dbs.elki.evaluation.scores.adapter.DecreasingVectorIter;
+import de.lmu.ifi.dbs.elki.evaluation.scores.adapter.VectorNonZero;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
-import de.lmu.ifi.dbs.elki.math.geometry.XYCurve;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
@@ -180,12 +181,12 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
public void run() {
// Note: the database contains the *result vectors*, not the original data.
final Database database = inputstep.getDatabase();
- Relation<NumberVector<?>> relation = database.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
- final NumberVector.Factory<NumberVector<?>, ?> factory = RelationUtil.getNumberVectorFactory(relation);
+ Relation<NumberVector> relation = database.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
+ final NumberVector.Factory<NumberVector> factory = RelationUtil.getNumberVectorFactory(relation);
final Relation<String> labels = DatabaseUtil.guessLabelRepresentation(database);
final DBID firstid = DBIDUtil.deref(labels.iterDBIDs());
final String firstlabel = labels.get(firstid);
- if (!firstlabel.matches("bylabel")) {
+ if(!firstlabel.matches("bylabel")) {
throw new AbortException("No 'by label' reference outlier found, which is needed for weighting!");
}
relation = applyPrescaling(prescaling, relation, firstid);
@@ -193,10 +194,10 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
// Dimensionality and reference vector
final int dim = RelationUtil.dimensionality(relation);
- final NumberVector<?> refvec = relation.get(firstid);
+ final NumberVector refvec = relation.get(firstid);
// Build the positive index set for ROC AUC.
- ROC.Predicate<ROC.DecreasingVectorIter> positive = new ROC.VectorNonZero(refvec);
+ VectorNonZero positive = new VectorNonZero(refvec);
final int desired_outliers = (int) (rate * dim);
int union_outliers = 0;
@@ -205,26 +206,26 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
// candidates.
{
int k = 0;
- ArrayList<ROC.DecreasingVectorIter> iters = new ArrayList<>(numcand);
- if (minvote >= numcand) {
+ ArrayList<DecreasingVectorIter> iters = new ArrayList<>(numcand);
+ if(minvote >= numcand) {
minvote = Math.max(1, numcand - 1);
}
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
// Skip "by label", obviously
- if (DBIDUtil.equal(firstid, iditer)) {
+ if(DBIDUtil.equal(firstid, iditer)) {
continue;
}
- iters.add(new ROC.DecreasingVectorIter(relation.get(iditer)));
+ iters.add(new DecreasingVectorIter(relation.get(iditer)));
}
- loop: while (union_outliers < desired_outliers) {
- for (ROC.DecreasingVectorIter iter : iters) {
- if (!iter.valid()) {
+ loop: while(union_outliers < desired_outliers) {
+ for(DecreasingVectorIter iter : iters) {
+ if(!iter.valid()) {
LOG.warning("Union_outliers=" + union_outliers + " < desired_outliers=" + desired_outliers + " minvote=" + minvote);
break loop;
}
int cur = iter.dim();
outliers_seen[cur] += 1;
- if (outliers_seen[cur] == minvote) {
+ if(outliers_seen[cur] == minvote) {
union_outliers += 1;
}
iter.advance();
@@ -237,32 +238,32 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
final double[] estimated_weights = new double[dim];
final double[] estimated_truth = new double[dim];
updateEstimations(outliers_seen, union_outliers, estimated_weights, estimated_truth);
- NumberVector<?> estimated_truth_vec = factory.newNumberVector(estimated_truth);
+ NumberVector estimated_truth_vec = factory.newNumberVector(estimated_truth);
- PrimitiveDoubleDistanceFunction<NumberVector<?>> wdist = getDistanceFunction(estimated_weights);
- PrimitiveDoubleDistanceFunction<NumberVector<?>> tdist = wdist;
+ PrimitiveDistanceFunction<NumberVector> wdist = getDistanceFunction(estimated_weights);
+ PrimitiveDistanceFunction<NumberVector> tdist = wdist;
// Build the naive ensemble:
final double[] naiveensemble = new double[dim];
{
double[] buf = new double[numcand];
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
int i = 0;
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- if (DBIDUtil.equal(firstid, iditer)) {
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ if(DBIDUtil.equal(firstid, iditer)) {
continue;
}
- final NumberVector<?> vec = relation.get(iditer);
+ final NumberVector vec = relation.get(iditer);
buf[i] = vec.doubleValue(d);
i++;
}
naiveensemble[d] = voting.combine(buf, i);
- if (Double.isNaN(naiveensemble[d])) {
+ if(Double.isNaN(naiveensemble[d])) {
LOG.warning("NaN after combining: " + FormatUtil.format(buf) + " i=" + i + " " + voting.toString());
}
}
}
- NumberVector<?> naivevec = factory.newNumberVector(naiveensemble);
+ NumberVector naivevec = factory.newNumberVector(naiveensemble);
// Compute single AUC scores and estimations.
// Remember the method most similar to the estimation
@@ -275,27 +276,27 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
{
final double[] greedyensemble = new double[dim];
// Compute individual scores
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- if (DBIDUtil.equal(firstid, iditer)) {
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ if(DBIDUtil.equal(firstid, iditer)) {
continue;
}
// fout.append(labels.get(id));
- final NumberVector<?> vec = relation.get(iditer);
+ final NumberVector vec = relation.get(iditer);
singleEnsemble(greedyensemble, vec);
final Vector v2 = new Vector(greedyensemble);
- double auc = XYCurve.areaUnderCurve(ROC.materializeROC(positive, new ROC.DecreasingVectorIter(v2)));
- double estimated = wdist.doubleDistance(v2, estimated_truth_vec);
- double cost = tdist.doubleDistance(v2, refvec);
+ double auc = ROCEvaluation.computeROCAUC(positive, new DecreasingVectorIter(v2));
+ double estimated = wdist.distance(v2, estimated_truth_vec);
+ double cost = tdist.distance(v2, refvec);
LOG.verbose("ROC AUC: " + auc + " estimated " + estimated + " cost " + cost + " " + labels.get(iditer));
- if (auc > bestauc) {
+ if(auc > bestauc) {
bestauc = auc;
bestaucstr = labels.get(iditer);
}
- if (cost < bestcost) {
+ if(cost < bestcost) {
bestcost = cost;
bestcoststr = labels.get(iditer);
}
- if (estimated < bestest || bestid == null) {
+ if(estimated < bestest || bestid == null) {
bestest = estimated;
bestid = DBIDUtil.deref(iditer);
}
@@ -303,12 +304,12 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
}
// Initialize ensemble with "best" method
- if (prescaling != null) {
+ if(prescaling != null) {
LOG.verbose("Input prescaling: " + prescaling);
}
LOG.verbose("Distance function: " + wdist);
LOG.verbose("Ensemble voting: " + voting);
- if (scaling != null) {
+ if(scaling != null) {
LOG.verbose("Ensemble rescaling: " + scaling);
}
LOG.verbose("Initial estimation of outliers: " + union_outliers);
@@ -323,31 +324,31 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
singleEnsemble(greedyensemble, relation.get(bestid));
// Greedily grow the ensemble
final double[] testensemble = new double[dim];
- while (enscands.size() > 0) {
- NumberVector<?> greedyvec = factory.newNumberVector(greedyensemble);
- final double oldd = wdist.doubleDistance(estimated_truth_vec, greedyvec);
+ while(enscands.size() > 0) {
+ NumberVector greedyvec = factory.newNumberVector(greedyensemble);
+ final double oldd = wdist.distance(estimated_truth_vec, greedyvec);
final int heapsize = enscands.size();
ArrayList<DoubleDBIDPair> heap = new ArrayList<>(heapsize);
double[] tmp = new double[dim];
- for (DBIDIter iter = enscands.iter(); iter.valid(); iter.advance()) {
- final NumberVector<?> vec = relation.get(iter);
+ for(DBIDIter iter = enscands.iter(); iter.valid(); iter.advance()) {
+ final NumberVector vec = relation.get(iter);
singleEnsemble(tmp, vec);
final Vector v2 = new Vector(greedyensemble);
- double diversity = wdist.doubleDistance(v2, greedyvec);
+ double diversity = wdist.distance(v2, greedyvec);
heap.add(DBIDUtil.newPair(diversity, iter));
}
Collections.sort(heap); // , Collections.reverseOrder());
- while (heap.size() > 0) {
+ while(heap.size() > 0) {
DBIDRef bestadd = heap.remove(heap.size() - 1);
enscands.remove(bestadd);
- final NumberVector<?> vec = relation.get(bestadd);
+ final NumberVector vec = relation.get(bestadd);
// Build combined ensemble.
{
double buf[] = new double[ensemble.size() + 1];
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
int j = 0;
- for (DBIDIter iter = ensemble.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ensemble.iter(); iter.valid(); iter.advance()) {
buf[j] = relation.get(iter).doubleValue(i);
j++;
}
@@ -356,46 +357,48 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
}
}
applyScaling(testensemble, scaling);
- NumberVector<?> testvec = factory.newNumberVector(testensemble);
- double newd = wdist.doubleDistance(estimated_truth_vec, testvec);
+ NumberVector testvec = factory.newNumberVector(testensemble);
+ double newd = wdist.distance(estimated_truth_vec, testvec);
// LOG.verbose("Distances: " + oldd + " vs. " + newd + " " +
// labels.get(bestadd));
- if (newd < oldd) {
+ if(newd < oldd) {
System.arraycopy(testensemble, 0, greedyensemble, 0, dim);
ensemble.add(bestadd);
// logger.verbose("Growing ensemble with: " + labels.get(bestadd));
break; // Recompute heap
- } else {
+ }
+ else {
dropped.add(bestadd);
// logger.verbose("Discarding: " + labels.get(bestadd));
- if (refine_truth) {
+ if(refine_truth) {
// Update target vectors and weights
- ArrayList<ROC.DecreasingVectorIter> iters = new ArrayList<>(numcand);
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ ArrayList<DecreasingVectorIter> iters = new ArrayList<>(numcand);
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
// Skip "by label", obviously
- if (DBIDUtil.equal(firstid, iditer) || dropped.contains(iditer)) {
+ if(DBIDUtil.equal(firstid, iditer) || dropped.contains(iditer)) {
continue;
}
- iters.add(new ROC.DecreasingVectorIter(relation.get(iditer)));
+ iters.add(new DecreasingVectorIter(relation.get(iditer)));
}
- if (minvote >= iters.size()) {
+ if(minvote >= iters.size()) {
minvote = iters.size() - 1;
}
union_outliers = 0;
Arrays.fill(outliers_seen, 0);
- while (union_outliers < desired_outliers) {
- for (ROC.DecreasingVectorIter iter : iters) {
- if (!iter.valid()) {
+ while(union_outliers < desired_outliers) {
+ for(DecreasingVectorIter iter : iters) {
+ if(!iter.valid()) {
break;
}
int cur = iter.dim();
- if (outliers_seen[cur] == 0) {
+ if(outliers_seen[cur] == 0) {
outliers_seen[cur] = 1;
- } else {
+ }
+ else {
outliers_seen[cur] += 1;
}
- if (outliers_seen[cur] == minvote) {
+ if(outliers_seen[cur] == minvote) {
union_outliers += 1;
}
iter.advance();
@@ -411,15 +414,15 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
// Build the improved ensemble:
StringBuilder greedylbl = new StringBuilder();
{
- for (DBIDIter iter = ensemble.iter(); iter.valid(); iter.advance()) {
- if (greedylbl.length() > 0) {
+ for(DBIDIter iter = ensemble.iter(); iter.valid(); iter.advance()) {
+ if(greedylbl.length() > 0) {
greedylbl.append(' ');
}
greedylbl.append(labels.get(iter));
}
}
- NumberVector<?> greedyvec = factory.newNumberVector(greedyensemble);
- if (refine_truth) {
+ NumberVector greedyvec = factory.newNumberVector(greedyensemble);
+ if(refine_truth) {
LOG.verbose("Estimated outliers remaining: " + union_outliers);
}
LOG.verbose("Greedy ensemble (" + ensemble.size() + "): " + greedylbl.toString());
@@ -429,15 +432,15 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
// Evaluate the naive ensemble and the "shrunk" ensemble
double naiveauc, naivecost;
{
- naiveauc = XYCurve.areaUnderCurve(ROC.materializeROC(positive, new ROC.DecreasingVectorIter(naivevec)));
- naivecost = tdist.doubleDistance(naivevec, refvec);
+ naiveauc = ROCEvaluation.computeROCAUC(positive, new DecreasingVectorIter(naivevec));
+ naivecost = tdist.distance(naivevec, refvec);
LOG.verbose("Naive ensemble AUC: " + naiveauc + " cost: " + naivecost);
LOG.verbose("Naive ensemble Gain: " + gain(naiveauc, bestauc, 1) + " cost gain: " + gain(naivecost, bestcost, 0));
}
double greedyauc, greedycost;
{
- greedyauc = XYCurve.areaUnderCurve(ROC.materializeROC(positive, new ROC.DecreasingVectorIter(greedyvec)));
- greedycost = tdist.doubleDistance(greedyvec, refvec);
+ greedyauc = ROCEvaluation.computeROCAUC(positive, new DecreasingVectorIter(greedyvec));
+ greedycost = tdist.distance(greedyvec, refvec);
LOG.verbose("Greedy ensemble AUC: " + greedyauc + " cost: " + greedycost);
LOG.verbose("Greedy ensemble Gain to best: " + gain(greedyauc, bestauc, 1) + " cost gain: " + gain(greedycost, bestcost, 0));
LOG.verbose("Greedy ensemble Gain to naive: " + gain(greedyauc, naiveauc, 1) + " cost gain: " + gain(greedycost, naivecost, 0));
@@ -447,17 +450,17 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
MeanVariance meancost = new MeanVariance();
HashSetModifiableDBIDs candidates = DBIDUtil.newHashSet(relation.getDBIDs());
candidates.remove(firstid);
- for (int i = 0; i < 1000; i++) {
+ for(int i = 0; i < 1000; i++) {
// Build the improved ensemble:
final double[] randomensemble = new double[dim];
{
DBIDs random = DBIDUtil.randomSample(candidates, ensemble.size(), (long) i);
double[] buf = new double[random.size()];
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
int j = 0;
- for (DBIDIter iter = random.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = random.iter(); iter.valid(); iter.advance()) {
assert (!DBIDUtil.equal(firstid, iter));
- final NumberVector<?> vec = relation.get(iter);
+ final NumberVector vec = relation.get(iter);
buf[j] = vec.doubleValue(d);
j++;
}
@@ -465,10 +468,10 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
}
}
applyScaling(randomensemble, scaling);
- NumberVector<?> randomvec = factory.newNumberVector(randomensemble);
- double auc = XYCurve.areaUnderCurve(ROC.materializeROC(positive, new ROC.DecreasingVectorIter(randomvec)));
+ NumberVector randomvec = factory.newNumberVector(randomensemble);
+ double auc = ROCEvaluation.computeROCAUC(positive, new DecreasingVectorIter(randomvec));
meanauc.put(auc);
- double cost = tdist.doubleDistance(randomvec, refvec);
+ double cost = tdist.distance(randomvec, refvec);
meancost.put(cost);
}
LOG.verbose("Random ensemble AUC: " + meanauc.getMean() + " + stddev: " + meanauc.getSampleStddev() + " = " + (meanauc.getMean() + meanauc.getSampleStddev()));
@@ -489,12 +492,12 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
* @param ensemble
* @param vec
*/
- protected void singleEnsemble(final double[] ensemble, final NumberVector<?> vec) {
+ protected void singleEnsemble(final double[] ensemble, final NumberVector vec) {
double buf[] = new double[1];
- for (int i = 0; i < ensemble.length; i++) {
+ for(int i = 0; i < ensemble.length; i++) {
buf[0] = vec.doubleValue(i);
ensemble[i] = voting.combine(buf, 1);
- if (Double.isNaN(ensemble[i])) {
+ if(Double.isNaN(ensemble[i])) {
LOG.warning("NaN after combining: " + FormatUtil.format(buf) + " " + voting.toString());
}
}
@@ -510,17 +513,17 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
* @param skip DBIDs to pass unmodified
* @return New relation
*/
- public static Relation<NumberVector<?>> applyPrescaling(ScalingFunction scaling, Relation<NumberVector<?>> relation, DBIDs skip) {
- if (scaling == null) {
+ public static Relation<NumberVector> applyPrescaling(ScalingFunction scaling, Relation<NumberVector> relation, DBIDs skip) {
+ if(scaling == null) {
return relation;
}
- NumberVector.Factory<NumberVector<?>, ?> factory = (NumberVector.Factory<NumberVector<?>, ?>) RelationUtil.assumeVectorField(relation).getFactory();
+ NumberVector.Factory<NumberVector> factory = RelationUtil.getNumberVectorFactory(relation);
DBIDs ids = relation.getDBIDs();
- WritableDataStore<NumberVector<?>> contents = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_HOT, NumberVector.class);
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- NumberVector<?> v = relation.get(iter);
+ WritableDataStore<NumberVector> contents = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_HOT, NumberVector.class);
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ NumberVector v = relation.get(iter);
double[] raw = v.getColumnVector().getArrayRef();
- if (!skip.contains(iter)) {
+ if(!skip.contains(iter)) {
applyScaling(raw, scaling);
}
contents.put(iter, factory.newNumberVector(raw, ArrayLikeUtil.DOUBLEARRAYADAPTER));
@@ -529,15 +532,15 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
}
private static void applyScaling(double[] raw, ScalingFunction scaling) {
- if (scaling == null) {
+ if(scaling == null) {
return;
}
- if (scaling instanceof OutlierScalingFunction) {
+ if(scaling instanceof OutlierScalingFunction) {
((OutlierScalingFunction) scaling).prepare(raw, ArrayLikeUtil.DOUBLEARRAYADAPTER);
}
- for (int i = 0; i < raw.length; i++) {
+ for(int i = 0; i < raw.length; i++) {
final double newval = scaling.getScaled(raw[i]);
- if (Double.isNaN(newval)) {
+ if(Double.isNaN(newval)) {
LOG.warning("NaN after prescaling: " + raw[i] + " " + scaling.toString() + " -> " + newval);
}
raw[i] = newval;
@@ -550,19 +553,20 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
// final double orate = union_outliers * 1.0 / (outliers_seen.length);
final double oscore = 1.; // .5 - .5 * orate;
final double iscore = 0.; // 1 - .5 * orate;
- for (int i = 0; i < outliers.length; i++) {
- if (outliers[i] >= minvote) {
+ for(int i = 0; i < outliers.length; i++) {
+ if(outliers[i] >= minvote) {
weights[i] = oweight;
truth[i] = oscore;
- } else {
+ }
+ else {
weights[i] = iweight;
truth[i] = iscore;
}
}
}
- private PrimitiveDoubleDistanceFunction<NumberVector<?>> getDistanceFunction(double[] estimated_weights) {
- switch(distance) {
+ private PrimitiveDistanceFunction<NumberVector> getDistanceFunction(double[] estimated_weights) {
+ switch(distance){
case SQEUCLIDEAN:
return new WeightedSquaredEuclideanDistanceFunction(estimated_weights);
case EUCLIDEAN:
@@ -658,29 +662,29 @@ public class GreedyEnsembleExperiment extends AbstractApplication {
inputstep = config.tryInstantiate(InputStep.class);
// Voting method
ObjectParameter<EnsembleVoting> votingP = new ObjectParameter<>(VOTING_ID, EnsembleVoting.class, EnsembleVotingMean.class);
- if (config.grab(votingP)) {
+ if(config.grab(votingP)) {
voting = votingP.instantiateClass(config);
}
// Similarity measure
EnumParameter<Distance> distanceP = new EnumParameter<>(DISTANCE_ID, Distance.class);
- if (config.grab(distanceP)) {
+ if(config.grab(distanceP)) {
distance = distanceP.getValue();
}
// Prescaling
ObjectParameter<ScalingFunction> prescalingP = new ObjectParameter<>(PRESCALING_ID, ScalingFunction.class);
prescalingP.setOptional(true);
- if (config.grab(prescalingP)) {
+ if(config.grab(prescalingP)) {
prescaling = prescalingP.instantiateClass(config);
}
// Ensemble scaling
ObjectParameter<ScalingFunction> scalingP = new ObjectParameter<>(SCALING_ID, ScalingFunction.class);
scalingP.setOptional(true);
- if (config.grab(scalingP)) {
+ if(config.grab(scalingP)) {
scaling = scalingP.instantiateClass(config);
}
// Expected rate of outliers
DoubleParameter rateP = new DoubleParameter(RATE_ID, 0.01);
- if (config.grab(rateP)) {
+ if(config.grab(rateP)) {
rate = rateP.doubleValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/application/greedyensemble/VisualizePairwiseGainMatrix.java b/src/de/lmu/ifi/dbs/elki/application/greedyensemble/VisualizePairwiseGainMatrix.java
index 3ef30c10..60678bea 100644
--- a/src/de/lmu/ifi/dbs/elki/application/greedyensemble/VisualizePairwiseGainMatrix.java
+++ b/src/de/lmu/ifi/dbs/elki/application/greedyensemble/VisualizePairwiseGainMatrix.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.greedyensemble;
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
@@ -39,13 +39,14 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
-import de.lmu.ifi.dbs.elki.evaluation.roc.ROC;
+import de.lmu.ifi.dbs.elki.evaluation.scores.ROCEvaluation;
+import de.lmu.ifi.dbs.elki.evaluation.scores.adapter.DecreasingVectorIter;
+import de.lmu.ifi.dbs.elki.evaluation.scores.adapter.VectorNonZero;
import de.lmu.ifi.dbs.elki.evaluation.similaritymatrix.ComputeSimilarityMatrixImage;
import de.lmu.ifi.dbs.elki.evaluation.similaritymatrix.ComputeSimilarityMatrixImage.SimilarityMatrix;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
-import de.lmu.ifi.dbs.elki.math.geometry.XYCurve;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
@@ -134,21 +135,21 @@ public class VisualizePairwiseGainMatrix extends AbstractApplication {
@Override
public void run() {
final Database database = inputstep.getDatabase();
- Relation<NumberVector<?>> relation = database.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
+ Relation<NumberVector> relation = database.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
final Relation<String> labels = DatabaseUtil.guessLabelRepresentation(database);
final DBID firstid = DBIDUtil.deref(labels.iterDBIDs());
final String firstlabel = labels.get(firstid);
- if (!firstlabel.matches(".*by.?label.*")) {
+ if(!firstlabel.matches(".*by.?label.*")) {
throw new AbortException("No 'by label' reference outlier found, which is needed for weighting!");
}
relation = GreedyEnsembleExperiment.applyPrescaling(prescaling, relation, firstid);
// Dimensionality and reference vector
final int dim = RelationUtil.dimensionality(relation);
- final NumberVector<?> refvec = relation.get(firstid);
+ final NumberVector refvec = relation.get(firstid);
// Build the truth vector
- ROC.VectorNonZero pos = new ROC.VectorNonZero(refvec);
+ VectorNonZero pos = new VectorNonZero(refvec);
ArrayModifiableDBIDs ids = DBIDUtil.newArray(relation.getDBIDs());
ids.remove(firstid);
@@ -162,46 +163,40 @@ public class VisualizePairwiseGainMatrix extends AbstractApplication {
FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Computing ensemble gain.", size * (size + 1) >> 1, LOG) : null;
double[] buf = new double[2]; // Vote combination buffer.
int a = 0;
- for (DBIDIter id = ids.iter(); id.valid(); id.advance(), a++) {
- final NumberVector<?> veca = relation.get(id);
+ for(DBIDIter id = ids.iter(); id.valid(); id.advance(), a++) {
+ final NumberVector veca = relation.get(id);
// Direct AUC score:
{
- double auc = XYCurve.areaUnderCurve(ROC.materializeROC(pos, new ROC.DecreasingVectorIter(veca)));
+ double auc = ROCEvaluation.computeROCAUC(pos, new DecreasingVectorIter(veca));
data[a][a] = auc;
// minmax.put(auc);
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
}
// Compare to others, exploiting symmetry
DBIDArrayIter id2 = ids.iter();
id2.seek(a + 1);
- for (int b = a + 1; b < size; b++, id2.advance()) {
- final NumberVector<?> vecb = relation.get(id2);
+ for(int b = a + 1; b < size; b++, id2.advance()) {
+ final NumberVector vecb = relation.get(id2);
double[] combined = new double[dim];
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
buf[0] = veca.doubleValue(d);
buf[1] = vecb.doubleValue(d);
combined[d] = voting.combine(buf);
}
- double auc = XYCurve.areaUnderCurve(ROC.materializeROC(pos, new ROC.DecreasingVectorIter(new Vector(combined))));
+ double auc = ROCEvaluation.computeROCAUC(pos, new DecreasingVectorIter(new Vector(combined)));
// logger.verbose(auc + " " + labels.get(ids.get(a)) + " " +
// labels.get(ids.get(b)));
data[a][b] = auc;
data[b][a] = auc;
commax.put(data[a][b]);
// minmax.put(auc);
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
}
}
- if (prog != null) {
- prog.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(prog);
}
- for (int a = 0; a < size; a++) {
- for (int b = a + 1; b < size; b++) {
+ for(int a = 0; a < size; a++) {
+ for(int b = a + 1; b < size; b++) {
double ref = Math.max(data[a][a], data[b][b]);
data[a][b] = (data[a][b] - ref) / (1 - ref);
data[b][a] = (data[b][a] - ref) / (1 - ref);
@@ -210,7 +205,7 @@ public class VisualizePairwiseGainMatrix extends AbstractApplication {
minmax.put(data[a][b]);
}
}
- for (int a = 0; a < size; a++) {
+ for(int a = 0; a < size; a++) {
data[a][a] = 0;
}
@@ -218,25 +213,27 @@ public class VisualizePairwiseGainMatrix extends AbstractApplication {
boolean hasneg = (minmax.getMin() < -1E-3);
LinearScaling scale;
- if (!hasneg) {
+ if(!hasneg) {
scale = LinearScaling.fromMinMax(0., minmax.getMax());
- } else {
+ }
+ else {
scale = LinearScaling.fromMinMax(0.0, Math.max(minmax.getMax(), -minmax.getMin()));
}
scale = LinearScaling.fromMinMax(0., .5);
BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
- for (int x = 0; x < size; x++) {
- for (int y = x; y < size; y++) {
+ for(int x = 0; x < size; x++) {
+ for(int y = x; y < size; y++) {
double val = data[x][y];
val = Math.max(-1, Math.min(1., scale.getScaled(val)));
// Compute color:
final int col;
{
- if (val >= 0) {
+ if(val >= 0) {
int ival = 0xFF & (int) (255 * val);
col = 0xff000000 | (ival << 8);
- } else {
+ }
+ else {
int ival = 0xFF & (int) (255 * -val);
col = 0xff000000 | (ival << 16);
}
@@ -255,8 +252,8 @@ public class VisualizePairwiseGainMatrix extends AbstractApplication {
factory.processNewResult(database, database);
List<VisualizationTask> tasks = ResultUtil.filterResults(database, VisualizationTask.class);
- for (VisualizationTask task : tasks) {
- if (task.getFactory() == factory) {
+ for(VisualizationTask task : tasks) {
+ if(task.getFactory() == factory) {
showVisualization(context, factory, task);
}
}
@@ -320,12 +317,12 @@ public class VisualizePairwiseGainMatrix extends AbstractApplication {
// Prescaling
ObjectParameter<ScalingFunction> prescalingP = new ObjectParameter<>(GreedyEnsembleExperiment.Parameterizer.PRESCALING_ID, ScalingFunction.class);
prescalingP.setOptional(true);
- if (config.grab(prescalingP)) {
+ if(config.grab(prescalingP)) {
prescaling = prescalingP.instantiateClass(config);
}
ObjectParameter<EnsembleVoting> votingP = new ObjectParameter<>(GreedyEnsembleExperiment.Parameterizer.VOTING_ID, EnsembleVoting.class, EnsembleVotingMean.class);
- if (config.grab(votingP)) {
+ if(config.grab(votingP)) {
voting = votingP.instantiateClass(config);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/application/greedyensemble/package-info.java b/src/de/lmu/ifi/dbs/elki/application/greedyensemble/package-info.java
index f8e8f705..05aad761 100644
--- a/src/de/lmu/ifi/dbs/elki/application/greedyensemble/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/application/greedyensemble/package-info.java
@@ -11,7 +11,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/application/internal/CheckELKIServices.java b/src/de/lmu/ifi/dbs/elki/application/internal/CheckELKIServices.java
index 7dca7f37..f5940e7d 100644
--- a/src/de/lmu/ifi/dbs/elki/application/internal/CheckELKIServices.java
+++ b/src/de/lmu/ifi/dbs/elki/application/internal/CheckELKIServices.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.internal;
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,22 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
+import java.net.JarURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
+import java.util.TreeSet;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -65,50 +72,66 @@ public class CheckELKIServices {
private Pattern strip = Pattern.compile("^[\\s#]*(?:deprecated:\\s*)?(.*?)[\\s]*$");
/**
- * Package to skip matches in - unreleased code.
- */
- private String[] skippackages = { "experimentalcode.", "project." };
-
- /**
* Main method.
*
* @param argv Command line arguments
*/
public static void main(String[] argv) {
- boolean update = false, noskip = false;
- for(String arg : argv) {
- if("-update".equals(arg)) {
- update = true;
- }
- if("-all".equals(arg)) {
- noskip = true;
- }
+ String update = null;
+ if(argv.length == 2 && "-update".equals(argv[0])) {
+ update = argv[1];
+ LOG.info("Updating service files in folder: " + update);
+ }
+ else if(argv.length != 0) {
+ throw new AbortException("Incorrect command line parameters.");
}
- new CheckELKIServices().checkServices(update, noskip);
+ new CheckELKIServices().checkServices(update);
}
/**
* Retrieve all properties and check them.
*
- * @param update Flag to enable automatic updating
- * @param noskip Override filters, include all (in particular,
- * experimentalcode)
+ * @param update Folder to update service files in
*/
- public void checkServices(boolean update, boolean noskip) {
- URL u = getClass().getClassLoader().getResource(ELKIServiceLoader.PREFIX);
+ public void checkServices(String update) {
+ TreeSet<String> props = new TreeSet<>();
+ Enumeration<URL> us;
try {
- for(String prop : new File(u.toURI()).list()) {
- if(".svn".equals(prop)) {
+ us = getClass().getClassLoader().getResources(ELKIServiceLoader.PREFIX);
+ }
+ catch(IOException e) {
+ throw new AbortException("Error enumerating service folders.", e);
+ }
+ while(us.hasMoreElements()) {
+ URL u = us.nextElement();
+ try {
+ if(("jar".equals(u.getProtocol()))) {
+ JarURLConnection con = (JarURLConnection) u.openConnection();
+ try (JarFile jar = con.getJarFile()) {
+ Enumeration<JarEntry> entries = jar.entries();
+ while(entries.hasMoreElements()) {
+ String prop = entries.nextElement().getName();
+ if(prop.length() > ELKIServiceLoader.PREFIX.length() && prop.startsWith(ELKIServiceLoader.PREFIX)) {
+ props.add(prop.substring(ELKIServiceLoader.PREFIX.length()));
+ }
+ }
+ }
continue;
}
- if(LOG.isVerbose()) {
- LOG.verbose("Checking property: " + prop);
+ if("file".equals(u.getProtocol())) {
+ props.addAll(Arrays.asList(new File(u.toURI()).list()));
}
- checkService(prop, update, noskip);
}
+ catch(IOException | URISyntaxException e) {
+ throw new AbortException("Error enumerating service folders.", e);
+ }
+
}
- catch(URISyntaxException e) {
- throw new AbortException("Cannot check all properties, as some are not in a file: URL.");
+ for(String prop : props) {
+ if(LOG.isVerbose()) {
+ LOG.verbose("Checking property: " + prop);
+ }
+ checkService(prop, update);
}
}
@@ -116,11 +139,9 @@ public class CheckELKIServices {
* Check a single service class
*
* @param prop Class name.
- * @param update Flag to enable automatic updating
- * @param noskip Override filters, include all (in particular,
- * experimentalcode)
+ * @param update Folder to update service files in
*/
- private void checkService(String prop, boolean update, boolean noskip) {
+ private void checkService(String prop, String update) {
Class<?> cls;
try {
cls = Class.forName(prop);
@@ -129,46 +150,37 @@ public class CheckELKIServices {
LOG.warning("Service file name is not a class name: " + prop);
return;
}
- List<Class<?>> impls = InspectionUtil.findAllImplementations(cls, false);
+ List<Class<?>> impls = InspectionUtil.findAllImplementations(cls, false, false);
HashSet<String> names = new HashSet<>();
for(Class<?> c2 : impls) {
- boolean skip = false;
- for(String pkg : skippackages) {
- if(c2.getName().startsWith(pkg)) {
- skip = true;
- break;
- }
- }
- if(!noskip && skip) {
- continue;
- }
names.add(c2.getName());
}
+ Matcher m = strip.matcher("");
try {
- InputStream is = getClass().getClassLoader().getResource(ELKIServiceLoader.PREFIX + cls.getName()).openStream();
- BufferedReader r = new BufferedReader(new InputStreamReader(is, "utf-8"));
- for(String line;;) {
- line = r.readLine();
- // End of stream:
- if(line == null) {
- break;
- }
- Matcher m = strip.matcher(line);
- if(m.matches()) {
+ Enumeration<URL> us = getClass().getClassLoader().getResources(ELKIServiceLoader.PREFIX + cls.getName());
+ while(us.hasMoreElements()) {
+ URL u = us.nextElement();
+ boolean injar = "jar".equals(u.getProtocol());
+ BufferedReader r = new BufferedReader(new InputStreamReader(u.openStream(), "utf-8"));
+ for(String line;;) {
+ line = r.readLine();
+ // End of stream:
+ if(line == null) {
+ break;
+ }
+ m.reset(line);
+ if(!m.matches()) {
+ LOG.warning("Line: " + line + " didn't match regexp.");
+ continue;
+ }
String stripped = m.group(1);
if(stripped.length() > 0) {
- if(names.contains(stripped)) {
- names.remove(stripped);
- }
- else {
- LOG.warning("Name " + stripped + " found for property " + prop + " but no class discovered (or referenced twice?).");
+ if(!names.remove(stripped) && !injar) {
+ LOG.warning("Name " + stripped + " found for property " + prop + " but no class discovered (or listed twice).");
}
}
}
- else {
- LOG.warning("Line: " + line + " didn't match regexp.");
- }
}
}
catch(IOException e) {
@@ -179,40 +191,30 @@ public class CheckELKIServices {
ArrayList<String> sorted = new ArrayList<>(names);
// TODO: sort by package, then classname
Collections.sort(sorted);
- if(!update) {
+ if(update == null) {
StringBuilder message = new StringBuilder();
message.append("Class ").append(prop).append(" lacks suggestions:").append(FormatUtil.NEWLINE);
for(String remaining : sorted) {
message.append("# ").append(remaining).append(FormatUtil.NEWLINE);
}
LOG.warning(message.toString());
+ return;
}
- else {
- // Try to automatically update:
- URL f = getClass().getClassLoader().getResource(ELKIServiceLoader.PREFIX + cls.getName());
- String fnam = f.getFile();
- if(fnam == null) {
- LOG.warning("Cannot update: " + f + " seems to be in a jar file.");
- }
- else {
- try {
- FileOutputStream out = new FileOutputStream(fnam, true);
- PrintStream pr = new PrintStream(out);
- pr.println();
- pr.println("### Automatically appended entries:");
- for(String remaining : sorted) {
- pr.println(remaining);
- }
- pr.flush();
- pr.close();
- out.flush();
- out.close();
- LOG.warning("Updated: " + fnam);
- }
- catch(IOException e) {
- LOG.exception(e);
- }
+ // Try to automatically update:
+ try {
+ Files.createDirectories(Paths.get(update + File.separator + ELKIServiceLoader.PREFIX));
+ String fname = update + File.separator + ELKIServiceLoader.PREFIX + prop;
+ PrintStream pr = new PrintStream(new FileOutputStream(fname, true));
+ pr.println(); // In case there was no linefeed at the end.
+ pr.println("### Automatically appended entries:");
+ for(String remaining : sorted) {
+ pr.println(remaining);
}
+ pr.close();
+ LOG.warning("Updated service file: " + fname);
+ }
+ catch(IOException e) {
+ LOG.exception(e);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/application/internal/CheckParameterizables.java b/src/de/lmu/ifi/dbs/elki/application/internal/CheckParameterizables.java
index 68a4b127..b0970b8f 100644
--- a/src/de/lmu/ifi/dbs/elki/application/internal/CheckParameterizables.java
+++ b/src/de/lmu/ifi/dbs/elki/application/internal/CheckParameterizables.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.internal;
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,17 +23,28 @@ package de.lmu.ifi.dbs.elki.application.internal;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.io.File;
+import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.net.JarURLConnection;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration;
import de.lmu.ifi.dbs.elki.logging.Logging.Level;
+import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
+import de.lmu.ifi.dbs.elki.utilities.ELKIServiceLoader;
import de.lmu.ifi.dbs.elki.utilities.InspectionUtil;
+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.Parameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
/**
@@ -43,7 +54,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
* @author Erich Schubert
*
* @apiviz.landmark
- * @apiviz.uses Parameterizable
+ * @apiviz.uses AbstractParameterizer
*/
public class CheckParameterizables {
/**
@@ -52,96 +63,208 @@ public class CheckParameterizables {
private static final Logging LOG = Logging.getLogger(CheckParameterizables.class);
/**
+ * Known parameterizable classes/interfaces.
+ */
+ private List<Class<?>> knownParameterizables;
+
+ /**
* Validate all "Parameterizable" objects for parts of the API contract that
* cannot be specified in Java interfaces (such as constructors, static
* methods)
*/
public void checkParameterizables() {
LoggingConfiguration.setVerbose(Level.VERBOSE);
- for(final Class<?> cls : InspectionUtil.findAllImplementations(Object.class, false)) {
- final Constructor<?> constructor;
- try {
- constructor = cls.getDeclaredConstructor(Parameterization.class);
- }
- catch(NoClassDefFoundError e) {
- LOG.verbose("Class discovered but not found?!? " + cls.getName());
- // Not found ?!?
- continue;
- }
- catch(Exception e) {
- // Not parameterizable.
- continue;
- }
- checkParameterizable(cls, constructor);
- }
- for(final Class<?> cls : InspectionUtil.findAllImplementations(Parameterizable.class, false)) {
- boolean hasConstructor = false;
- // check for a V3 Parameterizer class
- for(Class<?> inner : cls.getDeclaredClasses()) {
- if(AbstractParameterizer.class.isAssignableFrom(inner)) {
- try {
- Class<? extends AbstractParameterizer> pcls = inner.asSubclass(AbstractParameterizer.class);
- pcls.newInstance();
- if(checkParameterizer(cls, pcls)) {
- hasConstructor = true;
+ knownParameterizables = new ArrayList<>();
+ try {
+ Enumeration<URL> us = getClass().getClassLoader().getResources(ELKIServiceLoader.PREFIX);
+ while(us.hasMoreElements()) {
+ URL u = us.nextElement();
+ if("file".equals(u.getProtocol())) {
+ for(String prop : new File(u.toURI()).list()) {
+ try {
+ knownParameterizables.add(Class.forName(prop));
+ }
+ catch(ClassNotFoundException e) {
+ LOG.warning("Service file name is not a class name: " + prop);
continue;
}
}
- catch(Exception e) {
- LOG.verbose("Could not run Parameterizer: " + inner.getName() + ": " + e);
- // continue. Probably non-public
+ }
+ else if(("jar".equals(u.getProtocol()))) {
+ JarURLConnection con = (JarURLConnection) u.openConnection();
+ try (JarFile jar = con.getJarFile()) {
+ Enumeration<JarEntry> entries = jar.entries();
+ while(entries.hasMoreElements()) {
+ String prop = entries.nextElement().getName();
+ if(prop.length() > ELKIServiceLoader.PREFIX.length() && prop.startsWith(ELKIServiceLoader.PREFIX)) {
+ prop = prop.substring(ELKIServiceLoader.PREFIX.length());
+ try {
+ knownParameterizables.add(Class.forName(prop));
+ }
+ catch(ClassNotFoundException e) {
+ LOG.warning("Service file name is not a class name: " + prop);
+ continue;
+ }
+ }
+ }
}
}
}
+ }
+ catch(IOException | URISyntaxException e) {
+ throw new AbortException("Error enumerating service folders.", e);
+ }
- // check for a V2 factory method.
- try {
- ClassGenericsUtil.getParameterizationFactoryMethod(cls, Object.class);
- hasConstructor = true;
- // logger.debugFine("Found factory method for class: "+ cls.getName());
- }
- catch(NoClassDefFoundError e) {
- LOG.verbose("Class discovered but not found?!? " + cls.getName());
- // Not found ?!?
+ final String internal = de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizer.class.getPackage().getName();
+ for(final Class<?> cls : InspectionUtil.findAllImplementations(Object.class, false, false)) {
+ // Classes in the same package are special and don't cause warnings.
+ if(cls.getName().startsWith(internal)) {
continue;
}
- catch(Exception e) {
- // do nothing.
- }
try {
- cls.getConstructor(Parameterization.class);
- hasConstructor = true;
+ State state = State.NO_CONSTRUCTOR;
+ state = checkV3Parameterization(cls, state);
+ if(state == State.ERROR) {
+ continue;
+ }
+ state = checkV2Parameterization(cls, state);
+ if(state == State.ERROR) {
+ continue;
+ }
+ state = checkV1Parameterization(cls, state);
+ if(state == State.ERROR) {
+ continue;
+ }
+ state = checkDefaultConstructor(cls, state);
+ if(state == State.ERROR) {
+ continue;
+ }
+ boolean expectedParameterizer = checkSupertypes(cls);
+ if(state == State.NO_CONSTRUCTOR && expectedParameterizer) {
+ LOG.verbose("Class " + cls.getName() + //
+ " implements a parameterizable interface, but doesn't have a public and parameterless constructor!");
+ }
+ if(state == State.INSTANTIABLE && !expectedParameterizer) {
+ LOG.verbose("Class " + cls.getName() + //
+ " has a parameterizer, but there is no service file for any of its interfaces.");
+ }
}
catch(NoClassDefFoundError e) {
- LOG.verbose("Class discovered but not found?!? " + cls.getName());
- // Not found ?!?
- continue;
+ LOG.verbose("Class discovered but not found: " + cls.getName() + " (missing: " + e.getMessage() + ")");
}
- catch(Exception e) {
- // do nothing.
+ }
+ }
+
+ /**
+ * Check all supertypes of a class.
+ *
+ * @param cls Class to check.
+ * @return {@code true} when at least one supertype is a known parameterizable
+ * type.
+ */
+ private boolean checkSupertypes(Class<?> cls) {
+ for(Class<?> c : knownParameterizables) {
+ if(c.isAssignableFrom(cls)) {
+ return true;
}
- try {
- cls.getConstructor();
- hasConstructor = true;
+ }
+ return false;
+ }
+
+ /**
+ * Current verification state.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ enum State {
+ NO_CONSTRUCTOR, //
+ INSTANTIABLE, //
+ DEFAULT_INSTANTIABLE, //
+ ERROR, //
+ }
+
+ /** Check for a V1 constructor. */
+ private State checkV1Parameterization(Class<?> cls, State state) throws NoClassDefFoundError {
+ final Constructor<?> constructor;
+ try {
+ constructor = cls.getDeclaredConstructor(Parameterization.class);
+ if(state == State.INSTANTIABLE) {
+ LOG.warning("More than one parameterization method in class " + cls.getName());
}
- catch(NoClassDefFoundError e) {
- LOG.verbose("Class discovered but not found?!? " + cls.getName());
- // Not found ?!?
- continue;
+ LOG.warning("V1 constructor found in class: " + cls.getName());
+ if(!Modifier.isPublic(constructor.getModifiers())) {
+ LOG.verbose("Constructor for class " + cls.getName() + " is not public!");
}
- catch(Exception e) {
- // do nothing.
+ return State.INSTANTIABLE;
+ }
+ catch(NoSuchMethodException e) {
+ // Not parameterizable?
+ return state;
+ }
+ }
+
+ /** Check for a V2 constructor. */
+ private State checkV2Parameterization(Class<?> cls, State state) throws NoClassDefFoundError {
+ try {
+ ClassGenericsUtil.getParameterizationFactoryMethod(cls, Object.class);
+ if(state == State.INSTANTIABLE) {
+ LOG.warning("More than one parameterization method in class " + cls.getName());
}
- if(!hasConstructor) {
- LOG.verbose("Class " + cls.getName() + " is Parameterizable but doesn't have a constructor with the appropriate signature!");
+ LOG.warning("V2 factory method found in class: " + cls.getName());
+ return State.INSTANTIABLE;
+ }
+ catch(NoSuchMethodException e) {
+ // do nothing.
+ return state;
+ }
+ }
+
+ /** Check for a V3 constructor. */
+ private State checkV3Parameterization(Class<?> cls, State state) throws NoClassDefFoundError {
+ // check for a V3 Parameterizer class
+ for(Class<?> inner : cls.getDeclaredClasses()) {
+ if(AbstractParameterizer.class.isAssignableFrom(inner)) {
+ try {
+ Class<? extends AbstractParameterizer> pcls = inner.asSubclass(AbstractParameterizer.class);
+ pcls.newInstance();
+ if(checkParameterizer(cls, pcls)) {
+ if(state == State.INSTANTIABLE) {
+ LOG.warning("More than one parameterization method in class " + cls.getName());
+ }
+ state = State.INSTANTIABLE;
+ }
+ }
+ catch(Exception e) {
+ LOG.verbose("Could not run Parameterizer: " + inner.getName() + ": " + e.getMessage());
+ // continue. Probably non-public
+ }
+ catch(Error e) {
+ LOG.verbose("Could not run Parameterizer: " + inner.getName() + ": " + e.getMessage());
+ // continue. Probably non-public
+ }
}
}
+ return state;
+ }
+
+ /** Check for a default constructor. */
+ private State checkDefaultConstructor(Class<?> cls, State state) throws NoClassDefFoundError {
+ try {
+ cls.getConstructor();
+ return State.DEFAULT_INSTANTIABLE;
+ }
+ catch(Exception e) {
+ // do nothing.
+ }
+ return state;
}
private boolean checkParameterizer(Class<?> cls, Class<? extends AbstractParameterizer> par) {
+ int checkResult = 0;
try {
par.getConstructor();
- boolean hasMakeInstance = false;
final Method methods[] = par.getDeclaredMethods();
for(int i = 0; i < methods.length; ++i) {
final Method meth = methods[i];
@@ -150,33 +273,26 @@ public class CheckParameterizables {
if(meth.getParameterTypes().length == 0) {
// And check for proper return type.
if(cls.isAssignableFrom(meth.getReturnType())) {
- hasMakeInstance = true;
+ checkResult = 1;
+ }
+ else if(checkResult == 0) {
+ checkResult = 2; // Nothing better
}
}
+ else if(checkResult == 0) {
+ checkResult += 3;
+ }
}
}
- if(hasMakeInstance) {
- return true;
- }
}
catch(Exception e) {
LOG.warning("No proper Parameterizer.makeInstance for " + cls.getName() + ": " + e);
return false;
}
- LOG.warning("No proper Parameterizer.makeInstance for " + cls.getName() + " found!");
- return false;
- }
-
- private void checkParameterizable(Class<?> cls, Constructor<?> constructor) {
- // Classes in the same package are special and don't cause warnings.
- if(!cls.getName().startsWith(Parameterizable.class.getPackage().getName())) {
- if(!Modifier.isPublic(constructor.getModifiers())) {
- LOG.verbose("Constructor for class " + cls.getName() + " is not public!");
- }
- if(!Parameterizable.class.isAssignableFrom(cls)) {
- LOG.verbose("Class " + cls.getName() + " should implement Parameterizable!");
- }
+ if(checkResult > 1) {
+ LOG.warning("No proper Parameterizer.makeInstance for " + cls.getName() + " found!");
}
+ return checkResult == 1;
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java b/src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java
index b9a8ae43..fbeb72d8 100644
--- a/src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java
+++ b/src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.internal;
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
@@ -56,17 +56,17 @@ import org.w3c.dom.Element;
import de.lmu.ifi.dbs.elki.KDDTask;
import de.lmu.ifi.dbs.elki.application.AbstractApplication;
import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration;
import de.lmu.ifi.dbs.elki.logging.Logging.Level;
+import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
import de.lmu.ifi.dbs.elki.utilities.ELKIServiceLoader;
import de.lmu.ifi.dbs.elki.utilities.InspectionUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.SerializedParameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackedParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.UnParameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
@@ -74,12 +74,11 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
import de.lmu.ifi.dbs.elki.utilities.xml.HTMLUtil;
/**
- * Class to generate HTML parameter descriptions for all classes implementing
- * the {@link Parameterizable} interface. Used in documentation generation only.
+ * Class to generate HTML parameter descriptions for all classes that have ELKI
+ * {@link Parameter}s. Used in documentation generation only.
*
* @author Erich Schubert
- *
- * @apiviz.uses Parameterizable
+ *
* @apiviz.uses Parameter
*/
public class DocumentParameters {
@@ -116,23 +115,23 @@ public class DocumentParameters {
*/
public static void main(String[] args) {
LoggingConfiguration.setVerbose(Level.VERBOSE);
- if (args.length != 2 && args.length != 4) {
+ if(args.length != 2 && args.length != 4) {
LOG.warning("I need exactly two or four file names to operate!");
System.exit(1);
}
- if (!args[0].endsWith(".html")) {
+ if(!args[0].endsWith(".html")) {
LOG.warning("First file name doesn't end with .html!");
System.exit(1);
}
- if (!args[1].endsWith(".html")) {
+ if(!args[1].endsWith(".html")) {
LOG.warning("Second file name doesn't end with .html!");
System.exit(1);
}
- if (args.length > 2 && !args[2].endsWith(".wiki")) {
+ if(args.length > 2 && !args[2].endsWith(".wiki")) {
LOG.warning("Third file name doesn't end with .wiki!");
System.exit(1);
}
- if (args.length > 3 && !args[3].endsWith(".wiki")) {
+ if(args.length > 3 && !args[3].endsWith(".wiki")) {
LOG.warning("Fourth file name doesn't end with .wiki!");
System.exit(1);
}
@@ -145,7 +144,8 @@ public class DocumentParameters {
Map<OptionID, List<Pair<Parameter<?>, Class<?>>>> byopt = new HashMap<>();
try {
buildParameterIndex(byclass, byopt);
- } catch (Exception e) {
+ }
+ catch(Exception e) {
LOG.exception(e);
System.exit(1);
}
@@ -154,7 +154,8 @@ public class DocumentParameters {
FileOutputStream byclassfo;
try {
byclassfo = new FileOutputStream(byclsname);
- } catch (FileNotFoundException e) {
+ }
+ catch(FileNotFoundException e) {
LOG.exception("Can't create output stream!", e);
throw new RuntimeException(e);
}
@@ -165,16 +166,18 @@ public class DocumentParameters {
byclassstream.flush();
byclassstream.close();
byclassfo.close();
- } catch (IOException e) {
+ }
+ catch(IOException e) {
LOG.exception("IO Exception writing output.", e);
throw new RuntimeException(e);
}
}
- if (byclsnamew != null) {
+ if(byclsnamew != null) {
FileOutputStream byclassfo;
try {
byclassfo = new FileOutputStream(byclsnamew);
- } catch (FileNotFoundException e) {
+ }
+ catch(FileNotFoundException e) {
LOG.exception("Can't create output stream!", e);
throw new RuntimeException(e);
}
@@ -184,7 +187,8 @@ public class DocumentParameters {
byclassstream.flush();
byclassstream.close();
byclassfo.close();
- } catch (IOException e) {
+ }
+ catch(IOException e) {
LOG.exception("IO Exception writing output.", e);
throw new RuntimeException(e);
}
@@ -194,7 +198,8 @@ public class DocumentParameters {
FileOutputStream byoptfo;
try {
byoptfo = new FileOutputStream(byoptname);
- } catch (FileNotFoundException e) {
+ }
+ catch(FileNotFoundException e) {
LOG.exception("Can't create output stream!", e);
throw new RuntimeException(e);
}
@@ -205,17 +210,19 @@ public class DocumentParameters {
byoptstream.flush();
byoptstream.close();
byoptfo.close();
- } catch (IOException e) {
+ }
+ catch(IOException e) {
LOG.exception("IO Exception writing output.", e);
throw new RuntimeException(e);
}
}
- if (byoptnamew != null) {
+ if(byoptnamew != null) {
FileOutputStream byoptfo;
try {
byoptfo = new FileOutputStream(byoptnamew);
- } catch (FileNotFoundException e) {
+ }
+ catch(FileNotFoundException e) {
LOG.exception("Can't create output stream!", e);
throw new RuntimeException(e);
}
@@ -225,7 +232,8 @@ public class DocumentParameters {
byoptstream.flush();
byoptstream.close();
byoptfo.close();
- } catch (IOException e) {
+ }
+ catch(IOException e) {
LOG.exception("IO Exception writing output.", e);
throw new RuntimeException(e);
}
@@ -235,53 +243,58 @@ public class DocumentParameters {
}
private static void buildParameterIndex(Map<Class<?>, List<Parameter<?>>> byclass, Map<OptionID, List<Pair<Parameter<?>, Class<?>>>> byopt) {
- final ArrayList<Pair<Object, Parameter<?>>> options = new ArrayList<>();
+ final ArrayList<TrackedParameter> options = new ArrayList<>();
ExecutorService es = Executors.newSingleThreadExecutor();
- for (final Class<?> cls : InspectionUtil.findAllImplementations(Parameterizable.class, false)) {
+ for(final Class<?> cls : InspectionUtil.findAllImplementations(Object.class, false, true)) {
// Doesn't have a proper name?
- if (cls.getCanonicalName() == null) {
+ if(cls.getCanonicalName() == null) {
continue;
}
// Some of the "applications" do currently not have appropriate
// constructors / parameterizers and may start AWT threads - skip them.
- if (AbstractApplication.class.isAssignableFrom(cls)) {
+ if(AbstractApplication.class.isAssignableFrom(cls)) {
continue;
}
UnParameterization config = new UnParameterization();
- final TrackParameters track = new TrackParameters(config);
+ final TrackParameters track = new TrackParameters(config, cls);
// LoggingUtil.warning("Instantiating " + cls.getName());
FutureTask<?> instantiator = new FutureTask<>(new Runnable() {
@Override
public void run() {
// Try a V3 style parameterizer first.
Parameterizer par = ClassGenericsUtil.getParameterizer(cls);
- if (par != null) {
+ if(par != null) {
par.configure(track);
- } else {
+ }
+ else {
try {
ClassGenericsUtil.tryInstantiate(Object.class, cls, track);
- } catch (java.lang.NoSuchMethodException e) {
- LOG.warning("Could not instantiate class " + cls.getName() + " - no appropriate constructor or parameterizer found.");
- } catch (java.lang.reflect.InvocationTargetException e) {
- if (e.getCause() instanceof RuntimeException) {
+ }
+ catch(java.lang.NoSuchMethodException | java.lang.IllegalAccessException e) {
+ // LOG.warning("Could not instantiate class " + cls.getName() +
+ // " - no appropriate constructor or parameterizer found.");
+ }
+ catch(java.lang.reflect.InvocationTargetException e) {
+ if(e.getCause() instanceof RuntimeException) {
throw (RuntimeException) e.getCause();
}
- if (e.getCause() instanceof Error) {
+ if(e.getCause() instanceof Error) {
throw (Error) e.getCause();
}
throw new RuntimeException(e.getCause());
- } catch (RuntimeException e) {
+ }
+ catch(RuntimeException e) {
throw e;
- } catch (Exception e) {
- throw new RuntimeException(e);
- } catch (java.lang.Error e) {
+ }
+ catch(Exception | java.lang.Error e) {
throw new RuntimeException(e);
}
}
- for (Pair<Object, Parameter<?>> pair : track.getAllParameters()) {
- if (pair.first == null) {
- pair.first = cls;
+ for(TrackedParameter pair : track.getAllParameters()) {
+ if(pair.getOwner() == null) {
+ LOG.warning("No owner for parameter " + pair.getParameter() + " expected a " + cls.getName());
+ continue;
}
options.add(pair);
}
@@ -291,15 +304,18 @@ public class DocumentParameters {
try {
// Wait up to one second.
instantiator.get(1L, TimeUnit.SECONDS);
- } catch (TimeoutException e) {
+ }
+ catch(TimeoutException e) {
LOG.warning("Timeout on instantiating " + cls.getName());
es.shutdownNow();
throw new RuntimeException(e);
- } catch (java.util.concurrent.ExecutionException e) {
+ }
+ catch(java.util.concurrent.ExecutionException e) {
// Do full reporting only on release branch.
- if (cls.getName().startsWith("de.lmu.ifi.dbs.elki")) {
+ if(cls.getName().startsWith("de.lmu.ifi.dbs.elki")) {
LOG.warning("Error instantiating " + cls.getName(), e.getCause());
- } else {
+ }
+ else {
LOG.warning("Error instantiating " + cls.getName());
}
// es.shutdownNow();
@@ -308,11 +324,13 @@ public class DocumentParameters {
// }
// throw new RuntimeException(e.getCause());
continue;
- } catch (Exception e) {
+ }
+ catch(Exception e) {
// Do full reporting only on release branch.
- if (cls.getName().startsWith("de.lmu.ifi.dbs.elki")) {
+ if(cls.getName().startsWith("de.lmu.ifi.dbs.elki")) {
LOG.warning("Error instantiating " + cls.getName(), e.getCause());
- } else {
+ }
+ else {
LOG.warning("Error instantiating " + cls.getName());
}
// es.shutdownNow();
@@ -321,34 +339,35 @@ public class DocumentParameters {
}
}
LOG.debug("Documenting " + options.size() + " parameter instances.");
- for (Pair<Object, Parameter<?>> pp : options) {
- if (pp.first == null || pp.second == null) {
- LOG.debugFiner("Null: " + pp.first + " " + pp.second);
+ for(TrackedParameter pp : options) {
+ if(pp.getOwner() == null || pp.getParameter() == null) {
+ LOG.debugFiner("Null: " + pp.getOwner() + " " + pp.getParameter());
continue;
}
Class<?> c;
- if (pp.first instanceof Class) {
- c = (Class<?>) pp.first;
- } else {
- c = pp.first.getClass();
+ if(pp.getOwner() instanceof Class) {
+ c = (Class<?>) pp.getOwner();
}
- Parameter<?> o = pp.second;
+ else {
+ c = pp.getOwner().getClass();
+ }
+ Parameter<?> o = pp.getParameter();
// just collect unique occurrences
{
List<Parameter<?>> byc = byclass.get(c);
boolean inlist = false;
- if (byc != null) {
- for (Parameter<?> par : byc) {
- if (par.getOptionID() == o.getOptionID()) {
+ if(byc != null) {
+ for(Parameter<?> par : byc) {
+ if(par.getOptionID() == o.getOptionID()) {
inlist = true;
break;
}
}
}
- if (!inlist) {
+ if(!inlist) {
List<Parameter<?>> ex = byclass.get(c);
- if (ex == null) {
+ if(ex == null) {
ex = new ArrayList<>();
byclass.put(c, ex);
}
@@ -358,17 +377,17 @@ public class DocumentParameters {
{
List<Pair<Parameter<?>, Class<?>>> byo = byopt.get(o.getOptionID());
boolean inlist = false;
- if (byo != null) {
- for (Pair<Parameter<?>, Class<?>> pair : byo) {
- if (pair.second.equals(c)) {
+ if(byo != null) {
+ for(Pair<Parameter<?>, Class<?>> pair : byo) {
+ if(pair.second.equals(c)) {
inlist = true;
break;
}
}
}
- if (!inlist) {
+ if(!inlist) {
List<Pair<Parameter<?>, Class<?>>> ex = byopt.get(o.getOptionID());
- if (ex == null) {
+ if(ex == null) {
ex = new ArrayList<>();
byopt.put(o.getOptionID(), ex);
}
@@ -382,14 +401,18 @@ public class DocumentParameters {
protected static Constructor<?> getConstructor(final Class<?> cls) {
try {
return cls.getConstructor(Parameterization.class);
- } catch (java.lang.NoClassDefFoundError e) {
+ }
+ catch(java.lang.NoClassDefFoundError e) {
// Class not actually found
- } catch (RuntimeException e) {
+ }
+ catch(RuntimeException e) {
// Not parameterizable, usually not even found ...
LOG.warning("RuntimeException: ", e);
- } catch (Exception e) {
+ }
+ catch(Exception e) {
// Not parameterizable.
- } catch (java.lang.Error e) {
+ }
+ catch(java.lang.Error e) {
// Not parameterizable.
LOG.warning("Error: ", e);
}
@@ -401,7 +424,8 @@ public class DocumentParameters {
DocumentBuilder builder;
try {
builder = factory.newDocumentBuilder();
- } catch (ParserConfigurationException e1) {
+ }
+ catch(ParserConfigurationException e1) {
throw new RuntimeException(e1);
}
DOMImplementation impl = builder.getDOMImplementation();
@@ -454,7 +478,7 @@ public class DocumentParameters {
List<Class<?>> classes = new ArrayList<>(byclass.keySet());
Collections.sort(classes, new InspectionUtil.ClassSorter());
- for (Class<?> cls : classes) {
+ for(Class<?> cls : classes) {
// DT = definition term
Element classdt = htmldoc.createElement(HTMLUtil.HTML_DT_TAG);
// Anchor for references
@@ -477,7 +501,7 @@ public class DocumentParameters {
// nested definition list for options
Element classdl = htmldoc.createElement(HTMLUtil.HTML_DL_TAG);
classdd.appendChild(classdl);
- for (Parameter<?> opt : byclass.get(cls)) {
+ for(Parameter<?> opt : byclass.get(cls)) {
// DT definition term: option name, in TT for typewriter optics
Element elemdt = htmldoc.createElement(HTMLUtil.HTML_DT_TAG);
{
@@ -489,18 +513,18 @@ public class DocumentParameters {
// DD definition description - put the option description here.
Element elemdd = htmldoc.createElement(HTMLUtil.HTML_DD_TAG);
Element elemp = htmldoc.createElement(HTMLUtil.HTML_P_TAG);
- if (opt.getShortDescription() != null) {
+ if(opt.getShortDescription() != null) {
HTMLUtil.appendMultilineText(htmldoc, elemp, opt.getShortDescription());
}
elemdd.appendChild(elemp);
// class restriction?
- if (opt instanceof ClassParameter<?>) {
+ if(opt instanceof ClassParameter<?>) {
appendClassRestriction(htmldoc, ((ClassParameter<?>) opt).getRestrictionClass(), elemdd);
}
// default value? completions?
appendDefaultValueIfSet(htmldoc, opt, elemdd);
// known values?
- if (opt instanceof ClassParameter<?>) {
+ if(opt instanceof ClassParameter<?>) {
appendKnownImplementationsIfNonempty(htmldoc, (ClassParameter<?>) opt, elemdd);
}
classdl.appendChild(elemdd);
@@ -513,7 +537,7 @@ public class DocumentParameters {
* Write to a Wiki format.
*
* @author Erich Schubert
- *
+ *
* @apiviz.exclude
*/
private static class WikiStream {
@@ -535,20 +559,20 @@ public class DocumentParameters {
}
private void insertNewline() {
- if (newline == 2) {
+ if(newline == 2) {
out.print("[[br]]");
}
- if (newline != 0) {
+ if(newline != 0) {
printIndent();
newline = 0;
}
}
private void printIndent() {
- if (newline > 0) {
+ if(newline > 0) {
out.println();
}
- for (int i = indent; i > 0; i--) {
+ for(int i = indent; i > 0; i--) {
out.print(' ');
}
}
@@ -573,7 +597,7 @@ public class DocumentParameters {
insertNewline();
out.print("[[javadoc(");
out.print(cls.getCanonicalName());
- if (base != null) {
+ if(base != null) {
out.print(",");
out.print(ClassParameter.canonicalClassName(cls, base));
}
@@ -585,14 +609,14 @@ public class DocumentParameters {
List<Class<?>> classes = new ArrayList<>(byclass.keySet());
Collections.sort(classes, new InspectionUtil.ClassSorter());
- for (Class<?> cls : classes) {
+ for(Class<?> cls : classes) {
out.indent = 0;
out.printitem("'''");
out.javadocLink(cls, KDDTask.class);
out.println("''':");
out.indent = 1;
out.newline = 1; // No BR needed, we increase the indent.
- for (Parameter<?> opt : byclass.get(cls)) {
+ for(Parameter<?> opt : byclass.get(cls)) {
out.printitem("* ");
out.print("{{{"); // typewriter
out.print(SerializedParameterization.OPTION_PREFIX);
@@ -600,21 +624,21 @@ public class DocumentParameters {
out.print(" ");
out.print(opt.getSyntax());
out.println("}}}");
- if (opt.getShortDescription() != null) {
+ if(opt.getShortDescription() != null) {
appendMultilineTextWiki(out, opt.getShortDescription());
}
// class restriction?
- if (opt instanceof ClassParameter<?>) {
+ if(opt instanceof ClassParameter<?>) {
appendClassRestrictionWiki(out, ((ClassParameter<?>) opt).getRestrictionClass());
}
// default value?
- if (opt.hasDefaultValue()) {
+ if(opt.hasDefaultValue()) {
appendDefaultValueWiki(out, opt);
}
// known values?
- if (FULL_WIKI_OUTPUT) {
- if (opt instanceof ClassParameter<?>) {
- if (((ClassParameter<?>) opt).getKnownImplementations().size() > 0) {
+ if(FULL_WIKI_OUTPUT) {
+ if(opt instanceof ClassParameter<?>) {
+ if(((ClassParameter<?>) opt).getKnownImplementations().size() > 0) {
appendKnownImplementationsWiki(out, (ClassParameter<?>) opt);
}
}
@@ -625,7 +649,7 @@ public class DocumentParameters {
private static int appendMultilineTextWiki(WikiStream out, String text) {
final String[] lines = text.split("\n");
- for (int i = 0; i < lines.length; i++) {
+ for(int i = 0; i < lines.length; i++) {
out.println(lines[i]);
}
return lines.length;
@@ -636,7 +660,8 @@ public class DocumentParameters {
DocumentBuilder builder;
try {
builder = factory.newDocumentBuilder();
- } catch (ParserConfigurationException e1) {
+ }
+ catch(ParserConfigurationException e1) {
throw new RuntimeException(e1);
}
DOMImplementation impl = builder.getDOMImplementation();
@@ -689,7 +714,7 @@ public class DocumentParameters {
List<OptionID> opts = new ArrayList<>(byopt.keySet());
Collections.sort(opts, new SortByOption());
- for (OptionID oid : opts) {
+ for(OptionID oid : opts) {
final Parameter<?> firstopt = byopt.get(oid).get(0).getFirst();
// DT = definition term
Element optdt = htmldoc.createElement(HTMLUtil.HTML_DT_TAG);
@@ -715,12 +740,12 @@ public class DocumentParameters {
}
// class restriction?
Class<?> superclass = null;
- if (firstopt instanceof ClassParameter<?>) {
+ if(firstopt instanceof ClassParameter<?>) {
// Find superclass heuristically
superclass = ((ClassParameter<?>) firstopt).getRestrictionClass();
- for (Pair<Parameter<?>, Class<?>> clinst : byopt.get(oid)) {
+ for(Pair<Parameter<?>, Class<?>> clinst : byopt.get(oid)) {
ClassParameter<?> cls = (ClassParameter<?>) clinst.getFirst();
- if (!cls.getRestrictionClass().equals(superclass) && cls.getRestrictionClass().isAssignableFrom(superclass)) {
+ if(!cls.getRestrictionClass().equals(superclass) && cls.getRestrictionClass().isAssignableFrom(superclass)) {
superclass = cls.getRestrictionClass();
}
}
@@ -729,7 +754,7 @@ public class DocumentParameters {
// default value?
appendDefaultValueIfSet(htmldoc, firstopt, optdd);
// known values?
- if (firstopt instanceof ClassParameter<?>) {
+ if(firstopt instanceof ClassParameter<?>) {
appendKnownImplementationsIfNonempty(htmldoc, (ClassParameter<?>) firstopt, optdd);
}
maindl.appendChild(optdd);
@@ -741,7 +766,7 @@ public class DocumentParameters {
optdd.appendChild(p);
}
optdd.appendChild(classesul);
- for (Pair<Parameter<?>, Class<?>> clinst : byopt.get(oid)) {
+ for(Pair<Parameter<?>, Class<?>> clinst : byopt.get(oid)) {
// DT definition term: option name, in TT for typewriter optics
Element classli = htmldoc.createElement(HTMLUtil.HTML_LI_TAG);
@@ -752,24 +777,26 @@ public class DocumentParameters {
classa.setTextContent(clinst.getSecond().getName());
classli.appendChild(classa);
}
- if (clinst.getFirst() instanceof ClassParameter<?> && firstopt instanceof ClassParameter<?>) {
+ if(clinst.getFirst() instanceof ClassParameter<?> && firstopt instanceof ClassParameter<?>) {
ClassParameter<?> cls = (ClassParameter<?>) clinst.getFirst();
- if (cls.getRestrictionClass() != null) {
+ if(cls.getRestrictionClass() != null) {
// TODO: if it is null, it could still be different!
- if (!cls.getRestrictionClass().equals(superclass)) {
+ if(!cls.getRestrictionClass().equals(superclass)) {
appendClassRestriction(htmldoc, cls.getRestrictionClass(), classli);
}
- } else {
+ }
+ else {
appendNoClassRestriction(htmldoc, classli);
}
}
Parameter<?> param = clinst.getFirst();
- if (param.getDefaultValue() != null) {
- if (!param.getDefaultValue().equals(firstopt.getDefaultValue())) {
+ if(param.getDefaultValue() != null) {
+ if(!param.getDefaultValue().equals(firstopt.getDefaultValue())) {
appendDefaultValueIfSet(htmldoc, param, classli);
}
- } else {
- if (firstopt.getDefaultValue() != null) {
+ }
+ else {
+ if(firstopt.getDefaultValue() != null) {
appendNoDefaultValue(htmldoc, classli);
}
}
@@ -784,7 +811,7 @@ public class DocumentParameters {
List<OptionID> opts = new ArrayList<>(byopt.keySet());
Collections.sort(opts, new SortByOption());
- for (OptionID oid : opts) {
+ for(OptionID oid : opts) {
final Parameter<?> firstopt = byopt.get(oid).get(0).getFirst();
out.indent = 1;
out.printitem("");
@@ -800,53 +827,55 @@ public class DocumentParameters {
appendMultilineTextWiki(out, firstopt.getShortDescription());
// class restriction?
Class<?> superclass = null;
- if (firstopt instanceof ClassParameter<?>) {
+ if(firstopt instanceof ClassParameter<?>) {
// Find superclass heuristically
superclass = ((ClassParameter<?>) firstopt).getRestrictionClass();
- for (Pair<Parameter<?>, Class<?>> clinst : byopt.get(oid)) {
+ for(Pair<Parameter<?>, Class<?>> clinst : byopt.get(oid)) {
ClassParameter<?> cls = (ClassParameter<?>) clinst.getFirst();
- if (!cls.getRestrictionClass().equals(superclass) && cls.getRestrictionClass().isAssignableFrom(superclass)) {
+ if(!cls.getRestrictionClass().equals(superclass) && cls.getRestrictionClass().isAssignableFrom(superclass)) {
superclass = cls.getRestrictionClass();
}
}
appendClassRestrictionWiki(out, superclass);
}
// default value?
- if (firstopt.hasDefaultValue()) {
+ if(firstopt.hasDefaultValue()) {
appendDefaultValueWiki(out, firstopt);
}
- if (FULL_WIKI_OUTPUT) {
+ if(FULL_WIKI_OUTPUT) {
// known values?
- if (firstopt instanceof ClassParameter<?>) {
- if (((ClassParameter<?>) firstopt).getKnownImplementations().size() > 0) {
+ if(firstopt instanceof ClassParameter<?>) {
+ if(((ClassParameter<?>) firstopt).getKnownImplementations().size() > 0) {
appendKnownImplementationsWiki(out, (ClassParameter<?>) firstopt);
}
}
// List of classes that use this parameter
out.println("Used by:");
- for (Pair<Parameter<?>, Class<?>> clinst : byopt.get(oid)) {
+ for(Pair<Parameter<?>, Class<?>> clinst : byopt.get(oid)) {
out.indent = 3;
out.printitem("* ");
out.javadocLink(clinst.getSecond(), null);
out.println();
- if (clinst.getFirst() instanceof ClassParameter<?> && firstopt instanceof ClassParameter<?>) {
+ if(clinst.getFirst() instanceof ClassParameter<?> && firstopt instanceof ClassParameter<?>) {
ClassParameter<?> cls = (ClassParameter<?>) clinst.getFirst();
- if (cls.getRestrictionClass() != null) {
+ if(cls.getRestrictionClass() != null) {
// TODO: if it is null, it could still be different!
- if (!cls.getRestrictionClass().equals(superclass)) {
+ if(!cls.getRestrictionClass().equals(superclass)) {
appendClassRestrictionWiki(out, cls.getRestrictionClass());
}
- } else {
+ }
+ else {
appendNoClassRestrictionWiki(out);
}
}
Parameter<?> param = clinst.getFirst();
- if (param.getDefaultValue() != null) {
- if (!param.getDefaultValue().equals(firstopt.getDefaultValue())) {
+ if(param.getDefaultValue() != null) {
+ if(!param.getDefaultValue().equals(firstopt.getDefaultValue())) {
appendDefaultValueWiki(out, param);
}
- } else {
- if (firstopt.getDefaultValue() != null) {
+ }
+ else {
+ if(firstopt.getDefaultValue() != null) {
appendNoDefaultValueWiki(out);
}
}
@@ -864,15 +893,16 @@ public class DocumentParameters {
}
private static void appendClassRestriction(Document htmldoc, Class<?> restriction, Element elemdd) {
- if (restriction == null) {
+ if(restriction == null) {
LOG.warning("No restriction class!");
return;
}
Element p = htmldoc.createElement(HTMLUtil.HTML_P_TAG);
p.appendChild(htmldoc.createTextNode(HEADER_CLASS_RESTRICTION));
- if (restriction.isInterface()) {
+ if(restriction.isInterface()) {
p.appendChild(htmldoc.createTextNode(HEADER_CLASS_RESTRICTION_IMPLEMENTING));
- } else {
+ }
+ else {
p.appendChild(htmldoc.createTextNode(HEADER_CLASS_RESTRICTION_EXTENDING));
}
Element defa = htmldoc.createElement(HTMLUtil.HTML_A_TAG);
@@ -890,14 +920,15 @@ public class DocumentParameters {
}
private static void appendClassRestrictionWiki(WikiStream out, Class<?> restriction) {
- if (restriction == null) {
+ if(restriction == null) {
LOG.warning("No restriction class!");
return;
}
out.print(HEADER_CLASS_RESTRICTION);
- if (restriction.isInterface()) {
+ if(restriction.isInterface()) {
out.print(HEADER_CLASS_RESTRICTION_IMPLEMENTING);
- } else {
+ }
+ else {
out.print(HEADER_CLASS_RESTRICTION_EXTENDING);
}
out.javadocLink(restriction, null);
@@ -911,14 +942,14 @@ public class DocumentParameters {
}
private static void appendKnownImplementationsIfNonempty(Document htmldoc, ClassParameter<?> opt, Element elemdd) {
- if (opt.getRestrictionClass() != Object.class) {
+ if(opt.getRestrictionClass() != Object.class) {
List<Class<?>> iter = opt.getKnownImplementations();
- if (!iter.isEmpty()) {
+ if(!iter.isEmpty()) {
Element p = htmldoc.createElement(HTMLUtil.HTML_P_TAG);
p.appendChild(htmldoc.createTextNode(HEADER_KNOWN_IMPLEMENTATIONS));
elemdd.appendChild(p);
Element ul = htmldoc.createElement(HTMLUtil.HTML_UL_TAG);
- for (Class<?> c : iter) {
+ for(Class<?> c : iter) {
Element li = htmldoc.createElement(HTMLUtil.HTML_LI_TAG);
Element defa = htmldoc.createElement(HTMLUtil.HTML_A_TAG);
defa.setAttribute(HTMLUtil.HTML_HREF_ATTRIBUTE, linkForClassName(c.getName()));
@@ -930,7 +961,7 @@ public class DocumentParameters {
}
// Report when not in properties file.
Iterator<Class<?>> clss = new ELKIServiceLoader(opt.getRestrictionClass());
- if (!clss.hasNext()) {
+ if(!clss.hasNext() && !opt.getRestrictionClass().getName().startsWith("experimentalcode.")) {
LOG.warning(opt.getRestrictionClass().getName() + " not in properties. No autocompletion available in release GUI.");
}
}
@@ -940,7 +971,7 @@ public class DocumentParameters {
out.println(HEADER_KNOWN_IMPLEMENTATIONS);
List<Class<?>> implementations = opt.getKnownImplementations();
out.indent++;
- for (Class<?> c : implementations) {
+ for(Class<?> c : implementations) {
out.printitem("* ");
out.javadocLink(c, opt.getRestrictionClass());
out.println();
@@ -956,12 +987,13 @@ public class DocumentParameters {
* @param optdd HTML Element
*/
private static void appendDefaultValueIfSet(Document htmldoc, Parameter<?> par, Element optdd) {
- if (par.hasDefaultValue()) {
+ if(par.hasDefaultValue()) {
Element p = htmldoc.createElement(HTMLUtil.HTML_P_TAG);
p.appendChild(htmldoc.createTextNode(HEADER_DEFAULT_VALUE));
- if (par instanceof ClassParameter<?>) {
+ if(par instanceof ClassParameter<?>) {
appendDefaultClassLink(htmldoc, par, p);
- } else {
+ }
+ else {
Object def = par.getDefaultValue();
p.appendChild(htmldoc.createTextNode(def.toString()));
}
@@ -984,10 +1016,11 @@ public class DocumentParameters {
private static void appendDefaultValueWiki(WikiStream out, Parameter<?> par) {
out.print(HEADER_DEFAULT_VALUE);
- if (par instanceof ClassParameter<?>) {
+ if(par instanceof ClassParameter<?>) {
final Class<?> name = ((ClassParameter<?>) par).getDefaultValue();
out.javadocLink(name, null);
- } else {
+ }
+ else {
Object def = par.getDefaultValue();
out.print(def.toString());
}
diff --git a/src/de/lmu/ifi/dbs/elki/application/internal/DocumentReferences.java b/src/de/lmu/ifi/dbs/elki/application/internal/DocumentReferences.java
index 7878a759..34816b6f 100644
--- a/src/de/lmu/ifi/dbs/elki/application/internal/DocumentReferences.java
+++ b/src/de/lmu/ifi/dbs/elki/application/internal/DocumentReferences.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.internal;
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,9 +29,11 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -76,12 +78,12 @@ public class DocumentReferences {
LoggingUtil.warning("I need exactly one or two file names to operate!");
System.exit(1);
}
- if(!args[0].endsWith(".html") || (args.length > 1 && !args[1].endsWith(".wiki"))) {
+ if(!args[0].endsWith(".html") || (args.length > 1 && !args[1].endsWith(".trac"))) {
LoggingUtil.warning("File name doesn't end in expected extension!");
System.exit(1);
}
- List<Pair<Reference, List<Class<?>>>> refs = sortedReferences();
+ List<Pair<Reference, List<Object>>> refs = sortedReferences();
try {
File references = new File(args[0]);
FileOutputStream reffo = new FileOutputStream(references);
@@ -113,7 +115,7 @@ public class DocumentReferences {
}
}
- private static Document documentReferences(List<Pair<Reference, List<Class<?>>>> refs) {
+ private static Document documentReferences(List<Pair<Reference, List<Object>>> refs) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
try {
@@ -168,25 +170,40 @@ public class DocumentReferences {
// Main definition list
Element maindl = htmldoc.createElement(HTMLUtil.HTML_DL_TAG);
body.appendChild(maindl);
- for(Pair<Reference, List<Class<?>>> pair : refs) {
+ for(Pair<Reference, List<Object>> pair : refs) {
// DT = definition term
Element classdt = htmldoc.createElement(HTMLUtil.HTML_DT_TAG);
// Anchor for references
{
boolean first = true;
- for(Class<?> cls : pair.second) {
+ for(Object o : pair.second) {
if(!first) {
classdt.appendChild(htmldoc.createTextNode(", "));
}
- Element classan = htmldoc.createElement(HTMLUtil.HTML_A_TAG);
- classan.setAttribute(HTMLUtil.HTML_NAME_ATTRIBUTE, cls.getName());
- classdt.appendChild(classan);
+ if(o instanceof Class<?>) {
+ Class<?> cls = (Class<?>) o;
+ Element classan = htmldoc.createElement(HTMLUtil.HTML_A_TAG);
+ classan.setAttribute(HTMLUtil.HTML_NAME_ATTRIBUTE, cls.getName());
+ classdt.appendChild(classan);
- // Link back to original class
- Element classa = htmldoc.createElement(HTMLUtil.HTML_A_TAG);
- classa.setAttribute(HTMLUtil.HTML_HREF_ATTRIBUTE, linkForClassName(cls.getName()));
- classa.setTextContent(cls.getName());
- classdt.appendChild(classa);
+ // Link back to original class
+ Element classa = htmldoc.createElement(HTMLUtil.HTML_A_TAG);
+ classa.setAttribute(HTMLUtil.HTML_HREF_ATTRIBUTE, linkForClassName(cls.getName()));
+ classa.setTextContent(cls.getName());
+ classdt.appendChild(classa);
+ }
+ else if(o instanceof Package) {
+ Package pkg = (Package) o;
+ Element classan = htmldoc.createElement(HTMLUtil.HTML_A_TAG);
+ classan.setAttribute(HTMLUtil.HTML_NAME_ATTRIBUTE, pkg.getName());
+ classdt.appendChild(classan);
+
+ // Link back to original class
+ Element classa = htmldoc.createElement(HTMLUtil.HTML_A_TAG);
+ classa.setAttribute(HTMLUtil.HTML_HREF_ATTRIBUTE, linkForPackageName(pkg.getName()));
+ classa.setTextContent(pkg.getName());
+ classdt.appendChild(classa);
+ }
first = false;
}
@@ -215,9 +232,11 @@ public class DocumentReferences {
titlediv.appendChild(titleb);
classdd.appendChild(titlediv);
// Booktitle
- Element booktitlediv = htmldoc.createElement(HTMLUtil.HTML_DIV_TAG);
- booktitlediv.setTextContent("In: " + ref.booktitle());
- classdd.appendChild(booktitlediv);
+ if(ref.booktitle().length() > 0) {
+ Element booktitlediv = htmldoc.createElement(HTMLUtil.HTML_DIV_TAG);
+ booktitlediv.setTextContent("In: " + ref.booktitle());
+ classdd.appendChild(booktitlediv);
+ }
// URL
if(ref.url().length() > 0) {
Element urldiv = htmldoc.createElement(HTMLUtil.HTML_DIV_TAG);
@@ -232,20 +251,31 @@ public class DocumentReferences {
return htmldoc;
}
- private static void documentReferencesWiki(List<Pair<Reference, List<Class<?>>>> refs, PrintStream refstreamW) {
- for(Pair<Reference, List<Class<?>>> pair : refs) {
- // JavaDoc links for relevant classes.
+ private static void documentReferencesWiki(List<Pair<Reference, List<Object>>> refs, PrintStream refstreamW) {
+ for(Pair<Reference, List<Object>> pair : refs) {
+ // JavaDoc links for relevant classes and packages.
{
boolean first = true;
- for(Class<?> cls : pair.second) {
+ for(Object o : pair.second) {
if(!first) {
refstreamW.println(",[[br]]");
}
- refstreamW.print("[[javadoc(");
- refstreamW.print(cls.getName());
- refstreamW.print(",");
- refstreamW.print(cls.getName());
- refstreamW.print(")]]");
+ if(o instanceof Class<?>) {
+ Class<?> cls = (Class<?>) o;
+ refstreamW.print("[[javadoc(");
+ refstreamW.print(cls.getName());
+ refstreamW.print(",");
+ refstreamW.print(cls.getName());
+ refstreamW.print(")]]");
+ }
+ else if(o instanceof Package) {
+ Package pkg = (Package) o;
+ refstreamW.print("[[javadoc(");
+ refstreamW.print(pkg.getName());
+ refstreamW.print(",");
+ refstreamW.print(pkg.getName());
+ refstreamW.print(")]]");
+ }
first = false;
}
@@ -264,7 +294,9 @@ public class DocumentReferences {
// Title
refstreamW.println(indent + "'''" + ref.title() + "'''" + " [[br]]");
// Booktitle
- refstreamW.println(indent + "In: " + ref.booktitle() + " [[br]]");
+ if(ref.booktitle().length() > 0) {
+ refstreamW.println(indent + "In: " + ref.booktitle() + " [[br]]");
+ }
// URL
if(ref.url().length() > 0) {
refstreamW.println(indent + "Online: [" + ref.url() + "][[br]]");
@@ -275,27 +307,28 @@ public class DocumentReferences {
}
}
- private static List<Pair<Reference, List<Class<?>>>> sortedReferences() {
- List<Pair<Reference, List<Class<?>>>> refs = new ArrayList<>();
- Map<Reference, List<Class<?>>> map = new HashMap<>();
+ private static List<Pair<Reference, List<Object>>> sortedReferences() {
+ List<Pair<Reference, List<Object>>> refs = new ArrayList<>();
+ Map<Reference, List<Object>> map = new HashMap<>();
- for(final Class<?> cls : InspectionUtil.findAllImplementations(Object.class, true)) {
+ HashSet<Package> packages = new HashSet<>();
+ for(Class<?> cls : InspectionUtil.findAllImplementations(Object.class, true, false)) {
inspectClass(cls, refs, map);
+ if(packages.add(cls.getPackage())) {
+ inspectPackage(cls.getPackage(), refs, map);
+ }
}
return refs;
}
- private static void inspectClass(final Class<?> cls, List<Pair<Reference, List<Class<?>>>> refs, Map<Reference, List<Class<?>>> map) {
+ private static void inspectClass(final Class<?> cls, List<Pair<Reference, List<Object>>> refs, Map<Reference, List<Object>> map) {
+ if(cls.getSimpleName().equals("package-info")) {
+ return;
+ }
try {
if(cls.isAnnotationPresent(Reference.class)) {
Reference ref = cls.getAnnotation(Reference.class);
- List<Class<?>> list = map.get(ref);
- if(list == null) {
- list = new ArrayList<>(5);
- map.put(ref, list);
- refs.add(new Pair<>(ref, list));
- }
- list.add(cls);
+ addReference(cls, ref, refs, map);
}
// Inner classes
for(Class<?> c2 : cls.getDeclaredClasses()) {
@@ -304,13 +337,13 @@ public class DocumentReferences {
for(Method m : cls.getDeclaredMethods()) {
if(m.isAnnotationPresent(Reference.class)) {
Reference ref = m.getAnnotation(Reference.class);
- List<Class<?>> list = map.get(ref);
- if(list == null) {
- list = new ArrayList<>(5);
- map.put(ref, list);
- refs.add(new Pair<>(ref, list));
- }
- list.add(cls);
+ addReference(cls, ref, refs, map);
+ }
+ }
+ for(Field f : cls.getDeclaredFields()) {
+ if(f.isAnnotationPresent(Reference.class)) {
+ Reference ref = f.getAnnotation(Reference.class);
+ addReference(cls, ref, refs, map);
}
}
}
@@ -324,19 +357,39 @@ public class DocumentReferences {
}
}
+ private static void addReference(Object cls, Reference ref, List<Pair<Reference, List<Object>>> refs, Map<Reference, List<Object>> map) {
+ List<Object> list = map.get(ref);
+ if(list == null) {
+ list = new ArrayList<>(3);
+ map.put(ref, list);
+ refs.add(new Pair<>(ref, list));
+ }
+ list.add(cls);
+ }
+
+ private static void inspectPackage(Package p, List<Pair<Reference, List<Object>>> refs, Map<Reference, List<Object>> map) {
+ if(p.isAnnotationPresent(Reference.class)) {
+ Reference ref = p.getAnnotation(Reference.class);
+ addReference(p, ref, refs, map);
+ }
+ }
+
private static String linkForClassName(String name) {
- String link = name.replace(".", "/") + ".html";
- return link;
+ return name.replace(".", "/") + ".html";
+ }
+
+ private static String linkForPackageName(String name) {
+ return name.replace(".", "/") + "/package-summary.html";
}
/**
- * Fin all classes that have the reference annotation
+ * Find all classes that have the reference annotation
*
* @return All classes with the reference annotation.
*/
public static ArrayList<Class<?>> findAllClassesWithReferences() {
ArrayList<Class<?>> references = new ArrayList<>();
- for(final Class<?> cls : InspectionUtil.findAllImplementations(Object.class, true)) {
+ for(final Class<?> cls : InspectionUtil.findAllImplementations(Object.class, true, false)) {
if(cls.isAnnotationPresent(Reference.class)) {
references.add(cls);
}
diff --git a/src/de/lmu/ifi/dbs/elki/application/internal/package-info.java b/src/de/lmu/ifi/dbs/elki/application/internal/package-info.java
index ecd1724d..19c3a795 100644
--- a/src/de/lmu/ifi/dbs/elki/application/internal/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/application/internal/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/application/jsmap/JSONBuffer.java b/src/de/lmu/ifi/dbs/elki/application/jsmap/JSONBuffer.java
index e1ecc2cb..b831d633 100644
--- a/src/de/lmu/ifi/dbs/elki/application/jsmap/JSONBuffer.java
+++ b/src/de/lmu/ifi/dbs/elki/application/jsmap/JSONBuffer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.jsmap;
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/application/jsmap/JSONResultHandler.java b/src/de/lmu/ifi/dbs/elki/application/jsmap/JSONResultHandler.java
index 16331b02..3ce22e2a 100644
--- a/src/de/lmu/ifi/dbs/elki/application/jsmap/JSONResultHandler.java
+++ b/src/de/lmu/ifi/dbs/elki/application/jsmap/JSONResultHandler.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.jsmap;
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/application/jsmap/JSONWebServer.java b/src/de/lmu/ifi/dbs/elki/application/jsmap/JSONWebServer.java
index 6f8c8be7..4c861bef 100644
--- a/src/de/lmu/ifi/dbs/elki/application/jsmap/JSONWebServer.java
+++ b/src/de/lmu/ifi/dbs/elki/application/jsmap/JSONWebServer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.jsmap;
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
@@ -44,6 +44,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.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.datasource.bundle.SingleObjectBundle;
import de.lmu.ifi.dbs.elki.logging.Logging;
@@ -147,7 +148,7 @@ public class JSONWebServer implements HttpHandler {
// TODO: refactor to JSONFormatters!
// Format a NumberVector
if (data instanceof NumberVector) {
- NumberVector<?> v = (NumberVector<?>) data;
+ NumberVector v = (NumberVector) data;
re.appendKeyArray(bundle.meta(j));
for (int i = 0; i < v.getDimensionality(); i++) {
re.append(v.doubleValue(i));
@@ -312,7 +313,7 @@ public class JSONWebServer implements HttpHandler {
outlierMetaToJSON(re, meta);
re.appendKeyArray("scores");
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
DBIDIter iter = or.getOrdering().iter(scores.getDBIDs()).iter();
for (int i = 0; i < offset && iter.valid(); i++) {
iter.advance();
@@ -320,8 +321,8 @@ public class JSONWebServer implements HttpHandler {
for (int i = 0; i < pagesize && iter.valid(); i++, iter.advance()) {
re.startHash();
bundleToJSON(re, iter);
- final Double val = scores.get(iter);
- if (val != null) {
+ final double val = scores.doubleValue(iter);
+ if (!Double.isNaN(val)) {
re.appendKeyValue("score", val);
}
re.closeHash();
diff --git a/src/de/lmu/ifi/dbs/elki/application/jsmap/package-info.java b/src/de/lmu/ifi/dbs/elki/application/jsmap/package-info.java
index 458bbd93..c410b2a7 100644
--- a/src/de/lmu/ifi/dbs/elki/application/jsmap/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/application/jsmap/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/application/package-info.java b/src/de/lmu/ifi/dbs/elki/application/package-info.java
index b2e79f5d..0e050e5b 100644
--- a/src/de/lmu/ifi/dbs/elki/application/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/application/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/data/AbstractNumberVector.java b/src/de/lmu/ifi/dbs/elki/data/AbstractNumberVector.java
index aec6a579..e024cf94 100644
--- a/src/de/lmu/ifi/dbs/elki/data/AbstractNumberVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/AbstractNumberVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -29,10 +29,8 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;
* AbstractNumberVector is an abstract implementation of FeatureVector.
*
* @author Arthur Zimek
- *
- * @param <N> the type of number stored in this vector
*/
-public abstract class AbstractNumberVector<N extends Number> implements NumberVector<N> {
+public abstract class AbstractNumberVector implements NumberVector {
/**
* The String to separate attribute values in a String that represents the
* values.
@@ -77,12 +75,16 @@ public abstract class AbstractNumberVector<N extends Number> implements NumberVe
* @apiviz.has AbstractNumberVector
*
* @param <V> Vector type
- * @param <N> Number type
*/
- public abstract static class Factory<V extends AbstractNumberVector<N>, N extends Number> implements NumberVector.Factory<V, N> {
+ public abstract static class Factory<V extends AbstractNumberVector> implements NumberVector.Factory<V> {
@Override
public V newNumberVector(double[] values) {
return newNumberVector(values, ArrayLikeUtil.doubleArrayAdapter());
}
+
+ @Override
+ public V newNumberVector(NumberVector values) {
+ return newNumberVector(values, ArrayLikeUtil.numberVectorAdapter(values));
+ }
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/Arithmetic.java b/src/de/lmu/ifi/dbs/elki/data/Arithmetic.java
deleted file mode 100644
index c9236539..00000000
--- a/src/de/lmu/ifi/dbs/elki/data/Arithmetic.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package de.lmu.ifi.dbs.elki.data;
-
-/*
- 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/>.
- */
-
-/**
- * An interface to define requirements for a number to perform arithmetic
- * operations. The Numbers are supposed to remain unchanged by an arithmetic
- * operation.
- *
- * @author Arthur Zimek
- * @param <N> Number type
- */
-public interface Arithmetic<N extends Number> extends Comparable<N> {
- /**
- * Adds the given number to this number.
- *
- * @param number the number to add to this number.
- * @return the result of arithmetic addition of this Number with the given
- * number
- */
- N plus(N number);
-
- /**
- * Multiplies this number with the given number.
- *
- * @param number the number to multiply this number with
- * @return the result of arithmetic multiplication of this Number with the
- * given number
- */
- N times(N number);
-
- /**
- * Subtracts the given number from this number.
- *
- * @param number the number to subtract from this number
- * @return the result of arithmetic subtraction of the given number from this
- * Number
- */
- N minus(N number);
-
- /**
- * Divides this number by the given number.
- *
- * @param number the number to divide this number by
- * @return the result of arithmetic division of this Number by the given
- * number
- */
- N divided(N number);
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/Bit.java b/src/de/lmu/ifi/dbs/elki/data/Bit.java
index e39d9f42..a7d54b65 100644
--- a/src/de/lmu/ifi/dbs/elki/data/Bit.java
+++ b/src/de/lmu/ifi/dbs/elki/data/Bit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -26,7 +26,7 @@ package de.lmu.ifi.dbs.elki.data;
import java.util.regex.Pattern;
/**
- * Provides a bit number. The bit is internally represented as boolean.
+ * A boolean number type.
*
* @author Arthur Zimek
*/
@@ -83,7 +83,7 @@ public class Bit extends Number {
private boolean bit;
/**
- * Provides a new bit according to the specified boolean value.
+ * Create a new bit according to the specified boolean value.
*
* @param bit the boolean value of this bit
*
@@ -95,7 +95,7 @@ public class Bit extends Number {
}
/**
- * Provides a new bit according to the specified integer value. The bit value
+ * Create a new bit according to the specified integer value. The bit value
* is 1 for true and 0 for false.
*
* @param bit 1 for true and 0 for false
@@ -110,38 +110,21 @@ public class Bit extends Number {
this.bit = (bit == 1);
}
- /**
- * Provides an integer representation of the bit.
- *
- * @return 1 if the bit is set, 0 otherwise
- */
@Override
public int intValue() {
return bit ? 1 : 0;
}
- /**
- * Provides a long value for the integer representation of this Bit as given
- * by {@link #intValue() intValue()}.
- */
@Override
public long longValue() {
return intValue();
}
- /**
- * Provides a float value for the integer representation of this Bit as given
- * by {@link #intValue() intValue()}.
- */
@Override
public float floatValue() {
return intValue();
}
- /**
- * Provides a double value for the integer representation of this Bit as given
- * by {@link #intValue() intValue()}.
- */
@Override
public double doubleValue() {
return intValue();
@@ -156,12 +139,6 @@ public class Bit extends Number {
return this.bit;
}
- /**
- * Provides the String representation of the integer representation of this
- * Bit as given by {@link #intValue() intValue()}.
- *
- * @see java.lang.Object#toString()
- */
@Override
public String toString() {
return Integer.toString(intValue());
diff --git a/src/de/lmu/ifi/dbs/elki/data/BitVector.java b/src/de/lmu/ifi/dbs/elki/data/BitVector.java
index de0edc2d..0ec4a081 100644
--- a/src/de/lmu/ifi/dbs/elki/data/BitVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/BitVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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,25 +23,28 @@ package de.lmu.ifi.dbs.elki.data;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import gnu.trove.iterator.TIntDoubleIterator;
+import gnu.trove.map.TIntDoubleMap;
+
import java.io.IOException;
import java.nio.ByteBuffer;
-import java.util.BitSet;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
- * Provides a BitVector wrapping a BitSet.
+ * Vector using a dense bit set encoding, based on {@code long[]} storage.
*
* @author Arthur Zimek
*
* @apiviz.composedOf Bit
*/
-public class BitVector extends AbstractNumberVector<Bit> {
+public class BitVector extends AbstractNumberVector implements SparseNumberVector {
/**
* Static instance.
*/
@@ -55,71 +58,109 @@ public class BitVector extends AbstractNumberVector<Bit> {
/**
* Storing the bits.
*/
- private final BitSet bits;
+ private final long[] bits;
/**
* Dimensionality of this bit vector.
*/
- private final int dimensionality;
+ private int dimensionality;
/**
- * Provides a new BitVector corresponding to the specified bits and of the
+ * Create a new BitVector corresponding to the specified bits and of the
* specified dimensionality.
*
- * @param bits the bits to be set in this BitVector
+ * @param bits the bits to be set in this BitVector.
* @param dimensionality the dimensionality of this BitVector
- * @throws IllegalArgumentException if the specified dimensionality is to
- * small to match the given BitSet
*/
- public BitVector(BitSet bits, int dimensionality) throws IllegalArgumentException {
- if (dimensionality < bits.length()) {
- throw new IllegalArgumentException("Specified dimensionality " + dimensionality + " is to low for specified BitSet of length " + bits.length());
- }
+ public BitVector(long[] bits, int dimensionality) {
this.bits = bits;
this.dimensionality = dimensionality;
}
- /**
- * Provides a new BitVector corresponding to the bits in the given array.
- *
- * @param bits an array of bits specifying the bits in this bit vector
- */
- public BitVector(Bit[] bits) {
- this.bits = new BitSet(bits.length);
- for (int i = 0; i < bits.length; i++) {
- this.bits.set(i, bits[i].bitValue());
- }
- this.dimensionality = bits.length;
- }
-
@Override
public int getDimensionality() {
return dimensionality;
}
@Override
+ public void setDimensionality(int dimensionality) {
+ this.dimensionality = dimensionality;
+ }
+
+ /**
+ * Get the value of a single bit.
+ *
+ * @param dimension Bit number to get
+ * @return {@code true} when set
+ */
+ public boolean booleanValue(int dimension) {
+ return BitsUtil.get(bits, dimension);
+ }
+
+ @Override
@Deprecated
public Bit getValue(int dimension) {
- if (dimension < 1 || dimension > dimensionality) {
- throw new IllegalArgumentException("illegal dimension: " + dimension);
- }
- return new Bit(bits.get(dimension - 1));
+ return new Bit(booleanValue(dimension));
}
@Override
public double doubleValue(int dimension) {
- if (dimension < 0 || dimension >= dimensionality) {
- throw new IllegalArgumentException("illegal dimension: " + dimension);
- }
- return bits.get(dimension) ? 1.0 : 0.0;
+ return BitsUtil.get(bits, dimension) ? 1. : 0.;
}
@Override
public long longValue(int dimension) {
- if (dimension < 0 || dimension >= dimensionality) {
- throw new IllegalArgumentException("illegal dimension: " + dimension);
- }
- return bits.get(dimension) ? 1 : 0;
+ return BitsUtil.get(bits, dimension) ? 1L : 0L;
+ }
+
+ @Override
+ public int iter() {
+ return BitsUtil.nextSetBit(bits, 0);
+ }
+
+ @Override
+ public int iterAdvance(int iter) {
+ return BitsUtil.nextSetBit(bits, iter + 1);
+ }
+
+ @Override
+ public boolean iterValid(int iter) {
+ return iter >= 0;
+ }
+
+ @Override
+ public int iterDim(int iter) {
+ return iter; // Identity
+ }
+
+ @Override
+ public double iterDoubleValue(int iter) {
+ return 1.; // When properly used: always true!
+ }
+
+ @Override
+ public float iterFloatValue(int iter) {
+ return 1.f; // When properly used: always true!
+ }
+
+ @Override
+ public int iterIntValue(int iter) {
+ return 1; // When properly used: always true!
+ }
+
+ @Override
+ public short iterShortValue(int iter) {
+ return 1; // When properly used: always true!
+ }
+
+ @Override
+ public long iterLongValue(int iter) {
+ return 1L; // When properly used: always true!
+ }
+
+ @Override
+ public byte iterByteValue(int iter) {
+ return 1; // When properly used: always true!
}
/**
@@ -136,8 +177,8 @@ public class BitVector extends AbstractNumberVector<Bit> {
@Override
public Vector getColumnVector() {
double[] values = new double[dimensionality];
- for (int i = 0; i < dimensionality; i++) {
- values[i] = bits.get(i) ? 1 : 0;
+ for(int i = 0; i < dimensionality; i++) {
+ values[i] = BitsUtil.get(bits, i) ? 1 : 0;
}
return new Vector(values);
}
@@ -150,13 +191,17 @@ public class BitVector extends AbstractNumberVector<Bit> {
* @return true if this BitVector contains all bits that are set to true in
* the specified BitSet, false otherwise
*/
- public boolean contains(BitSet bitset) {
- boolean contains = true;
- for (int i = bitset.nextSetBit(0); i >= 0 && contains; i = bitset.nextSetBit(i + 1)) {
- // noinspection ConstantConditions
- contains &= bits.get(i);
+ public boolean contains(long[] bitset) {
+ for(int i = 0; i < bitset.length; i++) {
+ final long b = bitset[i];
+ if(i >= bits.length && b != 0L) {
+ return false;
+ }
+ if((b & bits[i]) != b) {
+ return false;
+ }
}
- return contains;
+ return true;
}
/**
@@ -164,8 +209,94 @@ public class BitVector extends AbstractNumberVector<Bit> {
*
* @return a copy of the bits currently set in this BitVector
*/
- public BitSet getBits() {
- return (BitSet) bits.clone();
+ public long[] cloneBits() {
+ return bits.clone();
+ }
+
+ /**
+ * Compute the vector cardinality (uncached!)
+ *
+ * @return Vector cardinality
+ */
+ public int cardinality() {
+ return BitsUtil.cardinality(bits);
+ }
+
+ /**
+ * Compute the Jaccard similarity of two bit vectors.
+ *
+ * @param v2 Second bit vector
+ * @return Jaccard similarity (intersection / union)
+ */
+ public double jaccardSimilarity(BitVector v2) {
+ return BitsUtil.intersectionSize(bits, v2.bits) / (double) BitsUtil.unionSize(bits, v2.bits);
+ }
+
+ /**
+ * Compute the Hamming distance of two bit vectors.
+ *
+ * @param v2 Second bit vector
+ * @return Hamming distance (number of bits difference)
+ */
+ public int hammingDistance(BitVector v2) {
+ return BitsUtil.hammingDistance(bits, v2.bits);
+ }
+
+ /**
+ * Compute the vector intersection size.
+ *
+ * @param v2 Second bit vector
+ * @return Intersection size (number of bits in both)
+ */
+ public int intersectionSize(BitVector v2) {
+ return BitsUtil.intersectionSize(bits, v2.bits);
+ }
+
+ /**
+ * Compute the vector union size.
+ *
+ * @param v2 Second bit vector
+ * @return Intersection size (number of bits in both)
+ */
+ public int unionSize(BitVector v2) {
+ return BitsUtil.unionSize(bits, v2.bits);
+ }
+
+ /**
+ * Compute whether two vectors intersect.
+ *
+ * @param v2 Second bit vector
+ * @return {@code true} if they intersect in at least one bit.
+ */
+ public boolean intersect(BitVector v2) {
+ return BitsUtil.intersect(bits, v2.bits);
+ }
+
+ /**
+ * Combine onto v using the AND operation, i.e. {@code v &= this}.
+ *
+ * @param v Existing bit set of same length.
+ */
+ public void andOnto(long[] v) {
+ BitsUtil.andI(v, bits);
+ }
+
+ /**
+ * Combine onto v using the OR operation, i.e. {@code v |= this}.
+ *
+ * @param v Existing bit set of same length.
+ */
+ public void orOnto(long[] v) {
+ BitsUtil.orI(v, bits);
+ }
+
+ /**
+ * Combine onto v using the XOR operation, i.e. {@code v ^= this}.
+ *
+ * @param v Existing bit set of same length.
+ */
+ public void xorOnto(long[] v) {
+ BitsUtil.xorI(v, bits);
}
/**
@@ -178,16 +309,12 @@ public class BitVector extends AbstractNumberVector<Bit> {
*/
@Override
public String toString() {
- Bit[] bitArray = new Bit[dimensionality];
- for (int i = 0; i < dimensionality; i++) {
- bitArray[i] = bits.get(i) ? Bit.TRUE : Bit.FALSE;
- }
StringBuilder representation = new StringBuilder();
- for (Bit bit : bitArray) {
- if (representation.length() > 0) {
+ for(int i = 0; i < dimensionality; i++) {
+ if(i > 0) {
representation.append(ATTRIBUTE_SEPARATOR);
}
- representation.append(bit.toString());
+ representation.append(BitsUtil.get(bits, i) ? '1' : '0');
}
return representation.toString();
}
@@ -201,11 +328,12 @@ public class BitVector extends AbstractNumberVector<Bit> {
*/
@Override
public boolean equals(Object obj) {
- if (obj instanceof BitVector) {
+ if(obj instanceof BitVector) {
BitVector bv = (BitVector) obj;
return this.getDimensionality() == bv.getDimensionality() && this.bits.equals(bv.bits);
- } else {
+ }
+ else {
return false;
}
}
@@ -217,14 +345,15 @@ public class BitVector extends AbstractNumberVector<Bit> {
*
* @apiviz.has BitVector
*/
- public static class Factory extends AbstractNumberVector.Factory<BitVector, Bit> {
+ public static class Factory extends AbstractNumberVector.Factory<BitVector> implements SparseNumberVector.Factory<BitVector> {
@Override
- public <A> BitVector newFeatureVector(A array, ArrayAdapter<Bit, A> adapter) {
+ public <A> BitVector newFeatureVector(A array, ArrayAdapter<? extends Number, A> adapter) {
int dim = adapter.size(array);
- BitSet bits = new BitSet(dim);
- for (int i = 0; i < dim; i++) {
- bits.set(i, adapter.get(array, i).bitValue());
- i++;
+ long[] bits = BitsUtil.zero(dim);
+ for(int i = 0; i < dim; i++) {
+ if(adapter.get(array, i).doubleValue() >= 0.5) {
+ BitsUtil.setI(bits, i);
+ }
}
return new BitVector(bits, dim);
}
@@ -232,20 +361,33 @@ public class BitVector extends AbstractNumberVector<Bit> {
@Override
public <A> BitVector newNumberVector(A array, NumberArrayAdapter<?, ? super A> adapter) {
int dim = adapter.size(array);
- BitSet bits = new BitSet(dim);
- for (int i = 0; i < dim; i++) {
- if (adapter.getDouble(array, i) >= 0.5) {
- bits.set(i);
+ long[] bits = BitsUtil.zero(dim);
+ for(int i = 0; i < dim; i++) {
+ if(adapter.getDouble(array, i) >= 0.5) {
+ BitsUtil.setI(bits, i);
}
}
return new BitVector(bits, dim);
}
@Override
+ public BitVector newNumberVector(TIntDoubleMap values, int maxdim) {
+ long[] bits = BitsUtil.zero(maxdim);
+ // Import and sort the indexes
+ for(TIntDoubleIterator iter = values.iterator(); iter.hasNext();) {
+ iter.advance();
+ if(iter.value() != 0.) {
+ BitsUtil.setI(bits, iter.key());
+ }
+ }
+ return new BitVector(bits, maxdim);
+ }
+
+ @Override
public ByteBufferSerializer<BitVector> getDefaultSerializer() {
return SHORT_SERIALIZER;
}
-
+
@Override
public Class<? super BitVector> getRestrictionClass() {
return BitVector.class;
@@ -280,23 +422,23 @@ public class BitVector extends AbstractNumberVector<Bit> {
public BitVector fromByteBuffer(ByteBuffer buffer) throws IOException {
short dimensionality = buffer.getShort();
final int len = ByteArrayUtil.SIZE_SHORT + (dimensionality + 7) / 8;
- if (buffer.remaining() < len) {
+ if(buffer.remaining() < len) {
throw new IOException("Not enough data for a bit vector!");
}
// read values
- BitSet values = new BitSet(dimensionality);
+ long[] bits = BitsUtil.zero(dimensionality);
byte b = 0;
- for (int i = 0; i < dimensionality; i++) {
+ for(int i = 0; i < dimensionality; i++) {
// read the next byte when needed.
- if ((i & 7) == 0) {
+ if((i & 7) == 0) {
b = buffer.get();
}
final byte bit = (byte) (1 << (i & 7));
- if ((b & bit) != 0) {
- values.set(i + 1);
+ if((b & bit) != 0) {
+ BitsUtil.setI(bits, i);
}
}
- return new BitVector(values, dimensionality);
+ return new BitVector(bits, dimensionality);
}
@Override
@@ -304,7 +446,7 @@ public class BitVector extends AbstractNumberVector<Bit> {
final int len = getByteSize(vec);
assert (vec.getDimensionality() <= Short.MAX_VALUE);
final short dim = (short) vec.getDimensionality();
- if (buffer.remaining() < len) {
+ if(buffer.remaining() < len) {
throw new IOException("Not enough space for the bit vector!");
}
// write size
@@ -312,15 +454,16 @@ public class BitVector extends AbstractNumberVector<Bit> {
// write values
// Next byte to write:
byte b = 0;
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
final byte mask = (byte) (1 << (i & 7));
- if (vec.bits.get(i)) {
+ if(BitsUtil.get(vec.bits, i)) {
b |= mask;
- } else {
+ }
+ else {
b &= ~mask;
}
// Write when appropriate
- if ((i & 7) == 7 || i == dim - 1) {
+ if((i & 7) == 7 || i == dim - 1) {
buffer.put(b);
b = 0;
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/ByteVector.java b/src/de/lmu/ifi/dbs/elki/data/ByteVector.java
index 10442a3f..e97d0f0f 100644
--- a/src/de/lmu/ifi/dbs/elki/data/ByteVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/ByteVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -27,19 +27,18 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
- * A ByteVector stores the data using bytes. This is beneficial e.g. when using
- * SIFT vectors based on byte values.
+ * Vector using {@code byte[]} storage.
*
* @author Erich Schubert
*/
-public class ByteVector extends AbstractNumberVector<Byte> {
+public class ByteVector extends AbstractNumberVector {
/**
* Static instance (object factory).
*/
@@ -67,16 +66,17 @@ public class ByteVector extends AbstractNumberVector<Byte> {
* @param nocopy Flag to use without copying.
*/
private ByteVector(byte[] values, boolean nocopy) {
- if (nocopy) {
+ if(nocopy) {
this.values = values;
- } else {
+ }
+ else {
this.values = new byte[values.length];
System.arraycopy(values, 0, this.values, 0, values.length);
}
}
/**
- * Provides an ByteVector consisting of the given Byte values.
+ * Create an ByteVector consisting of the given Byte values.
*
* @param values the values to be set as values of the ByteVector
*/
@@ -125,7 +125,7 @@ public class ByteVector extends AbstractNumberVector<Byte> {
@Override
public Vector getColumnVector() {
double[] data = new double[values.length];
- for (int i = 0; i < values.length; i++) {
+ for(int i = 0; i < values.length; i++) {
data[i] = values[i];
}
return new Vector(data);
@@ -134,9 +134,9 @@ public class ByteVector extends AbstractNumberVector<Byte> {
@Override
public String toString() {
StringBuilder featureLine = new StringBuilder();
- for (int i = 0; i < values.length; i++) {
+ for(int i = 0; i < values.length; i++) {
featureLine.append(values[i]);
- if (i + 1 < values.length) {
+ if(i + 1 < values.length) {
featureLine.append(ATTRIBUTE_SEPARATOR);
}
}
@@ -150,13 +150,13 @@ public class ByteVector extends AbstractNumberVector<Byte> {
*
* @apiviz.has ByteVector
*/
- public static class Factory extends AbstractNumberVector.Factory<ByteVector, Byte> {
+ public static class Factory extends AbstractNumberVector.Factory<ByteVector> {
@Override
- public <A> ByteVector newFeatureVector(A array, ArrayAdapter<Byte, A> adapter) {
+ public <A> ByteVector newFeatureVector(A array, ArrayAdapter<? extends Number, A> adapter) {
int dim = adapter.size(array);
byte[] values = new byte[dim];
- for (int i = 0; i < dim; i++) {
- values[i] = adapter.get(array, i);
+ for(int i = 0; i < dim; i++) {
+ values[i] = adapter.get(array, i).byteValue();
}
return new ByteVector(values, true);
}
@@ -165,7 +165,7 @@ public class ByteVector extends AbstractNumberVector<Byte> {
public <A> ByteVector newNumberVector(A array, NumberArrayAdapter<?, ? super A> adapter) {
int dim = adapter.size(array);
byte[] values = new byte[dim];
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
values[i] = adapter.getByte(array, i);
}
return new ByteVector(values, true);
@@ -210,7 +210,7 @@ public class ByteVector extends AbstractNumberVector<Byte> {
final byte dimensionality = buffer.get();
assert (buffer.remaining() >= ByteArrayUtil.SIZE_BYTE * dimensionality);
final byte[] values = new byte[dimensionality];
- for (int i = 0; i < dimensionality; i++) {
+ for(int i = 0; i < dimensionality; i++) {
values[i] = buffer.get();
}
return new ByteVector(values, true);
@@ -221,7 +221,7 @@ public class ByteVector extends AbstractNumberVector<Byte> {
assert (vec.values.length < Byte.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Byte.MAX_VALUE + "!";
assert (buffer.remaining() >= ByteArrayUtil.SIZE_BYTE * vec.values.length);
buffer.put((byte) vec.values.length);
- for (int i = 0; i < vec.values.length; i++) {
+ for(int i = 0; i < vec.values.length; i++) {
buffer.put(vec.values[i]);
}
}
@@ -248,7 +248,7 @@ public class ByteVector extends AbstractNumberVector<Byte> {
final short dimensionality = buffer.getShort();
assert (buffer.remaining() >= ByteArrayUtil.SIZE_BYTE * dimensionality);
final byte[] values = new byte[dimensionality];
- for (int i = 0; i < dimensionality; i++) {
+ for(int i = 0; i < dimensionality; i++) {
values[i] = buffer.get();
}
return new ByteVector(values, true);
@@ -259,7 +259,7 @@ public class ByteVector extends AbstractNumberVector<Byte> {
assert (vec.values.length < Short.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Short.MAX_VALUE + "!";
assert (buffer.remaining() >= ByteArrayUtil.SIZE_BYTE * vec.values.length);
buffer.putShort((short) vec.values.length);
- for (int i = 0; i < vec.values.length; i++) {
+ for(int i = 0; i < vec.values.length; i++) {
buffer.put(vec.values[i]);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/ClassLabel.java b/src/de/lmu/ifi/dbs/elki/data/ClassLabel.java
index 96df671d..7fc68dea 100644
--- a/src/de/lmu/ifi/dbs/elki/data/ClassLabel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/ClassLabel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
diff --git a/src/de/lmu/ifi/dbs/elki/data/Cluster.java b/src/de/lmu/ifi/dbs/elki/data/Cluster.java
index 00e1b693..9cacd047 100644
--- a/src/de/lmu/ifi/dbs/elki/data/Cluster.java
+++ b/src/de/lmu/ifi/dbs/elki/data/Cluster.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -174,12 +174,13 @@ public class Cluster<M extends Model> implements TextWriteable {
* @return a name for the cluster
*/
public String getNameAutomatic() {
- if (name != null) {
+ if(name != null) {
return name;
}
- if (isNoise()) {
+ if(isNoise()) {
return "Noise";
- } else {
+ }
+ else {
return "Cluster";
}
}
@@ -248,28 +249,14 @@ public class Cluster<M extends Model> implements TextWriteable {
@Override
public void writeToText(TextWriterStream out, String label) {
String name = getNameAutomatic();
- out.commentPrintLn(TextWriterStream.SER_MARKER + " " + Cluster.class.getName());
- if (name != null) {
- out.commentPrintLn("Name: " + name);
+ if(name != null) {
+ out.commentPrintLn("Cluster name: " + name);
}
- out.commentPrintLn("Noise flag: " + isNoise());
- out.commentPrintLn("Size: " + ids.size());
- // print hierarchy information.
- /*
- * if (isHierarchical()) { out.commentPrint("Parents: "); for (int i = 0; i
- * < numParents(); i++) { if (i > 0) { out.commentPrint(", "); }
- * out.commentPrint(getParents().get(i).getNameAutomatic()); }
- * out.commentPrintLn(); out.commentPrint("Children: "); for (int i = 0; i <
- * numChildren(); i++) { if (i > 0) { out.commentPrint(", "); }
- * out.commentPrint(getChildren().get(i).getNameAutomatic()); }
- * out.commentPrintLn(); }
- */
+ out.commentPrintLn("Cluster noise flag: " + isNoise());
+ out.commentPrintLn("Cluster size: " + ids.size());
// also print model, if any and printable
- if (getModel() != null) {
- out.commentPrintLn("Model class: " + getModel().getClass().getName());
- if (getModel() instanceof TextWriteable) {
- ((TextWriteable) getModel()).writeToText(out, label);
- }
+ if(getModel() != null && (getModel() instanceof TextWriteable)) {
+ ((TextWriteable) getModel()).writeToText(out, label);
}
}
@@ -299,18 +286,18 @@ public class Cluster<M extends Model> implements TextWriteable {
public static Comparator<Cluster<?>> BY_NAME_SORTER = new Comparator<Cluster<?>>() {
@Override
public int compare(Cluster<?> o1, Cluster<?> o2) {
- if (o1 == o2) {
+ if(o1 == o2) {
return 0;
}
// sort by label if possible
- if (o1 != null && o1.name != null && o2 != null && o2.name != null) {
+ if(o1 != null && o1.name != null && o2 != null && o2.name != null) {
int lblresult = o1.name.compareTo(o2.getName());
- if (lblresult != 0) {
+ if(lblresult != 0) {
return lblresult;
}
}
int hashresult = o1.hashCode() - o2.hashCode();
- if (hashresult != 0) {
+ if(hashresult != 0) {
return hashresult;
}
return 0;
diff --git a/src/de/lmu/ifi/dbs/elki/data/Clustering.java b/src/de/lmu/ifi/dbs/elki/data/Clustering.java
index ae70662e..808febba 100644
--- a/src/de/lmu/ifi/dbs/elki/data/Clustering.java
+++ b/src/de/lmu/ifi/dbs/elki/data/Clustering.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -75,6 +75,9 @@ public class Clustering<M extends Model> extends BasicResult {
super(name, shortname);
this.toplevelclusters = toplevelclusters;
this.hierarchy = new HashMapHierarchy<>();
+ for (Cluster<M> clus : toplevelclusters) {
+ hierarchy.add(clus);
+ }
}
/**
@@ -161,12 +164,13 @@ public class Clustering<M extends Model> extends BasicResult {
}
@Override
- public void advance() {
+ public Iter<Cluster<M>> advance() {
if (iter.hasNext()) {
cur = iter.next();
} else {
cur = null;
}
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/data/DoubleVector.java b/src/de/lmu/ifi/dbs/elki/data/DoubleVector.java
index 4f427d04..2dca83b6 100644
--- a/src/de/lmu/ifi/dbs/elki/data/DoubleVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/DoubleVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -29,21 +29,21 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
- * A DoubleVector is to store real values approximately as double values.
+ * Vector type using {@code double[]} storage for real numbers.
*
* @author Arthur Zimek
*
* @apiviz.landmark
*/
-public class DoubleVector extends AbstractNumberVector<Double> {
+public class DoubleVector extends AbstractNumberVector {
/**
* Static factory instance.
*/
@@ -80,7 +80,7 @@ public class DoubleVector extends AbstractNumberVector<Double> {
}
/**
- * Provides a DoubleVector consisting of the given double values.
+ * Create a DoubleVector consisting of the given double values.
*
* @param values the values to be set as values of the DoubleVector
*/
@@ -153,18 +153,18 @@ public class DoubleVector extends AbstractNumberVector<Double> {
*
* @apiviz.has DoubleVector
*/
- public static class Factory extends AbstractNumberVector.Factory<DoubleVector, Double> {
+ public static class Factory extends AbstractNumberVector.Factory<DoubleVector> {
@Override
public DoubleVector newNumberVector(double[] values) {
return new DoubleVector(values);
}
@Override
- public <A> DoubleVector newFeatureVector(A array, ArrayAdapter<Double, A> adapter) {
+ public <A> DoubleVector newFeatureVector(A array, ArrayAdapter<? extends Number, A> adapter) {
int dim = adapter.size(array);
double[] values = new double[dim];
for(int i = 0; i < dim; i++) {
- values[i] = adapter.get(array, i);
+ values[i] = adapter.get(array, i).doubleValue();
}
return new DoubleVector(values, true);
}
@@ -219,7 +219,8 @@ public class DoubleVector extends AbstractNumberVector<Double> {
@Override
public DoubleVector fromByteBuffer(ByteBuffer buffer) throws IOException {
final byte dimensionality = buffer.get();
- assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * dimensionality);
+ assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * dimensionality) : "Not enough data remaining in buffer to read " + dimensionality + " doubles";
+ ;
final double[] values = new double[dimensionality];
for(int i = 0; i < dimensionality; i++) {
values[i] = buffer.getDouble();
@@ -230,7 +231,7 @@ public class DoubleVector extends AbstractNumberVector<Double> {
@Override
public void toByteBuffer(ByteBuffer buffer, DoubleVector vec) throws IOException {
assert (vec.values.length < Byte.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Byte.MAX_VALUE + "!";
- assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * vec.values.length);
+ assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * vec.values.length) : "Not enough space remaining in buffer to write " + vec.values.length + " doubles";
buffer.put((byte) vec.values.length);
for(int i = 0; i < vec.values.length; i++) {
buffer.putDouble(vec.values[i]);
@@ -257,7 +258,8 @@ public class DoubleVector extends AbstractNumberVector<Double> {
@Override
public DoubleVector fromByteBuffer(ByteBuffer buffer) throws IOException {
final short dimensionality = buffer.getShort();
- assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * dimensionality);
+ assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * dimensionality) : "Not enough data remaining in buffer to read " + dimensionality + " doubles";
+ ;
final double[] values = new double[dimensionality];
for(int i = 0; i < dimensionality; i++) {
values[i] = buffer.getDouble();
@@ -268,7 +270,7 @@ public class DoubleVector extends AbstractNumberVector<Double> {
@Override
public void toByteBuffer(ByteBuffer buffer, DoubleVector vec) throws IOException {
assert (vec.values.length < Short.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Short.MAX_VALUE + "!";
- assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * vec.values.length);
+ assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * vec.values.length) : "Not enough space remaining in buffer to write " + vec.values.length + " doubles";
buffer.putShort((short) vec.values.length);
for(int i = 0; i < vec.values.length; i++) {
buffer.putDouble(vec.values[i]);
@@ -293,7 +295,7 @@ public class DoubleVector extends AbstractNumberVector<Double> {
@Override
public DoubleVector fromByteBuffer(ByteBuffer buffer) throws IOException {
final int dimensionality = ByteArrayUtil.readUnsignedVarint(buffer);
- assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * dimensionality);
+ assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * dimensionality) : "Not enough data remaining in buffer to read " + dimensionality + " doubles";
final double[] values = new double[dimensionality];
for(int i = 0; i < dimensionality; i++) {
values[i] = buffer.getDouble();
@@ -303,7 +305,7 @@ public class DoubleVector extends AbstractNumberVector<Double> {
@Override
public void toByteBuffer(ByteBuffer buffer, DoubleVector vec) throws IOException {
- assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * vec.values.length);
+ assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * vec.values.length) : "Not enough space remaining in buffer to write " + vec.values.length + " doubles";
ByteArrayUtil.writeUnsignedVarint(buffer, vec.values.length);
for(int i = 0; i < vec.values.length; i++) {
buffer.putDouble(vec.values[i]);
diff --git a/src/de/lmu/ifi/dbs/elki/data/ExternalID.java b/src/de/lmu/ifi/dbs/elki/data/ExternalID.java
index 702b0431..cbe93cf5 100644
--- a/src/de/lmu/ifi/dbs/elki/data/ExternalID.java
+++ b/src/de/lmu/ifi/dbs/elki/data/ExternalID.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
diff --git a/src/de/lmu/ifi/dbs/elki/data/FeatureVector.java b/src/de/lmu/ifi/dbs/elki/data/FeatureVector.java
index f6f2f751..3a9f6dc1 100644
--- a/src/de/lmu/ifi/dbs/elki/data/FeatureVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/FeatureVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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,9 +23,8 @@ package de.lmu.ifi.dbs.elki.data;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
/**
* Generic FeatureVector class that can contain any type of data (i.e. numerical
@@ -33,8 +32,6 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
* actually store numerical features.
*
* @author Erich Schubert
- *
- * @param <D> Data type
*/
public interface FeatureVector<D> {
/**
@@ -69,9 +66,8 @@ public interface FeatureVector<D> {
* @author Erich Schubert
*
* @param <V> Vector type
- * @param <D> Data type of vector
*/
- interface Factory<V extends FeatureVector<? extends D>, D> extends Parameterizable {
+ interface Factory<V extends FeatureVector<? extends D>, D> {
/**
* Returns a new FeatureVector of V for the given values.
*
@@ -80,7 +76,7 @@ public interface FeatureVector<D> {
* @param <A> Array type
* @return a new FeatureVector of V for the given values
*/
- <A> V newFeatureVector(A array, ArrayAdapter<D, A> adapter);
+ <A> V newFeatureVector(A array, ArrayAdapter<? extends D, A> adapter);
/**
* Get the default serializer for this type.
diff --git a/src/de/lmu/ifi/dbs/elki/data/FloatVector.java b/src/de/lmu/ifi/dbs/elki/data/FloatVector.java
index 6db8cd24..3b9316b0 100644
--- a/src/de/lmu/ifi/dbs/elki/data/FloatVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/FloatVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -27,20 +27,20 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
- * A FloatVector is to store real values with lower memory requirements by using
- * float values.
+ * Vector type using {@code float[]} storage, thus needing approximately half as
+ * much memory as {@link DoubleVector}.
*
* @author Elke Achtert
*/
-public class FloatVector extends AbstractNumberVector<Float> {
+public class FloatVector extends AbstractNumberVector {
/**
* Static factory instance.
*/
@@ -77,7 +77,7 @@ public class FloatVector extends AbstractNumberVector<Float> {
}
/**
- * Provides a FloatVector consisting of the given float values.
+ * Create a FloatVector consisting of the given float values.
*
* @param values the values to be set as values of the float vector
*/
@@ -143,13 +143,13 @@ public class FloatVector extends AbstractNumberVector<Float> {
*
* @apiviz.has FloatVector
*/
- public static class Factory extends AbstractNumberVector.Factory<FloatVector, Float> {
+ public static class Factory extends AbstractNumberVector.Factory<FloatVector> {
@Override
- public <A> FloatVector newFeatureVector(A array, ArrayAdapter<Float, A> adapter) {
+ public <A> FloatVector newFeatureVector(A array, ArrayAdapter<? extends Number, A> adapter) {
int dim = adapter.size(array);
float[] values = new float[dim];
for(int i = 0; i < dim; i++) {
- values[i] = adapter.get(array, i);
+ values[i] = adapter.get(array, i).floatValue();
}
return new FloatVector(values, true);
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/HierarchicalClassLabel.java b/src/de/lmu/ifi/dbs/elki/data/HierarchicalClassLabel.java
index 7e84b2bf..20f1b4d2 100644
--- a/src/de/lmu/ifi/dbs/elki/data/HierarchicalClassLabel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/HierarchicalClassLabel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -168,7 +168,7 @@ public class HierarchicalClassLabel extends ClassLabel {
}
/**
- * Provides a String representation of this ClassLabel comprising only the
+ * Create a String representation of this ClassLabel comprising only the
* first <code>level</code> levels.
*
* @param level the lowest level to include in the String representation.
diff --git a/src/de/lmu/ifi/dbs/elki/data/HyperBoundingBox.java b/src/de/lmu/ifi/dbs/elki/data/HyperBoundingBox.java
index a1533b0c..36fca2d2 100644
--- a/src/de/lmu/ifi/dbs/elki/data/HyperBoundingBox.java
+++ b/src/de/lmu/ifi/dbs/elki/data/HyperBoundingBox.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -136,7 +136,7 @@ public class HyperBoundingBox implements SpatialComparable, Externalizable {
*/
@Override
public String toString() {
- return "[Min(" + FormatUtil.format(min, ",", FormatUtil.NF) + "), Max(" + FormatUtil.format(max, ",", FormatUtil.NF) + ")]";
+ return "[Min(" + FormatUtil.format(min, ",") + "), Max(" + FormatUtil.format(max, ",") + ")]";
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/data/IntegerVector.java b/src/de/lmu/ifi/dbs/elki/data/IntegerVector.java
index aed931ef..cadda5c1 100644
--- a/src/de/lmu/ifi/dbs/elki/data/IntegerVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/IntegerVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -27,18 +27,18 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
- * An IntegerVector is to store integer values.
+ * Vector type using {@code int[]} storage.
*
* @author Erich Schubert
*/
-public class IntegerVector extends AbstractNumberVector<Integer> {
+public class IntegerVector extends AbstractNumberVector {
/**
* Static instance (object factory).
*/
@@ -80,13 +80,12 @@ public class IntegerVector extends AbstractNumberVector<Integer> {
}
/**
- * Provides an IntegerVector consisting of the given integer values.
+ * Create an IntegerVector consisting of the given integer values.
*
* @param values the values to be set as values of the IntegerVector
*/
public IntegerVector(int[] values) {
- this.values = new int[values.length];
- System.arraycopy(values, 0, this.values, 0, values.length);
+ this.values = values.clone();
}
@Override
@@ -165,13 +164,13 @@ public class IntegerVector extends AbstractNumberVector<Integer> {
*
* @apiviz.has IntegerVector
*/
- public static class Factory extends AbstractNumberVector.Factory<IntegerVector, Integer> {
+ public static class Factory extends AbstractNumberVector.Factory<IntegerVector> {
@Override
- public <A> IntegerVector newFeatureVector(A array, ArrayAdapter<Integer, A> adapter) {
+ public <A> IntegerVector newFeatureVector(A array, ArrayAdapter<? extends Number, A> adapter) {
int dim = adapter.size(array);
int[] values = new int[dim];
for (int i = 0; i < dim; i++) {
- values[i] = adapter.get(array, i);
+ values[i] = adapter.get(array, i).intValue();
}
return new IntegerVector(values, true);
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/LabelList.java b/src/de/lmu/ifi/dbs/elki/data/LabelList.java
index dc84439a..c3ac1f53 100644
--- a/src/de/lmu/ifi/dbs/elki/data/LabelList.java
+++ b/src/de/lmu/ifi/dbs/elki/data/LabelList.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -27,9 +27,9 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Collection;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
/**
* A list of string labels.
diff --git a/src/de/lmu/ifi/dbs/elki/data/ModifiableHyperBoundingBox.java b/src/de/lmu/ifi/dbs/elki/data/ModifiableHyperBoundingBox.java
index 3f1a3c8e..4c0c1789 100644
--- a/src/de/lmu/ifi/dbs/elki/data/ModifiableHyperBoundingBox.java
+++ b/src/de/lmu/ifi/dbs/elki/data/ModifiableHyperBoundingBox.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
diff --git a/src/de/lmu/ifi/dbs/elki/data/NumberVector.java b/src/de/lmu/ifi/dbs/elki/data/NumberVector.java
index 4fbd36dd..aaef3148 100644
--- a/src/de/lmu/ifi/dbs/elki/data/NumberVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/NumberVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -33,15 +33,14 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter
*
* @author Arthur Zimek
*
- * @param <N> the type of the attribute values
- *
* @apiviz.landmark
* @apiviz.has Vector
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.(datasource.filter|data.projection).*
*/
-public interface NumberVector<N extends Number> extends FeatureVector<N>, SpatialComparable {
+public interface NumberVector extends FeatureVector<Number>, SpatialComparable {
@Deprecated
@Override
- N getValue(int dimension);
+ Number getValue(int dimension);
/**
* Returns the value in the specified dimension as double.
@@ -139,9 +138,8 @@ public interface NumberVector<N extends Number> extends FeatureVector<N>, Spatia
* @apiviz.has NumberVector
*
* @param <V> Vector type
- * @param <N> Data type of vector
*/
- interface Factory<V extends NumberVector<? extends N>, N extends Number> extends FeatureVector.Factory<V, N> {
+ interface Factory<V extends NumberVector> extends FeatureVector.Factory<V, Number> {
/**
* Returns a new NumberVector of N for the given values.
*
@@ -151,6 +149,14 @@ public interface NumberVector<N extends Number> extends FeatureVector<N>, Spatia
V newNumberVector(double[] values);
/**
+ * Returns a new NumberVector of N for the given values.
+ *
+ * @param values Existing number vector
+ * @return a new NumberVector of N for the given values
+ */
+ V newNumberVector(NumberVector values);
+
+ /**
* Instantiate from any number-array like object.
*
* @param <A> Array type
diff --git a/src/de/lmu/ifi/dbs/elki/data/OneDimensionalDoubleVector.java b/src/de/lmu/ifi/dbs/elki/data/OneDimensionalDoubleVector.java
index 3412c835..d440b5e1 100644
--- a/src/de/lmu/ifi/dbs/elki/data/OneDimensionalDoubleVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/OneDimensionalDoubleVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -24,9 +24,9 @@ package de.lmu.ifi.dbs.elki.data;
*/
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
@@ -36,7 +36,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Erich Schubert
*/
-public class OneDimensionalDoubleVector extends AbstractNumberVector<Double> {
+public class OneDimensionalDoubleVector extends AbstractNumberVector {
/**
* Static factory instance.
*/
@@ -92,11 +92,11 @@ public class OneDimensionalDoubleVector extends AbstractNumberVector<Double> {
*
* @apiviz.has OneDimensionalDoubleVector
*/
- public static class Factory extends AbstractNumberVector.Factory<OneDimensionalDoubleVector, Double> {
+ public static class Factory extends AbstractNumberVector.Factory<OneDimensionalDoubleVector> {
@Override
- public <A> OneDimensionalDoubleVector newFeatureVector(A array, ArrayAdapter<Double, A> adapter) {
+ public <A> OneDimensionalDoubleVector newFeatureVector(A array, ArrayAdapter<? extends Number, A> adapter) {
assert (adapter.size(array) == 1) : "Incorrect dimensionality for 1-dimensional vector.";
- return new OneDimensionalDoubleVector(adapter.get(array, 0));
+ return new OneDimensionalDoubleVector(adapter.get(array, 0).doubleValue());
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/data/RationalNumber.java b/src/de/lmu/ifi/dbs/elki/data/RationalNumber.java
deleted file mode 100644
index 1b7c46f6..00000000
--- a/src/de/lmu/ifi/dbs/elki/data/RationalNumber.java
+++ /dev/null
@@ -1,401 +0,0 @@
-package de.lmu.ifi.dbs.elki.data;
-
-/*
- 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.math.BigInteger;
-
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-
-/**
- * RationalNumber represents rational numbers in arbitrary precision. Note that
- * the best possible precision is the primary objective of this class. Since
- * numerator and denominator of the RationalNumber are represented as
- * BigIntegers, the required space can grow unlimited. Also arithmetic
- * operations are considerably less efficient compared to the operations with
- * doubles.
- *
- * @author Arthur Zimek
- */
-public class RationalNumber extends Number implements Arithmetic<RationalNumber> {
- /**
- * Generated serial version UID.
- */
- private static final long serialVersionUID = 7347098153261459646L;
-
- /**
- * The canonical representation of zero as RationalNumber.
- */
- public static final RationalNumber ZERO = new RationalNumber(BigInteger.ZERO, BigInteger.ONE);
-
- /**
- * The canonical representation of 1 as RationalNumber.
- */
- public static final RationalNumber ONE = new RationalNumber(BigInteger.ONE, BigInteger.ONE);
-
- /**
- * Holding the numerator of the RationalNumber.
- */
- private BigInteger numerator;
-
- /**
- * Holding the denominator of the RationalNumber.
- */
- private BigInteger denominator;
-
- /**
- * Constructs a RationalNumber for a given numerator and denominator. The
- * denominator must not be 0.
- *
- * @param numerator the numerator of the RationalNumber
- * @param denominator the denominator of the RationalNumber
- * @throws IllegalArgumentException if {@link BigInteger#equals(Object)
- * denominator.equals(}{@link BigInteger#ZERO BigInteger.ZERO)}
- */
- public RationalNumber(final BigInteger numerator, final BigInteger denominator) {
- if(denominator.equals(BigInteger.ZERO)) {
- throw new IllegalArgumentException("denominator is 0");
- }
- this.numerator = new BigInteger(numerator.toByteArray());
- this.denominator = new BigInteger(denominator.toByteArray());
- normalize();
- }
-
- /**
- * Constructs a RationalNumber for a given numerator and denominator. The
- * denominator must not be 0.
- *
- * @param numerator the numerator of the RationalNumber
- * @param denominator the denominator of the RationalNumber
- * @throws IllegalArgumentException if {@link BigInteger#equals(Object)
- * denominator.equals(}{@link BigInteger#ZERO BigInteger.ZERO)}
- */
- public RationalNumber(final long numerator, final long denominator) throws IllegalArgumentException {
- if(denominator == 0) {
- throw new IllegalArgumentException("denominator is 0");
- }
- this.numerator = BigInteger.valueOf(numerator);
- this.denominator = BigInteger.valueOf(denominator);
- normalize();
- }
-
- /**
- * Constructs a RationalNumber out of the given double number.
- *
- * @param number a double number to be represented as a RationalNumber
- * @throws IllegalArgumentException if the given Double is infinit or not a
- * number
- */
- public RationalNumber(final Double number) throws IllegalArgumentException {
- this(number.toString());
- }
-
- /**
- * Constructs a RationalNumber out of the given double number.
- *
- * @param number a double number to be represented as a RationalNumber
- * @throws IllegalArgumentException if the given Double is infinit or not a
- * number
- */
- public RationalNumber(final double number) throws IllegalArgumentException {
- this(Double.toString(number));
- }
-
- /**
- * Constructs a RationalNumber for a given String representing a double.
- *
- * @param doubleString a String representing a double number
- * @throws IllegalArgumentException if the given String represents a double
- * number that is infinit or not a number
- */
- public RationalNumber(final String doubleString) throws IllegalArgumentException {
- try {
- double number = FormatUtil.parseDouble(doubleString);
- if(Double.isInfinite(number)) {
- throw new IllegalArgumentException("given number is infinite");
- }
- if(Double.isNaN(number)) {
- throw new IllegalArgumentException("given number is NotANumber");
- }
- // ensure standard encoding of the double argument
- String standardDoubleString = Double.toString(number);
- // index of decimal point '.'
- int pointIndex = standardDoubleString.indexOf('\u002E');
- // read integer part
- String integerPart = pointIndex == -1 ? standardDoubleString : standardDoubleString.substring(0, pointIndex);
- // index of power 'E'
- int powerIndex = standardDoubleString.indexOf('\u0045');
- // read fractional part
- String fractionalPart = powerIndex == -1 ? standardDoubleString.substring(pointIndex + 1) : standardDoubleString.substring(pointIndex + 1, powerIndex);
- // read power
- int power = powerIndex == -1 ? 0 : Integer.parseInt(standardDoubleString.substring(powerIndex + 1));
- // concatenate integer part and fractional part to numerator
- numerator = new BigInteger(integerPart + fractionalPart);
-
- // reduce power accordingly to the shift of the fraction point
- power -= fractionalPart.length();
- denominator = BigInteger.ONE;
- // translate power notation
- StringBuilder multiplicandString = new StringBuilder("1");
- for(int i = 0; i < Math.abs(power); i++) {
- multiplicandString.append('0');
- }
- BigInteger multiplicand = new BigInteger(multiplicandString.toString());
- if(power < 0) {
- denominator = denominator.multiply(multiplicand);
- }
- else if(power > 0) {
- numerator = numerator.multiply(multiplicand);
- }
- normalize();
- }
- catch(NumberFormatException e) {
- throw new IllegalArgumentException("Illegal format of given number: " + doubleString);
- }
- }
-
- /**
- * Normalizes the RationalNumber by normalizing the signum and canceling both,
- * numerator and denominator, by the greatest common divisor.
- * <p/>
- * If the numerator is zero, the denominator is always one.
- */
- protected void normalize() {
- if(numerator.equals(BigInteger.ZERO)) {
- denominator = BigInteger.ONE;
- }
- else {
- // normalize signum
- normalizeSignum();
- // greatest common divisor
- BigInteger gcd = numerator.gcd(denominator);
- // cancel
- numerator = numerator.divide(gcd);
- denominator = denominator.divide(gcd);
- }
- }
-
- /**
- * Normalizes the signum such that if the RationalNumber is negative, the
- * numerator will be negative, the denominator positive. If the RationalNumber
- * is positive, both, the numerator and the denominator will be positive.
- */
- protected void normalizeSignum() {
- int numeratorSignum = numerator.signum();
- int denominatorSignum = denominator.signum();
- if(numeratorSignum == denominatorSignum) {
- if(numeratorSignum < 0) {
- numerator = numerator.abs();
- denominator = denominator.abs();
- }
- }
- else {
- if(denominatorSignum < 0) {
- numerator = numerator.negate();
- denominator = denominator.negate();
- }
- }
- }
-
- /**
- * Returns the integer value of {@code this.doubleValue()}.
- *
- * @see #doubleValue()
- */
- @Override
- public int intValue() {
- return (int) doubleValue();
- }
-
- /**
- * Returns the long value of {@code this.doubleValue()}.
- *
- * @see #doubleValue()
- */
- @Override
- public long longValue() {
- return (long) doubleValue();
- }
-
- /**
- * Returns the float value of {@code this.doubleValue()}.
- *
- * @see #doubleValue()
- */
- @Override
- public float floatValue() {
- return (float) doubleValue();
- }
-
- /**
- * Returns the byte value of {@code this.doubleValue()}.
- *
- * @see #doubleValue()
- */
- @Override
- public byte byteValue() {
- return ((Double) doubleValue()).byteValue();
- }
-
- /**
- * Returns the short value of {@code this.doubleValue()}.
- *
- * @see #doubleValue()
- */
- @Override
- public short shortValue() {
- return ((Double) doubleValue()).shortValue();
- }
-
- /**
- * Returns the double value representation of this RationalNumber.
- * <p/>
- * The result is given by double division as
- * <code>numerator.doubleValue() / denominator.doubleValue()</code>. Note that
- * the result may not be exact. Thus after
- * <code>RationalNumber a = new RationalNumber(b.doubleValue())</code>,
- * <code>a.equals(b)</code> is not necessarily true.
- */
- @Override
- public double doubleValue() {
- return numerator.doubleValue() / denominator.doubleValue();
- }
-
- @Override
- public RationalNumber plus(final RationalNumber number) {
- BigInteger newNumerator = numerator.multiply(number.denominator).add(number.numerator.multiply(denominator));
- BigInteger newDenominator = denominator.multiply(number.denominator);
- return new RationalNumber(newNumerator, newDenominator);
- }
-
- @Override
- public RationalNumber times(final RationalNumber number) {
- BigInteger newNumerator = numerator.multiply(number.numerator);
- BigInteger newDenominator = denominator.multiply(number.denominator);
- return new RationalNumber(newNumerator, newDenominator);
- }
-
- @Override
- public RationalNumber minus(final RationalNumber number) {
- return plus(number.additiveInverse());
- }
-
- /**
- * @throws ArithmeticException if the given divisor is 0
- */
- @Override
- public RationalNumber divided(final RationalNumber number) throws ArithmeticException {
- return times(number.multiplicativeInverse());
- }
-
- /**
- * Returns the multiplicative inverse of this RationalNumber if it exists.
- *
- * @return the multiplicative inverse of this rational number
- * @throws ArithmeticException if numerator is 0 and hence the multiplicative
- * inverse of this rational number does not exist
- */
- public RationalNumber multiplicativeInverse() throws ArithmeticException {
- try {
- return new RationalNumber(denominator, numerator);
- }
- catch(IllegalArgumentException e) {
- throw new ArithmeticException("construction of inverse not possible for " + this);
- }
- }
-
- /**
- * Returns the additive inverse of this RationalNumber.
- *
- * @return the additive inverse of this RationalNumber
- */
- public RationalNumber additiveInverse() {
- return new RationalNumber(numerator.negate(), denominator);
- }
-
- /**
- * Returns the absolute value of this rational number.
- *
- * @return the absolute value of this rational number
- */
- public RationalNumber absValue() {
- if(this.compareTo(RationalNumber.ZERO) >= 0) {
- return this;
- }
- else {
- return this.additiveInverse();
- }
- }
-
- /**
- * Compares two RationalNumbers a/b and c/d. Result is the same as
- * <code>(a*d).compareTo(c*b)</code>.
- */
- @Override
- public int compareTo(final RationalNumber o) {
- BigInteger left = numerator.multiply(o.denominator);
- BigInteger right = o.numerator.multiply(denominator);
-
- return left.compareTo(right);
- }
-
- /**
- * Two RationalNumbers are considered to be equal if both denominators and
- * numerators are equal, respectively.
- */
- @Override
- public boolean equals(Object obj) {
- RationalNumber r = (RationalNumber) obj;
-
- return denominator.equals(r.denominator) && numerator.equals(r.numerator);
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((denominator == null) ? 0 : denominator.hashCode());
- result = prime * result + ((numerator == null) ? 0 : numerator.hashCode());
- return result;
- }
-
- /**
- * Returns a String representation of this RationalNumber.
- * <p/>
- * The representation consists of the numerator, a separating &quot; / &quot;,
- * and the denominator of the RationalNumber.
- */
- @Override
- public String toString() {
- return numerator.toString() + " / " + denominator.toString();
- }
-
- /**
- * Provides a deep copy of this RationalNumber.
- *
- * @return a deep copy of this RationalNumber
- */
- public RationalNumber copy() {
- return new RationalNumber(numerator, denominator);
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/ShortVector.java b/src/de/lmu/ifi/dbs/elki/data/ShortVector.java
index fe82abe7..da3d4348 100644
--- a/src/de/lmu/ifi/dbs/elki/data/ShortVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/ShortVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -27,18 +27,18 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
- * An ShortVector is to store Short values.
+ * Vector type using {@code short[]} storage.
*
* @author Erich Schubert
*/
-public class ShortVector extends AbstractNumberVector<Short> {
+public class ShortVector extends AbstractNumberVector {
/**
* Static instance (object factory).
*/
@@ -66,22 +66,22 @@ public class ShortVector extends AbstractNumberVector<Short> {
* @param nocopy Flag to use without copying.
*/
private ShortVector(short[] values, boolean nocopy) {
- if (nocopy) {
+ if(nocopy) {
this.values = values;
- } else {
+ }
+ else {
this.values = new short[values.length];
System.arraycopy(values, 0, this.values, 0, values.length);
}
}
/**
- * Provides an ShortVector consisting of the given Short values.
+ * Create an ShortVector consisting of the given Short values.
*
* @param values the values to be set as values of the ShortVector
*/
public ShortVector(short[] values) {
- this.values = new short[values.length];
- System.arraycopy(values, 0, this.values, 0, values.length);
+ this.values = values.clone();
}
@Override
@@ -140,7 +140,7 @@ public class ShortVector extends AbstractNumberVector<Short> {
@Override
public Vector getColumnVector() {
double[] data = new double[values.length];
- for (int i = 0; i < values.length; i++) {
+ for(int i = 0; i < values.length; i++) {
data[i] = values[i];
}
return new Vector(data);
@@ -149,9 +149,9 @@ public class ShortVector extends AbstractNumberVector<Short> {
@Override
public String toString() {
StringBuilder featureLine = new StringBuilder();
- for (int i = 0; i < values.length; i++) {
+ for(int i = 0; i < values.length; i++) {
featureLine.append(values[i]);
- if (i + 1 < values.length) {
+ if(i + 1 < values.length) {
featureLine.append(ATTRIBUTE_SEPARATOR);
}
}
@@ -165,13 +165,13 @@ public class ShortVector extends AbstractNumberVector<Short> {
*
* @apiviz.has ShortVector
*/
- public static class Factory extends AbstractNumberVector.Factory<ShortVector, Short> {
+ public static class Factory extends AbstractNumberVector.Factory<ShortVector> {
@Override
- public <A> ShortVector newFeatureVector(A array, ArrayAdapter<Short, A> adapter) {
+ public <A> ShortVector newFeatureVector(A array, ArrayAdapter<? extends Number, A> adapter) {
int dim = adapter.size(array);
short[] values = new short[dim];
- for (int i = 0; i < dim; i++) {
- values[i] = adapter.get(array, i);
+ for(int i = 0; i < dim; i++) {
+ values[i] = adapter.get(array, i).shortValue();
}
return new ShortVector(values, true);
}
@@ -180,7 +180,7 @@ public class ShortVector extends AbstractNumberVector<Short> {
public <A> ShortVector newNumberVector(A array, NumberArrayAdapter<?, ? super A> adapter) {
int dim = adapter.size(array);
short[] values = new short[dim];
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
values[i] = adapter.getShort(array, i);
}
return new ShortVector(values, true);
@@ -226,7 +226,7 @@ public class ShortVector extends AbstractNumberVector<Short> {
final short dimensionality = buffer.getShort();
assert (buffer.remaining() >= ByteArrayUtil.SIZE_SHORT * dimensionality);
final short[] values = new short[dimensionality];
- for (int i = 0; i < dimensionality; i++) {
+ for(int i = 0; i < dimensionality; i++) {
values[i] = buffer.getShort();
}
return new ShortVector(values, true);
@@ -237,7 +237,7 @@ public class ShortVector extends AbstractNumberVector<Short> {
assert (vec.values.length < Short.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Short.MAX_VALUE + "!";
assert (buffer.remaining() >= ByteArrayUtil.SIZE_SHORT * vec.values.length);
buffer.putShort((short) vec.values.length);
- for (int i = 0; i < vec.values.length; i++) {
+ for(int i = 0; i < vec.values.length; i++) {
buffer.putShort(vec.values[i]);
}
}
@@ -262,7 +262,7 @@ public class ShortVector extends AbstractNumberVector<Short> {
final int dimensionality = ByteArrayUtil.readUnsignedVarint(buffer);
assert (buffer.remaining() >= ByteArrayUtil.SIZE_INT * dimensionality);
final short[] values = new short[dimensionality];
- for (int i = 0; i < dimensionality; i++) {
+ for(int i = 0; i < dimensionality; i++) {
values[i] = (short) ByteArrayUtil.readSignedVarint(buffer);
}
return new ShortVector(values, true);
@@ -272,7 +272,7 @@ public class ShortVector extends AbstractNumberVector<Short> {
public void toByteBuffer(ByteBuffer buffer, ShortVector vec) throws IOException {
assert (vec.values.length < Short.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Short.MAX_VALUE + "!";
ByteArrayUtil.writeUnsignedVarint(buffer, vec.values.length);
- for (int i = 0; i < vec.values.length; i++) {
+ for(int i = 0; i < vec.values.length; i++) {
ByteArrayUtil.writeSignedVarint(buffer, vec.values[i]);
}
}
@@ -281,7 +281,7 @@ public class ShortVector extends AbstractNumberVector<Short> {
public int getByteSize(ShortVector vec) {
assert (vec.values.length < Short.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Short.MAX_VALUE + "!";
int len = ByteArrayUtil.getUnsignedVarintSize(vec.values.length);
- for (int i = 0; i < vec.values.length; i++) {
+ for(int i = 0; i < vec.values.length; i++) {
len += ByteArrayUtil.getSignedVarintSize(vec.values[i]);
}
return len;
diff --git a/src/de/lmu/ifi/dbs/elki/data/SimpleClassLabel.java b/src/de/lmu/ifi/dbs/elki/data/SimpleClassLabel.java
index 8799370d..01fc9410 100644
--- a/src/de/lmu/ifi/dbs/elki/data/SimpleClassLabel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/SimpleClassLabel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -28,8 +28,8 @@ import java.nio.ByteBuffer;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
/**
* A simple class label casting a String as it is as label.
diff --git a/src/de/lmu/ifi/dbs/elki/data/SparseByteVector.java b/src/de/lmu/ifi/dbs/elki/data/SparseByteVector.java
index 06649bb0..6afd9b22 100644
--- a/src/de/lmu/ifi/dbs/elki/data/SparseByteVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/SparseByteVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -31,23 +31,20 @@ import java.nio.ByteBuffer;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
- * <p>
- * A SparseByteVector is to store real values as double values.
- * </p>
- *
- * A SparseByteVector only requires storage for those attribute values that
- * are non-zero.
+ * Sparse vector type, using {@code byte[]} for storing the values, and
+ * {@code int[]} for storing the indexes, approximately 5 bytes per non-zero
+ * value (limited to -128..+127).
*
* @author Arthur Zimek
*/
-public class SparseByteVector extends AbstractNumberVector<Byte> implements SparseNumberVector<Byte> {
+public class SparseByteVector extends AbstractNumberVector implements SparseNumberVector {
/**
* Static instance.
*/
@@ -88,7 +85,7 @@ public class SparseByteVector extends AbstractNumberVector<Byte> implements Spar
}
/**
- * Provides a SparseByteVector consisting of double values according to the
+ * Create a SparseByteVector consisting of double values according to the
* specified mapping of indices and values.
*
* @param values the values to be set as values of the real vector
@@ -141,7 +138,7 @@ public class SparseByteVector extends AbstractNumberVector<Byte> implements Spar
}
/**
- * Provides a SparseByteVector consisting of double values according to the
+ * Create a SparseByteVector consisting of double values according to the
* specified mapping of indices and values.
*
* @param values the values to be set as values of the real vector
@@ -254,20 +251,15 @@ public class SparseByteVector extends AbstractNumberVector<Byte> implements Spar
}
/**
- * <p>
- * Provides a String representation of this SparseByteVector as suitable
- * for
+ * Create a String representation of this SparseByteVector as suitable for
* {@link de.lmu.ifi.dbs.elki.datasource.parser.SparseNumberVectorLabelParser}
* .
- * </p>
*
- * <p>
* The returned String is a single line with entries separated by
* {@link AbstractNumberVector#ATTRIBUTE_SEPARATOR}. The first entry gives the
- * number of values actually not zero. Following entries are pairs of Byte
- * and Byte where the Byte gives the index of the dimensionality and the
- * Byte gives the corresponding value.
- * </p>
+ * number of values actually not zero. Following entries are pairs of Byte and
+ * Byte where the Byte gives the index of the dimensionality and the Byte
+ * gives the corresponding value.
*
* <p>
* Example: a vector (0,1.2,1.3,0)<sup>T</sup> would result in the String<br>
@@ -360,13 +352,13 @@ public class SparseByteVector extends AbstractNumberVector<Byte> implements Spar
*
* @apiviz.has SparseByteVector
*/
- public static class Factory extends AbstractNumberVector.Factory<SparseByteVector, Byte> implements SparseNumberVector.Factory<SparseByteVector, Byte> {
+ public static class Factory extends AbstractNumberVector.Factory<SparseByteVector> implements SparseNumberVector.Factory<SparseByteVector> {
@Override
- public <A> SparseByteVector newFeatureVector(A array, ArrayAdapter<Byte, A> adapter) {
+ public <A> SparseByteVector newFeatureVector(A array, ArrayAdapter<? extends Number, A> adapter) {
int dim = adapter.size(array);
byte[] values = new byte[dim];
for(int i = 0; i < dim; i++) {
- values[i] = adapter.get(array, i);
+ values[i] = adapter.get(array, i).byteValue();
}
// TODO: improve efficiency
return new SparseByteVector(values);
diff --git a/src/de/lmu/ifi/dbs/elki/data/SparseDoubleVector.java b/src/de/lmu/ifi/dbs/elki/data/SparseDoubleVector.java
index 10d30b7f..400ed3fc 100644
--- a/src/de/lmu/ifi/dbs/elki/data/SparseDoubleVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/SparseDoubleVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -31,23 +31,20 @@ import java.nio.ByteBuffer;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
- * <p>
- * A SparseDoubleVector is to store real values as double values.
- * </p>
- *
- * A SparseDoubleVector only requires storage for those attribute values that
- * are non-zero.
+ * Sparse vector type, using {@code double[]} for storing the values, and
+ * {@code int[]} for storing the indexes, approximately 12 bytes per non-zero
+ * value.
*
* @author Arthur Zimek
*/
-public class SparseDoubleVector extends AbstractNumberVector<Double> implements SparseNumberVector<Double> {
+public class SparseDoubleVector extends AbstractNumberVector implements SparseNumberVector {
/**
* Static instance.
*/
@@ -88,7 +85,7 @@ public class SparseDoubleVector extends AbstractNumberVector<Double> implements
}
/**
- * Provides a SparseDoubleVector consisting of double values according to the
+ * Create a SparseDoubleVector consisting of double values according to the
* specified mapping of indices and values.
*
* @param values the values to be set as values of the real vector
@@ -141,7 +138,7 @@ public class SparseDoubleVector extends AbstractNumberVector<Double> implements
}
/**
- * Provides a SparseDoubleVector consisting of double values according to the
+ * Create a SparseDoubleVector consisting of double values according to the
* specified mapping of indices and values.
*
* @param values the values to be set as values of the real vector
@@ -243,24 +240,18 @@ public class SparseDoubleVector extends AbstractNumberVector<Double> implements
}
/**
- * <p>
- * Provides a String representation of this SparseDoubleVector as suitable for
+ * Create a String representation of this SparseDoubleVector as suitable for
* {@link de.lmu.ifi.dbs.elki.datasource.parser.SparseNumberVectorLabelParser}
* .
- * </p>
*
- * <p>
* The returned String is a single line with entries separated by
* {@link AbstractNumberVector#ATTRIBUTE_SEPARATOR}. The first entry gives the
* number of values actually not zero. Following entries are pairs of Integer
* and Double where the Integer gives the index of the dimensionality and the
* Double gives the corresponding value.
- * </p>
*
- * <p>
* Example: a vector (0,1.2,1.3,0)<sup>T</sup> would result in the String<br>
* <code>2 2 1.2 3 1.3</code><br>
- * </p>
*
* @return a String representation of this SparseDoubleVector
*/
@@ -348,13 +339,13 @@ public class SparseDoubleVector extends AbstractNumberVector<Double> implements
*
* @apiviz.has SparseDoubleVector
*/
- public static class Factory extends AbstractNumberVector.Factory<SparseDoubleVector, Double> implements SparseNumberVector.Factory<SparseDoubleVector, Double> {
+ public static class Factory extends AbstractNumberVector.Factory<SparseDoubleVector> implements SparseNumberVector.Factory<SparseDoubleVector> {
@Override
- public <A> SparseDoubleVector newFeatureVector(A array, ArrayAdapter<Double, A> adapter) {
+ public <A> SparseDoubleVector newFeatureVector(A array, ArrayAdapter<? extends Number, A> adapter) {
int dim = adapter.size(array);
double[] values = new double[dim];
for(int i = 0; i < dim; i++) {
- values[i] = adapter.get(array, i);
+ values[i] = adapter.get(array, i).doubleValue();
}
// TODO: improve efficiency
return new SparseDoubleVector(values);
diff --git a/src/de/lmu/ifi/dbs/elki/data/SparseFeatureVector.java b/src/de/lmu/ifi/dbs/elki/data/SparseFeatureVector.java
index 4de65abf..cf34b266 100644
--- a/src/de/lmu/ifi/dbs/elki/data/SparseFeatureVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/SparseFeatureVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -28,7 +28,6 @@ package de.lmu.ifi.dbs.elki.data;
*
* @author Erich Schubert
*
- * @param <D> Data type
*/
public interface SparseFeatureVector<D> extends FeatureVector<D> {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/data/SparseFloatVector.java b/src/de/lmu/ifi/dbs/elki/data/SparseFloatVector.java
index 5148920e..b9b2a9e4 100644
--- a/src/de/lmu/ifi/dbs/elki/data/SparseFloatVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/SparseFloatVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -33,23 +33,20 @@ import java.nio.ByteBuffer;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
- * <p>
- * A SparseFloatVector is to store real values approximately as float values.
- * </p>
- *
- * A SparseFloatVector only requires storage for those attribute values that are
- * non-zero.
+ * Sparse vector type, using {@code float[]} for storing the values, and
+ * {@code int[]} for storing the indexes, approximately 8 bytes per non-zero
+ * value.
*
* @author Arthur Zimek
*/
-public class SparseFloatVector extends AbstractNumberVector<Float> implements SparseNumberVector<Float> {
+public class SparseFloatVector extends AbstractNumberVector implements SparseNumberVector {
/**
* Static instance.
*/
@@ -90,7 +87,7 @@ public class SparseFloatVector extends AbstractNumberVector<Float> implements Sp
}
/**
- * Provides a SparseFloatVector consisting of double values according to the
+ * Create a SparseFloatVector consisting of double values according to the
* specified mapping of indices and values.
*
* @param values the values to be set as values of the real vector
@@ -143,7 +140,7 @@ public class SparseFloatVector extends AbstractNumberVector<Float> implements Sp
}
/**
- * Provides a SparseFloatVector consisting of double values according to the
+ * Create a SparseFloatVector consisting of double values according to the
* specified mapping of indices and values.
*
* @param values the values to be set as values of the real vector
@@ -245,24 +242,18 @@ public class SparseFloatVector extends AbstractNumberVector<Float> implements Sp
}
/**
- * <p>
- * Provides a String representation of this SparseFloatVector as suitable for
+ * Create a String representation of this SparseFloatVector as suitable for
* {@link de.lmu.ifi.dbs.elki.datasource.parser.SparseNumberVectorLabelParser}
* .
- * </p>
*
- * <p>
* The returned String is a single line with entries separated by
* {@link AbstractNumberVector#ATTRIBUTE_SEPARATOR}. The first entry gives the
* number of values actually not zero. Following entries are pairs of Integer
* and Float where the Integer gives the index of the dimensionality and the
* Float gives the corresponding value.
- * </p>
*
- * <p>
* Example: a vector (0,1.2,1.3,0)<sup>T</sup> would result in the String<br>
* <code>2 2 1.2 3 1.3</code><br>
- * </p>
*
* @return a String representation of this SparseFloatVector
*/
@@ -350,13 +341,13 @@ public class SparseFloatVector extends AbstractNumberVector<Float> implements Sp
*
* @apiviz.has SparseFloatVector
*/
- public static class Factory extends AbstractNumberVector.Factory<SparseFloatVector, Float> implements SparseNumberVector.Factory<SparseFloatVector, Float> {
+ public static class Factory extends AbstractNumberVector.Factory<SparseFloatVector> implements SparseNumberVector.Factory<SparseFloatVector> {
@Override
- public <A> SparseFloatVector newFeatureVector(A array, ArrayAdapter<Float, A> adapter) {
+ public <A> SparseFloatVector newFeatureVector(A array, ArrayAdapter<? extends Number, A> adapter) {
int dim = adapter.size(array);
float[] values = new float[dim];
for(int i = 0; i < dim; i++) {
- values[i] = adapter.get(array, i);
+ values[i] = adapter.get(array, i).floatValue();
}
// TODO: inefficient
return new SparseFloatVector(values);
diff --git a/src/de/lmu/ifi/dbs/elki/data/SparseIntegerVector.java b/src/de/lmu/ifi/dbs/elki/data/SparseIntegerVector.java
index 00811ba3..12711b02 100644
--- a/src/de/lmu/ifi/dbs/elki/data/SparseIntegerVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/SparseIntegerVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -31,23 +31,20 @@ import java.nio.ByteBuffer;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
- * <p>
- * A SparseIntegerVector is to store real values as double values.
- * </p>
- *
- * A SparseIntegerVector only requires storage for those attribute values that
- * are non-zero.
+ * Sparse vector type, using {@code int[]} for storing the values, and
+ * {@code int[]} for storing the indexes, approximately 8 bytes per non-zero
+ * integer value.
*
* @author Arthur Zimek
*/
-public class SparseIntegerVector extends AbstractNumberVector<Integer> implements SparseNumberVector<Integer> {
+public class SparseIntegerVector extends AbstractNumberVector implements SparseNumberVector {
/**
* Static instance.
*/
@@ -88,7 +85,7 @@ public class SparseIntegerVector extends AbstractNumberVector<Integer> implement
}
/**
- * Provides a SparseIntegerVector consisting of double values according to the
+ * Create a SparseIntegerVector consisting of double values according to the
* specified mapping of indices and values.
*
* @param values the values to be set as values of the real vector
@@ -141,7 +138,7 @@ public class SparseIntegerVector extends AbstractNumberVector<Integer> implement
}
/**
- * Provides a SparseIntegerVector consisting of double values according to the
+ * Create a SparseIntegerVector consisting of double values according to the
* specified mapping of indices and values.
*
* @param values the values to be set as values of the real vector
@@ -255,25 +252,18 @@ public class SparseIntegerVector extends AbstractNumberVector<Integer> implement
}
/**
- * <p>
- * Provides a String representation of this SparseIntegerVector as suitable
- * for
+ * Create a String representation of this SparseIntegerVector as suitable for
* {@link de.lmu.ifi.dbs.elki.datasource.parser.SparseNumberVectorLabelParser}
* .
- * </p>
*
- * <p>
* The returned String is a single line with entries separated by
* {@link AbstractNumberVector#ATTRIBUTE_SEPARATOR}. The first entry gives the
* number of values actually not zero. Following entries are pairs of Integer
* and Integer where the Integer gives the index of the dimensionality and the
* Integer gives the corresponding value.
- * </p>
*
- * <p>
* Example: a vector (0,1.2,1.3,0)<sup>T</sup> would result in the String<br>
* <code>2 2 1.2 3 1.3</code><br>
- * </p>
*
* @return a String representation of this SparseIntegerVector
*/
@@ -361,13 +351,13 @@ public class SparseIntegerVector extends AbstractNumberVector<Integer> implement
*
* @apiviz.has SparseIntegerVector
*/
- public static class Factory extends AbstractNumberVector.Factory<SparseIntegerVector, Integer> implements SparseNumberVector.Factory<SparseIntegerVector, Integer> {
+ public static class Factory extends AbstractNumberVector.Factory<SparseIntegerVector> implements SparseNumberVector.Factory<SparseIntegerVector> {
@Override
- public <A> SparseIntegerVector newFeatureVector(A array, ArrayAdapter<Integer, A> adapter) {
+ public <A> SparseIntegerVector newFeatureVector(A array, ArrayAdapter<? extends Number, A> adapter) {
int dim = adapter.size(array);
int[] values = new int[dim];
for(int i = 0; i < dim; i++) {
- values[i] = adapter.get(array, i);
+ values[i] = adapter.get(array, i).intValue();
}
// TODO: improve efficiency
return new SparseIntegerVector(values);
diff --git a/src/de/lmu/ifi/dbs/elki/data/SparseNumberVector.java b/src/de/lmu/ifi/dbs/elki/data/SparseNumberVector.java
index 7b97b268..bfa6ab41 100644
--- a/src/de/lmu/ifi/dbs/elki/data/SparseNumberVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/SparseNumberVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -29,10 +29,8 @@ import gnu.trove.map.TIntDoubleMap;
* Combines the SparseFeatureVector and NumberVector.
*
* @author Erich Schubert
- *
- * @param <N> Number type
*/
-public interface SparseNumberVector<N extends Number> extends NumberVector<N>, SparseFeatureVector<N> {
+public interface SparseNumberVector extends NumberVector, SparseFeatureVector<Number> {
/**
* Iterator over non-zero features only, <em>ascendingly</em>.
*
@@ -173,9 +171,8 @@ public interface SparseNumberVector<N extends Number> extends NumberVector<N>, S
* @apiviz.has SparseNumberVector
*
* @param <V> Vector type number type
- * @param <N> Number type
*/
- interface Factory<V extends SparseNumberVector<N>, N extends Number> extends NumberVector.Factory<V, N> {
+ interface Factory<V extends SparseNumberVector> extends NumberVector.Factory<V> {
/**
* Returns a new NumberVector of N for the given values.
*
diff --git a/src/de/lmu/ifi/dbs/elki/data/SparseShortVector.java b/src/de/lmu/ifi/dbs/elki/data/SparseShortVector.java
index 7e54dd5a..7191333f 100644
--- a/src/de/lmu/ifi/dbs/elki/data/SparseShortVector.java
+++ b/src/de/lmu/ifi/dbs/elki/data/SparseShortVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -31,23 +31,20 @@ import java.nio.ByteBuffer;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
- * <p>
- * A SparseShortVector is to store real values as double values.
- * </p>
- *
- * A SparseShortVector only requires storage for those attribute values that are
- * non-zero.
+ * Sparse vector type, using {@code short[]} for storing the values, and
+ * {@code int[]} for storing the indexes, approximately 6 bytes per non-zero
+ * value.
*
* @author Arthur Zimek
*/
-public class SparseShortVector extends AbstractNumberVector<Short> implements SparseNumberVector<Short> {
+public class SparseShortVector extends AbstractNumberVector implements SparseNumberVector {
/**
* Static instance.
*/
@@ -88,7 +85,7 @@ public class SparseShortVector extends AbstractNumberVector<Short> implements Sp
}
/**
- * Provides a SparseShortVector consisting of double values according to the
+ * Create a SparseShortVector consisting of double values according to the
* specified mapping of indices and values.
*
* @param values the values to be set as values of the real vector
@@ -141,7 +138,7 @@ public class SparseShortVector extends AbstractNumberVector<Short> implements Sp
}
/**
- * Provides a SparseShortVector consisting of double values according to the
+ * Create a SparseShortVector consisting of double values according to the
* specified mapping of indices and values.
*
* @param values the values to be set as values of the real vector
@@ -255,24 +252,18 @@ public class SparseShortVector extends AbstractNumberVector<Short> implements Sp
}
/**
- * <p>
- * Provides a String representation of this SparseShortVector as suitable for
+ * Create a String representation of this SparseShortVector as suitable for
* {@link de.lmu.ifi.dbs.elki.datasource.parser.SparseNumberVectorLabelParser}
* .
- * </p>
*
- * <p>
* The returned String is a single line with entries separated by
* {@link AbstractNumberVector#ATTRIBUTE_SEPARATOR}. The first entry gives the
* number of values actually not zero. Following entries are pairs of Short
* and Short where the Short gives the index of the dimensionality and the
* Short gives the corresponding value.
- * </p>
*
- * <p>
* Example: a vector (0,1.2,1.3,0)<sup>T</sup> would result in the String<br>
* <code>2 2 1.2 3 1.3</code><br>
- * </p>
*
* @return a String representation of this SparseShortVector
*/
@@ -360,13 +351,13 @@ public class SparseShortVector extends AbstractNumberVector<Short> implements Sp
*
* @apiviz.has SparseShortVector
*/
- public static class Factory extends AbstractNumberVector.Factory<SparseShortVector, Short> implements SparseNumberVector.Factory<SparseShortVector, Short> {
+ public static class Factory extends AbstractNumberVector.Factory<SparseShortVector> implements SparseNumberVector.Factory<SparseShortVector> {
@Override
- public <A> SparseShortVector newFeatureVector(A array, ArrayAdapter<Short, A> adapter) {
+ public <A> SparseShortVector newFeatureVector(A array, ArrayAdapter<? extends Number, A> adapter) {
int dim = adapter.size(array);
short[] values = new short[dim];
for(int i = 0; i < dim; i++) {
- values[i] = adapter.get(array, i);
+ values[i] = adapter.get(array, i).shortValue();
}
// TODO: improve efficiency
return new SparseShortVector(values);
diff --git a/src/de/lmu/ifi/dbs/elki/data/Subspace.java b/src/de/lmu/ifi/dbs/elki/data/Subspace.java
index c5072e46..085f4ad4 100644
--- a/src/de/lmu/ifi/dbs/elki/data/Subspace.java
+++ b/src/de/lmu/ifi/dbs/elki/data/Subspace.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -26,6 +26,8 @@ package de.lmu.ifi.dbs.elki.data;
import java.util.BitSet;
import java.util.Comparator;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
+
/**
* Represents a subspace of the original data space.
*
@@ -37,7 +39,7 @@ public class Subspace {
/**
* The dimensions building this subspace.
*/
- private final BitSet dimensions = new BitSet();
+ private final long[] dimensions;
/**
* The dimensionality of this subspace.
@@ -50,7 +52,8 @@ public class Subspace {
* @param dimension the dimension building this subspace
*/
public Subspace(int dimension) {
- dimensions.set(dimension);
+ dimensions = BitsUtil.zero(dimension);
+ BitsUtil.setI(dimensions, dimension);
dimensionality = 1;
}
@@ -59,9 +62,24 @@ public class Subspace {
*
* @param dimensions the dimensions building this subspace
*/
- public Subspace(BitSet dimensions) {
- this.dimensions.or(dimensions);
- dimensionality = dimensions.cardinality();
+ public Subspace(long[] dimensions) {
+ this.dimensions = dimensions;
+ dimensionality = BitsUtil.cardinality(dimensions);
+ }
+
+ /**
+ * Creates a new k-dimensional subspace of the original data space.
+ *
+ * @param bitset the dimensions building this subspace
+ *
+ * @deprecated use bitset.toLongArray() to convert to the preferred
+ * representation; or even better, use the preferred long arrays
+ * right away.
+ */
+ @Deprecated
+ public Subspace(BitSet bitset) {
+ this.dimensions = bitset.toLongArray();
+ dimensionality = BitsUtil.cardinality(dimensions);
}
/**
@@ -69,8 +87,8 @@ public class Subspace {
*
* @return the dimensions of this subspace
*/
- public final BitSet getDimensions() {
- return (BitSet) dimensions.clone();
+ public final long[] getDimensions() {
+ return dimensions;
}
/**
@@ -94,7 +112,7 @@ public class Subspace {
* @see Subspace#joinLastDimensions(Subspace)
*/
public Subspace join(Subspace other) {
- BitSet newDimensions = joinLastDimensions(other);
+ long[] newDimensions = joinLastDimensions(other);
if(newDimensions == null) {
return null;
}
@@ -123,8 +141,8 @@ public class Subspace {
public String toString(String pre) {
StringBuilder result = new StringBuilder();
result.append(pre).append("Dimensions: [");
- int start = dimensions.nextSetBit(0);
- for(int d = start; d >= 0; d = dimensions.nextSetBit(d + 1)) {
+ int start = BitsUtil.nextSetBit(dimensions, 0);
+ for(int d = start; d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
if(d != start) {
result.append(", ");
}
@@ -153,7 +171,7 @@ public class Subspace {
public String dimensonsToString(String sep) {
StringBuilder result = new StringBuilder();
result.append("[");
- for(int dim = dimensions.nextSetBit(0); dim >= 0; dim = dimensions.nextSetBit(dim + 1)) {
+ for(int dim = BitsUtil.nextSetBit(dimensions, 0); dim >= 0; dim = BitsUtil.nextSetBit(dimensions, dim + 1)) {
if(result.length() == 1) {
result.append(dim + 1);
}
@@ -179,8 +197,9 @@ public class Subspace {
if(this.dimensionality > subspace.dimensionality) {
return false;
}
- for(int d = dimensions.nextSetBit(0); d >= 0; d = dimensions.nextSetBit(d + 1)) {
- if(!subspace.dimensions.get(d)) {
+ // FIXME: use bit operations.
+ for(int d = BitsUtil.nextSetBit(dimensions, 0); d >= 0; d = BitsUtil.nextSetBit(dimensions, d + 1)) {
+ if(!BitsUtil.get(subspace.dimensions, d)) {
return false;
}
}
@@ -199,26 +218,25 @@ public class Subspace {
* specified subspace if the join condition is fulfilled, null
* otherwise.
*/
- protected BitSet joinLastDimensions(Subspace other) {
+ protected long[] joinLastDimensions(Subspace other) {
if(this.dimensionality != other.dimensionality) {
return null;
}
- BitSet resultDimensions = new BitSet();
+ long[] resultDimensions = BitsUtil.zero(this.dimensionality);
int last1 = -1, last2 = -1;
- for(int d1 = this.dimensions.nextSetBit(0), d2 = other.dimensions.nextSetBit(0); d1 >= 0 && d2 >= 0; d1 = this.dimensions.nextSetBit(d1 + 1), d2 = other.dimensions.nextSetBit(d2 + 1)) {
-
+ for(int d1 = BitsUtil.nextSetBit(this.dimensions, 0), d2 = BitsUtil.nextSetBit(other.dimensions, 0); d1 >= 0 && d2 >= 0; d1 = BitsUtil.nextSetBit(this.dimensions, d1 + 1), d2 = BitsUtil.nextSetBit(other.dimensions, d2 + 1)) {
if(d1 == d2) {
- resultDimensions.set(d1);
+ BitsUtil.setI(resultDimensions, d1);
}
last1 = d1;
last2 = d2;
}
if(last1 < last2) {
- resultDimensions.set(last1);
- resultDimensions.set(last2);
+ BitsUtil.setI(resultDimensions, last1);
+ BitsUtil.setI(resultDimensions, last2);
return resultDimensions;
}
else {
@@ -272,9 +290,9 @@ public class Subspace {
* greater than the dimensionality of the second subspace. Otherwise the
* comparison works as follows: Let {@code d1} and {@code d2} be the first
* occurrences of pairwise unequal dimensions in the specified subspaces.
- * Then a negative integer or a positive integer will be returned if {@code
- * d1} is less than or greater than {@code d2}. Otherwise the two subspaces
- * have equal dimensions and zero will be returned.
+ * Then a negative integer or a positive integer will be returned if
+ * {@code d1} is less than or greater than {@code d2}. Otherwise the two
+ * subspaces have equal dimensions and zero will be returned.
*
* {@inheritDoc}
*/
@@ -297,7 +315,7 @@ public class Subspace {
return compare;
}
- for(int d1 = s1.getDimensions().nextSetBit(0), d2 = s2.getDimensions().nextSetBit(0); d1 >= 0 && d2 >= 0; d1 = s1.getDimensions().nextSetBit(d1 + 1), d2 = s2.getDimensions().nextSetBit(d2 + 1)) {
+ for(int d1 = BitsUtil.nextSetBit(s1.getDimensions(), 0), d2 = BitsUtil.nextSetBit(s2.getDimensions(), 0); d1 >= 0 && d2 >= 0; d1 = BitsUtil.nextSetBit(s1.getDimensions(), d1 + 1), d2 = BitsUtil.nextSetBit(s2.getDimensions(), d2 + 1)) {
if(d1 != d2) {
return d1 - d2;
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/VectorUtil.java b/src/de/lmu/ifi/dbs/elki/data/VectorUtil.java
index 0a018622..59200ea9 100644
--- a/src/de/lmu/ifi/dbs/elki/data/VectorUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/data/VectorUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.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
@@ -36,7 +36,6 @@ 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.database.relation.RelationUtil;
-import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
@@ -60,23 +59,6 @@ public final class VectorUtil {
}
/**
- * Return the range across all dimensions. Useful in particular for time
- * series.
- *
- * @param vec Vector to process.
- * @return [min, max]
- */
- public static DoubleMinMax getRangeDouble(NumberVector<?> vec) {
- DoubleMinMax minmax = new DoubleMinMax();
-
- for(int i = 0; i < vec.getDimensionality(); i++) {
- minmax.put(vec.doubleValue(i));
- }
-
- return minmax;
- }
-
- /**
* Produce a new vector based on random numbers in [0:1].
*
* @param factory Vector factory
@@ -85,7 +67,7 @@ public final class VectorUtil {
* @param <V> vector type
* @return new instance
*/
- public static <V extends NumberVector<?>> V randomVector(NumberVector.Factory<V, ?> factory, int dim, Random r) {
+ public static <V extends NumberVector> V randomVector(NumberVector.Factory<V> factory, int dim, Random r) {
return factory.newNumberVector(MathUtil.randomDoubleArray(dim, r));
}
@@ -97,7 +79,7 @@ public final class VectorUtil {
* @param <V> vector type
* @return new instance
*/
- public static <V extends NumberVector<?>> V randomVector(NumberVector.Factory<V, ?> factory, int dim) {
+ public static <V extends NumberVector> V randomVector(NumberVector.Factory<V> factory, int dim) {
return randomVector(factory, dim, new Random());
}
@@ -108,7 +90,7 @@ public final class VectorUtil {
* @param v2 Second vector
* @return angle
*/
- public static double angleSparse(SparseNumberVector<?> v1, SparseNumberVector<?> v2) {
+ public static double angleSparse(SparseNumberVector v1, SparseNumberVector v2) {
// TODO: exploit precomputed length, when available?
// Length of first vector
double l1 = 0., l2 = 0., cross = 0.;
@@ -145,9 +127,14 @@ public final class VectorUtil {
l2 += val * val;
i2 = v2.iterAdvance(i2);
}
-
- final double a = cross / (Math.sqrt(l1) * Math.sqrt(l2));
- return (a > 1.) ? 1. : a;
+ if(cross == 0.) {
+ return 0.;
+ }
+ if(l1 == 0. || l2 == 0.) {
+ return 1.;
+ }
+ final double a = Math.sqrt((cross / l1) * (cross / l2));
+ return (a < 1.) ? a : 1.;
}
/**
@@ -158,35 +145,41 @@ public final class VectorUtil {
* @param o Origin
* @return Angle
*/
- public static double angle(NumberVector<?> v1, NumberVector<?> v2, Vector o) {
- final int dim1 = v1.getDimensionality(), dim2 = v1.getDimensionality(), dimo = v1.getDimensionality();
+ public static double angle(NumberVector v1, NumberVector v2, Vector o) {
+ final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality(), dimo = o.getDimensionality();
final int mindim = (dim1 <= dim2) ? dim1 : dim2;
// Essentially, we want to compute this:
// v1' = v1 - o, v2' = v2 - o
// v1'.transposeTimes(v2') / (v1'.euclideanLength()*v2'.euclideanLength());
// We can just compute all three in parallel.
double[] oe = o.getArrayRef();
- double s = 0, e1 = 0, e2 = 0;
+ double cross = 0., l1 = 0., l2 = 0.;
for(int k = 0; k < mindim; k++) {
final double dk = k < dimo ? oe[k] : 0.;
final double r1 = v1.doubleValue(k) - dk;
final double r2 = v2.doubleValue(k) - dk;
- s += r1 * r2;
- e1 += r1 * r1;
- e2 += r2 * r2;
+ cross += r1 * r2;
+ l1 += r1 * r1;
+ l2 += r2 * r2;
}
for(int k = mindim; k < dim1; k++) {
final double dk = k < dimo ? oe[k] : 0.;
final double r1 = v1.doubleValue(k) - dk;
- e1 += r1 * r1;
+ l1 += r1 * r1;
}
for(int k = mindim; k < dim2; k++) {
final double dk = k < dimo ? oe[k] : 0.;
final double r2 = v2.doubleValue(k) - dk;
- e2 += r2 * r2;
+ l2 += r2 * r2;
+ }
+ if(cross == 0.) {
+ return 0.;
+ }
+ if(l1 == 0. || l2 == 0.) {
+ return 1.;
}
- final double a = Math.sqrt((s / e1) * (s / e2));
- return (a > 1.) ? 1. : a;
+ final double a = Math.sqrt((cross / l1) * (cross / l2));
+ return (a < 1.) ? a : 1.;
}
/**
@@ -197,34 +190,40 @@ public final class VectorUtil {
* @param o Origin
* @return Angle
*/
- public static double angle(NumberVector<?> v1, NumberVector<?> v2, NumberVector<?> o) {
- final int dim1 = v1.getDimensionality(), dim2 = v1.getDimensionality(), dimo = o.getDimensionality();
+ public static double angle(NumberVector v1, NumberVector v2, NumberVector o) {
+ final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality(), dimo = o.getDimensionality();
final int mindim = (dim1 <= dim2) ? dim1 : dim2;
// Essentially, we want to compute this:
// v1' = v1 - o, v2' = v2 - o
// v1'.transposeTimes(v2') / (v1'.euclideanLength()*v2'.euclideanLength());
// We can just compute all three in parallel.
- double s = 0, e1 = 0, e2 = 0;
+ double cross = 0, l1 = 0, l2 = 0;
for(int k = 0; k < mindim; k++) {
final double ok = k < dimo ? o.doubleValue(k) : 0.;
final double r1 = v1.doubleValue(k) - ok;
final double r2 = v2.doubleValue(k) - o.doubleValue(k);
- s += r1 * r2;
- e1 += r1 * r1;
- e2 += r2 * r2;
+ cross += r1 * r2;
+ l1 += r1 * r1;
+ l2 += r2 * r2;
}
for(int k = mindim; k < dim1; k++) {
final double ok = k < dimo ? o.doubleValue(k) : 0.;
final double r1 = v1.doubleValue(k) - ok;
- e1 += r1 * r1;
+ l1 += r1 * r1;
}
for(int k = mindim; k < dim2; k++) {
final double ok = k < dimo ? o.doubleValue(k) : 0.;
final double r2 = v2.doubleValue(k) - ok;
- e2 += r2 * r2;
+ l2 += r2 * r2;
+ }
+ if(cross == 0.) {
+ return 0.;
+ }
+ if(l1 == 0. || l2 == 0.) {
+ return 1.;
}
- final double a = Math.sqrt((s / e1) * (s / e2));
- return (a > 1.) ? 1. : a;
+ final double a = Math.sqrt((cross / l1) * (cross / l2));
+ return (a < 1.) ? a : 1.;
}
/**
@@ -236,33 +235,39 @@ public final class VectorUtil {
* @param v2 second vector
* @return Angle
*/
- public static double cosAngle(NumberVector<?> v1, NumberVector<?> v2) {
- if(v1 instanceof SparseNumberVector<?> && v2 instanceof SparseNumberVector<?>) {
- return angleSparse((SparseNumberVector<?>) v1, (SparseNumberVector<?>) v2);
+ public static double cosAngle(NumberVector v1, NumberVector v2) {
+ if(v1 instanceof SparseNumberVector && v2 instanceof SparseNumberVector) {
+ return angleSparse((SparseNumberVector) v1, (SparseNumberVector) v2);
}
- final int dim1 = v1.getDimensionality(), dim2 = v1.getDimensionality();
+ final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality();
final int mindim = (dim1 <= dim2) ? dim1 : dim2;
// Essentially, we want to compute this:
// v1.transposeTimes(v2) / (v1.euclideanLength() * v2.euclideanLength());
// We can just compute all three in parallel.
- double s = 0, e1 = 0, e2 = 0;
+ double cross = 0, l1 = 0, l2 = 0;
for(int k = 0; k < mindim; k++) {
final double r1 = v1.doubleValue(k);
final double r2 = v2.doubleValue(k);
- s += r1 * r2;
- e1 += r1 * r1;
- e2 += r2 * r2;
+ cross += r1 * r2;
+ l1 += r1 * r1;
+ l2 += r2 * r2;
}
for(int k = mindim; k < dim1; k++) {
final double r1 = v1.doubleValue(k);
- e1 += r1 * r1;
+ l1 += r1 * r1;
}
for(int k = mindim; k < dim2; k++) {
final double r2 = v2.doubleValue(k);
- e2 += r2 * r2;
+ l2 += r2 * r2;
}
- final double a = Math.sqrt((s / e1) * (s / e2));
- return (a > 1.) ? 1. : a;
+ if(cross == 0.) {
+ return 0.;
+ }
+ if(l1 == 0. || l2 == 0.) {
+ return 1.;
+ }
+ final double a = Math.sqrt((cross / l1) * (cross / l2));
+ return (a < 1.) ? a : 1.;
}
// TODO: add more precise but slower O(n^2) angle computation according to:
@@ -277,60 +282,66 @@ public final class VectorUtil {
* @return Angle
*/
public static double minCosAngle(SpatialComparable v1, SpatialComparable v2) {
- if(v1 instanceof NumberVector<?> && v2 instanceof NumberVector<?>) {
- return cosAngle((NumberVector<?>) v1, (NumberVector<?>) v2);
+ if(v1 instanceof NumberVector && v2 instanceof NumberVector) {
+ return cosAngle((NumberVector) v1, (NumberVector) v2);
}
- final int dim1 = v1.getDimensionality(), dim2 = v1.getDimensionality();
+ final int dim1 = v1.getDimensionality(), dim2 = v2.getDimensionality();
final int mindim = (dim1 <= dim2) ? dim1 : dim2;
// Essentially, we want to compute this:
// absmax(v1.transposeTimes(v2))/(min(v1.euclideanLength())*min(v2.euclideanLength()));
// We can just compute all three in parallel.
- double s1 = 0, s2 = 0, e1 = 0, e2 = 0;
+ double s1 = 0, s2 = 0, l1 = 0, l2 = 0;
for(int k = 0; k < mindim; k++) {
final double min1 = v1.getMin(k), max1 = v1.getMax(k);
final double min2 = v2.getMin(k), max2 = v2.getMax(k);
final double p1 = min1 * min2, p2 = min1 * max2;
final double p3 = max1 * min2, p4 = max1 * max2;
- s1 += Math.max(Math.max(p1, p2), Math.max(p3, p4));
- s2 += Math.min(Math.min(p1, p2), Math.min(p3, p4));
+ s1 += Math.max(p1 > p2 ? p1 : p2, p3 > p4 ? p3 : p4);
+ s2 += Math.min(p1 < p2 ? p1 : p2, p3 < p4 ? p3 : p4);
if(max1 < 0) {
- e1 += max1 * max1;
+ l1 += max1 * max1;
}
else if(min1 > 0) {
- e1 += min1 * min1;
+ l1 += min1 * min1;
} // else: 0
if(max2 < 0) {
- e2 += max2 * max2;
+ l2 += max2 * max2;
}
else if(min2 > 0) {
- e2 += min2 * min2;
+ l2 += min2 * min2;
} // else: 0
}
for(int k = mindim; k < dim1; k++) {
final double min1 = v1.getMin(k), max1 = v1.getMax(k);
if(max1 < 0.) {
- e1 += max1 * max1;
+ l1 += max1 * max1;
}
else if(min1 > 0.) {
- e1 += min1 * min1;
+ l1 += min1 * min1;
} // else: 0
}
for(int k = mindim; k < dim2; k++) {
final double min2 = v2.getMin(k), max2 = v2.getMax(k);
if(max2 < 0.) {
- e2 += max2 * max2;
+ l2 += max2 * max2;
}
else if(min2 > 0.) {
- e2 += min2 * min2;
+ l2 += min2 * min2;
} // else: 0
}
- final double s = Math.max(s1, Math.abs(s2));
- final double a = Math.sqrt((s / e1) * (s / e2));
- return (a > 1.) ? 1. : a;
+ final double cross = Math.max(s1, Math.abs(s2));
+ if(cross == 0.) {
+ return 0.;
+ }
+ if(l1 == 0. || l2 == 0.) {
+ return 1.;
+ }
+ final double a = Math.sqrt((cross / l1) * (cross / l2));
+ return (a < 1.) ? a : 1.;
}
/**
- * Provides the scalar product (inner product) of this and the given
+ * Compute the scalar product (inner product) of this and the given
* DoubleVector.
*
* @param d1 the first vector to compute the scalar product for
@@ -338,7 +349,7 @@ public final class VectorUtil {
* @return the scalar product (inner product) of this and the given
* DoubleVector
*/
- public static double scalarProduct(NumberVector<?> d1, NumberVector<?> d2) {
+ public static double scalarProduct(NumberVector d1, NumberVector d2) {
final int dim = d1.getDimensionality();
double result = 0.;
for(int i = 0; i < dim; i++) {
@@ -354,7 +365,7 @@ public final class VectorUtil {
* @param sample Sample set
* @return Medoid vector
*/
- public static Vector computeMedoid(Relation<? extends NumberVector<?>> relation, DBIDs sample) {
+ public static Vector computeMedoid(Relation<? extends NumberVector> relation, DBIDs sample) {
final int dim = RelationUtil.dimensionality(relation);
ArrayModifiableDBIDs mids = DBIDUtil.newArray(sample);
SortDBIDsBySingleDimension s = new SortDBIDsBySingleDimension(relation);
@@ -375,7 +386,7 @@ public final class VectorUtil {
* @param v Vector
* @return {@code mat * v}, as double array.
*/
- public static double[] fastTimes(Matrix mat, NumberVector<?> v) {
+ public static double[] fastTimes(Matrix mat, NumberVector v) {
final double[][] elements = mat.getArrayRef();
final int cdim = mat.getColumnDimensionality();
final double[] X = new double[elements.length];
@@ -407,7 +418,7 @@ public final class VectorUtil {
/**
* The relation to sort.
*/
- private Relation<? extends NumberVector<?>> data;
+ private Relation<? extends NumberVector> data;
/**
* Constructor.
@@ -415,7 +426,7 @@ public final class VectorUtil {
* @param data Vector data source
* @param dim Dimension to sort by
*/
- public SortDBIDsBySingleDimension(Relation<? extends NumberVector<?>> data, int dim) {
+ public SortDBIDsBySingleDimension(Relation<? extends NumberVector> data, int dim) {
super();
this.data = data;
this.d = dim;
@@ -426,7 +437,7 @@ public final class VectorUtil {
*
* @param data Vector data source
*/
- public SortDBIDsBySingleDimension(Relation<? extends NumberVector<?>> data) {
+ public SortDBIDsBySingleDimension(Relation<? extends NumberVector> data) {
super();
this.data = data;
};
@@ -462,7 +473,7 @@ public final class VectorUtil {
*
* @apiviz.exclude
*/
- public static class SortVectorsBySingleDimension implements Comparator<NumberVector<?>> {
+ public static class SortVectorsBySingleDimension implements Comparator<NumberVector> {
/**
* Dimension to sort with.
*/
@@ -504,13 +515,13 @@ public final class VectorUtil {
}
@Override
- public int compare(NumberVector<?> o1, NumberVector<?> o2) {
+ public int compare(NumberVector o1, NumberVector o2) {
return Double.compare(o1.doubleValue(d), o2.doubleValue(d));
}
}
/**
- * Provides a new NumberVector as a projection on the specified attributes.
+ * Project a number vector to the specified attributes.
*
* @param v a NumberVector to project
* @param selectedAttributes the attributes selected for projection
@@ -518,9 +529,9 @@ public final class VectorUtil {
* @param <V> Vector type
* @return a new NumberVector as a projection on the specified attributes
*/
- public static <V extends NumberVector<?>> V project(V v, BitSet selectedAttributes, NumberVector.Factory<V, ?> factory) {
+ public static <V extends NumberVector> V project(V v, BitSet selectedAttributes, NumberVector.Factory<V> factory) {
if(factory instanceof SparseNumberVector.Factory) {
- final SparseNumberVector.Factory<?, ?> sfactory = (SparseNumberVector.Factory<?, ?>) factory;
+ final SparseNumberVector.Factory<?> sfactory = (SparseNumberVector.Factory<?>) factory;
TIntDoubleHashMap values = new TIntDoubleHashMap(selectedAttributes.cardinality(), 1);
for(int d = selectedAttributes.nextSetBit(0); d >= 0; d = selectedAttributes.nextSetBit(d + 1)) {
if(v.doubleValue(d) != 0.0) {
diff --git a/src/de/lmu/ifi/dbs/elki/data/images/AbstractComputeColorHistogram.java b/src/de/lmu/ifi/dbs/elki/data/images/AbstractComputeColorHistogram.java
deleted file mode 100644
index 25181acd..00000000
--- a/src/de/lmu/ifi/dbs/elki/data/images/AbstractComputeColorHistogram.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package de.lmu.ifi.dbs.elki.data.images;
-
-/*
- 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.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-
-import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
-
-/**
- * Abstract class for color histogram computation.
- *
- * @author Erich Schubert
- *
- * @apiviz.uses ImageUtil
- */
-public abstract class AbstractComputeColorHistogram implements ComputeColorHistogram {
- @Override
- public double[] computeColorHistogram(File file, File mask) throws IOException {
- BufferedImage image = ImageUtil.loadImage(file);
- int height = image.getHeight();
- int width = image.getWidth();
-
- BufferedImage maski = null;
- if(mask != null) {
- maski = ImageUtil.loadImage(mask);
- if(maski.getHeight() != height || maski.getWidth() != width) {
- throw new AbortException("Input image and mask do not agree on the image size!");
- }
- }
-
- double[] bins = new double[getNumBins()];
- long valid = 0;
-
- for(int x = 0; x < width; x++) {
- for(int y = 0; y < height; y++) {
- if(maski != null) {
- int col = maski.getRGB(x, y);
- // More transparent than covering
- if((col >>> 24) < 127) {
- continue;
- }
- // More black than white: (R+G+B) > 1.5 * 255
- if(((col >>> 16) & 0xFF) + ((col >>> 8) & 0xFF) + (col & 0xFF) < 382) {
- continue;
- }
- }
- int bin = getBinForColor(image.getRGB(x, y));
- assert (bin < bins.length);
- bins[bin] += 1;
- valid += 1;
- }
- }
- if (valid == 0) {
- throw new AbortException("Mask apparently was all-black.");
- }
- for(int i = 0; i < bins.length; i++) {
- bins[i] /= valid;
- }
- return bins;
- }
-
- /**
- * Get the number of bins.
- *
- * @return Number of bins
- */
- protected abstract int getNumBins();
-
- /**
- * Compute the bin number from a pixel color value.
- *
- * @param rgb Pixel color value
- * @return Bin number
- */
- protected abstract int getBinForColor(int rgb);
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/images/BlendComposite.java b/src/de/lmu/ifi/dbs/elki/data/images/BlendComposite.java
deleted file mode 100644
index 1c3037d6..00000000
--- a/src/de/lmu/ifi/dbs/elki/data/images/BlendComposite.java
+++ /dev/null
@@ -1,437 +0,0 @@
-package de.lmu.ifi.dbs.elki.data.images;
-
-/*
- 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.awt.Composite;
-import java.awt.CompositeContext;
-import java.awt.RenderingHints;
-import java.awt.image.ColorModel;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-
-/**
- * Class to use in {@link java.awt.Graphics2D#setComposite} that facilitates
- * basic image blending such as lighten-only overlays.
- *
- * @author Erich Schubert
- *
- * @apiviz.uses BlendingContext oneway - - «create»
- */
-public class BlendComposite implements Composite {
- /**
- * Source blending, using the source image only.
- */
- public static final int NORMAL = 0;
-
- /**
- * Lighten-only blending.
- */
- public static final int LIGHTEN = 1;
-
- /**
- * Darken-only blending.
- */
- public static final int DARKEN = 2;
-
- /**
- * "Screen" blending.
- */
- public static final int SCREEN = 3;
-
- /**
- * "Multiply" blending.
- */
- public static final int MULTIPLY = 4;
-
- /**
- * "Overlay" blending.
- */
- public static final int OVERLAY = 5;
-
- /**
- * "Average" blending.
- */
- public static final int AVERAGE = 6;
-
- // TODO: Add the missing common blend modes:
- // ADD, Color Burn, Color Dodge, Reflect, Glow, Difference, Negation
-
- /**
- * Alpha (opacity) value.
- */
- private double alpha;
-
- /**
- * Blending mode to use.
- */
- private int mode;
-
- /**
- * Simplified constructor with full opacity.
- *
- * @param mode Blending mode.
- */
- public BlendComposite(int mode) {
- this(mode, 1.0);
- }
-
- /**
- * Full constructor, with alpha (opacity) value.
- *
- * @param mode Blending mode
- * @param alpha Opacity value
- */
- public BlendComposite(int mode, double alpha) {
- this.mode = mode;
- this.alpha = alpha;
- }
-
- @Override
- public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints) {
- switch(mode){
- case NORMAL:
- return new BlendingContext(srcColorModel, dstColorModel, alpha);
- case LIGHTEN:
- return new LightenBlendingContext(srcColorModel, dstColorModel, alpha);
- case DARKEN:
- return new DarkenBlendingContext(srcColorModel, dstColorModel, alpha);
- case SCREEN:
- return new ScreenBlendingContext(srcColorModel, dstColorModel, alpha);
- case MULTIPLY:
- return new MultiplyBlendingContext(srcColorModel, dstColorModel, alpha);
- case OVERLAY:
- return new OverlayBlendingContext(srcColorModel, dstColorModel, alpha);
- case AVERAGE:
- return new AverageBlendingContext(srcColorModel, dstColorModel, alpha);
- default:
- return new BlendingContext(srcColorModel, dstColorModel, alpha);
- }
- }
-
- /**
- * Abstract blending context that takes care of color space conversion and
- * pixel iteration. The base class does simple replacing.
- *
- * @author Erich Schubert
- */
- protected class BlendingContext implements CompositeContext {
- /**
- * Source color model
- */
- private ColorModel srcColorModel;
-
- /**
- * Destination color model
- */
- private ColorModel dstColorModel;
-
- /**
- * Opacity factor
- */
- protected double alpha;
-
- /**
- * Additive inverse of alpha value.
- */
- protected double ialpha;
-
- /**
- * Constructor.
- *
- * @param srcColorModel source color model
- * @param dstColorModel destination color model
- * @param alpha Alpha (opacity) factor
- */
- protected BlendingContext(ColorModel srcColorModel, ColorModel dstColorModel, double alpha) {
- this.srcColorModel = srcColorModel;
- this.dstColorModel = dstColorModel;
- this.alpha = alpha;
- this.ialpha = 1. - alpha;
- }
-
- @Override
- public void dispose() {
- // Nothing to do by default
- }
-
- /**
- * Compose a raster image (source) and a background (destination) to a
- * result raster.
- */
- @Override
- public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
- int width = Math.min(src.getWidth(), dstIn.getWidth());
- int height = Math.min(src.getHeight(), dstIn.getHeight());
-
- Object resPixel = null;
- Object srcPixel = null;
- Object dstPixel = null;
-
- for(int y = dstOut.getMinY(); y < height; y++) {
- for(int x = dstOut.getMinX(); x < width; x++) {
- srcPixel = src.getDataElements(x, y, srcPixel);
- dstPixel = dstIn.getDataElements(x, y, dstPixel);
-
- final int srcAlpha = srcColorModel.getAlpha(srcPixel);
- final int dstAlpha = dstColorModel.getAlpha(dstPixel);
- final int srcRed = srcColorModel.getRed(srcPixel);
- final int dstRed = dstColorModel.getRed(dstPixel);
- final int srcGreen = srcColorModel.getGreen(srcPixel);
- final int dstGreen = dstColorModel.getGreen(dstPixel);
- final int srcBlue = srcColorModel.getBlue(srcPixel);
- final int dstBlue = dstColorModel.getBlue(dstPixel);
- int rgb = blend(srcAlpha, srcRed, srcGreen, srcBlue, dstAlpha, dstRed, dstGreen, dstBlue);
-
- resPixel = dstColorModel.getDataElements(rgb, resPixel);
-
- dstOut.setDataElements(x, y, resPixel);
- }
- }
- }
-
- /**
- * The actual blending function for two colors.
- *
- * @param sA source alpha component (0-255)
- * @param sR source red component (0-255)
- * @param sG source green component (0-255)
- * @param sB source blue component (0-255)
- * @param dA destination alpha component (0-255)
- * @param dR destination red component (0-255)
- * @param dG destination green component (0-255)
- * @param dB destination blues component (0-255)
- * @return Combined color in single-integer ARGB format (see
- * {@link BlendComposite#combineComponents} and {@link #mixAlpha}
- * helper functions)
- */
- protected int blend(final int sA, final int sR, final int sG, final int sB, final int dA, final int dR, final int dG, final int dB) {
- return mixAlpha(sA, sR, sG, sB, dA, dR, dG, dB);
- }
-
- /**
- * Mix the new values with the original values taking the alpha value into
- * account.
- *
- * @param nA new alpha component (0-255)
- * @param nR new red component (0-255)
- * @param nG new green component (0-255)
- * @param nB new blue component (0-255)
- * @param dA old alpha component (0-255)
- * @param dR old red component (0-255)
- * @param dG old green component (0-255)
- * @param dB old blue component (0-255)
- * @return Combined color in single-integer ARGB format.
- */
- protected int mixAlpha(final int nA, final int nR, final int nG, final int nB, final int dA, final int dR, final int dG, final int dB) {
- int a = (int) (nA * alpha + dA * ialpha);
- int r = (int) (nR * alpha + dR * ialpha);
- int g = (int) (nG * alpha + dG * ialpha);
- int b = (int) (nB * alpha + dB * ialpha);
-
- return combineComponents(a, r, g, b);
- }
- }
-
- /**
- * Helper function that combines separate ARGB values into a single ARGB
- * integer.
- *
- * @param a alpha component (0-255)
- * @param r red component (0-255)
- * @param g green component (0-255)
- * @param b blue component (0-255)
- * @return Integer value in ARGB order.
- */
- protected static final int combineComponents(int a, int r, int g, int b) {
- return (a & 0xFF) << 24 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF);
- }
-
- /**
- * Blending context for a "lighten only" blending.
- *
- * @author Erich Schubert
- */
- class LightenBlendingContext extends BlendingContext {
- /**
- * Constructor.
- *
- * @param srcColorModel color model
- * @param dstColorModel color model
- * @param alpha Opacity value
- */
- protected LightenBlendingContext(ColorModel srcColorModel, ColorModel dstColorModel, double alpha) {
- super(srcColorModel, dstColorModel, alpha);
- }
-
- @Override
- protected int blend(final int sA, final int sR, final int sG, final int sB, final int dA, final int dR, final int dG, final int dB) {
- int a = Math.min(255, sA + dA - (sA * dA) / 255);
- int r = Math.max(sR, dR);
- int g = Math.max(sG, dG);
- int b = Math.max(sB, dB);
-
- return mixAlpha(a, r, g, b, dA, dR, dG, dB);
- }
- }
-
- /**
- * Blending context for a "darken only" blending.
- *
- * @author Erich Schubert
- */
- class DarkenBlendingContext extends BlendingContext {
- /**
- * Constructor.
- *
- * @param srcColorModel color model
- * @param dstColorModel color model
- * @param alpha Opacity value
- */
- protected DarkenBlendingContext(ColorModel srcColorModel, ColorModel dstColorModel, double alpha) {
- super(srcColorModel, dstColorModel, alpha);
- }
-
- @Override
- protected int blend(final int sA, final int sR, final int sG, final int sB, final int dA, final int dR, final int dG, final int dB) {
- int a = Math.min(255, sA + dA - (sA * dA) / 255);
- int r = Math.min(sR, dR);
- int g = Math.min(sG, dG);
- int b = Math.min(sB, dB);
-
- return mixAlpha(a, r, g, b, dA, dR, dG, dB);
- }
- }
-
- /**
- * Blending context for a "screen" blending.
- *
- * @author Erich Schubert
- */
- class ScreenBlendingContext extends BlendingContext {
- /**
- * Constructor.
- *
- * @param srcColorModel color model
- * @param dstColorModel color model
- * @param alpha Opacity value
- */
- protected ScreenBlendingContext(ColorModel srcColorModel, ColorModel dstColorModel, double alpha) {
- super(srcColorModel, dstColorModel, alpha);
- }
-
- @Override
- protected int blend(final int sA, final int sR, final int sG, final int sB, final int dA, final int dR, final int dG, final int dB) {
- int a = Math.min(255, sA + dA - (sA * dA) / 255);
- int r = 255 - ((255 - sR) * (255 - dR) >> 8);
- int g = 255 - ((255 - sG) * (255 - dG) >> 8);
- int b = 255 - ((255 - sB) * (255 - dB) >> 8);
-
- return mixAlpha(a, r, g, b, dA, dR, dG, dB);
- }
- }
-
- /**
- * Blending context for a "multiply" blending.
- *
- * @author Erich Schubert
- */
- class MultiplyBlendingContext extends BlendingContext {
- /**
- * Constructor.
- *
- * @param srcColorModel color model
- * @param dstColorModel color model
- * @param alpha Opacity value
- */
- protected MultiplyBlendingContext(ColorModel srcColorModel, ColorModel dstColorModel, double alpha) {
- super(srcColorModel, dstColorModel, alpha);
- }
-
- @Override
- protected int blend(final int sA, final int sR, final int sG, final int sB, final int dA, final int dR, final int dG, final int dB) {
- int a = Math.min(255, sA + dA - (sA * dA) / 255);
- int r = (sR * dR) >> 8;
- int g = (sG * dG) >> 8;
- int b = (sB * dB) >> 8;
-
- return mixAlpha(a, r, g, b, dA, dR, dG, dB);
- }
- }
-
- /**
- * Blending context for a "overlay" blending.
- *
- * @author Erich Schubert
- */
- class OverlayBlendingContext extends BlendingContext {
- /**
- * Constructor.
- *
- * @param srcColorModel color model
- * @param dstColorModel color model
- * @param alpha Opacity value
- */
- protected OverlayBlendingContext(ColorModel srcColorModel, ColorModel dstColorModel, double alpha) {
- super(srcColorModel, dstColorModel, alpha);
- }
-
- @Override
- protected int blend(final int sA, final int sR, final int sG, final int sB, final int dA, final int dR, final int dG, final int dB) {
- int a = Math.min(255, sA + dA - (sA * dA) / 255);
- int r = (dR < 128) ? (dR * sR >> 7) : (255 - ((255 - dR) * (255 - sR) >> 7));
- int g = (dG < 128) ? (dG * sG >> 7) : (255 - ((255 - dG) * (255 - sG) >> 7));
- int b = (dB < 128) ? (dB * sB >> 7) : (255 - ((255 - dB) * (255 - sB) >> 7));
-
- return mixAlpha(a, r, g, b, dA, dR, dG, dB);
- }
- }
-
- /**
- * Blending context for an "average" blending.
- *
- * @author Erich Schubert
- */
- class AverageBlendingContext extends BlendingContext {
- /**
- * Constructor.
- *
- * @param srcColorModel color model
- * @param dstColorModel color model
- * @param alpha Opacity value
- */
- protected AverageBlendingContext(ColorModel srcColorModel, ColorModel dstColorModel, double alpha) {
- super(srcColorModel, dstColorModel, alpha);
- }
-
- @Override
- protected int blend(final int sA, final int sR, final int sG, final int sB, final int dA, final int dR, final int dG, final int dB) {
- int a = Math.min(255, sA + dA - (sA * dA) / 255);
- int r = (sR + dR) >> 1;
- int g = (sG + dG) >> 1;
- int b = (sB + dB) >> 1;
-
- return mixAlpha(a, r, g, b, dA, dR, dG, dB);
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/images/ComputeColorHistogram.java b/src/de/lmu/ifi/dbs/elki/data/images/ComputeColorHistogram.java
deleted file mode 100644
index daa74726..00000000
--- a/src/de/lmu/ifi/dbs/elki/data/images/ComputeColorHistogram.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package de.lmu.ifi.dbs.elki.data.images;
-
-/*
- 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.File;
-import java.io.IOException;
-
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
-
-/**
- * Interface for color histogram implementations.
- *
- * @author Erich Schubert
- *
- * @apiviz.uses File
- */
-public interface ComputeColorHistogram extends Parameterizable {
- /**
- * Compute a color histogram given a file name.
- *
- * The mask file (which may be null) is expected to use >50% transparent or
- * black to mask pixels, Non-transparent white to keep pixels. Alpha values
- * are not used.
- *
- * @param file File name
- * @param mask Mask file (optional)
- * @return Color histogram
- * @throws IOException on file read errors.
- */
- public double[] computeColorHistogram(File file, File mask) throws IOException;
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/images/ComputeHSBColorHistogram.java b/src/de/lmu/ifi/dbs/elki/data/images/ComputeHSBColorHistogram.java
deleted file mode 100644
index 53dd6496..00000000
--- a/src/de/lmu/ifi/dbs/elki/data/images/ComputeHSBColorHistogram.java
+++ /dev/null
@@ -1,149 +0,0 @@
-package de.lmu.ifi.dbs.elki.data.images;
-
-/*
- 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.awt.Color;
-import java.util.List;
-
-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.constraints.CommonConstraints;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.ListSizeConstraint;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntListParameter;
-
-/**
- * Compute color histograms in a Hue-Saturation-Brightness model.
- *
- * @author Erich Schubert
- */
-public class ComputeHSBColorHistogram extends AbstractComputeColorHistogram {
- /**
- * Parameter that specifies the number of bins (per plane) to use.
- *
- * <p>
- * Key: {@code -rgbhist.bpp}
- * </p>
- */
- public static final OptionID BINSPERPLANE_ID = new OptionID("hsbhist.bpp", "Bins per plane for HSV/HSB histogram. This will result in bpp ** 3 bins.");
-
- /**
- * Number of bins in hue to use.
- */
- int quanth;
-
- /**
- * Number of bins in saturation to use.
- */
- int quants;
-
- /**
- * Number of bins in brightness to use.
- */
- int quantb;
-
- /**
- * Constructor.
- *
- * @param quanth Hue bins
- * @param quants Saturation bins
- * @param quantb Brightness bins
- */
- public ComputeHSBColorHistogram(int quanth, int quants, int quantb) {
- super();
- this.quanth = quanth;
- this.quants = quants;
- this.quantb = quantb;
- }
-
- @Override
- protected int getBinForColor(int rgb) {
- int r = (rgb & 0xFF0000) >> 16;
- int g = (rgb & 0x00FF00) >> 8;
- int b = (rgb & 0x0000FF);
-
- float[] hsbvals = Color.RGBtoHSB(r, g, b, null);
- // The values returned by RGBtoHSB are all in [0:1]
- int h = (int) Math.floor(quanth * hsbvals[0]);
- int s = (int) Math.floor(quants * hsbvals[1]);
- int v = (int) Math.floor(quantb * hsbvals[2]);
- // Guard against the value of 1.0
- if(h >= quanth) {
- h = quanth - 1;
- }
- if(s >= quants) {
- s = quants - 1;
- }
- if(v >= quantb) {
- v = quantb - 1;
- }
- return h * quants * quantb + s * quantb + v;
- }
-
- @Override
- protected int getNumBins() {
- return quanth * quants * quantb;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer extends AbstractParameterizer {
- int quanth = 0;
-
- int quants = 0;
-
- int quantb = 0;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- final IntListParameter param = new IntListParameter(BINSPERPLANE_ID);
- param.addConstraint(new ListSizeConstraint(3));
- param.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT_LIST);
-
- if(config.grab(param)) {
- List<Integer> quant = param.getValue();
- if(quant.size() != 3) {
- config.reportError(new WrongParameterValueException(param, "I need exactly three values for the bpp parameter."));
- }
- else {
- quanth = quant.get(0);
- quants = quant.get(1);
- quantb = quant.get(2);
- }
- }
- }
-
- @Override
- protected ComputeHSBColorHistogram makeInstance() {
- return new ComputeHSBColorHistogram(quanth, quants, quantb);
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveRGBColorHistogram.java b/src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveRGBColorHistogram.java
deleted file mode 100644
index 5c40262e..00000000
--- a/src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveRGBColorHistogram.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package de.lmu.ifi.dbs.elki.data.images;
-
-/*
- 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.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.IntParameter;
-
-/**
- * Compute a (rather naive) RGB color histogram.
- *
- * @author Erich Schubert
- */
-public class ComputeNaiveRGBColorHistogram extends AbstractComputeColorHistogram {
- /**
- * Parameter that specifies the number of bins (per plane) to use.
- *
- * <p>
- * Key: {@code -rgbhist.bpp}
- * </p>
- */
- public static final OptionID BINSPERPLANE_ID = new OptionID("rgbhist.bpp", "Bins per plane for RGB histogram. This will result in bpp ** 3 bins.");
-
- /**
- * Number of bins in each dimension to use.
- */
- int quant;
-
- /**
- * Constructor.
- *
- * @param quant Number of bins to use.
- */
- public ComputeNaiveRGBColorHistogram(int quant) {
- super();
- this.quant = quant;
- }
-
- @Override
- protected int getBinForColor(int rgb) {
- int r = (rgb & 0xFF0000) >> 16;
- int g = (rgb & 0x00FF00) >> 8;
- int b = (rgb & 0x0000FF);
- r = (int) Math.floor(quant * r / 256.);
- g = (int) Math.floor(quant * g / 256.);
- b = (int) Math.floor(quant * b / 256.);
- return r * quant * quant + g * quant + b;
- }
-
- @Override
- protected int getNumBins() {
- return quant * quant * quant;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer extends AbstractParameterizer {
- protected int quant = 0;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- final IntParameter param = new IntParameter(BINSPERPLANE_ID);
- if(config.grab(param)) {
- quant = param.getValue();
- }
- }
-
- @Override
- protected ComputeNaiveRGBColorHistogram makeInstance() {
- return new ComputeNaiveRGBColorHistogram(quant);
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/images/ImageUtil.java b/src/de/lmu/ifi/dbs/elki/data/images/ImageUtil.java
deleted file mode 100644
index 06363625..00000000
--- a/src/de/lmu/ifi/dbs/elki/data/images/ImageUtil.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package de.lmu.ifi.dbs.elki.data.images;
-
-/*
- 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.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-import java.util.Iterator;
-
-import javax.imageio.ImageIO;
-import javax.imageio.ImageReader;
-import javax.imageio.stream.ImageInputStream;
-
-/**
- * Class with generic image handling utility functions.
- *
- * @author Erich Schubert
- *
- * @apiviz.has BufferedImage
- * @apiviz.uses File
- */
-public final class ImageUtil {
- /**
- * Load an image from a file using ImageIO.
- *
- * @param file File name
- * @return Image
- * @throws IOException thrown on IO errors
- */
- public static BufferedImage loadImage(File file) throws IOException {
- ImageInputStream is = ImageIO.createImageInputStream(file);
- Iterator<ImageReader> iter = ImageIO.getImageReaders(is);
-
- if(!iter.hasNext()) {
- throw new IOException("Unsupported file format.");
- }
- ImageReader imageReader = iter.next();
- imageReader.setInput(is);
- return imageReader.read(0);
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/BaseModel.java b/src/de/lmu/ifi/dbs/elki/data/model/AbstractModel.java
index 98fa0567..c756cdb0 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/BaseModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/AbstractModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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,20 +30,21 @@ import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
*
* @author Erich Schubert
*/
-public abstract class BaseModel implements Model {
+public abstract class AbstractModel implements Model {
/**
- * Implement writeToText as per {@link de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable} interface.
- * However BaseModel is not given the interface directly, since
- * it is meant as signal to make Models printable.
+ * Implement writeToText as per
+ * {@link de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable} interface.
+ * However BaseModel is not given the interface directly, since it is meant as
+ * signal to make Models printable.
*
* @param out Output steam
* @param label Optional label to prefix
*/
// actually @Override, for TextWriteable.
public void writeToText(TextWriterStream out, String label) {
- if (label != null) {
+ if(label != null) {
out.commentPrintLn(label);
}
- out.commentPrintLn(TextWriterStream.SER_MARKER+" " + BaseModel.class.getName());
+ out.commentPrintLn("Model class: " + getClass().getName());
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/BiclusterModel.java b/src/de/lmu/ifi/dbs/elki/data/model/BiclusterModel.java
index d3be1b66..05b2d210 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/BiclusterModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/BiclusterModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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/data/model/BiclusterWithInversionsModel.java b/src/de/lmu/ifi/dbs/elki/data/model/BiclusterWithInversionsModel.java
index 5f4c1bba..e20b8312 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/BiclusterWithInversionsModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/BiclusterWithInversionsModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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/data/model/ClusterModel.java b/src/de/lmu/ifi/dbs/elki/data/model/ClusterModel.java
index eacab5bc..e199b82c 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/ClusterModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/ClusterModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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,7 +32,7 @@ package de.lmu.ifi.dbs.elki.data.model;
*
* @apiviz.landmark
*/
-public final class ClusterModel extends BaseModel {
+public final class ClusterModel extends AbstractModel {
/**
* Static cluster model that can be shared for all clusters (since the object
* doesn't include meta information.
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/CoreObjectsModel.java b/src/de/lmu/ifi/dbs/elki/data/model/CoreObjectsModel.java
index 4a79d350..f8a75794 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/CoreObjectsModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/CoreObjectsModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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,7 +31,7 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
*
* @author Erich Schubert
*/
-public class CoreObjectsModel extends BaseModel {
+public class CoreObjectsModel extends AbstractModel {
/**
* Objects that are part of the cluster core.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/CorrelationAnalysisSolution.java b/src/de/lmu/ifi/dbs/elki/data/model/CorrelationAnalysisSolution.java
index 364fc3dc..6945cc7c 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/CorrelationAnalysisSolution.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/CorrelationAnalysisSolution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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
@@ -50,7 +50,7 @@ import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
*
* @param <V> the type of NumberVector handled by this Result
*/
-public class CorrelationAnalysisSolution<V extends NumberVector<?>> implements TextWriteable, Result, Model {
+public class CorrelationAnalysisSolution<V extends NumberVector> implements TextWriteable, Result, Model {
/**
* Stores the solution equations.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/CorrelationModel.java b/src/de/lmu/ifi/dbs/elki/data/model/CorrelationModel.java
index 6cfa5137..34a6c108 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/CorrelationModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/CorrelationModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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
@@ -38,7 +38,7 @@ import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
*
* @param <V> Vector type
*/
-public class CorrelationModel<V extends FeatureVector<?>> extends BaseModel implements TextWriteable {
+public class CorrelationModel<V extends FeatureVector<?>> extends AbstractModel implements TextWriteable {
/**
* The computed PCA result of this cluster.
*/
@@ -104,7 +104,7 @@ public class CorrelationModel<V extends FeatureVector<?>> extends BaseModel impl
*/
@Override
public void writeToText(TextWriterStream out, String label) {
- out.commentPrintLn(TextWriterStream.SER_MARKER + " " + CorrelationModel.class.getName());
+ super.writeToText(out, label);
out.commentPrintLn("Centroid: " + out.normalizationRestore(getCentroid()).toString());
out.commentPrintLn("Strong Eigenvectors:");
String strong = getPCAResult().getStrongEigenvectors().toString();
@@ -118,6 +118,6 @@ public class CorrelationModel<V extends FeatureVector<?>> extends BaseModel impl
weak = weak.substring(0, weak.length() - 1);
}
out.commentPrintLn(weak);
- out.commentPrintLn("Eigenvalues: " + FormatUtil.format(getPCAResult().getEigenvalues(), " ", 2));
+ out.commentPrintLn("Eigenvalues: " + FormatUtil.format(getPCAResult().getEigenvalues(), " ", FormatUtil.NF2));
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/DendrogramModel.java b/src/de/lmu/ifi/dbs/elki/data/model/DendrogramModel.java
index ac1c53f0..ba89a031 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/DendrogramModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/DendrogramModel.java
@@ -1,28 +1,28 @@
package de.lmu.ifi.dbs.elki.data.model;
-/*
-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.distance.distancevalue.Distance;
+/*
+ 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.result.textwriter.TextWriteable;
import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
@@ -32,18 +32,18 @@ import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
* @author Elke Achtert
*/
// TODO: comments
-public class DendrogramModel<D extends Distance<D>> extends BaseModel {
+public class DendrogramModel extends AbstractModel {
/**
* Distance to child cluster
*/
- private D distance;
+ private double distance;
/**
* Constructor.
- *
+ *
* @param distance Distance to child cluster.
*/
- public DendrogramModel(D distance) {
+ public DendrogramModel(double distance) {
super();
this.distance = distance;
}
@@ -51,7 +51,7 @@ public class DendrogramModel<D extends Distance<D>> extends BaseModel {
/**
* @return the distance
*/
- public D getDistance() {
+ public double getDistance() {
return distance;
}
@@ -61,11 +61,11 @@ public class DendrogramModel<D extends Distance<D>> extends BaseModel {
@Override
public void writeToText(TextWriterStream out, String label) {
super.writeToText(out, label);
- out.commentPrintLn("Distance to children: " + (distance != null ? distance.toString() : "null"));
+ out.commentPrintLn("Distance to children: " + distance);
}
@Override
public String toString() {
- return "Distance to children: " + (distance != null ? distance.toString() : "null");
+ return "Distance to children: " + distance;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/DimensionModel.java b/src/de/lmu/ifi/dbs/elki/data/model/DimensionModel.java
index 36b5653e..a6691ad9 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/DimensionModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/DimensionModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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,7 +31,7 @@ import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
*
* @author Erich Schubert
*/
-public class DimensionModel extends BaseModel implements TextWriteable {
+public class DimensionModel extends AbstractModel implements TextWriteable {
/**
* Number of dimensions
*/
@@ -41,7 +41,7 @@ public class DimensionModel extends BaseModel implements TextWriteable {
* Constructor
* @param dimension number of dimensions
*/
- public DimensionModel(Integer dimension) {
+ public DimensionModel(int dimension) {
super();
this.dimension = dimension;
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/EMModel.java b/src/de/lmu/ifi/dbs/elki/data/model/EMModel.java
index e83f4c72..d0e13191 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/EMModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/EMModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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,8 @@ package de.lmu.ifi.dbs.elki.data.model;
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.math.linearalgebra.Matrix;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
/**
@@ -32,10 +32,8 @@ import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
* Matrix.
*
* @author Erich Schubert
- *
- * @param <V> Vector type
*/
-public class EMModel<V extends FeatureVector<?>> extends MeanModel<V> {
+public class EMModel extends MeanModel {
/**
* Cluster covariance matrix
*/
@@ -47,7 +45,7 @@ public class EMModel<V extends FeatureVector<?>> extends MeanModel<V> {
* @param mean Mean vector
* @param covarianceMatrix Covariance matrix
*/
- public EMModel(V mean, Matrix covarianceMatrix) {
+ public EMModel(Vector mean, Matrix covarianceMatrix) {
super(mean);
this.covarianceMatrix = covarianceMatrix;
}
@@ -55,7 +53,6 @@ public class EMModel<V extends FeatureVector<?>> extends MeanModel<V> {
@Override
public void writeToText(TextWriterStream out, String label) {
super.writeToText(out, label);
- out.commentPrintLn("Mean: " + out.normalizationRestore(this.getMean()).toString());
out.commentPrintLn("Covariance Matrix: " + this.covarianceMatrix.toString());
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/KMeansModel.java b/src/de/lmu/ifi/dbs/elki/data/model/KMeansModel.java
index a1867695..5641c893 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/KMeansModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/KMeansModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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,23 +22,37 @@ package de.lmu.ifi.dbs.elki.data.model;
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.math.linearalgebra.Vector;
/**
* Trivial subclass of the {@link MeanModel} that indicates the clustering to be
* produced by k-means (so the Voronoi cell visualization is sensible).
*
* @author Erich Schubert
- *
- * @param <V> Vector type.
*/
-public class KMeansModel<V extends NumberVector<?>> extends MeanModel<V> {
+public class KMeansModel extends MeanModel {
+ /**
+ * Variance sum.
+ */
+ double varsum;
+
/**
* Constructor with mean.
*
* @param mean Mean vector.
+ * @param varsum Variance sum.
*/
- public KMeansModel(V mean) {
+ public KMeansModel(Vector mean, double varsum) {
super(mean);
+ this.varsum = varsum;
+ }
+
+ /**
+ * Get the variance contribution of the cluster (sum of variances)
+ *
+ * @return Sum of in-cluster variance
+ */
+ public double getVarianceContribution() {
+ return varsum;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/LinearEquationModel.java b/src/de/lmu/ifi/dbs/elki/data/model/LinearEquationModel.java
index cff9cc42..ba6ab245 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/LinearEquationModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/LinearEquationModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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,7 +34,7 @@ import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
*
* @apiviz.composedOf LinearEquationSystem
*/
-public class LinearEquationModel extends BaseModel implements TextWriteable {
+public class LinearEquationModel extends AbstractModel implements TextWriteable {
/**
* Equation system
*/
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/MeanModel.java b/src/de/lmu/ifi/dbs/elki/data/model/MeanModel.java
index 84896d06..487f639d 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/MeanModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/MeanModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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,56 +23,33 @@ package de.lmu.ifi.dbs.elki.data.model;
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.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable;
-import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
/**
* Cluster model that stores a mean for the cluster.
*
* @author Erich Schubert
- *
- * @param <V> Vector type
*/
-public class MeanModel<V extends FeatureVector<?>> extends BaseModel implements TextWriteable{
- /**
- * Cluster mean
- */
- private V mean;
-
+public class MeanModel extends PrototypeModel<Vector> implements TextWriteable {
/**
* Constructor with mean
*
* @param mean Cluster mean
*/
- public MeanModel(V mean) {
- super();
- this.mean = mean;
+ public MeanModel(Vector mean) {
+ super(mean);
}
/**
* @return mean
*/
- public V getMean() {
- return mean;
- }
-
- /**
- * @param mean Mean vector
- */
- public void setMean(V mean) {
- this.mean = mean;
+ public Vector getMean() {
+ return prototype;
}
- /**
- * Implementation of {@link TextWriteable} interface.
- */
@Override
- public void writeToText(TextWriterStream out, String label) {
- if(label != null) {
- out.commentPrintLn(label);
- }
- out.commentPrintLn(TextWriterStream.SER_MARKER + " " + getClass().getName());
- out.commentPrintLn("Cluster Mean: " + mean.toString());
+ protected String getPrototypeType() {
+ return "Mean";
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/MedoidModel.java b/src/de/lmu/ifi/dbs/elki/data/model/MedoidModel.java
index 6df2356d..5510041d 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/MedoidModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/MedoidModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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,52 +25,31 @@ package de.lmu.ifi.dbs.elki.data.model;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable;
-import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
/**
* Cluster model that stores a mean for the cluster.
*
* @author Erich Schubert
*/
-public class MedoidModel extends BaseModel implements TextWriteable {
- /**
- * Cluster medoid
- */
- private DBID medoid;
-
+public class MedoidModel extends PrototypeModel<DBID> implements TextWriteable {
/**
* Constructor with medoid
*
* @param medoid Cluster medoid
*/
public MedoidModel(DBID medoid) {
- super();
- this.medoid = medoid;
+ super(medoid);
}
/**
* @return medoid
*/
public DBID getMedoid() {
- return medoid;
+ return prototype;
}
- /**
- * @param medoid Medoid object
- */
- public void setMedoid(DBID medoid) {
- this.medoid = medoid;
- }
-
- /**
- * Implementation of {@link TextWriteable} interface.
- */
@Override
- public void writeToText(TextWriterStream out, String label) {
- if(label != null) {
- out.commentPrintLn(label);
- }
- out.commentPrintLn(TextWriterStream.SER_MARKER + " " + getClass().getName());
- out.commentPrintLn("Cluster Medoid: " + medoid.toString());
+ protected String getPrototypeType() {
+ return "Medoid";
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/Model.java b/src/de/lmu/ifi/dbs/elki/data/model/Model.java
index fb2d533f..6225ecda 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/Model.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/Model.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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/data/model/ModelUtil.java b/src/de/lmu/ifi/dbs/elki/data/model/ModelUtil.java
new file mode 100644
index 00000000..5cd9abce
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/data/model/ModelUtil.java
@@ -0,0 +1,113 @@
+package de.lmu.ifi.dbs.elki.data.model;
+
+/*
+ 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.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;
+
+/**
+ * Utility classes for dealing with cluster models.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.uses Model
+ * @apiviz.uses NumberVector
+ */
+public final class ModelUtil {
+ /**
+ * Get (and convert!) the representative vector for a cluster model.
+ *
+ * <b>Only representative-based models are supported!</b>
+ *
+ * {@code null} is returned when the model is not supported!
+ *
+ * @param model Model
+ * @param relation Data relation (for representatives specified per DBID)
+ * @param factory Vector factory, for type conversion.
+ * @return Vector of type V, {@code null} if not supported.
+ * @param <V> desired vector type
+ */
+ @SuppressWarnings("unchecked")
+ public static <V extends NumberVector> V getPrototype(Model model, Relation<? extends V> relation, NumberVector.Factory<V> factory) {
+ // Mean model contains a numeric Vector
+ if(model instanceof MeanModel) {
+ final Vector p = ((MeanModel) model).getMean();
+ if(factory.getRestrictionClass().isInstance(p)) {
+ return (V) p;
+ }
+ return factory.newNumberVector(p.getArrayRef());
+ }
+ // Handle medoid models
+ if(model instanceof MedoidModel) {
+ NumberVector p = relation.get(((MedoidModel) model).getMedoid());
+ if(factory.getRestrictionClass().isInstance(p)) {
+ return (V) p;
+ }
+ return factory.newNumberVector(p, ArrayLikeUtil.NUMBERVECTORADAPTER);
+ }
+ if(model instanceof PrototypeModel) {
+ Object p = ((PrototypeModel<?>) model).getPrototype();
+ if(factory.getRestrictionClass().isInstance(p)) {
+ return (V) p;
+ }
+ if(p instanceof NumberVector) {
+ return factory.newNumberVector((NumberVector) p, ArrayLikeUtil.NUMBERVECTORADAPTER);
+ }
+ return null; // Inconvertible
+ }
+ return null;
+ }
+
+ /**
+ * Get (and convert!) the representative vector for a cluster model.
+ *
+ * <b>Only representative-based models are supported!</b>
+ *
+ * {@code null} is returned when the model is not supported!
+ *
+ * @param model Model
+ * @param relation Data relation (for representatives specified per DBID)
+ * @return Some {@link NumberVector}, {@code null} if not supported.
+ */
+ public static NumberVector getPrototype(Model model, Relation<? extends NumberVector> relation) {
+ // Mean model contains a numeric Vector
+ if(model instanceof MeanModel) {
+ return ((MeanModel) model).getMean();
+ }
+ // Handle medoid models
+ if(model instanceof MedoidModel) {
+ return relation.get(((MedoidModel) model).getMedoid());
+ }
+ if(model instanceof PrototypeModel) {
+ Object p = ((PrototypeModel<?>) model).getPrototype();
+ if(p instanceof NumberVector) {
+ return (NumberVector) p;
+ }
+ return null; // Inconvertible
+ }
+ return null;
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/OPTICSModel.java b/src/de/lmu/ifi/dbs/elki/data/model/OPTICSModel.java
index bf942ff5..cace376b 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/OPTICSModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/OPTICSModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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 @@ package de.lmu.ifi.dbs.elki.data.model;
*
* @author Erich Schubert
*/
-public class OPTICSModel extends BaseModel {
+public class OPTICSModel extends AbstractModel {
/**
* Start index
*/
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/PrototypeModel.java b/src/de/lmu/ifi/dbs/elki/data/model/PrototypeModel.java
new file mode 100644
index 00000000..e7b57c85
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/data/model/PrototypeModel.java
@@ -0,0 +1,74 @@
+package de.lmu.ifi.dbs.elki.data.model;
+
+/*
+ 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.result.textwriter.TextWriteable;
+import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
+
+/**
+ * Cluster model that stores a prototype for each cluster.
+ *
+ * @author Erich Schubert
+ */
+public class PrototypeModel<V> extends AbstractModel implements TextWriteable {
+ /**
+ * Cluster prototype
+ */
+ protected V prototype;
+
+ /**
+ * Constructor with prototype
+ *
+ * @param prototype Cluster prototype
+ */
+ public PrototypeModel(V prototype) {
+ super();
+ this.prototype = prototype;
+ }
+
+ /**
+ * @return mean
+ */
+ public V getPrototype() {
+ return prototype;
+ }
+
+ /**
+ * Implementation of {@link TextWriteable} interface.
+ */
+ @Override
+ public void writeToText(TextWriterStream out, String label) {
+ super.writeToText(out, label);
+ out.commentPrintLn("Cluster " + getPrototypeType() + ": " + prototype.toString());
+ }
+
+ /**
+ * Type of prototype (Median, Mean, ...) for printing.
+ *
+ * @return String name
+ */
+ protected String getPrototypeType() {
+ return "Prototype";
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/SubspaceModel.java b/src/de/lmu/ifi/dbs/elki/data/model/SubspaceModel.java
index 1cace130..6c5144aa 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/SubspaceModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/SubspaceModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.model;
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,10 +23,8 @@ package de.lmu.ifi.dbs.elki.data.model;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.BitSet;
-
-import de.lmu.ifi.dbs.elki.data.FeatureVector;
import de.lmu.ifi.dbs.elki.data.Subspace;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable;
import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
@@ -37,10 +35,8 @@ import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
* @author Elke Achtert
*
* @apiviz.composedOf Subspace
- *
- * @param <V> the type of FeatureVector the subspace contains
*/
-public class SubspaceModel<V extends FeatureVector<?>> extends MeanModel<V> implements TextWriteable {
+public class SubspaceModel extends MeanModel implements TextWriteable {
/**
* The subspace of the cluster.
*/
@@ -53,7 +49,7 @@ public class SubspaceModel<V extends FeatureVector<?>> extends MeanModel<V> impl
* @param subspace the subspace of the cluster
* @param mean the cluster mean
*/
- public SubspaceModel(Subspace subspace, V mean) {
+ public SubspaceModel(Subspace subspace, Vector mean) {
super(mean);
this.subspace = subspace;
}
@@ -73,7 +69,7 @@ public class SubspaceModel<V extends FeatureVector<?>> extends MeanModel<V> impl
*
* @return the dimensions of the subspace
*/
- public BitSet getDimensions() {
+ public long[] getDimensions() {
return subspace.getDimensions();
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/package-info.java b/src/de/lmu/ifi/dbs/elki/data/model/package-info.java
index a7789826..7a170018 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/package-info.java
@@ -3,27 +3,28 @@
*
* @apiviz.exclude result.textwriter
* @apiviz.exclude visualization
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.algorithm\..*
*/
/*
-This file is part of ELKI:
-Environment for Developing KDD-Applications Supported by Index-Structures
+ 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
+ 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 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.
+ 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/>.
-*/
+ 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.data.model; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/package-info.java b/src/de/lmu/ifi/dbs/elki/data/package-info.java
index 73d500ea..2ea6db71 100644
--- a/src/de/lmu/ifi/dbs/elki/data/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/data/package-info.java
@@ -1,36 +1,39 @@
/**
* <p>Basic classes for different data types, database object types and label types.</p>
*
- * @apiviz.exclude de.lmu.ifi.dbs.elki.algorithm.*
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.(algorithm|evaluation).*
* @apiviz.exclude de.lmu.ifi.dbs.elki.result.textwriter.*
* @apiviz.exclude de.lmu.ifi.dbs.elki.visualization.*
- * @apiviz.exclude de.lmu.ifi.dbs.elki.datasource.parser.*
- * @apiviz.exclude de.lmu.ifi.dbs.elki.datasource.filter.*
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.datasource.(parser|filter).*
* @apiviz.exclude de.lmu.ifi.dbs.elki.math.linearalgebra.*
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.data.model.ModelUtil
* @apiviz.exclude java.io.*
* @apiviz.exclude java.util.*
* @apiviz.exclude java.lang.*
+ * @apiviz.exclude .*\.Factory$
+ * @apiviz.exclude ByteBufferSerializer$
*/
/*
-This file is part of ELKI:
-Environment for Developing KDD-Applications Supported by Index-Structures
+ 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
+ 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 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.
+ 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/>.
-*/
+ 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.data;
+
diff --git a/src/de/lmu/ifi/dbs/elki/data/projection/FeatureSelection.java b/src/de/lmu/ifi/dbs/elki/data/projection/FeatureSelection.java
index f6fb6a6a..b48eda9d 100644
--- a/src/de/lmu/ifi/dbs/elki/data/projection/FeatureSelection.java
+++ b/src/de/lmu/ifi/dbs/elki/data/projection/FeatureSelection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.projection;
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
@@ -45,6 +45,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntListParameter;
*
* @author Erich Schubert
*
+ * @apiviz.uses FeatureVector
+ *
* @param <V> Vector type
* @param <F> Feature type
*/
@@ -125,7 +127,7 @@ public class FeatureSelection<V extends FeatureVector<F>, F> implements Projecti
public TypeInformation getInputDataTypeInformation() {
@SuppressWarnings("unchecked")
final Class<V> cls = (Class<V>) factory.getRestrictionClass();
- return new VectorTypeInformation<>(cls, mindim, Integer.MAX_VALUE);
+ return VectorTypeInformation.typeRequest(cls, mindim, Integer.MAX_VALUE);
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/data/projection/LatLngToECEFProjection.java b/src/de/lmu/ifi/dbs/elki/data/projection/LatLngToECEFProjection.java
index ee7ba931..75ea237f 100644
--- a/src/de/lmu/ifi/dbs/elki/data/projection/LatLngToECEFProjection.java
+++ b/src/de/lmu/ifi/dbs/elki/data/projection/LatLngToECEFProjection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.projection;
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,6 +24,7 @@ package de.lmu.ifi.dbs.elki.data.projection;
*/
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.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.math.geodesy.EarthModel;
import de.lmu.ifi.dbs.elki.math.geodesy.SphericalVincentyEarthModel;
@@ -38,14 +39,15 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @author Erich Schubert
*
* @apiviz.composedOf EarthModel
+ * @apiviz.uses NumberVector
*
* @param <V> Vector type
*/
-public class LatLngToECEFProjection<V extends NumberVector<?>> implements Projection<V, V> {
+public class LatLngToECEFProjection<V extends NumberVector> implements Projection<V, V> {
/**
* Vector factory to use.
*/
- private NumberVector.Factory<V, ?> factory;
+ private NumberVector.Factory<V> factory;
/**
* Earth model to use.
@@ -62,10 +64,11 @@ public class LatLngToECEFProjection<V extends NumberVector<?>> implements Projec
this.model = model;
}
+ @SuppressWarnings("unchecked")
@Override
public void initialize(SimpleTypeInformation<V> in) {
final VectorFieldTypeInformation<V> vin = (VectorFieldTypeInformation<V>) in;
- factory = (NumberVector.Factory<V, ?>) vin.getFactory();
+ factory = (NumberVector.Factory<V>) vin.getFactory();
}
@Override
@@ -75,7 +78,7 @@ public class LatLngToECEFProjection<V extends NumberVector<?>> implements Projec
@Override
public SimpleTypeInformation<? super V> getInputDataTypeInformation() {
- return new VectorFieldTypeInformation<>(NumberVector.class, 2, 2);
+ return TypeUtil.NUMBER_VECTOR_FIELD_2D;
}
@Override
@@ -100,13 +103,13 @@ public class LatLngToECEFProjection<V extends NumberVector<?>> implements Projec
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);
}
}
@Override
- protected LatLngToECEFProjection<NumberVector<?>> makeInstance() {
+ protected LatLngToECEFProjection<NumberVector> makeInstance() {
return new LatLngToECEFProjection<>(model);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/projection/LngLatToECEFProjection.java b/src/de/lmu/ifi/dbs/elki/data/projection/LngLatToECEFProjection.java
index d6769c9c..9d5e118f 100644
--- a/src/de/lmu/ifi/dbs/elki/data/projection/LngLatToECEFProjection.java
+++ b/src/de/lmu/ifi/dbs/elki/data/projection/LngLatToECEFProjection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.projection;
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,6 +24,7 @@ package de.lmu.ifi.dbs.elki.data.projection;
*/
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.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.math.geodesy.EarthModel;
import de.lmu.ifi.dbs.elki.math.geodesy.SphericalVincentyEarthModel;
@@ -38,10 +39,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @author Erich Schubert
*
* @apiviz.composedOf EarthModel
+ * @apiviz.uses NumberVector
*
* @param <V> Vector type
*/
-public class LngLatToECEFProjection<V extends NumberVector<?>> implements Projection<V, V> {
+public class LngLatToECEFProjection<V extends NumberVector> implements Projection<V, V> {
/**
* Earth model to use
*/
@@ -50,7 +52,7 @@ public class LngLatToECEFProjection<V extends NumberVector<?>> implements Projec
/**
* Vector factory to use.
*/
- private NumberVector.Factory<V, ?> factory;
+ private NumberVector.Factory<V> factory;
/**
* Constructor.
@@ -62,10 +64,11 @@ public class LngLatToECEFProjection<V extends NumberVector<?>> implements Projec
this.model = model;
}
+ @SuppressWarnings("unchecked")
@Override
public void initialize(SimpleTypeInformation<V> in) {
final VectorFieldTypeInformation<V> vin = (VectorFieldTypeInformation<V>) in;
- factory = (NumberVector.Factory<V, ?>) vin.getFactory();
+ factory = (NumberVector.Factory<V>) vin.getFactory();
}
@Override
@@ -75,7 +78,7 @@ public class LngLatToECEFProjection<V extends NumberVector<?>> implements Projec
@Override
public SimpleTypeInformation<? super V> getInputDataTypeInformation() {
- return new VectorFieldTypeInformation<>(NumberVector.class, 2, 2);
+ return TypeUtil.NUMBER_VECTOR_FIELD_2D;
}
@Override
@@ -100,13 +103,13 @@ public class LngLatToECEFProjection<V extends NumberVector<?>> implements Projec
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);
}
}
@Override
- protected LngLatToECEFProjection<NumberVector<?>> makeInstance() {
+ protected LngLatToECEFProjection<NumberVector> makeInstance() {
return new LngLatToECEFProjection<>(model);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/projection/NumericalFeatureSelection.java b/src/de/lmu/ifi/dbs/elki/data/projection/NumericalFeatureSelection.java
index 158866c1..56831b96 100644
--- a/src/de/lmu/ifi/dbs/elki/data/projection/NumericalFeatureSelection.java
+++ b/src/de/lmu/ifi/dbs/elki/data/projection/NumericalFeatureSelection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.projection;
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
@@ -44,9 +44,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntListParameter;
*
* @author Erich Schubert
*
+ * @apiviz.uses NumberVector
+ *
* @param <V> Vector type
*/
-public class NumericalFeatureSelection<V extends NumberVector<?>> implements Projection<V, V> {
+public class NumericalFeatureSelection<V extends NumberVector> implements Projection<V, V> {
/**
* Minimum dimensionality required for projection.
*/
@@ -55,7 +57,7 @@ public class NumericalFeatureSelection<V extends NumberVector<?>> implements Pro
/**
* Object factory.
*/
- private NumberVector.Factory<V, ?> factory;
+ private NumberVector.Factory<V> factory;
/**
* Output dimensionality.
@@ -84,10 +86,11 @@ public class NumericalFeatureSelection<V extends NumberVector<?>> implements Pro
this.mindim = mind;
}
+ @SuppressWarnings("unchecked")
@Override
public void initialize(SimpleTypeInformation<V> in) {
final VectorFieldTypeInformation<V> vin = (VectorFieldTypeInformation<V>) in;
- factory = (NumberVector.Factory<V, ?>) vin.getFactory();
+ factory = (NumberVector.Factory<V>) vin.getFactory();
if(vin.getDimensionality() < mindim) {
throw new AbortException("Data does not have enough dimensions for this projection!");
}
@@ -109,7 +112,7 @@ public class NumericalFeatureSelection<V extends NumberVector<?>> implements Pro
@Override
public TypeInformation getInputDataTypeInformation() {
- return new VectorTypeInformation<>(NumberVector.class, mindim, Integer.MAX_VALUE);
+ return VectorTypeInformation.typeRequest(NumberVector.class, mindim, Integer.MAX_VALUE);
}
/**
@@ -119,7 +122,7 @@ public class NumericalFeatureSelection<V extends NumberVector<?>> implements Pro
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* Dimensions to select.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/data/projection/Projection.java b/src/de/lmu/ifi/dbs/elki/data/projection/Projection.java
index b1e458e4..29394aeb 100644
--- a/src/de/lmu/ifi/dbs/elki/data/projection/Projection.java
+++ b/src/de/lmu/ifi/dbs/elki/data/projection/Projection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.projection;
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.data.projection;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Projection interface.
@@ -35,7 +34,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
* @param <IN> Input data type
* @param <OUT> Output data type
*/
-public interface Projection<IN, OUT> extends Parameterizable {
+public interface Projection<IN, OUT> {
/**
* Initialize
*
diff --git a/src/de/lmu/ifi/dbs/elki/data/projection/RandomProjection.java b/src/de/lmu/ifi/dbs/elki/data/projection/RandomProjection.java
index 7400a3f0..35eb7071 100644
--- a/src/de/lmu/ifi/dbs/elki/data/projection/RandomProjection.java
+++ b/src/de/lmu/ifi/dbs/elki/data/projection/RandomProjection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.projection;
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
@@ -47,9 +47,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
+ * @apiviz.uses NumberVector
+ *
* @param <V> Vector type
*/
-public class RandomProjection<V extends NumberVector<?>> implements Projection<V, V> {
+public class RandomProjection<V extends NumberVector> implements Projection<V, V> {
/**
* Class logger.
*/
@@ -58,7 +60,7 @@ public class RandomProjection<V extends NumberVector<?>> implements Projection<V
/**
* Vector factory.
*/
- private NumberVector.Factory<V, ?> factory = null;
+ private NumberVector.Factory<V> factory = null;
/**
* Output dimensionality.
@@ -87,10 +89,11 @@ public class RandomProjection<V extends NumberVector<?>> implements Projection<V
this.family = family;
}
+ @SuppressWarnings("unchecked")
@Override
public void initialize(SimpleTypeInformation<V> in) {
final VectorFieldTypeInformation<V> vin = (VectorFieldTypeInformation<V>) in;
- factory = (NumberVector.Factory<V, ?>) vin.getFactory();
+ factory = (NumberVector.Factory<V>) vin.getFactory();
int inputdim = vin.getDimensionality();
projection = family.generateProjection(inputdim, dimensionality);
@@ -159,7 +162,7 @@ public class RandomProjection<V extends NumberVector<?>> implements Projection<V
}
@Override
- protected RandomProjection<NumberVector<?>> makeInstance() {
+ protected RandomProjection<NumberVector> makeInstance() {
return new RandomProjection<>(dimensionality, family);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/projection/package-info.java b/src/de/lmu/ifi/dbs/elki/data/projection/package-info.java
index 2fe8b010..1db806d2 100644
--- a/src/de/lmu/ifi/dbs/elki/data/projection/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/data/projection/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/data/spatial/Polygon.java b/src/de/lmu/ifi/dbs/elki/data/spatial/Polygon.java
index eef19e82..6166e0ce 100644
--- a/src/de/lmu/ifi/dbs/elki/data/spatial/Polygon.java
+++ b/src/de/lmu/ifi/dbs/elki/data/spatial/Polygon.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.spatial;
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/data/spatial/PolygonsObject.java b/src/de/lmu/ifi/dbs/elki/data/spatial/PolygonsObject.java
index dbda87bd..cf1ff3d0 100644
--- a/src/de/lmu/ifi/dbs/elki/data/spatial/PolygonsObject.java
+++ b/src/de/lmu/ifi/dbs/elki/data/spatial/PolygonsObject.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.spatial;
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/data/spatial/SpatialComparable.java b/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialComparable.java
index 0783a748..9da23fce 100644
--- a/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialComparable.java
+++ b/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialComparable.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.spatial;
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/data/spatial/SpatialSingleMaxComparator.java b/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialSingleMaxComparator.java
index 8e491b97..cbf52c3b 100644
--- a/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialSingleMaxComparator.java
+++ b/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialSingleMaxComparator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.spatial;
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/data/spatial/SpatialSingleMeanComparator.java b/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialSingleMeanComparator.java
index ec8f4a38..30261ce4 100644
--- a/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialSingleMeanComparator.java
+++ b/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialSingleMeanComparator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.spatial;
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/data/spatial/SpatialSingleMinComparator.java b/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialSingleMinComparator.java
index 8156cbd1..4827a669 100644
--- a/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialSingleMinComparator.java
+++ b/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialSingleMinComparator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.spatial;
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/data/spatial/SpatialUtil.java b/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialUtil.java
index 50ea7243..873e2e30 100644
--- a/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/data/spatial/SpatialUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.spatial;
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.data.spatial;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.data.HyperBoundingBox;
import de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
@@ -35,7 +34,7 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
* @apiviz.landmark
*
* @apiviz.uses SpatialComparable oneway - - «compares»
- * @apiviz.has HyperBoundingBox oneway - - «creates»
+ * @apiviz.has ModifiableHyperBoundingBox oneway - - «creates»
*/
// IMPORTANT NOTE: when editing this class, bear in mind that the dimension
// numbers start at 1 or 0 depending on the context!
@@ -57,7 +56,7 @@ public final class SpatialUtil {
*/
public static int assertSameDimensionality(SpatialComparable box1, SpatialComparable box2) {
final int dim = box1.getDimensionality();
- if (dim != box2.getDimensionality()) {
+ if(dim != box2.getDimensionality()) {
throw new IllegalArgumentException("The spatial objects do not have the same dimensionality!");
}
return dim;
@@ -72,7 +71,7 @@ public final class SpatialUtil {
public static double[] getMin(SpatialComparable box) {
final int dim = box.getDimensionality();
double[] min = new double[dim];
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
min[i] = box.getMin(i);
}
return min;
@@ -87,7 +86,7 @@ public final class SpatialUtil {
public static double[] getMax(SpatialComparable box) {
final int dim = box.getDimensionality();
double[] max = new double[dim];
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
max[i] = box.getMax(i);
}
return max;
@@ -102,8 +101,8 @@ public final class SpatialUtil {
*/
public static boolean intersects(SpatialComparable box1, SpatialComparable box2) {
final int dim = assertSameDimensionality(box1, box2);
- for (int i = 0; i < dim; i++) {
- if (box2.getMax(i) < box1.getMin(i) || box1.getMax(i) < box2.getMin(i)) {
+ for(int i = 0; i < dim; i++) {
+ if(box2.getMax(i) < box1.getMin(i) || box1.getMax(i) < box2.getMin(i)) {
return false;
}
}
@@ -121,8 +120,8 @@ public final class SpatialUtil {
*/
public static boolean contains(SpatialComparable box1, SpatialComparable box2) {
final int dim = assertSameDimensionality(box1, box2);
- for (int i = 0; i < dim; i++) {
- if (box2.getMin(i) < box1.getMin(i) || box1.getMax(i) < box2.getMax(i)) {
+ for(int i = 0; i < dim; i++) {
+ if(box2.getMin(i) < box1.getMin(i) || box1.getMax(i) < box2.getMax(i)) {
return false;
}
}
@@ -140,12 +139,12 @@ public final class SpatialUtil {
*/
public static boolean contains(SpatialComparable box, double[] point) {
final int dim = box.getDimensionality();
- if (dim != point.length) {
+ if(dim != point.length) {
throw new IllegalArgumentException("This HyperBoundingBox and the given point need same dimensionality");
}
- for (int i = 0; i < dim; i++) {
- if (box.getMin(i) > point[i] || box.getMax(i) < point[i]) {
+ for(int i = 0; i < dim; i++) {
+ if(box.getMin(i) > point[i] || box.getMax(i) < point[i]) {
return false;
}
}
@@ -161,9 +160,9 @@ public final class SpatialUtil {
public static double volume(SpatialComparable box) {
final int dim = box.getDimensionality();
double vol = 1.;
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
double delta = box.getMax(i) - box.getMin(i);
- if (delta == 0.) {
+ if(delta == 0.) {
return 0.;
}
vol *= delta;
@@ -181,7 +180,7 @@ public final class SpatialUtil {
public static double volumeUnion(SpatialComparable box1, SpatialComparable box2) {
final int dim = assertSameDimensionality(box1, box2);
double volume = 1.;
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
final double min = Math.min(box1.getMin(i), box2.getMin(i));
final double max = Math.max(box1.getMax(i), box2.getMax(i));
volume *= (max - min);
@@ -199,9 +198,9 @@ public final class SpatialUtil {
public static double volumeScaled(SpatialComparable box, double scale) {
final int dim = box.getDimensionality();
double vol = 1.;
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
double delta = box.getMax(i) - box.getMin(i);
- if (delta == 0.) {
+ if(delta == 0.) {
return 0.;
}
vol *= delta * scale;
@@ -220,7 +219,7 @@ public final class SpatialUtil {
public static double volumeUnionScaled(SpatialComparable box1, SpatialComparable box2, double scale) {
final int dim = assertSameDimensionality(box1, box2);
double volume = 1.;
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
final double min = Math.min(box1.getMin(i), box2.getMin(i));
final double max = Math.max(box1.getMax(i), box2.getMax(i));
volume *= (max - min) * scale;
@@ -239,7 +238,7 @@ public final class SpatialUtil {
final int dim = assertSameDimensionality(exist, addit);
double v1 = 1.;
double v2 = 1.;
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
final double emin = exist.getMin(i);
final double emax = exist.getMax(i);
final double amin = addit.getMin(i);
@@ -265,7 +264,7 @@ public final class SpatialUtil {
final int dim = assertSameDimensionality(exist, addit);
double v1 = 1.;
double v2 = 1.;
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
final double emin = exist.getMin(i);
final double emax = exist.getMax(i);
final double amin = addit.getMin(i);
@@ -288,7 +287,7 @@ public final class SpatialUtil {
public static double perimeter(SpatialComparable box) {
final int dim = box.getDimensionality();
double perimeter = 0.;
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
perimeter += box.getMax(i) - box.getMin(i);
}
return perimeter;
@@ -310,7 +309,7 @@ public final class SpatialUtil {
// the overlap volume
double overlap = 1.;
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
// The maximal value of that overlap box in the current
// dimension is the minimum of the max values.
omax = Math.min(box1.getMax(i), box2.getMax(i));
@@ -318,7 +317,7 @@ public final class SpatialUtil {
omin = Math.max(box1.getMin(i), box2.getMin(i));
// if omax <= omin in any dimension, the overlap box has a volume of zero
- if (omax <= omin) {
+ if(omax <= omin) {
return 0.;
}
@@ -345,7 +344,7 @@ public final class SpatialUtil {
double vol1 = 1.;
double vol2 = 1.;
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
final double box1min = box1.getMin(i);
final double box1max = box1.getMax(i);
final double box2min = box2.getMin(i);
@@ -355,7 +354,7 @@ public final class SpatialUtil {
final double omin = Math.max(box1min, box2min);
// if omax <= omin in any dimension, the overlap box has a volume of zero
- if (omax <= omin) {
+ if(omax <= omin) {
return 0.;
}
@@ -381,7 +380,7 @@ public final class SpatialUtil {
double[] min = new double[dim];
double[] max = new double[dim];
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
min[i] = Math.min(box1.getMin(i), box2.getMin(i));
max[i] = Math.max(box1.getMax(i), box2.getMax(i));
}
@@ -395,17 +394,17 @@ public final class SpatialUtil {
* @param mbr2 the second MBR
* @return the union of the two specified MBRs
*/
- public static HyperBoundingBox unionTolerant(SpatialComparable mbr1, SpatialComparable mbr2) {
- if (mbr1 == null && mbr2 == null) {
+ public static ModifiableHyperBoundingBox unionTolerant(SpatialComparable mbr1, SpatialComparable mbr2) {
+ if(mbr1 == null && mbr2 == null) {
return null;
}
- if (mbr1 == null) {
+ if(mbr1 == null) {
// Clone - intentionally
- return new HyperBoundingBox(mbr2);
+ return new ModifiableHyperBoundingBox(mbr2);
}
- if (mbr2 == null) {
+ if(mbr2 == null) {
// Clone - intentionally
- return new HyperBoundingBox(mbr1);
+ return new ModifiableHyperBoundingBox(mbr1);
}
return union(mbr1, mbr2);
}
@@ -429,14 +428,14 @@ public final class SpatialUtil {
final E first = getter.get(data, 0);
dim = first.getDimensionality();
mbr = new double[2 * dim];
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
mbr[d] = first.getMin(d);
mbr[dim + d] = first.getMax(d);
}
} // Remaining entries
- for (int i = 1; i < num; i++) {
+ for(int i = 1; i < num; i++) {
E next = getter.get(data, i);
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
mbr[d] = Math.min(mbr[d], next.getMin(d));
mbr[dim + d] = Math.max(mbr[dim + d], next.getMax(d));
}
@@ -445,6 +444,31 @@ public final class SpatialUtil {
}
/**
+ * Calculate the intersection of the two MBRs or <code>null</code> if they do
+ * not intersect. <em>Note</em>: if the given MBRs intersect in only one point
+ * of any dimension, this method still returns a result!
+ *
+ * @param box1 the first MBR
+ * @param box2 the second MBR
+ * @return the union of the two specified MBRs
+ */
+ public static ModifiableHyperBoundingBox intersection(final SpatialComparable box1, final SpatialComparable box2) {
+ final int dim = assertSameDimensionality(box1, box2);
+
+ double[] min = new double[dim];
+ double[] max = new double[dim];
+
+ for(int i = 0; i < dim; i++) {
+ min[i] = Math.max(box1.getMin(i), box2.getMin(i));
+ max[i] = Math.min(box1.getMax(i), box2.getMax(i));
+ if(min[i] > max[i]) {
+ return null;
+ }
+ }
+ return new ModifiableHyperBoundingBox(min, max);
+ }
+
+ /**
* Returns the centroid of this SpatialComparable.
*
* @param obj Spatial object to process
@@ -453,7 +477,7 @@ public final class SpatialUtil {
public static double[] centroid(SpatialComparable obj) {
final int dim = obj.getDimensionality();
double[] centroid = new double[dim];
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
centroid[d] = (obj.getMax(d) + obj.getMin(d)) * .5;
}
return centroid;
@@ -467,14 +491,14 @@ public final class SpatialUtil {
* @return true when the boxes are equal
*/
public static boolean equals(SpatialComparable box1, SpatialComparable box2) {
- if (box1.getDimensionality() != box2.getDimensionality()) {
+ if(box1.getDimensionality() != box2.getDimensionality()) {
return false;
}
- for (int i = 0; i < box1.getDimensionality(); i++) {
- if (box1.getMin(i) != box2.getMin(i)) {
+ for(int i = 0; i < box1.getDimensionality(); i++) {
+ if(box1.getMin(i) != box2.getMin(i)) {
return false;
}
- if (box1.getMax(i) != box2.getMax(i)) {
+ if(box1.getMax(i) != box2.getMax(i)) {
return false;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/spatial/package-info.java b/src/de/lmu/ifi/dbs/elki/data/spatial/package-info.java
index a208bd04..c935fb69 100644
--- a/src/de/lmu/ifi/dbs/elki/data/spatial/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/data/spatial/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/data/synthetic/bymodel/GeneratorInterface.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterface.java
index 7988ade4..66c958e2 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterface.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterface.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
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/data/synthetic/bymodel/GeneratorInterfaceDynamic.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterfaceDynamic.java
index 5523355f..d9246507 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterfaceDynamic.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterfaceDynamic.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
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/data/synthetic/bymodel/GeneratorMain.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java
index 0dccaf77..0d6f92e0 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
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/data/synthetic/bymodel/GeneratorSingleCluster.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorSingleCluster.java
index 8ebe2ca6..e5135b8b 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorSingleCluster.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorSingleCluster.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
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/data/synthetic/bymodel/GeneratorStatic.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorStatic.java
index b8b0dff0..c541d3fd 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorStatic.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorStatic.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
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/data/synthetic/bymodel/package-info.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/package-info.java
index 714a7835..a4e09dbe 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/package-info.java
@@ -13,7 +13,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/data/synthetic/package-info.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/package-info.java
index 98957f09..d0e2a1d0 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/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/data/type/AlternativeTypeInformation.java b/src/de/lmu/ifi/dbs/elki/data/type/AlternativeTypeInformation.java
index f1d85620..54a3c8c8 100644
--- a/src/de/lmu/ifi/dbs/elki/data/type/AlternativeTypeInformation.java
+++ b/src/de/lmu/ifi/dbs/elki/data/type/AlternativeTypeInformation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type;
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/data/type/CombinedTypeInformation.java b/src/de/lmu/ifi/dbs/elki/data/type/CombinedTypeInformation.java
index efb22237..a1c5d714 100644
--- a/src/de/lmu/ifi/dbs/elki/data/type/CombinedTypeInformation.java
+++ b/src/de/lmu/ifi/dbs/elki/data/type/CombinedTypeInformation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type;
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/data/type/MultivariateSeriesTypeInformation.java b/src/de/lmu/ifi/dbs/elki/data/type/MultivariateSeriesTypeInformation.java
new file mode 100644
index 00000000..fc2f7083
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/data/type/MultivariateSeriesTypeInformation.java
@@ -0,0 +1,93 @@
+package de.lmu.ifi.dbs.elki.data.type;
+
+/*
+ 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.utilities.io.ByteBufferSerializer;
+
+/**
+ * Type information for multi-variate time series.
+ *
+ * @author Sebastian Hollizeck
+ *
+ * @param <V> Vector type
+ */
+public class MultivariateSeriesTypeInformation<V extends FeatureVector<?>> extends VectorTypeInformation<V> {
+ /**
+ * Number of variates per dimension.
+ */
+ protected final int multiplicity;
+
+ /**
+ * Constructor for a type request without dimensionality constraints.
+ *
+ * @param cls Class constraint
+ * @param <V> vector type
+ */
+ public static <V extends FeatureVector<?>> MultivariateSeriesTypeInformation<V> typeRequest(Class<? super V> cls) {
+ return new MultivariateSeriesTypeInformation<>(cls, -1, Integer.MAX_VALUE, -1);
+ }
+
+ /**
+ * Constructor for an actual type.
+ *
+ * @param cls base class
+ * @param mindim Minimum dimensionality
+ * @param maxdim Maximum dimensionality
+ * @param multiplicity Number of variates
+ */
+ public MultivariateSeriesTypeInformation(Class<? super V> cls, int mindim, int maxdim, int multiplicity) {
+ super(cls, mindim, maxdim);
+ this.multiplicity = multiplicity;
+ }
+
+ /**
+ * Constructor for an actual type.
+ *
+ * @param factory Vector factory
+ * @param serializer Serializer
+ * @param mindim Minimum dimensionality
+ * @param maxdim Maximum dimensionality
+ * @param multiplicity Number of variates
+ */
+ public MultivariateSeriesTypeInformation(FeatureVector.Factory<V, ?> factory, ByteBufferSerializer<? super V> serializer, int mindim, int maxdim, int multiplicity) {
+ super(factory, serializer, mindim, maxdim);
+ this.multiplicity = multiplicity;
+ }
+
+ /**
+ * Get the multiplicity of the vector.
+ *
+ * @return Multiplicity
+ */
+ @Override
+ public int getMultiplicity() {
+ return multiplicity;
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + ",multiplicity=" + multiplicity;
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/data/type/NoSupportedDataTypeException.java b/src/de/lmu/ifi/dbs/elki/data/type/NoSupportedDataTypeException.java
index f1bfce91..a762c197 100644
--- a/src/de/lmu/ifi/dbs/elki/data/type/NoSupportedDataTypeException.java
+++ b/src/de/lmu/ifi/dbs/elki/data/type/NoSupportedDataTypeException.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type;
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/data/type/SimpleTypeInformation.java b/src/de/lmu/ifi/dbs/elki/data/type/SimpleTypeInformation.java
index 9fdabd36..8e428e8e 100644
--- a/src/de/lmu/ifi/dbs/elki/data/type/SimpleTypeInformation.java
+++ b/src/de/lmu/ifi/dbs/elki/data/type/SimpleTypeInformation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type;
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.data.type;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
/**
* Class wrapping a particular data type.
@@ -43,12 +43,12 @@ public class SimpleTypeInformation<T> implements TypeInformation {
/**
* Type label.
*/
- private String label = null;
+ private String label;
/**
* Type serializer.
*/
- private ByteBufferSerializer<? super T> serializer = null;
+ private ByteBufferSerializer<? super T> serializer;
/**
* Constructor.
@@ -58,6 +58,8 @@ public class SimpleTypeInformation<T> implements TypeInformation {
public SimpleTypeInformation(Class<? super T> cls) {
super();
this.cls = cls;
+ this.label = null;
+ this.serializer = null;
}
/**
@@ -70,6 +72,7 @@ public class SimpleTypeInformation<T> implements TypeInformation {
super();
this.cls = cls;
this.label = label;
+ this.serializer = null;
}
/**
@@ -81,6 +84,7 @@ public class SimpleTypeInformation<T> implements TypeInformation {
public SimpleTypeInformation(Class<? super T> cls, ByteBufferSerializer<? super T> serializer) {
super();
this.cls = cls;
+ this.label = null;
this.serializer = serializer;
}
@@ -109,7 +113,7 @@ public class SimpleTypeInformation<T> implements TypeInformation {
@Override
public boolean isAssignableFromType(TypeInformation type) {
- if (!(type instanceof SimpleTypeInformation)) {
+ if(!(type instanceof SimpleTypeInformation)) {
return false;
}
final SimpleTypeInformation<?> simpleType = (SimpleTypeInformation<?>) type;
diff --git a/src/de/lmu/ifi/dbs/elki/data/type/TypeInformation.java b/src/de/lmu/ifi/dbs/elki/data/type/TypeInformation.java
index d91a88c6..aaf46ec7 100644
--- a/src/de/lmu/ifi/dbs/elki/data/type/TypeInformation.java
+++ b/src/de/lmu/ifi/dbs/elki/data/type/TypeInformation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type;
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/data/type/TypeInformationSerializer.java b/src/de/lmu/ifi/dbs/elki/data/type/TypeInformationSerializer.java
index ac3fd164..e38a55e6 100644
--- a/src/de/lmu/ifi/dbs/elki/data/type/TypeInformationSerializer.java
+++ b/src/de/lmu/ifi/dbs/elki/data/type/TypeInformationSerializer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type;
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,10 +28,10 @@ import java.nio.ByteBuffer;
import de.lmu.ifi.dbs.elki.data.DoubleVector;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
/**
* Class to handle the serialization and deserialization of type information.
@@ -232,20 +232,22 @@ public class TypeInformationSerializer implements ByteBufferSerializer<TypeInfor
@Override
public VectorTypeInformation<?> fromByteBuffer(ByteBuffer buffer) throws IOException, UnsupportedOperationException {
try {
+ // Factory type!
String typename = ByteArrayUtil.STRING_SERIALIZER.fromByteBuffer(buffer);
- Class<DoubleVector> clz = (Class<DoubleVector>) Class.forName(typename);
+ NumberVector.Factory<DoubleVector> factory = (NumberVector.Factory<DoubleVector>) ClassGenericsUtil.instantiate(NumberVector.Factory.class, typename);
String label = ByteArrayUtil.STRING_SERIALIZER.fromByteBuffer(buffer);
label = ("".equals(label)) ? null : label;
String sername = ByteArrayUtil.STRING_SERIALIZER.fromByteBuffer(buffer);
ByteBufferSerializer<DoubleVector> serializer = (ByteBufferSerializer<DoubleVector>) Class.forName(sername).newInstance();
int mindim = ByteArrayUtil.readSignedVarint(buffer);
int maxdim = ByteArrayUtil.readSignedVarint(buffer);
- return new VectorTypeInformation<>(clz, serializer, mindim, maxdim);
+ // FIXME: should/must provide a factory now!
+ return new VectorTypeInformation<>(factory, serializer, mindim, maxdim);
+ } catch (UnableToComplyException e) {
+ throw new UnsupportedOperationException("Cannot deserialize - cannot instantiate factory: "+e, e);
} catch (ClassNotFoundException e) {
throw new UnsupportedOperationException("Cannot deserialize - class not found: "+e, e);
- } catch (InstantiationException e) {
- throw new UnsupportedOperationException("Cannot deserialize - cannot instantiate serializer: "+e.getMessage(), e);
- } catch (IllegalAccessException e) {
+ } catch (InstantiationException | IllegalAccessException e) {
throw new UnsupportedOperationException("Cannot deserialize - cannot instantiate serializer: "+e.getMessage(), e);
}
}
@@ -265,8 +267,8 @@ public class TypeInformationSerializer implements ByteBufferSerializer<TypeInfor
} catch (SecurityException e) {
throw new UnsupportedOperationException("Serialization not possible.", e);
}
- // Type class
- ByteArrayUtil.writeString(buffer, object.getRestrictionClass().getName());
+ // Use *factory* class!
+ ByteArrayUtil.writeString(buffer, object.getFactory().getClass().getName());
// Name, or an empty string.
ByteArrayUtil.writeString(buffer, object.getLabel());
// Serializer class
@@ -320,7 +322,7 @@ public class TypeInformationSerializer implements ByteBufferSerializer<TypeInfor
try {
// Factory type!
String typename = ByteArrayUtil.STRING_SERIALIZER.fromByteBuffer(buffer);
- NumberVector.Factory<DoubleVector, ?> factory = (NumberVector.Factory<DoubleVector, ?>) ClassGenericsUtil.instantiate(NumberVector.Factory.class, typename);
+ NumberVector.Factory<DoubleVector> factory = (NumberVector.Factory<DoubleVector>) ClassGenericsUtil.instantiate(NumberVector.Factory.class, typename);
// Relation label
String label = ByteArrayUtil.STRING_SERIALIZER.fromByteBuffer(buffer);
label = ("".equals(label)) ? null : label;
@@ -346,9 +348,7 @@ public class TypeInformationSerializer implements ByteBufferSerializer<TypeInfor
throw new UnsupportedOperationException("Cannot deserialize - cannot instantiate factory: "+e, e);
} catch (ClassNotFoundException e) {
throw new UnsupportedOperationException("Cannot deserialize - class not found: "+e, e);
- } catch (InstantiationException e) {
- throw new UnsupportedOperationException("Cannot deserialize - cannot instantiate serializer: "+e.getMessage(), e);
- } catch (IllegalAccessException e) {
+ } catch (InstantiationException | IllegalAccessException e) {
throw new UnsupportedOperationException("Cannot deserialize - cannot instantiate serializer: "+e.getMessage(), e);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/type/TypeUtil.java b/src/de/lmu/ifi/dbs/elki/data/type/TypeUtil.java
index 2eabf64b..94648aaf 100644
--- a/src/de/lmu/ifi/dbs/elki/data/type/TypeUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/data/type/TypeUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type;
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,10 +40,10 @@ import de.lmu.ifi.dbs.elki.data.spatial.PolygonsObject;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
/**
* Utility package containing various common types.
@@ -99,7 +99,7 @@ public final class TypeUtil {
/**
* A list of neighbors.
*/
- public static final SimpleTypeInformation<DistanceDBIDList<?>> NEIGHBORLIST = new SimpleTypeInformation<>(DistanceDBIDList.class);
+ public static final SimpleTypeInformation<DoubleDBIDList> NEIGHBORLIST = new SimpleTypeInformation<>(DoubleDBIDList.class);
/**
* Either class label, object labels or a string - anything that will be
@@ -112,55 +112,75 @@ public final class TypeUtil {
/**
* Number vectors of <em>variable</em> length.
*/
- public static final SimpleTypeInformation<? super NumberVector<?>> NUMBER_VECTOR_VARIABLE_LENGTH = new SimpleTypeInformation<>(NumberVector.class);
+ public static final VectorTypeInformation<NumberVector> NUMBER_VECTOR_VARIABLE_LENGTH = VectorTypeInformation.typeRequest(NumberVector.class);
/**
* Input type for algorithms that require number vector fields.
*/
- public static final VectorFieldTypeInformation<NumberVector<?>> NUMBER_VECTOR_FIELD = new VectorFieldTypeInformation<>(NumberVector.class);
+ public static final VectorFieldTypeInformation<NumberVector> NUMBER_VECTOR_FIELD = VectorFieldTypeInformation.typeRequest(NumberVector.class);
+
+ /**
+ * Type request for two-dimensional number vectors
+ */
+ public static final VectorFieldTypeInformation<? super NumberVector> NUMBER_VECTOR_FIELD_1D = VectorFieldTypeInformation.typeRequest(NumberVector.class, 1, 1);
+
+ /**
+ * Type request for two-dimensional number vectors
+ */
+ public static final VectorFieldTypeInformation<? super NumberVector> NUMBER_VECTOR_FIELD_2D = VectorFieldTypeInformation.typeRequest(NumberVector.class, 2, 2);
+
+ /**
+ * Type request for multivariate time series.
+ */
+ public static final MultivariateSeriesTypeInformation<NumberVector> MULTIVARIATE_SERIES = MultivariateSeriesTypeInformation.typeRequest(NumberVector.class);
/**
* Input type for algorithms that require number vector fields.
*
* If possible, please use {@link #NUMBER_VECTOR_FIELD}!
*/
- public static final VectorFieldTypeInformation<DoubleVector> DOUBLE_VECTOR_FIELD = new VectorFieldTypeInformation<>(DoubleVector.class);
+ public static final VectorFieldTypeInformation<DoubleVector> DOUBLE_VECTOR_FIELD = VectorFieldTypeInformation.typeRequest(DoubleVector.class);
/**
* Input type for algorithms that require number vector fields.
*
* If possible, please use {@link #NUMBER_VECTOR_FIELD}!
*/
- public static final VectorFieldTypeInformation<FloatVector> FLOAT_VECTOR_FIELD = new VectorFieldTypeInformation<>(FloatVector.class);
+ public static final VectorFieldTypeInformation<FloatVector> FLOAT_VECTOR_FIELD = VectorFieldTypeInformation.typeRequest(FloatVector.class);
/**
- * Input type for algorithms that require number vector fields.
+ * Input type for algorithms that require bit vectors.
+ */
+ public static final VectorTypeInformation<BitVector> BIT_VECTOR = VectorTypeInformation.typeRequest(BitVector.class);
+
+ /**
+ * Input type for algorithms that require bit vector fields.
*/
- public static final VectorFieldTypeInformation<BitVector> BIT_VECTOR_FIELD = new VectorFieldTypeInformation<>(BitVector.class);
+ public static final VectorFieldTypeInformation<BitVector> BIT_VECTOR_FIELD = VectorFieldTypeInformation.typeRequest(BitVector.class);
/**
* Sparse float vector field.
*/
- public static final SimpleTypeInformation<SparseNumberVector<?>> SPARSE_VECTOR_VARIABLE_LENGTH = new SimpleTypeInformation<>(SparseNumberVector.class);
+ public static final VectorTypeInformation<SparseNumberVector> SPARSE_VECTOR_VARIABLE_LENGTH = VectorTypeInformation.typeRequest(SparseNumberVector.class);
/**
* Sparse vector field.
*/
- public static final VectorFieldTypeInformation<SparseNumberVector<?>> SPARSE_VECTOR_FIELD = new VectorFieldTypeInformation<>(SparseNumberVector.class);
+ public static final VectorFieldTypeInformation<SparseNumberVector> SPARSE_VECTOR_FIELD = VectorFieldTypeInformation.typeRequest(SparseNumberVector.class);
/**
* Sparse float vector field.
*
* If possible, please use {@link #SPARSE_VECTOR_FIELD} instead!
*/
- public static final VectorFieldTypeInformation<SparseFloatVector> SPARSE_FLOAT_FIELD = new VectorFieldTypeInformation<>(SparseFloatVector.class);
+ public static final VectorFieldTypeInformation<SparseFloatVector> SPARSE_FLOAT_FIELD = VectorFieldTypeInformation.typeRequest(SparseFloatVector.class);
/**
* Sparse double vector field.
*
* If possible, please use {@link #SPARSE_VECTOR_FIELD} instead!
*/
- public static final VectorFieldTypeInformation<SparseDoubleVector> SPARSE_DOUBLE_FIELD = new VectorFieldTypeInformation<>(SparseDoubleVector.class);
+ public static final VectorFieldTypeInformation<SparseDoubleVector> SPARSE_DOUBLE_FIELD = VectorFieldTypeInformation.typeRequest(SparseDoubleVector.class);
/**
* External ID type.
@@ -200,7 +220,7 @@ public final class TypeUtil {
/**
* Any feature vector type.
*/
- public static final SimpleTypeInformation<FeatureVector<?>> FEATURE_VECTORS = new SimpleTypeInformation<>(FeatureVector.class);
+ public static final VectorTypeInformation<FeatureVector<?>> FEATURE_VECTORS = VectorTypeInformation.typeRequest(FeatureVector.class);
/**
* Make a type array easily.
diff --git a/src/de/lmu/ifi/dbs/elki/data/type/VectorFieldTypeInformation.java b/src/de/lmu/ifi/dbs/elki/data/type/VectorFieldTypeInformation.java
index d05eed34..448cb147 100644
--- a/src/de/lmu/ifi/dbs/elki/data/type/VectorFieldTypeInformation.java
+++ b/src/de/lmu/ifi/dbs/elki/data/type/VectorFieldTypeInformation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type;
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.data.type;
*/
import de.lmu.ifi.dbs.elki.data.FeatureVector;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
/**
* Type information to specify that a type has a fixed dimensionality.
@@ -35,9 +35,26 @@ import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
*/
public class VectorFieldTypeInformation<V extends FeatureVector<?>> extends VectorTypeInformation<V> {
/**
- * Object factory for producing new instances.
+ * Constructor for a type request without dimensionality constraints.
+ *
+ * @param cls Class constraint
+ * @param <V> vector type
+ */
+ public static <V extends FeatureVector<?>> VectorFieldTypeInformation<V> typeRequest(Class<? super V> cls) {
+ return new VectorFieldTypeInformation<>(cls, -1, Integer.MAX_VALUE);
+ }
+
+ /**
+ * Constructor for a type request with dimensionality constraints.
+ *
+ * @param cls Class constraint
+ * @param mindim Minimum dimensionality
+ * @param maxdim Maximum dimensionality
+ * @param <V> vector type
*/
- private final FeatureVector.Factory<V, ?> factory;
+ public static <V extends FeatureVector<?>> VectorFieldTypeInformation<V> typeRequest(Class<? super V> cls, int mindim, int maxdim) {
+ return new VectorFieldTypeInformation<>(cls, mindim, maxdim);
+ }
/**
* Labels.
@@ -53,8 +70,7 @@ public class VectorFieldTypeInformation<V extends FeatureVector<?>> extends Vect
* @param serializer Serializer
*/
public VectorFieldTypeInformation(FeatureVector.Factory<V, ?> factory, int dim, String[] labels, ByteBufferSerializer<? super V> serializer) {
- super(factory.getRestrictionClass(), serializer, dim, dim);
- this.factory = factory;
+ super(factory, serializer, dim, dim);
this.labels = labels;
assert (labels == null || labels.length == dim) : "Created vector field with incomplete labels.";
}
@@ -68,8 +84,7 @@ public class VectorFieldTypeInformation<V extends FeatureVector<?>> extends Vect
* @param serializer Serializer
*/
public VectorFieldTypeInformation(FeatureVector.Factory<V, ?> factory, int mindim, int maxdim, ByteBufferSerializer<? super V> serializer) {
- super(factory.getRestrictionClass(), serializer, mindim, maxdim);
- this.factory = factory;
+ super(factory, serializer, mindim, maxdim);
}
/**
@@ -80,8 +95,7 @@ public class VectorFieldTypeInformation<V extends FeatureVector<?>> extends Vect
* @param serializer Serializer
*/
public VectorFieldTypeInformation(FeatureVector.Factory<V, ?> factory, int dim, ByteBufferSerializer<? super V> serializer) {
- super(factory.getRestrictionClass(), serializer, dim, dim);
- this.factory = factory;
+ super(factory, serializer, dim, dim);
}
/**
@@ -92,8 +106,7 @@ public class VectorFieldTypeInformation<V extends FeatureVector<?>> extends Vect
* @param labels Labels
*/
public VectorFieldTypeInformation(FeatureVector.Factory<V, ?> factory, int dim, String[] labels) {
- super(factory.getRestrictionClass(), factory.getDefaultSerializer(), dim, dim);
- this.factory = factory;
+ super(factory, factory.getDefaultSerializer(), dim, dim);
this.labels = labels;
assert (labels == null || labels.length == dim) : "Created vector field with incomplete labels.";
}
@@ -105,9 +118,8 @@ public class VectorFieldTypeInformation<V extends FeatureVector<?>> extends Vect
* @param mindim Minimum dimensionality request
* @param maxdim Maximum dimensionality request
*/
- public VectorFieldTypeInformation(Class<? super V> cls, int mindim, int maxdim) {
+ private VectorFieldTypeInformation(Class<? super V> cls, int mindim, int maxdim) {
super(cls, mindim, maxdim);
- this.factory = null;
}
/**
@@ -117,29 +129,7 @@ public class VectorFieldTypeInformation<V extends FeatureVector<?>> extends Vect
* @param dim Dimensionality
*/
public VectorFieldTypeInformation(FeatureVector.Factory<V, ?> factory, int dim) {
- super(factory.getRestrictionClass(), factory.getDefaultSerializer(), dim, dim);
- this.factory = factory;
- }
-
- /**
- * Constructor for a request with fixed dimensionality.
- *
- * @param cls Vector restriction class.
- * @param dim Dimensionality request
- */
- public VectorFieldTypeInformation(Class<? super V> cls, int dim) {
- super(cls, dim, dim);
- this.factory = null;
- }
-
- /**
- * Constructor for a request without fixed dimensionality.
- *
- * @param cls Vector restriction class.
- */
- public VectorFieldTypeInformation(Class<? super V> cls) {
- super(cls);
- this.factory = null;
+ super(factory, factory.getDefaultSerializer(), dim, dim);
}
@Override
@@ -168,18 +158,6 @@ public class VectorFieldTypeInformation<V extends FeatureVector<?>> extends Vect
return mindim;
}
- /**
- * Get the object type factory.
- *
- * @return the factory
- */
- public FeatureVector.Factory<V, ?> getFactory() {
- if (factory == null) {
- throw new UnsupportedOperationException("Requesting factory for a type request!");
- }
- return factory;
- }
-
@Override
public String toString() {
StringBuilder buf = new StringBuilder(getRestrictionClass().getSimpleName());
diff --git a/src/de/lmu/ifi/dbs/elki/data/type/VectorTypeInformation.java b/src/de/lmu/ifi/dbs/elki/data/type/VectorTypeInformation.java
index 7d568a55..8334e88d 100644
--- a/src/de/lmu/ifi/dbs/elki/data/type/VectorTypeInformation.java
+++ b/src/de/lmu/ifi/dbs/elki/data/type/VectorTypeInformation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.type;
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.data.type;
*/
import de.lmu.ifi.dbs.elki.data.FeatureVector;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
/**
* Construct a type information for vector spaces with fixed dimensionality.
@@ -37,31 +37,43 @@ import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
*/
public class VectorTypeInformation<V extends FeatureVector<?>> extends SimpleTypeInformation<V> {
/**
- * Minimum dimensionality.
+ * Object factory for producing new instances.
*/
- protected final int mindim;
+ private final FeatureVector.Factory<V, ?> factory;
/**
- * Maximum dimensionality.
+ * Constructor for a type request without dimensionality constraints.
+ *
+ * @param cls Class constraint
+ * @param <V> vector type
*/
- protected final int maxdim;
-
+ public static <V extends FeatureVector<?>> VectorTypeInformation<V> typeRequest(Class<? super V> cls) {
+ return new VectorTypeInformation<>(cls, -1, Integer.MAX_VALUE);
+ }
+
/**
- * Constructor for an actual type.
+ * Constructor for a type request with dimensionality constraints.
*
- * @param cls base class
- * @param serializer Serializer
+ * @param cls Class constraint
* @param mindim Minimum dimensionality
* @param maxdim Maximum dimensionality
+ * @param <V> vector type
*/
- public VectorTypeInformation(Class<? super V> cls, ByteBufferSerializer<? super V> serializer, int mindim, int maxdim) {
- super(cls, serializer);
- assert (this.mindim <= this.maxdim);
- this.mindim = mindim;
- this.maxdim = maxdim;
+ public static <V extends FeatureVector<?>> VectorTypeInformation<V> typeRequest(Class<? super V> cls, int mindim, int maxdim) {
+ return new VectorTypeInformation<>(cls, mindim, maxdim);
}
/**
+ * Minimum dimensionality.
+ */
+ protected final int mindim;
+
+ /**
+ * Maximum dimensionality.
+ */
+ protected final int maxdim;
+
+ /**
* Constructor for a type request.
*
* @param cls base class
@@ -69,16 +81,27 @@ public class VectorTypeInformation<V extends FeatureVector<?>> extends SimpleTyp
* @param maxdim Maximum dimensionality
*/
public VectorTypeInformation(Class<? super V> cls, int mindim, int maxdim) {
- this(cls, null, mindim, maxdim);
+ super(cls);
+ this.factory = null;
+ assert (mindim <= maxdim);
+ this.mindim = mindim;
+ this.maxdim = maxdim;
}
/**
- * Constructor for a type request without dimensionality constraints.
+ * Constructor for an actual type.
*
- * @param cls Class constraint
+ * @param factory Vector factory
+ * @param serializer Serializer
+ * @param mindim Minimum dimensionality
+ * @param maxdim Maximum dimensionality
*/
- public VectorTypeInformation(Class<? super V> cls) {
- this(cls, null, -1, Integer.MAX_VALUE);
+ public VectorTypeInformation(FeatureVector.Factory<V, ?> factory, ByteBufferSerializer<? super V> serializer, int mindim, int maxdim) {
+ super(factory.getRestrictionClass(), serializer);
+ this.factory = factory;
+ assert (mindim <= maxdim);
+ this.mindim = mindim;
+ this.maxdim = maxdim;
}
@Override
@@ -122,6 +145,18 @@ public class VectorTypeInformation<V extends FeatureVector<?>> extends SimpleTyp
}
/**
+ * Get the object type factory.
+ *
+ * @return the factory
+ */
+ public FeatureVector.Factory<V, ?> getFactory() {
+ if(factory == null) {
+ throw new UnsupportedOperationException("Requesting factory for a type request!");
+ }
+ return factory;
+ }
+
+ /**
* Get the minimum dimensionality of the occurring vectors.
*
* @return dimensionality
@@ -145,6 +180,15 @@ public class VectorTypeInformation<V extends FeatureVector<?>> extends SimpleTyp
return maxdim;
}
+ /**
+ * Get the multiplicity of the vector.
+ *
+ * @return Multiplicity {@code 1} (except for subclasses)
+ */
+ public int getMultiplicity() {
+ return 1;
+ }
+
@Override
public String toString() {
StringBuilder buf = new StringBuilder(super.toString());
diff --git a/src/de/lmu/ifi/dbs/elki/data/type/package-info.java b/src/de/lmu/ifi/dbs/elki/data/type/package-info.java
index ad666ab4..941c9574 100644
--- a/src/de/lmu/ifi/dbs/elki/data/type/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/data/type/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/database/AbstractDatabase.java b/src/de/lmu/ifi/dbs/elki/database/AbstractDatabase.java
index ef2374cc..5ff2c6e9 100644
--- a/src/de/lmu/ifi/dbs/elki/database/AbstractDatabase.java
+++ b/src/de/lmu/ifi/dbs/elki/database/AbstractDatabase.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database;
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
@@ -43,8 +43,8 @@ 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.datasource.bundle.SingleObjectBundle;
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.similarityfunction.SimilarityFunction;
+import de.lmu.ifi.dbs.elki.index.DistanceIndex;
import de.lmu.ifi.dbs.elki.index.Index;
import de.lmu.ifi.dbs.elki.index.IndexFactory;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
@@ -155,15 +155,30 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem
}
@Override
- public <O, D extends Distance<D>> DistanceQuery<O, D> getDistanceQuery(Relation<O> objQuery, DistanceFunction<? super O, D> distanceFunction, Object... hints) {
+ public <O> DistanceQuery<O> getDistanceQuery(Relation<O> objQuery, DistanceFunction<? super O> distanceFunction, Object... hints) {
if(distanceFunction == null) {
throw new AbortException("Distance query requested for 'null' distance!");
}
+ ListIterator<Index> iter = indexes.listIterator(indexes.size());
+ while(iter.hasPrevious()) {
+ Index idx = iter.previous();
+ if(idx instanceof DistanceIndex) {
+ if(getLogger().isDebuggingFinest()) {
+ getLogger().debugFinest("Considering index for kNN Query: " + idx);
+ }
+ @SuppressWarnings("unchecked")
+ final DistanceIndex<O> distanceIndex = (DistanceIndex<O>) idx;
+ DistanceQuery<O> q = distanceIndex.getDistanceQuery(distanceFunction, hints);
+ if(q != null) {
+ return q;
+ }
+ }
+ }
return distanceFunction.instantiate(objQuery);
}
@Override
- public <O, D extends Distance<D>> SimilarityQuery<O, D> getSimilarityQuery(Relation<O> objQuery, SimilarityFunction<? super O, D> similarityFunction, Object... hints) {
+ public <O> SimilarityQuery<O> getSimilarityQuery(Relation<O> objQuery, SimilarityFunction<? super O> similarityFunction, Object... hints) {
if(similarityFunction == null) {
throw new AbortException("Similarity query requested for 'null' similarity!");
}
@@ -171,7 +186,7 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem
}
@Override
- public <O, D extends Distance<D>> KNNQuery<O, D> getKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
+ public <O> KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
if(distanceQuery == null) {
throw new AbortException("kNN query requested for 'null' distance!");
}
@@ -184,7 +199,7 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem
}
@SuppressWarnings("unchecked")
final KNNIndex<O> knnIndex = (KNNIndex<O>) idx;
- KNNQuery<O, D> q = knnIndex.getKNNQuery(distanceQuery, hints);
+ KNNQuery<O> q = knnIndex.getKNNQuery(distanceQuery, hints);
if(q != null) {
return q;
}
@@ -201,7 +216,7 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem
}
@Override
- public <O, D extends Distance<D>> RangeQuery<O, D> getRangeQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
+ public <O> RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
if(distanceQuery == null) {
throw new AbortException("Range query requested for 'null' distance!");
}
@@ -214,7 +229,7 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem
}
@SuppressWarnings("unchecked")
final RangeIndex<O> rangeIndex = (RangeIndex<O>) idx;
- RangeQuery<O, D> q = rangeIndex.getRangeQuery(distanceQuery, hints);
+ RangeQuery<O> q = rangeIndex.getRangeQuery(distanceQuery, hints);
if(q != null) {
return q;
}
@@ -231,7 +246,7 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem
}
@Override
- public <O, D extends Distance<D>> RKNNQuery<O, D> getRKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
+ public <O> RKNNQuery<O> getRKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
if(distanceQuery == null) {
throw new AbortException("RKNN query requested for 'null' distance!");
}
@@ -244,7 +259,7 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem
}
@SuppressWarnings("unchecked")
final RKNNIndex<O> rknnIndex = (RKNNIndex<O>) idx;
- RKNNQuery<O, D> q = rknnIndex.getRKNNQuery(distanceQuery, hints);
+ RKNNQuery<O> q = rknnIndex.getRKNNQuery(distanceQuery, hints);
if(q != null) {
return q;
}
@@ -261,7 +276,7 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem
maxk = (Integer) hint;
}
}
- KNNQuery<O, D> knnQuery = getKNNQuery(distanceQuery, DatabaseQuery.HINT_BULK, maxk);
+ KNNQuery<O> knnQuery = getKNNQuery(distanceQuery, DatabaseQuery.HINT_BULK, maxk);
return new LinearScanRKNNQuery<>(distanceQuery, knnQuery, maxk);
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/Database.java b/src/de/lmu/ifi/dbs/elki/database/Database.java
index 10bc0eac..9eab5c94 100644
--- a/src/de/lmu/ifi/dbs/elki/database/Database.java
+++ b/src/de/lmu/ifi/dbs/elki/database/Database.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database;
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
@@ -38,7 +38,6 @@ 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.datasource.bundle.SingleObjectBundle;
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.similarityfunction.SimilarityFunction;
import de.lmu.ifi.dbs.elki.index.Index;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
@@ -87,25 +86,23 @@ public interface Database extends HierarchicalResult {
* Get the distance query for a particular distance function.
*
* @param <O> Object type
- * @param <D> Distance result type
* @param relation Relation used
* @param distanceFunction Distance function to use
* @param hints Optimizer hints
* @return Instance to query the database with this distance
*/
- <O, D extends Distance<D>> DistanceQuery<O, D> getDistanceQuery(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, Object... hints);
+ <O> DistanceQuery<O> getDistanceQuery(Relation<O> relation, DistanceFunction<? super O> distanceFunction, Object... hints);
/**
* Get the similarity query for a particular similarity function.
*
* @param <O> Object type
- * @param <D> Similarity result type
* @param relation Relation used
* @param similarityFunction Similarity function to use
* @param hints Optimizer hints
* @return Instance to query the database with this similarity
*/
- <O, D extends Distance<D>> SimilarityQuery<O, D> getSimilarityQuery(Relation<O> relation, SimilarityFunction<? super O, D> similarityFunction, Object... hints);
+ <O> SimilarityQuery<O> getSimilarityQuery(Relation<O> relation, SimilarityFunction<? super O> similarityFunction, Object... hints);
/**
* Get a KNN query object for the given distance query.
@@ -121,12 +118,11 @@ public interface Database extends HierarchicalResult {
* </ul>
*
* @param <O> Object type
- * @param <D> Distance type
* @param distanceQuery Distance query
* @param hints Optimizer hints
* @return KNN Query object
*/
- <O, D extends Distance<D>> KNNQuery<O, D> getKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints);
+ <O> KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints);
/**
* Get a range query object for the given distance query.
@@ -142,12 +138,11 @@ public interface Database extends HierarchicalResult {
* </ul>
*
* @param <O> Object type
- * @param <D> Distance type
* @param distanceQuery Distance query
* @param hints Optimizer hints
* @return KNN Query object
*/
- <O, D extends Distance<D>> RangeQuery<O, D> getRangeQuery(DistanceQuery<O, D> distanceQuery, Object... hints);
+ <O> RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints);
/**
* Get a rKNN query object for the given distance query.
@@ -163,12 +158,11 @@ public interface Database extends HierarchicalResult {
* </ul>
*
* @param <O> Object type
- * @param <D> Distance type
* @param distanceQuery Distance query
* @param hints Optimizer hints
* @return KNN Query object
*/
- <O, D extends Distance<D>> RKNNQuery<O, D> getRKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints);
+ <O> RKNNQuery<O> getRKNNQuery(DistanceQuery<O> distanceQuery, Object... hints);
/**
* Returns the DatabaseObject represented by the specified id.
diff --git a/src/de/lmu/ifi/dbs/elki/database/DatabaseEventManager.java b/src/de/lmu/ifi/dbs/elki/database/DatabaseEventManager.java
index 4b9c9d94..1596c82f 100644
--- a/src/de/lmu/ifi/dbs/elki/database/DatabaseEventManager.java
+++ b/src/de/lmu/ifi/dbs/elki/database/DatabaseEventManager.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.database;
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/database/HashmapDatabase.java b/src/de/lmu/ifi/dbs/elki/database/HashmapDatabase.java
index 26f18bce..541d59fc 100644
--- a/src/de/lmu/ifi/dbs/elki/database/HashmapDatabase.java
+++ b/src/de/lmu/ifi/dbs/elki/database/HashmapDatabase.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database;
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,11 +29,11 @@ import java.util.Collection;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory;
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.DBIDVar;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.relation.DBIDView;
@@ -50,15 +50,13 @@ import de.lmu.ifi.dbs.elki.index.IndexFactory;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
- * Provides a mapping for associations based on a Hashtable and functions to get
- * the next usable ID for insertion, making IDs reusable after deletion of the
- * entry.
+ * Database storing data using hashtable storage, and thus allowing additional
+ * and removal of objects.
*
* @author Arthur Zimek
* @author Erich Schubert
@@ -67,7 +65,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.composedOf HashSetModifiableDBIDs
*/
@Description("Database using an in-memory hashtable and at least providing linear scans.")
-public class HashmapDatabase extends AbstractDatabase implements UpdatableDatabase, Parameterizable {
+public class HashmapDatabase extends AbstractDatabase implements UpdatableDatabase {
/**
* Our logger
*/
@@ -103,7 +101,7 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba
this.addChildResult(idrep);
// Add indexes.
- if (indexFactories != null) {
+ if(indexFactories != null) {
this.indexFactories.addAll(indexFactories);
}
}
@@ -121,7 +119,7 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba
*/
@Override
public void initialize() {
- if (databaseConnection != null) {
+ if(databaseConnection != null) {
this.insert(databaseConnection.loadData());
// Run at most once.
databaseConnection = null;
@@ -130,50 +128,37 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba
@Override
public DBIDs insert(ObjectBundle objpackages) {
- if (objpackages.dataLength() == 0) {
+ if(objpackages.dataLength() == 0) {
return DBIDUtil.EMPTYDBIDS;
}
// insert into db
ArrayModifiableDBIDs newids = DBIDUtil.newArray(objpackages.dataLength());
Relation<?>[] targets = alignColumns(objpackages);
- int idrepnr = -1;
- for (int i = 0; i < targets.length; i++) {
- if (targets[i] == idrep) {
- idrepnr = i;
- break;
- }
- }
-
- for (int j = 0; j < objpackages.dataLength(); j++) {
+ DBIDVar var = DBIDUtil.newVar();
+ for(int j = 0; j < objpackages.dataLength(); j++) {
// insert object
- final DBID newid;
- if (idrepnr < 0) {
- newid = DBIDUtil.generateSingleDBID();
- } else {
- newid = (DBID) objpackages.data(j, idrepnr);
+ if(!objpackages.assignDBID(j, var)) {
+ var.set(DBIDUtil.generateSingleDBID());
}
- if (ids.contains(newid)) {
+ if(ids.contains(var)) {
throw new AbortException("Duplicate DBID conflict.");
}
- ids.add(newid);
- for (int i = 0; i < targets.length; i++) {
- // DBIDs were handled above.
- if (i == idrepnr) {
- continue;
- }
+ ids.add(var);
+ for(int i = 0; i < targets.length; i++) {
@SuppressWarnings("unchecked")
final Relation<Object> relation = (Relation<Object>) targets[i];
- relation.set(newid, objpackages.data(j, i));
+ relation.set(var, objpackages.data(j, i));
}
- newids.add(newid);
+ newids.add(var);
}
// Notify indexes of insertions
- for (Index index : indexes) {
- if (index instanceof DynamicIndex) {
+ for(Index index : indexes) {
+ if(index instanceof DynamicIndex) {
((DynamicIndex) index).insertAll(newids);
- } else {
+ }
+ else {
LOG.warning("Non-dynamic indexes have been added to the database. Updates are not possible!");
}
}
@@ -195,19 +180,19 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba
Relation<?>[] targets = new Relation<?>[pack.metaLength()];
{
BitSet used = new BitSet(relations.size());
- for (int i = 0; i < targets.length; i++) {
+ for(int i = 0; i < targets.length; i++) {
SimpleTypeInformation<?> meta = pack.meta(i);
// TODO: aggressively try to match exact metas first?
// Try to match unused representations only
- for (int j = used.nextClearBit(0); j >= 0 && j < relations.size(); j = used.nextClearBit(j + 1)) {
+ for(int j = used.nextClearBit(0); j >= 0 && j < relations.size(); j = used.nextClearBit(j + 1)) {
Relation<?> relation = relations.get(j);
- if (relation.getDataTypeInformation().isAssignableFromType(meta)) {
+ if(relation.getDataTypeInformation().isAssignableFromType(meta)) {
targets[i] = relation;
used.set(j);
break;
}
}
- if (targets[i] == null) {
+ if(targets[i] == null) {
targets[i] = addNewRelation(meta);
used.set(relations.size() - 1);
}
@@ -229,8 +214,8 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba
relations.add(relation);
getHierarchy().add(this, relation);
// Try to add indexes where appropriate
- for (IndexFactory<?, ?> factory : indexFactories) {
- if (factory.getInputTypeRestriction().isAssignableFromType(meta)) {
+ for(IndexFactory<?, ?> factory : indexFactories) {
+ if(factory.getInputTypeRestriction().isAssignableFromType(meta)) {
@SuppressWarnings("unchecked")
final IndexFactory<Object, ?> ofact = (IndexFactory<Object, ?>) factory;
@SuppressWarnings("unchecked")
@@ -254,22 +239,23 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba
public MultipleObjectsBundle delete(DBIDs ids) {
// Prepare bundle to return
MultipleObjectsBundle bundle = new MultipleObjectsBundle();
- for (Relation<?> relation : relations) {
+ for(Relation<?> relation : relations) {
ArrayList<Object> data = new ArrayList<>(ids.size());
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
data.add(relation.get(iter));
}
bundle.appendColumn(relation.getDataTypeInformation(), data);
}
// remove from db
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
doDelete(iter);
}
// Remove from indexes
- for (Index index : indexes) {
- if (index instanceof DynamicIndex) {
+ for(Index index : indexes) {
+ if(index instanceof DynamicIndex) {
((DynamicIndex) index).deleteAll(ids);
- } else {
+ }
+ else {
LOG.warning("Non-dynamic indexes have been added to the database. Updates are not possible!");
}
@@ -290,15 +276,16 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba
public SingleObjectBundle delete(DBIDRef id) {
// Prepare bundle to return
SingleObjectBundle bundle = new SingleObjectBundle();
- for (Relation<?> relation : relations) {
+ for(Relation<?> relation : relations) {
bundle.append(relation.getDataTypeInformation(), relation.get(id));
}
doDelete(id);
// Remove from indexes
- for (Index index : indexes) {
- if (index instanceof DynamicIndex) {
+ for(Index index : indexes) {
+ if(index instanceof DynamicIndex) {
((DynamicIndex) index).delete(id);
- } else {
+ }
+ else {
LOG.warning("Non-dynamic indexes have been added to the database. Updates are not possible!");
}
}
@@ -317,9 +304,9 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba
// Remove id
ids.remove(id);
// Remove from all representations.
- for (Relation<?> relation : relations) {
+ for(Relation<?> relation : relations) {
// ID has already been removed, and this would loop...
- if (relation != idrep) {
+ if(relation != idrep) {
relation.delete(id);
}
}
@@ -354,12 +341,12 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba
super.makeOptions(config);
// Get database connection.
final ObjectParameter<DatabaseConnection> dbcP = new ObjectParameter<>(DATABASE_CONNECTION_ID, DatabaseConnection.class, FileBasedDatabaseConnection.class);
- if (config.grab(dbcP)) {
+ if(config.grab(dbcP)) {
databaseConnection = dbcP.instantiateClass(config);
}
// Get indexes.
final ObjectListParameter<IndexFactory<?, ?>> indexFactoryP = new ObjectListParameter<>(INDEX_ID, IndexFactory.class, true);
- if (config.grab(indexFactoryP)) {
+ if(config.grab(indexFactoryP)) {
indexFactories = indexFactoryP.instantiateClasses(config);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ProxyDatabase.java b/src/de/lmu/ifi/dbs/elki/database/ProxyDatabase.java
index a06b7a12..bdcec783 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ProxyDatabase.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ProxyDatabase.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database;
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/database/QueryUtil.java b/src/de/lmu/ifi/dbs/elki/database/QueryUtil.java
index 44afece1..6ebd870d 100644
--- a/src/de/lmu/ifi/dbs/elki/database/QueryUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/database/QueryUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database;
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,23 +23,25 @@ package de.lmu.ifi.dbs.elki.database;
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.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.integer.DoubleIntegerDBIDKNNList;
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.query.knn.DoubleOptimizedDistanceKNNQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.LinearScanDistanceKNNQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.LinearScanEuclideanDistanceKNNQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.LinearScanPrimitiveDistanceKNNQuery;
-import de.lmu.ifi.dbs.elki.database.query.range.DoubleOptimizedDistanceRangeQuery;
import de.lmu.ifi.dbs.elki.database.query.range.LinearScanDistanceRangeQuery;
+import de.lmu.ifi.dbs.elki.database.query.range.LinearScanEuclideanDistanceRangeQuery;
import de.lmu.ifi.dbs.elki.database.query.range.LinearScanPrimitiveDistanceRangeQuery;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery;
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.distancefunction.PrimitiveDoubleDistanceFunction;
-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.distancefunction.minkowski.EuclideanDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction;
/**
@@ -63,13 +65,12 @@ public final class QueryUtil {
* a relation.
*
* @param <O> Object type
- * @param <D> Distance type
* @param database Database
* @param distanceFunction Distance function
* @param hints Optimizer hints
* @return Distance query
*/
- public static <O, D extends Distance<D>> DistanceQuery<O, D> getDistanceQuery(Database database, DistanceFunction<? super O, D> distanceFunction, Object... hints) {
+ public static <O> DistanceQuery<O> getDistanceQuery(Database database, DistanceFunction<? super O> distanceFunction, Object... hints) {
final Relation<O> objectQuery = database.getRelation(distanceFunction.getInputTypeRestriction(), hints);
return database.getDistanceQuery(objectQuery, distanceFunction, hints);
}
@@ -78,13 +79,12 @@ public final class QueryUtil {
* Get a similarity query, automatically choosing a relation.
*
* @param <O> Object type
- * @param <D> Distance type
* @param database Database
* @param similarityFunction Similarity function
* @param hints Optimizer hints
* @return Similarity Query
*/
- public static <O, D extends Distance<D>> SimilarityQuery<O, D> getSimilarityQuery(Database database, SimilarityFunction<? super O, D> similarityFunction, Object... hints) {
+ public static <O> SimilarityQuery<O> getSimilarityQuery(Database database, SimilarityFunction<? super O> similarityFunction, Object... hints) {
final Relation<O> objectQuery = database.getRelation(similarityFunction.getInputTypeRestriction(), hints);
return database.getSimilarityQuery(objectQuery, similarityFunction, hints);
}
@@ -103,15 +103,14 @@ public final class QueryUtil {
* </ul>
*
* @param <O> Object type
- * @param <D> Distance type
* @param database Database
* @param distanceFunction Distance function
* @param hints Optimizer hints
* @return KNN Query object
*/
- public static <O, D extends Distance<D>> KNNQuery<O, D> getKNNQuery(Database database, DistanceFunction<? super O, D> distanceFunction, Object... hints) {
+ public static <O> KNNQuery<O> getKNNQuery(Database database, DistanceFunction<? super O> distanceFunction, Object... hints) {
final Relation<O> relation = database.getRelation(distanceFunction.getInputTypeRestriction(), hints);
- final DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints);
+ final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints);
return database.getKNNQuery(distanceQuery, hints);
}
@@ -133,12 +132,11 @@ public final class QueryUtil {
* @param hints Optimizer hints
*
* @param <O> Object type
- * @param <D> Distance type
* @return KNN Query object
*/
- public static <O, D extends Distance<D>> KNNQuery<O, D> getKNNQuery(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, Object... hints) {
+ public static <O> KNNQuery<O> getKNNQuery(Relation<O> relation, DistanceFunction<? super O> distanceFunction, Object... hints) {
final Database database = relation.getDatabase();
- final DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints);
+ final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints);
return database.getKNNQuery(distanceQuery, hints);
}
@@ -156,15 +154,14 @@ public final class QueryUtil {
* </ul>
*
* @param <O> Object type
- * @param <D> Distance type
* @param database Database
* @param distanceFunction Distance function
* @param hints Optimizer hints
* @return KNN Query object
*/
- public static <O, D extends Distance<D>> RangeQuery<O, D> getRangeQuery(Database database, DistanceFunction<? super O, D> distanceFunction, Object... hints) {
+ public static <O> RangeQuery<O> getRangeQuery(Database database, DistanceFunction<? super O> distanceFunction, Object... hints) {
final Relation<O> relation = database.getRelation(distanceFunction.getInputTypeRestriction(), hints);
- final DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints);
+ final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints);
return database.getRangeQuery(distanceQuery, hints);
}
@@ -186,12 +183,11 @@ public final class QueryUtil {
* @param hints Optimizer hints
*
* @param <O> Object type
- * @param <D> Distance type
* @return KNN Query object
*/
- public static <O, D extends Distance<D>> RangeQuery<O, D> getRangeQuery(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, Object... hints) {
+ public static <O> RangeQuery<O> getRangeQuery(Relation<O> relation, DistanceFunction<? super O> distanceFunction, Object... hints) {
final Database database = relation.getDatabase();
- final DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints);
+ final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints);
return database.getRangeQuery(distanceQuery, hints);
}
@@ -213,12 +209,11 @@ public final class QueryUtil {
* @param hints Optimizer hints
*
* @param <O> Object type
- * @param <D> Distance type
* @return RKNN Query object
*/
- public static <O, D extends Distance<D>> RKNNQuery<O, D> getRKNNQuery(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, Object... hints) {
+ public static <O> RKNNQuery<O> getRKNNQuery(Relation<O> relation, DistanceFunction<? super O> distanceFunction, Object... hints) {
final Database database = relation.getDatabase();
- final DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints);
+ final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints);
return database.getRKNNQuery(distanceQuery, hints);
}
@@ -226,25 +221,19 @@ public final class QueryUtil {
* Get a linear scan query for the given distance query.
*
* @param <O> Object type
- * @param <D> Distance type
* @param distanceQuery distance query
* @return KNN query
*/
- public static <O, D extends Distance<D>> KNNQuery<O, D> getLinearScanKNNQuery(DistanceQuery<O, D> distanceQuery) {
+ @SuppressWarnings("unchecked")
+ public static <O> KNNQuery<O> getLinearScanKNNQuery(DistanceQuery<O> distanceQuery) {
// Slight optimizations of linear scans
if(distanceQuery instanceof PrimitiveDistanceQuery) {
- if(distanceQuery.getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction) {
- final PrimitiveDistanceQuery<O, ?> pdq = (PrimitiveDistanceQuery<O, ?>) distanceQuery;
- @SuppressWarnings("unchecked")
- final KNNQuery<O, ?> knnQuery = new DoubleOptimizedDistanceKNNQuery<>((PrimitiveDistanceQuery<O, DoubleDistance>) pdq);
- @SuppressWarnings("unchecked")
- final KNNQuery<O, D> castQuery = (KNNQuery<O, D>) knnQuery;
- return castQuery;
- }
- else {
- final PrimitiveDistanceQuery<O, D> pdq = (PrimitiveDistanceQuery<O, D>) distanceQuery;
- return new LinearScanPrimitiveDistanceKNNQuery<>(pdq);
+ final PrimitiveDistanceQuery<O> pdq = (PrimitiveDistanceQuery<O>) distanceQuery;
+ if (EuclideanDistanceFunction.STATIC.equals(pdq.getDistanceFunction())) {
+ final PrimitiveDistanceQuery<NumberVector> ndq = (PrimitiveDistanceQuery<NumberVector>)pdq;
+ return (KNNQuery<O>) new LinearScanEuclideanDistanceKNNQuery<>(ndq);
}
+ return new LinearScanPrimitiveDistanceKNNQuery<>(pdq);
}
return new LinearScanDistanceKNNQuery<>(distanceQuery);
}
@@ -253,26 +242,34 @@ public final class QueryUtil {
* Get a linear scan query for the given distance query.
*
* @param <O> Object type
- * @param <D> Distance type
* @param distanceQuery distance query
* @return Range query
*/
- public static <O, D extends Distance<D>> RangeQuery<O, D> getLinearScanRangeQuery(DistanceQuery<O, D> distanceQuery) {
+ @SuppressWarnings("unchecked")
+ public static <O> RangeQuery<O> getLinearScanRangeQuery(DistanceQuery<O> distanceQuery) {
// Slight optimizations of linear scans
if(distanceQuery instanceof PrimitiveDistanceQuery) {
- if(distanceQuery.getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction) {
- final PrimitiveDistanceQuery<O, ?> pdq = (PrimitiveDistanceQuery<O, ?>) distanceQuery;
- @SuppressWarnings("unchecked")
- final RangeQuery<O, ?> knnQuery = new DoubleOptimizedDistanceRangeQuery<>((PrimitiveDistanceQuery<O, DoubleDistance>) pdq);
- @SuppressWarnings("unchecked")
- final RangeQuery<O, D> castQuery = (RangeQuery<O, D>) knnQuery;
- return castQuery;
- }
- else {
- final PrimitiveDistanceQuery<O, D> pdq = (PrimitiveDistanceQuery<O, D>) distanceQuery;
- return new LinearScanPrimitiveDistanceRangeQuery<>(pdq);
+ final PrimitiveDistanceQuery<O> pdq = (PrimitiveDistanceQuery<O>) distanceQuery;
+ if (EuclideanDistanceFunction.STATIC.equals(pdq.getDistanceFunction())) {
+ final PrimitiveDistanceQuery<NumberVector> ndq = (PrimitiveDistanceQuery<NumberVector>)pdq;
+ return (RangeQuery<O>) new LinearScanEuclideanDistanceRangeQuery<>(ndq);
}
+ return new LinearScanPrimitiveDistanceRangeQuery<>(pdq);
}
return new LinearScanDistanceRangeQuery<>(distanceQuery);
}
+
+ /**
+ * Apply the square root function to each value in the list.
+ *
+ * @param knnList kNN list
+ * @return new list, after taking the square root
+ */
+ public static KNNList applySqrt(KNNList knnList) {
+ DoubleIntegerDBIDKNNList ret = new DoubleIntegerDBIDKNNList(knnList.getK(), knnList.size());
+ for(DoubleDBIDListIter iter = knnList.iter(); iter.valid(); iter.advance()) {
+ ret.add(Math.sqrt(iter.doubleValue()), iter);
+ }
+ return ret;
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/StaticArrayDatabase.java b/src/de/lmu/ifi/dbs/elki/database/StaticArrayDatabase.java
index 2fc4a5bb..8b34583f 100644
--- a/src/de/lmu/ifi/dbs/elki/database/StaticArrayDatabase.java
+++ b/src/de/lmu/ifi/dbs/elki/database/StaticArrayDatabase.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database;
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,12 +27,10 @@ import java.util.BitSet;
import java.util.Collection;
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.ArrayDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayStaticDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.DBIDView;
import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
@@ -45,7 +43,6 @@ import de.lmu.ifi.dbs.elki.index.IndexFactory;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.statistics.Duration;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
@@ -63,7 +60,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.uses DatabaseConnection
*/
@Description("Database using an in-memory hashtable and at least providing linear scans.")
-public class StaticArrayDatabase extends AbstractDatabase implements Parameterizable {
+public class StaticArrayDatabase extends AbstractDatabase {
/**
* Our logger
*/
@@ -72,7 +69,7 @@ public class StaticArrayDatabase extends AbstractDatabase implements Parameteriz
/**
* IDs of this database
*/
- private ArrayDBIDs ids;
+ private ArrayStaticDBIDs ids;
/**
* The DBID representation we use
@@ -123,26 +120,22 @@ public class StaticArrayDatabase extends AbstractDatabase implements Parameteriz
// Run at most once.
databaseConnection = null;
- // Find DBID column
- int idrepnr = findDBIDColumn(objpackages);
- // Build DBID array
- final int numObjects = objpackages.dataLength();
- if(LOG.isDebugging()) {
- LOG.debugFine("Importing " + numObjects + " instances.");
- }
- if(idrepnr == -1) {
- this.ids = DBIDUtil.generateStaticDBIDRange(numObjects);
- }
- else {
- final ArrayModifiableDBIDs newids = DBIDUtil.newArray(numObjects);
- for(int j = 0; j < numObjects; j++) {
- DBID newid = (DBID) objpackages.data(j, idrepnr);
- newids.add(newid);
+ // Find DBIDs for bundle
+ int numObjects = objpackages.dataLength();
+ {
+ DBIDs bids = objpackages.getDBIDs();
+ if(bids instanceof ArrayStaticDBIDs) {
+ this.ids = (ArrayStaticDBIDs) bids;
+ }
+ else if(bids == null) {
+ this.ids = DBIDUtil.generateStaticDBIDRange(objpackages.dataLength());
+ }
+ else {
+ this.ids = (ArrayStaticDBIDs) DBIDUtil.makeUnmodifiable(bids);
}
- this.ids = newids;
}
- // Replace id representation.
- // TODO: this is an ugly hack
+ // Replace id representation (it would be nicer if we would not need
+ // DBIDView at all)
this.idrep = new DBIDView(this, this.ids);
relations.add(this.idrep);
getHierarchy().add(this, idrep);
@@ -154,10 +147,6 @@ public class StaticArrayDatabase extends AbstractDatabase implements Parameteriz
for(int j = 0; j < numObjects; j++, newid.advance()) {
// insert object
for(int i = 0; i < targets.length; i++) {
- // DBIDs were handled above.
- if(i == idrepnr) {
- continue;
- }
@SuppressWarnings("unchecked")
final Relation<Object> relation = (Relation<Object>) targets[i];
relation.set(newid, objpackages.data(j, i));
@@ -174,14 +163,10 @@ public class StaticArrayDatabase extends AbstractDatabase implements Parameteriz
@SuppressWarnings("unchecked")
final Relation<Object> orep = (Relation<Object>) relation;
final Index index = ofact.instantiate(orep);
- Duration duration = LOG.isStatistics() ? LOG.newDuration(index.getClass().getName() + ".construction") : null;
- if(duration != null) {
- duration.begin();
- }
+ Duration duration = LOG.isStatistics() ? LOG.newDuration(index.getClass().getName() + ".construction").begin() : null;
index.initialize();
if(duration != null) {
- duration.end();
- LOG.statistics(duration);
+ LOG.statistics(duration.end());
}
addIndex(index);
}
@@ -204,22 +189,6 @@ public class StaticArrayDatabase extends AbstractDatabase implements Parameteriz
}
/**
- * Find an DBID column.
- *
- * @param pack Package to process
- * @return DBID column
- */
- protected int findDBIDColumn(ObjectBundle pack) {
- for(int i = 0; i < pack.metaLength(); i++) {
- SimpleTypeInformation<?> meta = pack.meta(i);
- if(TypeUtil.DBID.isAssignableFromType(meta)) {
- return i;
- }
- }
- return -1;
- }
-
- /**
* Find a mapping from package columns to database columns, eventually adding
* new database columns when needed.
*
diff --git a/src/de/lmu/ifi/dbs/elki/database/UpdatableDatabase.java b/src/de/lmu/ifi/dbs/elki/database/UpdatableDatabase.java
index f22dd799..b7ae2d0a 100644
--- a/src/de/lmu/ifi/dbs/elki/database/UpdatableDatabase.java
+++ b/src/de/lmu/ifi/dbs/elki/database/UpdatableDatabase.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database;
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
@@ -41,9 +41,8 @@ public interface UpdatableDatabase extends Database {
*
* @param objpackages the objects to be inserted
* @return the IDs assigned to the inserted objects
- * @throws UnableToComplyException if insertion is not possible
*/
- DBIDs insert(ObjectBundle objpackages) throws UnableToComplyException;
+ DBIDs insert(ObjectBundle objpackages);
/**
* Removes and returns the specified objects with the given ids from the
diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/DBIDDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DBIDDataStore.java
index 8c0eb2cb..8100fb66 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/DBIDDataStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DBIDDataStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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/database/datastore/DataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStore.java
index 384680c6..368488f2 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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/database/datastore/DataStoreEvent.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreEvent.java
index 7942fb9b..5b374a4e 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreEvent.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreEvent.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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/database/datastore/DataStoreFactory.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreFactory.java
index 7b3cd0e7..2695f51f 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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,8 +34,11 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
* @author Erich Schubert
*
* @apiviz.stereotype factory,interface
- * @apiviz.uses WritableDataStore oneway - - «create»
- * @apiviz.uses WritableRecordStore oneway - - «create»
+ * @apiviz.has WritableDataStore oneway - - «create»
+ * @apiviz.has WritableIntegerDataStore oneway - - «create»
+ * @apiviz.has WritableDoubleDataStore oneway - - «create»
+ * @apiviz.has WritableDBIDDataStore oneway - - «create»
+ * @apiviz.has WritableRecordStore oneway - - «create»
*/
public interface DataStoreFactory {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreIDMap.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreIDMap.java
index adfd1354..215c660f 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreIDMap.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreIDMap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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/database/datastore/DataStoreListener.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreListener.java
index a3f1319d..e437af78 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreListener.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreListener.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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/database/datastore/DataStoreUtil.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreUtil.java
index 6d0c2d0f..5369dda9 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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,10 @@ package de.lmu.ifi.dbs.elki.database.datastore;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.Comparator;
+
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
/**
* Storage utility class. Mostly a shorthand for
@@ -126,15 +128,60 @@ public final class DataStoreUtil {
}
/**
- * Make a new storage, to associate the given ids with an double valued
- * distance.
+ * Sort objects by a double relation
*
- * @param ids DBIDs to store data for
- * @param hints Hints for the storage manager
- * @return new data store
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
*/
- public static WritableDoubleDistanceDataStore makeDoubleDistanceStorage(DBIDs ids, int hints) {
- // FIXME: this is an ugly work-around.
- return (WritableDoubleDistanceDataStore) DataStoreFactory.FACTORY.makeStorage(ids, hints, DoubleDistance.class);
+ public static class AscendingByDoubleDataStore implements Comparator<DBIDRef> {
+ /**
+ * Scores to use for sorting.
+ */
+ private final DoubleDataStore scores;
+
+ /**
+ * Constructor.
+ *
+ * @param scores Scores for sorting
+ */
+ public AscendingByDoubleDataStore(DoubleDataStore scores) {
+ super();
+ this.scores = scores;
+ }
+
+ @Override
+ public int compare(DBIDRef id1, DBIDRef id2) {
+ return Double.compare(scores.doubleValue(id1), scores.doubleValue(id2));
+ }
+ }
+
+ /**
+ * Sort objects by a double relation
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class DescendingByDoubleDataStore implements Comparator<DBIDRef> {
+ /**
+ * Scores to use for sorting.
+ */
+ private final DoubleDataStore scores;
+
+ /**
+ * Constructor.
+ *
+ * @param scores Scores for sorting
+ */
+ public DescendingByDoubleDataStore(DoubleDataStore scores) {
+ super();
+ this.scores = scores;
+ }
+
+ @Override
+ public int compare(DBIDRef id1, DBIDRef id2) {
+ return Double.compare(scores.doubleValue(id2), scores.doubleValue(id1));
+ }
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/DoubleDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DoubleDataStore.java
index b121d195..0995d40a 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/DoubleDataStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DoubleDataStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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/database/datastore/IntegerDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/IntegerDataStore.java
index 969e2228..45b5f43c 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/IntegerDataStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/IntegerDataStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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/database/datastore/RecordStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/RecordStore.java
index 07bf2dcf..e7f6adc1 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/RecordStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/RecordStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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/database/datastore/WritableDBIDDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDBIDDataStore.java
index bae55a57..d7bf02bc 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDBIDDataStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDBIDDataStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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/database/datastore/WritableDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDataStore.java
index c62fc721..c746eda3 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDataStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDataStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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/database/datastore/WritableDoubleDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDataStore.java
index a40f0ef4..7755d0de 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDataStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDataStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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
@@ -61,4 +61,18 @@ public interface WritableDoubleDataStore extends DoubleDataStore, WritableDataSt
* @return previous value
*/
public double put(DBIDRef id, double value);
+
+
+ /**
+ * Increment the specified value with the specified id in this storage.
+ *
+ * @param id Database ID.
+ * @param value Value to add to the previous value.
+ */
+ public void increment(DBIDRef id, double value);
+
+ /**
+ * Reinitialize (reset to default value).
+ */
+ public void clear();
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDistanceDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDistanceDataStore.java
deleted file mode 100644
index f929d5d7..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDistanceDataStore.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.datastore;
-
-/*
- 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.distance.distancevalue.DoubleDistance;
-
-/**
- * Data store specialized for doubles. Avoids boxing/unboxing.
- *
- * @author Erich Schubert
- */
-public interface WritableDoubleDistanceDataStore extends DoubleDistanceDataStore, WritableDataStore<DoubleDistance> {
- /**
- * Setter, but using objects.
- *
- * @deprecated Use {@link #putDouble} instead, to avoid boxing/unboxing cost.
- */
- @Override
- @Deprecated
- public DoubleDistance put(DBIDRef id, DoubleDistance value);
-
- /**
- * Associates the specified value with the specified id in this storage. If
- * the storage previously contained a value for the id, the previous value is
- * replaced by the specified value.
- *
- * @param id Database ID.
- * @param value Value to store.
- * @return previous value
- */
- public double putDouble(DBIDRef id, double value);
-
- /**
- * Associates the specified value with the specified id in this storage. If
- * the storage previously contained a value for the id, the previous value is
- * replaced by the specified value.
- *
- * @param id Database ID.
- * @param value Value to store.
- * @return previous value
- */
- public double put(DBIDRef id, double value);
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableIntegerDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableIntegerDataStore.java
index fb323b02..2c0e61e9 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableIntegerDataStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableIntegerDataStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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/database/datastore/WritableRecordStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableRecordStore.java
index c4c182e9..8d0c58fd 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableRecordStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableRecordStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore;
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/database/datastore/memory/ArrayDBIDStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDBIDStore.java
index 78cb51d2..2134c75a 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDBIDStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDBIDStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory;
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/database/datastore/memory/ArrayDoubleDistanceStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleDistanceStore.java
deleted file mode 100644
index abb81d95..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleDistanceStore.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.datastore.memory;
-
-/*
- 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.Arrays;
-
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreIDMap;
-import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDistanceDataStore;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-
-/**
- * A class to answer representation queries using the stored Array.
- *
- * @author Erich Schubert
- *
- * @apiviz.composedOf de.lmu.ifi.dbs.elki.database.datastore.DataStoreIDMap
- */
-public class ArrayDoubleDistanceStore implements WritableDoubleDistanceDataStore {
- /**
- * Data array
- */
- private double[] data;
-
- /**
- * DBID to index map
- */
- private DataStoreIDMap idmap;
-
- /**
- * Constructor.
- *
- * @param size Size
- * @param idmap ID map
- */
- public ArrayDoubleDistanceStore(int size, DataStoreIDMap idmap) {
- this(size, idmap, Double.NaN);
- }
-
- /**
- * Constructor.
- *
- * @param size Size
- * @param idmap ID map
- * @param def Default value
- */
- public ArrayDoubleDistanceStore(int size, DataStoreIDMap idmap, double def) {
- super();
- this.data = new double[size];
- if (def != 0) {
- Arrays.fill(this.data, def);
- }
- this.idmap = idmap;
- }
-
- @Override
- @Deprecated
- public DoubleDistance get(DBIDRef id) {
- return new DoubleDistance(data[idmap.mapDBIDToOffset(id)]);
- }
-
- @Override
- @Deprecated
- public DoubleDistance put(DBIDRef id, DoubleDistance value) {
- final int off = idmap.mapDBIDToOffset(id);
- double ret = data[off];
- data[off] = value.doubleValue();
- return new DoubleDistance(ret);
- }
-
- @Override
- public double doubleValue(DBIDRef id) {
- return data[idmap.mapDBIDToOffset(id)];
- }
-
- @Override
- public double putDouble(DBIDRef id, double value) {
- final int off = idmap.mapDBIDToOffset(id);
- final double ret = data[off];
- data[off] = value;
- return ret;
- }
-
- @Override
- public double put(DBIDRef id, double value) {
- final int off = idmap.mapDBIDToOffset(id);
- final double ret = data[off];
- data[off] = value;
- return ret;
- }
-
- @Override
- public void destroy() {
- data = null;
- idmap = null;
- }
-
- @Override
- public void delete(DBIDRef id) {
- throw new UnsupportedOperationException("Can't delete from a static array storage.");
- }
-
- @Override
- public String getLongName() {
- return "raw";
- }
-
- @Override
- public String getShortName() {
- return "raw";
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleStore.java
index c41991eb..8b2ec127 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory;
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
@@ -41,6 +41,11 @@ public class ArrayDoubleStore implements WritableDoubleDataStore {
* Data array
*/
private double[] data;
+
+ /**
+ * Default value.
+ */
+ private double def;
/**
* DBID to index map
@@ -67,9 +72,10 @@ public class ArrayDoubleStore implements WritableDoubleDataStore {
public ArrayDoubleStore(int size, DataStoreIDMap idmap, double def) {
super();
this.data = new double[size];
- if (def != 0) {
+ if(def != 0) {
Arrays.fill(this.data, def);
}
+ this.def = def;
this.idmap = idmap;
}
@@ -110,6 +116,16 @@ public class ArrayDoubleStore implements WritableDoubleDataStore {
}
@Override
+ public void increment(DBIDRef id, double value) {
+ data[idmap.mapDBIDToOffset(id)] += value;
+ }
+
+ @Override
+ public void clear() {
+ Arrays.fill(data, def);
+ }
+
+ @Override
public void destroy() {
data = null;
idmap = null;
diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayIntegerStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayIntegerStore.java
index b8a76646..29541065 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayIntegerStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayIntegerStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory;
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/database/datastore/memory/ArrayRecordStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayRecordStore.java
index e9c78cb7..2fac747f 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayRecordStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayRecordStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory;
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/database/datastore/memory/ArrayStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayStore.java
index 695ddc48..b0e5add8 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory;
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/database/datastore/memory/MapIntegerDBIDDBIDStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDBIDStore.java
index 9b8a4be8..ed60cf0a 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDBIDStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDBIDStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory;
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
@@ -50,7 +50,7 @@ public class MapIntegerDBIDDBIDStore implements WritableDBIDDataStore {
*/
public MapIntegerDBIDDBIDStore(int size) {
super();
- map = new TIntIntHashMap(size, 0.5f, Integer.MIN_VALUE, DBIDUtil.invalid().internalGetIndex());
+ map = new TIntIntHashMap(size, 0.5f, Integer.MIN_VALUE, DBIDUtil.asInteger(DBIDUtil.invalid()));
}
@Override
@@ -72,7 +72,7 @@ public class MapIntegerDBIDDBIDStore implements WritableDBIDDataStore {
@Override
@Deprecated
public DBID put(DBIDRef id, DBID value) {
- return DBIDUtil.importInteger(map.put(id.internalGetIndex(), value.internalGetIndex()));
+ return DBIDUtil.importInteger(map.put(DBIDUtil.asInteger(id), DBIDUtil.asInteger(value)));
}
@Override
@@ -88,17 +88,17 @@ public class MapIntegerDBIDDBIDStore implements WritableDBIDDataStore {
@Override
public void put(DBIDRef id, DBIDRef value) {
- map.put(id.internalGetIndex(), value.internalGetIndex());
+ map.put(DBIDUtil.asInteger(id), DBIDUtil.asInteger(value));
}
@Override
public void putDBID(DBIDRef id, DBIDRef value) {
- map.put(id.internalGetIndex(), value.internalGetIndex());
+ map.put(DBIDUtil.asInteger(id), DBIDUtil.asInteger(value));
}
@Override
public void assignVar(DBIDRef id, DBIDVar var) {
- final int val = map.get(id.internalGetIndex());
+ final int val = map.get(DBIDUtil.asInteger(id));
DBIDFactory.FACTORY.assignVar(var, val);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleDistanceStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleDistanceStore.java
deleted file mode 100644
index be12b54c..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleDistanceStore.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.datastore.memory;
-
-/*
- 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 gnu.trove.map.TIntDoubleMap;
-import gnu.trove.map.hash.TIntDoubleHashMap;
-import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDistanceDataStore;
-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;
-
-/**
- * Writable data store for double values.
- *
- * @author Erich Schubert
- */
-public class MapIntegerDBIDDoubleDistanceStore implements WritableDoubleDistanceDataStore {
- /**
- * Data storage.
- */
- private TIntDoubleMap map;
-
- /**
- * Constructor.
- *
- * @param size Expected size
- */
- public MapIntegerDBIDDoubleDistanceStore(int size) {
- this(size, Double.NaN);
- }
-
- /**
- * Constructor.
- *
- * @param size Expected size
- * @param def Default value
- */
- public MapIntegerDBIDDoubleDistanceStore(int size, double def) {
- super();
- map = new TIntDoubleHashMap(size, 0.5f, Integer.MIN_VALUE, def);
- }
-
- @Override
- @Deprecated
- public DoubleDistance get(DBIDRef id) {
- return new DoubleDistance(map.get(DBIDUtil.asInteger(id)));
- }
-
- @Override
- public double doubleValue(DBIDRef id) {
- return map.get(DBIDUtil.asInteger(id));
- }
-
- @Override
- public String getLongName() {
- return "raw";
- }
-
- @Override
- public String getShortName() {
- return "raw";
- }
-
- @Override
- @Deprecated
- public DoubleDistance put(DBIDRef id, DoubleDistance value) {
- return new DoubleDistance(map.put(DBIDUtil.asInteger(id), value.doubleValue()));
- }
-
- @Override
- public void destroy() {
- map.clear();
- map = null;
- }
-
- @Override
- public void delete(DBIDRef id) {
- map.remove(DBIDUtil.asInteger(id));
- }
-
- @Override
- public double putDouble(DBIDRef id, double value) {
- return map.put(DBIDUtil.asInteger(id), value);
- }
-
- @Override
- public double put(DBIDRef id, double value) {
- return map.put(DBIDUtil.asInteger(id), value);
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleStore.java
index 8d73b672..8779eb46 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory;
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
@@ -88,12 +88,6 @@ public class MapIntegerDBIDDoubleStore implements WritableDoubleDataStore {
}
@Override
- public void destroy() {
- map.clear();
- map = null;
- }
-
- @Override
public void delete(DBIDRef id) {
map.remove(DBIDUtil.asInteger(id));
}
@@ -107,4 +101,20 @@ public class MapIntegerDBIDDoubleStore implements WritableDoubleDataStore {
public double put(DBIDRef id, double value) {
return map.put(DBIDUtil.asInteger(id), value);
}
+
+ @Override
+ public void increment(DBIDRef id, double value) {
+ map.adjustOrPutValue(DBIDUtil.asInteger(id), value, map.getNoEntryValue() + value);
+ }
+
+ @Override
+ public void clear() {
+ map.clear();
+ }
+
+ @Override
+ public void destroy() {
+ map.clear();
+ map = null;
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDIntegerStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDIntegerStore.java
index 935f23f4..2f2a42a2 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDIntegerStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDIntegerStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory;
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/database/datastore/memory/MapIntegerDBIDRecordStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDRecordStore.java
index 9efe2221..7963b78c 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDRecordStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDRecordStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory;
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/database/datastore/memory/MapIntegerDBIDStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDStore.java
index ede82f15..55402703 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory;
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/database/datastore/memory/MapRecordStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapRecordStore.java
index 045d5bf4..6b5b1a50 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapRecordStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapRecordStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory;
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/database/datastore/memory/MapStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapStore.java
index c40e0a72..3432e124 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory;
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/database/datastore/memory/MemoryDataStoreFactory.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MemoryDataStoreFactory.java
index 2a6cd1cb..2ad2dd05 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MemoryDataStoreFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MemoryDataStoreFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory;
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,12 +27,10 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDBIDDataStore;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
-import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDistanceDataStore;
import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
import de.lmu.ifi.dbs.elki.database.datastore.WritableRecordStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRange;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
/**
* Simple factory class that will store all data in memory using object arrays
@@ -44,18 +42,15 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
* @author Erich Schubert
*
* @apiviz.stereotype factory
- * @apiviz.uses ArrayStore oneway - - «create»
- * @apiviz.uses ArrayRecordStore oneway - - «create»
- * @apiviz.uses MapStore oneway - - «create»
- * @apiviz.uses MapRecordStore oneway - - «create»
+ * @apiviz.has ArrayStore oneway - - «create»
+ * @apiviz.has ArrayRecordStore oneway - - «create»
+ * @apiviz.has MapStore oneway - - «create»
+ * @apiviz.has MapRecordStore oneway - - «create»
*/
public class MemoryDataStoreFactory implements DataStoreFactory {
@SuppressWarnings("unchecked")
@Override
public <T> WritableDataStore<T> makeStorage(DBIDs ids, int hints, Class<? super T> dataclass) {
- if (DoubleDistance.class.equals(dataclass)) {
- return (WritableDataStore<T>) makeDoubleDistanceStorage(ids, hints);
- }
if (Double.class.equals(dataclass)) {
return (WritableDataStore<T>) makeDoubleStorage(ids, hints);
}
@@ -83,23 +78,6 @@ public class MemoryDataStoreFactory implements DataStoreFactory {
}
}
- /**
- * Make a data storage for double distances.
- *
- * @param ids IDs to store for
- * @param hints Storage hints
- * @return double distance storage
- */
- public WritableDoubleDistanceDataStore makeDoubleDistanceStorage(DBIDs ids, int hints) {
- if(ids instanceof DBIDRange) {
- DBIDRange range = (DBIDRange) ids;
- return new ArrayDoubleDistanceStore(range.size(), range);
- }
- else {
- return new MapIntegerDBIDDoubleDistanceStore(ids.size());
- }
- }
-
@Override
public WritableDoubleDataStore makeDoubleStorage(DBIDs ids, int hints) {
if(ids instanceof DBIDRange) {
@@ -155,4 +133,4 @@ public class MemoryDataStoreFactory implements DataStoreFactory {
return new MapIntegerDBIDRecordStore(ids.size(), dataclasses.length);
}
}
-} \ No newline at end of file
+}
diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/package-info.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/package-info.java
index 5ea46015..dada2a9b 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/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/database/datastore/package-info.java b/src/de/lmu/ifi/dbs/elki/database/datastore/package-info.java
index f213019d..aa15d1c2 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/database/datastore/package-info.java
@@ -24,7 +24,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/database/ids/ArrayDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/ArrayDBIDs.java
index 5839a2e0..3cca1242 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/ArrayDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/ArrayDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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/database/ids/ArrayModifiableDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/ArrayModifiableDBIDs.java
index 3db40630..0554a0e2 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/ArrayModifiableDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/ArrayModifiableDBIDs.java
@@ -6,7 +6,7 @@ import java.util.Comparator;
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/database/ids/ArrayStaticDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/ArrayStaticDBIDs.java
index 47cf295f..6328f375 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/ArrayStaticDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/ArrayStaticDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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/database/ids/DBID.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBID.java
index a773ee27..c46b13bd 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/DBID.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBID.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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/database/ids/DBIDArrayIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayIter.java
index ef1132b3..c5cf171a 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayIter.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayIter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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,5 +30,15 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.ArrayIter;
* @author Erich Schubert
*/
public interface DBIDArrayIter extends DBIDIter, ArrayIter {
- // Nothing added - see {@link ArrayIter}!
+ @Override
+ DBIDArrayIter advance();
+
+ @Override
+ DBIDArrayIter advance(int count);
+
+ @Override
+ DBIDArrayIter retract();
+
+ @Override
+ DBIDArrayIter seek(int off);
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayMIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayMIter.java
index 1aaefc8e..9700de1b 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayMIter.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayMIter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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/database/ids/DBIDFactory.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDFactory.java
index 1b269eea..58cf5791 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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,15 +23,9 @@ package de.lmu.ifi.dbs.elki.database.ids;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
import de.lmu.ifi.dbs.elki.database.ids.integer.TrivialDBIDFactory;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
-import de.lmu.ifi.dbs.elki.persistent.FixedSizeByteBufferSerializer;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
+import de.lmu.ifi.dbs.elki.utilities.io.FixedSizeByteBufferSerializer;
/**
* Factory interface for generating DBIDs. See {@link #FACTORY} for the static
@@ -106,6 +100,15 @@ public interface DBIDFactory {
DBIDRange generateStaticDBIDRange(int size);
/**
+ * Generate a static DBID range.
+ *
+ * @param begin Range begin
+ * @param size Requested size
+ * @return DBID range
+ */
+ DBIDRange generateStaticDBIDRange(int begin, int size);
+
+ /**
* Deallocate a static DBID range.
*
* @param range Range to deallocate
@@ -132,25 +135,6 @@ public interface DBIDFactory {
DoubleDBIDPair newPair(double val, DBIDRef id);
/**
- * Make a new distance-DBID pair.
- *
- * @param val Distance value
- * @param id Object ID
- * @param <D> Distance type
- * @return New pair
- */
- <D extends Distance<D>> DistanceDBIDPair<D> newDistancePair(D val, DBIDRef id);
-
- /**
- * Make a new distance-DBID pair.
- *
- * @param val Distance value
- * @param id Object ID
- * @return New pair
- */
- DoubleDistanceDBIDPair newDistancePair(double val, DBIDRef id);
-
- /**
* Make a new (modifiable) array of DBIDs.
*
* @return New array
@@ -197,33 +181,20 @@ public interface DBIDFactory {
HashSetModifiableDBIDs newHashSet(DBIDs existing);
/**
- * Create an appropriate heap for the distance function.
- *
- * This will use a double heap if appropriate.
+ * Create an heap for kNN search.
*
- * @param factory distance prototype
* @param k K value
- * @param <D> distance type
- * @return New heap of size k, appropriate for this distance type.
+ * @return New heap of size k.
*/
- <D extends Distance<D>> KNNHeap<D> newHeap(D factory, int k);
+ KNNHeap newHeap(int k);
/**
* Build a new heap from a given list.
*
* @param exist Existing result
- * @param <D> Distance type
* @return New heap
*/
- <D extends Distance<D>> KNNHeap<D> newHeap(KNNList<D> exist);
-
- /**
- * Create an appropriate heap for double distances.
- *
- * @param k K value
- * @return New heap of size k, appropriate for this distance type.
- */
- DoubleDistanceKNNHeap newDoubleDistanceHeap(int k);
+ KNNHeap newHeap(KNNList exist);
/**
* Get a serializer for DBIDs.
@@ -278,4 +249,19 @@ public interface DBIDFactory {
* @return Invalid value
*/
DBIDRef invalid();
+
+ /**
+ * Create a modifiable list to store distance-DBID pairs.
+ *
+ * @param size initial size estimate
+ * @return New list of given initial size
+ */
+ ModifiableDoubleDBIDList newDistanceDBIDList(int size);
+
+ /**
+ * Create a modifiable list to store distance-DBID pairs.
+ *
+ * @return New list
+ */
+ ModifiableDoubleDBIDList newDistanceDBIDList();
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDIter.java
index f051d51c..0c1bedba 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDIter.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDIter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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
@@ -54,9 +54,10 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter;
* </ul>
*
* @author Erich Schubert
- *
+ *
* @apiviz.landmark
*/
public interface DBIDIter extends DBIDRef, Iter {
- // Empty - use as DBIDRef or Iter
+ @Override
+ DBIDIter advance();
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDMIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDMIter.java
index 0fbed7e0..8778a5a3 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDMIter.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDMIter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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/database/ids/DBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDPair.java
index bdbbe2da..f8bcfb88 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDPair.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDPair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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,6 @@ package de.lmu.ifi.dbs.elki.database.ids;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.utilities.pairs.PairInterface;
-
/**
* Immutable pair of two DBIDs. This can be stored more efficiently than when
* using {@link de.lmu.ifi.dbs.elki.utilities.pairs.Pair}
@@ -33,21 +31,24 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.PairInterface;
*
* @apiviz.composedOf de.lmu.ifi.dbs.elki.database.ids.DBID
*/
-// TODO: implement DBIDs?
-public interface DBIDPair extends PairInterface<DBID, DBID> {
+public interface DBIDPair extends DBIDs {
/**
- * Getter for first
+ * Getter for first.
*
* @return first element in pair
+ * @deprecated This method can be expensive. The use of a {@link DBIDVar} is
+ * recommended when many such accesses are needed.
*/
- @Override
+ @Deprecated
public DBID getFirst();
/**
* Getter for second element in pair
*
* @return second element in pair
+ * @deprecated This method can be expensive. The use of a {@link DBIDVar} is
+ * recommended when many such accesses are needed.
*/
- @Override
+ @Deprecated
public DBID getSecond();
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRange.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRange.java
index 588cfe6a..1bd2d0d1 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRange.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRange.java
@@ -1,12 +1,10 @@
package de.lmu.ifi.dbs.elki.database.ids;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreIDMap;
-
/*
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 +23,8 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreIDMap;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreIDMap;
+
/**
* Static DBID range.
*
@@ -35,7 +35,7 @@ public interface DBIDRange extends ArrayStaticDBIDs, DataStoreIDMap {
* Get offset in the array for a particular DBID.
*
* Should satisfy {@code range.get(getOffset(id)) == id} and
- * {@code range.getOffset(range.get(idx)) == idx}.
+ * {@code range.getOffset(range.get(idx)) == idx}.
*
* @param dbid ID to compute index for
* @return index
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRef.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRef.java
index 77cc621e..8d7ee6b3 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRef.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRef.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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/database/ids/DBIDUtil.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDUtil.java
index c60e63ae..9c39fc77 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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,24 +25,19 @@ package de.lmu.ifi.dbs.elki.database.ids;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.DoubleDistanceKNNSubList;
import de.lmu.ifi.dbs.elki.database.ids.generic.KNNSubList;
import de.lmu.ifi.dbs.elki.database.ids.generic.UnmodifiableArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.generic.UnmodifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.integer.IntegerArrayDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.integer.IntegerDBIDKNNList;
+import de.lmu.ifi.dbs.elki.database.ids.integer.IntegerDBIDKNNSubList;
import de.lmu.ifi.dbs.elki.database.ids.integer.IntegerDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.integer.UnmodifiableIntegerArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.integer.UnmodifiableIntegerDBIDs;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
-import de.lmu.ifi.dbs.elki.utilities.UnsafeRandom;
+import de.lmu.ifi.dbs.elki.math.random.FastNonThreadsafeRandom;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
/**
* DBID Utility functions.
@@ -51,9 +46,8 @@ import de.lmu.ifi.dbs.elki.utilities.UnsafeRandom;
*
* @apiviz.landmark
*
- * @apiviz.has DBID
* @apiviz.has DBIDs
- * @apiviz.uses DBIDRef
+ * @apiviz.has DBIDRef
* @apiviz.composedOf DBIDFactory
*/
public final class DBIDUtil {
@@ -131,7 +125,7 @@ public final class DBIDUtil {
* @return DBID
*/
public static DBID deref(DBIDRef ref) {
- if (ref instanceof DBID) {
+ if(ref instanceof DBID) {
return (DBID) ref;
}
return importInteger(ref.internalGetIndex());
@@ -154,12 +148,12 @@ public final class DBIDUtil {
* @return String representation
*/
public static String toString(DBIDs ids) {
- if (ids instanceof DBID) {
+ if(ids instanceof DBID) {
return DBIDFactory.FACTORY.toString((DBID) ids);
}
StringBuilder buf = new StringBuilder();
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- if (buf.length() > 0) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ if(buf.length() > 0) {
buf.append(", ");
}
buf.append(DBIDFactory.FACTORY.toString(iter));
@@ -308,12 +302,12 @@ public final class DBIDUtil {
*/
// TODO: optimize better?
public static ModifiableDBIDs intersection(DBIDs first, DBIDs second) {
- if (first.size() > second.size()) {
+ if(first.size() > second.size()) {
return intersection(second, first);
}
ModifiableDBIDs inter = newHashSet(first.size());
- for (DBIDIter it = first.iter(); it.valid(); it.advance()) {
- if (second.contains(it)) {
+ for(DBIDIter it = first.iter(); it.valid(); it.advance()) {
+ if(second.contains(it)) {
inter.add(it);
}
}
@@ -329,20 +323,22 @@ public final class DBIDUtil {
*/
public static int intersectionSize(DBIDs first, DBIDs second) {
// If exactly one is a Set, use it as second parameter.
- if (second instanceof SetDBIDs) {
- if (!(first instanceof SetDBIDs)) {
+ if(second instanceof SetDBIDs) {
+ if(!(first instanceof SetDBIDs)) {
return internalIntersectionSize(first, second);
}
- } else {
- if (first instanceof SetDBIDs) {
+ }
+ else {
+ if(first instanceof SetDBIDs) {
return internalIntersectionSize(second, first);
}
}
// Both are the same type: both set or both non set.
// Smaller goes first.
- if (first.size() <= second.size()) {
+ if(first.size() <= second.size()) {
return internalIntersectionSize(first, second);
- } else {
+ }
+ else {
return internalIntersectionSize(second, first);
}
}
@@ -356,8 +352,8 @@ public final class DBIDUtil {
*/
private static int internalIntersectionSize(DBIDs first, DBIDs second) {
int c = 0;
- for (DBIDIter it = first.iter(); it.valid(); it.advance()) {
- if (second.contains(it)) {
+ for(DBIDIter it = first.iter(); it.valid(); it.advance()) {
+ if(second.contains(it)) {
c++;
}
}
@@ -375,7 +371,7 @@ public final class DBIDUtil {
*/
// TODO: optimize?
public static void symmetricIntersection(DBIDs first, DBIDs second, HashSetModifiableDBIDs firstonly, HashSetModifiableDBIDs intersection, HashSetModifiableDBIDs secondonly) {
- if (first.size() > second.size()) {
+ if(first.size() > second.size()) {
symmetricIntersection(second, first, secondonly, intersection, firstonly);
return;
}
@@ -384,11 +380,12 @@ public final class DBIDUtil {
assert (secondonly.size() == 0) : "OUTPUT set should be empty!";
// Initialize with second
secondonly.addDBIDs(second);
- for (DBIDIter it = first.iter(); it.valid(); it.advance()) {
+ for(DBIDIter it = first.iter(); it.valid(); it.advance()) {
// Try to remove
- if (secondonly.remove(it)) {
+ if(secondonly.remove(it)) {
intersection.add(it);
- } else {
+ }
+ else {
firstonly.add(it);
}
}
@@ -428,16 +425,16 @@ public final class DBIDUtil {
* @return Unmodifiable collection
*/
public static StaticDBIDs makeUnmodifiable(DBIDs existing) {
- if (existing instanceof StaticDBIDs) {
+ if(existing instanceof StaticDBIDs) {
return (StaticDBIDs) existing;
}
- if (existing instanceof IntegerArrayDBIDs) {
+ if(existing instanceof IntegerArrayDBIDs) {
return new UnmodifiableIntegerArrayDBIDs((IntegerArrayDBIDs) existing);
}
- if (existing instanceof IntegerDBIDs) {
+ if(existing instanceof IntegerDBIDs) {
return new UnmodifiableIntegerDBIDs((IntegerDBIDs) existing);
}
- if (existing instanceof ArrayDBIDs) {
+ if(existing instanceof ArrayDBIDs) {
return new UnmodifiableArrayDBIDs((ArrayDBIDs) existing);
}
return new UnmodifiableDBIDs(existing);
@@ -450,9 +447,10 @@ public final class DBIDUtil {
* @return Array DBIDs.
*/
public static ArrayDBIDs ensureArray(DBIDs ids) {
- if (ids instanceof ArrayDBIDs) {
+ if(ids instanceof ArrayDBIDs) {
return (ArrayDBIDs) ids;
- } else {
+ }
+ else {
return newArray(ids);
}
}
@@ -464,9 +462,10 @@ public final class DBIDUtil {
* @return Set DBIDs.
*/
public static SetDBIDs ensureSet(DBIDs ids) {
- if (ids instanceof SetDBIDs) {
+ if(ids instanceof SetDBIDs) {
return (SetDBIDs) ids;
- } else {
+ }
+ else {
return newHashSet(ids);
}
}
@@ -478,13 +477,14 @@ public final class DBIDUtil {
* @return Modifiable DBIDs.
*/
public static ModifiableDBIDs ensureModifiable(DBIDs ids) {
- if (ids instanceof ModifiableDBIDs) {
+ if(ids instanceof ModifiableDBIDs) {
return (ModifiableDBIDs) ids;
- } else {
- if (ids instanceof ArrayDBIDs) {
+ }
+ else {
+ if(ids instanceof ArrayDBIDs) {
return newArray(ids);
}
- if (ids instanceof HashSetDBIDs) {
+ if(ids instanceof HashSetDBIDs) {
return newHashSet(ids);
}
return newArray(ids);
@@ -515,59 +515,24 @@ public final class DBIDUtil {
}
/**
- * Make a DistanceDBIDPair.
- *
- * @param dist Distance value
- * @param id ID
- * @return new pair
- */
- public static <D extends Distance<D>> DistanceDBIDPair<D> newDistancePair(D dist, DBIDRef id) {
- return DBIDFactory.FACTORY.newDistancePair(dist, id);
- }
-
- /**
- * Make a DoubleDistanceDBIDPair.
- *
- * @param dist Distance value
- * @param id ID
- * @return new pair
- */
- public static DoubleDistanceDBIDPair newDistancePair(double dist, DBIDRef id) {
- return DBIDFactory.FACTORY.newDistancePair(dist, id);
- }
-
- /**
* Create an appropriate heap for the distance type.
*
* This will use a double heap if appropriate.
*
- * @param distancetype distance prototype
- * @param k K value
- * @param <D> distance type
- * @return New heap of size k, appropriate for this distance type.
- */
- public static <D extends Distance<D>> KNNHeap<D> newHeap(D distancetype, int k) {
- return DBIDFactory.FACTORY.newHeap(distancetype, k);
- }
-
- /**
- * Create an appropriate heap for double distances.
- *
* @param k K value
* @return New heap of size k, appropriate for this distance type.
*/
- public static DoubleDistanceKNNHeap newDoubleDistanceHeap(int k) {
- return DBIDFactory.FACTORY.newDoubleDistanceHeap(k);
+ public static KNNHeap newHeap(int k) {
+ return DBIDFactory.FACTORY.newHeap(k);
}
/**
* Build a new heap from a given list.
*
* @param exist Existing result
- * @param <D> Distance type
* @return New heap
*/
- public static <D extends Distance<D>> KNNHeap<D> newHeap(KNNList<D> exist) {
+ public static KNNHeap newHeap(KNNList exist) {
return DBIDFactory.FACTORY.newHeap(exist);
}
@@ -601,7 +566,7 @@ public final class DBIDUtil {
* @param limit Shuffling limit.
*/
public static void randomShuffle(ArrayModifiableDBIDs ids, Random random, final int limit) {
- for (int i = 1; i < limit; i++) {
+ for(int i = 1; i < limit; i++) {
ids.swap(i - 1, i + random.nextInt(limit - i));
}
}
@@ -627,9 +592,10 @@ public final class DBIDUtil {
* @return new DBIDs
*/
public static ModifiableDBIDs randomSample(DBIDs source, int k, Long seed) {
- if (seed != null) {
+ if(seed != null) {
return randomSample(source, k, new Random(seed.longValue()));
- } else {
+ }
+ else {
return randomSample(source, k, new Random());
}
}
@@ -655,29 +621,31 @@ public final class DBIDUtil {
* @return new DBIDs
*/
public static ModifiableDBIDs randomSample(DBIDs source, int k, Random random) {
- if (k < 0 || k > source.size()) {
+ if(k < 0 || k > source.size()) {
throw new IllegalArgumentException("Illegal value for size of random sample: " + k + " > " + source.size() + " or < 0");
}
- if (random == null) {
- random = new UnsafeRandom(); // Fast, and we're single-threaded here anyway.
+ if(random == null) {
+ // Fast, and we're single-threaded here anyway.
+ random = new FastNonThreadsafeRandom();
}
-
+
// TODO: better balancing for different sizes
// Two methods: constructive vs. destructive
- if (k < source.size() >> 1) {
+ if(k < source.size() >> 1) {
ArrayDBIDs aids = DBIDUtil.ensureArray(source);
DBIDArrayIter iter = aids.iter();
HashSetModifiableDBIDs sample = DBIDUtil.newHashSet(k);
- while (sample.size() < k) {
+ while(sample.size() < k) {
iter.seek(random.nextInt(aids.size()));
sample.add(iter);
}
return sample;
- } else {
+ }
+ else {
ArrayModifiableDBIDs sample = DBIDUtil.newArray(source);
randomShuffle(sample, random, k);
// Delete trailing elements
- for (int i = sample.size() - 1; i > k; i--) {
+ for(int i = sample.size() - 1; i > k; i--) {
sample.remove(i);
}
return sample;
@@ -703,19 +671,20 @@ public final class DBIDUtil {
* @param random Random generator
*/
public static ArrayDBIDs[] randomSplit(DBIDs oids, int p, Random random) {
- if (random == null) {
- random = new UnsafeRandom(); // Fast, and we're single-threaded here anyway.
+ if(random == null) {
+ // Fast, and we're single-threaded here anyway.
+ random = new FastNonThreadsafeRandom();
}
ArrayModifiableDBIDs ids = newArray(oids);
final int size = ids.size();
ArrayDBIDs[] split = new ArrayDBIDs[p];
// Shuffle
- for (int i = 1; i < size; i++) {
+ for(int i = 1; i < size; i++) {
ids.swap(i - 1, i + random.nextInt(size - i));
}
final int minsize = size / p; // Floor.
final int extra = size % p; // Remainder
- for (int beg = 0, part = 0; part < p; part++) {
+ for(int beg = 0, part = 0; part < p; part++) {
// First partitions are smaller, last partitions are larger.
final int psize = minsize + ((part < extra) ? 1 : 0);
split[part] = ids.slice(beg, beg + psize);
@@ -729,17 +698,48 @@ public final class DBIDUtil {
*
* @param list Existing list
* @param k k
- * @param <D> distance type
* @return Subset
*/
- @SuppressWarnings("unchecked")
- public static <D extends Distance<D>> KNNList<D> subList(KNNList<D> list, int k) {
- if (k >= list.size()) {
+ public static KNNList subList(KNNList list, int k) {
+ if(k >= list.size()) {
return list;
}
- if (list instanceof DoubleDistanceKNNList) {
- return (KNNList<D>) new DoubleDistanceKNNSubList((DoubleDistanceKNNList) list, k);
+ if(list instanceof IntegerDBIDKNNList) {
+ return new IntegerDBIDKNNSubList((IntegerDBIDKNNList) list, k);
+ }
+ return new KNNSubList(list, k);
+ }
+
+ /**
+ * Create a modifiable list to store distance-DBID pairs.
+ *
+ * @param size Estimated upper list size
+ * @return Empty list
+ */
+ public static ModifiableDoubleDBIDList newDistanceDBIDList(int size) {
+ return DBIDFactory.FACTORY.newDistanceDBIDList(size);
+ }
+
+ /**
+ * Create a modifiable list to store distance-DBID pairs.
+ *
+ * @return Empty list
+ */
+ public static ModifiableDoubleDBIDList newDistanceDBIDList() {
+ return DBIDFactory.FACTORY.newDistanceDBIDList();
+ }
+
+ /**
+ * Assert that the presented ids constitute a continuous {@link DBIDRange}.
+ *
+ * @param ids ID range.
+ * @return DBID range.
+ * @throws AbortException
+ */
+ public static DBIDRange assertRange(DBIDs ids) {
+ if(!(ids instanceof DBIDRange)) {
+ throw new AbortException("This class may currently only be used with static databases and DBID ranges.");
}
- return new KNNSubList<>(list, k);
+ return (DBIDRange) ids;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDVar.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDVar.java
index 94480fe9..bdc7b76a 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDVar.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDVar.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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
@@ -39,4 +39,30 @@ public interface DBIDVar extends DBIDRef, ArrayDBIDs, SetDBIDs {
* @param ref Reference
*/
void set(DBIDRef ref);
+
+ /**
+ * Clear the contents.
+ */
+ void unset();
+
+ /**
+ * Test if the variable is well-defined.
+ *
+ * @return {@code true} when assigned.
+ */
+ boolean isSet();
+
+ /**
+ * Assign the first pair member to this variable.
+ *
+ * @param pair Pair
+ */
+ void setFirst(DBIDPair pair);
+
+ /**
+ * Assign the second pair member to this variable.
+ *
+ * @param pair Pair
+ */
+ void setSecond(DBIDPair pair);
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDs.java
index 2bf2b28d..5aecff02 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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/database/ids/distance/DistanceDBIDList.java b/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDList.java
index 360dda12..939a0fe7 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDList.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDList.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.database.ids.distance;
+package de.lmu.ifi.dbs.elki.database.ids;
/*
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,19 +23,17 @@ package de.lmu.ifi.dbs.elki.database.ids.distance;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
- * Collection of objects and their distances.
+ * Collection of double values associated with objects.
*
* To iterate over the results, use the following code:
*
* <pre>
* {@code
- * for (DistanceDBIDResultIter<D> iter = result.iter(); iter.valid(); iter.advance()) {
- * // You can get the distance via: iter.getDistance();
- * // Or use iter just like any other DBIDRef
+ * for (DoubleDBIDListIter iter = result.iter(); iter.valid(); iter.advance()) {
+ * // You can get the distance via: iter.doubleValue();
+ * // And use iter just like any other DBIDRef
* }
* }
* </pre>
@@ -45,7 +43,7 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
*
* <pre>
* {@code
- * for (DBIDIter<D> iter = result.iter(); iter.valid(); iter.advance()) {
+ * for (DBIDIter iter = result.iter(); iter.valid(); iter.advance()) {
* // Use iter just like any other DBIDRef
* }
* }
@@ -55,12 +53,10 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
*
* @apiviz.landmark
*
- * @apiviz.composedOf DistanceDBIDPair
- * @apiviz.has DistanceDBIDListIter
- *
- * @param <D> Distance type
+ * @apiviz.composedOf DoubleDBIDPair
+ * @apiviz.has DoubleDBIDListIter
*/
-public interface DistanceDBIDList<D extends Distance<D>> extends DBIDs {
+public interface DoubleDBIDList extends DBIDs {
/**
* Size of list.
*
@@ -70,12 +66,12 @@ public interface DistanceDBIDList<D extends Distance<D>> extends DBIDs {
int size();
/**
- * Access a single pair.
+ * Materialize a single pair.
*
* @param off Offset
* @return Pair
*/
- DistanceDBIDPair<D> get(int off);
+ DoubleDBIDPair get(int off);
/**
* Get an iterator
@@ -83,5 +79,5 @@ public interface DistanceDBIDList<D extends Distance<D>> extends DBIDs {
* @return New iterator
*/
@Override
- DistanceDBIDListIter<D> iter();
+ DoubleDBIDListIter iter();
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDListIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDListIter.java
index 914f3676..d5b0e4f7 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDListIter.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDListIter.java
@@ -1,10 +1,11 @@
-package de.lmu.ifi.dbs.elki.database.ids.distance;
+package de.lmu.ifi.dbs.elki.database.ids;
+
/*
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,11 +24,8 @@ package de.lmu.ifi.dbs.elki.database.ids.distance;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-
/**
- * Iterator over distance-based query results.
+ * Iterator over double-DBID pairs results.
*
* There is no getter for the DBID, as this implements
* {@link de.lmu.ifi.dbs.elki.database.ids.DBIDRef}.
@@ -36,20 +34,37 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
*
* @apiviz.landmark
*
- * @apiviz.has DistanceDBIDPair - - iterator for
+ * @apiviz.has DoubleDBIDPair
*/
-public interface DistanceDBIDListIter<D extends Distance<D>> extends DBIDArrayIter {
+public interface DoubleDBIDListIter extends DBIDArrayIter {
/**
- * Get the distance
+ * Get the double value
*
- * @return distance
+ * @return double value
*/
- public D getDistance();
+ public double doubleValue();
/**
- * Get an object pair.
+ * Materialize an object pair.
+ *
+ * Note: currently, this will create a <em>new object</em>. In order to avoid
+ * the garbage collection overhead, it is preferable to use
+ * {@code #doubleValue()} and exploit that the iterator itself is a
+ * {@code DBIDRef} reference.
*
* @return object pair
*/
- public DistanceDBIDPair<D> getDistancePair();
+ public DoubleDBIDPair getPair();
+
+ @Override
+ DoubleDBIDListIter advance();
+
+ @Override
+ DoubleDBIDListIter advance(int count);
+
+ @Override
+ DoubleDBIDListIter retract();
+
+ @Override
+ DoubleDBIDListIter seek(int off);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDPair.java
index 970092b0..9459dbf6 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDPair.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDPair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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,42 +23,19 @@ package de.lmu.ifi.dbs.elki.database.ids;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.utilities.pairs.PairInterface;
-
/**
- * Pair of a double value and a DBID
+ * Pair of a double value and a DBID.
+ *
+ * Note: this interface implements {@link DBIDRef}, i.e. it can be used as DBID
+ * object reference.
*
* @author Erich Schubert
*/
-public interface DoubleDBIDPair extends PairInterface<Double, DBID>, DBIDRef, Comparable<DoubleDBIDPair> {
+public interface DoubleDBIDPair extends DBIDRef, Comparable<DoubleDBIDPair> {
/**
* Get the double value of the pair.
*
* @return Double
*/
public double doubleValue();
-
- /**
- * Get the first object - note: this may cause autoboxing, use pair.first for
- * native pairs!
- *
- * @deprecated Avoid autoboxing. Use {@link #doubleValue}!
- *
- * @return First object
- */
- @Override
- @Deprecated
- public Double getFirst();
-
- /**
- * Get the second object - note: this may cause autoboxing, use pair.second
- * for native pairs!
- *
- * @deprecated Avoid autoboxing! Use {@link DBIDRef} interface!
- *
- * @return Second object
- */
- @Override
- @Deprecated
- public DBID getSecond();
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/EmptyDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/EmptyDBIDs.java
index 0081fd44..3fb539df 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/EmptyDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/EmptyDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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
@@ -99,8 +99,9 @@ public class EmptyDBIDs implements ArrayStaticDBIDs, SetDBIDs {
}
@Override
- public void advance() {
+ public EmptyDBIDIterator advance() {
assert (false) : "Misplaced call to advance()";
+ return this;
}
@Override
@@ -122,18 +123,21 @@ public class EmptyDBIDs implements ArrayStaticDBIDs, SetDBIDs {
}
@Override
- public void advance(int count) {
+ public EmptyDBIDIterator advance(int count) {
assert (count != 0) : "Misplaced call to advance()";
+ return this;
}
@Override
- public void retract() {
+ public EmptyDBIDIterator retract() {
assert (false) : "Misplaced call to retract()";
+ return this;
}
@Override
- public void seek(int off) {
+ public EmptyDBIDIterator seek(int off) {
// Ignore
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/HashSetDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/HashSetDBIDs.java
index cabe9898..6fcb40cc 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/HashSetDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/HashSetDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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/database/ids/HashSetModifiableDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/HashSetModifiableDBIDs.java
index 6a57f5f0..90574599 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/HashSetModifiableDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/HashSetModifiableDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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/database/ids/distance/KNNHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/KNNHeap.java
index 5e94de47..1169caf6 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/KNNHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/KNNHeap.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.database.ids.distance;
+package de.lmu.ifi.dbs.elki.database.ids;
/*
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,27 @@ package de.lmu.ifi.dbs.elki.database.ids.distance;
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.distance.distancevalue.Distance;
/**
* Interface for kNN heaps.
*
- * To instantiate, use: {@link de.lmu.ifi.dbs.elki.database.ids.DBIDUtil#newHeap}!
+ * To instantiate, use:
+ * {@link de.lmu.ifi.dbs.elki.database.ids.DBIDUtil#newHeap}!
*
* @author Erich Schubert
*
* @apiviz.landmark
*
* @apiviz.uses KNNList - - «serializes to»
- * @apiviz.composedOf DistanceDBIDPair
- *
- * @param <D> Distance function
+ * @apiviz.composedOf DoubleDBIDPair
*/
-public interface KNNHeap<D extends Distance<D>> {
+public interface KNNHeap {
/**
* Serialize to a {@link KNNList}. This empties the heap!
*
* @return KNNList with the heaps contents.
*/
- KNNList<D> toKNNList();
+ KNNList toKNNList();
/**
* Get the K parameter ("maxsize" internally).
@@ -60,7 +57,7 @@ public interface KNNHeap<D extends Distance<D>> {
*
* @return Maximum distance
*/
- D getKNNDistance();
+ double getKNNDistance();
/**
* Add a distance-id pair to the heap unless the distance is too large.
@@ -69,8 +66,18 @@ public interface KNNHeap<D extends Distance<D>> {
*
* @param distance Distance value
* @param id ID number
+ * @return current k-distance
*/
- void insert(D distance, DBIDRef id);
+ double insert(double distance, DBIDRef id);
+
+ /**
+ * Add a distance-id pair to the heap unless the distance is too large.
+ *
+ * Use for existing pairs.
+ *
+ * @param e Existing distance pair
+ */
+ void insert(DoubleDBIDPair e);
/**
* Current size of heap.
@@ -78,14 +85,14 @@ public interface KNNHeap<D extends Distance<D>> {
* @return Heap size
*/
int size();
-
+
/**
* Test if the heap is empty.
*
* @return true when empty.
*/
boolean isEmpty();
-
+
/**
* Clear the heap.
*/
@@ -100,12 +107,12 @@ public interface KNNHeap<D extends Distance<D>> {
*
* @return largest element
*/
- DistanceDBIDPair<D> poll();
+ DoubleDBIDPair poll();
/**
* Peek at the <em>largest</em> element in the heap.
*
* @return The current largest element.
*/
- DistanceDBIDPair<D> peek();
+ DoubleDBIDPair peek();
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/KNNList.java b/src/de/lmu/ifi/dbs/elki/database/ids/KNNList.java
index 61b75ba8..6d3dc778 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/KNNList.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/KNNList.java
@@ -1,10 +1,11 @@
-package de.lmu.ifi.dbs.elki.database.ids.distance;
+package de.lmu.ifi.dbs.elki.database.ids;
+
/*
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 +24,6 @@ package de.lmu.ifi.dbs.elki.database.ids.distance;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Interface for kNN results.
@@ -54,11 +54,9 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
*
* @apiviz.landmark
*
- * @apiviz.composedOf DistanceDBIDPair
- *
- * @param <D> Distance type
+ * @apiviz.composedOf DoubleDBIDPair
*/
-public interface KNNList<D extends Distance<D>> extends DistanceDBIDList<D> {
+public interface KNNList extends DoubleDBIDList {
/**
* Size
*/
@@ -78,12 +76,12 @@ public interface KNNList<D extends Distance<D>> extends DistanceDBIDList<D> {
* @param index
*/
@Override
- public DistanceDBIDPair<D> get(int index);
+ public DoubleDBIDPair get(int index);
/**
* Get the distance to the k nearest neighbor, or maxdist otherwise.
*
* @return Maximum distance
*/
- public D getKNNDistance();
+ public double getKNNDistance();
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/ModifiableDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/ModifiableDBIDs.java
index 1cd8c4e7..aa9a5052 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/ModifiableDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/ModifiableDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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/database/ids/distance/ModifiableDistanceDBIDList.java b/src/de/lmu/ifi/dbs/elki/database/ids/ModifiableDoubleDBIDList.java
index afb15f93..2ae62345 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/ModifiableDistanceDBIDList.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/ModifiableDoubleDBIDList.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.database.ids.distance;
+package de.lmu.ifi.dbs.elki.database.ids;
/*
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,23 +23,34 @@ package de.lmu.ifi.dbs.elki.database.ids.distance;
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.distance.distancevalue.Distance;
+
/**
* Modifiable API for Distance-DBID results
*
* @author Erich Schubert
- *
- * @param <D> Distance type
+ *
+ * @apiviz.composedOf DoubleDBIDPair
*/
-public interface ModifiableDistanceDBIDList<D extends Distance<D>> extends DistanceDBIDList<D> {
+public interface ModifiableDoubleDBIDList extends DoubleDBIDList {
/**
* Add an object to this result.
*
* @param distance Distance to add
* @param id DBID to add
*/
- public void add(D distance, DBIDRef id);
+ void add(double distance, DBIDRef id);
+
+ /**
+ * Add an element.
+ *
+ * @param pair Pair to add
+ */
+ void add(DoubleDBIDPair pair);
+
+ /**
+ * Clear the list contents.
+ */
+ void clear();
/**
* Sort the result in ascending order
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/SetDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/SetDBIDs.java
index 3a92593e..0b316ca2 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/SetDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/SetDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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/database/ids/StaticDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/StaticDBIDs.java
index 2ba30d4b..24f6b585 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/StaticDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/StaticDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids;
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/database/ids/distance/DoubleDistanceDBIDPairList.java b/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDPairList.java
deleted file mode 100644
index 58ce433d..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDPairList.java
+++ /dev/null
@@ -1,217 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.ids.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 java.util.ArrayList;
-import java.util.Collections;
-
-import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory;
-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.distance.distanceresultlist.DistanceDBIDResultUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-
-/**
- * Default class to keep a list of distance-object pairs.
- *
- * @author Erich Schubert
- *
- * @apiviz.composedOf DoubleDistanceDBIDPair
- * @apiviz.has DoubleDistanceDBIDListIter
- */
-public class DoubleDistanceDBIDPairList implements ModifiableDoubleDistanceDBIDList {
- /**
- * Actual storage.
- */
- final ArrayList<DoubleDistanceDBIDPair> storage;
-
- /**
- * Constructor.
- */
- public DoubleDistanceDBIDPairList() {
- super();
- storage = new ArrayList<>();
- }
-
- /**
- * Constructor.
- *
- * @param initialCapacity Capacity
- */
- public DoubleDistanceDBIDPairList(int initialCapacity) {
- super();
- storage = new ArrayList<>(initialCapacity);
- }
-
- /**
- * Add an element.
- *
- * @deprecated Pass a double value instead.
- *
- * @param dist Distance
- * @param id ID
- */
- @Override
- @Deprecated
- public void add(DoubleDistance dist, DBIDRef id) {
- storage.add(DBIDFactory.FACTORY.newDistancePair(dist.doubleValue(), id));
- }
-
- /**
- * Add an element.
- *
- * @param dist Distance
- * @param id ID
- */
- @Override
- public void add(double dist, DBIDRef id) {
- storage.add(DBIDFactory.FACTORY.newDistancePair(dist, id));
- }
-
- /**
- * Add an element.
- *
- * @param pair Pair to add
- */
- @Override
- public void add(DoubleDistanceDBIDPair pair) {
- storage.add(pair);
- }
-
- @Override
- public void clear() {
- storage.clear();
- }
-
- @Override
- public void sort() {
- Collections.sort(storage, DistanceDBIDResultUtil.distanceComparator());
- }
-
- @Override
- public int size() {
- return storage.size();
- }
-
- @Override
- public DoubleDistanceDBIDPair get(int off) {
- return storage.get(off);
- }
-
- @Override
- public DoubleDistanceDBIDListIter iter() {
- return new Itr();
- }
-
- @Override
- public boolean contains(DBIDRef o) {
- for(DBIDIter iter = iter(); iter.valid(); iter.advance()) {
- if(DBIDUtil.equal(iter, o)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean isEmpty() {
- return size() == 0;
- }
-
- @Override
- public String toString() {
- return DistanceDBIDResultUtil.toString(this);
- }
-
- /**
- * Iterator class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- protected class Itr implements DoubleDistanceDBIDListIter {
- /**
- * Iterator position.
- */
- int pos = 0;
-
- @Override
- public int internalGetIndex() {
- return get(pos).internalGetIndex();
- }
-
- @Override
- public boolean valid() {
- return pos < size();
- }
-
- @Override
- public void advance() {
- pos++;
- }
-
- @Override
- @Deprecated
- public DoubleDistance getDistance() {
- return get(pos).getDistance();
- }
-
- @Override
- public double doubleDistance() {
- return get(pos).doubleDistance();
- }
-
- @Override
- public DoubleDistanceDBIDPair getDistancePair() {
- return get(pos);
- }
-
- @Override
- public String toString() {
- return valid() ? getDistancePair().toString() : "null";
- }
-
- @Override
- public int getOffset() {
- return pos;
- }
-
- @Override
- public void advance(int count) {
- pos += count;
- }
-
- @Override
- public void retract() {
- --pos;
- }
-
- @Override
- public void seek(int off) {
- pos = off;
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceKNNHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceKNNHeap.java
deleted file mode 100644
index ed687877..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceKNNHeap.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.ids.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.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-
-/**
- * Interface for kNN heaps storing double distances and DBIDs.
- *
- * @author Erich Schubert
- */
-public interface DoubleDistanceKNNHeap extends KNNHeap<DoubleDistance> {
- /**
- * Add a distance-id pair to the heap unless the distance is too large.
- *
- * Compared to the super.add() method, this often saves the pair construction.
- *
- * @param distance Distance value
- * @param id ID number
- * @return updated k-distance
- */
- double insert(double distance, DBIDRef id);
-
- /**
- * Add a distance-id pair to the heap unless the distance is too large.
- *
- * Compared to the super.add() method, this often saves the pair construction.
- *
- * @param distance Distance value
- * @param id ID number
- */
- @Deprecated
- void insert(Double distance, DBIDRef id);
-
- /**
- * Add a distance-id pair to the heap unless the distance is too large.
- *
- * Use for existing pairs.
- *
- * @param e Existing distance pair
- */
- void insert(DoubleDistanceDBIDPair e);
-
- /**
- * {@inheritDoc}
- *
- * @deprecated if you know your distances are double-valued, you should be
- * using the primitive type.
- */
- @Override
- @Deprecated
- void insert(DoubleDistance dist, DBIDRef id);
-
- /**
- * Get the distance to the k nearest neighbor, or maxdist otherwise.
- *
- * @return Maximum distance
- */
- double doubleKNNDistance();
-
- /**
- * {@inheritDoc}
- *
- * @deprecated if you know your distances are double-valued, you should be
- * using the primitive type.
- */
- @Override
- @Deprecated
- DoubleDistance getKNNDistance();
-
- @Override
- DoubleDistanceDBIDPair poll();
-
- @Override
- DoubleDistanceDBIDPair peek();
-
- @Override
- DoubleDistanceKNNList toKNNList();
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/AbstractKNNHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/AbstractKNNHeap.java
deleted file mode 100644
index c42c728d..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/AbstractKNNHeap.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.ids.generic;
-
-/*
- 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.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.distance.distanceresultlist.DistanceDBIDResultUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.TiedTopBoundedHeap;
-
-/**
- * Heap used for KNN management.
- *
- * @author Erich Schubert
- *
- * @param <P> pair type
- * @param <D> distance type
- */
-abstract class AbstractKNNHeap<P extends DistanceDBIDPair<D>, D extends Distance<D>> implements KNNHeap<D> {
- /**
- * The actual heap.
- */
- protected final TiedTopBoundedHeap<P> heap;
-
- /**
- * Constructor.
- *
- * @param k Maximum heap size (unless tied)
- */
- public AbstractKNNHeap(int k) {
- super();
- heap = new TiedTopBoundedHeap<>(k, DistanceDBIDResultUtil.BY_REVERSE_DISTANCE);
- }
-
- /**
- * Add a pair to the heap.
- *
- * @param pair Pair to add.
- */
- public abstract void insert(P pair);
-
- @Override
- public final int getK() {
- return heap.getMaxSize();
- }
-
- @Override
- public int size() {
- return heap.size();
- }
-
- @Override
- public P peek() {
- return heap.peek();
- }
-
- @Override
- public boolean isEmpty() {
- return heap.isEmpty();
- }
-
- @Override
- public void clear() {
- heap.clear();
- }
-
- @Override
- public P poll() {
- return heap.poll();
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DistanceDBIDPairKNNHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/DistanceDBIDPairKNNHeap.java
deleted file mode 100644
index e102d716..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DistanceDBIDPairKNNHeap.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.ids.generic;
-
-/*
- 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.DBIDFactory;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-
-/**
- * Heap for collecting kNN candidates with arbitrary distance types.
- *
- * For double distances, see {@link DoubleDistanceDBIDPairKNNHeap}
- *
- * <b>To instantiate, use {@link de.lmu.ifi.dbs.elki.database.ids.DBIDUtil#newHeap} instead!</b>
- *
- * @author Erich Schubert
- *
- * @param <D> Distance type
- */
-public class DistanceDBIDPairKNNHeap<D extends Distance<D>> extends AbstractKNNHeap<DistanceDBIDPair<D>, D> {
- /**
- * Cached distance to k nearest neighbor (to avoid going through {@link #peek}
- * each time).
- */
- protected D knndistance = null;
-
- /**
- * Constructor.
- *
- * <b>To instantiate, use {@link de.lmu.ifi.dbs.elki.database.ids.DBIDUtil#newHeap} instead!</b>
- *
- * @param k Heap size
- */
- public DistanceDBIDPairKNNHeap(int k) {
- super(k);
- }
-
- /**
- * Serialize to a {@link DistanceDBIDPairKNNList}. This empties the heap!
- *
- * @return KNNList with the heaps contents.
- */
- @Override
- public DistanceDBIDPairKNNList<D> toKNNList() {
- return new DistanceDBIDPairKNNList<>(this);
- }
-
- @Override
- public void insert(D distance, DBIDRef id) {
- if (size() < getK()) {
- heap.add(DBIDFactory.FACTORY.newDistancePair(distance, id));
- heapModified();
- return;
- }
- // size >= maxsize. Insert only when necessary.
- if (knndistance.compareTo(distance) >= 0) {
- // Replace worst element.
- heap.add(DBIDFactory.FACTORY.newDistancePair(distance, id));
- heapModified();
- }
- }
-
- @Override
- public void insert(DistanceDBIDPair<D> pair) {
- if (size() < getK() || knndistance.compareTo(pair.getDistance()) >= 0) {
- heap.add(pair);
- heapModified();
- }
- }
-
- // @Override
- protected void heapModified() {
- // super.heapModified();
- // Update threshold.
- if (size() >= getK()) {
- knndistance = heap.peek().getDistance();
- }
- }
-
- @Override
- public D getKNNDistance() {
- return knndistance;
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DistanceDBIDPairKNNList.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/DistanceDBIDPairKNNList.java
deleted file mode 100644
index bc5392d6..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DistanceDBIDPairKNNList.java
+++ /dev/null
@@ -1,211 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.ids.generic;
-
-/*
- 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.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.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap;
-
-/**
- * Finalized KNN List.
- *
- * @author Erich Schubert
- *
- * @param <D> Distance type
- */
-public class DistanceDBIDPairKNNList<D extends Distance<D>> implements KNNList<D> {
- /**
- * The value of k this was materialized for.
- */
- private final int k;
-
- /**
- * The actual data array.
- */
- private final Object[] data;
-
- /**
- * Constructor, to be called from KNNHeap only. Use {@link KNNHeap#toKNNList}
- * instead!
- *
- * @param heap Calling heap
- */
- protected DistanceDBIDPairKNNList(KNNHeap<D> heap) {
- super();
- this.data = new Object[heap.size()];
- this.k = heap.getK();
- // Get sorted data from heap; but in reverse.
- int i = heap.size();
- while (heap.size() > 0) {
- i--;
- assert (i >= 0);
- data[i] = heap.poll();
- }
- assert (data.length == 0 || data[0] != null);
- assert (heap.size() == 0);
- }
-
- /**
- * Constructor. With a KNNHeap, use {@link KNNHeap#toKNNList} instead!
- *
- * @param heap Calling heap
- * @param k K value
- */
- public DistanceDBIDPairKNNList(Heap<? extends DistanceDBIDPair<D>> heap, int k) {
- super();
- this.data = new Object[heap.size()];
- this.k = k;
- assert (heap.size() >= this.k) : "Heap doesn't contain enough objects!";
- // Get sorted data from heap; but in reverse.
- int i = heap.size();
- while (!heap.isEmpty()) {
- i--;
- assert (i >= 0);
- data[i] = heap.poll();
- }
- assert (data.length == 0 || data[0] != null);
- assert (heap.size() == 0);
- }
-
- @Override
- public int getK() {
- return k;
- }
-
- @Override
- public D getKNNDistance() {
- return get(getK() - 1).getDistance();
- }
-
- @Override
- public String toString() {
- StringBuilder buf = new StringBuilder();
- buf.append("kNNList[");
- for (DistanceDBIDListIter<D> iter = this.iter(); iter.valid();) {
- buf.append(iter.getDistance()).append(':').append(DBIDUtil.toString(iter));
- iter.advance();
- if (iter.valid()) {
- buf.append(',');
- }
- }
- buf.append(']');
- return buf.toString();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public DistanceDBIDPair<D> get(int index) {
- return (DistanceDBIDPair<D>) data[index];
- }
-
- @Override
- public DistanceDBIDListIter<D> iter() {
- return new Itr();
- }
-
- @Override
- public int size() {
- return data.length;
- }
-
- @Override
- public boolean contains(DBIDRef o) {
- for (DBIDIter iter = iter(); iter.valid(); iter.advance()) {
- if (DBIDUtil.equal(iter, o)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean isEmpty() {
- return size() == 0;
- }
-
- /**
- * Iterator.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- private class Itr implements DistanceDBIDListIter<D> {
- /**
- * Cursor position.
- */
- private int pos = 0;
-
- @Override
- public int internalGetIndex() {
- return get(pos).internalGetIndex();
- }
-
- @Override
- public boolean valid() {
- return pos < data.length;
- }
-
- @Override
- public void advance() {
- pos++;
- }
-
- @Override
- public D getDistance() {
- return get(pos).getDistance();
- }
-
- @Override
- public DistanceDBIDPair<D> getDistancePair() {
- return get(pos);
- }
-
- @Override
- public int getOffset() {
- return pos;
- }
-
- @Override
- public void advance(int count) {
- pos += count;
- }
-
- @Override
- public void retract() {
- --pos;
- }
-
- @Override
- public void seek(int off) {
- pos += off;
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNHeap.java
deleted file mode 100644
index 8e489a79..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNHeap.java
+++ /dev/null
@@ -1,218 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.ids.generic;
-
-/*
- 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.Comparator;
-
-import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-
-/**
- * Heap for collecting double-valued KNN instances.
- *
- * See also: {@link de.lmu.ifi.dbs.elki.database.ids.DBIDUtil#newHeap}!
- *
- * Experiments have shown that it <em>can</em> be much more performant to track
- * the knndistance <em>outside</em> of the heap, and do comparisons on the
- * stack: <blockquote>
- *
- * <pre>
- * {@code
- * double knndist = Double.POSITIVE_INFINITY;
- * DoubleDistanceDBIDPairKNNHeap heap = new DoubleDistanceDBIDPairKNNHeap(k);
- * for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- * double dist = computeDistance(iditer, ...);
- * if (dist < knndist) {
- * heap.add(dist, iditer);
- * if (heap.size() >= k) {
- * max = heap.doubleKNNDistance();
- * }
- * }
- * }
- * }
- * </pre>
- *
- * </blockquote>
- *
- * The reason probably is that {@code knndist} resides on the stack and can be
- * better optimized by the hotspot compiler.
- *
- * @author Erich Schubert
- */
-public class DoubleDistanceDBIDPairKNNHeap extends AbstractKNNHeap<DoubleDistanceDBIDPair, DoubleDistance> implements DoubleDistanceKNNHeap {
- /**
- * Comparator class.
- */
- public static final Comparator<DoubleDistanceDBIDPair> COMPARATOR = new Comp();
-
- /**
- * Reverse comparator.
- */
- public static final Comparator<DoubleDistanceDBIDPair> REVERSE_COMPARATOR = new RComp();
-
- /**
- * Cached distance to k nearest neighbor (to avoid going through {@link #peek}
- * too often).
- */
- protected double knndistance = Double.POSITIVE_INFINITY;
-
- /**
- * Constructor.
- *
- * See also: {@link de.lmu.ifi.dbs.elki.database.ids.DBIDUtil#newHeap}!
- *
- * @param k Heap size
- */
- public DoubleDistanceDBIDPairKNNHeap(int k) {
- super(k);
- }
-
- /**
- * Serialize to a {@link DoubleDistanceDBIDPairKNNList}. This empties the
- * heap!
- *
- * @return KNNList with the heaps contents.
- */
- @Override
- public DoubleDistanceDBIDPairKNNList toKNNList() {
- return new DoubleDistanceDBIDPairKNNList(this);
- }
-
- /**
- * Add a distance-id pair to the heap unless the distance is too large.
- *
- * Compared to the super.add() method, this often saves the pair construction.
- *
- * @param distance Distance value
- * @param id ID number
- * @return knn distance.
- */
- @Override
- public final double insert(final double distance, final DBIDRef id) {
- if (size() < getK() || knndistance >= distance) {
- heap.add(DBIDFactory.FACTORY.newDistancePair(distance, id));
- heapModified();
- }
- return knndistance;
- }
-
- /**
- * Add a distance-id pair to the heap unless the distance is too large.
- *
- * Compared to the super.add() method, this often saves the pair construction.
- *
- * @param distance Distance value
- * @param id ID number
- */
- @Override
- @Deprecated
- public final void insert(final Double distance, final DBIDRef id) {
- if (size() < getK() || knndistance >= distance) {
- heap.add(DBIDFactory.FACTORY.newDistancePair(distance, id));
- heapModified();
- }
- }
-
- // @Override
- protected void heapModified() {
- // super.heapModified();
- if (size() >= getK()) {
- knndistance = heap.peek().doubleDistance();
- }
- }
-
- @Override
- public void insert(final DoubleDistanceDBIDPair e) {
- if (size() < getK() || knndistance >= e.doubleDistance()) {
- heap.add(e);
- heapModified();
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @deprecated if you know your distances are double-valued, you should be
- * using the primitive type.
- *
- */
- @Override
- @Deprecated
- public void insert(DoubleDistance dist, DBIDRef id) {
- insert(dist.doubleValue(), id);
- }
-
- /**
- * Get the distance to the k nearest neighbor, or maxdist otherwise.
- *
- * @return Maximum distance
- */
- @Override
- public double doubleKNNDistance() {
- return knndistance;
- }
-
- /**
- * {@inheritDoc}
- *
- * @deprecated if you know your distances are double-valued, you should be
- * using the primitive type.
- */
- @Override
- @Deprecated
- public DoubleDistance getKNNDistance() {
- return new DoubleDistance(knndistance);
- }
-
- /**
- * Comparator to use.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- protected static class Comp implements Comparator<DoubleDistanceDBIDPair> {
- @Override
- public int compare(DoubleDistanceDBIDPair o1, DoubleDistanceDBIDPair o2) {
- return -Double.compare(o1.doubleDistance(), o2.doubleDistance());
- }
- }
-
- /**
- * Comparator to use.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- protected static class RComp implements Comparator<DoubleDistanceDBIDPair> {
- @Override
- public int compare(DoubleDistanceDBIDPair o1, DoubleDistanceDBIDPair o2) {
- return Double.compare(o1.doubleDistance(), o2.doubleDistance());
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNList.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNList.java
deleted file mode 100644
index c72529ad..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNList.java
+++ /dev/null
@@ -1,257 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.ids.generic;
-
-/*
- 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.Collection;
-import java.util.Iterator;
-
-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.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap;
-
-/**
- * Finalized KNN List.
- *
- * @author Erich Schubert
- *
- * @apiviz.composedOf DoubleDistanceDBIDPair
- * @apiviz.has DoubleDistanceDBIDListIter
- */
-public class DoubleDistanceDBIDPairKNNList implements DoubleDistanceKNNList {
- /**
- * The value of k this was materialized for.
- */
- private final int k;
-
- /**
- * The actual data array.
- */
- private final DoubleDistanceDBIDPair[] data;
-
- /**
- * Constructor. This will <em>clone</em> the given collection!
- *
- * @param col Existing collection
- * @param k K parameter
- */
- public DoubleDistanceDBIDPairKNNList(Collection<DoubleDistanceDBIDPair> col, int k) {
- super();
- this.data = new DoubleDistanceDBIDPair[col.size()];
- this.k = k;
- assert (col.size() >= this.k) : "Collection doesn't contain enough objects!";
- // Get sorted data from heap; but in reverse.
- Iterator<DoubleDistanceDBIDPair> it = col.iterator();
- for (int i = 0; it.hasNext(); i++) {
- data[i] = it.next();
- }
- assert (data.length == 0 || data[0] != null);
- }
-
- /**
- * Constructor, to be called from KNNHeap only. Use {@link KNNHeap#toKNNList}
- * instead!
- *
- * @param heap Calling heap
- */
- protected DoubleDistanceDBIDPairKNNList(DoubleDistanceDBIDPairKNNHeap heap) {
- super();
- this.data = new DoubleDistanceDBIDPair[heap.size()];
- this.k = heap.getK();
- // Get sorted data from heap; but in reverse.
- int i = heap.size();
- while (heap.size() > 0) {
- i--;
- assert (i >= 0);
- data[i] = heap.poll();
- }
- assert (data.length == 0 || data[0] != null);
- assert (heap.size() == 0);
- }
-
- /**
- * Constructor, to be called from KNNHeap only. Use {@link KNNHeap#toKNNList}
- * instead!
- *
- * @param heap Calling heap
- * @param k Target number of neighbors (before ties)
- */
- public DoubleDistanceDBIDPairKNNList(Heap<DoubleDistanceDBIDPair> heap, int k) {
- super();
- this.data = new DoubleDistanceDBIDPair[heap.size()];
- this.k = k;
- assert (heap.size() >= this.k) : "Heap doesn't contain enough objects!";
- // Get sorted data from heap; but in reverse.
- int i = heap.size();
- while (heap.size() > 0) {
- i--;
- assert (i >= 0);
- data[i] = heap.poll();
- }
- assert (data.length == 0 || data[0] != null);
- assert (heap.size() == 0);
- }
-
- @Override
- public int getK() {
- return k;
- }
-
- @Override
- @Deprecated
- public DoubleDistance getKNNDistance() {
- if (size() < k) {
- return DoubleDistance.INFINITE_DISTANCE;
- }
- return get(k - 1).getDistance();
- }
-
- @Override
- public double doubleKNNDistance() {
- if (size() < k) {
- return Double.POSITIVE_INFINITY;
- }
- return get(k - 1).doubleDistance();
- }
-
- @Override
- public String toString() {
- StringBuilder buf = new StringBuilder();
- buf.append("kNNList[");
- for (DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) {
- buf.append(iter.doubleDistance()).append(':').append(DBIDUtil.toString(iter));
- iter.advance();
- if (iter.valid()) {
- buf.append(',');
- }
- }
- buf.append(']');
- return buf.toString();
- }
-
- @Override
- public DoubleDistanceDBIDPair get(int index) {
- return data[index];
- }
-
- @Override
- public DoubleDistanceDBIDListIter iter() {
- return new Itr();
- }
-
- @Override
- public int size() {
- return data.length;
- }
-
- @Override
- public boolean contains(DBIDRef o) {
- for (DBIDIter iter = iter(); iter.valid(); iter.advance()) {
- if (DBIDUtil.equal(iter, o)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean isEmpty() {
- return size() == 0;
- }
-
- /**
- * Iterator.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- private class Itr implements DoubleDistanceDBIDListIter {
- /**
- * Cursor position.
- */
- private int pos = 0;
-
- @Override
- public int internalGetIndex() {
- return get(pos).internalGetIndex();
- }
-
- @Override
- public boolean valid() {
- return pos < data.length;
- }
-
- @Override
- public void advance() {
- pos++;
- }
-
- /**
- * {@inheritDoc}
- *
- * @deprecated use {@link #doubleDistance}!
- */
- @Override
- @Deprecated
- public DoubleDistance getDistance() {
- return get(pos).getDistance();
- }
-
- @Override
- public double doubleDistance() {
- return get(pos).doubleDistance();
- }
-
- @Override
- public DoubleDistanceDBIDPair getDistancePair() {
- return get(pos);
- }
-
- @Override
- public int getOffset() {
- return pos;
- }
-
- @Override
- public void advance(int count) {
- pos += count;
- }
-
- @Override
- public void retract() {
- --pos;
- }
-
- @Override
- public void seek(int off) {
- pos = off;
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNListHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNListHeap.java
deleted file mode 100644
index ca00129b..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNListHeap.java
+++ /dev/null
@@ -1,289 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.ids.generic;
-
-/*
- 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.Arrays;
-
-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.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-
-/**
- * Finalized KNN List.
- *
- * @author Erich Schubert
- *
- * @apiviz.composedOf DoubleDistanceDBIDPair
- * @apiviz.has DoubleDistanceDBIDListIter
- */
-public class DoubleDistanceDBIDPairKNNListHeap implements DoubleDistanceKNNList, DoubleDistanceKNNHeap {
- /**
- * The value of k this was materialized for.
- */
- private final int k;
-
- /**
- * The actual data array.
- */
- private DoubleDistanceDBIDPair[] data;
-
- /**
- * Current size
- */
- private int size;
-
- /**
- * Constructor.
- *
- * @param k K parameter
- */
- public DoubleDistanceDBIDPairKNNListHeap(int k) {
- super();
- this.data = new DoubleDistanceDBIDPair[k + 11];
- this.k = k;
- }
-
- @Override
- public void clear() {
- size = 0;
- Arrays.fill(data, null);
- }
-
- @Override
- public double insert(double distance, DBIDRef id) {
- if (size < k || distance <= data[k - 1].doubleDistance()) {
- insert(DBIDUtil.newDistancePair(distance, id));
- }
- return (size < k) ? Double.POSITIVE_INFINITY : get(k - 1).doubleDistance();
- }
-
- @Override
- @Deprecated
- public void insert(Double distance, DBIDRef id) {
- insert(DBIDUtil.newDistancePair(distance.doubleValue(), id));
- }
-
- @Override
- @Deprecated
- public void insert(DoubleDistance dist, DBIDRef id) {
- insert(DBIDUtil.newDistancePair(dist.doubleValue(), id));
- }
-
- @Override
- public void insert(DoubleDistanceDBIDPair e) {
- if (size >= k) {
- if (e.doubleDistance() > data[size - 1].doubleDistance()) {
- return;
- }
- // Ensure we have enough space.
- final int len = data.length;
- if (size > len) {
- final int newlength = len + (len >>> 1);
- assert (newlength > size);
- data = Arrays.copyOf(data, newlength);
- }
- }
- insertionSort(e);
- // Truncate if necessary:
- if (size > k && data[k].doubleDistance() > data[k - 1].doubleDistance()) {
- size = k;
- }
- }
-
- /**
- * Perform insertion sort.
- *
- * @param obj Object to insert
- */
- private void insertionSort(DoubleDistanceDBIDPair obj) {
- // Insertion sort:
- int pos = size;
- while (pos > 0) {
- DoubleDistanceDBIDPair pobj = data[pos - 1];
- if (pobj.doubleDistance() <= obj.doubleDistance()) {
- break;
- }
- data[pos] = pobj;
- --pos;
- }
- data[pos] = obj;
- ++size;
- }
-
- @Override
- public DoubleDistanceDBIDPair poll() {
- assert (size > 0);
- return data[size--];
- }
-
- @Override
- public DoubleDistanceDBIDPair peek() {
- assert (size > 0);
- return data[size - 1];
- }
-
- @Override
- public DoubleDistanceKNNList toKNNList() {
- return this;
- }
-
- @Override
- public int getK() {
- return k;
- }
-
- @Override
- @Deprecated
- public DoubleDistance getKNNDistance() {
- if (size < k) {
- return DoubleDistance.INFINITE_DISTANCE;
- }
- return get(k - 1).getDistance();
- }
-
- @Override
- public double doubleKNNDistance() {
- return (size < k) ? Double.POSITIVE_INFINITY : get(k - 1).doubleDistance();
- }
-
- @Override
- public String toString() {
- StringBuilder buf = new StringBuilder();
- buf.append("kNNList[");
- for (DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) {
- buf.append(iter.doubleDistance()).append(':').append(DBIDUtil.toString(iter));
- iter.advance();
- if (iter.valid()) {
- buf.append(',');
- }
- }
- buf.append(']');
- return buf.toString();
- }
-
- @Override
- public DoubleDistanceDBIDPair get(int index) {
- return data[index];
- }
-
- @Override
- public DoubleDistanceDBIDListIter iter() {
- return new Itr();
- }
-
- @Override
- public int size() {
- return data.length;
- }
-
- @Override
- public boolean contains(DBIDRef o) {
- for (DBIDIter iter = iter(); iter.valid(); iter.advance()) {
- if (DBIDUtil.equal(iter, o)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean isEmpty() {
- return size() == 0;
- }
-
- /**
- * Iterator.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- private class Itr implements DoubleDistanceDBIDListIter {
- /**
- * Cursor position.
- */
- private int pos = 0;
-
- @Override
- public int internalGetIndex() {
- return get(pos).internalGetIndex();
- }
-
- @Override
- public boolean valid() {
- return pos < data.length;
- }
-
- @Override
- public void advance() {
- pos++;
- }
-
- /**
- * {@inheritDoc}
- *
- * @deprecated use {@link #doubleDistance}!
- */
- @Override
- @Deprecated
- public DoubleDistance getDistance() {
- return get(pos).getDistance();
- }
-
- @Override
- public double doubleDistance() {
- return get(pos).doubleDistance();
- }
-
- @Override
- public DoubleDistanceDBIDPair getDistancePair() {
- return get(pos);
- }
-
- @Override
- public int getOffset() {
- return pos;
- }
-
- @Override
- public void advance(int count) {
- pos += count;
- }
-
- @Override
- public void retract() {
- --pos;
- }
-
- @Override
- public void seek(int off) {
- pos = off;
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/GenericDistanceDBIDList.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/GenericDistanceDBIDList.java
deleted file mode 100644
index 911c58e7..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/GenericDistanceDBIDList.java
+++ /dev/null
@@ -1,206 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.ids.generic;
-
-/*
- 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.Arrays;
-import java.util.Comparator;
-
-import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory;
-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.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.distance.distanceresultlist.DistanceDBIDResultUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-
-/**
- * Default class to keep a list of distance-object pairs.
- *
- * @author Erich Schubert
- *
- * @param <D> Distance type
- */
-public class GenericDistanceDBIDList<D extends Distance<D>> implements ModifiableDistanceDBIDList<D> {
- /**
- * Actual storage.
- */
- Object[] storage;
-
- /**
- * Current size.
- */
- int size = 0;
-
- /**
- * Constructor.
- */
- public GenericDistanceDBIDList() {
- super();
- storage = new Object[21];
- }
-
- /**
- * Constructor.
- *
- * @param initialCapacity Capacity
- */
- public GenericDistanceDBIDList(int initialCapacity) {
- super();
- storage = new Object[initialCapacity];
- }
-
- @Override
- public void add(D dist, DBIDRef id) {
- ensureSize(size + 1);
- storage[size] = DBIDFactory.FACTORY.newDistancePair(dist, id);
- ++size;
- }
-
- /**
- * Add a prepared pair.
- *
- * @param pair Pair to add
- */
- public void add(DistanceDBIDPair<D> pair) {
- ensureSize(size + 1);
- storage[size] = pair;
- ++size;
- }
-
- private void ensureSize(int size) {
- if (size < storage.length) {
- storage = Arrays.copyOf(storage, (size << 1) + 1);
- }
- }
-
- @Override
- public void sort() {
- @SuppressWarnings("unchecked")
- final Comparator<Object> comp = (Comparator<Object>) DistanceDBIDResultUtil.distanceComparator();
- Arrays.sort(storage, 0, size, comp);
- // DistanceDBIDResultUtil.sortByDistance(storage);
- }
-
- @Override
- public int size() {
- return size;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public DistanceDBIDPair<D> get(int off) {
- return (DistanceDBIDPair<D>) storage[off];
- }
-
- @Override
- public DistanceDBIDListIter<D> iter() {
- return new Itr();
- }
-
- @Override
- public boolean contains(DBIDRef o) {
- for (DBIDIter iter = iter(); iter.valid(); iter.advance()) {
- if (DBIDUtil.equal(iter, o)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean isEmpty() {
- return size() == 0;
- }
-
- @Override
- public String toString() {
- return DistanceDBIDResultUtil.toString(this);
- }
-
- /**
- * Iterator class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- protected class Itr implements DistanceDBIDListIter<D> {
- /**
- * Iterator position.
- */
- int pos = 0;
-
- @Override
- public int internalGetIndex() {
- return get(pos).internalGetIndex();
- }
-
- @Override
- public boolean valid() {
- return pos < size();
- }
-
- @Override
- public void advance() {
- pos++;
- }
-
- @Override
- public D getDistance() {
- return get(pos).getDistance();
- }
-
- @Override
- public DistanceDBIDPair<D> getDistancePair() {
- return get(pos);
- }
-
- @Override
- public String toString() {
- return valid() ? getDistancePair().toString() : "null";
- }
-
- @Override
- public int getOffset() {
- return pos;
- }
-
- @Override
- public void advance(int count) {
- pos += count;
- }
-
- @Override
- public void retract() {
- --pos;
- }
-
- @Override
- public void seek(int off) {
- pos = off;
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/KNNSubList.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/KNNSubList.java
index 3d7863fd..6bfb05b0 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/KNNSubList.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/generic/KNNSubList.java
@@ -1,18 +1,10 @@
package de.lmu.ifi.dbs.elki.database.ids.generic;
-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.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-
/*
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,15 +22,19 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
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.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.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
/**
* Sublist of an existing result to contain only the first k elements.
*
* @author Erich Schubert
- *
- * @param <D> Distance
*/
-public class KNNSubList<D extends Distance<D>> implements KNNList<D> {
+public class KNNSubList implements KNNList {
/**
* Parameter k.
*/
@@ -52,7 +48,7 @@ public class KNNSubList<D extends Distance<D>> implements KNNList<D> {
/**
* Wrapped inner result.
*/
- private final KNNList<D> inner;
+ private final KNNList inner;
/**
* Constructor.
@@ -60,22 +56,24 @@ public class KNNSubList<D extends Distance<D>> implements KNNList<D> {
* @param inner Inner instance
* @param k k value
*/
- public KNNSubList(KNNList<D> inner, int k) {
+ public KNNSubList(KNNList inner, int k) {
this.inner = inner;
this.k = k;
// Compute list size
- // TODO: optimize for double distances.
- {
- DistanceDBIDPair<D> dist = inner.get(k);
+ if(k < inner.getK()) {
+ DoubleDBIDPair dist = inner.get(k);
int i = k;
- while (i + 1 < inner.size()) {
- if (dist.compareByDistance(inner.get(i + 1)) < 0) {
+ while(i + 1 < inner.size()) {
+ if(dist.doubleValue() < inner.get(i + 1).doubleValue()) {
break;
}
i++;
}
size = i;
}
+ else {
+ size = inner.size();
+ }
}
@Override
@@ -84,25 +82,25 @@ public class KNNSubList<D extends Distance<D>> implements KNNList<D> {
}
@Override
- public DistanceDBIDPair<D> get(int index) {
+ public DoubleDBIDPair get(int index) {
assert (index < size) : "Access beyond design size of list.";
return inner.get(index);
}
@Override
- public D getKNNDistance() {
- return inner.get(k).getDistance();
+ public double getKNNDistance() {
+ return inner.get(k).doubleValue();
}
@Override
- public DistanceDBIDListIter<D> iter() {
+ public DoubleDBIDListIter iter() {
return new Itr();
}
@Override
public boolean contains(DBIDRef o) {
- for (DBIDIter iter = iter(); iter.valid(); iter.advance()) {
- if (DBIDUtil.equal(iter, o)) {
+ for(DBIDIter iter = iter(); iter.valid(); iter.advance()) {
+ if(DBIDUtil.equal(iter, o)) {
return true;
}
}
@@ -126,7 +124,7 @@ public class KNNSubList<D extends Distance<D>> implements KNNList<D> {
*
* @apiviz.exclude
*/
- private class Itr implements DistanceDBIDListIter<D> {
+ private class Itr implements DoubleDBIDListIter {
/**
* Current position.
*/
@@ -134,21 +132,22 @@ public class KNNSubList<D extends Distance<D>> implements KNNList<D> {
@Override
public boolean valid() {
- return pos < size;
+ return pos < size && pos >= 0;
}
@Override
- public void advance() {
+ public Itr advance() {
pos++;
+ return this;
}
@Override
- public D getDistance() {
- return inner.get(pos).getDistance();
+ public double doubleValue() {
+ return inner.get(pos).doubleValue();
}
@Override
- public DistanceDBIDPair<D> getDistancePair() {
+ public DoubleDBIDPair getPair() {
return inner.get(pos);
}
@@ -163,18 +162,21 @@ public class KNNSubList<D extends Distance<D>> implements KNNList<D> {
}
@Override
- public void advance(int count) {
- pos -= count;
+ public Itr advance(int count) {
+ pos += count;
+ return this;
}
@Override
- public void retract() {
+ public Itr retract() {
--pos;
+ return this;
}
@Override
- public void seek(int off) {
+ public Itr seek(int off) {
pos = off;
+ return this;
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/MaskedDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/MaskedDBIDs.java
index 2b481fca..19162450 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/MaskedDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/generic/MaskedDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.generic;
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
@@ -35,6 +35,8 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
/**
* View on an ArrayDBIDs masked using a BitMask for efficient mask changing.
*
+ * FIXME: switch to long[] instead of BitSet
+ *
* @author Erich Schubert
*
* @apiviz.uses DBIDs
@@ -137,8 +139,9 @@ public class MaskedDBIDs implements DBIDs {
}
@Override
- public void advance() {
+ public DBIDIter advance() {
pos = bits.nextSetBit(pos + 1);
+ return this;
}
@Override
@@ -180,8 +183,9 @@ public class MaskedDBIDs implements DBIDs {
}
@Override
- public void advance() {
+ public DBIDIter advance() {
pos = bits.nextClearBit(pos + 1);
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableArrayDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableArrayDBIDs.java
index 49c6b07e..0b5d8ed2 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableArrayDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableArrayDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.generic;
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
@@ -131,8 +131,9 @@ public class UnmodifiableArrayDBIDs implements ArrayStaticDBIDs {
}
@Override
- public void advance() {
+ public DBIDArrayIter advance() {
it.advance();
+ return this;
}
@Override
@@ -141,18 +142,21 @@ public class UnmodifiableArrayDBIDs implements ArrayStaticDBIDs {
}
@Override
- public void advance(int count) {
+ public DBIDArrayIter advance(int count) {
it.advance(count);
+ return this;
}
@Override
- public void retract() {
+ public DBIDArrayIter retract() {
it.retract();
+ return this;
}
@Override
- public void seek(int off) {
+ public DBIDArrayIter seek(int off) {
it.seek(off);
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableDBIDs.java
index 458dab3f..0f4920a5 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.generic;
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
@@ -109,8 +109,9 @@ public class UnmodifiableDBIDs implements StaticDBIDs {
}
@Override
- public void advance() {
+ public DBIDIter advance() {
it.advance();
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/package-info.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/package-info.java
index 9920cac7..e2232e18 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/generic/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/database/ids/integer/AbstractIntegerDBIDFactory.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/AbstractIntegerDBIDFactory.java
index 72ecb9be..2317ac43 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/AbstractIntegerDBIDFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/AbstractIntegerDBIDFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,17 +31,11 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.DistanceDBIDPairKNNHeap;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
-import de.lmu.ifi.dbs.elki.persistent.FixedSizeByteBufferSerializer;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
+import de.lmu.ifi.dbs.elki.utilities.io.FixedSizeByteBufferSerializer;
/**
* Abstract base class for DBID factories.
@@ -89,7 +83,7 @@ abstract class AbstractIntegerDBIDFactory implements DBIDFactory {
@Override
public String toString(DBIDRef id) {
- return Integer.toString(id.internalGetIndex());
+ return (id != null) ? Integer.toString(id.internalGetIndex()) : "null";
}
@Override
@@ -134,60 +128,32 @@ abstract class AbstractIntegerDBIDFactory implements DBIDFactory {
@Override
public DoubleDBIDPair newPair(double val, DBIDRef id) {
- return new IntegerDoubleDBIDPair(val, id.internalGetIndex());
+ return new DoubleIntegerDBIDPair(val, id.internalGetIndex());
}
- @SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> DistanceDBIDPair<D> newDistancePair(D val, DBIDRef id) {
- if(val instanceof DoubleDistance) {
- return (DistanceDBIDPair<D>) new DoubleDistanceIntegerDBIDPair(((DoubleDistance) val).doubleValue(), id.internalGetIndex());
- }
- return new DistanceIntegerDBIDPair<>(val, id.internalGetIndex());
- }
-
- @Override
- public DoubleDistanceDBIDPair newDistancePair(double val, DBIDRef id) {
- return new DoubleDistanceIntegerDBIDPair(val, id.internalGetIndex());
+ public KNNHeap newHeap(int k) {
+ return new DoubleIntegerDBIDKNNHeap(k);
}
- @SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> KNNHeap<D> newHeap(D factory, int k) {
- if(factory instanceof DoubleDistance) {
- return (KNNHeap<D>) newDoubleDistanceHeap(k);
+ public KNNHeap newHeap(KNNList exist) {
+ KNNHeap heap = newHeap(exist.getK());
+ // Insert backwards, as this will produce a proper heap
+ for(int i = exist.size() - 1; i >= 0; i--) {
+ heap.insert(exist.get(i));
}
- return new DistanceDBIDPairKNNHeap<>(k);
+ return heap;
}
- @SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> KNNHeap<D> newHeap(KNNList<D> exist) {
- if(exist instanceof DoubleDistanceKNNList) {
- DoubleDistanceKNNHeap heap = newDoubleDistanceHeap(exist.getK());
- // Insert backwards, as this will produce a proper heap
- for(int i = exist.size() - 1; i >= 0; i--) {
- heap.insert((DoubleDistanceDBIDPair) exist.get(i));
- }
- return (KNNHeap<D>) heap;
- }
- else {
- DistanceDBIDPairKNNHeap<D> heap = new DistanceDBIDPairKNNHeap<>(exist.getK());
- // Insert backwards, as this will produce a proper heap
- for(int i = exist.size() - 1; i >= 0; i--) {
- heap.insert(exist.get(i));
- }
- return heap;
- }
+ public ModifiableDoubleDBIDList newDistanceDBIDList(int size) {
+ return new DoubleIntegerDBIDList(size);
}
@Override
- public DoubleDistanceKNNHeap newDoubleDistanceHeap(int k) {
- // TODO: benchmark threshold!
- if(k > 1000) {
- return new DoubleDistanceIntegerDBIDKNNHeap(k);
- }
- return new DoubleDistanceIntegerDBIDSortedKNNList(k);
+ public ModifiableDoubleDBIDList newDistanceDBIDList() {
+ return new DoubleIntegerDBIDList();
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayModifiableIntegerDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayModifiableIntegerDBIDs.java
index 2fc94ddb..1ead59b6 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayModifiableIntegerDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayModifiableIntegerDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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
@@ -38,7 +38,7 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
*
* @author Erich Schubert
*/
-public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, IntegerArrayDBIDs {
+class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, IntegerArrayDBIDs {
/**
* The actual Trove array list.
*/
@@ -292,8 +292,9 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
}
@Override
- public void advance() {
+ public Itr advance() {
++pos;
+ return this;
}
@Override
@@ -302,18 +303,21 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
}
@Override
- public void advance(int count) {
+ public Itr advance(int count) {
pos += count;
+ return this;
}
@Override
- public void retract() {
+ public Itr retract() {
--pos;
+ return this;
}
@Override
- public void seek(int off) {
+ public Itr seek(int off) {
pos = off;
+ return this;
}
@Override
@@ -423,8 +427,9 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
}
@Override
- public void advance() {
+ public SliceItr advance() {
++pos;
+ return this;
}
@Override
@@ -433,18 +438,21 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
}
@Override
- public void advance(int count) {
+ public SliceItr advance(int count) {
pos += count;
+ return this;
}
@Override
- public void retract() {
+ public SliceItr retract() {
--pos;
+ return this;
}
@Override
- public void seek(int off) {
+ public SliceItr seek(int off) {
pos = off;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayStaticIntegerDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayStaticIntegerDBIDs.java
index fcb426ac..60d43ff8 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayStaticIntegerDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayStaticIntegerDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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
@@ -37,7 +37,7 @@ import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
*
* @author Erich Schubert
*/
-public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs {
+class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs {
/**
* The actual storage.
*/
@@ -48,7 +48,7 @@ public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs {
*
* @param ids Array of ids.
*/
- public ArrayStaticIntegerDBIDs(int... ids) {
+ protected ArrayStaticIntegerDBIDs(int... ids) {
super();
this.store = ids;
}
@@ -123,23 +123,27 @@ public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs {
}
@Override
- public void advance() {
+ public Itr advance() {
pos++;
+ return this;
}
@Override
- public void advance(int count) {
+ public Itr advance(int count) {
pos += 0;
+ return this;
}
@Override
- public void retract() {
+ public Itr retract() {
pos--;
+ return this;
}
@Override
- public void seek(int off) {
+ public Itr seek(int off) {
pos = off;
+ return this;
}
@Override
@@ -262,8 +266,9 @@ public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs {
}
@Override
- public void advance() {
+ public SliceItr advance() {
++pos;
+ return this;
}
@Override
@@ -272,18 +277,21 @@ public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs {
}
@Override
- public void advance(int count) {
+ public SliceItr advance(int count) {
pos += count;
+ return this;
}
@Override
- public void retract() {
+ public SliceItr retract() {
--pos;
+ return this;
}
@Override
- public void seek(int off) {
+ public SliceItr seek(int off) {
pos = begin + off;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DistanceIntegerDBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DistanceIntegerDBIDPair.java
deleted file mode 100644
index a8930b87..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DistanceIntegerDBIDPair.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.ids.integer;
-
-/*
- 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.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.utilities.Util;
-
-/**
- * Class storing a double distance a DBID.
- *
- * @author Erich Schubert
- *
- * @param <D> Distance type
- */
-class DistanceIntegerDBIDPair<D extends Distance<D>> implements DistanceDBIDPair<D>, IntegerDBIDRef {
- /**
- * The distance value.
- */
- D distance;
-
- /**
- * The integer DBID.
- */
- int id;
-
- /**
- * Constructor.
- *
- * @param distance Distance
- * @param id Object ID
- */
- protected DistanceIntegerDBIDPair(D distance, int id) {
- super();
- this.distance = distance;
- this.id = id;
- }
-
- @Override
- public D getDistance() {
- return distance;
- }
-
- @Override
- public int internalGetIndex() {
- return id;
- }
-
- @Override
- public int compareByDistance(DistanceDBIDPair<D> o) {
- return distance.compareTo(o.getDistance());
- }
-
- @Override
- public String toString() {
- return distance.toString() + ":" + id;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o instanceof DistanceIntegerDBIDPair) {
- DistanceIntegerDBIDPair<?> p = (DistanceIntegerDBIDPair<?>) o;
- return (this.id == p.id) && distance.equals(p.getDistance());
- }
- if (o instanceof DoubleDistanceIntegerDBIDPair && distance instanceof DoubleDistance) {
- DoubleDistanceIntegerDBIDPair p = (DoubleDistanceIntegerDBIDPair) o;
- return (this.id == p.id) && (Double.compare(((DoubleDistance) this.distance).doubleValue(), p.distance) == 0);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Util.mixHashCodes(distance.hashCode(), id);
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPair.java
deleted file mode 100644
index 1f3b2a45..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPair.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.ids.integer;
-
-/*
- 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.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.utilities.Util;
-
-/**
- * Class storing a double distance a DBID.
- *
- * @author Erich Schubert
- */
-class DoubleDistanceIntegerDBIDPair implements DoubleDistanceDBIDPair, IntegerDBIDRef {
- /**
- * The distance value.
- */
- final double distance;
-
- /**
- * The integer DBID.
- */
- final int id;
-
- /**
- * Constructor.
- *
- * @param distance Distance value
- * @param id integer object ID
- */
- protected DoubleDistanceIntegerDBIDPair(double distance, int id) {
- super();
- this.distance = distance;
- this.id = id;
- }
-
- @Override
- public double doubleDistance() {
- return distance;
- }
-
- @Override
- @Deprecated
- public DoubleDistance getDistance() {
- return new DoubleDistance(distance);
- }
-
- @Override
- public int internalGetIndex() {
- return id;
- }
-
- @Override
- public int compareByDistance(DistanceDBIDPair<DoubleDistance> o) {
- if (o instanceof DoubleDistanceDBIDPair) {
- return Double.compare(distance, ((DoubleDistanceDBIDPair) o).doubleDistance());
- }
- return Double.compare(distance, o.getDistance().doubleValue());
- }
-
- @Override
- public String toString() {
- return distance + ":" + id;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o instanceof DoubleDistanceIntegerDBIDPair) {
- DoubleDistanceIntegerDBIDPair p = (DoubleDistanceIntegerDBIDPair) o;
- return (this.id == p.id) && (Double.compare(this.distance, p.distance) == 0);
- }
- if (o instanceof DistanceIntegerDBIDPair) {
- DistanceIntegerDBIDPair<?> p = (DistanceIntegerDBIDPair<?>) o;
- if (p.distance instanceof DoubleDistance) {
- return (this.id == p.id) && (Double.compare(this.distance, ((DoubleDistance) p.distance).doubleValue()) == 0);
- }
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- long bits = Double.doubleToLongBits(distance);
- return Util.mixHashCodes((int) (bits ^ (bits >>> 32)), id);
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairKNNListHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairKNNListHeap.java
deleted file mode 100644
index aa0a9739..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairKNNListHeap.java
+++ /dev/null
@@ -1,339 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.ids.integer;
-
-/*
- 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.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.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-
-/**
- * Finalized KNN List.
- *
- * @author Erich Schubert
- *
- * @apiviz.composedOf DoubleDistanceDBIDPair
- * @apiviz.has DoubleDistanceDBIDListIter
- */
-public class DoubleDistanceIntegerDBIDPairKNNListHeap implements DoubleDistanceKNNList, DoubleDistanceKNNHeap {
- /**
- * The value of k this was materialized for.
- */
- private final int k;
-
- /**
- * The actual data array.
- */
- private DoubleDistanceIntegerDBIDPair[] data;
-
- /**
- * Current size
- */
- private int size;
-
- /**
- * Constructor.
- *
- * @param k K parameter
- */
- public DoubleDistanceIntegerDBIDPairKNNListHeap(int k) {
- super();
- this.data = new DoubleDistanceIntegerDBIDPair[k + 5];
- this.k = k;
- this.size = 0;
- }
-
- @Override
- public void clear() {
- for(int i = 0; i < size; i++) {
- data[i] = null; // discard
- }
- size = 0;
- }
-
- @Override
- public double insert(double distance, DBIDRef id) {
- final int kminus1 = k - 1;
- if(size < k || distance <= data[kminus1].doubleDistance()) {
- // Ensure we have enough space.
- if(size > data.length) {
- grow();
- }
- insertionSort(new DoubleDistanceIntegerDBIDPair(distance, id.internalGetIndex()));
- // Truncate if necessary:
- if(size > k && data[k].doubleDistance() > data[kminus1].doubleDistance()) {
- truncate();
- }
- }
- return (size < k) ? Double.POSITIVE_INFINITY : get(kminus1).doubleDistance();
- }
-
- private void truncate() {
- for(int i = k; i < size; i++) {
- data[i] = null; // discard
- }
- size = k;
- }
-
- @Override
- @Deprecated
- public void insert(Double distance, DBIDRef id) {
- final int kminus1 = k - 1;
- if(size < k || distance.doubleValue() <= data[kminus1].doubleDistance()) {
- // Ensure we have enough space.
- if(size > data.length) {
- grow();
- }
- insertionSort(new DoubleDistanceIntegerDBIDPair(distance.doubleValue(), id.internalGetIndex()));
- // Truncate if necessary:
- if(size > k && data[k].doubleDistance() > data[kminus1].doubleDistance()) {
- truncate();
- }
- }
- }
-
- @Override
- @Deprecated
- public void insert(DoubleDistance dist, DBIDRef id) {
- final int kminus1 = k - 1;
- if(size < k || dist.doubleValue() <= data[kminus1].doubleDistance()) {
- // Ensure we have enough space.
- if(size > data.length) {
- grow();
- }
- insertionSort(new DoubleDistanceIntegerDBIDPair(dist.doubleValue(), id.internalGetIndex()));
- // Truncate if necessary:
- if(size > k && data[k].doubleDistance() > data[kminus1].doubleDistance()) {
- truncate();
- }
- }
- }
-
- @Override
- public void insert(DoubleDistanceDBIDPair e) {
- final int kminus1 = k - 1;
- final double dist = e.doubleDistance();
- if(size < k || dist <= data[kminus1].doubleDistance()) {
- // Ensure we have enough space.
- if(size > data.length) {
- grow();
- }
- if(e instanceof DoubleDistanceIntegerDBIDPair) {
- insertionSort((DoubleDistanceIntegerDBIDPair) e);
- }
- else {
- insertionSort(new DoubleDistanceIntegerDBIDPair(dist, e.internalGetIndex()));
- }
- // Truncate if necessary:
- if(size > k && data[k].doubleDistance() > data[kminus1].doubleDistance()) {
- truncate();
- }
- }
- }
-
- /**
- * Perform insertion sort.
- *
- * @param obj Object to insert
- */
- private void insertionSort(DoubleDistanceIntegerDBIDPair obj) {
- // Insertion sort:
- int pos = size;
- while(pos > 0) {
- final int prev = pos - 1;
- DoubleDistanceIntegerDBIDPair pobj = data[prev];
- if(pobj.doubleDistance() <= obj.doubleDistance()) {
- break;
- }
- data[pos] = pobj;
- pos = prev;
- }
- data[pos] = obj;
- ++size;
- }
-
- private void grow() {
- final DoubleDistanceIntegerDBIDPair[] old = data;
- data = new DoubleDistanceIntegerDBIDPair[data.length + (data.length >> 1)];
- System.arraycopy(old, 0, data, 0, old.length);
- }
-
- @Override
- public DoubleDistanceIntegerDBIDPair poll() {
- assert (size > 0);
- return data[size--];
- }
-
- @Override
- public DoubleDistanceIntegerDBIDPair peek() {
- assert (size > 0);
- return data[size - 1];
- }
-
- @Override
- public DoubleDistanceKNNList toKNNList() {
- return this;
- }
-
- @Override
- public int getK() {
- return k;
- }
-
- @Override
- @Deprecated
- public DoubleDistance getKNNDistance() {
- if(size < k) {
- return DoubleDistance.INFINITE_DISTANCE;
- }
- return get(k - 1).getDistance();
- }
-
- @Override
- public double doubleKNNDistance() {
- if(size < k) {
- return Double.POSITIVE_INFINITY;
- }
- return get(k - 1).doubleDistance();
- }
-
- @Override
- public String toString() {
- StringBuilder buf = new StringBuilder();
- buf.append("kNNList[");
- for(DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) {
- buf.append(iter.doubleDistance()).append(':').append(DBIDUtil.toString(iter));
- iter.advance();
- if(iter.valid()) {
- buf.append(',');
- }
- }
- buf.append(']');
- return buf.toString();
- }
-
- @Override
- public DoubleDistanceIntegerDBIDPair get(int index) {
- return data[index];
- }
-
- @Override
- public DoubleDistanceIntegerDBIDListIter iter() {
- return new Itr();
- }
-
- @Override
- public int size() {
- return size;
- }
-
- @Override
- public boolean contains(DBIDRef o) {
- for(DBIDIter iter = iter(); iter.valid(); iter.advance()) {
- if(DBIDUtil.equal(iter, o)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean isEmpty() {
- return size == 0;
- }
-
- /**
- * Iterator.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- private class Itr implements DoubleDistanceIntegerDBIDListIter {
- /**
- * Cursor position.
- */
- private int pos = 0;
-
- @Override
- public int internalGetIndex() {
- return get(pos).internalGetIndex();
- }
-
- @Override
- public boolean valid() {
- return pos < size;
- }
-
- @Override
- public void advance() {
- pos++;
- }
-
- /**
- * {@inheritDoc}
- *
- * @deprecated use {@link #doubleDistance}!
- */
- @Override
- @Deprecated
- public DoubleDistance getDistance() {
- return get(pos).getDistance();
- }
-
- @Override
- public double doubleDistance() {
- return get(pos).doubleDistance();
- }
-
- @Override
- public DoubleDistanceIntegerDBIDPair getDistancePair() {
- return get(pos);
- }
-
- @Override
- public int getOffset() {
- return pos;
- }
-
- @Override
- public void advance(int count) {
- pos += count;
- }
-
- @Override
- public void retract() {
- --pos;
- }
-
- @Override
- public void seek(int off) {
- pos = off;
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDKNNHeap.java
index 96babaa3..45a247f9 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDKNNHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,9 +26,8 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.DoubleIntegerMaxHeap;
/**
@@ -36,10 +35,10 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.DoubleIntegerMaxHeap;
*
* @author Erich Schubert
*
- * @apiviz.has DoubleDistanceIntegerDBIDKNNList
+ * @apiviz.has DoubleIntegerDBIDKNNList
* @apiviz.composedOf DoubleIntegerMaxHeap
*/
-public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
+class DoubleIntegerDBIDKNNHeap implements KNNHeap {
/**
* k for this heap.
*/
@@ -75,7 +74,7 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
*
* @param k Size of knn.
*/
- public DoubleDistanceIntegerDBIDKNNHeap(int k) {
+ protected DoubleIntegerDBIDKNNHeap(int k) {
super();
this.k = k;
this.heap = new DoubleIntegerMaxHeap(k);
@@ -88,66 +87,11 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
}
@Override
- @Deprecated
- public DoubleDistance getKNNDistance() {
- if(heap.size() < k) {
- return DoubleDistance.INFINITE_DISTANCE;
- }
- return new DoubleDistance(kdist);
- }
-
- @Override
- public double doubleKNNDistance() {
+ public double getKNNDistance() {
return kdist;
}
@Override
- @Deprecated
- public void insert(DoubleDistance distance, DBIDRef id) {
- final double dist = distance.doubleValue();
- final int iid = id.internalGetIndex();
- if(heap.size() < k) {
- heap.add(dist, iid);
- if(heap.size() >= k) {
- kdist = heap.peekKey();
- }
- return;
- }
- // Tied with top:
- if(dist >= kdist) {
- if(dist == kdist) {
- addToTies(iid);
- }
- return;
- }
- // Old top element: (kdist, previd)
- updateHeap(dist, iid);
- }
-
- @Override
- @Deprecated
- public void insert(Double distance, DBIDRef id) {
- final double dist = distance.doubleValue();
- final int iid = id.internalGetIndex();
- if(heap.size() < k) {
- heap.add(dist, iid);
- if(heap.size() >= k) {
- kdist = heap.peekKey();
- }
- return;
- }
- // Tied with top:
- if(dist >= kdist) {
- if(dist == kdist) {
- addToTies(iid);
- }
- return;
- }
- // Old top element: (kdist, previd)
- updateHeap(dist, iid);
- }
-
- @Override
public final double insert(final double distance, final DBIDRef id) {
final int iid = id.internalGetIndex();
if(heap.size() < k) {
@@ -170,8 +114,8 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
}
@Override
- public void insert(final DoubleDistanceDBIDPair e) {
- final double distance = e.doubleDistance();
+ public void insert(final DoubleDBIDPair e) {
+ final double distance = e.doubleValue();
final int iid = e.internalGetIndex();
if(heap.size() < k) {
heap.add(distance, iid);
@@ -225,16 +169,12 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
}
@Override
- public DoubleDistanceIntegerDBIDPair poll() {
- final DoubleDistanceIntegerDBIDPair ret;
+ public DoubleIntegerDBIDPair poll() {
if(numties > 0) {
- ret = new DoubleDistanceIntegerDBIDPair(kdist, ties[numties - 1]);
- --numties;
- }
- else {
- ret = new DoubleDistanceIntegerDBIDPair(heap.peekKey(), heap.peekValue());
- heap.poll();
+ return new DoubleIntegerDBIDPair(kdist, ties[--numties]);
}
+ final DoubleIntegerDBIDPair ret = new DoubleIntegerDBIDPair(heap.peekKey(), heap.peekValue());
+ heap.poll();
return ret;
}
@@ -251,11 +191,11 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
}
@Override
- public DoubleDistanceIntegerDBIDPair peek() {
+ public DoubleIntegerDBIDPair peek() {
if(numties > 0) {
- return new DoubleDistanceIntegerDBIDPair(kdist, ties[numties - 1]);
+ return new DoubleIntegerDBIDPair(kdist, ties[numties - 1]);
}
- return new DoubleDistanceIntegerDBIDPair(heap.peekKey(), heap.peekValue());
+ return new DoubleIntegerDBIDPair(heap.peekKey(), heap.peekValue());
}
@Override
@@ -265,7 +205,7 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
@Override
public boolean isEmpty() {
- return heap.size() == 0;
+ return heap.isEmpty();
}
@Override
@@ -275,9 +215,9 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
}
@Override
- public DoubleDistanceIntegerDBIDKNNList toKNNList() {
+ public DoubleIntegerDBIDKNNList toKNNList() {
final int hsize = heap.size();
- DoubleDistanceIntegerDBIDKNNList ret = new DoubleDistanceIntegerDBIDKNNList(k, hsize + numties);
+ DoubleIntegerDBIDKNNList ret = new DoubleIntegerDBIDKNNList(k, hsize + numties);
// Add ties:
for(int i = 0; i < numties; i++) {
ret.dists[hsize + i] = kdist;
@@ -289,7 +229,6 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
heap.poll();
}
ret.size = hsize + numties;
- ret.sort();
return ret;
}
@@ -299,12 +238,7 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
* @return distance
*/
protected double peekDistance() {
- if(numties > 0) {
- return kdist;
- }
- else {
- return heap.peekKey();
- }
+ return (numties > 0) ? kdist : heap.peekKey();
}
/**
@@ -313,9 +247,6 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
* @return internal id
*/
protected int peekInternalDBID() {
- if(numties > 0) {
- return ties[numties - 1];
- }
- return heap.peekValue();
+ return (numties > 0) ? ties[numties - 1] : heap.peekValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDKNNList.java
index f6515d88..b324955a 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNList.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDKNNList.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,9 +22,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
/**
* kNN list, but without automatic sorting. Use with care, as others may expect
@@ -32,7 +30,7 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
*
* @author Erich Schubert
*/
-public class DoubleDistanceIntegerDBIDKNNList extends DoubleDistanceIntegerDBIDList implements DoubleDistanceKNNList {
+public class DoubleIntegerDBIDKNNList extends DoubleIntegerDBIDList implements IntegerDBIDKNNList {
/**
* The k value this list was generated for.
*/
@@ -41,7 +39,7 @@ public class DoubleDistanceIntegerDBIDKNNList extends DoubleDistanceIntegerDBIDL
/**
* Constructor.
*/
- public DoubleDistanceIntegerDBIDKNNList() {
+ public DoubleIntegerDBIDKNNList() {
super();
this.k = -1;
}
@@ -52,7 +50,7 @@ public class DoubleDistanceIntegerDBIDKNNList extends DoubleDistanceIntegerDBIDL
* @param k K parameter
* @param size Actual size
*/
- public DoubleDistanceIntegerDBIDKNNList(final int k, int size) {
+ public DoubleIntegerDBIDKNNList(final int k, int size) {
super(size);
this.k = k;
}
@@ -62,18 +60,8 @@ public class DoubleDistanceIntegerDBIDKNNList extends DoubleDistanceIntegerDBIDL
return k;
}
- /**
- * @deprecated Since you know this is a double distance heap, use
- * {@link #doubleKNNDistance()}
- */
- @Override
- @Deprecated
- public DoubleDistance getKNNDistance() {
- return new DoubleDistance(doubleKNNDistance());
- }
-
@Override
- public double doubleKNNDistance() {
+ public double getKNNDistance() {
return (size >= k) ? dists[k - 1] : Double.POSITIVE_INFINITY;
}
@@ -81,10 +69,10 @@ public class DoubleDistanceIntegerDBIDKNNList extends DoubleDistanceIntegerDBIDL
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("kNNList[");
- for (DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) {
- buf.append(iter.doubleDistance()).append(':').append(iter.internalGetIndex());
+ for(DoubleDBIDListIter iter = this.iter(); iter.valid();) {
+ buf.append(iter.doubleValue()).append(':').append(iter.internalGetIndex());
iter.advance();
- if (iter.valid()) {
+ if(iter.valid()) {
buf.append(',');
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDList.java
index 0db0204c..706938d5 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDList.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDList.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,10 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDoubleDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.DoubleIntegerArrayQuickSort;
/**
* Class to store double distance, integer DBID results.
@@ -36,7 +36,7 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
*
* @apiviz.uses DoubleIntegerArrayQuickSort
*/
-public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDBIDList, IntegerDBIDs {
+class DoubleIntegerDBIDList implements ModifiableDoubleDBIDList, IntegerDBIDs {
/**
* Initial size allocation.
*/
@@ -70,7 +70,7 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB
/**
* Constructor.
*/
- public DoubleDistanceIntegerDBIDList() {
+ protected DoubleIntegerDBIDList() {
dists = EMPTY_DISTS;
ids = EMPTY_IDS;
}
@@ -80,10 +80,10 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB
*
* @param size Initial size
*/
- public DoubleDistanceIntegerDBIDList(int size) {
+ protected DoubleIntegerDBIDList(int size) {
this.dists = new double[size];
this.ids = new int[size];
- // This is default anyway: this.size = 0;
+ // This is default: this.size = 0;
}
@Override
@@ -94,8 +94,8 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB
@Override
public boolean contains(DBIDRef o) {
final int q = o.internalGetIndex();
- for (int i = 0; i < size; i++) {
- if (q == ids[i]) {
+ for(int i = 0; i < size; i++) {
+ if(q == ids[i]) {
return true;
}
}
@@ -113,8 +113,8 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB
}
@Override
- public DoubleDistanceIntegerDBIDPair get(int index) {
- return new DoubleDistanceIntegerDBIDPair(dists[index], ids[index]);
+ public DoubleIntegerDBIDPair get(int index) {
+ return new DoubleIntegerDBIDPair(dists[index], ids[index]);
}
/**
@@ -124,7 +124,7 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB
* @param id Internal index
*/
protected void addInternal(double dist, int id) {
- if (size == dists.length) {
+ if(size == dists.length) {
grow();
}
dists[size] = dist;
@@ -136,7 +136,7 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB
* Grow the data storage.
*/
protected void grow() {
- if (dists == EMPTY_DISTS) {
+ if(dists == EMPTY_DISTS) {
dists = new double[INITIAL_SIZE];
ids = new int[INITIAL_SIZE];
return;
@@ -152,19 +152,13 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB
}
@Override
- @Deprecated
- public void add(DoubleDistance dist, DBIDRef id) {
- addInternal(dist.doubleValue(), id.internalGetIndex());
- }
-
- @Override
public void add(double dist, DBIDRef id) {
addInternal(dist, id.internalGetIndex());
}
@Override
- public void add(DoubleDistanceDBIDPair pair) {
- addInternal(pair.doubleDistance(), pair.internalGetIndex());
+ public void add(DoubleDBIDPair pair) {
+ addInternal(pair.doubleValue(), pair.internalGetIndex());
}
@Override
@@ -182,7 +176,7 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB
* Reverse the list.
*/
protected void reverse() {
- for (int i = 0, j = size - 1; i < j; i++, j--) {
+ for(int i = 0, j = size - 1; i < j; i++, j--) {
double tmpd = dists[j];
dists[j] = dists[i];
dists[i] = tmpd;
@@ -198,7 +192,7 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB
* @param newsize New size
*/
public void truncate(int newsize) {
- if (newsize < size) {
+ if(newsize < size) {
double[] odists = dists;
dists = new double[newsize];
System.arraycopy(odists, 0, dists, 0, newsize);
@@ -225,11 +219,11 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
- buf.append("DistanceDBIDList[");
- for (DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) {
- buf.append(iter.doubleDistance()).append(':').append(iter.internalGetIndex());
+ buf.append("DoubleDBIDList[");
+ for(DoubleDBIDListIter iter = this.iter(); iter.valid();) {
+ buf.append(iter.doubleValue()).append(':').append(iter.internalGetIndex());
iter.advance();
- if (iter.valid()) {
+ if(iter.valid()) {
buf.append(',');
}
}
@@ -244,11 +238,11 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB
*
* @apiviz.exclude
*/
- private class Itr implements DoubleDistanceIntegerDBIDListIter {
+ private class Itr implements DoubleIntegerDBIDListIter, IntegerDBIDArrayIter {
/**
* Current offset.
*/
- int offset = 0;
+ int pos = 0;
/**
* Constructor.
@@ -259,53 +253,51 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB
@Override
public boolean valid() {
- return offset < size;
+ return pos < size && pos >= 0;
}
@Override
- public void advance() {
- ++offset;
+ public Itr advance() {
+ ++pos;
+ return this;
}
@Override
public int getOffset() {
- return offset;
+ return pos;
}
@Override
- public void advance(int count) {
- offset += count;
+ public Itr advance(int count) {
+ pos += count;
+ return this;
}
@Override
- public void retract() {
- --offset;
+ public Itr retract() {
+ --pos;
+ return this;
}
@Override
- public void seek(int off) {
- offset = off;
+ public Itr seek(int off) {
+ pos = off;
+ return this;
}
@Override
public int internalGetIndex() {
- return ids[offset];
- }
-
- @Override
- public double doubleDistance() {
- return dists[offset];
+ return ids[pos];
}
@Override
- public DoubleDistanceDBIDPair getDistancePair() {
- return new DoubleDistanceIntegerDBIDPair(dists[offset], ids[offset]);
+ public double doubleValue() {
+ return dists[pos];
}
@Override
- @Deprecated
- public DoubleDistance getDistance() {
- return new DoubleDistance(dists[offset]);
+ public DoubleDBIDPair getPair() {
+ return new DoubleIntegerDBIDPair(dists[pos], ids[pos]);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDListIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDListIter.java
index 0df81929..82d19990 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDListIter.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDListIter.java
@@ -1,10 +1,9 @@
package de.lmu.ifi.dbs.elki.database.ids.integer;
-
/*
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,13 +21,14 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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.distance.DoubleDistanceDBIDListIter;
+
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
/**
- * Combination interface.
+ * Combination interface of the DoubleDBIDListIter with IntegerDBIDIter.
*
* @author Erich Schubert
*/
-public interface DoubleDistanceIntegerDBIDListIter extends DoubleDistanceDBIDListIter, IntegerDBIDArrayIter {
- // Yet another painful combination interface.
+public interface DoubleIntegerDBIDListIter extends DoubleDBIDListIter, IntegerDBIDIter {
+ // No additional methods.
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDSortedKNNList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDListKNNHeap.java
index c4c60bc0..b2cd9d25 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDSortedKNNList.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDListKNNHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,11 +23,10 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
/**
* Track the k nearest neighbors, with insertion sort to ensure the correct
@@ -35,13 +34,13 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
*
* @author Erich Schubert
*/
-public class DoubleDistanceIntegerDBIDSortedKNNList extends DoubleDistanceIntegerDBIDKNNList implements DoubleDistanceKNNHeap {
+class DoubleIntegerDBIDListKNNHeap extends DoubleIntegerDBIDKNNList implements KNNHeap {
/**
* Constructor.
*
* @param k K parameter
*/
- public DoubleDistanceIntegerDBIDSortedKNNList(int k) {
+ protected DoubleIntegerDBIDListKNNHeap(int k) {
super(k, k + 11);
}
@@ -107,36 +106,24 @@ public class DoubleDistanceIntegerDBIDSortedKNNList extends DoubleDistanceIntege
}
@Override
- @Deprecated
- public void insert(Double dist, DBIDRef id) {
- addInternal(dist.doubleValue(), id.internalGetIndex());
+ public void insert(DoubleDBIDPair e) {
+ addInternal(e.doubleValue(), e.internalGetIndex());
}
@Override
- public void insert(DoubleDistanceDBIDPair e) {
- addInternal(e.doubleDistance(), e.internalGetIndex());
- }
-
- @Override
- @Deprecated
- public void insert(DoubleDistance dist, DBIDRef id) {
- addInternal(dist.doubleValue(), id.internalGetIndex());
- }
-
- @Override
- public DoubleDistanceIntegerDBIDPair poll() {
+ public DoubleIntegerDBIDPair poll() {
final int last = size - 1;
- return new DoubleDistanceIntegerDBIDPair(dists[last], ids[last]);
+ return new DoubleIntegerDBIDPair(dists[last], ids[last]);
}
@Override
- public DoubleDistanceIntegerDBIDPair peek() {
+ public DoubleIntegerDBIDPair peek() {
final int last = size - 1;
- return new DoubleDistanceIntegerDBIDPair(dists[last], ids[last]);
+ return new DoubleIntegerDBIDPair(dists[last], ids[last]);
}
@Override
- public DoubleDistanceKNNList toKNNList() {
+ public KNNList toKNNList() {
return this;
}
@@ -144,8 +131,8 @@ public class DoubleDistanceIntegerDBIDSortedKNNList extends DoubleDistanceIntege
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("kNNListHeap[");
- for(DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) {
- buf.append(iter.doubleDistance()).append(':').append(iter.internalGetIndex());
+ for(DoubleDBIDListIter iter = this.iter(); iter.valid();) {
+ buf.append(iter.doubleValue()).append(':').append(iter.internalGetIndex());
iter.advance();
if(iter.valid()) {
buf.append(',');
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDoubleDBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPair.java
index b522ffb2..563fceb5 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDoubleDBIDPair.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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.database.ids.integer;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
/**
@@ -31,7 +30,7 @@ import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
*
* @author Erich Schubert
*/
-class IntegerDoubleDBIDPair implements DoubleDBIDPair, IntegerDBIDRef {
+class DoubleIntegerDBIDPair implements DoubleDBIDPair, IntegerDBIDRef {
/**
* The double value.
*/
@@ -48,7 +47,7 @@ class IntegerDoubleDBIDPair implements DoubleDBIDPair, IntegerDBIDRef {
* @param value Double value
* @param id DBID
*/
- protected IntegerDoubleDBIDPair(double value, int id) {
+ protected DoubleIntegerDBIDPair(double value, int id) {
super();
this.value = value;
this.id = id;
@@ -68,16 +67,4 @@ class IntegerDoubleDBIDPair implements DoubleDBIDPair, IntegerDBIDRef {
public double doubleValue() {
return value;
}
-
- @Override
- @Deprecated
- public Double getFirst() {
- return new Double(value);
- }
-
- @Override
- @Deprecated
- public DBID getSecond() {
- return new IntegerDBID(id);
- }
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPairKNNListHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPairKNNListHeap.java
new file mode 100644
index 00000000..086b5f69
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPairKNNListHeap.java
@@ -0,0 +1,286 @@
+package de.lmu.ifi.dbs.elki.database.ids.integer;
+
+/*
+ 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.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.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+
+/**
+ * KNN Heap implemented using a list of DoubleInt pair objects.
+ *
+ * Currently unused, needs benchmarking.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.composedOf DoubleIntegerDBIDPair
+ */
+class DoubleIntegerDBIDPairKNNListHeap implements IntegerDBIDKNNList, KNNHeap {
+ /**
+ * The value of k this was materialized for.
+ */
+ private final int k;
+
+ /**
+ * The actual data array.
+ */
+ private DoubleIntegerDBIDPair[] data;
+
+ /**
+ * Current size
+ */
+ private int size;
+
+ /**
+ * Constructor.
+ *
+ * @param k K parameter
+ */
+ protected DoubleIntegerDBIDPairKNNListHeap(int k) {
+ super();
+ this.data = new DoubleIntegerDBIDPair[k + 5];
+ this.k = k;
+ this.size = 0;
+ }
+
+ @Override
+ public void clear() {
+ for(int i = 0; i < size; i++) {
+ data[i] = null; // discard
+ }
+ size = 0;
+ }
+
+ @Override
+ public double insert(double distance, DBIDRef id) {
+ final int kminus1 = k - 1;
+ if(size < k || distance <= data[kminus1].doubleValue()) {
+ // Ensure we have enough space.
+ if(size > data.length) {
+ grow();
+ }
+ insertionSort(new DoubleIntegerDBIDPair(distance, id.internalGetIndex()));
+ // Truncate if necessary:
+ if(size > k && data[k].doubleValue() > data[kminus1].doubleValue()) {
+ truncate();
+ }
+ }
+ return (size < k) ? Double.POSITIVE_INFINITY : get(kminus1).doubleValue();
+ }
+
+ private void truncate() {
+ for(int i = k; i < size; i++) {
+ data[i] = null; // discard
+ }
+ size = k;
+ }
+
+ @Override
+ public void insert(DoubleDBIDPair e) {
+ final int kminus1 = k - 1;
+ final double dist = e.doubleValue();
+ if(size < k || dist <= data[kminus1].doubleValue()) {
+ // Ensure we have enough space.
+ if(size > data.length) {
+ grow();
+ }
+ if(e instanceof DoubleIntegerDBIDPair) {
+ insertionSort((DoubleIntegerDBIDPair) e);
+ }
+ else {
+ insertionSort(new DoubleIntegerDBIDPair(dist, e.internalGetIndex()));
+ }
+ // Truncate if necessary:
+ if(size > k && data[k].doubleValue() > data[kminus1].doubleValue()) {
+ truncate();
+ }
+ }
+ }
+
+ /**
+ * Perform insertion sort.
+ *
+ * @param obj Object to insert
+ */
+ private void insertionSort(DoubleIntegerDBIDPair obj) {
+ // Insertion sort:
+ int pos = size;
+ while(pos > 0) {
+ final int prev = pos - 1;
+ DoubleIntegerDBIDPair pobj = data[prev];
+ if(pobj.doubleValue() <= obj.doubleValue()) {
+ break;
+ }
+ data[pos] = pobj;
+ pos = prev;
+ }
+ data[pos] = obj;
+ ++size;
+ }
+
+ private void grow() {
+ final DoubleIntegerDBIDPair[] old = data;
+ data = new DoubleIntegerDBIDPair[data.length + (data.length >> 1)];
+ System.arraycopy(old, 0, data, 0, old.length);
+ }
+
+ @Override
+ public DoubleIntegerDBIDPair poll() {
+ assert (size > 0);
+ return data[size--];
+ }
+
+ @Override
+ public DoubleIntegerDBIDPair peek() {
+ assert (size > 0);
+ return data[size - 1];
+ }
+
+ @Override
+ public KNNList toKNNList() {
+ return this;
+ }
+
+ @Override
+ public int getK() {
+ return k;
+ }
+
+ @Override
+ public double getKNNDistance() {
+ return (size >= k) ? get(k - 1).doubleValue() : Double.POSITIVE_INFINITY;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("kNNList[");
+ for(DoubleDBIDListIter iter = this.iter(); iter.valid();) {
+ buf.append(iter.doubleValue()).append(':').append(DBIDUtil.toString(iter));
+ iter.advance();
+ if(iter.valid()) {
+ buf.append(',');
+ }
+ }
+ buf.append(']');
+ return buf.toString();
+ }
+
+ @Override
+ public DoubleIntegerDBIDPair get(int index) {
+ return data[index];
+ }
+
+ @Override
+ public Itr iter() {
+ return new Itr();
+ }
+
+ @Override
+ public int size() {
+ return size;
+ }
+
+ @Override
+ public boolean contains(DBIDRef o) {
+ for(DBIDIter iter = iter(); iter.valid(); iter.advance()) {
+ if(DBIDUtil.equal(iter, o)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ /**
+ * Iterator.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ private class Itr implements DoubleIntegerDBIDListIter, IntegerDBIDArrayIter {
+ /**
+ * Cursor position.
+ */
+ private int pos = 0;
+
+ @Override
+ public int internalGetIndex() {
+ return get(pos).internalGetIndex();
+ }
+
+ @Override
+ public boolean valid() {
+ return pos < size && pos >= 0;
+ }
+
+ @Override
+ public Itr advance() {
+ pos++;
+ return this;
+ }
+
+ @Override
+ public double doubleValue() {
+ return get(pos).doubleValue();
+ }
+
+ @Override
+ public DoubleIntegerDBIDPair getPair() {
+ return get(pos);
+ }
+
+ @Override
+ public int getOffset() {
+ return pos;
+ }
+
+ @Override
+ public Itr advance(int count) {
+ pos += count;
+ return this;
+ }
+
+ @Override
+ public Itr retract() {
+ --pos;
+ return this;
+ }
+
+ @Override
+ public Itr seek(int off) {
+ pos = off;
+ return this;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPairList.java
index 5b33d3f9..bee9d47d 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairList.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPairList.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,18 +25,18 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDoubleDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.distance.distanceresultlist.DistanceDBIDResultUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
/**
* Class to store double distance, integer DBID results.
*
+ * Currently unused. Needs benchmarking.
+ *
* @author Erich Schubert
*/
-public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistanceDBIDList, IntegerDBIDs {
+class DoubleIntegerDBIDPairList implements ModifiableDoubleDBIDList, IntegerDBIDs {
/**
* The size
*/
@@ -45,14 +45,14 @@ public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistan
/**
* Distance values
*/
- DoubleDistanceIntegerDBIDPair[] data;
+ DoubleIntegerDBIDPair[] data;
/**
* Constructor.
*/
- public DoubleDistanceIntegerDBIDPairList() {
+ protected DoubleIntegerDBIDPairList() {
super();
- this.data = new DoubleDistanceIntegerDBIDPair[21];
+ this.data = new DoubleIntegerDBIDPair[21];
}
/**
@@ -60,24 +60,24 @@ public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistan
*
* @param size Initial size
*/
- public DoubleDistanceIntegerDBIDPairList(int size) {
+ protected DoubleIntegerDBIDPairList(int size) {
super();
- if (size > 0) {
+ if(size > 0) {
size = 21;
}
- this.data = new DoubleDistanceIntegerDBIDPair[size];
+ this.data = new DoubleIntegerDBIDPair[size];
}
@Override
- public DoubleDistanceIntegerDBIDListIter iter() {
+ public Itr iter() {
return new Itr();
}
@Override
public boolean contains(DBIDRef o) {
final int q = o.internalGetIndex();
- for (int i = 0; i < size; i++) {
- if (q == data[i].internalGetIndex()) {
+ for(int i = 0; i < size; i++) {
+ if(q == data[i].internalGetIndex()) {
return true;
}
}
@@ -95,7 +95,7 @@ public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistan
}
@Override
- public DoubleDistanceIntegerDBIDPair get(int index) {
+ public DoubleIntegerDBIDPair get(int index) {
return data[index];
}
@@ -104,32 +104,27 @@ public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistan
*
* @param pair entry
*/
- protected void addInternal(DoubleDistanceIntegerDBIDPair pair) {
- if (size == data.length) {
- DoubleDistanceIntegerDBIDPair[] old = data;
- data = new DoubleDistanceIntegerDBIDPair[(data.length << 1) + 1];
+ protected void addInternal(DoubleIntegerDBIDPair pair) {
+ if(size == data.length) {
+ DoubleIntegerDBIDPair[] old = data;
+ data = new DoubleIntegerDBIDPair[(data.length << 1) + 1];
System.arraycopy(old, 0, data, 0, old.length);
}
data[size++] = pair;
}
@Override
- @Deprecated
- public void add(DoubleDistance dist, DBIDRef id) {
- add(dist.doubleValue(), id);
- }
-
- @Override
public void add(double dist, DBIDRef id) {
- addInternal(new DoubleDistanceIntegerDBIDPair(dist, id.internalGetIndex()));
+ addInternal(new DoubleIntegerDBIDPair(dist, id.internalGetIndex()));
}
@Override
- public void add(DoubleDistanceDBIDPair pair) {
- if (pair instanceof DoubleDistanceIntegerDBIDPair) {
- addInternal((DoubleDistanceIntegerDBIDPair) pair);
- } else {
- addInternal(new DoubleDistanceIntegerDBIDPair(pair.doubleDistance(), pair.internalGetIndex()));
+ public void add(DoubleDBIDPair pair) {
+ if(pair instanceof DoubleIntegerDBIDPair) {
+ addInternal((DoubleIntegerDBIDPair) pair);
+ }
+ else {
+ addInternal(new DoubleIntegerDBIDPair(pair.doubleValue(), pair.internalGetIndex()));
}
}
@@ -141,15 +136,15 @@ public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistan
@Override
public void sort() {
- Arrays.sort(data, 0, size, DistanceDBIDResultUtil.distanceComparator());
+ Arrays.sort(data, 0, size);
}
/**
* Reverse the list.
*/
protected void reverse() {
- for (int i = 0, j = size - 1; i < j; i++, j--) {
- DoubleDistanceIntegerDBIDPair tmpd = data[j];
+ for(int i = 0, j = size - 1; i < j; i++, j--) {
+ DoubleIntegerDBIDPair tmpd = data[j];
data[j] = data[i];
data[i] = tmpd;
}
@@ -159,10 +154,10 @@ public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistan
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("kNNList[");
- for (DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) {
- buf.append(iter.doubleDistance()).append(':').append(iter.internalGetIndex());
+ for(DoubleDBIDListIter iter = this.iter(); iter.valid();) {
+ buf.append(iter.doubleValue()).append(':').append(iter.internalGetIndex());
iter.advance();
- if (iter.valid()) {
+ if(iter.valid()) {
buf.append(',');
}
}
@@ -177,58 +172,56 @@ public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistan
*
* @apiviz.exclude
*/
- private class Itr implements DoubleDistanceIntegerDBIDListIter {
- int offset = 0;
+ private class Itr implements DoubleDBIDListIter, IntegerDBIDArrayIter {
+ int pos = 0;
@Override
public boolean valid() {
- return offset < size;
+ return pos < size && pos >= 0;
}
@Override
- public void advance() {
- ++offset;
+ public Itr advance() {
+ ++pos;
+ return this;
}
@Override
public int getOffset() {
- return offset;
+ return pos;
}
@Override
- public void advance(int count) {
- offset += count;
+ public Itr advance(int count) {
+ pos += count;
+ return this;
}
@Override
- public void retract() {
- offset--;
+ public Itr retract() {
+ pos--;
+ return this;
}
@Override
- public void seek(int off) {
- offset = off;
+ public Itr seek(int off) {
+ pos = off;
+ return this;
}
@Override
public int internalGetIndex() {
- return data[offset].internalGetIndex();
- }
-
- @Override
- public double doubleDistance() {
- return data[offset].doubleDistance();
+ return data[pos].internalGetIndex();
}
@Override
- public DoubleDistanceDBIDPair getDistancePair() {
- return data[offset];
+ public double doubleValue() {
+ return data[pos].doubleValue();
}
@Override
- @Deprecated
- public DoubleDistance getDistance() {
- return new DoubleDistance(data[offset].doubleDistance());
+ public DoubleDBIDPair getPair() {
+ return data[pos];
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayDBIDs.java
index 286bedf9..99519ce8 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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/database/ids/integer/IntegerArrayStaticDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayStaticDBIDs.java
index 9e18631b..8e82ba3f 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayStaticDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayStaticDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,7 +30,7 @@ import de.lmu.ifi.dbs.elki.database.ids.ArrayStaticDBIDs;
*
* @author Erich Schubert
*/
-public interface IntegerArrayStaticDBIDs extends ArrayStaticDBIDs, IntegerArrayDBIDs {
+interface IntegerArrayStaticDBIDs extends ArrayStaticDBIDs, IntegerArrayDBIDs {
@Override
IntegerDBIDArrayIter iter();
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBID.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBID.java
index 6b7ec5ac..572ec5d9 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBID.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBID.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,9 +32,9 @@ 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.DBIDVar;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
-import de.lmu.ifi.dbs.elki.persistent.FixedSizeByteBufferSerializer;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
+import de.lmu.ifi.dbs.elki.utilities.io.FixedSizeByteBufferSerializer;
/**
* Database ID object.
@@ -185,23 +185,27 @@ final class IntegerDBID implements DBID, IntegerDBIDRef {
int pos = 0;
@Override
- public void advance() {
+ public Itr advance() {
pos++;
+ return this;
}
@Override
- public void advance(int count) {
+ public Itr advance(int count) {
pos += count;
+ return this;
}
@Override
- public void retract() {
+ public Itr retract() {
pos--;
+ return this;
}
@Override
- public void seek(int off) {
+ public Itr seek(int off) {
pos = off;
+ return this;
}
@Override
@@ -248,7 +252,7 @@ final class IntegerDBID implements DBID, IntegerDBIDRef {
/**
* Constructor. Protected: use static instance!
*/
- protected DynamicSerializer() {
+ public DynamicSerializer() {
super();
}
@@ -277,7 +281,7 @@ final class IntegerDBID implements DBID, IntegerDBIDRef {
/**
* Constructor. Protected: use static instance!
*/
- protected StaticSerializer() {
+ public StaticSerializer() {
super();
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayIter.java
index c604ac71..30255d87 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayIter.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayIter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,6 +29,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
*
* @author Erich Schubert
*/
-public interface IntegerDBIDArrayIter extends IntegerDBIDIter, DBIDArrayIter {
+interface IntegerDBIDArrayIter extends IntegerDBIDIter, DBIDArrayIter {
// Empty
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayMIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayMIter.java
index dcead6bd..750f7644 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayMIter.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayMIter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,6 +29,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayMIter;
*
* @author Erich Schubert
*/
-public interface IntegerDBIDArrayMIter extends IntegerDBIDArrayIter, IntegerDBIDMIter, DBIDArrayMIter {
+interface IntegerDBIDArrayMIter extends IntegerDBIDArrayIter, IntegerDBIDMIter, DBIDArrayMIter {
// Empty
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayQuickSort.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayQuickSort.java
index d6cadf60..03fcb16b 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayQuickSort.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayQuickSort.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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/database/ids/integer/IntegerDBIDIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDIter.java
index 721e6e4e..893649fa 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDIter.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDIter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
*
* @apiviz.landmark
*/
-public interface IntegerDBIDIter extends IntegerDBIDRef, DBIDIter {
+interface IntegerDBIDIter extends IntegerDBIDRef, DBIDIter {
// Empty
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDKNNList.java
index 85182313..d493271e 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDList.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDKNNList.java
@@ -1,10 +1,9 @@
-package de.lmu.ifi.dbs.elki.database.ids.distance;
-
+package de.lmu.ifi.dbs.elki.database.ids.integer;
/*
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,17 +22,18 @@ package de.lmu.ifi.dbs.elki.database.ids.distance;
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.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
/**
- * An object containing Double-DBID-Pairs.
+ * Combination interface for KNNList and IntegerDBIDs.
*
* @author Erich Schubert
*/
-public interface DoubleDistanceDBIDList extends DistanceDBIDList<DoubleDistance> {
+public interface IntegerDBIDKNNList extends KNNList, DoubleDBIDList, IntegerDBIDs {
@Override
- DoubleDistanceDBIDListIter iter();
-
+ DoubleIntegerDBIDListIter iter();
+
@Override
- DoubleDistanceDBIDPair get(int off);
+ public DoubleIntegerDBIDPair get(int index);
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceKNNSubList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDKNNSubList.java
index c2854a54..bd53f7e1 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceKNNSubList.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDKNNSubList.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.database.ids.generic;
+package de.lmu.ifi.dbs.elki.database.ids.integer;
/*
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,19 +25,14 @@ package de.lmu.ifi.dbs.elki.database.ids.generic;
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.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
/**
* Sublist of an existing result to contain only the first k elements.
*
- * TOOD: can be optimized slightly better.
- *
* @author Erich Schubert
*/
-public class DoubleDistanceKNNSubList implements DoubleDistanceKNNList {
+public class IntegerDBIDKNNSubList implements IntegerDBIDKNNList {
/**
* Parameter k.
*/
@@ -51,7 +46,7 @@ public class DoubleDistanceKNNSubList implements DoubleDistanceKNNList {
/**
* Wrapped inner result.
*/
- private final DoubleDistanceKNNList inner;
+ private final IntegerDBIDKNNList inner;
/**
* Constructor.
@@ -59,21 +54,23 @@ public class DoubleDistanceKNNSubList implements DoubleDistanceKNNList {
* @param inner Inner instance
* @param k k value
*/
- public DoubleDistanceKNNSubList(DoubleDistanceKNNList inner, int k) {
+ public IntegerDBIDKNNSubList(IntegerDBIDKNNList inner, int k) {
this.inner = inner;
this.k = k;
// Compute list size
- {
- DoubleDistanceDBIDPair dist = inner.get(k);
+ if(k < inner.getK()) {
+ DoubleIntegerDBIDListIter iter = inner.iter();
+ final double kdist = iter.seek(k - 1).doubleValue();
+ // Add all values tied:
int i = k;
- while (i + 1 < inner.size()) {
- if (dist.compareByDistance(inner.get(i + 1)) < 0) {
- break;
- }
+ for(iter.advance(); iter.valid() && iter.doubleValue() <= kdist; iter.advance()) {
i++;
}
size = i;
}
+ else {
+ size = inner.size();
+ }
}
@Override
@@ -82,31 +79,25 @@ public class DoubleDistanceKNNSubList implements DoubleDistanceKNNList {
}
@Override
- public DoubleDistanceDBIDPair get(int index) {
+ public DoubleIntegerDBIDPair get(int index) {
assert (index < size) : "Access beyond design size of list.";
return inner.get(index);
}
@Override
- @Deprecated
- public DoubleDistance getKNNDistance() {
- return inner.get(k).getDistance();
- }
-
- @Override
- public double doubleKNNDistance() {
- return inner.get(k).doubleDistance();
+ public double getKNNDistance() {
+ return inner.get(k).doubleValue();
}
@Override
- public DoubleDistanceDBIDListIter iter() {
+ public DoubleIntegerDBIDListIter iter() {
return new Itr();
}
@Override
public boolean contains(DBIDRef o) {
- for (DBIDIter iter = iter(); iter.valid(); iter.advance()) {
- if (DBIDUtil.equal(iter, o)) {
+ for(DBIDIter iter = iter(); iter.valid(); iter.advance()) {
+ if(DBIDUtil.equal(iter, o)) {
return true;
}
}
@@ -130,7 +121,7 @@ public class DoubleDistanceKNNSubList implements DoubleDistanceKNNList {
*
* @apiviz.exclude
*/
- private class Itr implements DoubleDistanceDBIDListIter {
+ private class Itr implements DoubleIntegerDBIDListIter {
/**
* Current position.
*/
@@ -138,27 +129,22 @@ public class DoubleDistanceKNNSubList implements DoubleDistanceKNNList {
@Override
public boolean valid() {
- return pos < size;
+ return pos < size && pos >= 0;
}
@Override
- public void advance() {
+ public Itr advance() {
pos++;
+ return this;
}
@Override
- @Deprecated
- public DoubleDistance getDistance() {
- return inner.get(pos).getDistance();
- }
-
- @Override
- public double doubleDistance() {
- return inner.get(pos).doubleDistance();
+ public double doubleValue() {
+ return inner.get(pos).doubleValue();
}
@Override
- public DoubleDistanceDBIDPair getDistancePair() {
+ public DoubleDBIDPair getPair() {
return inner.get(pos);
}
@@ -173,18 +159,21 @@ public class DoubleDistanceKNNSubList implements DoubleDistanceKNNList {
}
@Override
- public void advance(int count) {
+ public Itr advance(int count) {
pos += count;
+ return this;
}
@Override
- public void retract() {
+ public Itr retract() {
--pos;
+ return this;
}
@Override
- public void seek(int off) {
+ public Itr seek(int off) {
pos = off;
+ return this;
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDMIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDMIter.java
index c0291d5b..067a257b 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDMIter.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDMIter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,6 +29,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDMIter;
*
* @author Erich Schubert
*/
-public interface IntegerDBIDMIter extends DBIDMIter, IntegerDBIDIter {
+interface IntegerDBIDMIter extends DBIDMIter, IntegerDBIDIter {
// Empty.
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDPair.java
index 12e9b685..9c691bc9 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDPair.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDPair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,16 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+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;
/**
* DBID pair using two ints for storage.
*
* @author Erich Schubert
*/
-public class IntegerDBIDPair implements DBIDPair {
+class IntegerDBIDPair implements DBIDPair, IntegerDBIDs {
/**
* First value in pair
*/
@@ -47,7 +49,7 @@ public class IntegerDBIDPair implements DBIDPair {
* @param first first parameter
* @param second second parameter
*/
- public IntegerDBIDPair(int first, int second) {
+ protected IntegerDBIDPair(int first, int second) {
this.first = first;
this.second = second;
}
@@ -60,36 +62,18 @@ public class IntegerDBIDPair implements DBIDPair {
return "Pair(" + first + ", " + second + ")";
}
- /**
- * Getter for first
- *
- * @return first element in pair
- */
+ @Deprecated
@Override
public final IntegerDBID getFirst() {
return new IntegerDBID(first);
}
- /**
- * Getter for second element in pair
- *
- * @return second element in pair
- */
+ @Deprecated
@Override
public final IntegerDBID getSecond() {
return new IntegerDBID(second);
}
- /**
- * Simple equals statement.
- *
- * This Pair equals another Object if they are identical or if the other
- * Object is also a Pair and the {@link #first} and {@link #second} element of
- * this Pair equal the {@link #first} and {@link #second} element,
- * respectively, of the other Pair.
- *
- * @param obj Object to compare to
- */
@Override
public boolean equals(Object obj) {
if(this == obj) {
@@ -118,4 +102,68 @@ public class IntegerDBIDPair implements DBIDPair {
result = prime * result + second;
return (int) result;
}
+
+ @Override
+ public int size() {
+ return 2;
+ }
+
+ @Override
+ public boolean contains(DBIDRef o) {
+ final int i = o.internalGetIndex();
+ return (i == first) || (i == second);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
+ public IntegerDBIDIter iter() {
+ return new Itr(first, second);
+ }
+
+ /**
+ * Iterator.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ private static class Itr implements IntegerDBIDIter {
+ /**
+ * State
+ */
+ int first, second, pos;
+
+ /**
+ * Constructor.
+ *
+ * @param first First ID
+ * @param second Second ID
+ */
+ public Itr(int first, int second) {
+ super();
+ this.first = first;
+ this.second = second;
+ this.pos = 0;
+ }
+
+ @Override
+ public boolean valid() {
+ return pos < 2;
+ }
+
+ @Override
+ public DBIDIter advance() {
+ ++pos;
+ return this;
+ }
+
+ @Override
+ public int internalGetIndex() {
+ return (pos == 0) ? first : second;
+ }
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRange.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRange.java
index e418db5f..4b8aed26 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRange.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRange.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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
@@ -184,23 +184,27 @@ final class IntegerDBIDRange implements IntegerDBIDs, DBIDRange, SetDBIDs {
}
@Override
- public void advance() {
+ public Itr advance() {
++pos;
+ return this;
}
@Override
- public void advance(int count) {
+ public Itr advance(int count) {
pos += count;
+ return this;
}
@Override
- public void retract() {
+ public Itr retract() {
--pos;
+ return this;
}
@Override
- public void seek(int off) {
+ public Itr seek(int off) {
pos = off;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRef.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRef.java
index 0e1e82a9..ddd56209 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRef.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRef.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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/database/ids/integer/IntegerDBIDVar.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDVar.java
index 9120c0d7..c5dfb9b6 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDVar.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDVar.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
+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.DBIDVar;
@@ -49,7 +50,7 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs {
* Constructor.
*/
protected IntegerDBIDVar() {
- this.id = -1;
+ this.id = Integer.MIN_VALUE;
}
/**
@@ -81,8 +82,21 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs {
}
@Override
+ public void setFirst(DBIDPair pair) {
+ assert pair instanceof IntegerDBIDPair;
+ id = ((IntegerDBIDPair) pair).first;
+ }
+
+ @Override
+ public void setSecond(DBIDPair pair) {
+ assert pair instanceof IntegerDBIDPair;
+ id = ((IntegerDBIDPair) pair).second;
+ }
+
+ @Override
+ @Deprecated
public DBID get(int i) {
- if (i != 0) {
+ if(i != 0) {
throw new ArrayIndexOutOfBoundsException();
}
return new IntegerDBID(i);
@@ -90,12 +104,22 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs {
@Override
public int size() {
- return 1;
+ return id < 0 ? 0 : 1;
}
@Override
public boolean isEmpty() {
- return false;
+ return id < 0;
+ }
+
+ @Override
+ public void unset() {
+ id = Integer.MIN_VALUE;
+ }
+
+ @Override
+ public boolean isSet() {
+ return id > 0;
}
@Override
@@ -111,9 +135,10 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs {
@Override
public void assignVar(int i, DBIDVar var) {
- if (var instanceof IntegerDBIDVar) {
+ if(var instanceof IntegerDBIDVar) {
((IntegerDBIDVar) var).internalSetIndex(i);
- } else {
+ }
+ else {
// Much less efficient:
var.set(get(i));
}
@@ -121,9 +146,10 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs {
@Override
public ArrayDBIDs slice(int begin, int end) {
- if (begin == 0 && end == 1) {
+ if(begin == 0 && end == 1) {
return this;
- } else {
+ }
+ else {
return DBIDUtil.EMPTYDBIDS;
}
}
@@ -150,56 +176,60 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs {
* Iterator position: We use an integer so we can support retract().
*/
int pos = 0;
-
+
@Override
- public void advance() {
+ public Itr advance() {
pos++;
+ return this;
}
-
+
@Override
- public void advance(int count) {
+ public Itr advance(int count) {
pos += count;
+ return this;
}
-
+
@Override
- public void retract() {
+ public Itr retract() {
pos--;
+ return this;
}
-
+
@Override
- public void seek(int off) {
+ public Itr seek(int off) {
pos = off;
+ return this;
}
-
+
@Override
public int getOffset() {
return pos;
}
-
+
@Override
public int internalGetIndex() {
return IntegerDBIDVar.this.id;
}
-
+
@Override
public boolean valid() {
return (pos == 0);
}
-
+
@Override
public int hashCode() {
// Override, because we also are overriding equals.
return super.hashCode();
}
-
+
@Override
public boolean equals(Object other) {
- if (other instanceof DBID) {
+ if(other instanceof DBID) {
LoggingUtil.warning("Programming error detected: DBIDItr.equals(DBID). Use sameDBID()!", new Throwable());
}
return super.equals(other);
}
-
+
@Override
public String toString() {
return Integer.toString(internalGetIndex());
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDs.java
index 14faa72a..1abaa423 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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/database/ids/integer/ReusingDBIDFactory.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ReusingDBIDFactory.java
index ebb36f22..da730f4f 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ReusingDBIDFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ReusingDBIDFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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/database/ids/integer/SimpleDBIDFactory.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/SimpleDBIDFactory.java
index c3abd43a..33ddd240 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/SimpleDBIDFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/SimpleDBIDFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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
@@ -48,7 +48,7 @@ public class SimpleDBIDFactory extends AbstractIntegerDBIDFactory {
* The starting point for static DBID range allocations.
*/
int rangestart = 0;
-
+
/**
* Constructor.
*/
@@ -81,6 +81,16 @@ public class SimpleDBIDFactory extends AbstractIntegerDBIDFactory {
}
@Override
+ public DBIDRange generateStaticDBIDRange(int begin, int size) {
+ if(begin + size >= Integer.MAX_VALUE) {
+ throw new AbortException("DBID range allocation error - too many objects allocated!");
+ }
+ DBIDRange alloc = new IntegerDBIDRange(begin, size);
+ rangestart = Math.max(rangestart, begin + size);
+ return alloc;
+ }
+
+ @Override
public void deallocateDBIDRange(DBIDRange range) {
// ignore.
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/TrivialDBIDFactory.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/TrivialDBIDFactory.java
index 577c29ac..cc5f6add 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/TrivialDBIDFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/TrivialDBIDFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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
@@ -55,7 +55,7 @@ final public class TrivialDBIDFactory extends AbstractIntegerDBIDFactory {
@Override
final public DBID generateSingleDBID() {
final int id = next.getAndIncrement();
- if (id == Integer.MAX_VALUE) {
+ if(id == Integer.MAX_VALUE) {
throw new AbortException("DBID allocation error - too many objects allocated!");
}
DBID ret = new IntegerDBID(id);
@@ -70,7 +70,7 @@ final public class TrivialDBIDFactory extends AbstractIntegerDBIDFactory {
@Override
final public DBIDRange generateStaticDBIDRange(int size) {
final int start = next.getAndAdd(size);
- if (start > next.get()) {
+ if(start > next.get()) {
throw new AbortException("DBID range allocation error - too many objects allocated!");
}
DBIDRange alloc = new IntegerDBIDRange(start, size);
@@ -78,6 +78,22 @@ final public class TrivialDBIDFactory extends AbstractIntegerDBIDFactory {
}
@Override
+ public DBIDRange generateStaticDBIDRange(int begin, int size) {
+ final int end = begin + size;
+ if(end > Integer.MAX_VALUE) {
+ throw new AbortException("DBID range allocation error - too many objects allocated!");
+ }
+ DBIDRange alloc = new IntegerDBIDRange(begin, size);
+ int v;
+ while((v = next.get()) < end) {
+ if(next.compareAndSet(v, end)) {
+ break;
+ }
+ }
+ return alloc;
+ }
+
+ @Override
public void deallocateDBIDRange(DBIDRange range) {
// ignore.
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveHashSetModifiableDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveHashSetModifiableDBIDs.java
index 35276606..61007e10 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveHashSetModifiableDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveHashSetModifiableDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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
@@ -184,8 +184,9 @@ class TroveHashSetModifiableDBIDs implements HashSetModifiableDBIDs, IntegerDBID
}
@Override
- public void advance() {
+ public IntegerDBIDMIter advance() {
it.advance();
+ return this;
}
@Override
@@ -237,8 +238,9 @@ class TroveHashSetModifiableDBIDs implements HashSetModifiableDBIDs, IntegerDBID
}
@Override
- public void advance() {
+ public Iter advance() {
this._index = nextIndex();
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerArrayDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerArrayDBIDs.java
index d1c37ab9..1e68cb5a 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerArrayDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerArrayDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,6 +24,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDMIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
@@ -65,7 +66,7 @@ public class UnmodifiableIntegerArrayDBIDs implements IntegerArrayStaticDBIDs {
@Override
public IntegerDBIDArrayIter iter() {
IntegerDBIDArrayIter it = inner.iter();
- if (it instanceof DBIDMIter) {
+ if(it instanceof DBIDMIter) {
return new UnmodifiableDBIDIter(it);
}
return it;
@@ -128,23 +129,27 @@ public class UnmodifiableIntegerArrayDBIDs implements IntegerArrayStaticDBIDs {
}
@Override
- public void advance() {
+ public DBIDArrayIter advance() {
it.advance();
+ return this;
}
@Override
- public void advance(int count) {
+ public DBIDArrayIter advance(int count) {
it.advance(count);
+ return this;
}
@Override
- public void retract() {
+ public DBIDArrayIter retract() {
it.retract();
+ return this;
}
@Override
- public void seek(int off) {
+ public DBIDArrayIter seek(int off) {
it.seek(off);
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerDBIDs.java
index a3f03bd9..6ac91c5e 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerDBIDs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
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,6 +23,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDMIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.ids.StaticDBIDs;
@@ -107,8 +108,9 @@ public class UnmodifiableIntegerDBIDs implements StaticDBIDs, IntegerDBIDs {
}
@Override
- public void advance() {
+ public DBIDIter advance() {
it.advance();
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/package-info.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/package-info.java
index 74a39fb9..661a9cf4 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/package-info.java
@@ -10,7 +10,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/database/ids/package-info.java b/src/de/lmu/ifi/dbs/elki/database/ids/package-info.java
index eb0a6733..b4c8fd1f 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/package-info.java
@@ -57,8 +57,6 @@
* </ul>
*
* <h2>Generic utility classes:</h2>
- * <p>{@link de.lmu.ifi.dbs.elki.database.ids.generic.MergedDBIDs MergedDBIDs}
- * allows virtual concatenation of multiple DBIDs objects.</p>
*
* <p>{@link de.lmu.ifi.dbs.elki.database.ids.generic.MaskedDBIDs MaskedDBIDs}
* allows masking an ArrayDBIDs with a BitSet.</p>
@@ -69,21 +67,17 @@
* @apiviz.exclude de.lmu.ifi.dbs.elki.database.ids.EmptyDBIDs.EmptyDBIDIterator
* @apiviz.exclude de.lmu.ifi.dbs.elki.database.*Database
* @apiviz.exclude de.lmu.ifi.dbs.elki.data.Cluster
- * @apiviz.exclude de.lmu.ifi.dbs.elki.utilities.*
* @apiviz.exclude de.lmu.ifi.dbs.elki.datasource.filter.*
* @apiviz.exclude de.lmu.ifi.dbs.elki.database.query.*
- * @apiviz.exclude de.lmu.ifi.dbs.elki.distance.*
- * @apiviz.exclude de.lmu.ifi.dbs.elki.index.*
- * @apiviz.exclude de.lmu.ifi.dbs.elki.result.*
- * @apiviz.exclude de.lmu.ifi.dbs.elki.persistent.*
- * @apiviz.exclude de.lmu.ifi.dbs.elki.algorithm.*
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.(algorithm|evaluation|parallel|distance|index|result|persistent|utilities).*
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.database.relation.*
* @apiviz.exclude java.*
*/
/*
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/database/package-info.java b/src/de/lmu/ifi/dbs/elki/database/package-info.java
index 0b5d16ea..99d3a941 100644
--- a/src/de/lmu/ifi/dbs/elki/database/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/database/package-info.java
@@ -9,7 +9,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/database/query/DatabaseQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/DatabaseQuery.java
index caba81e3..f88261a8 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/DatabaseQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/DatabaseQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query;
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/database/query/DistanceSimilarityQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/DistanceSimilarityQuery.java
index 8906e07c..f0bc7e9a 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/DistanceSimilarityQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/DistanceSimilarityQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query;
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,17 +25,15 @@ package de.lmu.ifi.dbs.elki.database.query;
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.distance.distancevalue.Distance;
/**
- * Interface that is a combination of distance and a similarity function.
- * For combined implementations of both.
+ * Interface that is a combination of distance and a similarity function. For
+ * combined implementations of both.
*
* @author Erich Schubert
- *
+ *
* @param <O> Object type
- * @param <D> Distance type
*/
-public interface DistanceSimilarityQuery<O, D extends Distance<D>> extends DistanceQuery<O, D>, SimilarityQuery<O, D> {
+public interface DistanceSimilarityQuery<O> extends DistanceQuery<O>, SimilarityQuery<O> {
// Empty
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/LinearScanQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/LinearScanQuery.java
index 6cb35025..e55e7d19 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/LinearScanQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/LinearScanQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query;
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/database/query/distance/AbstractDatabaseDistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDatabaseDistanceQuery.java
index f530b72a..2edd9d0b 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDatabaseDistanceQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDatabaseDistanceQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance;
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,10 +23,8 @@ package de.lmu.ifi.dbs.elki.database.query.distance;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-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.distancevalue.Distance;
/**
* Run a database query in a database context.
@@ -34,9 +32,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @author Erich Schubert
*
* @param <O> Database object type.
- * @param <D> Distance result type.
*/
-public abstract class AbstractDatabaseDistanceQuery<O, D extends Distance<D>> extends AbstractDistanceQuery<O, D> {
+public abstract class AbstractDatabaseDistanceQuery<O> extends AbstractDistanceQuery<O> {
/**
* Constructor.
*
@@ -47,25 +44,25 @@ public abstract class AbstractDatabaseDistanceQuery<O, D extends Distance<D>> ex
}
@Override
- public D distance(O o1, DBIDRef id2) {
- if(o1 instanceof DBID) {
- return distance((DBID) o1, id2);
+ public double distance(O o1, DBIDRef id2) {
+ if(o1 instanceof DBIDRef) {
+ return distance((DBIDRef) o1, id2);
}
throw new UnsupportedOperationException("This distance function is only defined for known DBIDs.");
}
@Override
- public D distance(DBIDRef id1, O o2) {
- if(o2 instanceof DBID) {
- return distance(id1, (DBID) o2);
+ public double distance(DBIDRef id1, O o2) {
+ if(o2 instanceof DBIDRef) {
+ return distance(id1, (DBIDRef) o2);
}
throw new UnsupportedOperationException("This distance function is only defined for known DBIDs.");
}
@Override
- public D distance(O o1, O o2) {
- if(o1 instanceof DBID && o2 instanceof DBID) {
- return distance((DBID) o1, (DBID) o2);
+ public double distance(O o1, O o2) {
+ if(o1 instanceof DBIDRef && o2 instanceof DBIDRef) {
+ return distance((DBIDRef) o1, (DBIDRef) o2);
}
throw new UnsupportedOperationException("This distance function is only defined for known DBIDs.");
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDistanceQuery.java
index 933bd0d3..8f35eb58 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDistanceQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDistanceQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance;
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,9 +24,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.query.AbstractDataBasedQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* A distance query serves as adapter layer for database and primitive
@@ -35,16 +33,21 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @author Erich Schubert
*
* @param O Input object type
- * @param D Distance result type
*/
-public abstract class AbstractDistanceQuery<O, D extends Distance<D>> extends AbstractDataBasedQuery<O> implements DistanceQuery<O, D> {
+public abstract class AbstractDistanceQuery<O> implements DistanceQuery<O> {
+ /**
+ * The data to use for this query
+ */
+ final protected Relation<? extends O> relation;
+
/**
* Constructor.
*
* @param relation Relation to use.
*/
public AbstractDistanceQuery(Relation<? extends O> relation) {
- super(relation);
+ super();
+ this.relation = relation;
}
/**
@@ -55,7 +58,7 @@ public abstract class AbstractDistanceQuery<O, D extends Distance<D>> extends Ab
* @return the distance between the two objects specified by their object ids
*/
@Override
- public abstract D distance(DBIDRef id1, DBIDRef id2);
+ public abstract double distance(DBIDRef id1, DBIDRef id2);
/**
* Returns the distance between the two objects specified by their object ids.
@@ -65,7 +68,7 @@ public abstract class AbstractDistanceQuery<O, D extends Distance<D>> extends Ab
* @return the distance between the two objects specified by their object ids
*/
@Override
- public abstract D distance(O o1, DBIDRef id2);
+ public abstract double distance(O o1, DBIDRef id2);
/**
* Returns the distance between the two objects specified by their object ids.
@@ -75,7 +78,7 @@ public abstract class AbstractDistanceQuery<O, D extends Distance<D>> extends Ab
* @return the distance between the two objects specified by their object ids
*/
@Override
- public abstract D distance(DBIDRef id1, O o2);
+ public abstract double distance(DBIDRef id1, O o2);
/**
* Returns the distance between the two objects specified by their object ids.
@@ -85,40 +88,10 @@ public abstract class AbstractDistanceQuery<O, D extends Distance<D>> extends Ab
* @return the distance between the two objects specified by their object ids
*/
@Override
- public abstract D distance(O o1, O o2);
-
- @Override
- public D getDistanceFactory() {
- return getDistanceFunction().getDistanceFactory();
- }
+ public abstract double distance(O o1, O o2);
- /**
- * Provides an infinite distance.
- *
- * @return an infinite distance
- */
- @Override
- public D infiniteDistance() {
- return getDistanceFunction().getDistanceFactory().infiniteDistance();
- }
-
- /**
- * Provides a null distance.
- *
- * @return a null distance
- */
- @Override
- public D nullDistance() {
- return getDistanceFunction().getDistanceFactory().nullDistance();
- }
-
- /**
- * Provides an undefined distance.
- *
- * @return an undefined distance
- */
@Override
- public D undefinedDistance() {
- return getDistanceFunction().getDistanceFactory().undefinedDistance();
+ public Relation<? extends O> getRelation() {
+ return relation;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDDistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDDistanceQuery.java
index e619bc57..b9966b53 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDDistanceQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDDistanceQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance;
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.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.DBIDDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Run a distance query based on DBIDs
@@ -36,14 +35,12 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
*
* @apiviz.landmark
* @apiviz.uses DBIDDistanceFunction
- *
- * @param <D> Distance result type.
*/
-public class DBIDDistanceQuery<D extends Distance<D>> extends AbstractDatabaseDistanceQuery<DBID, D> {
+public class DBIDDistanceQuery extends AbstractDatabaseDistanceQuery<DBID> {
/**
* The distance function we use.
*/
- final protected DBIDDistanceFunction<D> distanceFunction;
+ final protected DBIDDistanceFunction distanceFunction;
/**
* Constructor.
@@ -51,13 +48,13 @@ public class DBIDDistanceQuery<D extends Distance<D>> extends AbstractDatabaseDi
* @param relation Database to use.
* @param distanceFunction Our distance function
*/
- public DBIDDistanceQuery(Relation<DBID> relation, DBIDDistanceFunction<D> distanceFunction) {
+ public DBIDDistanceQuery(Relation<DBID> relation, DBIDDistanceFunction distanceFunction) {
super(relation);
this.distanceFunction = distanceFunction;
}
@Override
- public D distance(DBIDRef id1, DBIDRef id2) {
+ public double distance(DBIDRef id1, DBIDRef id2) {
if(id1 == null) {
throw new UnsupportedOperationException("This distance function can only be used for objects stored in the database.");
}
@@ -68,7 +65,7 @@ public class DBIDDistanceQuery<D extends Distance<D>> extends AbstractDatabaseDi
}
@Override
- public DBIDDistanceFunction<D> getDistanceFunction() {
+ public DBIDDistanceFunction getDistanceFunction() {
return distanceFunction;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDRangeDistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDRangeDistanceQuery.java
new file mode 100644
index 00000000..d5457dd5
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDRangeDistanceQuery.java
@@ -0,0 +1,74 @@
+package de.lmu.ifi.dbs.elki.database.query.distance;
+
+/*
+ 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.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRange;
+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.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DBIDDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DBIDRangeDistanceFunction;
+
+/**
+ * Run a distance query based on DBIDRanges
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.landmark
+ * @apiviz.uses DBIDRangeDistanceFunction
+ */
+public class DBIDRangeDistanceQuery extends DBIDDistanceQuery {
+ /**
+ * The distance function we use.
+ */
+ final protected DBIDRangeDistanceFunction distanceFunction;
+
+ /**
+ * The DBID range we are accessing.
+ */
+ final protected DBIDRange range;
+
+ /**
+ * Constructor.
+ *
+ * @param relation Database to use.
+ * @param distanceFunction Our distance function
+ */
+ public DBIDRangeDistanceQuery(Relation<DBID> relation, DBIDRangeDistanceFunction distanceFunction) {
+ super(relation, distanceFunction);
+ this.range = DBIDUtil.assertRange(relation.getDBIDs());
+ this.distanceFunction = distanceFunction;
+ }
+
+ @Override
+ public double distance(DBIDRef id1, DBIDRef id2) {
+ return distanceFunction.distance(range.getOffset(id1), range.getOffset(id2));
+ }
+
+ @Override
+ public DBIDDistanceFunction getDistanceFunction() {
+ return distanceFunction;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/DistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/DistanceQuery.java
index 12e76ace..07bd6c53 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/distance/DistanceQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/DistanceQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance;
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,20 +27,18 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
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.Distance;
/**
- * A distance query serves as adapter layer for database and primitive distances.
+ * A distance query serves as adapter layer for database and primitive
+ * distances.
*
* @author Erich Schubert
*
* @apiviz.landmark
- * @apiviz.has Distance
*
* @param O Input object type
- * @param D Distance result type
*/
-public interface DistanceQuery<O, D extends Distance<?>> extends DatabaseQuery {
+public interface DistanceQuery<O> extends DatabaseQuery {
/**
* Returns the distance between the two objects specified by their object ids.
*
@@ -48,7 +46,7 @@ public interface DistanceQuery<O, D extends Distance<?>> extends DatabaseQuery {
* @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);
/**
* Returns the distance between the two objects specified by their object ids.
@@ -57,7 +55,7 @@ public interface DistanceQuery<O, D extends Distance<?>> extends DatabaseQuery {
* @param id2 second object id
* @return the distance between the two objects specified by their object ids
*/
- D distance(O o1, DBIDRef id2);
+ double distance(O o1, DBIDRef id2);
/**
* Returns the distance between the two objects specified by their object ids.
@@ -66,7 +64,7 @@ public interface DistanceQuery<O, D extends Distance<?>> extends DatabaseQuery {
* @param o2 second object
* @return the distance between the two objects specified by their object ids
*/
- D distance(DBIDRef id1, O o2);
+ double distance(DBIDRef id1, O o2);
/**
* Returns the distance between the two objects specified by their object ids.
@@ -75,44 +73,16 @@ public interface DistanceQuery<O, D extends Distance<?>> extends DatabaseQuery {
* @param o2 second object
* @return the distance between the two objects specified by their object ids
*/
- D distance(O o1, O o2);
-
- /**
- * Method to get the distance functions factory.
- *
- * @return Factory for distance objects
- */
- D getDistanceFactory();
+ double distance(O o1, O o2);
/**
* Get the inner distance function.
*
* @return Distance function
*/
- DistanceFunction<? super O, D> getDistanceFunction();
-
- /**
- * Provides an infinite distance.
- *
- * @return an infinite distance
- */
- D infiniteDistance();
+ DistanceFunction<? super O> getDistanceFunction();
/**
- * Provides a null distance.
- *
- * @return a null distance
- */
- D nullDistance();
-
- /**
- * Provides an undefined distance.
- *
- * @return an undefined distance
- */
- D undefinedDistance();
-
- /**
* Access the underlying data query.
*
* @return data query in use
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceQuery.java
index ab3046ed..92125ae7 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance;
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.database.query.distance;
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.PrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Run a database query in a database context.
@@ -37,13 +36,12 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @apiviz.uses PrimitiveDistanceFunction
*
* @param <O> Database object type.
- * @param <D> Distance result type.
*/
-public class PrimitiveDistanceQuery<O, D extends Distance<D>> extends AbstractDistanceQuery<O, D> {
+public class PrimitiveDistanceQuery<O> extends AbstractDistanceQuery<O> {
/**
* The distance function we use.
*/
- final protected PrimitiveDistanceFunction<? super O, D> distanceFunction;
+ final protected PrimitiveDistanceFunction<? super O> distanceFunction;
/**
* Constructor.
@@ -51,32 +49,32 @@ public class PrimitiveDistanceQuery<O, D extends Distance<D>> extends AbstractDi
* @param relation Representation to use.
* @param distanceFunction Our distance function
*/
- public PrimitiveDistanceQuery(Relation<? extends O> relation, PrimitiveDistanceFunction<? super O, D> distanceFunction) {
+ public PrimitiveDistanceQuery(Relation<? extends O> relation, PrimitiveDistanceFunction<? super O> distanceFunction) {
super(relation);
this.distanceFunction = distanceFunction;
}
@Override
- public D distance(DBIDRef id1, DBIDRef id2) {
+ public double distance(DBIDRef id1, DBIDRef id2) {
O o1 = relation.get(id1);
O o2 = relation.get(id2);
return distance(o1, o2);
}
@Override
- public D distance(O o1, DBIDRef id2) {
+ public double distance(O o1, DBIDRef id2) {
O o2 = relation.get(id2);
return distance(o1, o2);
}
@Override
- public D distance(DBIDRef id1, O o2) {
+ public double distance(DBIDRef id1, O o2) {
O o1 = relation.get(id1);
return distance(o1, o2);
}
@Override
- public D distance(O o1, O o2) {
+ public double distance(O o1, O o2) {
if(o1 == null) {
throw new UnsupportedOperationException("This distance function can only be used for object instances.");
}
@@ -87,7 +85,7 @@ public class PrimitiveDistanceQuery<O, D extends Distance<D>> extends AbstractDi
}
@Override
- public PrimitiveDistanceFunction<? super O, D> getDistanceFunction() {
+ public PrimitiveDistanceFunction<? super O> getDistanceFunction() {
return distanceFunction;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceSimilarityQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceSimilarityQuery.java
index 52f79f06..b90abc23 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceSimilarityQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceSimilarityQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance;
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.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.query.DistanceSimilarityQuery;
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.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFunction;
/**
@@ -38,14 +37,13 @@ import de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFuncti
* @apiviz.uses PrimitiveSimilarityFunction
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class PrimitiveDistanceSimilarityQuery<O, D extends Distance<D>> extends PrimitiveDistanceQuery<O, D> implements DistanceSimilarityQuery<O, D> {
+public class PrimitiveDistanceSimilarityQuery<O> extends PrimitiveDistanceQuery<O> implements DistanceSimilarityQuery<O> {
/**
* Typed reference to the similarity function (usually the same as the
* distance function!)
*/
- private PrimitiveSimilarityFunction<? super O, D> similarityFunction;
+ private PrimitiveSimilarityFunction<? super O> similarityFunction;
/**
* Constructor.
@@ -55,37 +53,37 @@ public class PrimitiveDistanceSimilarityQuery<O, D extends Distance<D>> extends
* @param similarityFunction similarity function (usually the same as the
* distance function!)
*/
- public PrimitiveDistanceSimilarityQuery(Relation<? extends O> relation, PrimitiveDistanceFunction<? super O, D> distanceFunction, PrimitiveSimilarityFunction<? super O, D> similarityFunction) {
+ public PrimitiveDistanceSimilarityQuery(Relation<? extends O> relation, PrimitiveDistanceFunction<? super O> distanceFunction, PrimitiveSimilarityFunction<? super O> similarityFunction) {
super(relation, distanceFunction);
this.similarityFunction = similarityFunction;
}
@Override
- public D similarity(DBIDRef id1, DBIDRef id2) {
+ public double similarity(DBIDRef id1, DBIDRef id2) {
O o1 = relation.get(id1);
O o2 = relation.get(id2);
return similarity(o1, o2);
}
@Override
- public D similarity(O o1, DBIDRef id2) {
+ public double similarity(O o1, DBIDRef id2) {
O o2 = relation.get(id2);
return similarity(o1, o2);
}
@Override
- public D similarity(DBIDRef id1, O o2) {
+ public double similarity(DBIDRef id1, O o2) {
O o1 = relation.get(id1);
return similarity(o1, o2);
}
@Override
- public D similarity(O o1, O o2) {
+ public double similarity(O o1, O o2) {
return this.similarityFunction.similarity(o1, o2);
}
@Override
- public PrimitiveSimilarityFunction<? super O, D> getSimilarityFunction() {
+ public PrimitiveSimilarityFunction<? super O> getSimilarityFunction() {
return similarityFunction;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialDistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialDistanceQuery.java
index 14839dd7..1340130e 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialDistanceQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialDistanceQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance;
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.database.query.distance;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Query interface for spatial distance queries.
@@ -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 SpatialDistanceQuery<V extends SpatialComparable, D extends Distance<D>> extends DistanceQuery<V, D> {
+public interface SpatialDistanceQuery<V extends SpatialComparable> extends DistanceQuery<V> {
/**
* Computes the minimum distance between the given MBR and the FeatureVector
* object according to this distance function.
@@ -46,7 +44,7 @@ public interface SpatialDistanceQuery<V extends SpatialComparable, D extends Dis
* @return the minimum distance between the given MBR and the FeatureVector
* object according to this distance function
*/
- D minDist(SpatialComparable mbr, V v);
+ double minDist(SpatialComparable mbr, V v);
/**
* Computes the minimum distance between the given MBR and the FeatureVector
@@ -57,7 +55,7 @@ public interface SpatialDistanceQuery<V extends SpatialComparable, D extends Dis
* @return the minimum distance between the given MBR and the FeatureVector
* object according to this distance function
*/
- D minDist(SpatialComparable mbr, DBID id);
+ double minDist(SpatialComparable mbr, DBID id);
/**
* Get the inner distance function.
@@ -65,5 +63,5 @@ public interface SpatialDistanceQuery<V extends SpatialComparable, D extends Dis
* @return Distance function
*/
@Override
- SpatialPrimitiveDistanceFunction<? super V, D> getDistanceFunction();
+ SpatialPrimitiveDistanceFunction<? super V> getDistanceFunction();
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialPrimitiveDistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialPrimitiveDistanceQuery.java
index c5a601bd..4453a2ef 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialPrimitiveDistanceQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialPrimitiveDistanceQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance;
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.spatial.SpatialComparable;
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.distancefunction.SpatialPrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Distance query for spatial distance functions
@@ -36,35 +35,34 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @apiviz.uses SpatialPrimitiveDistanceFunction
*
* @param <V> Vector type to use
- * @param <D> Distance result type
*/
-public class SpatialPrimitiveDistanceQuery<V extends SpatialComparable, D extends Distance<D>> extends PrimitiveDistanceQuery<V, D> implements SpatialDistanceQuery<V, D> {
+public class SpatialPrimitiveDistanceQuery<V extends SpatialComparable> extends PrimitiveDistanceQuery<V> implements SpatialDistanceQuery<V> {
/**
* The distance function we use.
*/
- final protected SpatialPrimitiveDistanceFunction<? super V, D> distanceFunction;
+ final protected SpatialPrimitiveDistanceFunction<? super V> distanceFunction;
/**
* @param relation Representation to use
* @param distanceFunction Distance function to use
*/
- public SpatialPrimitiveDistanceQuery(Relation<? extends V> relation, SpatialPrimitiveDistanceFunction<? super V, D> distanceFunction) {
+ public SpatialPrimitiveDistanceQuery(Relation<? extends V> relation, SpatialPrimitiveDistanceFunction<? super V> distanceFunction) {
super(relation, distanceFunction);
this.distanceFunction = distanceFunction;
}
@Override
- public D minDist(SpatialComparable mbr, V v) {
+ public double minDist(SpatialComparable mbr, V v) {
return distanceFunction.minDist(mbr, v);
}
@Override
- public D minDist(SpatialComparable mbr, DBID id) {
+ public double minDist(SpatialComparable mbr, DBID id) {
return distanceFunction.minDist(mbr, relation.get(id));
}
@Override
- public SpatialPrimitiveDistanceFunction<? super V, D> getDistanceFunction() {
+ public SpatialPrimitiveDistanceFunction<? super V> getDistanceFunction() {
return distanceFunction;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/package-info.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/package-info.java
index 97bc471d..0d949669 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/distance/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/package-info.java
@@ -2,12 +2,13 @@
* <p>Prepared queries for distances.</p>
*
* @apiviz.exclude .*Instance
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.index.distance.*
*/
/*
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/database/query/knn/AbstractDistanceKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/AbstractDistanceKNNQuery.java
index f9f7d018..8d0d574f 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/knn/AbstractDistanceKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/knn/AbstractDistanceKNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.knn;
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,49 +29,54 @@ import java.util.List;
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.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.query.AbstractDataBasedQuery;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.database.relation.Relation;
/**
* Instance for the query on a particular database.
*
* @author Erich Schubert
*/
-public abstract class AbstractDistanceKNNQuery<O, D extends Distance<D>> extends AbstractDataBasedQuery<O> implements KNNQuery<O, D> {
+public abstract class AbstractDistanceKNNQuery<O> implements KNNQuery<O> {
+ /**
+ * The data to use for this query
+ */
+ final protected Relation<? extends O> relation;
+
/**
* Hold the distance function to be used.
*/
- protected DistanceQuery<O, D> distanceQuery;
+ final protected DistanceQuery<O> distanceQuery;
/**
* Constructor.
*
* @param distanceQuery Distance query used
*/
- public AbstractDistanceKNNQuery(DistanceQuery<O, D> distanceQuery) {
- super(distanceQuery.getRelation());
+ public AbstractDistanceKNNQuery(DistanceQuery<O> distanceQuery) {
+ super();
+ this.relation = distanceQuery.getRelation();
this.distanceQuery = distanceQuery;
}
@Override
- public List<? extends KNNList<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ public List<? extends KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
// throw new
// UnsupportedOperationException(ExceptionMessages.UNSUPPORTED_NOT_YET);
// TODO: optimize
- List<KNNList<D>> ret = new ArrayList<>(ids.size());
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ List<KNNList> ret = new ArrayList<>(ids.size());
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
ret.add(getKNNForDBID(iter, k));
}
return ret;
}
@Override
- public KNNList<D> getKNNForDBID(DBIDRef id, int k) {
+ public KNNList getKNNForDBID(DBIDRef id, int k) {
return getKNNForObject(relation.get(id), k);
}
@Override
- abstract public KNNList<D> getKNNForObject(O obj, int k);
+ abstract public KNNList getKNNForObject(O obj, int k);
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/DoubleOptimizedDistanceKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/DoubleOptimizedDistanceKNNQuery.java
deleted file mode 100644
index 4391b745..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/query/knn/DoubleOptimizedDistanceKNNQuery.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.query.knn;
-
-/*
- 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.DBIDFactory;
-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.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery;
-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.distancefunction.PrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-
-/**
- * Optimized linear scan query for {@link PrimitiveDoubleDistanceFunction}s.
- *
- * @author Erich Schubert
- *
- * @apiviz.uses PrimitiveDoubleDistanceFunction
- *
- * @param <O> Object type
- */
-public class DoubleOptimizedDistanceKNNQuery<O> extends AbstractDistanceKNNQuery<O, DoubleDistance> implements LinearScanQuery {
- /**
- * Raw distance function.
- */
- PrimitiveDoubleDistanceFunction<O> rawdist;
-
- /**
- * Constructor.newDoubleDistanceHeap
- *
- * @param distanceQuery Distance function to use
- */
- @SuppressWarnings("unchecked")
- public DoubleOptimizedDistanceKNNQuery(PrimitiveDistanceQuery<O, DoubleDistance> distanceQuery) {
- super(distanceQuery);
- if(!(distanceQuery.getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction)) {
- throw new UnsupportedOperationException("DoubleOptimizedKNNQuery instantiated for non-PrimitiveDoubleDistanceFunction!");
- }
- rawdist = (PrimitiveDoubleDistanceFunction<O>) distanceQuery.getDistanceFunction();
- }
-
- @Override
- public DoubleDistanceKNNList getKNNForDBID(DBIDRef id, int k) {
- final Relation<? extends O> relation = this.relation;
- DoubleDistanceKNNHeap heap = DBIDFactory.FACTORY.newDoubleDistanceHeap(k);
- linearScan(relation, relation.iterDBIDs(), rawdist, relation.get(id), heap);
- return heap.toKNNList();
- }
-
- @Override
- public DoubleDistanceKNNList getKNNForObject(O obj, int k) {
- DoubleDistanceKNNHeap heap = DBIDFactory.FACTORY.newDoubleDistanceHeap(k);
- linearScan(relation, relation.iterDBIDs(), rawdist, obj, heap);
- return heap.toKNNList();
- }
-
- private static <O> void linearScan(Relation<? extends O> relation, DBIDIter iter, PrimitiveDoubleDistanceFunction<? super O> rawdist, final O obj, DoubleDistanceKNNHeap heap) {
- double kdist = Double.POSITIVE_INFINITY;
- while(iter.valid()) {
- final double dist = rawdist.doubleDistance(obj, relation.get(iter));
- if(dist <= kdist) {
- kdist = heap.insert(dist, iter);
- }
- iter.advance();
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/KNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/KNNQuery.java
index c94f3d42..1798ea0b 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/knn/KNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/knn/KNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.knn;
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,8 @@ import java.util.List;
import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
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.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* The interface of an actual instance.
@@ -40,9 +39,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @apiviz.has KNNList oneway - - «create»
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public interface KNNQuery<O, D extends Distance<D>> extends DatabaseQuery {
+public interface KNNQuery<O> extends DatabaseQuery {
/**
* Get the k nearest neighbors for a particular id.
*
@@ -50,7 +48,7 @@ public interface KNNQuery<O, D extends Distance<D>> extends DatabaseQuery {
* @param k Number of neighbors requested
* @return neighbors
*/
- public KNNList<D> getKNNForDBID(DBIDRef id, int k);
+ public KNNList getKNNForDBID(DBIDRef id, int k);
/**
* Bulk query method
@@ -59,7 +57,7 @@ public interface KNNQuery<O, D extends Distance<D>> extends DatabaseQuery {
* @param k Number of neighbors requested
* @return neighbors
*/
- public List<? extends KNNList<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k);
+ public List<? extends KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k);
/**
* Get the k nearest neighbors for a particular id.
@@ -68,5 +66,5 @@ public interface KNNQuery<O, D extends Distance<D>> extends DatabaseQuery {
* @param k Number of neighbors requested
* @return neighbors
*/
- public KNNList<D> getKNNForObject(O obj, int k);
+ public KNNList getKNNForObject(O obj, int k);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanDistanceKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanDistanceKNNQuery.java
index 395db289..06e8ca00 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanDistanceKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanDistanceKNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.knn;
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,12 +30,10 @@ 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.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery;
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.distance.distancevalue.Distance;
/**
* Instance of this query for a particular database.
@@ -45,76 +43,73 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @apiviz.landmark
* @apiviz.has DistanceQuery
*/
-public class LinearScanDistanceKNNQuery<O, D extends Distance<D>> extends AbstractDistanceKNNQuery<O, D> implements LinearScanQuery {
+public class LinearScanDistanceKNNQuery<O> extends AbstractDistanceKNNQuery<O> implements LinearScanQuery {
/**
* Constructor.
*
* @param distanceQuery Distance function to use
*/
- public LinearScanDistanceKNNQuery(DistanceQuery<O, D> distanceQuery) {
+ public LinearScanDistanceKNNQuery(DistanceQuery<O> distanceQuery) {
super(distanceQuery);
}
- /**
- * Linear batch knn for arbitrary distance functions.
- *
- * @param ids DBIDs to process
- * @param heaps Heaps to store the results in
- */
- private void linearScanBatchKNN(ArrayDBIDs ids, List<KNNHeap<D>> heaps) {
- // The distance is computed on database IDs
+ @Override
+ public KNNList getKNNForDBID(DBIDRef id, int k) {
+ KNNHeap heap = DBIDUtil.newHeap(k);
+ double max = Double.POSITIVE_INFINITY;
for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) {
- int index = 0;
- for(DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) {
- KNNHeap<D> heap = heaps.get(index);
- heap.insert(distanceQuery.distance(iter2, iter), iter);
- index++;
+ final double dist = distanceQuery.distance(id, iter);
+ if(dist <= max) {
+ max = heap.insert(dist, iter);
}
}
+ return heap.toKNNList();
}
@Override
- public KNNList<D> getKNNForDBID(DBIDRef id, int k) {
- if(PrimitiveDistanceQuery.class.isInstance(distanceQuery)) {
- // This should have yielded a LinearScanPrimitiveDistanceKNNQuery class!
- return getKNNForObject(relation.get(id), k);
- }
- KNNHeap<D> heap = DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k);
- D max = distanceQuery.getDistanceFactory().infiniteDistance();
+ public KNNList getKNNForObject(O obj, int k) {
+ KNNHeap heap = DBIDUtil.newHeap(k);
+ double max = Double.POSITIVE_INFINITY;
for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) {
- final D dist = distanceQuery.distance(id, iter);
- if(max.compareTo(dist) > 0) {
- heap.insert(dist, iter);
- if(heap.size() >= k) {
- max = heap.getKNNDistance();
- }
+ final double dist = distanceQuery.distance(obj, iter);
+ if(dist <= max) {
+ max = heap.insert(dist, iter);
}
}
return heap.toKNNList();
}
@Override
- public List<KNNList<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ public List<KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
final int size = ids.size();
- final List<KNNHeap<D>> heaps = new ArrayList<>(size);
+ final List<KNNHeap> heaps = new ArrayList<>(size);
for(int i = 0; i < size; i++) {
- heaps.add(DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k));
+ heaps.add(DBIDUtil.newHeap(k));
}
linearScanBatchKNN(ids, heaps);
// Serialize heaps
- List<KNNList<D>> result = new ArrayList<>(size);
- for(KNNHeap<D> heap : heaps) {
+ List<KNNList> result = new ArrayList<>(size);
+ for(KNNHeap heap : heaps) {
result.add(heap.toKNNList());
}
return result;
}
- @Override
- public KNNList<D> getKNNForObject(O obj, int k) {
- KNNHeap<D> heap = DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k);
+ /**
+ * Linear batch knn for arbitrary distance functions.
+ *
+ * @param ids DBIDs to process
+ * @param heaps Heaps to store the results in
+ */
+ private void linearScanBatchKNN(ArrayDBIDs ids, List<KNNHeap> heaps) {
+ // The distance is computed on database IDs
for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) {
- heap.insert(distanceQuery.distance(obj, iter), iter);
+ int index = 0;
+ for(DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) {
+ KNNHeap heap = heaps.get(index);
+ heap.insert(distanceQuery.distance(iter2, iter), iter);
+ index++;
+ }
}
- return heap.toKNNList();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanEuclideanDistanceKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanEuclideanDistanceKNNQuery.java
new file mode 100644
index 00000000..36d739ac
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanEuclideanDistanceKNNQuery.java
@@ -0,0 +1,141 @@
+package de.lmu.ifi.dbs.elki.database.query.knn;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.database.QueryUtil;
+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.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery;
+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.distancefunction.minkowski.EuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
+
+/**
+ * Instance of this query for a particular database.
+ *
+ * This is a subtle optimization: for primitive queries, it is clearly faster to
+ * retrieve the query object from the relation only once!
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.uses PrimitiveDistanceQuery
+ * @apiviz.uses EuclideanDistanceFunction
+ * @apiviz.uses SquaredEuclideanDistanceFunction
+ */
+public class LinearScanEuclideanDistanceKNNQuery<O extends NumberVector> extends LinearScanPrimitiveDistanceKNNQuery<O> implements LinearScanQuery {
+ /**
+ * Squared Euclidean distance function.
+ */
+ private static final SquaredEuclideanDistanceFunction SQUARED = SquaredEuclideanDistanceFunction.STATIC;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceQuery Distance function to use
+ */
+ public LinearScanEuclideanDistanceKNNQuery(PrimitiveDistanceQuery<O> distanceQuery) {
+ super(distanceQuery);
+ assert (EuclideanDistanceFunction.STATIC.equals(distanceQuery.getDistanceFunction()));
+ }
+
+ @Override
+ public KNNList getKNNForDBID(DBIDRef id, int k) {
+ return QueryUtil.applySqrt(linearScan(relation, relation.iterDBIDs(), relation.get(id), DBIDUtil.newHeap(k)).toKNNList());
+ }
+
+ @Override
+ public KNNList getKNNForObject(O obj, int k) {
+ return QueryUtil.applySqrt(linearScan(relation, relation.iterDBIDs(), obj, DBIDUtil.newHeap(k)).toKNNList());
+ }
+
+ /**
+ * Main loop of the linear scan.
+ *
+ * @param relation Data relation
+ * @param iter ID iterator
+ * @param obj Query object
+ * @param heap Output heap
+ * @return Heap
+ */
+ private KNNHeap linearScan(Relation<? extends O> relation, DBIDIter iter, final O obj, KNNHeap heap) {
+ double max = Double.POSITIVE_INFINITY;
+ while(iter.valid()) {
+ final double dist = SQUARED.distance(obj, relation.get(iter));
+ if(dist <= max) {
+ max = heap.insert(dist, iter);
+ }
+ iter.advance();
+ }
+ return heap;
+ }
+
+ @Override
+ public List<KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ final int size = ids.size();
+ final List<KNNHeap> heaps = new ArrayList<>(size);
+ List<O> objs = new ArrayList<>(size);
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ heaps.add(DBIDUtil.newHeap(k));
+ objs.add(relation.get(iter));
+ }
+ linearScanBatchKNN(objs, heaps);
+
+ List<KNNList> result = new ArrayList<>(heaps.size());
+ for(KNNHeap heap : heaps) {
+ result.add(QueryUtil.applySqrt(heap.toKNNList()));
+ }
+ return result;
+ }
+
+ /**
+ * Perform a linear scan batch kNN for primitive distance functions.
+ *
+ * @param objs Objects list
+ * @param heaps Heaps array
+ */
+ @Override
+ protected void linearScanBatchKNN(List<O> objs, List<KNNHeap> heaps) {
+ final int size = objs.size();
+ // Linear scan style KNN.
+ for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) {
+ O candidate = relation.get(iter);
+ for(int index = 0; index < size; index++) {
+ final KNNHeap heap = heaps.get(index);
+ final double dist = SQUARED.distance(objs.get(index), candidate);
+ if(dist <= heap.getKNNDistance()) {
+ heap.insert(dist, iter);
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanPrimitiveDistanceKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanPrimitiveDistanceKNNQuery.java
index 59a6d6e3..20a120e5 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanPrimitiveDistanceKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanPrimitiveDistanceKNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.knn;
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,11 +30,12 @@ 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.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery;
import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceQuery;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
/**
* Instance of this query for a particular database.
@@ -45,69 +46,91 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @author Erich Schubert
*
* @apiviz.uses PrimitiveDistanceQuery
+ * @apiviz.uses PrimitiveDistanceFunction
*/
-public class LinearScanPrimitiveDistanceKNNQuery<O, D extends Distance<D>> extends AbstractDistanceKNNQuery<O, D> implements LinearScanQuery {
+public class LinearScanPrimitiveDistanceKNNQuery<O> extends AbstractDistanceKNNQuery<O> implements LinearScanQuery {
+ /**
+ * Unboxed distance function.
+ */
+ private PrimitiveDistanceFunction<? super O> rawdist;
+
/**
* Constructor.
*
* @param distanceQuery Distance function to use
*/
- public LinearScanPrimitiveDistanceKNNQuery(PrimitiveDistanceQuery<O, D> distanceQuery) {
+ public LinearScanPrimitiveDistanceKNNQuery(PrimitiveDistanceQuery<O> distanceQuery) {
super(distanceQuery);
+ rawdist = distanceQuery.getDistanceFunction();
}
- /**
- * Perform a linear scan batch kNN for primitive distance functions.
- *
- * @param objs Objects list
- * @param heaps Heaps array
- */
- protected void linearScanBatchKNN(List<O> objs, List<KNNHeap<D>> heaps) {
- final int size = objs.size();
- // Linear scan style KNN.
- for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) {
- O candidate = relation.get(iter);
- for(int index = 0; index < size; index++) {
- O object = objs.get(index);
- heaps.get(index).insert(distanceQuery.distance(object, candidate), iter);
- }
- }
+ @Override
+ public KNNList getKNNForDBID(DBIDRef id, int k) {
+ return linearScan(relation, relation.iterDBIDs(), relation.get(id), DBIDUtil.newHeap(k)).toKNNList();
}
@Override
- public KNNList<D> getKNNForDBID(DBIDRef id, int k) {
- final O obj = relation.get(id);
- KNNHeap<D> heap = DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k);
- for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) {
- heap.insert(distanceQuery.distance(obj, iter), iter);
- }
- return heap.toKNNList();
+ public KNNList getKNNForObject(O obj, int k) {
+ return linearScan(relation, relation.iterDBIDs(), obj, DBIDUtil.newHeap(k)).toKNNList();
}
- @Override
- public KNNList<D> getKNNForObject(O obj, int k) {
- KNNHeap<D> heap = DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k);
- for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) {
- heap.insert(distanceQuery.distance(obj, iter), iter);
+ /**
+ * Main loop of the linear scan.
+ *
+ * @param relation Data relation
+ * @param iter ID iterator
+ * @param obj Query object
+ * @param heap Output heap
+ * @return Heap
+ */
+ private KNNHeap linearScan(Relation<? extends O> relation, DBIDIter iter, final O obj, KNNHeap heap) {
+ double max = Double.POSITIVE_INFINITY;
+ while(iter.valid()) {
+ final double dist = rawdist.distance(obj, relation.get(iter));
+ if(dist <= max) {
+ max = heap.insert(dist, iter);
+ }
+ iter.advance();
}
- return heap.toKNNList();
+ return heap;
}
@Override
- public List<KNNList<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ public List<KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
final int size = ids.size();
- final List<KNNHeap<D>> heaps = new ArrayList<>(size);
+ final List<KNNHeap> heaps = new ArrayList<>(size);
List<O> objs = new ArrayList<>(size);
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- heaps.add(DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k));
+ heaps.add(DBIDUtil.newHeap(k));
objs.add(relation.get(iter));
}
linearScanBatchKNN(objs, heaps);
- List<KNNList<D>> result = new ArrayList<>(heaps.size());
- for(KNNHeap<D> heap : heaps) {
+ List<KNNList> result = new ArrayList<>(heaps.size());
+ for(KNNHeap heap : heaps) {
result.add(heap.toKNNList());
}
return result;
}
+
+ /**
+ * Perform a linear scan batch kNN for primitive distance functions.
+ *
+ * @param objs Objects list
+ * @param heaps Heaps array
+ */
+ protected void linearScanBatchKNN(List<O> objs, List<KNNHeap> heaps) {
+ final int size = objs.size();
+ // Linear scan style KNN.
+ for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) {
+ O candidate = relation.get(iter);
+ for(int index = 0; index < size; index++) {
+ final KNNHeap heap = heaps.get(index);
+ final double dist = rawdist.distance(objs.get(index), candidate);
+ if(dist <= heap.getKNNDistance()) {
+ heap.insert(dist, iter);
+ }
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/PreprocessorKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/PreprocessorKNNQuery.java
index 0f555c79..2f51c998 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/knn/PreprocessorKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/knn/PreprocessorKNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.knn;
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,10 +30,8 @@ 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.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.query.AbstractDataBasedQuery;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.preprocessed.knn.AbstractMaterializeKNNPreprocessor;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
@@ -42,12 +40,19 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
* Instance for a particular database, invoking the preprocessor.
*
* @author Erich Schubert
+ *
+ * @param <O> Data object type
*/
-public class PreprocessorKNNQuery<O, D extends Distance<D>, T extends KNNList<D>> extends AbstractDataBasedQuery<O> implements KNNQuery<O, D> {
+public class PreprocessorKNNQuery<O> implements KNNQuery<O> {
+ /**
+ * The data to use for this query
+ */
+ final protected Relation<? extends O> relation;
+
/**
* The last preprocessor result
*/
- final private AbstractMaterializeKNNPreprocessor<O, D, T> preprocessor;
+ final private AbstractMaterializeKNNPreprocessor<O> preprocessor;
/**
* Warn only once.
@@ -57,36 +62,27 @@ public class PreprocessorKNNQuery<O, D extends Distance<D>, T extends KNNList<D>
/**
* Constructor.
*
- * @param database Database to query
+ * @param relation Relation to query
* @param preprocessor Preprocessor instance to use
*/
- public PreprocessorKNNQuery(Relation<O> database, AbstractMaterializeKNNPreprocessor<O, D, T> preprocessor) {
- super(database);
+ public PreprocessorKNNQuery(Relation<O> relation, AbstractMaterializeKNNPreprocessor<O> preprocessor) {
+ super();
+ this.relation = relation;
this.preprocessor = preprocessor;
}
- /**
- * Constructor.
- *
- * @param database Database to query
- * @param preprocessor Preprocessor to use
- */
- public PreprocessorKNNQuery(Relation<O> database, AbstractMaterializeKNNPreprocessor.Factory<O, D, T> preprocessor) {
- this(database, preprocessor.instantiate(database));
- }
-
@Override
- public KNNList<D> getKNNForDBID(DBIDRef id, int k) {
+ public KNNList getKNNForDBID(DBIDRef id, int k) {
if(!warned && k > preprocessor.getK()) {
LoggingUtil.warning("Requested more neighbors than preprocessed!");
}
if(!warned && k < preprocessor.getK()) {
- KNNList<D> dr = preprocessor.get(id);
+ KNNList dr = preprocessor.get(id);
int subk = k;
- D kdist = dr.get(subk - 1).getDistance();
+ double kdist = dr.get(subk - 1).doubleValue();
while(subk < dr.size()) {
- D ndist = dr.get(subk).getDistance();
- if(kdist.equals(ndist)) {
+ double ndist = dr.get(subk).doubleValue();
+ if(kdist == ndist) {
// Tie - increase subk.
subk++;
}
@@ -105,19 +101,19 @@ public class PreprocessorKNNQuery<O, D extends Distance<D>, T extends KNNList<D>
}
@Override
- public List<KNNList<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ public List<KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
if(!warned && k > preprocessor.getK()) {
LoggingUtil.warning("Requested more neighbors than preprocessed!");
}
- List<KNNList<D>> result = new ArrayList<>(ids.size());
+ List<KNNList> result = new ArrayList<>(ids.size());
if(k < preprocessor.getK()) {
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- KNNList<D> dr = preprocessor.get(iter);
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ KNNList dr = preprocessor.get(iter);
int subk = k;
- D kdist = dr.get(subk - 1).getDistance();
+ double kdist = dr.get(subk - 1).doubleValue();
while(subk < dr.size()) {
- D ndist = dr.get(subk).getDistance();
- if(kdist.equals(ndist)) {
+ double ndist = dr.get(subk).doubleValue();
+ if(kdist == ndist) {
// Tie - increase subk.
subk++;
}
@@ -134,7 +130,7 @@ public class PreprocessorKNNQuery<O, D extends Distance<D>, T extends KNNList<D>
}
}
else {
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
result.add(preprocessor.get(iter));
}
}
@@ -142,7 +138,7 @@ public class PreprocessorKNNQuery<O, D extends Distance<D>, T extends KNNList<D>
}
@Override
- public KNNList<D> getKNNForObject(O obj, int k) {
+ public KNNList getKNNForObject(O obj, int k) {
throw new AbortException("Preprocessor KNN query only supports ID queries.");
}
@@ -151,7 +147,7 @@ public class PreprocessorKNNQuery<O, D extends Distance<D>, T extends KNNList<D>
*
* @return preprocessor instance
*/
- public AbstractMaterializeKNNPreprocessor<O, D, T> getPreprocessor() {
+ public AbstractMaterializeKNNPreprocessor<O> getPreprocessor() {
return preprocessor;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/package-info.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/package-info.java
index 17d8e4b0..31ecd704 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/knn/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/knn/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/database/query/package-info.java b/src/de/lmu/ifi/dbs/elki/database/query/package-info.java
index fb3539bc..bf4b4be9 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/package-info.java
@@ -81,7 +81,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/database/query/range/AbstractDistanceRangeQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/range/AbstractDistanceRangeQuery.java
index 531fa09d..1a3687d6 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/range/AbstractDistanceRangeQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/range/AbstractDistanceRangeQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.range;
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,9 @@ package de.lmu.ifi.dbs.elki.database.query.range;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.query.AbstractDataBasedQuery;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
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.database.relation.Relation;
/**
* Abstract base class for range queries that use a distance query in their
@@ -36,34 +35,34 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @author Erich Schubert
*
* @param <O> Database object type
- * @param <D> Distance type
*/
-public abstract class AbstractDistanceRangeQuery<O, D extends Distance<D>> extends AbstractDataBasedQuery<O> implements RangeQuery<O, D> {
+public abstract class AbstractDistanceRangeQuery<O> implements RangeQuery<O> {
+ /**
+ * The data to use for this query
+ */
+ final protected Relation<? extends O> relation;
+
/**
* Hold the distance function to be used.
*/
- protected DistanceQuery<O, D> distanceQuery;
+ final protected DistanceQuery<O> distanceQuery;
/**
* Constructor.
*
* @param distanceQuery Distance query
*/
- public AbstractDistanceRangeQuery(DistanceQuery<O, D> distanceQuery) {
- super(distanceQuery.getRelation());
+ public AbstractDistanceRangeQuery(DistanceQuery<O> distanceQuery) {
+ super();
+ this.relation = distanceQuery.getRelation();
this.distanceQuery = distanceQuery;
}
@Override
- public DistanceDBIDList<D> getRangeForDBID(DBIDRef id, D range) {
+ public DoubleDBIDList getRangeForDBID(DBIDRef id, double range) {
return getRangeForObject(relation.get(id), range);
}
@Override
- abstract public DistanceDBIDList<D> getRangeForObject(O obj, D range);
-
- @Override
- public D getDistanceFactory() {
- return distanceQuery.getDistanceFactory();
- }
+ abstract public DoubleDBIDList getRangeForObject(O obj, double range);
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/range/DoubleOptimizedDistanceRangeQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/range/DoubleOptimizedDistanceRangeQuery.java
deleted file mode 100644
index 90b867e3..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/query/range/DoubleOptimizedDistanceRangeQuery.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.query.range;
-
-/*
- 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.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDoubleDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.integer.DoubleDistanceIntegerDBIDList;
-import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery;
-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.distancefunction.PrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-
-/**
- * Default linear scan range query class.
- *
- * @author Erich Schubert
- *
- * @apiviz.uses PrimitiveDoubleDistanceFunction
- *
- * @param <O> Database object type
- */
-public class DoubleOptimizedDistanceRangeQuery<O> extends AbstractDistanceRangeQuery<O, DoubleDistance> implements LinearScanQuery {
- /**
- * Raw distance function.
- */
- PrimitiveDoubleDistanceFunction<? super O> rawdist;
-
- /**
- * Constructor.
- *
- * @param distanceQuery Distance function to use
- */
- @SuppressWarnings("unchecked")
- public DoubleOptimizedDistanceRangeQuery(DistanceQuery<O, DoubleDistance> distanceQuery) {
- super(distanceQuery);
- if(!(distanceQuery.getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction)) {
- throw new UnsupportedOperationException("DoubleOptimizedRangeQuery instantiated for non-PrimitiveDoubleDistanceFunction!");
- }
- rawdist = (PrimitiveDoubleDistanceFunction<O>) distanceQuery.getDistanceFunction();
- }
-
- @Override
- public DistanceDBIDList<DoubleDistance> getRangeForDBID(DBIDRef id, DoubleDistance range) {
- final Relation<? extends O> relation = this.relation;
- DoubleDistanceIntegerDBIDList result = new DoubleDistanceIntegerDBIDList();
- linearScan(relation, relation.iterDBIDs(), rawdist, relation.get(id), range.doubleValue(), result);
- result.sort();
- return result;
- }
-
- @Override
- public DistanceDBIDList<DoubleDistance> getRangeForObject(O obj, DoubleDistance range) {
- DoubleDistanceIntegerDBIDList result = new DoubleDistanceIntegerDBIDList();
- linearScan(relation, relation.iterDBIDs(), rawdist, obj, range.doubleValue(), result);
- result.sort();
- return result;
- }
-
- private static <O> void linearScan(Relation<? extends O> relation, DBIDIter iter, PrimitiveDoubleDistanceFunction<? super O> rawdist, O obj, double range, ModifiableDoubleDistanceDBIDList result) {
- while(iter.valid()) {
- final double doubleDistance = rawdist.doubleDistance(obj, relation.get(iter));
- if(doubleDistance <= range) {
- result.add(doubleDistance, iter);
- }
- iter.advance();
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanDistanceRangeQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanDistanceRangeQuery.java
index 8830dd45..8747cebf 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanDistanceRangeQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanDistanceRangeQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.range;
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,11 +25,11 @@ package de.lmu.ifi.dbs.elki.database.query.range;
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.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Default linear scan range query class.
@@ -40,24 +40,23 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @apiviz.has DistanceQuery
*
* @param <O> Database object type
- * @param <D> Distance type
*/
-public class LinearScanDistanceRangeQuery<O, D extends Distance<D>> extends AbstractDistanceRangeQuery<O, D> implements LinearScanQuery {
+public class LinearScanDistanceRangeQuery<O> extends AbstractDistanceRangeQuery<O> implements LinearScanQuery {
/**
* Constructor.
*
* @param distanceQuery Distance function to use
*/
- public LinearScanDistanceRangeQuery(DistanceQuery<O, D> distanceQuery) {
+ public LinearScanDistanceRangeQuery(DistanceQuery<O> distanceQuery) {
super(distanceQuery);
}
@Override
- public DistanceDBIDList<D> getRangeForDBID(DBIDRef id, D range) {
- GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>();
+ public DoubleDBIDList getRangeForDBID(DBIDRef id, double range) {
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) {
- D currentDistance = distanceQuery.distance(id, iter);
- if(currentDistance.compareTo(range) <= 0) {
+ double currentDistance = distanceQuery.distance(id, iter);
+ if(currentDistance <= range) {
result.add(currentDistance, iter);
}
}
@@ -66,11 +65,11 @@ public class LinearScanDistanceRangeQuery<O, D extends Distance<D>> extends Abst
}
@Override
- public DistanceDBIDList<D> getRangeForObject(O obj, D range) {
- GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>();
+ public DoubleDBIDList getRangeForObject(O obj, double range) {
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) {
- D currentDistance = distanceQuery.distance(obj, iter);
- if(currentDistance.compareTo(range) <= 0) {
+ double currentDistance = distanceQuery.distance(obj, iter);
+ if(currentDistance <= range) {
result.add(currentDistance, iter);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanEuclideanDistanceRangeQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanEuclideanDistanceRangeQuery.java
new file mode 100644
index 00000000..a12a4368
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanEuclideanDistanceRangeQuery.java
@@ -0,0 +1,104 @@
+package de.lmu.ifi.dbs.elki.database.query.range;
+
+/*
+ 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.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.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
+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.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
+
+/**
+ * Optimized linear scan for Euclidean distance range queries.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.uses SquaredEuclideanDistanceFunction
+ *
+ * @param <O> Database object type
+ */
+public class LinearScanEuclideanDistanceRangeQuery<O extends NumberVector> extends LinearScanPrimitiveDistanceRangeQuery<O> {
+ /**
+ * Squared Euclidean distance function.
+ */
+ private static final SquaredEuclideanDistanceFunction SQUARED = SquaredEuclideanDistanceFunction.STATIC;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceQuery Distance function to use
+ */
+ public LinearScanEuclideanDistanceRangeQuery(PrimitiveDistanceQuery<O> distanceQuery) {
+ super(distanceQuery);
+ }
+
+ @Override
+ public DoubleDBIDList getRangeForDBID(DBIDRef id, double range) {
+ // Note: subtle optimization. Get "id" only once!
+ final O obj = relation.get(id);
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
+ linearScan(relation, relation.iterDBIDs(), obj, range, result);
+ result.sort();
+ return result;
+ }
+
+ @Override
+ public DoubleDBIDList getRangeForObject(O obj, double range) {
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
+ linearScan(relation, relation.iterDBIDs(), obj, range, result);
+ result.sort();
+ return result;
+ }
+
+ /**
+ * Main loop for linear scan,
+ *
+ * @param relation Data relation
+ * @param iter Iterator
+ * @param obj Query object
+ * @param range Query radius
+ * @param result Output data structure
+ */
+ private void linearScan(Relation<? extends O> relation, DBIDIter iter, O obj, double range, ModifiableDoubleDBIDList result) {
+ // Avoid a loss in numerical precision when using the squared radius:
+ final double upper = range * 1.0000001;
+ // This should be more precise, but slower:
+ // upper = MathUtil.floatToDoubleUpper((float)range);
+ final double sqrange = upper * upper;
+ while(iter.valid()) {
+ final double sqdistance = SQUARED.distance(obj, relation.get(iter));
+ if(sqdistance <= sqrange) {
+ final double dist = Math.sqrt(sqdistance);
+ if(dist <= range) { // double check, as we increased the radius above
+ result.add(dist, iter);
+ }
+ }
+ iter.advance();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanPrimitiveDistanceRangeQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanPrimitiveDistanceRangeQuery.java
index ab4dd2be..69d6a0b7 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanPrimitiveDistanceRangeQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanPrimitiveDistanceRangeQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.range;
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,10 +25,12 @@ package de.lmu.ifi.dbs.elki.database.query.range;
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.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceQuery;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
/**
* Default linear scan range query class.
@@ -41,43 +43,57 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @apiviz.uses PrimitiveDistanceQuery
*
* @param <O> Database object type
- * @param <D> Distance type
*/
-public class LinearScanPrimitiveDistanceRangeQuery<O, D extends Distance<D>> extends AbstractDistanceRangeQuery<O, D> {
+public class LinearScanPrimitiveDistanceRangeQuery<O> extends AbstractDistanceRangeQuery<O> {
+ /**
+ * Unboxed distance function.
+ */
+ private PrimitiveDistanceFunction<? super O> rawdist;
+
/**
* Constructor.
*
* @param distanceQuery Distance function to use
*/
- public LinearScanPrimitiveDistanceRangeQuery(PrimitiveDistanceQuery<O, D> distanceQuery) {
+ public LinearScanPrimitiveDistanceRangeQuery(PrimitiveDistanceQuery<O> distanceQuery) {
super(distanceQuery);
+ rawdist = distanceQuery.getDistanceFunction();
}
@Override
- public DistanceDBIDList<D> getRangeForDBID(DBIDRef id, D range) {
+ public DoubleDBIDList getRangeForDBID(DBIDRef id, double range) {
// Note: subtle optimization. Get "id" only once!
final O obj = relation.get(id);
- GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>();
- for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) {
- D currentDistance = distanceQuery.distance(obj, iter);
- if(currentDistance.compareTo(range) <= 0) {
- result.add(currentDistance, iter);
- }
- }
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
+ linearScan(relation, relation.iterDBIDs(), obj, range, result);
result.sort();
return result;
}
@Override
- public DistanceDBIDList<D> getRangeForObject(O obj, D range) {
- GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>();
- for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) {
- D currentDistance = distanceQuery.distance(obj, iter);
- if(currentDistance.compareTo(range) <= 0) {
- result.add(currentDistance, iter);
- }
- }
+ public DoubleDBIDList getRangeForObject(O obj, double range) {
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
+ linearScan(relation, relation.iterDBIDs(), obj, range, result);
result.sort();
return result;
}
+
+ /**
+ * Main loop for linear scan,
+ *
+ * @param relation Data relation
+ * @param iter Iterator
+ * @param obj Query object
+ * @param range Query radius
+ * @param result Output data structure
+ */
+ private void linearScan(Relation<? extends O> relation, DBIDIter iter, O obj, double range, ModifiableDoubleDBIDList result) {
+ while(iter.valid()) {
+ final double distance = rawdist.distance(obj, relation.get(iter));
+ if(distance <= range) {
+ result.add(distance, iter);
+ }
+ iter.advance();
+ }
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/range/RangeQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/range/RangeQuery.java
index 3f21c5f8..364b79c2 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/range/RangeQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/range/RangeQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.range;
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,9 +24,8 @@ package de.lmu.ifi.dbs.elki.database.query.range;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* The interface for range queries
@@ -34,12 +33,11 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @author Erich Schubert
*
* @apiviz.landmark
- * @apiviz.uses DistanceDBIDList oneway - - «create»
+ * @apiviz.uses DoubleDBIDList oneway - - «create»
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public interface RangeQuery<O, D extends Distance<D>> extends DatabaseQuery {
+public interface RangeQuery<O> extends DatabaseQuery {
/**
* Get the nearest neighbors for a particular id in a given query range
*
@@ -47,7 +45,7 @@ public interface RangeQuery<O, D extends Distance<D>> extends DatabaseQuery {
* @param range Query range
* @return neighbors
*/
- public DistanceDBIDList<D> getRangeForDBID(DBIDRef id, D range);
+ public DoubleDBIDList getRangeForDBID(DBIDRef id, double range);
/**
* Get the nearest neighbors for a particular object in a given query range
@@ -56,12 +54,5 @@ public interface RangeQuery<O, D extends Distance<D>> extends DatabaseQuery {
* @param range Query range
* @return neighbors
*/
- public DistanceDBIDList<D> getRangeForObject(O obj, D range);
-
- /**
- * Get the distance factory for the given distance type.
- *
- * @return Distance factory.
- */
- public D getDistanceFactory();
+ public DoubleDBIDList getRangeForObject(O obj, double range);
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/range/package-info.java b/src/de/lmu/ifi/dbs/elki/database/query/range/package-info.java
index b2e3427d..d47d3ad4 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/range/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/range/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/database/query/rknn/AbstractRKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/rknn/AbstractRKNNQuery.java
index 8a88bf0f..5036ae43 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/rknn/AbstractRKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/rknn/AbstractRKNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.rknn;
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,32 +24,37 @@ package de.lmu.ifi.dbs.elki.database.query.rknn;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.query.AbstractDataBasedQuery;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
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.database.relation.Relation;
/**
* Instance for the query on a particular database.
*
* @author Erich Schubert
*/
-public abstract class AbstractRKNNQuery<O, D extends Distance<D>> extends AbstractDataBasedQuery<O> implements RKNNQuery<O, D> {
+public abstract class AbstractRKNNQuery<O> implements RKNNQuery<O> {
+ /**
+ * The data to use for this query
+ */
+ final protected Relation<? extends O> relation;
+
/**
* Hold the distance function to be used.
*/
- protected final DistanceQuery<O, D> distanceQuery;
+ final protected DistanceQuery<O> distanceQuery;
/**
* Constructor.
*
* @param distanceQuery distance query
*/
- public AbstractRKNNQuery(DistanceQuery<O, D> distanceQuery) {
- super(distanceQuery.getRelation());
+ public AbstractRKNNQuery(DistanceQuery<O> distanceQuery) {
+ super();
+ this.relation = distanceQuery.getRelation();
this.distanceQuery = distanceQuery;
}
@Override
- abstract public DistanceDBIDList<D> getRKNNForDBID(DBIDRef id, int k);
+ abstract public DoubleDBIDList getRKNNForDBID(DBIDRef id, int k);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/rknn/LinearScanRKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/rknn/LinearScanRKNNQuery.java
index 71cf0619..3d55c3a6 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/rknn/LinearScanRKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/rknn/LinearScanRKNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.rknn;
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,14 +30,13 @@ 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.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery;
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.distance.distancevalue.Distance;
/**
* Default linear scan RKNN query class.
@@ -48,14 +47,13 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @apiviz.has KNNQuery
*
* @param <O> Database object type
- * @param <D> Distance type
*/
// FIXME: Validate this works correctly.
-public class LinearScanRKNNQuery<O, D extends Distance<D>> extends AbstractRKNNQuery<O, D> implements LinearScanQuery {
+public class LinearScanRKNNQuery<O> extends AbstractRKNNQuery<O> implements LinearScanQuery {
/**
* KNN query we use.
*/
- protected final KNNQuery<O, D> knnQuery;
+ protected final KNNQuery<O> knnQuery;
/**
* Constructor.
@@ -64,24 +62,24 @@ public class LinearScanRKNNQuery<O, D extends Distance<D>> extends AbstractRKNNQ
* @param knnQuery kNN query to use.
* @param maxk k to use
*/
- public LinearScanRKNNQuery(DistanceQuery<O, D> distanceQuery, KNNQuery<O, D> knnQuery, Integer maxk) {
+ public LinearScanRKNNQuery(DistanceQuery<O> distanceQuery, KNNQuery<O> knnQuery, Integer maxk) {
super(distanceQuery);
this.knnQuery = knnQuery;
}
@Override
- public DistanceDBIDList<D> getRKNNForObject(O obj, int k) {
- GenericDistanceDBIDList<D> rNNlist = new GenericDistanceDBIDList<>();
+ public DoubleDBIDList getRKNNForObject(O obj, int k) {
+ ModifiableDoubleDBIDList rNNlist = DBIDUtil.newDistanceDBIDList();
ArrayDBIDs allIDs = DBIDUtil.ensureArray(relation.getDBIDs());
- List<? extends KNNList<D>> kNNLists = knnQuery.getKNNForBulkDBIDs(allIDs, k);
+ List<? extends KNNList> kNNLists = knnQuery.getKNNForBulkDBIDs(allIDs, k);
int i = 0;
- for (DBIDIter iter = allIDs.iter(); iter.valid(); iter.advance()) {
- KNNList<D> knn = kNNLists.get(i);
+ for(DBIDIter iter = allIDs.iter(); iter.valid(); iter.advance()) {
+ KNNList knn = kNNLists.get(i);
int last = Math.min(k - 1, knn.size() - 1);
- D dist = distanceQuery.distance(obj, iter);
- if(last < k - 1 || dist.compareTo(knn.get(last).getDistance()) < 1) {
+ double dist = distanceQuery.distance(obj, iter);
+ if(last < k - 1 || dist <= knn.get(last).doubleValue()) {
rNNlist.add(dist, iter);
}
i++;
@@ -91,18 +89,18 @@ public class LinearScanRKNNQuery<O, D extends Distance<D>> extends AbstractRKNNQ
}
@Override
- public DistanceDBIDList<D> getRKNNForDBID(DBIDRef id, int k) {
- GenericDistanceDBIDList<D> rNNList = new GenericDistanceDBIDList<>();
-
+ public DoubleDBIDList getRKNNForDBID(DBIDRef id, int k) {
+ ModifiableDoubleDBIDList rNNList = DBIDUtil.newDistanceDBIDList();
+
ArrayDBIDs allIDs = DBIDUtil.ensureArray(relation.getDBIDs());
- List<? extends KNNList<D>> kNNList = knnQuery.getKNNForBulkDBIDs(allIDs, k);
+ List<? extends KNNList> kNNList = knnQuery.getKNNForBulkDBIDs(allIDs, k);
int i = 0;
- for (DBIDIter iter = allIDs.iter(); iter.valid(); iter.advance()) {
- KNNList<D> knn = kNNList.get(i);
- for(DistanceDBIDListIter<D> n = knn.iter(); n.valid(); n.advance()) {
+ for(DBIDIter iter = allIDs.iter(); iter.valid(); iter.advance()) {
+ KNNList knn = kNNList.get(i);
+ for(DoubleDBIDListIter n = knn.iter(); n.valid(); n.advance()) {
if(DBIDUtil.equal(n, id)) {
- rNNList.add(n.getDistance(), iter);
+ rNNList.add(n.doubleValue(), iter);
}
}
i++;
@@ -112,24 +110,24 @@ public class LinearScanRKNNQuery<O, D extends Distance<D>> extends AbstractRKNNQ
}
@Override
- public List<GenericDistanceDBIDList<D>> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
- List<GenericDistanceDBIDList<D>> rNNList = new ArrayList<>(ids.size());
+ public List<? extends DoubleDBIDList> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ List<ModifiableDoubleDBIDList> rNNList = new ArrayList<>(ids.size());
for(int i = 0; i < ids.size(); i++) {
- rNNList.add(new GenericDistanceDBIDList<D>());
+ rNNList.add(DBIDUtil.newDistanceDBIDList());
}
ArrayDBIDs allIDs = DBIDUtil.ensureArray(relation.getDBIDs());
- List<? extends KNNList<D>> kNNList = knnQuery.getKNNForBulkDBIDs(allIDs, k);
+ List<? extends KNNList> kNNList = knnQuery.getKNNForBulkDBIDs(allIDs, k);
int i = 0;
- for (DBIDIter iter = allIDs.iter(); iter.valid(); iter.advance()) {
- KNNList<D> knn = kNNList.get(i);
- for(DistanceDBIDListIter<D> n = knn.iter(); n.valid(); n.advance()) {
+ for(DBIDIter iter = allIDs.iter(); iter.valid(); iter.advance()) {
+ KNNList knn = kNNList.get(i);
+ for(DoubleDBIDListIter n = knn.iter(); n.valid(); n.advance()) {
int j = 0;
- for (DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) {
+ for(DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) {
if(DBIDUtil.equal(n, iter2)) {
- GenericDistanceDBIDList<D> rNN = rNNList.get(j);
- rNN.add(n.getDistance(), iter);
+ ModifiableDoubleDBIDList rNN = rNNList.get(j);
+ rNN.add(n.doubleValue(), iter);
}
j++;
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/rknn/PreprocessorRKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/rknn/PreprocessorRKNNQuery.java
index 9f8f9c71..d18b2c21 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/rknn/PreprocessorRKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/rknn/PreprocessorRKNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.rknn;
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,10 +29,8 @@ import java.util.List;
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.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.query.AbstractDataBasedQuery;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
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.preprocessed.knn.MaterializeKNNAndRKNNPreprocessor;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
@@ -42,11 +40,16 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
*
* @author Elke Achtert
*/
-public class PreprocessorRKNNQuery<O, D extends Distance<D>> extends AbstractDataBasedQuery<O> implements RKNNQuery<O, D> {
+public class PreprocessorRKNNQuery<O> implements RKNNQuery<O> {
+ /**
+ * The data to use for this query
+ */
+ final protected Relation<? extends O> relation;
+
/**
* The last preprocessor result
*/
- final private MaterializeKNNAndRKNNPreprocessor<O, D> preprocessor;
+ final private MaterializeKNNAndRKNNPreprocessor<O> preprocessor;
/**
* Warn only once.
@@ -56,11 +59,12 @@ public class PreprocessorRKNNQuery<O, D extends Distance<D>> extends AbstractDat
/**
* Constructor.
*
- * @param database Database to query
+ * @param relation Relation to query
* @param preprocessor Preprocessor instance to use
*/
- public PreprocessorRKNNQuery(Relation<O> database, MaterializeKNNAndRKNNPreprocessor<O, D> preprocessor) {
- super(database);
+ public PreprocessorRKNNQuery(Relation<O> relation, MaterializeKNNAndRKNNPreprocessor<O> preprocessor) {
+ super();
+ this.relation = relation;
this.preprocessor = preprocessor;
}
@@ -70,30 +74,30 @@ public class PreprocessorRKNNQuery<O, D extends Distance<D>> extends AbstractDat
* @param database Database to query
* @param preprocessor Preprocessor to use
*/
- public PreprocessorRKNNQuery(Relation<O> database, MaterializeKNNAndRKNNPreprocessor.Factory<O, D> preprocessor) {
+ public PreprocessorRKNNQuery(Relation<O> database, MaterializeKNNAndRKNNPreprocessor.Factory<O> preprocessor) {
this(database, preprocessor.instantiate(database));
}
@Override
- public DistanceDBIDList<D> getRKNNForDBID(DBIDRef id, int k) {
+ public DoubleDBIDList getRKNNForDBID(DBIDRef id, int k) {
if(!warned && k != preprocessor.getK()) {
LoggingUtil.warning("Requested more neighbors than preprocessed!");
}
return preprocessor.getRKNN(id);
}
-
+
@Override
- public DistanceDBIDList<D> getRKNNForObject(O obj, int k) {
+ public DoubleDBIDList getRKNNForObject(O obj, int k) {
throw new AbortException("Preprocessor KNN query only supports ID queries.");
}
-
+
@Override
- public List<? extends DistanceDBIDList<D>> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ public List<? extends DoubleDBIDList> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
if(!warned && k != preprocessor.getK()) {
LoggingUtil.warning("Requested more neighbors than preprocessed!");
}
- List<DistanceDBIDList<D>> result = new ArrayList<>(ids.size());
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ List<DoubleDBIDList> result = new ArrayList<>(ids.size());
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
result.add(preprocessor.getRKNN(iter));
}
return result;
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/rknn/RKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/rknn/RKNNQuery.java
index 0a05d797..97ea76be 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/rknn/RKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/rknn/RKNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.rknn;
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,21 +27,19 @@ import java.util.List;
import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Abstract reverse kNN Query interface.
*
* @author Erich Schubert
*
- * @apiviz.uses DistanceDBIDList oneway - - «create»
+ * @apiviz.uses DoubleDBIDList oneway - - «create»
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public interface RKNNQuery<O, D extends Distance<D>> extends DatabaseQuery {
+public interface RKNNQuery<O> extends DatabaseQuery {
/**
* Get the reverse k nearest neighbors for a particular id.
*
@@ -49,7 +47,7 @@ public interface RKNNQuery<O, D extends Distance<D>> extends DatabaseQuery {
* @param k number of neighbors requested
* @return reverse k nearest neighbors
*/
- public DistanceDBIDList<D> getRKNNForDBID(DBIDRef id, int k);
+ public DoubleDBIDList getRKNNForDBID(DBIDRef id, int k);
/**
* Get the reverse k nearest neighbors for a particular object.
@@ -58,7 +56,7 @@ public interface RKNNQuery<O, D extends Distance<D>> extends DatabaseQuery {
* @param k number of neighbors requested
* @return reverse k nearest neighbors
*/
- public DistanceDBIDList<D> getRKNNForObject(O obj, int k);
+ public DoubleDBIDList getRKNNForObject(O obj, int k);
/**
* Bulk query method for reverse k nearest neighbors for ids.
@@ -67,5 +65,5 @@ public interface RKNNQuery<O, D extends Distance<D>> extends DatabaseQuery {
* @param k number of neighbors requested
* @return reverse k nearest neighbors
*/
- public List<? extends DistanceDBIDList<D>> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k);
+ public List<? extends DoubleDBIDList> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/rknn/package-info.java b/src/de/lmu/ifi/dbs/elki/database/query/rknn/package-info.java
index 8c0501b6..9ab02433 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/rknn/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/rknn/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/database/query/similarity/AbstractDBIDSimilarityQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractDBIDSimilarityQuery.java
index 8dc6dd61..b7a8c5af 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractDBIDSimilarityQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractDBIDSimilarityQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.similarity;
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.database.query.similarity;
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.Distance;
/**
* Run a database query in a database context.
@@ -33,9 +32,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* @author Erich Schubert
*
* @param <O> Database object type.
- * @param <D> Distance result type.
*/
-public abstract class AbstractDBIDSimilarityQuery<O, D extends Distance<D>> extends AbstractSimilarityQuery<O, D> {
+public abstract class AbstractDBIDSimilarityQuery<O> extends AbstractSimilarityQuery<O> {
/**
* Constructor.
*
@@ -46,17 +44,17 @@ public abstract class AbstractDBIDSimilarityQuery<O, D extends Distance<D>> exte
}
@Override
- public D similarity(O o1, DBIDRef id2) {
+ public double similarity(O o1, DBIDRef id2) {
throw new UnsupportedOperationException("This distance function can only be used for objects when referenced by ID.");
}
@Override
- public D similarity(DBIDRef id1, O o2) {
+ public double similarity(DBIDRef id1, O o2) {
throw new UnsupportedOperationException("This distance function can only be used for objects when referenced by ID.");
}
@Override
- public D similarity(O o1, O o2) {
+ public double similarity(O o1, O o2) {
throw new UnsupportedOperationException("This distance function can only be used for objects when referenced by ID.");
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractSimilarityQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractSimilarityQuery.java
index fbcf76a7..99cce405 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractSimilarityQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractSimilarityQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.similarity;
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,9 +24,7 @@ package de.lmu.ifi.dbs.elki.database.query.similarity;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.query.AbstractDataBasedQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* A distance query serves as adapter layer for database and primitive
@@ -34,17 +32,22 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
*
* @author Erich Schubert
*
- * @param O Input object type
- * @param D Distance result type
+ * @param <O> Input object type
*/
-public abstract class AbstractSimilarityQuery<O, D extends Distance<D>> extends AbstractDataBasedQuery<O> implements SimilarityQuery<O, D> {
+public abstract class AbstractSimilarityQuery<O> implements SimilarityQuery<O> {
+ /**
+ * The data to use for this query
+ */
+ final protected Relation<? extends O> relation;
+
/**
* Constructor.
*
* @param relation Relation to use.
*/
public AbstractSimilarityQuery(Relation<? extends O> relation) {
- super(relation);
+ super();
+ this.relation = relation;
}
/**
@@ -55,7 +58,7 @@ public abstract class AbstractSimilarityQuery<O, D extends Distance<D>> extends
* @return the distance between the two objects specified by their object ids
*/
@Override
- public abstract D similarity(DBIDRef id1, DBIDRef id2);
+ public abstract double similarity(DBIDRef id1, DBIDRef id2);
/**
* Returns the distance between the two objects specified by their object ids.
@@ -65,7 +68,7 @@ public abstract class AbstractSimilarityQuery<O, D extends Distance<D>> extends
* @return the distance between the two objects specified by their object ids
*/
@Override
- public abstract D similarity(O o1, DBIDRef id2);
+ public abstract double similarity(O o1, DBIDRef id2);
/**
* Returns the distance between the two objects specified by their object ids.
@@ -75,7 +78,7 @@ public abstract class AbstractSimilarityQuery<O, D extends Distance<D>> extends
* @return the distance between the two objects specified by their object ids
*/
@Override
- public abstract D similarity(DBIDRef id1, O o2);
+ public abstract double similarity(DBIDRef id1, O o2);
/**
* Returns the distance between the two objects specified by their object ids.
@@ -85,5 +88,10 @@ public abstract class AbstractSimilarityQuery<O, D extends Distance<D>> extends
* @return the distance between the two objects specified by their object ids
*/
@Override
- public abstract D similarity(O o1, O o2);
+ public abstract double similarity(O o1, O o2);
+
+ @Override
+ public Relation<? extends O> getRelation() {
+ return relation;
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/similarity/PrimitiveSimilarityQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/similarity/PrimitiveSimilarityQuery.java
index 58020239..f39383a2 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/similarity/PrimitiveSimilarityQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/similarity/PrimitiveSimilarityQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.similarity;
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.database.query.similarity;
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.Distance;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFunction;
/**
@@ -33,14 +32,15 @@ import de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFuncti
*
* @author Erich Schubert
*
+ * @apiviz.has PrimitiveSimilarityFunction
+ *
* @param <O> Database object type.
- * @param <D> Distance result type.
*/
-public class PrimitiveSimilarityQuery<O, D extends Distance<D>> extends AbstractSimilarityQuery<O, D> {
+public class PrimitiveSimilarityQuery<O> extends AbstractSimilarityQuery<O> {
/**
* The distance function we use.
*/
- final protected PrimitiveSimilarityFunction<? super O, D> similarityFunction;
+ final protected PrimitiveSimilarityFunction<? super O> similarityFunction;
/**
* Constructor.
@@ -48,48 +48,33 @@ public class PrimitiveSimilarityQuery<O, D extends Distance<D>> extends Abstract
* @param relation Relation to use.
* @param similarityFunction Our similarity function
*/
- public PrimitiveSimilarityQuery(Relation<? extends O> relation, PrimitiveSimilarityFunction<? super O, D> similarityFunction) {
+ public PrimitiveSimilarityQuery(Relation<? extends O> relation, PrimitiveSimilarityFunction<? super O> similarityFunction) {
super(relation);
this.similarityFunction = similarityFunction;
}
@Override
- public D similarity(DBIDRef id1, DBIDRef id2) {
- O o1 = relation.get(id1);
- O o2 = relation.get(id2);
- return similarity(o1, o2);
+ public double similarity(DBIDRef id1, DBIDRef id2) {
+ return similarity(relation.get(id1), relation.get(id2));
}
@Override
- public D similarity(O o1, DBIDRef id2) {
- O o2 = relation.get(id2);
- return similarity(o1, o2);
+ public double similarity(O o1, DBIDRef id2) {
+ return similarity(o1, relation.get(id2));
}
@Override
- public D similarity(DBIDRef id1, O o2) {
- O o1 = relation.get(id1);
- return similarity(o1, o2);
+ public double similarity(DBIDRef id1, O o2) {
+ return similarity(relation.get(id1), o2);
}
@Override
- public D similarity(O o1, O o2) {
- if (o1 == null) {
- throw new UnsupportedOperationException("This distance function can only be used for object instances.");
- }
- if (o2 == null) {
- throw new UnsupportedOperationException("This distance function can only be used for object instances.");
- }
+ public double similarity(O o1, O o2) {
return similarityFunction.similarity(o1, o2);
}
@Override
- public D getDistanceFactory() {
- return similarityFunction.getDistanceFactory();
- }
-
- @Override
- public PrimitiveSimilarityFunction<? super O, D> getSimilarityFunction() {
+ public PrimitiveSimilarityFunction<? super O> getSimilarityFunction() {
return similarityFunction;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/similarity/SimilarityQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/similarity/SimilarityQuery.java
index 80347fb7..2b835437 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/similarity/SimilarityQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/similarity/SimilarityQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.similarity;
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.database.query.similarity;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction;
/**
@@ -36,12 +35,10 @@ import de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction;
* @author Erich Schubert
*
* @apiviz.landmark
- * @apiviz.has Distance
*
- * @param O Input object type
- * @param D Distance result type
+ * @param <O> Input object type
*/
-public interface SimilarityQuery<O, D extends Distance<?>> extends DatabaseQuery {
+public interface SimilarityQuery<O> extends DatabaseQuery {
/**
* Returns the similarity between the two objects specified by their object
* ids.
@@ -51,7 +48,7 @@ public interface SimilarityQuery<O, D extends Distance<?>> extends DatabaseQuery
* @return the similarity between the two objects specified by their object
* ids
*/
- D similarity(DBIDRef id1, DBIDRef id2);
+ double similarity(DBIDRef id1, DBIDRef id2);
/**
* Returns the similarity between the two objects specified by their object
@@ -62,7 +59,7 @@ public interface SimilarityQuery<O, D extends Distance<?>> extends DatabaseQuery
* @return the similarity between the two objects specified by their object
* ids
*/
- D similarity(O o1, DBIDRef id2);
+ double similarity(O o1, DBIDRef id2);
/**
* Returns the similarity between the two objects specified by their object
@@ -73,7 +70,7 @@ public interface SimilarityQuery<O, D extends Distance<?>> extends DatabaseQuery
* @return the similarity between the two objects specified by their object
* ids
*/
- D similarity(DBIDRef id1, O o2);
+ double similarity(DBIDRef id1, O o2);
/**
* Returns the similarity between the two objects specified by their object
@@ -84,14 +81,7 @@ public interface SimilarityQuery<O, D extends Distance<?>> extends DatabaseQuery
* @return the similarity between the two objects specified by their object
* ids
*/
- D similarity(O o1, O o2);
-
- /**
- * Method to get the distance functions factory.
- *
- * @return Factory for distance objects
- */
- D getDistanceFactory();
+ double similarity(O o1, O o2);
/**
* Access the underlying data query.
@@ -105,5 +95,5 @@ public interface SimilarityQuery<O, D extends Distance<?>> extends DatabaseQuery
*
* @return Similarity function
*/
- SimilarityFunction<? super O, D> getSimilarityFunction();
+ SimilarityFunction<? super O> getSimilarityFunction();
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/query/similarity/package-info.java b/src/de/lmu/ifi/dbs/elki/database/query/similarity/package-info.java
index dde6909b..720096ad 100644
--- a/src/de/lmu/ifi/dbs/elki/database/query/similarity/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/database/query/similarity/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/database/relation/ConvertToStringView.java b/src/de/lmu/ifi/dbs/elki/database/relation/ConvertToStringView.java
index 3ce4d935..26cd6675 100644
--- a/src/de/lmu/ifi/dbs/elki/database/relation/ConvertToStringView.java
+++ b/src/de/lmu/ifi/dbs/elki/database/relation/ConvertToStringView.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.relation;
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/database/relation/DBIDView.java b/src/de/lmu/ifi/dbs/elki/database/relation/DBIDView.java
index 7eb14983..47891443 100644
--- a/src/de/lmu/ifi/dbs/elki/database/relation/DBIDView.java
+++ b/src/de/lmu/ifi/dbs/elki/database/relation/DBIDView.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.relation;
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/database/datastore/DoubleDistanceDataStore.java b/src/de/lmu/ifi/dbs/elki/database/relation/DoubleRelation.java
index 88b9d4dc..f128cb23 100644
--- a/src/de/lmu/ifi/dbs/elki/database/datastore/DoubleDistanceDataStore.java
+++ b/src/de/lmu/ifi/dbs/elki/database/relation/DoubleRelation.java
@@ -1,10 +1,9 @@
-package de.lmu.ifi.dbs.elki.database.datastore;
-
+package de.lmu.ifi.dbs.elki.database.relation;
/*
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,28 +23,41 @@ package de.lmu.ifi.dbs.elki.database.datastore;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
/**
- * Double-valued data store (avoids boxing/unboxing).
+ * Interface for double-valued relations.
*
* @author Erich Schubert
*/
-public interface DoubleDistanceDataStore extends DataStore<DoubleDistance> {
+public interface DoubleRelation extends Relation<Double> {
/**
- * Getter, but using objects.
+ * Get the representation of an object.
*
- * @deprecated Use {@link #doubleValue} instead, to avoid boxing/unboxing cost.
+ * @param id Object ID
+ * @return object instance
*/
- @Override
- @Deprecated
- public DoubleDistance get(DBIDRef id);
+ public double doubleValue(DBIDRef id);
/**
- * Retrieves an object from the storage.
+ * Set an object representation.
*
- * @param id Database ID.
- * @return Double value
+ * @param id Object ID
+ * @param val Value
*/
- public double doubleValue(DBIDRef id);
-} \ No newline at end of file
+ // TODO: remove / move to a writable API?
+ public void set(DBIDRef id, double val);
+
+ /**
+ * @deprecated use {@link #doubleValue} instead.
+ */
+ @Deprecated
+ @Override
+ public Double get(DBIDRef id);
+
+ /**
+ * @deprecated use {@link #set(DBIDRef, double)} instead.
+ */
+ @Deprecated
+ @Override
+ public void set(DBIDRef id, Double val);
+}
diff --git a/src/de/lmu/ifi/dbs/elki/database/relation/MaterializedDoubleRelation.java b/src/de/lmu/ifi/dbs/elki/database/relation/MaterializedDoubleRelation.java
new file mode 100644
index 00000000..8687efd8
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/database/relation/MaterializedDoubleRelation.java
@@ -0,0 +1,209 @@
+package de.lmu.ifi.dbs.elki.database.relation;
+
+/*
+ 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.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.DoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+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.StaticDBIDs;
+import de.lmu.ifi.dbs.elki.result.AbstractHierarchicalResult;
+
+/**
+ * Represents a single representation. This is attached to a DBIDs object, which
+ * you are supposed to manage first. I.e. put the new DBID in, then invoke
+ * set(), remove the DBID, then delete().
+ *
+ * @author Erich Schubert
+ */
+public class MaterializedDoubleRelation extends AbstractHierarchicalResult implements DoubleRelation {
+ /**
+ * Our database
+ */
+ private final Database database;
+
+ /**
+ * Map to hold the objects of the database.
+ */
+ private final DoubleDataStore content;
+
+ /**
+ * The DBIDs this is supposed to be defined for.
+ *
+ * Note: we only keep an unmodifiable reference.
+ */
+ private final StaticDBIDs ids;
+
+ /**
+ * The relation name.
+ */
+ private String name;
+
+ /**
+ * The relation name (short version)
+ */
+ private String shortname = "relation";
+
+ /**
+ * Constructor.
+ *
+ * @param database Database
+ * @param ids IDs
+ */
+ public MaterializedDoubleRelation(Database database, DBIDs ids) {
+ this(database, ids, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param database Database
+ * @param ids IDs
+ * @param name Name
+ */
+ public MaterializedDoubleRelation(Database database, DBIDs ids, String name) {
+ // We can't call this() since we'll have generics issues then.
+ super();
+ this.database = database;
+ this.ids = DBIDUtil.makeUnmodifiable(ids);
+ this.name = name;
+ this.content = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_DB);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param database Database
+ * @param ids IDs
+ * @param name Name
+ * @param content Content
+ */
+ public MaterializedDoubleRelation(Database database, DBIDs ids, String name, DoubleDataStore content) {
+ super();
+ this.database = database;
+ this.ids = DBIDUtil.makeUnmodifiable(ids);
+ this.name = name;
+ this.content = content;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param name Name
+ * @param shortname Short name of the result
+ * @param content Content
+ * @param ids IDs
+ */
+ public MaterializedDoubleRelation(String name, String shortname, DoubleDataStore content, DBIDs ids) {
+ super();
+ this.database = null;
+ this.ids = DBIDUtil.makeUnmodifiable(ids);
+ this.name = name;
+ this.shortname = shortname;
+ this.content = content;
+ }
+
+ @Override
+ public Database getDatabase() {
+ return database;
+ }
+
+ @Deprecated
+ @Override
+ public Double get(DBIDRef id) {
+ return content.doubleValue(id);
+ }
+
+ @Override
+ public double doubleValue(DBIDRef id) {
+ return content.doubleValue(id);
+ }
+
+ @Override
+ public void set(DBIDRef id, double val) {
+ assert (ids.contains(id));
+ if(content instanceof WritableDoubleDataStore) {
+ ((WritableDoubleDataStore) content).putDouble(id, val);
+ }
+ }
+
+ @Deprecated
+ @Override
+ public void set(DBIDRef id, Double val) {
+ assert (ids.contains(id));
+ if(content instanceof WritableDoubleDataStore) {
+ ((WritableDoubleDataStore) content).putDouble(id, val);
+ }
+ }
+
+ /**
+ * Delete an objects values.
+ *
+ * @param id ID to delete
+ */
+ @Override
+ public void delete(DBIDRef id) {
+ assert (!ids.contains(id));
+ if(content instanceof WritableDoubleDataStore) {
+ ((WritableDoubleDataStore) content).delete(id);
+ }
+ }
+
+ @Override
+ public StaticDBIDs getDBIDs() {
+ return ids;
+ }
+
+ @Override
+ public DBIDIter iterDBIDs() {
+ return ids.iter();
+ }
+
+ @Override
+ public int size() {
+ return ids.size();
+ }
+
+ @Override
+ public SimpleTypeInformation<Double> getDataTypeInformation() {
+ return TypeUtil.DOUBLE;
+ }
+
+ @Override
+ public String getLongName() {
+ return (name != null) ? name : "Double";
+ }
+
+ @Override
+ public String getShortName() {
+ return shortname;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/relation/MaterializedRelation.java b/src/de/lmu/ifi/dbs/elki/database/relation/MaterializedRelation.java
index 8df4a42b..6ad66b6e 100644
--- a/src/de/lmu/ifi/dbs/elki/database/relation/MaterializedRelation.java
+++ b/src/de/lmu/ifi/dbs/elki/database/relation/MaterializedRelation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.relation;
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
@@ -129,6 +129,7 @@ public class MaterializedRelation<O> extends AbstractHierarchicalResult implemen
/**
* Constructor.
+ *
* @param name Name
* @param shortname Short name of the result
* @param type Type information
@@ -198,10 +199,7 @@ public class MaterializedRelation<O> extends AbstractHierarchicalResult implemen
@Override
public String getLongName() {
- if(name != null) {
- return name;
- }
- return type.toString();
+ return (name != null) ? name : type.toString();
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/database/relation/ProjectedView.java b/src/de/lmu/ifi/dbs/elki/database/relation/ProjectedView.java
index 252b651b..71fc25e4 100644
--- a/src/de/lmu/ifi/dbs/elki/database/relation/ProjectedView.java
+++ b/src/de/lmu/ifi/dbs/elki/database/relation/ProjectedView.java
@@ -12,7 +12,7 @@ import de.lmu.ifi.dbs.elki.result.AbstractHierarchicalResult;
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/database/relation/ProxyView.java b/src/de/lmu/ifi/dbs/elki/database/relation/ProxyView.java
index d6e12d60..56f349dc 100644
--- a/src/de/lmu/ifi/dbs/elki/database/relation/ProxyView.java
+++ b/src/de/lmu/ifi/dbs/elki/database/relation/ProxyView.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.relation;
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/database/relation/Relation.java b/src/de/lmu/ifi/dbs/elki/database/relation/Relation.java
index 9ac4e408..e6acea60 100644
--- a/src/de/lmu/ifi/dbs/elki/database/relation/Relation.java
+++ b/src/de/lmu/ifi/dbs/elki/database/relation/Relation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.relation;
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
@@ -37,6 +37,7 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
* @author Erich Schubert
*
* @apiviz.uses DBIDRef
+ * @apiviz.exclude TooltipStringVisualization
*
* @param <O> Object type
*/
@@ -96,7 +97,7 @@ public interface Relation<O> extends DatabaseQuery, HierarchicalResult {
* <pre>
* {@code
* for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
- * DBID id = iter.getDBID();
+ * relation.get(iter); // Get the current element
* }
* }
* </pre>
diff --git a/src/de/lmu/ifi/dbs/elki/database/relation/RelationUtil.java b/src/de/lmu/ifi/dbs/elki/database/relation/RelationUtil.java
index 662767b7..925af2c2 100644
--- a/src/de/lmu/ifi/dbs/elki/database/relation/RelationUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/database/relation/RelationUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.relation;
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,11 +23,19 @@ package de.lmu.ifi.dbs.elki.database.relation;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+
import de.lmu.ifi.dbs.elki.data.FeatureVector;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
+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.DBIDs;
/**
* Utility functions for handling database relation.
@@ -35,6 +43,8 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
* @author Erich Schubert
*
* @apiviz.uses Relation oneway
+ * @apiviz.has CollectionFromRelation
+ * @apiviz.has RelationObjectIterator
*/
public final class RelationUtil {
/**
@@ -54,7 +64,8 @@ public final class RelationUtil {
public static <V extends FeatureVector<?>> VectorFieldTypeInformation<V> assumeVectorField(Relation<V> relation) {
try {
return ((VectorFieldTypeInformation<V>) relation.getDataTypeInformation());
- } catch (Exception e) {
+ }
+ catch(Exception e) {
throw new UnsupportedOperationException("Expected a vector field, got type information: " + relation.getDataTypeInformation().toString(), e);
}
}
@@ -64,13 +75,12 @@ public final class RelationUtil {
*
* @param relation relation
* @param <V> Vector type
- * @param <N> Number type
* @return Vector field type information
*/
- public static <V extends NumberVector<? extends N>, N extends Number> NumberVector.Factory<V, N> getNumberVectorFactory(Relation<V> relation) {
+ public static <V extends NumberVector> NumberVector.Factory<V> getNumberVectorFactory(Relation<V> relation) {
final VectorFieldTypeInformation<V> type = assumeVectorField(relation);
@SuppressWarnings("unchecked")
- final NumberVector.Factory<V, N> factory = (NumberVector.Factory<V, N>) type.getFactory();
+ final NumberVector.Factory<V> factory = (NumberVector.Factory<V>) type.getFactory();
return factory;
}
@@ -83,12 +93,61 @@ public final class RelationUtil {
public static int dimensionality(Relation<? extends FeatureVector<?>> relation) {
try {
return ((VectorFieldTypeInformation<? extends FeatureVector<?>>) relation.getDataTypeInformation()).getDimensionality();
- } catch (Exception e) {
+ }
+ catch(Exception e) {
return -1;
}
}
/**
+ * Determines the minimum and maximum values in each dimension of all objects
+ * stored in the given database.
+ *
+ * @param relation the database storing the objects
+ * @return Minimum and Maximum vector for the hyperrectangle
+ */
+ public static double[][] computeMinMax(Relation<? extends NumberVector> relation) {
+ int dim = RelationUtil.dimensionality(relation);
+ double[] mins = new double[dim], maxs = new double[dim];
+ for(int i = 0; i < dim; i++) {
+ mins[i] = Double.MAX_VALUE;
+ maxs[i] = -Double.MAX_VALUE;
+ }
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ final NumberVector o = relation.get(iditer);
+ for(int d = 0; d < dim; d++) {
+ final double v = o.doubleValue(d);
+ mins[d] = (v < mins[d]) ? v : mins[d];
+ maxs[d] = (v > maxs[d]) ? v : maxs[d];
+ }
+ }
+ return new double[][] { mins, maxs };
+ }
+
+ /**
+ * Determines the variances in each dimension of the specified objects stored
+ * in the given database.
+ *
+ * @param database the database storing the objects
+ * @param ids the ids of the objects
+ * @param centroid the centroid or reference vector of the ids
+ * @return the variances in each dimension of the specified objects
+ */
+ public static double[] variances(Relation<? extends NumberVector> database, NumberVector centroid, DBIDs ids) {
+ final int size = ids.size();
+ double[] variances = new double[centroid.getDimensionality()];
+
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ NumberVector o = database.get(iter);
+ for(int d = 0; d < centroid.getDimensionality(); d++) {
+ final double diff = o.doubleValue(d) - centroid.doubleValue(d);
+ variances[d] += diff * diff / size;
+ }
+ }
+ return variances;
+ }
+
+ /**
* <em>Copy</em> a relation into a double matrix.
*
* This is <em>not recommended</em> unless you need to modify the data
@@ -98,15 +157,15 @@ public final class RelationUtil {
* @param ids IDs, with well-defined order (i.e. array)
* @return Data matrix
*/
- public static double[][] relationAsMatrix(final Relation<? extends NumberVector<?>> relation, ArrayDBIDs ids) {
+ public static double[][] relationAsMatrix(final Relation<? extends NumberVector> relation, ArrayDBIDs ids) {
final int rowdim = ids.size();
final int coldim = dimensionality(relation);
double[][] mat = new double[rowdim][coldim];
int r = 0;
- for (DBIDArrayIter iter = ids.iter(); iter.valid(); iter.advance(), r++) {
- NumberVector<?> vec = relation.get(iter);
+ for(DBIDArrayIter iter = ids.iter(); iter.valid(); iter.advance(), r++) {
+ NumberVector vec = relation.get(iter);
double[] row = mat[r];
- for (int c = 0; c < coldim; c++) {
+ for(int c = 0; c < coldim; c++) {
row[c] = vec.doubleValue(c);
}
}
@@ -124,10 +183,171 @@ public final class RelationUtil {
*/
public static <V extends FeatureVector<?>> String getColumnLabel(Relation<? extends V> rel, int col) {
String lbl = assumeVectorField(rel).getLabel(col);
- if (lbl != null) {
+ if(lbl != null) {
return lbl;
- } else {
+ }
+ else {
return "Column " + col;
}
}
+
+ /**
+ * An ugly vector type cast unavoidable in some situations due to Generics.
+ *
+ * @param <V> Base vector type
+ * @param <T> Derived vector type (is actually V, too)
+ * @param database Database
+ * @return Database
+ */
+ @SuppressWarnings("unchecked")
+ public static <V extends NumberVector, T extends NumberVector> Relation<V> relationUglyVectorCast(Relation<T> database) {
+ return (Relation<V>) database;
+ }
+
+ /**
+ * Iterator class that retrieves the given objects from the database.
+ *
+ * @author Erich Schubert
+ */
+ public static class RelationObjectIterator<O> implements Iterator<O> {
+ /**
+ * The real iterator.
+ */
+ final DBIDIter iter;
+
+ /**
+ * The database we use.
+ */
+ final Relation<? extends O> database;
+
+ /**
+ * Full Constructor.
+ *
+ * @param iter Original iterator.
+ * @param database Database
+ */
+ public RelationObjectIterator(DBIDIter iter, Relation<? extends O> database) {
+ super();
+ this.iter = iter;
+ this.database = database;
+ }
+
+ /**
+ * Simplified constructor.
+ *
+ * @param database Database
+ */
+ public RelationObjectIterator(Relation<? extends O> database) {
+ super();
+ this.database = database;
+ this.iter = database.iterDBIDs();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return iter.valid();
+ }
+
+ @Override
+ public O next() {
+ O ret = database.get(iter);
+ iter.advance();
+ return ret;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Collection view on a database that retrieves the objects when needed.
+ *
+ * @author Erich Schubert
+ */
+ public static class CollectionFromRelation<O> extends AbstractCollection<O> implements Collection<O> {
+ /**
+ * The database we query.
+ */
+ Relation<? extends O> db;
+
+ /**
+ * Constructor.
+ *
+ * @param db Database
+ */
+ public CollectionFromRelation(Relation<? extends O> db) {
+ super();
+ this.db = db;
+ }
+
+ @Override
+ public Iterator<O> iterator() {
+ return new RelationObjectIterator<>(db);
+ }
+
+ @Override
+ public int size() {
+ return db.size();
+ }
+ }
+
+ /**
+ * Sort objects by a double relation
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class AscendingByDoubleRelation implements Comparator<DBIDRef> {
+ /**
+ * Scores to use for sorting.
+ */
+ private final DoubleRelation scores;
+
+ /**
+ * Constructor.
+ *
+ * @param scores Scores for sorting
+ */
+ public AscendingByDoubleRelation(DoubleRelation scores) {
+ super();
+ this.scores = scores;
+ }
+
+ @Override
+ public int compare(DBIDRef id1, DBIDRef id2) {
+ return Double.compare(scores.doubleValue(id1), scores.doubleValue(id2));
+ }
+ }
+
+ /**
+ * Sort objects by a double relation
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class DescendingByDoubleRelation implements Comparator<DBIDRef> {
+ /**
+ * Scores to use for sorting.
+ */
+ private final DoubleRelation scores;
+
+ /**
+ * Constructor.
+ *
+ * @param scores Scores for sorting
+ */
+ public DescendingByDoubleRelation(DoubleRelation scores) {
+ super();
+ this.scores = scores;
+ }
+
+ @Override
+ public int compare(DBIDRef id1, DBIDRef id2) {
+ return Double.compare(scores.doubleValue(id2), scores.doubleValue(id1));
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/relation/package-info.java b/src/de/lmu/ifi/dbs/elki/database/relation/package-info.java
index 133d6574..396c41f0 100644
--- a/src/de/lmu/ifi/dbs/elki/database/relation/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/database/relation/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/datasource/AbstractDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/AbstractDatabaseConnection.java
index 77cdb12c..9da9a550 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/AbstractDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/AbstractDatabaseConnection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource;
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 java.util.List;
import de.lmu.ifi.dbs.elki.datasource.bundle.BundleStreamSource;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
-import de.lmu.ifi.dbs.elki.datasource.bundle.StreamFromBundle;
import de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter;
import de.lmu.ifi.dbs.elki.datasource.filter.StreamFilter;
import de.lmu.ifi.dbs.elki.datasource.parser.Parser;
@@ -73,83 +72,50 @@ public abstract class AbstractDatabaseConnection implements DatabaseConnection {
* @param bundle the objects to process
* @return processed objects
*/
- protected MultipleObjectsBundle invokeFilters(MultipleObjectsBundle bundle) {
- BundleStreamSource prevs = null;
- MultipleObjectsBundle prevb = bundle;
- if(filters != null) {
- for(ObjectFilter filter : filters) {
- if(filter instanceof StreamFilter) {
- StreamFilter sfilter = (StreamFilter) filter;
- if(prevs != null) {
- sfilter.init(prevs);
- }
- else {
- sfilter.init(new StreamFromBundle(prevb));
- }
- prevs = sfilter;
- prevb = null;
- }
- else {
- if(prevs != null) {
- prevb = filter.filter(MultipleObjectsBundle.fromStream(prevs));
- prevs = null;
- }
- else {
- prevb = filter.filter(prevb);
- prevs = null;
- }
- }
- }
- }
- if(prevb != null) {
- return prevb;
+ protected MultipleObjectsBundle invokeBundleFilters(MultipleObjectsBundle bundle) {
+ if(filters == null) {
+ return bundle;
}
- else {
- return MultipleObjectsBundle.fromStream(prevs);
+ // We dynamically switch between streaming and bundle operations.
+ BundleStreamSource stream = null;
+ for(ObjectFilter filter : filters) {
+ if(filter instanceof StreamFilter) {
+ StreamFilter sfilter = (StreamFilter) filter;
+ stream = sfilter.init((stream != null) ? stream : bundle.asStream());
+ bundle = null; // No longer a bundle
+ }
+ else {
+ bundle = filter.filter((bundle != null) ? bundle : stream.asMultipleObjectsBundle());
+ stream = null; // No longer a stream
+ }
}
+ return (bundle != null) ? bundle : stream.asMultipleObjectsBundle();
}
/**
* Transforms the specified list of objects and their labels into a list of
* objects and their associations.
*
- * @param bundle the objects to process
+ * @param stream the objects to process
* @return processed objects
*/
- protected BundleStreamSource invokeFilters(BundleStreamSource bundle) {
- BundleStreamSource prevs = bundle;
- MultipleObjectsBundle prevb = null;
- if(filters != null) {
- for(ObjectFilter filter : filters) {
- if(filter instanceof StreamFilter) {
- StreamFilter sfilter = (StreamFilter) filter;
- if(prevs != null) {
- sfilter.init(prevs);
- }
- else {
- sfilter.init(new StreamFromBundle(prevb));
- }
- prevs = sfilter;
- prevb = null;
- }
- else {
- if(prevs != null) {
- prevb = filter.filter(MultipleObjectsBundle.fromStream(prevs));
- prevs = null;
- }
- else {
- prevb = filter.filter(prevb);
- prevs = null;
- }
- }
- }
- }
- if(prevs != null) {
- return prevs;
+ protected BundleStreamSource invokeStreamFilters(BundleStreamSource stream) {
+ if(filters == null) {
+ return stream;
}
- else {
- return new StreamFromBundle(prevb);
+ // We dynamically switch between streaming and bundle operations.
+ MultipleObjectsBundle bundle = null;
+ for(ObjectFilter filter : filters) {
+ if(filter instanceof StreamFilter) {
+ stream = ((StreamFilter) filter).init((stream != null) ? stream : bundle.asStream());
+ bundle = null;
+ }
+ else {
+ bundle = filter.filter((bundle != null) ? bundle : stream.asMultipleObjectsBundle());
+ stream = null;
+ }
}
+ return (stream != null) ? stream : bundle.asStream();
}
/**
@@ -187,7 +153,7 @@ public abstract class AbstractDatabaseConnection implements DatabaseConnection {
* Filters
*/
protected List<ObjectFilter> filters;
-
+
/**
* Parser to use
*/
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/ArrayAdapterDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/ArrayAdapterDatabaseConnection.java
index 1779f851..244033c2 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/ArrayAdapterDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/ArrayAdapterDatabaseConnection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource;
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,8 +31,7 @@ import de.lmu.ifi.dbs.elki.data.DoubleVector;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
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.ids.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
@@ -97,11 +96,7 @@ public class ArrayAdapterDatabaseConnection implements DatabaseConnection {
public MultipleObjectsBundle loadData() {
MultipleObjectsBundle b = new MultipleObjectsBundle();
if(startid != null) {
- List<DBID> ids = new ArrayList<>(data.length);
- for(int i = 0; i < data.length; i++) {
- ids.add(DBIDUtil.importInteger(startid.intValue() + i));
- }
- b.appendColumn(TypeUtil.DBID, Arrays.asList(labels));
+ b.setDBIDs(DBIDFactory.FACTORY.generateStaticDBIDRange(startid, data.length));
}
int mind = Integer.MAX_VALUE;
@@ -112,13 +107,7 @@ public class ArrayAdapterDatabaseConnection implements DatabaseConnection {
maxd = Math.max(maxd, data[i].length);
vecs.add(new DoubleVector(data[i]));
}
- SimpleTypeInformation<DoubleVector> type;
- if(mind == maxd) {
- type = new VectorFieldTypeInformation<>(DoubleVector.FACTORY, mind);
- }
- else {
- type = new SimpleTypeInformation<>(DoubleVector.class);
- }
+ SimpleTypeInformation<DoubleVector> type = new VectorFieldTypeInformation<>(DoubleVector.FACTORY, mind, maxd, DoubleVector.FACTORY.getDefaultSerializer());
b.appendColumn(type, vecs);
if(labels != null) {
if(labels.length != data.length) {
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/BundleDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/BundleDatabaseConnection.java
index c8821bc9..7407bf55 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/BundleDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/BundleDatabaseConnection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource;
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,6 @@ import java.nio.channels.FileChannel;
import java.util.List;
import de.lmu.ifi.dbs.elki.datasource.bundle.BundleReader;
-import de.lmu.ifi.dbs.elki.datasource.bundle.BundleStreamSource;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
import de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter;
import de.lmu.ifi.dbs.elki.logging.Logging;
@@ -47,7 +46,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
*
* @author Erich Schubert
*
- * @apiviz.composedOf BundleStreamSource
+ * @apiviz.composedOf BundleStreamSource
*/
public class BundleDatabaseConnection extends AbstractDatabaseConnection {
/**
@@ -76,12 +75,12 @@ public class BundleDatabaseConnection extends AbstractDatabaseConnection {
try {
FileInputStream fis = new FileInputStream(infile);
FileChannel channel = fis.getChannel();
- BundleStreamSource src = invokeFilters(new BundleReader(channel));
- MultipleObjectsBundle bundle = MultipleObjectsBundle.fromStream(src);
+ MultipleObjectsBundle bundle = invokeStreamFilters(new BundleReader(channel)).asMultipleObjectsBundle();
channel.close();
fis.close();
return bundle;
- } catch (IOException e) {
+ }
+ catch(IOException e) {
throw new AbortException("IO error loading bundle", e);
}
}
@@ -114,7 +113,7 @@ public class BundleDatabaseConnection extends AbstractDatabaseConnection {
super.makeOptions(config);
configFilters(config);
FileParameter infileP = new FileParameter(BUNDLE_ID, FileParameter.FileType.INPUT_FILE);
- if (config.grab(infileP)) {
+ if(config.grab(infileP)) {
infile = infileP.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/ConcatenateFilesDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/ConcatenateFilesDatabaseConnection.java
index 22aadc08..110e131a 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/ConcatenateFilesDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/ConcatenateFilesDatabaseConnection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource;
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
@@ -36,7 +36,6 @@ import de.lmu.ifi.dbs.elki.datasource.bundle.BundleMeta;
import de.lmu.ifi.dbs.elki.datasource.bundle.BundleStreamSource;
import de.lmu.ifi.dbs.elki.datasource.bundle.BundleStreamSource.Event;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
-import de.lmu.ifi.dbs.elki.datasource.bundle.StreamFromBundle;
import de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter;
import de.lmu.ifi.dbs.elki.datasource.parser.NumberVectorLabelParser;
import de.lmu.ifi.dbs.elki.datasource.parser.Parser;
@@ -86,35 +85,37 @@ public class ConcatenateFilesDatabaseConnection extends AbstractDatabaseConnecti
public MultipleObjectsBundle loadData() {
MultipleObjectsBundle objects = new MultipleObjectsBundle();
objects.appendColumn(TypeUtil.STRING, new ArrayList<>());
- for (File file : files) {
+ for(File file : files) {
String filestr = file.getPath();
try {
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
inputStream = FileUtil.tryGzipInput(inputStream);
final BundleStreamSource source;
- if (parser instanceof StreamingParser) {
+ if(parser instanceof StreamingParser) {
final StreamingParser streamParser = (StreamingParser) parser;
streamParser.initStream(inputStream);
source = streamParser;
- } else {
+ }
+ else {
MultipleObjectsBundle parsingResult = parser.parse(inputStream);
// normalize objects and transform labels
- source = new StreamFromBundle(parsingResult);
+ source = parsingResult.asStream();
}
BundleMeta meta = null; // NullPointerException on invalid streams
- loop: for (Event e = source.nextEvent();; e = source.nextEvent()) {
- switch(e) {
+ loop: for(Event e = source.nextEvent();; e = source.nextEvent()) {
+ switch(e){
case END_OF_STREAM:
break loop;
case META_CHANGED:
meta = source.getMeta();
- for (int i = 0; i < meta.size(); i++) {
- if (i + 1 >= objects.metaLength()) {
+ for(int i = 0; i < meta.size(); i++) {
+ if(i + 1 >= objects.metaLength()) {
objects.appendColumn(meta.get(i), new ArrayList<>());
- } else {
+ }
+ else {
// Ensure compatibility:
- if (!objects.meta(i + 1).isAssignableFromType(meta.get(i))) {
+ if(!objects.meta(i + 1).isAssignableFromType(meta.get(i))) {
throw new AbortException("Incompatible files loaded. Cannot concatenate with unaligned columns, please preprocess manually.");
}
}
@@ -123,22 +124,24 @@ public class ConcatenateFilesDatabaseConnection extends AbstractDatabaseConnecti
case NEXT_OBJECT:
Object[] o = new Object[objects.metaLength()];
o[0] = filestr;
- for (int i = 0; i < meta.size(); i++) {
+ for(int i = 0; i < meta.size(); i++) {
o[i + 1] = source.data(i);
}
objects.appendSimple(o);
break; // switch
}
}
- } catch (IOException e) {
+ }
+ catch(IOException e) {
throw new AbortException("Loading file " + filestr + " failed: " + e.toString(), e);
}
}
+ parser.cleanup();
// Invoke filters
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
LOG.debugFine("Invoking filters.");
}
- return invokeFilters(objects);
+ return invokeBundleFilters(objects);
}
@Override
@@ -163,7 +166,7 @@ public class ConcatenateFilesDatabaseConnection extends AbstractDatabaseConnecti
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
FileListParameter filesP = new FileListParameter(FileBasedDatabaseConnection.Parameterizer.INPUT_ID, FilesType.INPUT_FILES);
- if (config.grab(filesP)) {
+ if(config.grab(filesP)) {
files = filesP.getValue();
}
configFilters(config);
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/DBIDRangeDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/DBIDRangeDatabaseConnection.java
index 2e7f59e7..2883a008 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/DBIDRangeDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/DBIDRangeDatabaseConnection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource;
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,7 @@ package de.lmu.ifi.dbs.elki.datasource;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.ArrayList;
-import java.util.List;
-
-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.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -70,11 +65,7 @@ public class DBIDRangeDatabaseConnection implements DatabaseConnection {
@Override
public MultipleObjectsBundle loadData() {
MultipleObjectsBundle b = new MultipleObjectsBundle();
- List<DBID> ids = new ArrayList<>(count);
- for(int i = 0; i < count; i++) {
- ids.add(DBIDUtil.importInteger(start + i));
- }
- b.appendColumn(TypeUtil.DBID, ids);
+ b.setDBIDs(DBIDFactory.FACTORY.generateStaticDBIDRange(start, count));
return b;
}
@@ -109,13 +100,13 @@ public class DBIDRangeDatabaseConnection implements DatabaseConnection {
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- IntParameter startp = new IntParameter(START_ID, Integer.valueOf(0));
+ IntParameter startp = new IntParameter(START_ID, 0);
if(config.grab(startp)) {
- start = startp.getValue().intValue();
+ start = startp.intValue();
}
IntParameter countp = new IntParameter(COUNT_ID);
if(config.grab(countp)) {
- count = countp.getValue().intValue();
+ count = countp.intValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/DatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/DatabaseConnection.java
index 6fe3ae39..ac6718c7 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/DatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/DatabaseConnection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource;
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.datasource;
*/
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* DatabaseConnection is used to load data into a database.
@@ -39,7 +38,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
* @apiviz.landmark
* @apiviz.has MultipleObjectsBundle
*/
-public interface DatabaseConnection extends Parameterizable {
+public interface DatabaseConnection {
/**
* Returns the initial data for a database.
*
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/EmptyDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/EmptyDatabaseConnection.java
index 70b1da50..1c6e7566 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/EmptyDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/EmptyDatabaseConnection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource;
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/datasource/ExternalIDJoinDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/ExternalIDJoinDatabaseConnection.java
index 38aefaca..509a6c28 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/ExternalIDJoinDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/ExternalIDJoinDatabaseConnection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource;
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
@@ -37,7 +37,6 @@ import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParameter;
@@ -48,7 +47,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParamet
*
* @apiviz.uses ExternalID
*/
-public class ExternalIDJoinDatabaseConnection extends AbstractDatabaseConnection implements Parameterizable {
+public class ExternalIDJoinDatabaseConnection extends AbstractDatabaseConnection {
/**
* Logger
*/
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/FileBasedDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/FileBasedDatabaseConnection.java
index f2ced700..300b34d2 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/FileBasedDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/FileBasedDatabaseConnection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource;
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
@@ -39,7 +39,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
/**
- * Provides a file based database connection based on the parser to be set.
+ * File based database connection based on the parser to be set.
*
* @author Arthur Zimek
*
@@ -51,7 +51,41 @@ public class FileBasedDatabaseConnection extends InputStreamDatabaseConnection {
*
* @param filters Filters, can be null
* @param parser the parser to provide a database
- * @param in the input stream to parse from.
+ * @param infile File to load the data from
+ */
+ public FileBasedDatabaseConnection(List<ObjectFilter> filters, Parser parser, File infile) {
+ super(filters, parser);
+ try {
+ this.in = new BufferedInputStream(FileUtil.tryGzipInput(new FileInputStream(infile)));
+ }
+ catch(IOException e) {
+ throw new AbortException("Could not load input file: " + infile, e);
+ }
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param filters Filters, can be null
+ * @param parser the parser to provide a database
+ * @param infile File to load the data from
+ */
+ public FileBasedDatabaseConnection(List<ObjectFilter> filters, Parser parser, String infile) {
+ super(filters, parser);
+ try {
+ this.in = new BufferedInputStream(FileUtil.tryGzipInput(new FileInputStream(infile)));
+ }
+ catch(IOException e) {
+ throw new AbortException("Could not load input file: " + infile, e);
+ }
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param filters Filters, can be null
+ * @param parser the parser to provide a database
+ * @param in Input stream
*/
public FileBasedDatabaseConnection(List<ObjectFilter> filters, Parser parser, InputStream in) {
super(filters, parser);
@@ -91,12 +125,7 @@ public class FileBasedDatabaseConnection extends InputStreamDatabaseConnection {
@Override
protected FileBasedDatabaseConnection makeInstance() {
- try {
- return new FileBasedDatabaseConnection(filters, parser, new BufferedInputStream(FileUtil.tryGzipInput(new FileInputStream(infile))));
- }
- catch(IOException e) {
- throw new AbortException("Input file could not be opened.", e);
- }
+ return new FileBasedDatabaseConnection(filters, parser, infile);
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/GeneratorXMLDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/GeneratorXMLDatabaseConnection.java
index 57bfd6bc..2c3e2019 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/GeneratorXMLDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/GeneratorXMLDatabaseConnection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource;
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/datasource/InputStreamDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/InputStreamDatabaseConnection.java
index 0e99b421..21439807 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/InputStreamDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/InputStreamDatabaseConnection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource;
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
@@ -38,8 +38,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
/**
- * Provides a database connection expecting input from an input stream such as
- * stdin.
+ * Database connection expecting input from an input stream such as stdin.
*
* @author Arthur Zimek
*
@@ -80,48 +79,39 @@ public class InputStreamDatabaseConnection extends AbstractDatabaseConnection {
if(LOG.isDebugging()) {
LOG.debugFine("Invoking parsers.");
}
+ // Streaming parsers may yield to stream filters immediately.
if(parser instanceof StreamingParser) {
- final StreamingParser streamParser = (StreamingParser)parser;
+ final StreamingParser streamParser = (StreamingParser) parser;
streamParser.initStream(in);
-
// normalize objects and transform labels
if(LOG.isDebugging()) {
- LOG.debugFine("Invoking filters.");
- }
- Duration duration = LOG.isStatistics() ? LOG.newDuration(this.getClass().getName() + ".load") : null;
- if (duration != null) {
- duration.begin();
+ LOG.debugFine("Parsing as stream.");
}
- MultipleObjectsBundle objects = MultipleObjectsBundle.fromStream(invokeFilters(streamParser));
- if (duration != null) {
- duration.end();
- LOG.statistics(duration);
+ Duration duration = LOG.isStatistics() ? LOG.newDuration(this.getClass().getName() + ".load").begin() : null;
+ MultipleObjectsBundle objects = invokeStreamFilters(streamParser).asMultipleObjectsBundle();
+ parser.cleanup();
+ if(duration != null) {
+ LOG.statistics(duration.end());
}
return objects;
}
else {
- Duration duration = LOG.isStatistics() ? LOG.newDuration(this.getClass().getName() + ".parse") : null;
- if (duration != null) {
- duration.begin();
- }
+ // For non-streaming parsers, we first parse, then filter
+ Duration duration = LOG.isStatistics() ? LOG.newDuration(this.getClass().getName() + ".parse").begin() : null;
MultipleObjectsBundle parsingResult = parser.parse(in);
- if (duration != null) {
- duration.end();
- LOG.statistics(duration);
+ parser.cleanup();
+ if(duration != null) {
+ LOG.statistics(duration.end());
}
// normalize objects and transform labels
if(LOG.isDebugging()) {
LOG.debugFine("Invoking filters.");
}
- Duration fduration = LOG.isStatistics() ? LOG.newDuration(this.getClass().getName() + ".filter") : null;
- if (fduration != null) {
- fduration.begin();
- }
- MultipleObjectsBundle objects = invokeFilters(parsingResult);
- if (fduration != null) {
- fduration.end();
- LOG.statistics(fduration);
+ Duration fduration = LOG.isStatistics() ? LOG.newDuration(this.getClass().getName() + ".filter").begin() : null;
+ MultipleObjectsBundle objects = invokeBundleFilters(parsingResult);
+ if(fduration != null) {
+ LOG.statistics(fduration.end());
}
return objects;
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/LabelJoinDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/LabelJoinDatabaseConnection.java
index fc28b989..de581230 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/LabelJoinDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/LabelJoinDatabaseConnection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource;
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
@@ -37,7 +37,6 @@ import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParameter;
@@ -48,7 +47,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParamet
*
* @apiviz.uses LabelList
*/
-public class LabelJoinDatabaseConnection extends AbstractDatabaseConnection implements Parameterizable {
+public class LabelJoinDatabaseConnection extends AbstractDatabaseConnection {
/**
* Logger
*/
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/MultipleObjectsBundleDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/MultipleObjectsBundleDatabaseConnection.java
new file mode 100644
index 00000000..202d1871
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/MultipleObjectsBundleDatabaseConnection.java
@@ -0,0 +1,54 @@
+package de.lmu.ifi.dbs.elki.datasource;
+
+/*
+ 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.datasource.bundle.MultipleObjectsBundle;
+
+/**
+ * Data source to feed a precomputed {@link MultipleObjectsBundle} into a
+ * database.
+ *
+ * @author Erich Schubert
+ */
+public class MultipleObjectsBundleDatabaseConnection implements DatabaseConnection {
+ /**
+ * Bundle.
+ */
+ MultipleObjectsBundle bundle;
+
+ /**
+ * Constructor.
+ *
+ * @param bundle Existing bundle.
+ */
+ public MultipleObjectsBundleDatabaseConnection(MultipleObjectsBundle bundle) {
+ super();
+ this.bundle = bundle;
+ }
+
+ @Override
+ public MultipleObjectsBundle loadData() {
+ return bundle;
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/PresortedBlindJoinDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/PresortedBlindJoinDatabaseConnection.java
index 4f52f5f2..b51a23df 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/PresortedBlindJoinDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/PresortedBlindJoinDatabaseConnection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource;
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,7 +32,6 @@ import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParameter;
@@ -43,7 +42,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParamet
* @author Erich Schubert
*/
@Description("Blindly joins multiple data sources, assuming they are ordered the same way.")
-public class PresortedBlindJoinDatabaseConnection extends AbstractDatabaseConnection implements Parameterizable {
+public class PresortedBlindJoinDatabaseConnection extends AbstractDatabaseConnection {
/**
* Logger
*/
@@ -84,7 +83,7 @@ public class PresortedBlindJoinDatabaseConnection extends AbstractDatabaseConnec
}
}
- return invokeFilters(first);
+ return invokeBundleFilters(first);
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/RandomDoubleVectorDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/RandomDoubleVectorDatabaseConnection.java
index 2f3a943b..29d7f2d7 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/RandomDoubleVectorDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/RandomDoubleVectorDatabaseConnection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource;
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
@@ -33,7 +33,7 @@ import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
import de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter;
import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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.IntParameter;
@@ -154,11 +154,11 @@ public class RandomDoubleVectorDatabaseConnection extends AbstractDatabaseConnec
configFilters(config);
IntParameter dimParam = new IntParameter(DIM_ID);
if(config.grab(dimParam)) {
- dim = dimParam.getValue().intValue();
+ dim = dimParam.intValue();
}
IntParameter sizeParam = new IntParameter(SIZE_ID);
if(config.grab(sizeParam)) {
- size = sizeParam.getValue().intValue();
+ size = sizeParam.intValue();
}
RandomParameter rndP = new RandomParameter(SEED_ID);
if(config.grab(rndP)) {
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleMeta.java b/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleMeta.java
index 442c00e8..7b148f3c 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleMeta.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleMeta.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.bundle;
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/datasource/bundle/BundleReader.java b/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleReader.java
index 4f57cac8..da72ac1b 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleReader.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleReader.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.bundle;
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,13 +26,15 @@ import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
-import java.util.ArrayList;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeInformationSerializer;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
+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.DBIDVar;
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.io.ByteBufferSerializer;
/**
* Read an ELKI bundle file into a data stream.
@@ -41,7 +43,8 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
*
* @author Erich Schubert
*
- * @apiviz.uses FileChannel
+ * @apiviz.uses MappedByteBuffer - - «reads»
+ * @apiviz.uses FileChannel - - «reads»
*/
public class BundleReader implements BundleStreamSource {
/**
@@ -52,7 +55,7 @@ public class BundleReader implements BundleStreamSource {
/**
* The stream buffer.
*/
- MappedByteBuffer buffer;
+ MappedByteBuffer buffer = null;
/**
* Bundle metadata.
@@ -62,17 +65,33 @@ public class BundleReader implements BundleStreamSource {
/**
* Input channel.
*/
- FileChannel input;
+ FileChannel input = null;
/**
* Serializers to use.
*/
- ArrayList<ByteBufferSerializer<?>> sers;
+ ByteBufferSerializer<?>[] sers;
/**
* Current object.
*/
- ArrayList<Object> data;
+ Object[] data;
+
+ /**
+ * Whether or not we have DBIDs.
+ */
+ boolean hasids = false;
+
+ /**
+ * Constructor.
+ *
+ * @param buffer Input buffer
+ */
+ public BundleReader(MappedByteBuffer buffer) {
+ super();
+ this.buffer = buffer;
+ this.input = null;
+ }
/**
* Constructor.
@@ -86,7 +105,7 @@ public class BundleReader implements BundleStreamSource {
@Override
public BundleMeta getMeta() {
- if (meta == null) {
+ if(meta == null) {
openBuffer();
readMeta();
}
@@ -97,10 +116,13 @@ public class BundleReader implements BundleStreamSource {
* Map the input file.
*/
void openBuffer() {
- try {
- buffer = input.map(MapMode.READ_ONLY, 0, input.size());
- } catch (IOException e) {
- throw new AbortException("Cannot map input bundle.", e);
+ if(buffer == null) {
+ try {
+ buffer = input.map(MapMode.READ_ONLY, 0, input.size());
+ }
+ catch(IOException e) {
+ throw new AbortException("Cannot map input bundle.", e);
+ }
}
}
@@ -109,23 +131,30 @@ public class BundleReader implements BundleStreamSource {
*/
void readMeta() {
final int check = buffer.getInt();
- if (check != MAGIC) {
+ if(check != MAGIC) {
throw new AbortException("File does not start with expected magic.");
}
final int nummeta = buffer.getInt();
- assert (nummeta > 0);
+ assert (nummeta > 0) : "Empty bundle?";
meta = new BundleMeta(nummeta);
- sers = new ArrayList<>(nummeta);
- data = new ArrayList<>(nummeta);
- for (int i = 0; i < nummeta; i++) {
+ sers = new ByteBufferSerializer<?>[nummeta];
+ data = new Object[nummeta];
+ for(int i = 0; i < nummeta; i++) {
try {
@SuppressWarnings("unchecked")
SimpleTypeInformation<? extends Object> type = (SimpleTypeInformation<? extends Object>) TypeInformationSerializer.STATIC.fromByteBuffer(buffer);
- meta.add(type);
- sers.add(type.getSerializer());
- } catch (UnsupportedOperationException e) {
- throw new AbortException("Deserialization failed: "+e.getMessage(), e);
- } catch (IOException e) {
+ sers[i] = type.getSerializer();
+ if(i == 0 && TypeUtil.DBID.isAssignableFromType(type)) {
+ hasids = true;
+ }
+ else {
+ meta.add(type);
+ }
+ }
+ catch(UnsupportedOperationException e) {
+ throw new AbortException("Deserialization failed: " + e.getMessage(), e);
+ }
+ catch(IOException e) {
throw new AbortException("IO error", e);
}
}
@@ -135,13 +164,14 @@ public class BundleReader implements BundleStreamSource {
* Read an object.
*/
void readObject() {
- data.clear();
- for (ByteBufferSerializer<?> ser : sers) {
+ for(int i = 0; i < sers.length; ++i) {
try {
- data.add(ser.fromByteBuffer(buffer));
- } catch (UnsupportedOperationException e) {
+ data[i] = sers[i].fromByteBuffer(buffer);
+ }
+ catch(UnsupportedOperationException e) {
throw new AbortException("Deserialization failed.", e);
- } catch (IOException e) {
+ }
+ catch(IOException e) {
throw new AbortException("IO error", e);
}
}
@@ -150,10 +180,10 @@ public class BundleReader implements BundleStreamSource {
@Override
public Event nextEvent() {
// Send initial meta
- if (meta == null) {
+ if(meta == null) {
return Event.META_CHANGED;
}
- if (buffer.remaining() == 0) {
+ if(buffer.remaining() == 0) {
ByteArrayUtil.unmapByteBuffer(buffer);
return Event.END_OF_STREAM;
}
@@ -163,6 +193,25 @@ public class BundleReader implements BundleStreamSource {
@Override
public Object data(int rnum) {
- return data.get(rnum);
+ return data[!hasids ? rnum : (rnum + 1)];
+ }
+
+ @Override
+ public boolean hasDBIDs() {
+ return hasids;
+ }
+
+ @Override
+ public boolean assignDBID(DBIDVar var) {
+ if(!hasids) {
+ return false;
+ }
+ var.set((DBID) data[0]);
+ return true;
+ }
+
+ @Override
+ public MultipleObjectsBundle asMultipleObjectsBundle() {
+ return MultipleObjectsBundle.fromStream(this);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleStreamSource.java b/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleStreamSource.java
index cbac6134..bffbd6a0 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleStreamSource.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleStreamSource.java
@@ -1,10 +1,12 @@
package de.lmu.ifi.dbs.elki.datasource.bundle;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
+
/*
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,14 +31,13 @@ package de.lmu.ifi.dbs.elki.datasource.bundle;
* @author Erich Schubert
*
* @apiviz.composedOf BundleMeta
+ * @apiviz.has BundleStreamSource.Event
*/
public interface BundleStreamSource {
/**
* Events
*
* @author Erich Schubert
- *
- * @apiviz.exclude
*/
public static enum Event {
// Metadata has changed
@@ -63,9 +64,31 @@ public interface BundleStreamSource {
public Object data(int rnum);
/**
+ * Indicate whether the stream contains DBIDs.
+ *
+ * @return {@code true} if the stream contains DBIDs.
+ */
+ public boolean hasDBIDs();
+
+ /**
+ * Assign the current object ID to a {@link DBIDVar}.
+ *
+ * @param var Variable to assign the object id to
+ * @return {@code false} when no object id is available
+ */
+ public boolean assignDBID(DBIDVar var);
+
+ /**
* Get the next event
*
* @return Event type
*/
public Event nextEvent();
+
+ /**
+ * Return (or collect) the stream as bundle.
+ *
+ * @return Bundle
+ */
+ public MultipleObjectsBundle asMultipleObjectsBundle();
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleWriter.java b/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleWriter.java
index 4b7c4a3d..dbad6794 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleWriter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleWriter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.bundle;
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,9 +29,13 @@ import java.nio.channels.WritableByteChannel;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeInformationSerializer;
+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.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
/**
* Write an object bundle stream to a file channel.
@@ -40,8 +44,8 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
*
* @author Erich Schubert
*
- * @apiviz.uses BundleStreamSource
- * @apiviz.uses WritableByteChannel
+ * @apiviz.uses BundleStreamSource - - «reads»
+ * @apiviz.uses WritableByteChannel - - «writes»
*/
public class BundleWriter {
/**
@@ -69,22 +73,36 @@ public class BundleWriter {
public void writeBundleStream(BundleStreamSource source, WritableByteChannel output) throws IOException {
ByteBuffer buffer = ByteBuffer.allocateDirect(INITIAL_BUFFER);
- ByteBufferSerializer<Object>[] serializers = null;
- loop: while (true) {
+ DBIDVar var = DBIDUtil.newVar();
+ ByteBufferSerializer<?>[] serializers = null;
+ loop: while(true) {
BundleStreamSource.Event ev = source.nextEvent();
- switch(ev) {
+ switch(ev){
case NEXT_OBJECT:
- if (serializers == null) {
+ if(serializers == null) {
serializers = writeHeader(source, buffer, output);
}
- for (int i = 0; i < serializers.length; i++) {
- int size = serializers[i].getByteSize(source.data(i));
+ if(serializers[0] != null) {
+ if(!source.assignDBID(var)) {
+ throw new AbortException("An object did not have an DBID assigned.");
+ }
+ DBID id = DBIDUtil.deref(var);
+ @SuppressWarnings("unchecked")
+ ByteBufferSerializer<DBID> ser = (ByteBufferSerializer<DBID>) serializers[0];
+ int size = ser.getByteSize(id);
buffer = ensureBuffer(size, buffer, output);
- serializers[i].toByteBuffer(buffer, source.data(i));
+ ser.toByteBuffer(buffer, id);
+ }
+ for(int i = 1, j = 0; i < serializers.length; ++i, ++j) {
+ @SuppressWarnings("unchecked")
+ ByteBufferSerializer<Object> ser = (ByteBufferSerializer<Object>) serializers[i];
+ int size = ser.getByteSize(source.data(j));
+ buffer = ensureBuffer(size, buffer, output);
+ ser.toByteBuffer(buffer, source.data(j));
}
break; // switch
case META_CHANGED:
- if (serializers != null) {
+ if(serializers != null) {
throw new AbortException("Meta changes are not supported, once the block header has been written.");
}
break; // switch
@@ -95,7 +113,7 @@ public class BundleWriter {
break; // switch
}
}
- if (buffer.position() > 0) {
+ if(buffer.position() > 0) {
flushBuffer(buffer, output);
}
}
@@ -124,11 +142,11 @@ public class BundleWriter {
* @throws IOException on IO errors
*/
private ByteBuffer ensureBuffer(int size, ByteBuffer buffer, WritableByteChannel output) throws IOException {
- if (buffer.remaining() >= size) {
+ if(buffer.remaining() >= size) {
return buffer;
}
flushBuffer(buffer, output);
- if (buffer.remaining() >= size) {
+ if(buffer.remaining() >= size) {
return buffer;
}
// Aggressively grow the buffer
@@ -144,25 +162,33 @@ public class BundleWriter {
* @return Array of serializers
* @throws IOException on IO errors
*/
- @SuppressWarnings("unchecked")
- private ByteBufferSerializer<Object>[] writeHeader(BundleStreamSource source, ByteBuffer buffer, WritableByteChannel output) throws IOException {
+ private ByteBufferSerializer<?>[] writeHeader(BundleStreamSource source, ByteBuffer buffer, WritableByteChannel output) throws IOException {
final BundleMeta meta = source.getMeta();
final int nummeta = meta.size();
@SuppressWarnings("rawtypes")
- final ByteBufferSerializer[] serializers = new ByteBufferSerializer[nummeta];
+ final ByteBufferSerializer[] serializers = new ByteBufferSerializer[1 + nummeta];
// Write our magic ID first.
assert (buffer.position() == 0) : "Buffer is supposed to be at 0.";
buffer.putInt(MAGIC);
- // Write the number of metas next
- buffer.putInt(nummeta);
- for (int i = 0; i < nummeta; i++) {
+ // Write the number of metas next.
+ // For compatibility with earlier versions, treat DBIDs as extra type
+ if(source.hasDBIDs()) {
+ buffer.putInt(1 + nummeta);
+ ByteBufferSerializer<?> ser = TypeUtil.DBID.getSerializer();
+ TypeInformationSerializer.STATIC.toByteBuffer(buffer, TypeUtil.DBID);
+ serializers[0] = ser;
+ }
+ else {
+ buffer.putInt(nummeta);
+ }
+ for(int i = 0; i < nummeta; i++) {
SimpleTypeInformation<?> type = meta.get(i);
- ByteBufferSerializer<Object> ser = (ByteBufferSerializer<Object>) type.getSerializer();
- if (ser == null) {
+ ByteBufferSerializer<?> ser = type.getSerializer();
+ if(ser == null) {
throw new AbortException("Cannot serialize - no serializer found for type: " + type.toString());
}
TypeInformationSerializer.STATIC.toByteBuffer(buffer, type);
- serializers[i] = ser;
+ serializers[i + 1] = ser;
}
return serializers;
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/bundle/MultipleObjectsBundle.java b/src/de/lmu/ifi/dbs/elki/datasource/bundle/MultipleObjectsBundle.java
index 37b517dd..4979360c 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/bundle/MultipleObjectsBundle.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/bundle/MultipleObjectsBundle.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.bundle;
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,6 +27,11 @@ import java.util.ArrayList;
import java.util.List;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
+import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
@@ -41,6 +46,11 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
*/
public class MultipleObjectsBundle implements ObjectBundle {
/**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(MultipleObjectsBundle.class);
+
+ /**
* Storing the meta data.
*/
private BundleMeta meta;
@@ -51,38 +61,16 @@ public class MultipleObjectsBundle implements ObjectBundle {
private List<List<?>> columns;
/**
- * Constructor.
+ * DBIDs for these objects, but may be null.
*/
- public MultipleObjectsBundle() {
- this.meta = new BundleMeta();
- this.columns = new ArrayList<>();
- }
+ private ArrayDBIDs ids;
/**
* Constructor.
- *
- * @param meta Meta data contained.
- * @param columns Content in columns
*/
- @Deprecated
- public MultipleObjectsBundle(BundleMeta meta, List<List<?>> columns) {
- super();
- this.meta = meta;
- this.columns = columns;
- if(this.columns.size() != this.meta.size()) {
- throw new AbortException("Meta size and columns do not agree!");
- }
- int len = -1;
- for(List<?> col : columns) {
- if(len < 0) {
- len = col.size();
- }
- else {
- if(col.size() != len) {
- throw new AbortException("Column lengths do not agree.");
- }
- }
- }
+ public MultipleObjectsBundle() {
+ this.meta = new BundleMeta();
+ this.columns = new ArrayList<>();
}
@Override
@@ -106,8 +94,18 @@ public class MultipleObjectsBundle implements ObjectBundle {
}
@Override
+ public boolean assignDBID(int onum, DBIDVar var) {
+ if(ids == null) {
+ var.unset();
+ return false;
+ }
+ ids.assignVar(onum, var);
+ return true;
+ }
+
+ @Override
public int dataLength() {
- return (columns.size() == 0) ? 0 : columns.get(0).size();
+ return (ids != null) ? ids.size() : (columns.size() == 0) ? 0 : columns.get(0).size();
}
/**
@@ -141,6 +139,24 @@ public class MultipleObjectsBundle implements ObjectBundle {
}
/**
+ * Set the DBID range for this bundle.
+ *
+ * @param ids DBIDs
+ */
+ public void setDBIDs(ArrayDBIDs ids) {
+ this.ids = ids;
+ }
+
+ /**
+ * Get the DBIDs, may be {@code null}.
+ *
+ * @return DBIDs
+ */
+ public ArrayDBIDs getDBIDs() {
+ return ids;
+ }
+
+ /**
* Get the raw objects columns. Use with caution!
*
* @param i column number
@@ -202,6 +218,15 @@ public class MultipleObjectsBundle implements ObjectBundle {
}
/**
+ * Process this bundle as stream.
+ *
+ * @return Stream
+ */
+ public BundleStreamSource asStream() {
+ return new StreamFromBundle(this);
+ }
+
+ /**
* Convert an object stream to a bundle
*
* @param source Object stream
@@ -210,6 +235,9 @@ public class MultipleObjectsBundle implements ObjectBundle {
public static MultipleObjectsBundle fromStream(BundleStreamSource source) {
MultipleObjectsBundle bundle = new MultipleObjectsBundle();
boolean stop = false;
+ DBIDVar var = null;
+ ArrayModifiableDBIDs ids = null;
+ int size = 0;
while(!stop) {
BundleStreamSource.Event ev = source.nextEvent();
switch(ev){
@@ -227,19 +255,35 @@ public class MultipleObjectsBundle implements ObjectBundle {
List<Object> data = new ArrayList<>(bundle.dataLength() + 1);
bundle.appendColumn(smeta.get(i), data);
}
+ if(var == null && source.hasDBIDs()) {
+ var = DBIDUtil.newVar();
+ ids = DBIDUtil.newArray();
+ }
continue;
case NEXT_OBJECT:
+ if(var != null && source.assignDBID(var)) {
+ ids.add(var);
+ }
for(int i = 0; i < bundle.metaLength(); i++) {
@SuppressWarnings("unchecked")
final List<Object> col = (List<Object>) bundle.columns.get(i);
col.add(source.data(i));
}
+ ++size;
continue;
default:
LoggingUtil.warning("Unknown event: " + ev);
continue;
}
}
+ if(ids != null) {
+ if(size != ids.size()) {
+ LOG.warning("Not every object had an DBID - discarding DBIDs: " + size + " != " + ids.size());
+ }
+ else {
+ bundle.setDBIDs(ids);
+ }
+ }
return bundle;
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/bundle/ObjectBundle.java b/src/de/lmu/ifi/dbs/elki/datasource/bundle/ObjectBundle.java
index fbf88f3d..8833fb6b 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/bundle/ObjectBundle.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/bundle/ObjectBundle.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.bundle;
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,6 +24,7 @@ package de.lmu.ifi.dbs.elki.datasource.bundle;
*/
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
/**
* Abstract interface for object packages.
@@ -72,4 +73,13 @@ public interface ObjectBundle {
* @return Contained data
*/
public Object data(int onum, int rnum);
+
+ /**
+ * Assign the object DBID to a variable
+ *
+ * @param onum Object number
+ * @param var Variable
+ * @return {@code false} if there was no predefined DBID.
+ */
+ public boolean assignDBID(int onum, DBIDVar var);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/bundle/SingleObjectBundle.java b/src/de/lmu/ifi/dbs/elki/datasource/bundle/SingleObjectBundle.java
index f0db03f7..8339aed4 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/bundle/SingleObjectBundle.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/bundle/SingleObjectBundle.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.bundle;
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,6 +27,8 @@ import java.util.ArrayList;
import java.util.List;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
/**
* This class represents a "packaged" object, which is a transfer container for
@@ -47,6 +49,11 @@ public class SingleObjectBundle implements ObjectBundle {
private List<Object> contents;
/**
+ * Object ID
+ */
+ private DBID id;
+
+ /**
* Constructor.
*/
public SingleObjectBundle() {
@@ -66,6 +73,21 @@ public class SingleObjectBundle implements ObjectBundle {
assert (meta.size() == contents.size());
}
+ /**
+ * Constructor.
+ *
+ * @param meta Metadata
+ * @param id ID of object
+ * @param contents Object values
+ */
+ public SingleObjectBundle(BundleMeta meta, DBID id, List<Object> contents) {
+ super();
+ this.meta = meta;
+ this.id = id;
+ this.contents = contents;
+ assert (meta.size() == contents.size());
+ }
+
@Override
public BundleMeta meta() {
return meta;
@@ -104,6 +126,16 @@ public class SingleObjectBundle implements ObjectBundle {
return contents.get(rnum);
}
+ @Override
+ public boolean assignDBID(int onum, DBIDVar var) {
+ if(id == null) {
+ var.unset();
+ return false;
+ }
+ var.set(id);
+ return true;
+ }
+
/**
* Append a single representation to the object.
*
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/bundle/StreamFromBundle.java b/src/de/lmu/ifi/dbs/elki/datasource/bundle/StreamFromBundle.java
index de683b30..7a9a68b2 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/bundle/StreamFromBundle.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/bundle/StreamFromBundle.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.bundle;
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,12 @@ package de.lmu.ifi.dbs.elki.datasource.bundle;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
+
/**
- * Convert a MultipleObjectsBundle to a stream
+ * Convert a MultipleObjectsBundle to a stream.
+ *
+ * To use this, invoke {@link MultipleObjectsBundle#asStream()}.
*
* @author Erich Schubert
*/
@@ -60,6 +64,16 @@ public class StreamFromBundle implements BundleStreamSource {
}
@Override
+ public boolean hasDBIDs() {
+ return bundle.getDBIDs() != null;
+ }
+
+ @Override
+ public boolean assignDBID(DBIDVar var) {
+ return bundle.assignDBID(onum, var);
+ }
+
+ @Override
public Event nextEvent() {
onum += 1;
if(onum < 0) {
@@ -70,4 +84,9 @@ public class StreamFromBundle implements BundleStreamSource {
}
return Event.NEXT_OBJECT;
}
+
+ @Override
+ public MultipleObjectsBundle asMultipleObjectsBundle() {
+ return bundle;
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/bundle/package-info.java b/src/de/lmu/ifi/dbs/elki/datasource/bundle/package-info.java
index 8834e40b..6de7a929 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/bundle/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/bundle/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/datasource/filter/AbstractConversionFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractConversionFilter.java
index 1cb68b30..8bedbcc3 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractConversionFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractConversionFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter;
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
@@ -58,6 +58,7 @@ public abstract class AbstractConversionFilter<I, O> implements ObjectFilter {
}
MultipleObjectsBundle bundle = new MultipleObjectsBundle();
+ final Logging logger = getLogger();
for(int r = 0; r < objects.metaLength(); r++) {
@SuppressWarnings("unchecked")
SimpleTypeInformation<Object> type = (SimpleTypeInformation<Object>) objects.meta(r);
@@ -73,18 +74,14 @@ public abstract class AbstractConversionFilter<I, O> implements ObjectFilter {
// When necessary, perform an initialization scan
if(prepareStart(castType)) {
- FiniteProgress pprog = getLogger().isVerbose() ? new FiniteProgress("Preparing normalization.", objects.dataLength(), getLogger()) : null;
+ FiniteProgress pprog = logger.isVerbose() ? new FiniteProgress("Preparing normalization.", objects.dataLength(), logger) : null;
for(Object o : column) {
@SuppressWarnings("unchecked")
final I obj = (I) o;
prepareProcessInstance(obj);
- if (pprog != null) {
- pprog.incrementProcessed(getLogger());
- }
- }
- if (pprog != null) {
- pprog.ensureCompleted(getLogger());
+ logger.incrementProcessed(pprog);
}
+ logger.ensureCompleted(pprog);
prepareComplete();
}
@@ -93,19 +90,15 @@ public abstract class AbstractConversionFilter<I, O> implements ObjectFilter {
bundle.appendColumn(convertedType(castType), castColumn);
// Normalization scan
- FiniteProgress nprog = getLogger().isVerbose() ? new FiniteProgress("Data normalization.", objects.dataLength(), getLogger()) : null;
+ FiniteProgress nprog = logger.isVerbose() ? new FiniteProgress("Data normalization.", objects.dataLength(), logger) : null;
for(int i = 0; i < objects.dataLength(); i++) {
@SuppressWarnings("unchecked")
final I obj = (I) column.get(i);
final O normalizedObj = filterSingleObject(obj);
castColumn.set(i, normalizedObj);
- if (nprog != null) {
- nprog.incrementProcessed(getLogger());
- }
- }
- if (nprog != null) {
- nprog.ensureCompleted(getLogger());
+ logger.incrementProcessed(nprog);
}
+ logger.ensureCompleted(nprog);
}
return bundle;
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractStreamConversionFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractStreamConversionFilter.java
index 5b48a8c0..0d4b5f8d 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractStreamConversionFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractStreamConversionFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter;
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/datasource/filter/AbstractStreamFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractStreamFilter.java
index 6a210db3..dca3d221 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractStreamFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractStreamFilter.java
@@ -1,14 +1,10 @@
package de.lmu.ifi.dbs.elki.datasource.filter;
-import de.lmu.ifi.dbs.elki.datasource.bundle.BundleStreamSource;
-import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
-import de.lmu.ifi.dbs.elki.datasource.bundle.StreamFromBundle;
-
/*
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,6 +22,10 @@ import de.lmu.ifi.dbs.elki.datasource.bundle.StreamFromBundle;
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.DBIDVar;
+import de.lmu.ifi.dbs.elki.datasource.bundle.BundleStreamSource;
+import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+
/**
* Abstract base class for streaming filters.
*
@@ -39,12 +39,27 @@ public abstract class AbstractStreamFilter implements StreamFilter {
@Override
public MultipleObjectsBundle filter(MultipleObjectsBundle objects) {
- init(new StreamFromBundle(objects));
- return MultipleObjectsBundle.fromStream(this);
+ return init(objects.asStream()).asMultipleObjectsBundle();
}
@Override
- public void init(BundleStreamSource source) {
+ public BundleStreamSource init(BundleStreamSource source) {
this.source = source;
+ return this;
+ }
+
+ @Override
+ public boolean hasDBIDs() {
+ return source.hasDBIDs();
+ }
+
+ @Override
+ public boolean assignDBID(DBIDVar var) {
+ return source.assignDBID(var);
+ }
+
+ @Override
+ public MultipleObjectsBundle asMultipleObjectsBundle() {
+ return MultipleObjectsBundle.fromStream(this);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractVectorConversionFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractVectorConversionFilter.java
index b9305aa6..c565a36c 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractVectorConversionFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractVectorConversionFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter;
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,11 +34,11 @@ import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
* @param <I> Input vector type
* @param <O> Output vector type
*/
-public abstract class AbstractVectorConversionFilter<I, O extends NumberVector<?>> extends AbstractConversionFilter<I, O> {
+public abstract class AbstractVectorConversionFilter<I, O extends NumberVector> extends AbstractConversionFilter<I, O> {
/**
* Number vector factory.
*/
- protected NumberVector.Factory<O, ?> factory;
+ protected NumberVector.Factory<O> factory;
/**
* Initialize factory from a data type.
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractVectorStreamConversionFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractVectorStreamConversionFilter.java
index 6a15c41c..b9c337bc 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractVectorStreamConversionFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/AbstractVectorStreamConversionFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter;
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
@@ -33,11 +33,11 @@ import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
* @param <I> Input type
* @param <O> Output vector type
*/
-public abstract class AbstractVectorStreamConversionFilter<I, O extends NumberVector<?>> extends AbstractStreamConversionFilter<I, O> {
+public abstract class AbstractVectorStreamConversionFilter<I, O extends NumberVector> extends AbstractStreamConversionFilter<I, O> {
/**
* Number vector factory.
*/
- protected NumberVector.Factory<O, ?> factory;
+ protected NumberVector.Factory<O> factory;
/**
* Initialize factory from a data type.
@@ -47,5 +47,4 @@ public abstract class AbstractVectorStreamConversionFilter<I, O extends NumberVe
protected void initializeOutputType(SimpleTypeInformation<O> type) {
factory = FilterUtil.guessFactory(type);
}
-
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/FilterUtil.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/FilterUtil.java
index 9ef9d34f..8873c9a1 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/FilterUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/FilterUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter;
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 java.lang.reflect.Field;
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.VectorFieldTypeInformation;
+import de.lmu.ifi.dbs.elki.data.type.VectorTypeInformation;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
/**
@@ -51,16 +51,16 @@ public final class FilterUtil {
* @return Factory
*/
@SuppressWarnings("unchecked")
- public static <V extends NumberVector<?>> NumberVector.Factory<V, ?> guessFactory(SimpleTypeInformation<V> in) {
- NumberVector.Factory<V, ?> factory = null;
- if(in instanceof VectorFieldTypeInformation) {
- factory = (NumberVector.Factory<V, ?>) ((VectorFieldTypeInformation<V>) in).getFactory();
+ public static <V extends NumberVector> NumberVector.Factory<V> guessFactory(SimpleTypeInformation<V> in) {
+ NumberVector.Factory<V> factory = null;
+ if(in instanceof VectorTypeInformation) {
+ factory = (NumberVector.Factory<V> ) ((VectorTypeInformation<V>) in).getFactory();
}
if(factory == null) {
// FIXME: hack. Add factories to simple type information, too?
try {
Field f = in.getRestrictionClass().getField("FACTORY");
- factory = (NumberVector.Factory<V, ?>) f.get(null);
+ factory = (NumberVector.Factory<V> ) f.get(null);
}
catch(Exception e) {
LoggingUtil.warning("Cannot determine factory for type " + in.getRestrictionClass(), e);
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/FixedDBIDsFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/FixedDBIDsFilter.java
index ce02fc29..3c66ad85 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/FixedDBIDsFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/FixedDBIDsFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter;
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,13 @@ package de.lmu.ifi.dbs.elki.datasource.filter;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-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.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRange;
import de.lmu.ifi.dbs.elki.datasource.bundle.BundleMeta;
+import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
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;
@@ -40,7 +41,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*
* @apiviz.has DBID oneway - - «produces»
*/
-public class FixedDBIDsFilter extends AbstractStreamFilter {
+public class FixedDBIDsFilter implements ObjectFilter {
/**
* The filtered meta
*/
@@ -62,35 +63,11 @@ public class FixedDBIDsFilter extends AbstractStreamFilter {
}
@Override
- public BundleMeta getMeta() {
- return meta;
- }
-
- @Override
- public Event nextEvent() {
- Event ev = source.nextEvent();
- if(ev == Event.META_CHANGED) {
- if(meta == null) {
- meta = new BundleMeta();
- meta.add(TypeUtil.DBID);
- }
- BundleMeta origmeta = source.getMeta();
- // Note -1 for the injected DBID column
- for(int i = meta.size() - 1; i < origmeta.size(); i++) {
- meta.add(origmeta.get(i));
- }
- }
- return ev;
- }
-
- @Override
- public Object data(int rnum) {
- if(rnum == 0) {
- DBID ret = DBIDUtil.importInteger(curid);
- curid++;
- return ret;
- }
- return source.data(rnum - 1);
+ public MultipleObjectsBundle filter(MultipleObjectsBundle objects) {
+ DBIDRange ids = DBIDFactory.FACTORY.generateStaticDBIDRange(curid, objects.dataLength());
+ objects.setDBIDs(ids);
+ curid += objects.dataLength();
+ return objects;
}
/**
@@ -108,19 +85,24 @@ public class FixedDBIDsFilter extends AbstractStreamFilter {
* </p>
*/
public static final OptionID IDSTART_ID = new OptionID("dbc.startid", "Object ID to start counting with");
- int startid = -1;
+
+ /**
+ * First ID to use.
+ */
+ int startid = 0;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- IntParameter startidParam = new IntParameter(IDSTART_ID);
+ IntParameter startidParam = new IntParameter(IDSTART_ID, 0) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_INT);
if(config.grab(startidParam)) {
- startid = startidParam.getValue().intValue();
+ startid = startidParam.intValue();
}
}
@Override
- protected Object makeInstance() {
+ protected FixedDBIDsFilter makeInstance() {
return new FixedDBIDsFilter(startid);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/NoOpFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/NoOpFilter.java
index ce758763..09896f15 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/NoOpFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/NoOpFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter;
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/datasource/filter/ObjectFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/ObjectFilter.java
index 5073cea8..a6c364aa 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/ObjectFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/ObjectFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter;
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/datasource/filter/StreamFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/StreamFilter.java
index 798cd05d..45464f31 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/StreamFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/StreamFilter.java
@@ -1,12 +1,10 @@
package de.lmu.ifi.dbs.elki.datasource.filter;
-import de.lmu.ifi.dbs.elki.datasource.bundle.BundleStreamSource;
-
/*
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 +23,11 @@ import de.lmu.ifi.dbs.elki.datasource.bundle.BundleStreamSource;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import de.lmu.ifi.dbs.elki.datasource.bundle.BundleStreamSource;
+
/**
- * Streaming filters are often more efficient (less memory use) and can be used
- * in more settings.
+ * Streaming filters are often more efficient (less memory use) as they do not
+ * keep a reference to earlier data.
*
* @author Erich Schubert
*
@@ -41,5 +41,5 @@ public interface StreamFilter extends ObjectFilter, BundleStreamSource {
*
* @param source Stream source
*/
- public void init(BundleStreamSource source);
+ public BundleStreamSource init(BundleStreamSource source);
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/DropNaNFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/DropNaNFilter.java
index fb9cf83e..4c226085 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/DropNaNFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/DropNaNFilter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter;
+package de.lmu.ifi.dbs.elki.datasource.filter.cleaning;
/*
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,7 +30,9 @@ import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.datasource.bundle.BundleMeta;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.datasource.filter.AbstractStreamFilter;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -43,6 +45,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Erich Schubert
*/
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.DropNaNFilter" })
public class DropNaNFilter extends AbstractStreamFilter {
/**
* Class logger
@@ -73,33 +76,33 @@ public class DropNaNFilter extends AbstractStreamFilter {
@Override
public Event nextEvent() {
- while (true) {
+ while(true) {
Event ev = source.nextEvent();
- switch(ev) {
+ switch(ev){
case END_OF_STREAM:
return ev;
case META_CHANGED:
updateMeta(source.getMeta());
return ev;
case NEXT_OBJECT:
- if (densecols == null) {
+ if(densecols == null) {
updateMeta(source.getMeta());
}
boolean good = true;
- for (int j = densecols.nextSetBit(0); j >= 0; j = densecols.nextSetBit(j + 1)) {
- NumberVector<?> v = (NumberVector<?>) source.data(j);
- if (v == null) {
+ for(int j = densecols.nextSetBit(0); j >= 0; j = densecols.nextSetBit(j + 1)) {
+ NumberVector v = (NumberVector) source.data(j);
+ if(v == null) {
good = false;
break;
}
- for (int i = 0; i < v.getDimensionality(); i++) {
- if (Double.isNaN(v.doubleValue(i))) {
+ for(int i = 0; i < v.getDimensionality(); i++) {
+ if(Double.isNaN(v.doubleValue(i))) {
good = false;
break;
}
}
}
- if (good) {
+ if(good) {
return ev;
}
continue;
@@ -114,21 +117,22 @@ public class DropNaNFilter extends AbstractStreamFilter {
*/
private void updateMeta(BundleMeta meta) {
int cols = meta.size();
- if (densecols == null) {
+ if(densecols == null) {
densecols = new BitSet();
- } else {
+ }
+ else {
densecols.clear();
}
- for (int i = 0; i < cols; i++) {
- if (TypeUtil.SPARSE_VECTOR_VARIABLE_LENGTH.isAssignableFromType(meta.get(i))) {
+ for(int i = 0; i < cols; i++) {
+ if(TypeUtil.SPARSE_VECTOR_VARIABLE_LENGTH.isAssignableFromType(meta.get(i))) {
throw new AbortException("Filtering sparse vectors is not yet supported by this filter. Please contribute.");
}
// TODO: only check for double and float?
- if (TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH.isAssignableFromType(meta.get(i))) {
+ if(TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH.isAssignableFromType(meta.get(i))) {
densecols.set(i);
continue;
}
- if (TypeUtil.DOUBLE_VECTOR_FIELD.isAssignableFromType(meta.get(i))) {
+ if(TypeUtil.DOUBLE_VECTOR_FIELD.isAssignableFromType(meta.get(i))) {
densecols.set(i);
continue;
}
@@ -137,32 +141,32 @@ public class DropNaNFilter extends AbstractStreamFilter {
@Override
public MultipleObjectsBundle filter(final MultipleObjectsBundle objects) {
- if (LOG.isDebuggingFinest()) {
+ if(LOG.isDebuggingFinest()) {
LOG.debugFinest("Removing records with NaN values.");
}
updateMeta(objects.meta());
MultipleObjectsBundle bundle = new MultipleObjectsBundle();
- for (int j = 0; j < objects.metaLength(); j++) {
+ for(int j = 0; j < objects.metaLength(); j++) {
bundle.appendColumn(objects.meta(j), new ArrayList<>());
}
- for (int i = 0; i < objects.dataLength(); i++) {
+ for(int i = 0; i < objects.dataLength(); i++) {
final Object[] row = objects.getRow(i);
boolean good = true;
- for (int j = densecols.nextSetBit(0); j >= 0; j = densecols.nextSetBit(j + 1)) {
- NumberVector<?> v = (NumberVector<?>) row[j];
- if (v == null) {
+ for(int j = densecols.nextSetBit(0); j >= 0; j = densecols.nextSetBit(j + 1)) {
+ NumberVector v = (NumberVector) row[j];
+ if(v == null) {
good = false;
break;
}
- for (int d = 0; d < v.getDimensionality(); d++) {
- if (Double.isNaN(v.doubleValue(d))) {
+ for(int d = 0; d < v.getDimensionality(); d++) {
+ if(Double.isNaN(v.doubleValue(d))) {
good = false;
break;
}
}
}
- if (good) {
+ if(good) {
bundle.appendSimple(row);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/NoMissingValuesFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/NoMissingValuesFilter.java
index b3f0af53..9b7ab977 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/NoMissingValuesFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/NoMissingValuesFilter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter;
+package de.lmu.ifi.dbs.elki.datasource.filter.cleaning;
/*
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,9 @@ import java.util.ArrayList;
import de.lmu.ifi.dbs.elki.datasource.bundle.BundleMeta;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.datasource.filter.AbstractStreamFilter;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
@@ -35,6 +37,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Erich Schubert
*/
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.NoMissingValuesFilter" })
public class NoMissingValuesFilter extends AbstractStreamFilter {
/**
* Class logger
@@ -123,7 +126,7 @@ public class NoMissingValuesFilter extends AbstractStreamFilter {
*/
public static class Parameterizer extends AbstractParameterizer {
@Override
- protected Object makeInstance() {
+ protected NoMissingValuesFilter makeInstance() {
return new NoMissingValuesFilter();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/ReplaceNaNWithRandomFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/ReplaceNaNWithRandomFilter.java
index 9029d8ea..96a5f059 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/ReplaceNaNWithRandomFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/ReplaceNaNWithRandomFilter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter;
+package de.lmu.ifi.dbs.elki.datasource.filter.cleaning;
/*
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,8 +30,10 @@ import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.datasource.bundle.BundleMeta;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.datasource.filter.AbstractStreamFilter;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.statistics.distribution.Distribution;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
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;
@@ -47,6 +49,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*/
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.ReplaceNaNWithRandomFilter" })
public class ReplaceNaNWithRandomFilter extends AbstractStreamFilter {
/**
* Class logger
@@ -56,7 +59,7 @@ public class ReplaceNaNWithRandomFilter extends AbstractStreamFilter {
/**
* Columns to check.
*/
- private NumberVector.Factory<?, ?>[] densecols = null;
+ private NumberVector.Factory<?>[] densecols = null;
/**
* Distribution to generate replacement values with.
@@ -88,28 +91,28 @@ public class ReplaceNaNWithRandomFilter extends AbstractStreamFilter {
@Override
public Event nextEvent() {
- while (true) {
+ while(true) {
Event ev = source.nextEvent();
- switch(ev) {
+ switch(ev){
case END_OF_STREAM:
return ev;
case META_CHANGED:
updateMeta(source.getMeta());
return ev;
case NEXT_OBJECT:
- if (densecols == null) {
+ if(densecols == null) {
updateMeta(source.getMeta());
}
rows.clear();
- for (int j = 0; j < densecols.length; j++) {
+ for(int j = 0; j < densecols.length; j++) {
Object o = source.data(j);
- if (densecols[j] != null) {
- NumberVector<?> v = (NumberVector<?>) o;
+ if(densecols[j] != null) {
+ NumberVector v = (NumberVector) o;
double[] ro = null; // replacement
- if (v != null) {
- for (int i = 0; i < v.getDimensionality(); i++) {
- if (Double.isNaN(v.doubleValue(i))) {
- if (ro != null) {
+ if(v != null) {
+ for(int i = 0; i < v.getDimensionality(); i++) {
+ if(Double.isNaN(v.doubleValue(i))) {
+ if(ro != null) {
ro = v.getColumnVector().getArrayRef();
}
ro[i] = dist.nextRandom();
@@ -132,19 +135,19 @@ public class ReplaceNaNWithRandomFilter extends AbstractStreamFilter {
*/
private void updateMeta(BundleMeta meta) {
final int cols = meta.size();
- densecols = new NumberVector.Factory<?, ?>[cols];
- for (int i = 0; i < cols; i++) {
- if (TypeUtil.SPARSE_VECTOR_VARIABLE_LENGTH.isAssignableFromType(meta.get(i))) {
+ densecols = new NumberVector.Factory<?>[cols];
+ for(int i = 0; i < cols; i++) {
+ if(TypeUtil.SPARSE_VECTOR_VARIABLE_LENGTH.isAssignableFromType(meta.get(i))) {
throw new AbortException("Filtering sparse vectors is not yet supported by this filter. Please contribute.");
}
- if (TypeUtil.FLOAT_VECTOR_FIELD.isAssignableFromType(meta.get(i))) {
+ if(TypeUtil.FLOAT_VECTOR_FIELD.isAssignableFromType(meta.get(i))) {
VectorFieldTypeInformation<?> vmeta = (VectorFieldTypeInformation<?>) meta.get(i);
- densecols[i] = (NumberVector.Factory<?, ?>) vmeta.getFactory();
+ densecols[i] = (NumberVector.Factory<?>) vmeta.getFactory();
continue;
}
- if (TypeUtil.DOUBLE_VECTOR_FIELD.isAssignableFromType(meta.get(i))) {
+ if(TypeUtil.DOUBLE_VECTOR_FIELD.isAssignableFromType(meta.get(i))) {
VectorFieldTypeInformation<?> vmeta = (VectorFieldTypeInformation<?>) meta.get(i);
- densecols[i] = (NumberVector.Factory<?, ?>) vmeta.getFactory();
+ densecols[i] = (NumberVector.Factory<?>) vmeta.getFactory();
continue;
}
}
@@ -152,25 +155,25 @@ public class ReplaceNaNWithRandomFilter extends AbstractStreamFilter {
@Override
public MultipleObjectsBundle filter(final MultipleObjectsBundle objects) {
- if (LOG.isDebuggingFinest()) {
+ if(LOG.isDebuggingFinest()) {
LOG.debugFinest("Removing records with NaN values.");
}
updateMeta(objects.meta());
MultipleObjectsBundle bundle = new MultipleObjectsBundle();
- for (int j = 0; j < objects.metaLength(); j++) {
+ for(int j = 0; j < objects.metaLength(); j++) {
bundle.appendColumn(objects.meta(j), new ArrayList<>());
}
- for (int i = 0; i < objects.dataLength(); i++) {
+ for(int i = 0; i < objects.dataLength(); i++) {
final Object[] row = objects.getRow(i);
- for (int j = 0; j < densecols.length; j++) {
- if (densecols[j] != null) {
- NumberVector<?> v = (NumberVector<?>) row[j];
+ for(int j = 0; j < densecols.length; j++) {
+ if(densecols[j] != null) {
+ NumberVector v = (NumberVector) row[j];
double[] ro = null; // replacement
- if (v != null) {
- for (int d = 0; d < v.getDimensionality(); d++) {
- if (Double.isNaN(v.doubleValue(d))) {
- if (ro != null) {
+ if(v != null) {
+ for(int d = 0; d < v.getDimensionality(); d++) {
+ if(Double.isNaN(v.doubleValue(d))) {
+ if(ro != null) {
ro = v.getColumnVector().getArrayRef();
}
ro[d] = dist.nextRandom();
@@ -207,7 +210,7 @@ public class ReplaceNaNWithRandomFilter extends AbstractStreamFilter {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
ObjectParameter<Distribution> distP = new ObjectParameter<>(REPLACEMENT_DISTRIBUTION, Distribution.class);
- if (config.grab(distP)) {
+ if(config.grab(distP)) {
dist = distP.instantiateClass(config);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/VectorDimensionalityFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/VectorDimensionalityFilter.java
new file mode 100644
index 00000000..5d4e2d2a
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/VectorDimensionalityFilter.java
@@ -0,0 +1,219 @@
+package de.lmu.ifi.dbs.elki.datasource.filter.cleaning;
+
+/*
+ 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.data.type.VectorFieldTypeInformation;
+import de.lmu.ifi.dbs.elki.data.type.VectorTypeInformation;
+import de.lmu.ifi.dbs.elki.datasource.bundle.BundleMeta;
+import de.lmu.ifi.dbs.elki.datasource.filter.AbstractStreamFilter;
+import de.lmu.ifi.dbs.elki.datasource.filter.FilterUtil;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
+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.constraints.CommonConstraints;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+
+/**
+ * Filter to remove all vectors that do not have the desired dimensionality.
+ *
+ * @author Erich Schubert
+ *
+ * @param <V> Vector type
+ */
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.VectorDimensionalityFilter" })
+public class VectorDimensionalityFilter<V extends NumberVector> extends AbstractStreamFilter {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(VectorDimensionalityFilter.class);
+
+ /**
+ * The filtered meta.
+ */
+ BundleMeta meta;
+
+ /**
+ * The column to filter.
+ */
+ int column = -1;
+
+ /**
+ * Desired dimensionality.
+ */
+ int dim = -1;
+
+ /**
+ * Constructor.
+ *
+ * @param dim Dimensionality to enforce (use -1 to use the dimensionality of
+ * the first vector in the data set)
+ */
+ public VectorDimensionalityFilter(int dim) {
+ super();
+ this.dim = dim;
+ }
+
+ @Override
+ public BundleMeta getMeta() {
+ if(meta == null) {
+ updateMeta();
+ }
+ return source.getMeta();
+ }
+
+ @Override
+ public Object data(int rnum) {
+ return source.data(rnum);
+ }
+
+ @Override
+ public Event nextEvent() {
+ while(true) {
+ Event ev = source.nextEvent();
+ switch(ev){
+ case END_OF_STREAM:
+ return ev;
+ case META_CHANGED:
+ meta = null;
+ return ev;
+ case NEXT_OBJECT:
+ if(meta == null) {
+ updateMeta();
+ }
+ if(column >= 0 && dim >= 0) {
+ @SuppressWarnings("unchecked")
+ V vec = (V) source.data(column);
+ if(vec == null) {
+ if(LOG.isVeryVerbose()) {
+ LOG.veryverbose("Skipping null vector.");
+ }
+ continue;
+ }
+ if(vec.getDimensionality() != dim) {
+ if(LOG.isVeryVerbose()) {
+ StringBuilder buf = new StringBuilder();
+ buf.append("Skipping vector of wrong dimensionality ");
+ buf.append(vec.getDimensionality());
+ buf.append(':');
+ for(int i = 0; i < meta.size(); i++) {
+ buf.append(' ');
+ buf.append(source.data(i));
+ }
+ LOG.veryverbose(buf.toString());
+ }
+ continue;
+ }
+ }
+ return ev;
+ }
+ }
+ }
+
+ /**
+ * Update metadata.
+ */
+ private void updateMeta() {
+ meta = new BundleMeta();
+ BundleMeta origmeta = source.getMeta();
+ for(int i = 0; i < origmeta.size(); i++) {
+ SimpleTypeInformation<?> type = origmeta.get(i);
+ if(column < 0) {
+ // Test whether this type matches
+ if(TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH.isAssignableFromType(type)) {
+ if(type instanceof VectorFieldTypeInformation) {
+ @SuppressWarnings("unchecked")
+ final VectorFieldTypeInformation<V> castType = (VectorFieldTypeInformation<V>) type;
+ if(dim != -1 && castType.mindim() > dim) {
+ throw new AbortException("Would filter all vectors: minimum dimensionality " + castType.mindim() + " > desired dimensionality " + dim);
+ }
+ if(dim != -1 && castType.maxdim() < dim) {
+ throw new AbortException("Would filter all vectors: maximum dimensionality " + castType.maxdim() + " < desired dimensionality " + dim);
+ }
+ if(dim == -1) {
+ dim = castType.mindim();
+ }
+ if(castType.mindim() == castType.maxdim()) {
+ meta.add(castType);
+ column = i;
+ continue;
+ }
+ }
+ @SuppressWarnings("unchecked")
+ final VectorTypeInformation<V> castType = (VectorTypeInformation<V>) type;
+ if(dim != -1) {
+ meta.add(new VectorFieldTypeInformation<>(FilterUtil.guessFactory(castType), dim, dim, castType.getSerializer()));
+ }
+ else {
+ LOG.warning("No dimensionality yet for column " + i);
+ meta.add(castType);
+ }
+ column = i;
+ continue;
+ }
+ }
+ meta.add(type);
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <V> Vector type
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * Parameter for specifying the dimensionality.
+ */
+ private static final OptionID DIM_P = new OptionID("filter.dim", "Dimensionality of vectors to retain.");
+
+ /**
+ * Desired dimensionality.
+ */
+ int dim = -1;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ IntParameter dimP = new IntParameter(DIM_P)//
+ .setOptional(true)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ dim = config.grab(dimP) ? dimP.intValue() : -1;
+ }
+
+ @Override
+ protected VectorDimensionalityFilter<V> makeInstance() {
+ return new VectorDimensionalityFilter<>(dim);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/package-info.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/package-info.java
new file mode 100644
index 00000000..b2d47e69
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/cleaning/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Filters for data cleaning.
+ */
+
+/*
+ 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.datasource.filter.cleaning; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AbstractNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AbstractNormalization.java
index 0b4d7ae0..8ad13355 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AbstractNormalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AbstractNormalization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
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
@@ -33,9 +33,9 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.LinearEquationSystem;
*
* @author Elke Achtert
*
- * @param <O> Object type processed
+ * @param <V> Object type processed
*/
-public abstract class AbstractNormalization<O extends NumberVector<?>> extends AbstractVectorConversionFilter<O, O> implements Normalization<O> {
+public abstract class AbstractNormalization<V extends NumberVector> extends AbstractVectorConversionFilter<V, V> implements Normalization<V> {
/**
* Initializes the option handler and the parameter map.
*/
@@ -44,12 +44,18 @@ public abstract class AbstractNormalization<O extends NumberVector<?>> extends A
}
@Override
- protected SimpleTypeInformation<? super O> convertedType(SimpleTypeInformation<O> in) {
+ protected SimpleTypeInformation<? super V> convertedType(SimpleTypeInformation<V> in) {
initializeOutputType(in);
return in;
}
@Override
+ public V restore(V featureVector) throws NonNumericFeaturesException {
+ // FIXME: implement everywhere.
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ @Override
public LinearEquationSystem transform(LinearEquationSystem linearEquationSystem) {
// FIXME: implement.
throw new UnsupportedOperationException("Not yet implemented!");
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AbstractStreamNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AbstractStreamNormalization.java
index 54fc7794..38e0bf31 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AbstractStreamNormalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AbstractStreamNormalization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
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
@@ -33,9 +33,9 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.LinearEquationSystem;
*
* @author Erich Schubert
*
- * @param <O> Object type processed
+ * @param <V> Object type processed
*/
-public abstract class AbstractStreamNormalization<O extends NumberVector<?>> extends AbstractVectorStreamConversionFilter<O, O> implements Normalization<O> {
+public abstract class AbstractStreamNormalization<V extends NumberVector> extends AbstractVectorStreamConversionFilter<V, V> implements Normalization<V> {
/**
* Initializes the option handler and the parameter map.
*/
@@ -44,12 +44,17 @@ public abstract class AbstractStreamNormalization<O extends NumberVector<?>> ext
}
@Override
- protected SimpleTypeInformation<? super O> convertedType(SimpleTypeInformation<O> in) {
+ protected SimpleTypeInformation<? super V> convertedType(SimpleTypeInformation<V> in) {
initializeOutputType(in);
return in;
}
@Override
+ public V restore(V featureVector) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public LinearEquationSystem transform(LinearEquationSystem linearEquationSystem) {
// FIXME: implement.
throw new UnsupportedOperationException("Not yet implemented!");
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/NonNumericFeaturesException.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/NonNumericFeaturesException.java
index 0abaac95..d9002c93 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/NonNumericFeaturesException.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/NonNumericFeaturesException.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
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/datasource/filter/normalization/Normalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/Normalization.java
index 3c3e7bdf..bf913852 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/Normalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/Normalization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
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.datasource.filter.normalization;
import de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter;
import de.lmu.ifi.dbs.elki.math.linearalgebra.LinearEquationSystem;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Normalization performs a normalization on a set of feature vectors and is
@@ -41,7 +40,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
*
* @param <O> object type
*/
-public interface Normalization<O> extends ObjectFilter, Parameterizable {
+public interface Normalization<O> extends ObjectFilter {
/**
* Transforms a feature vector to the original attribute ranges.
*
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/TFIDFNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/TFIDFNormalization.java
deleted file mode 100644
index 09b73aa4..00000000
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/TFIDFNormalization.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
-
-/*
- 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 gnu.trove.map.hash.TIntDoubleHashMap;
-import de.lmu.ifi.dbs.elki.data.SparseNumberVector;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-
-/**
- * Perform full TF-IDF Normalization as commonly used in text mining.
- *
- * Each record is first normalized using "term frequencies" to sum up to 1. Then
- * it is globally normalized using the Inverse Document Frequency, so rare terms
- * are weighted stronger than common terms.
- *
- * Restore will only undo the IDF part of the normalization!
- *
- * @author Erich Schubert
- *
- * @param <V> Vector type
- */
-public class TFIDFNormalization<V extends SparseNumberVector<?>> extends InverseDocumentFrequencyNormalization<V> {
- /**
- * Class logger.
- */
- private static final Logging LOG = Logging.getLogger(TFIDFNormalization.class);
-
- /**
- * Constructor.
- */
- public TFIDFNormalization() {
- super();
- }
-
- @Override
- protected V filterSingleObject(V featureVector) {
- double sum = 0.0;
- for(int it = featureVector.iter(); featureVector.iterValid(it); it = featureVector.iterAdvance(it)) {
- sum += featureVector.iterDoubleValue(it);
- }
- if(sum <= 0) {
- sum = 1.0;
- }
- TIntDoubleHashMap vals = new TIntDoubleHashMap();
- for(int it = featureVector.iter(); featureVector.iterValid(it); it = featureVector.iterAdvance(it)) {
- final int dim = featureVector.iterDim(it);
- vals.put(dim, featureVector.iterDoubleValue(it) / sum * idf.get(dim));
- }
- return ((SparseNumberVector.Factory<V, ?>) factory).newNumberVector(vals, featureVector.getDimensionality());
- }
-
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseBetaNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseBetaNormalization.java
new file mode 100644
index 00000000..a1618b9f
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseBetaNormalization.java
@@ -0,0 +1,326 @@
+package de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise;
+
+/*
+ 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.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+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.data.type.VectorFieldTypeInformation;
+import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.datasource.filter.FilterUtil;
+import de.lmu.ifi.dbs.elki.datasource.filter.normalization.NonNumericFeaturesException;
+import de.lmu.ifi.dbs.elki.datasource.filter.normalization.Normalization;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.LinearEquationSystem;
+import de.lmu.ifi.dbs.elki.math.statistics.distribution.BetaDistribution;
+import de.lmu.ifi.dbs.elki.math.statistics.distribution.Distribution;
+import de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.DistributionEstimator;
+import de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.meta.BestFitEstimator;
+import de.lmu.ifi.dbs.elki.math.statistics.tests.KolmogorovSmirnovTest;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
+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.DoubleParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParameter;
+
+/**
+ * Project the data using a Beta distribution.
+ *
+ * This is a crude heuristic, that may or may not work for your data set. There
+ * currently is no theoretical foundation of why it may be sensible or not to do
+ * this.
+ *
+ * @author Erich Schubert
+ *
+ * @param <V> vector type
+ *
+ * @apiviz.uses NumberVector
+ * @apiviz.uses DistributionEstimator
+ */
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.AttributeWiseBetaNormalization"})
+public class AttributeWiseBetaNormalization<V extends NumberVector> implements Normalization<V> {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(AttributeWiseBetaNormalization.class);
+
+ /**
+ * Stores the distribution estimators
+ */
+ private List<DistributionEstimator<?>> estimators;
+
+ /**
+ * Stores the estimated distributions
+ */
+ private List<Distribution> dists;
+
+ /**
+ * Number vector factory.
+ */
+ protected NumberVector.Factory<V> factory;
+
+ /**
+ * Expected outlier rate alpha.
+ */
+ protected double alpha = 0.01;
+
+ /**
+ * Constructor.
+ *
+ * @param estimators Distribution estimators
+ */
+ public AttributeWiseBetaNormalization(List<DistributionEstimator<?>> estimators, double alpha) {
+ super();
+ this.estimators = estimators;
+ this.alpha = alpha;
+ }
+
+ @Override
+ public MultipleObjectsBundle filter(MultipleObjectsBundle objects) {
+ if(objects.dataLength() == 0) {
+ return objects;
+ }
+ for(int r = 0; r < objects.metaLength(); r++) {
+ SimpleTypeInformation<?> type = (SimpleTypeInformation<?>) objects.meta(r);
+ final List<?> column = (List<?>) objects.getColumn(r);
+ if(!TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(type)) {
+ continue;
+ }
+ @SuppressWarnings("unchecked")
+ final List<V> castColumn = (List<V>) column;
+ // Get the replacement type information
+ @SuppressWarnings("unchecked")
+ final VectorFieldTypeInformation<V> castType = (VectorFieldTypeInformation<V>) type;
+ factory = FilterUtil.guessFactory(castType);
+
+ // Scan to find the best
+ final int dim = castType.getDimensionality();
+ dists = new ArrayList<>(dim);
+ // Scratch space for testing:
+ double[] test = new double[castColumn.size()];
+
+ // We iterate over dimensions, this kind of filter needs fast random
+ // access.
+ Adapter adapter = new Adapter();
+ for(int d = 0; d < dim; d++) {
+ adapter.dim = d;
+ if(estimators.size() == 1) {
+ dists.add(estimators.get(0).estimate(castColumn, adapter));
+ continue;
+ }
+ Distribution best = null;
+ double bestq = Double.POSITIVE_INFINITY;
+ trials: for(DistributionEstimator<?> est : estimators) {
+ try {
+ Distribution dist = est.estimate(castColumn, adapter);
+ for(int i = 0; i < test.length; i++) {
+ test[i] = dist.cdf(castColumn.get(i).doubleValue(d));
+ if(Double.isNaN(test[i])) {
+ LOG.warning("Got NaN after fitting " + est.toString() + ": " + dist.toString());
+ continue trials;
+ }
+ if(Double.isInfinite(test[i])) {
+ LOG.warning("Got infinite value after fitting " + est.toString() + ": " + dist.toString());
+ continue trials;
+ }
+ }
+ Arrays.sort(test);
+ double q = KolmogorovSmirnovTest.simpleTest(test);
+ if(LOG.isVeryVerbose()) {
+ LOG.veryverbose("Estimator " + est.toString() + " (" + dist.toString() + ") has maximum deviation " + q + " for dimension " + d);
+ }
+ if(best == null || q < bestq) {
+ best = dist;
+ bestq = q;
+ }
+ }
+ catch(ArithmeticException e) {
+ if(LOG.isVeryVerbose()) {
+ LOG.veryverbose("Fitting distribution " + est + " failed: " + e.getMessage());
+ }
+ continue;
+ }
+ }
+ if(LOG.isVerbose()) {
+ LOG.verbose("Best fit for dimension " + d + ": " + best.toString());
+ }
+ dists.add(best);
+ }
+
+ // Beta distribution for projection
+ double p = Math.pow(alpha, -1 / Math.sqrt(dim));
+ BetaDistribution beta = new BetaDistribution(p, p);
+ // Normalization scan
+ double[] buf = new double[dim];
+ for(int i = 0; i < objects.dataLength(); i++) {
+ final V obj = castColumn.get(i);
+ for(int d = 0; d < dim; d++) {
+ // TODO: when available, use logspace for better numerical precision!
+ buf[d] = beta.quantile(dists.get(d).cdf(obj.doubleValue(d)));
+ }
+ castColumn.set(i, factory.newNumberVector(buf));
+ }
+ }
+ return objects;
+ }
+
+ @Override
+ public V restore(V featureVector) throws NonNumericFeaturesException {
+ throw new UnsupportedOperationException(ExceptionMessages.UNSUPPORTED_NOT_YET);
+ }
+
+ @Override
+ public LinearEquationSystem transform(LinearEquationSystem linearEquationSystem) {
+ throw new UnsupportedOperationException(ExceptionMessages.UNSUPPORTED_NOT_YET);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+ result.append("normalization class: ").append(getClass().getName());
+ result.append('\n');
+ result.append("normalization distributions: ");
+ boolean first = true;
+ for(DistributionEstimator<?> est : estimators) {
+ if(!first) {
+ result.append(',');
+ }
+ first = false;
+ result.append(est.getClass().getSimpleName());
+ }
+ return result.toString();
+ }
+
+ /**
+ * Array adapter class for vectors.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ private static class Adapter implements NumberArrayAdapter<Double, List<? extends NumberVector>> {
+ /**
+ * Dimension to process.
+ */
+ int dim;
+
+ @Override
+ public int size(List<? extends NumberVector> array) {
+ return array.size();
+ }
+
+ @Override
+ public Double get(List<? extends NumberVector> array, int off) throws IndexOutOfBoundsException {
+ return getDouble(array, off);
+ }
+
+ @Override
+ public double getDouble(List<? extends NumberVector> array, int off) throws IndexOutOfBoundsException {
+ return array.get(off).doubleValue(dim);
+ }
+
+ @Override
+ public float getFloat(List<? extends NumberVector> array, int off) throws IndexOutOfBoundsException {
+ return array.get(off).floatValue(dim);
+ }
+
+ @Override
+ public int getInteger(List<? extends NumberVector> array, int off) throws IndexOutOfBoundsException {
+ return array.get(off).intValue(dim);
+ }
+
+ @Override
+ public short getShort(List<? extends NumberVector> array, int off) throws IndexOutOfBoundsException {
+ return array.get(off).shortValue(dim);
+ }
+
+ @Override
+ public long getLong(List<? extends NumberVector> array, int off) throws IndexOutOfBoundsException {
+ return array.get(off).longValue(dim);
+ }
+
+ @Override
+ public byte getByte(List<? extends NumberVector> array, int off) throws IndexOutOfBoundsException {
+ return array.get(off).byteValue(dim);
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * Parameter for distribution estimators.
+ */
+ public static final OptionID DISTRIBUTIONS_ID = new OptionID("betanormalize.distributions", "A list of the distribution estimators to try.");
+
+ /**
+ * Shape parameter.
+ */
+ public static final OptionID ALPHA_ID = new OptionID("betanormalize.alpha", "Alpha parameter to control the shape of the output distribution.");
+
+ /**
+ * Stores the distribution estimators
+ */
+ private List<DistributionEstimator<?>> estimators;
+
+ /**
+ * Expected outlier rate alpha.
+ */
+ private double alpha;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ ObjectListParameter<DistributionEstimator<?>> estP = new ObjectListParameter<>(DISTRIBUTIONS_ID, DistributionEstimator.class);
+ List<Class<? extends DistributionEstimator<?>>> def = new ArrayList<>(1);
+ def.add(BestFitEstimator.class);
+ estP.setDefaultValue(def);
+ if(config.grab(estP)) {
+ estimators = estP.instantiateClasses(config);
+ }
+
+ DoubleParameter alphaP = new DoubleParameter(ALPHA_ID, 0.1);
+ if(config.grab(alphaP)) {
+ alpha = alphaP.doubleValue();
+ }
+ }
+
+ @Override
+ protected AttributeWiseBetaNormalization<V> makeInstance() {
+ return new AttributeWiseBetaNormalization<>(estimators, alpha);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseCDFNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseCDFNormalization.java
index dd86cc5a..be501b11 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseCDFNormalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseCDFNormalization.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
+package de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise;
/*
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
@@ -33,12 +33,16 @@ import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
import de.lmu.ifi.dbs.elki.datasource.filter.FilterUtil;
+import de.lmu.ifi.dbs.elki.datasource.filter.normalization.NonNumericFeaturesException;
+import de.lmu.ifi.dbs.elki.datasource.filter.normalization.Normalization;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.linearalgebra.LinearEquationSystem;
import de.lmu.ifi.dbs.elki.math.statistics.distribution.Distribution;
+import de.lmu.ifi.dbs.elki.math.statistics.distribution.UniformDistribution;
import de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.DistributionEstimator;
import de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.meta.BestFitEstimator;
import de.lmu.ifi.dbs.elki.math.statistics.tests.KolmogorovSmirnovTest;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -66,7 +70,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParamet
* @apiviz.uses DistributionEstimator
*/
// TODO: extract superclass AbstractAttributeWiseNormalization
-public class AttributeWiseCDFNormalization<V extends NumberVector<?>> implements Normalization<V> {
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.AttributeWiseCDFNormalization"})
+public class AttributeWiseCDFNormalization<V extends NumberVector> implements Normalization<V> {
/**
* Class logger.
*/
@@ -85,7 +90,7 @@ public class AttributeWiseCDFNormalization<V extends NumberVector<?>> implements
/**
* Number vector factory.
*/
- protected NumberVector.Factory<V, ?> factory;
+ protected NumberVector.Factory<V> factory;
/**
* Constructor.
@@ -99,13 +104,13 @@ public class AttributeWiseCDFNormalization<V extends NumberVector<?>> implements
@Override
public MultipleObjectsBundle filter(MultipleObjectsBundle objects) {
- if (objects.dataLength() == 0) {
+ if(objects.dataLength() == 0) {
return objects;
}
- for (int r = 0; r < objects.metaLength(); r++) {
+ for(int r = 0; r < objects.metaLength(); r++) {
SimpleTypeInformation<?> type = (SimpleTypeInformation<?>) objects.meta(r);
final List<?> column = (List<?>) objects.getColumn(r);
- if (!TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(type)) {
+ if(!TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(type)) {
continue;
}
@SuppressWarnings("unchecked")
@@ -119,60 +124,33 @@ public class AttributeWiseCDFNormalization<V extends NumberVector<?>> implements
final int dim = castType.getDimensionality();
dists = new ArrayList<>(dim);
// Scratch space for testing:
- double[] test = new double[castColumn.size()];
+ double[] test = estimators.size() > 1 ? new double[castColumn.size()] : null;
// We iterate over dimensions, this kind of filter needs fast random
// access.
Adapter adapter = new Adapter();
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
adapter.dim = d;
- if (estimators.size() == 1) {
- dists.add(estimators.get(0).estimate(castColumn, adapter));
- } else {
- Distribution best = null;
- double bestq = Double.POSITIVE_INFINITY;
- trials: for (DistributionEstimator<?> est : estimators) {
- try {
- Distribution dist = est.estimate(castColumn, adapter);
- for (int i = 0; i < test.length; i++) {
- test[i] = dist.cdf(castColumn.get(i).doubleValue(d));
- if (Double.isNaN(test[i])) {
- LOG.warning("Got NaN after fitting " + est.toString() + ": " + dist.toString());
- continue trials;
- }
- if (Double.isInfinite(test[i])) {
- LOG.warning("Got infinite value after fitting " + est.toString() + ": " + dist.toString());
- continue trials;
- }
- }
- Arrays.sort(test);
- double q = KolmogorovSmirnovTest.simpleTest(test);
- if (LOG.isVeryVerbose()) {
- LOG.veryverbose("Estimator " + est.toString() + " (" + dist.toString() + ") has maximum deviation " + q + " for dimension " + d);
- }
- if (best == null || q < bestq) {
- best = dist;
- bestq = q;
- }
- } catch (ArithmeticException e) {
- if (LOG.isVeryVerbose()) {
- LOG.veryverbose("Fitting distribution " + est + " failed: " + e.getMessage());
- }
- continue;
- }
- }
- if (LOG.isVerbose()) {
- LOG.verbose("Best fit for dimension " + d + ": " + best.toString());
- }
- dists.add(best);
+ Distribution dist;
+ if(estimators.size() == 1) {
+ dist = estimators.get(0).estimate(castColumn, adapter);
+ }
+ else {
+ dist = findBestFit(castColumn, adapter, d, test);
+ }
+ // Special handling for constant distributions:
+ // We want them to remain 0, instead of - usually - becoming constant .5
+ if(dist instanceof UniformDistribution) {
+ dist = constantZero(castColumn, adapter) ? new UniformDistribution(0., 1.) : dist;
}
+ dists.add(dist);
}
// Normalization scan
double[] buf = new double[dim];
- for (int i = 0; i < objects.dataLength(); i++) {
+ for(int i = 0; i < objects.dataLength(); i++) {
final V obj = castColumn.get(i);
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
buf[d] = dists.get(d).cdf(obj.doubleValue(d));
}
castColumn.set(i, factory.newNumberVector(buf));
@@ -181,6 +159,71 @@ public class AttributeWiseCDFNormalization<V extends NumberVector<?>> implements
return objects;
}
+ /**
+ * Find the best fitting distribution.
+ *
+ * @param col Column of table
+ * @param adapter Adapter for accessing the data
+ * @param d Dimension
+ * @param test Scatch space for testing goodness of fit
+ * @return Best fit distribution
+ */
+ protected Distribution findBestFit(final List<V> col, Adapter adapter, int d, double[] test) {
+ Distribution best = null;
+ double bestq = Double.POSITIVE_INFINITY;
+ trials: for(DistributionEstimator<?> est : estimators) {
+ try {
+ Distribution dist = est.estimate(col, adapter);
+ for(int i = 0; i < test.length; i++) {
+ test[i] = dist.cdf(col.get(i).doubleValue(d));
+ if(Double.isNaN(test[i])) {
+ LOG.warning("Got NaN after fitting " + est.toString() + ": " + dist.toString());
+ continue trials;
+ }
+ if(Double.isInfinite(test[i])) {
+ LOG.warning("Got infinite value after fitting " + est.toString() + ": " + dist.toString());
+ continue trials;
+ }
+ }
+ Arrays.sort(test);
+ double q = KolmogorovSmirnovTest.simpleTest(test);
+ if(LOG.isVeryVerbose()) {
+ LOG.veryverbose("Estimator " + est.toString() + " (" + dist.toString() + ") has maximum deviation " + q + " for dimension " + d);
+ }
+ if(best == null || q < bestq) {
+ best = dist;
+ bestq = q;
+ }
+ }
+ catch(ArithmeticException e) {
+ if(LOG.isVeryVerbose()) {
+ LOG.veryverbose("Fitting distribution " + est + " failed: " + e.getMessage());
+ }
+ continue trials;
+ }
+ }
+ if(LOG.isVerbose()) {
+ LOG.verbose("Best fit for dimension " + d + ": " + best.toString());
+ }
+ return best;
+ }
+
+ /**
+ * Test if an attribute is constant zero.
+ *
+ * @param column Column
+ * @param adapter Data accessor.
+ * @return {@code true} if all values are zero
+ */
+ protected boolean constantZero(List<V> column, Adapter adapter) {
+ for(int i = 0, s = adapter.size(column); i < s; i++) {
+ if(adapter.get(column, i) != 0.) {
+ return false;
+ }
+ }
+ return true;
+ }
+
@Override
public V restore(V featureVector) throws NonNumericFeaturesException {
throw new UnsupportedOperationException(ExceptionMessages.UNSUPPORTED_NOT_YET);
@@ -198,8 +241,8 @@ public class AttributeWiseCDFNormalization<V extends NumberVector<?>> implements
result.append('\n');
result.append("normalization distributions: ");
boolean first = true;
- for (DistributionEstimator<?> est : estimators) {
- if (!first) {
+ for(DistributionEstimator<?> est : estimators) {
+ if(!first) {
result.append(',');
}
first = false;
@@ -212,52 +255,52 @@ public class AttributeWiseCDFNormalization<V extends NumberVector<?>> implements
* Array adapter class for vectors.
*
* @author Erich Schubert
- *
+ *
* @apiviz.exclude
*/
- private static class Adapter implements NumberArrayAdapter<Double, List<? extends NumberVector<?>>> {
+ private static class Adapter implements NumberArrayAdapter<Double, List<? extends NumberVector>> {
/**
* Dimension to process.
*/
int dim;
@Override
- public int size(List<? extends NumberVector<?>> array) {
+ public int size(List<? extends NumberVector> array) {
return array.size();
}
@Override
- public Double get(List<? extends NumberVector<?>> array, int off) throws IndexOutOfBoundsException {
+ public Double get(List<? extends NumberVector> array, int off) throws IndexOutOfBoundsException {
return getDouble(array, off);
}
@Override
- public double getDouble(List<? extends NumberVector<?>> array, int off) throws IndexOutOfBoundsException {
+ public double getDouble(List<? extends NumberVector> array, int off) throws IndexOutOfBoundsException {
return array.get(off).doubleValue(dim);
}
@Override
- public float getFloat(List<? extends NumberVector<?>> array, int off) throws IndexOutOfBoundsException {
+ public float getFloat(List<? extends NumberVector> array, int off) throws IndexOutOfBoundsException {
return array.get(off).floatValue(dim);
}
@Override
- public int getInteger(List<? extends NumberVector<?>> array, int off) throws IndexOutOfBoundsException {
+ public int getInteger(List<? extends NumberVector> array, int off) throws IndexOutOfBoundsException {
return array.get(off).intValue(dim);
}
@Override
- public short getShort(List<? extends NumberVector<?>> array, int off) throws IndexOutOfBoundsException {
+ public short getShort(List<? extends NumberVector> array, int off) throws IndexOutOfBoundsException {
return array.get(off).shortValue(dim);
}
@Override
- public long getLong(List<? extends NumberVector<?>> array, int off) throws IndexOutOfBoundsException {
+ public long getLong(List<? extends NumberVector> array, int off) throws IndexOutOfBoundsException {
return array.get(off).longValue(dim);
}
@Override
- public byte getByte(List<? extends NumberVector<?>> array, int off) throws IndexOutOfBoundsException {
+ public byte getByte(List<? extends NumberVector> array, int off) throws IndexOutOfBoundsException {
return array.get(off).byteValue(dim);
}
}
@@ -269,7 +312,7 @@ public class AttributeWiseCDFNormalization<V extends NumberVector<?>> implements
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* Parameter for distribution estimators.
*/
@@ -287,7 +330,7 @@ public class AttributeWiseCDFNormalization<V extends NumberVector<?>> implements
List<Class<? extends DistributionEstimator<?>>> def = new ArrayList<>(1);
def.add(BestFitEstimator.class);
estP.setDefaultValue(def);
- if (config.grab(estP)) {
+ if(config.grab(estP)) {
estimators = estP.instantiateClasses(config);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseErfNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseErfNormalization.java
index 9a263171..e4af3a92 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseErfNormalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseErfNormalization.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
+package de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise;
/*
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,10 @@ package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
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.datasource.filter.normalization.AbstractNormalization;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.statistics.distribution.NormalDistribution;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
/**
* Attribute-wise Normalization using the error function. This mostly makes
@@ -35,11 +37,12 @@ import de.lmu.ifi.dbs.elki.math.statistics.distribution.NormalDistribution;
*
* @author Erich Schubert
*
- * @param <O> Object type
+ * @param <V> Object type
*
* @apiviz.uses NumberVector
*/
-public class AttributeWiseErfNormalization<O extends NumberVector<?>> extends AbstractNormalization<O> {
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.AttributeWiseErfNormalization"})
+public class AttributeWiseErfNormalization<V extends NumberVector> extends AbstractNormalization<V> {
/**
* Class logger.
*/
@@ -53,26 +56,21 @@ public class AttributeWiseErfNormalization<O extends NumberVector<?>> extends Ab
}
@Override
- public O restore(O featureVector) {
- throw new UnsupportedOperationException("Not implemented yet.");
- }
-
- @Override
- protected O filterSingleObject(O obj) {
+ protected V filterSingleObject(V obj) {
double[] val = new double[obj.getDimensionality()];
- for (int i = 0; i < val.length; i++) {
+ for(int i = 0; i < val.length; i++) {
val[i] = NormalDistribution.erf(obj.doubleValue(i));
}
return factory.newNumberVector(val);
}
@Override
- protected SimpleTypeInformation<? super O> getInputTypeRestriction() {
- return TypeUtil.NUMBER_VECTOR_FIELD;
+ protected Logging getLogger() {
+ return LOG;
}
@Override
- protected Logging getLogger() {
- return LOG;
+ protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_FIELD;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseMADNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseMADNormalization.java
index 8c4f15e1..ec50aadd 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseMADNormalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseMADNormalization.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
+package de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise;
/*
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,10 +31,13 @@ import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
import de.lmu.ifi.dbs.elki.datasource.filter.FilterUtil;
+import de.lmu.ifi.dbs.elki.datasource.filter.normalization.NonNumericFeaturesException;
+import de.lmu.ifi.dbs.elki.datasource.filter.normalization.Normalization;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.linearalgebra.LinearEquationSystem;
import de.lmu.ifi.dbs.elki.math.statistics.distribution.NormalDistribution;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.datastructures.QuickSelect;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
@@ -54,7 +57,8 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
* @apiviz.uses NumberVector
*/
// TODO: extract superclass AbstractAttributeWiseNormalization
-public class AttributeWiseMADNormalization<V extends NumberVector<?>> implements Normalization<V> {
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.AttributeWiseMADNormalization"})
+public class AttributeWiseMADNormalization<V extends NumberVector> implements Normalization<V> {
/**
* Class logger.
*/
@@ -63,7 +67,7 @@ public class AttributeWiseMADNormalization<V extends NumberVector<?>> implements
/**
* Number vector factory.
*/
- protected NumberVector.Factory<V, ?> factory;
+ protected NumberVector.Factory<V> factory;
/**
* Stores the median in each dimension.
@@ -71,9 +75,9 @@ public class AttributeWiseMADNormalization<V extends NumberVector<?>> implements
private double[] median = new double[0];
/**
- * Stores the median absolute deviation in each dimension.
+ * Stores the inverse median absolute deviation in each dimension.
*/
- private double[] madsigma = new double[0];
+ private double[] imadsigma = new double[0];
/**
* Constructor.
@@ -84,13 +88,13 @@ public class AttributeWiseMADNormalization<V extends NumberVector<?>> implements
@Override
public MultipleObjectsBundle filter(MultipleObjectsBundle objects) {
- if (objects.dataLength() == 0) {
+ if(objects.dataLength() == 0) {
return objects;
}
- for (int r = 0; r < objects.metaLength(); r++) {
+ for(int r = 0; r < objects.metaLength(); r++) {
SimpleTypeInformation<?> type = (SimpleTypeInformation<?>) objects.meta(r);
final List<?> column = (List<?>) objects.getColumn(r);
- if (!TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(type)) {
+ if(!TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(type)) {
continue;
}
@SuppressWarnings("unchecked")
@@ -103,61 +107,72 @@ public class AttributeWiseMADNormalization<V extends NumberVector<?>> implements
// Scan to find the best
final int dim = castType.getDimensionality();
median = new double[dim];
- madsigma = new double[dim];
+ imadsigma = new double[dim];
// Scratch space for testing:
double[] test = new double[castColumn.size()];
FiniteProgress dprog = LOG.isVerbose() ? new FiniteProgress("Analyzing data.", dim, LOG) : null;
// We iterate over dimensions, this kind of filter needs fast random
// access.
- for (int d = 0; d < dim; d++) {
- for (int i = 0; i < test.length; i++) {
+ for(int d = 0; d < dim; d++) {
+ for(int i = 0; i < test.length; i++) {
test[i] = castColumn.get(i).doubleValue(d);
}
final double med = QuickSelect.median(test);
median[d] = med;
- for (int i = 0; i < test.length; i++) {
+ int zeros = 0;
+ for(int i = 0; i < test.length; i++) {
test[i] = Math.abs(test[i] - med);
+ if(test[i] == 0.) {
+ zeros++;
+ }
}
// Rescale the true MAD for the best standard deviation estimate:
- madsigma[d] = QuickSelect.median(test) * NormalDistribution.ONEBYPHIINV075;
- if (dprog != null) {
- dprog.incrementProcessed(LOG);
+ if(zeros < (test.length >>> 1)) {
+ imadsigma[d] = NormalDistribution.PHIINV075 / QuickSelect.median(test);
}
+ else if(zeros == test.length) {
+ LOG.warning("Constant attribute detected. Using MAD=1.");
+ imadsigma[d] = 1.; // Does not matter. Constant distribution.
+ }
+ else {
+ // We have more than 50% zeros, so the regular MAD estimate does not
+ // work. Generalize the MAD approach to use the 50% non-zero value:
+ final int rank = zeros + ((test.length - zeros) >> 1);
+ final double rel = .5 + rank * .5 / test.length;
+ imadsigma[d] = NormalDistribution.quantile(0., 1., rel) / QuickSelect.quickSelect(test, rank);
+ LOG.warning("Near-constant attribute detected. Using modified MAD.");
+ }
+ LOG.incrementProcessed(dprog);
}
- if (dprog != null) {
- dprog.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(dprog);
FiniteProgress nprog = LOG.isVerbose() ? new FiniteProgress("Data normalization.", objects.dataLength(), LOG) : null;
// Normalization scan
double[] buf = new double[dim];
- for (int i = 0; i < objects.dataLength(); i++) {
+ for(int i = 0; i < objects.dataLength(); i++) {
final V obj = castColumn.get(i);
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
buf[d] = normalize(d, obj.doubleValue(d));
}
castColumn.set(i, factory.newNumberVector(buf));
- if (nprog != null) {
- nprog.incrementProcessed(LOG);
- }
- }
- if (nprog != null) {
- nprog.ensureCompleted(LOG);
+ LOG.incrementProcessed(nprog);
}
+ LOG.ensureCompleted(nprog);
}
return objects;
}
@Override
public V restore(V featureVector) throws NonNumericFeaturesException {
- if (featureVector.getDimensionality() == median.length) {
+ if(featureVector.getDimensionality() == median.length) {
double[] values = new double[featureVector.getDimensionality()];
- for (int d = 0; d < featureVector.getDimensionality(); d++) {
+ for(int d = 0; d < featureVector.getDimensionality(); d++) {
values[d] = restore(d, featureVector.doubleValue(d));
}
return factory.newNumberVector(values);
- } else {
+ }
+ else {
throw new NonNumericFeaturesException("Attributes cannot be resized: current dimensionality: " + featureVector.getDimensionality() + " former dimensionality: " + median.length);
}
}
@@ -175,7 +190,7 @@ public class AttributeWiseMADNormalization<V extends NumberVector<?>> implements
* @return Normalized value
*/
private double normalize(int d, double val) {
- return (val - median[d]) / madsigma[d];
+ return (val - median[d]) * imadsigma[d];
}
/**
@@ -186,7 +201,7 @@ public class AttributeWiseMADNormalization<V extends NumberVector<?>> implements
* @return Normalized value
*/
private double restore(int d, double val) {
- return (val * madsigma[d]) + median[d];
+ return (val / imadsigma[d]) + median[d];
}
@Override
@@ -196,7 +211,7 @@ public class AttributeWiseMADNormalization<V extends NumberVector<?>> implements
result.append('\n');
result.append("normalization median: ").append(FormatUtil.format(median));
result.append('\n');
- result.append("normalization MAD sigma: ").append(FormatUtil.format(madsigma));
+ result.append("normalization scaling factor: ").append(FormatUtil.format(imadsigma));
return result.toString();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseMeanNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseMeanNormalization.java
new file mode 100644
index 00000000..1039ab5b
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseMeanNormalization.java
@@ -0,0 +1,207 @@
+package de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise;
+
+/*
+ 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.datasource.filter.normalization.AbstractNormalization;
+import de.lmu.ifi.dbs.elki.datasource.filter.normalization.NonNumericFeaturesException;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.LinearEquationSystem;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
+
+/**
+ * Normalization designed for data with a <em>meaningful zero</em>: Each
+ * attribute is scaled to have the same mean (but 0 is not changed).
+ *
+ * @author Erich Schubert
+ * @param <V> vector type
+ *
+ * @apiviz.uses NumberVector
+ */
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.AttributeWiseMeanNormalization"})
+public class AttributeWiseMeanNormalization<V extends NumberVector> extends AbstractNormalization<V> {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(AttributeWiseMeanNormalization.class);
+
+ /**
+ * Stores the mean in each dimension.
+ */
+ private double[] mean = null;
+
+ /**
+ * Temporary storage used during initialization.
+ */
+ double[] sums = null;
+
+ /**
+ * Count the number of values seen.
+ */
+ int c = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param mean Mean value
+ */
+ public AttributeWiseMeanNormalization(double[] mean) {
+ super();
+ this.mean = mean;
+ }
+
+ /**
+ * Constructor.
+ */
+ public AttributeWiseMeanNormalization() {
+ super();
+ }
+
+ @Override
+ protected boolean prepareStart(SimpleTypeInformation<V> in) {
+ return (mean == null || mean.length == 0);
+ }
+
+ @Override
+ protected void prepareProcessInstance(V featureVector) {
+ // First object? Then init. (We didn't have a dimensionality before!)
+ if(sums == null || sums.length == 0) {
+ int dimensionality = featureVector.getDimensionality();
+ sums = new double[dimensionality];
+ }
+ for(int d = 0; d < featureVector.getDimensionality(); d++) {
+ sums[d] += featureVector.doubleValue(d);
+ }
+ ++c;
+ }
+
+ @Override
+ protected void prepareComplete() {
+ StringBuilder buf = LOG.isVerbose() ? new StringBuilder() : null;
+ final int dimensionality = sums.length;
+ mean = new double[dimensionality];
+ if(buf != null) {
+ buf.append("Normalization parameters: ");
+ }
+ for(int d = 0; d < dimensionality; d++) {
+ mean[d] = sums[d] / c;
+ if(buf != null) {
+ buf.append(" m: ").append(mean[d]);
+ }
+ }
+ sums = null;
+ if(buf != null) {
+ LOG.debugFine(buf.toString());
+ }
+ }
+
+ @Override
+ protected V filterSingleObject(V featureVector) {
+ double[] values = new double[featureVector.getDimensionality()];
+ for(int d = 0; d < featureVector.getDimensionality(); d++) {
+ values[d] = normalize(d, featureVector.doubleValue(d));
+ }
+ return factory.newNumberVector(values);
+ }
+
+ @Override
+ public V restore(V featureVector) throws NonNumericFeaturesException {
+ if(featureVector.getDimensionality() != mean.length) {
+ throw new NonNumericFeaturesException("Attributes cannot be resized: current dimensionality: " + featureVector.getDimensionality() + " former dimensionality: " + mean.length);
+ }
+ double[] values = new double[featureVector.getDimensionality()];
+ for(int d = 0; d < featureVector.getDimensionality(); d++) {
+ values[d] = restore(d, featureVector.doubleValue(d));
+ }
+ return factory.newNumberVector(values);
+ }
+
+ /**
+ * Normalize a single dimension.
+ *
+ * @param d Dimension
+ * @param val Value
+ * @return Normalized value
+ */
+ private double normalize(int d, double val) {
+ d = (mean.length == 1) ? 0 : d;
+ return val / mean[d];
+ }
+
+ /**
+ * Restore a single dimension.
+ *
+ * @param d Dimension
+ * @param val Value
+ * @return Normalized value
+ */
+ private double restore(int d, double val) {
+ d = (mean.length == 1) ? 0 : d;
+ return val * mean[d];
+ }
+
+ @Override
+ public LinearEquationSystem transform(LinearEquationSystem linearEquationSystem) {
+ double[][] coeff = linearEquationSystem.getCoefficents();
+ double[] rhs = linearEquationSystem.getRHS();
+ int[] row = linearEquationSystem.getRowPermutations();
+ int[] col = linearEquationSystem.getColumnPermutations();
+
+ for(int i = 0; i < coeff.length; i++) {
+ for(int r = 0; r < coeff.length; r++) {
+ double sum = 0.0;
+ for(int c = 0; c < coeff[0].length; c++) {
+ sum += coeff[row[r]][col[c]] / mean[c];
+ coeff[row[r]][col[c]] = coeff[row[r]][col[c]] / mean[c];
+ }
+ rhs[row[r]] = rhs[row[r]] + sum;
+ }
+ }
+
+ return new LinearEquationSystem(coeff, rhs, row, col);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+ result.append("normalization class: ").append(getClass().getName());
+ result.append('\n');
+ result.append("normalization means: ").append(FormatUtil.format(mean));
+
+ return result.toString();
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ @Override
+ protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_FIELD;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseMinMaxNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseMinMaxNormalization.java
index 47b6db5f..26a125ad 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseMinMaxNormalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseMinMaxNormalization.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
+package de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise;
/*
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,11 @@ package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
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.datasource.filter.normalization.AbstractNormalization;
+import de.lmu.ifi.dbs.elki.datasource.filter.normalization.NonNumericFeaturesException;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.linearalgebra.LinearEquationSystem;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -46,24 +49,14 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleListParamet
*
* @apiviz.uses NumberVector
*/
-// TODO: extract superclass AbstractAttributeWiseNormalization
-public class AttributeWiseMinMaxNormalization<V extends NumberVector<?>> extends AbstractNormalization<V> {
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.AttributeWiseMinMaxNormalization"})
+public class AttributeWiseMinMaxNormalization<V extends NumberVector> extends AbstractNormalization<V> {
/**
* Class logger.
*/
private static final Logging LOG = Logging.getLogger(AttributeWiseMinMaxNormalization.class);
/**
- * Parameter for minimum.
- */
- public static final OptionID MINIMA_ID = new OptionID("normalize.min", "a comma separated concatenation of the minimum values in each dimension that are mapped to 0. If no value is specified, the minimum value of the attribute range in this dimension will be taken.");
-
- /**
- * Parameter for maximum.
- */
- public static final OptionID MAXIMA_ID = new OptionID("normalize.max", "a comma separated concatenation of the maximum values in each dimension that are mapped to 1. If no value is specified, the maximum value of the attribute range in this dimension will be taken.");
-
- /**
* Stores the maximum in each dimension.
*/
private double[] maxima = new double[0];
@@ -130,16 +123,14 @@ public class AttributeWiseMinMaxNormalization<V extends NumberVector<?>> extends
@Override
public V restore(V featureVector) throws NonNumericFeaturesException {
- if(featureVector.getDimensionality() == maxima.length && featureVector.getDimensionality() == minima.length) {
- double[] values = new double[featureVector.getDimensionality()];
- for(int d = 0; d < featureVector.getDimensionality(); d++) {
- values[d] = (featureVector.doubleValue(d) * (factor(d)) + minima[d]);
- }
- return factory.newNumberVector(values);
- }
- else {
+ if(featureVector.getDimensionality() != maxima.length || featureVector.getDimensionality() != minima.length) {
throw new NonNumericFeaturesException("Attributes cannot be resized: current dimensionality: " + featureVector.getDimensionality() + " former dimensionality: " + maxima.length);
}
+ double[] values = new double[featureVector.getDimensionality()];
+ for(int d = 0; d < featureVector.getDimensionality(); d++) {
+ values[d] = featureVector.doubleValue(d) * factor(d) + minima[d];
+ }
+ return factory.newNumberVector(values);
}
/**
@@ -174,8 +165,7 @@ public class AttributeWiseMinMaxNormalization<V extends NumberVector<?>> extends
}
}
- LinearEquationSystem lq = new LinearEquationSystem(coeff, rhs, row, col);
- return lq;
+ return new LinearEquationSystem(coeff, rhs, row, col);
}
@Override
@@ -190,13 +180,13 @@ public class AttributeWiseMinMaxNormalization<V extends NumberVector<?>> extends
}
@Override
- protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
- return TypeUtil.NUMBER_VECTOR_FIELD;
+ protected Logging getLogger() {
+ return LOG;
}
@Override
- protected Logging getLogger() {
- return LOG;
+ protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_FIELD;
}
/**
@@ -206,7 +196,17 @@ public class AttributeWiseMinMaxNormalization<V extends NumberVector<?>> extends
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * Parameter for minimum.
+ */
+ public static final OptionID MINIMA_ID = new OptionID("normalize.min", "a comma separated concatenation of the minimum values in each dimension that are mapped to 0. If no value is specified, the minimum value of the attribute range in this dimension will be taken.");
+
+ /**
+ * Parameter for maximum.
+ */
+ public static final OptionID MAXIMA_ID = new OptionID("normalize.max", "a comma separated concatenation of the maximum values in each dimension that are mapped to 1. If no value is specified, the maximum value of the attribute range in this dimension will be taken.");
+
/**
* Stores the maximum in each dimension.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseVarianceNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseVarianceNormalization.java
index a24cae25..a7241441 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/AttributeWiseVarianceNormalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/AttributeWiseVarianceNormalization.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
+package de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise;
/*
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,9 +26,12 @@ package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
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.datasource.filter.normalization.AbstractNormalization;
+import de.lmu.ifi.dbs.elki.datasource.filter.normalization.NonNumericFeaturesException;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
import de.lmu.ifi.dbs.elki.math.linearalgebra.LinearEquationSystem;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -48,32 +51,22 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleListParamet
*
* @apiviz.uses NumberVector
*/
-// TODO: extract superclass AbstractAttributeWiseNormalization
-public class AttributeWiseVarianceNormalization<V extends NumberVector<?>> extends AbstractNormalization<V> {
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.AttributeWiseVarianceNormalization", "z" })
+public class AttributeWiseVarianceNormalization<V extends NumberVector> extends AbstractNormalization<V> {
/**
* Class logger.
*/
private static final Logging LOG = Logging.getLogger(AttributeWiseVarianceNormalization.class);
/**
- * Parameter for means.
- */
- public static final OptionID MEAN_ID = new OptionID("normalize.mean", "a comma separated concatenation of the mean values in each dimension that are mapped to 0. If no value is specified, the mean value of the attribute range in this dimension will be taken.");
-
- /**
- * Parameter for stddevs.
- */
- public static final OptionID STDDEV_ID = new OptionID("normalize.stddev", "a comma separated concatenation of the standard deviations in each dimension that are scaled to 1. If no value is specified, the standard deviation of the attribute range in this dimension will be taken.");
-
- /**
* Stores the mean in each dimension.
*/
- private double[] mean = new double[0];
+ private double[] mean;
/**
* Stores the standard deviation in each dimension.
*/
- private double[] stddev = new double[0];
+ private double[] stddev;
/**
* Temporary storage used during initialization.
@@ -152,16 +145,14 @@ public class AttributeWiseVarianceNormalization<V extends NumberVector<?>> exten
@Override
public V restore(V featureVector) throws NonNumericFeaturesException {
- if(featureVector.getDimensionality() == mean.length) {
- double[] values = new double[featureVector.getDimensionality()];
- for(int d = 0; d < featureVector.getDimensionality(); d++) {
- values[d] = restore(d, featureVector.doubleValue(d));
- }
- return factory.newNumberVector(values);
- }
- else {
+ if(featureVector.getDimensionality() != mean.length) {
throw new NonNumericFeaturesException("Attributes cannot be resized: current dimensionality: " + featureVector.getDimensionality() + " former dimensionality: " + mean.length);
}
+ double[] values = new double[featureVector.getDimensionality()];
+ for(int d = 0; d < featureVector.getDimensionality(); d++) {
+ values[d] = restore(d, featureVector.doubleValue(d));
+ }
+ return factory.newNumberVector(values);
}
/**
@@ -172,12 +163,8 @@ public class AttributeWiseVarianceNormalization<V extends NumberVector<?>> exten
* @return Normalized value
*/
private double normalize(int d, double val) {
- if(mean.length == 1) {
- return (val - mean[0]) / stddev[0];
- }
- else {
- return (val - mean[d]) / stddev[d];
- }
+ d = (mean.length == 1) ? 0 : d;
+ return (val - mean[d]) / stddev[d];
}
/**
@@ -188,12 +175,8 @@ public class AttributeWiseVarianceNormalization<V extends NumberVector<?>> exten
* @return Normalized value
*/
private double restore(int d, double val) {
- if(mean.length == 1) {
- return (val * stddev[0]) + mean[0];
- }
- else {
- return (val * stddev[d]) + mean[d];
- }
+ d = (mean.length == 1) ? 0 : d;
+ return (val * stddev[d]) + mean[d];
}
@Override
@@ -214,13 +197,7 @@ public class AttributeWiseVarianceNormalization<V extends NumberVector<?>> exten
}
}
- LinearEquationSystem lq = new LinearEquationSystem(coeff, rhs, row, col);
- return lq;
- }
-
- @Override
- protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
- return TypeUtil.NUMBER_VECTOR_FIELD;
+ return new LinearEquationSystem(coeff, rhs, row, col);
}
@Override
@@ -240,6 +217,11 @@ public class AttributeWiseVarianceNormalization<V extends NumberVector<?>> exten
return LOG;
}
+ @Override
+ protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_FIELD;
+ }
+
/**
* Parameterization class.
*
@@ -247,7 +229,17 @@ public class AttributeWiseVarianceNormalization<V extends NumberVector<?>> exten
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * Parameter for means.
+ */
+ public static final OptionID MEAN_ID = new OptionID("normalize.mean", "a comma separated concatenation of the mean values in each dimension that are mapped to 0. If no value is specified, the mean value of the attribute range in this dimension will be taken.");
+
+ /**
+ * Parameter for stddevs.
+ */
+ public static final OptionID STDDEV_ID = new OptionID("normalize.stddev", "a comma separated concatenation of the standard deviations in each dimension that are scaled to 1. If no value is specified, the standard deviation of the attribute range in this dimension will be taken.");
+
/**
* Stores the mean in each dimension.
*/
@@ -261,22 +253,22 @@ public class AttributeWiseVarianceNormalization<V extends NumberVector<?>> exten
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- DoubleListParameter meanP = new DoubleListParameter(MEAN_ID, true);
- DoubleListParameter stddevP = new DoubleListParameter(STDDEV_ID, true);
- config.grab(meanP);
- config.grab(stddevP);
- // Note: grab first, then use isDefined, to ensure the stddev is grabbed.
- if(meanP.isDefined() && stddevP.isDefined()) {
+ DoubleListParameter meanP = new DoubleListParameter(MEAN_ID) //
+ .setOptional(true);
+ if(config.grab(meanP)) {
mean = ArrayLikeUtil.toPrimitiveDoubleArray(meanP.getValue());
+ }
+ DoubleListParameter stddevP = new DoubleListParameter(STDDEV_ID) //
+ .setOptional(true);
+ if(config.grab(stddevP)) {
stddev = ArrayLikeUtil.toPrimitiveDoubleArray(stddevP.getValue());
for(double d : stddev) {
- if(d == 0) {
+ if(d == 0.) {
config.reportError(new WrongParameterValueException("Standard deviations must not be 0."));
}
}
}
-
config.checkConstraint(new AllOrNoneMustBeSetGlobalConstraint(meanP, stddevP));
config.checkConstraint(new EqualSizeGlobalConstraint(meanP, stddevP));
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/RankTieNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/IntegerRankTieNormalization.java
index bb9c2aec..ca320ec6 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/RankTieNormalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/IntegerRankTieNormalization.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
+package de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise;
/*
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.datasource.filter.normalization;
*/
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import de.lmu.ifi.dbs.elki.data.IntegerVector;
@@ -34,21 +33,25 @@ import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
import de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerArrayQuickSort;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerComparator;
/**
* Normalize vectors according to their rank in the attributes.
*
- * Note: ranks are multiplied by 2, to be able to give ties an integer rank.
- * (e.g. first two records are tied at "1" then, followed by the next on "4")
+ * Note: <b>ranks are multiplied by 2</b>, to be able to give ties an integer
+ * rank. (e.g. when the first two records are tied, they both have rank "1"
+ * then, followed by the next on "4")
*
* @author Erich Schubert
*/
-public class RankTieNormalization implements ObjectFilter {
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.IntegerRankTieNormalization"})
+public class IntegerRankTieNormalization implements ObjectFilter {
/**
* Constructor.
*/
- public RankTieNormalization() {
+ public IntegerRankTieNormalization() {
super();
}
@@ -57,6 +60,12 @@ public class RankTieNormalization implements ObjectFilter {
final int len = objects.dataLength();
MultipleObjectsBundle bundle = new MultipleObjectsBundle();
+ int[] order = new int[len];
+ for(int i = 0; i < len; i++) {
+ order[i] = i;
+ }
+ Sorter comparator = new Sorter();
+
for(int r = 0; r < objects.metaLength(); r++) {
final SimpleTypeInformation<?> type = objects.meta(r);
final List<?> column = objects.getColumn(r);
@@ -65,7 +74,7 @@ public class RankTieNormalization implements ObjectFilter {
continue;
}
@SuppressWarnings("unchecked")
- final List<? extends NumberVector<?>> castColumn = (List<? extends NumberVector<?>>) column;
+ final List<? extends NumberVector> castColumn = (List<? extends NumberVector>) column;
// Get the replacement type information
final int dim = ((VectorFieldTypeInformation<?>) type).getDimensionality();
final VectorFieldTypeInformation<IntegerVector> outType = new VectorFieldTypeInformation<>(IntegerVector.STATIC, dim);
@@ -73,29 +82,21 @@ public class RankTieNormalization implements ObjectFilter {
// Output vectors
int[][] posvecs = new int[len][dim];
// Sort for each dimension
- // TODO: an int[] array would be enough, if we could use a comparator...
- DoubleIntPair[] sorter = new DoubleIntPair[len];
- for(int i = 0; i < sorter.length; i++) {
- sorter[i] = new DoubleIntPair(Double.NaN, -1);
- }
for(int d = 0; d < dim; d++) {
- // fill array
- for(int i = 0; i < sorter.length; i++) {
- sorter[i].first = castColumn.get(i).doubleValue(d);
- sorter[i].second = i;
- }
// Sort
- Arrays.sort(sorter);
+ comparator.setup(castColumn, d);
+ IntegerArrayQuickSort.sort(order, comparator);
// Transfer positions to output vectors
- for(int sta = 0; sta < sorter.length;) {
+ for(int sta = 0; sta < order.length;) {
+ double v = castColumn.get(order[sta]).doubleValue(d);
// Compute ties
int end = sta + 1;
- while(end < sorter.length && !(sorter[sta].first < sorter[end].first)) {
+ while(end < order.length && !(v < castColumn.get(order[end]).doubleValue(d))) {
end++;
}
final int pos = (sta + end - 1);
for(int i = sta; i < end; i++) {
- posvecs[sorter[i].second][d] = pos;
+ posvecs[order[i]][d] = pos;
}
sta = end;
}
@@ -110,4 +111,40 @@ public class RankTieNormalization implements ObjectFilter {
}
return bundle;
}
+
+ /**
+ * Class to sort an index array by a particular dimension.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ private static class Sorter implements IntegerComparator {
+ /**
+ * Column to use for sorting.
+ */
+ List<? extends NumberVector> col;
+
+ /**
+ * Dimension to use for sorting.
+ */
+ int dim;
+
+ /**
+ * Configure the sorting class.
+ *
+ * @param col Column to read
+ * @param dim Dimension to use.
+ */
+ public void setup(List<? extends NumberVector> col, int dim) {
+ this.col = col;
+ this.dim = dim;
+ }
+
+ @Override
+ public int compare(int x, int y) {
+ final double vx = col.get(x).doubleValue(dim), vy = col.get(y).doubleValue(dim);
+ return (vx < vy) ? -1 : (vx == vy) ? 0 : +1;
+ }
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/InverseDocumentFrequencyNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/InverseDocumentFrequencyNormalization.java
index 21263890..99054f83 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/InverseDocumentFrequencyNormalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/InverseDocumentFrequencyNormalization.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
+package de.lmu.ifi.dbs.elki.datasource.filter.normalization.columnwise;
/*
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,11 +29,13 @@ import gnu.trove.map.hash.TIntDoubleHashMap;
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.datasource.filter.normalization.AbstractNormalization;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
/**
- * Normalization for text frequency vectors, using the inverse document
- * frequency.
+ * Normalization for text frequency (TF) vectors, using the inverse document
+ * frequency (IDF). See also: TF-IDF for text analysis.
*
* @author Erich Schubert
*
@@ -41,7 +43,8 @@ import de.lmu.ifi.dbs.elki.logging.Logging;
*
* @param <V> Vector type
*/
-public class InverseDocumentFrequencyNormalization<V extends SparseNumberVector<?>> extends AbstractNormalization<V> {
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.InverseDocumentFrequencyNormalization" })
+public class InverseDocumentFrequencyNormalization<V extends SparseNumberVector> extends AbstractNormalization<V> {
/**
* Class logger.
*/
@@ -102,7 +105,7 @@ public class InverseDocumentFrequencyNormalization<V extends SparseNumberVector<
final int dim = featureVector.iterDim(it);
vals.put(dim, featureVector.iterDoubleValue(it) * idf.get(dim));
}
- return ((SparseNumberVector.Factory<V, ?>) factory).newNumberVector(vals, featureVector.getDimensionality());
+ return ((SparseNumberVector.Factory<V>) factory).newNumberVector(vals, featureVector.getDimensionality());
}
@Override
@@ -112,12 +115,12 @@ public class InverseDocumentFrequencyNormalization<V extends SparseNumberVector<
final int dim = featureVector.iterDim(it);
vals.put(dim, featureVector.iterDoubleValue(it) / idf.get(dim));
}
- return ((SparseNumberVector.Factory<V, ?>) factory).newNumberVector(vals, featureVector.getDimensionality());
+ return ((SparseNumberVector.Factory<V>) factory).newNumberVector(vals, featureVector.getDimensionality());
}
@Override
protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
- return TypeUtil.SPARSE_VECTOR_FIELD;
+ return TypeUtil.SPARSE_VECTOR_VARIABLE_LENGTH;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/package-info.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/package-info.java
new file mode 100644
index 00000000..f1fac885
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/columnwise/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Normalizations operating on columns / variates; where each column is treated independently.
+ */
+
+/*
+ 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.datasource.filter.normalization.columnwise; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/HellingerHistogramNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/HellingerHistogramNormalization.java
new file mode 100644
index 00000000..b2da96a9
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/HellingerHistogramNormalization.java
@@ -0,0 +1,97 @@
+package de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise;
+
+/*
+ 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.datasource.filter.normalization.AbstractStreamNormalization;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Normalize histograms by scaling them to L1 norm 1, then taking the square
+ * root in each attribute.
+ *
+ * Using Euclidean distance (linear kernel) and this transformation is the same
+ * as using Hellinger distance:
+ * {@link de.lmu.ifi.dbs.elki.distance.distancefunction.probabilistic.HellingerDistanceFunction}
+ *
+ * @author Erich Schubert
+ *
+ * @param <V> vector type
+ */
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.HellingerHistogramNormalization" })
+public class HellingerHistogramNormalization<V extends NumberVector> extends AbstractStreamNormalization<V> {
+ /**
+ * Static instance.
+ */
+ public static final HellingerHistogramNormalization<NumberVector> STATIC = new HellingerHistogramNormalization<>();
+
+ /**
+ * Constructor.
+ */
+ public HellingerHistogramNormalization() {
+ super();
+ }
+
+ @Override
+ protected V filterSingleObject(V featureVector) {
+ double[] data = new double[featureVector.getDimensionality()];
+ double sum = 0.;
+ for(int d = 0; d < data.length; ++d) {
+ data[d] = featureVector.doubleValue(d);
+ data[d] = data[d] > 0 ? data[d] : -data[d];
+ sum += data[d];
+ }
+ // Normalize and sqrt:
+ if(sum > 0.) {
+ for(int d = 0; d < data.length; ++d) {
+ if(data[d] > 0) {
+ data[d] = Math.sqrt(data[d] / sum);
+ }
+ }
+ }
+ return factory.newNumberVector(data);
+ }
+
+ @Override
+ protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected HellingerHistogramNormalization<NumberVector> makeInstance() {
+ return STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/InstanceMeanVarianceNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/InstanceMeanVarianceNormalization.java
new file mode 100644
index 00000000..05485909
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/InstanceMeanVarianceNormalization.java
@@ -0,0 +1,159 @@
+package de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise;
+
+/*
+ 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.data.type.VectorTypeInformation;
+import de.lmu.ifi.dbs.elki.datasource.filter.normalization.AbstractStreamNormalization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Normalize vectors such that they have zero mean and unit variance.
+ *
+ * @author Erich Schubert
+ *
+ * @param <V> vector type
+ */
+public class InstanceMeanVarianceNormalization<V extends NumberVector> extends AbstractStreamNormalization<V> {
+ /**
+ * Multiplicity of the vector.
+ */
+ private int multiplicity;
+
+ /**
+ * Constructor.
+ */
+ public InstanceMeanVarianceNormalization() {
+ super();
+ }
+
+ @Override
+ protected V filterSingleObject(V featureVector) {
+ double[] raw = featureVector.getColumnVector().getArrayRef();
+ if(raw.length == 0) {
+ return factory.newNumberVector(new double[] {});
+ }
+ if(raw.length == 1) {
+ // Constant, but preserve NaNs
+ return factory.newNumberVector(new double[] { raw[0] == raw[0] ? 0. : Double.NaN });
+ }
+ // Multivariate codepath:
+ if(multiplicity > 1) {
+ assert (raw.length % multiplicity == 0) : "Vector length is not divisible by multiplicity?";
+ return factory.newNumberVector(multivariateStandardization(raw));
+ }
+ return factory.newNumberVector(univariateStandardization(raw));
+ }
+
+ protected double[] univariateStandardization(double[] raw) {
+ // Two pass normalization is numerically most stable,
+ // And Java should optimize this well enough.
+ double sum = 0.;
+ for(int i = 0; i < raw.length; ++i) {
+ final double v = raw[i];
+ if(v != v) { // NaN guard
+ continue;
+ }
+ sum += v;
+ }
+ final double mean = sum / raw.length;
+ double ssum = 0.;
+ for(int i = 0; i < raw.length; ++i) {
+ double v = raw[i] - mean;
+ if(v != v) {
+ continue;
+ }
+ ssum += v * v;
+ }
+ final double std = Math.sqrt(ssum) / (raw.length - 1);
+ if(std > 0.) {
+ for(int i = 0; i < raw.length; ++i) {
+ raw[i] = (raw[i] - mean) / std;
+ }
+ }
+ return raw;
+ }
+
+ protected double[] multivariateStandardization(double[] raw) {
+ final int len = raw.length / multiplicity;
+ if(len <= 1) {
+ return raw;
+ }
+ // Two pass normalization is numerically most stable,
+ // And Java should optimize this well enough.
+ double[] mean = new double[multiplicity];
+ for(int i = 0, j = 0; i < raw.length; ++i, j = ++j % multiplicity) {
+ final double v = raw[i];
+ if(v != v) { // NaN guard
+ continue;
+ }
+ mean[j] += v;
+ }
+ for(int j = 0; j < multiplicity; ++j) {
+ mean[j] /= len;
+ }
+ double[] std = new double[multiplicity];
+ for(int i = 0, j = 0; i < raw.length; ++i, j = ++j % multiplicity) {
+ double v = raw[i] - mean[j];
+ if(v != v) {
+ continue;
+ }
+ std[j] += v * v;
+ }
+ for(int j = 0; j < multiplicity; ++j) {
+ std[j] = std[j] > 0. ? Math.sqrt(std[j]) / (len - 1) : 1;
+ }
+ for(int i = 0, j = 0; i < raw.length; ++i, j = ++j % multiplicity) {
+ raw[i] = (raw[i] - mean[j]) / std[j];
+ }
+ return raw;
+ }
+
+ @Override
+ protected void initializeOutputType(SimpleTypeInformation<V> type) {
+ super.initializeOutputType(type);
+ multiplicity = ((VectorTypeInformation<?>) type).getMultiplicity();
+ }
+
+ @Override
+ protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ @Override
+ protected InstanceMeanVarianceNormalization<V> makeInstance() {
+ return new InstanceMeanVarianceNormalization<>();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/InstanceMinMaxNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/InstanceMinMaxNormalization.java
new file mode 100644
index 00000000..9f8f7680
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/InstanceMinMaxNormalization.java
@@ -0,0 +1,177 @@
+package de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise;
+
+/*
+ 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.data.type.VectorTypeInformation;
+import de.lmu.ifi.dbs.elki.datasource.filter.normalization.AbstractStreamNormalization;
+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.LessGlobalConstraint;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
+/**
+ * Normalize vectors such that the smallest attribute is 0, the largest is 1.
+ *
+ * @author Erich Schubert
+ *
+ * @param <V> vector type
+ */
+public class InstanceMinMaxNormalization<V extends NumberVector> extends AbstractStreamNormalization<V> {
+ /**
+ * Minimum and maximum values.
+ */
+ private double min, max;
+
+ /**
+ * Multiplicity of the vector.
+ */
+ private int multiplicity;
+
+ /**
+ * Constructor.
+ *
+ * @param min Desired minimum value
+ * @param max Desired maximum value
+ */
+ public InstanceMinMaxNormalization(double min, double max) {
+ super();
+ this.min = min;
+ this.max = max;
+ }
+
+ /**
+ * Constructor, normalizing to {@code [0;1]}
+ */
+ public InstanceMinMaxNormalization() {
+ this(0., 1.);
+ }
+
+ @Override
+ protected V filterSingleObject(V featureVector) {
+ double[] raw = featureVector.getColumnVector().getArrayRef();
+ // Multivariate codepath:
+ if(multiplicity > 1) {
+ assert (raw.length % multiplicity == 0) : "Vector length is not divisible by multiplicity?";
+ double[] mi = new double[multiplicity], ma = new double[multiplicity];
+ for(int i = 0; i < multiplicity; i++) {
+ mi[i] = Double.POSITIVE_INFINITY;
+ ma[i] = Double.NEGATIVE_INFINITY;
+ }
+ for(int i = 0, j = 0; i < raw.length; ++i, j = ++j % multiplicity) {
+ final double v = raw[i];
+ if(v != v) { // NaN guard
+ continue;
+ }
+ mi[j] = (mi[j] < v) ? mi[j] : v;
+ ma[j] = (ma[j] > v) ? ma[j] : v;
+ }
+ for(int j = 0; j < multiplicity; j++) {
+ if(mi[j] < ma[j]) {
+ final double s = (max - min) / (ma[j] - mi[j]);
+ for(int i = 0; i < raw.length; i += multiplicity) {
+ raw[i] = (raw[i] - mi[j]) * s + min;
+ }
+ }
+ }
+ return factory.newNumberVector(raw);
+ }
+ // Default codepath
+ double mi = Double.POSITIVE_INFINITY, ma = Double.NEGATIVE_INFINITY;
+ for(int i = 0; i < raw.length; ++i) {
+ final double v = raw[i];
+ if(v != v) { // NaN guard
+ continue;
+ }
+ mi = (mi < v) ? mi : v;
+ ma = (ma > v) ? ma : v;
+ }
+ if(mi < ma) {
+ final double s = (max - min) / (ma - mi);
+ for(int i = 0; i < raw.length; ++i) {
+ raw[i] = (raw[i] - mi) * s + min;
+ }
+ }
+ return factory.newNumberVector(raw);
+ }
+
+ @Override
+ protected void initializeOutputType(SimpleTypeInformation<V> type) {
+ super.initializeOutputType(type);
+ multiplicity = ((VectorTypeInformation<?>) type).getMultiplicity();
+ }
+
+ @Override
+ protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * Option ID for minimum value.
+ */
+ public static final OptionID MIN_ID = new OptionID("normalization.min", "Minimum value to assign to objects.");
+
+ /**
+ * Option ID for maximum value.
+ */
+ public static final OptionID MAX_ID = new OptionID("normalization.max", "Maximum value to assign to objects.");
+
+ /**
+ * Minimum and maximum values.
+ */
+ private double min, max;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ DoubleParameter minP = new DoubleParameter(MIN_ID, 0.) //
+ .setOptional(true);
+ if(config.grab(minP)) {
+ min = minP.doubleValue();
+ }
+ DoubleParameter maxP = new DoubleParameter(MAX_ID, 1.) //
+ .setOptional(true);
+ if(config.grab(maxP)) {
+ max = maxP.doubleValue();
+ }
+ config.checkConstraint(new LessGlobalConstraint<>(minP, maxP));
+ }
+
+ @Override
+ protected InstanceMinMaxNormalization<V> makeInstance() {
+ return new InstanceMinMaxNormalization<>(min, max);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/LengthNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/LengthNormalization.java
index a12dea3b..51b2a34b 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/LengthNormalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/LengthNormalization.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
+package de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise;
/*
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
@@ -26,9 +26,10 @@ package de.lmu.ifi.dbs.elki.datasource.filter.normalization;
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.DoubleNorm;
+import de.lmu.ifi.dbs.elki.datasource.filter.normalization.AbstractStreamNormalization;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.Norm;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.LinearEquationSystem;
+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;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -42,42 +43,32 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @param <V> vector type
*/
-public class LengthNormalization<V extends NumberVector<?>> extends AbstractStreamNormalization<V> {
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.LengthNormalization"})
+public class LengthNormalization<V extends NumberVector> extends AbstractStreamNormalization<V> {
/**
* Norm to use.
*/
- DoubleNorm<? super V> norm;
+ Norm<? super V> norm;
/**
* Constructor.
*
* @param norm Norm to use
*/
- public LengthNormalization(DoubleNorm<? super V> norm) {
+ public LengthNormalization(Norm<? super V> norm) {
super();
this.norm = norm;
}
@Override
protected V filterSingleObject(V featureVector) {
- final double d = norm.doubleNorm(featureVector);
+ final double d = norm.norm(featureVector);
return factory.newNumberVector(featureVector.getColumnVector().timesEquals(1 / d).getArrayRef());
}
@Override
- public V restore(V featureVector) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public LinearEquationSystem transform(LinearEquationSystem linearEquationSystem) {
- // TODO.
- throw new UnsupportedOperationException();
- }
-
- @Override
protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
- return TypeUtil.NUMBER_VECTOR_FIELD;
+ return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH;
}
/**
@@ -87,7 +78,7 @@ public class LengthNormalization<V extends NumberVector<?>> extends AbstractStre
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* Option ID for normalization norm.
*/
@@ -96,12 +87,12 @@ public class LengthNormalization<V extends NumberVector<?>> extends AbstractStre
/**
* Norm to use.
*/
- DoubleNorm<? super V> norm;
+ Norm<? super V> norm;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- ObjectParameter<DoubleNorm<? super V>> normP = new ObjectParameter<>(NORM_ID, DoubleNorm.class, EuclideanDistanceFunction.class);
+ ObjectParameter<Norm<? super V>> normP = new ObjectParameter<>(NORM_ID, Norm.class, EuclideanDistanceFunction.class);
if(config.grab(normP)) {
norm = normP.instantiateClass(config);
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/Log1PlusNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/Log1PlusNormalization.java
new file mode 100644
index 00000000..8970e7ef
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/Log1PlusNormalization.java
@@ -0,0 +1,119 @@
+package de.lmu.ifi.dbs.elki.datasource.filter.normalization.instancewise;
+
+/*
+ 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.datasource.filter.normalization.AbstractStreamNormalization;
+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;
+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;
+
+/**
+ * Normalize the data set by applying log(1+|x|*b)/log(b+1) to any value. If the
+ * input data was in [0;1], then the resulting values will be in the same range.
+ *
+ * By default b=1, and thus the transformation is log2(1+|x|).
+ *
+ * @author Erich Schubert
+ *
+ * @param <V> vector type
+ */
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.Log1PlusNormalization" })
+public class Log1PlusNormalization<V extends NumberVector> extends AbstractStreamNormalization<V> {
+ /**
+ * Static instance.
+ */
+ public static final Log1PlusNormalization<NumberVector> STATIC = new Log1PlusNormalization<>(1.);
+
+ /**
+ * Boosting factor, and scaling coefficient.
+ */
+ protected double boost, scale;
+
+ /**
+ * Constructor.
+ *
+ * @param boost Boosting parameter
+ */
+ public Log1PlusNormalization(double boost) {
+ super();
+ this.boost = boost;
+ this.scale = 1. / Math.log1p(boost);
+ }
+
+ @Override
+ protected V filterSingleObject(V featureVector) {
+ double[] data = new double[featureVector.getDimensionality()];
+ for(int d = 0; d < data.length; ++d) {
+ data[d] = featureVector.doubleValue(d);
+ data[d] = Math.log1p((data[d] > 0 ? data[d] : -data[d]) * boost) * scale;
+ }
+ return factory.newNumberVector(data);
+ }
+
+ @Override
+ protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * Boosting factor parameter.
+ */
+ public static final OptionID BOOST_ID = new OptionID("log1pscale.boost", "Boosting factor. Larger values will yield a steeper curve.");
+
+ /**
+ * Boosting factor.
+ */
+ protected double boost;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter boostP = new DoubleParameter(BOOST_ID, 1.) //
+ .addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ if(config.grab(boostP)) {
+ boost = boostP.doubleValue();
+ }
+ }
+
+ @Override
+ protected Log1PlusNormalization<V> makeInstance() {
+ return new Log1PlusNormalization<>(boost);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/package-info.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/package-info.java
new file mode 100644
index 00000000..9ac613c0
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/instancewise/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Instancewise normalization, where each instance is normalized independently.
+ */
+
+/*
+ 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.datasource.filter.normalization.instancewise; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/package-info.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/package-info.java
index 15d689d7..552d7003 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/normalization/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/datasource/filter/package-info.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/package-info.java
index 87684499..249c3764 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/package-info.java
@@ -2,12 +2,13 @@
* <p>Data filtering, in particular for normalization and projection.</p>
*
* @apiviz.exclude de.lmu.ifi.dbs.elki.utilities.*
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.datasource.filter\.(normalization|transform)\.*
*/
/*
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/datasource/filter/ByLabelFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/selection/ByLabelFilter.java
index 66707da6..8683ca8c 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/ByLabelFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/selection/ByLabelFilter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter;
+package de.lmu.ifi.dbs.elki.datasource.filter.selection;
/*
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,15 @@ package de.lmu.ifi.dbs.elki.datasource.filter;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.lmu.ifi.dbs.elki.data.LabelList;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.datasource.bundle.BundleMeta;
+import de.lmu.ifi.dbs.elki.datasource.filter.AbstractStreamFilter;
import de.lmu.ifi.dbs.elki.logging.Logging;
+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;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -36,12 +39,13 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.PatternParameter;
/**
- * A filter to sort the data set by some label.
+ * A filter to select data set by their label.
*
* @author Erich Schubert
*
* @apiviz.uses LabelList oneway - - «reads»
*/
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.ByLabelFilter" })
public class ByLabelFilter extends AbstractStreamFilter {
/**
* Class logger
@@ -49,9 +53,9 @@ public class ByLabelFilter extends AbstractStreamFilter {
private static final Logging LOG = Logging.getLogger(ByLabelFilter.class);
/**
- * The filter pattern
+ * The filter pattern matcher
*/
- private final Pattern pattern;
+ private final Matcher matcher;
/**
* Inversion flag
@@ -71,7 +75,7 @@ public class ByLabelFilter extends AbstractStreamFilter {
*/
public ByLabelFilter(Pattern pattern, boolean inverted) {
super();
- this.pattern = pattern;
+ this.matcher = pattern.matcher("");
this.inverted = inverted;
}
@@ -91,7 +95,7 @@ public class ByLabelFilter extends AbstractStreamFilter {
Event ev = source.nextEvent();
switch(ev){
case END_OF_STREAM:
- if (lblcol < 0) {
+ if(lblcol < 0) {
LOG.warning("By label filter was used, but never saw a label relation!");
}
return Event.END_OF_STREAM;
@@ -114,7 +118,8 @@ public class ByLabelFilter extends AbstractStreamFilter {
boolean good = false;
final LabelList ll = (LabelList) l;
for(int i = 0; i < ll.size(); i++) {
- if(pattern.matcher(ll.get(i)).matches()) {
+ matcher.reset(ll.get(i));
+ if(matcher.matches()) {
good = true;
break;
}
@@ -124,7 +129,8 @@ public class ByLabelFilter extends AbstractStreamFilter {
}
}
else {
- if(!pattern.matcher(l.toString()).matches()) {
+ matcher.reset(l.toString());
+ if(!matcher.matches()) {
continue;
}
}
@@ -190,7 +196,7 @@ public class ByLabelFilter extends AbstractStreamFilter {
}
@Override
- protected Object makeInstance() {
+ protected ByLabelFilter makeInstance() {
return new ByLabelFilter(pattern, inverted);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/RandomSamplingStreamFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/selection/RandomSamplingStreamFilter.java
index a7e44d4d..3e1a3d89 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/RandomSamplingStreamFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/selection/RandomSamplingStreamFilter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter;
+package de.lmu.ifi.dbs.elki.datasource.filter.selection;
/*
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,9 @@ package de.lmu.ifi.dbs.elki.datasource.filter;
import java.util.Random;
import de.lmu.ifi.dbs.elki.datasource.bundle.BundleMeta;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.datasource.filter.AbstractStreamFilter;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+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;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -39,6 +41,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
*
* @author Erich Schubert
*/
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.RandomSamplingStreamFilter" })
public class RandomSamplingStreamFilter extends AbstractStreamFilter {
/**
* Probability
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/ShuffleObjectsFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/selection/ShuffleObjectsFilter.java
index 8afa8290..3fb77ce4 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/ShuffleObjectsFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/selection/ShuffleObjectsFilter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter;
+package de.lmu.ifi.dbs.elki.datasource.filter.selection;
/*
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,8 +28,10 @@ import java.util.List;
import java.util.Random;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter;
import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+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;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -40,6 +42,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
*
* @author Erich Schubert
*/
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.ShuffleObjectsFilter" })
public class ShuffleObjectsFilter implements ObjectFilter {
/**
* Class logger
@@ -73,18 +76,18 @@ public class ShuffleObjectsFilter implements ObjectFilter {
@Override
public MultipleObjectsBundle filter(MultipleObjectsBundle objects) {
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
LOG.debug("Shuffling the data set");
}
final Random random = rnd.getSingleThreadedRandom();
final int size = objects.dataLength();
final int[] offsets = new int[size];
- for (int i = 0; i < size; i++) {
+ for(int i = 0; i < size; i++) {
offsets[i] = i;
}
// Randomize the offset array
- for (int i = size; i > 1; i--) {
+ for(int i = size; i > 1; i--) {
final int j = random.nextInt(i);
// Swap the elements at positions j and i - 1:
final int temp = offsets[j];
@@ -93,11 +96,11 @@ public class ShuffleObjectsFilter implements ObjectFilter {
}
MultipleObjectsBundle bundle = new MultipleObjectsBundle();
- for (int j = 0; j < objects.metaLength(); j++) {
+ for(int j = 0; j < objects.metaLength(); j++) {
// Reorder column accordingly
List<?> in = objects.getColumn(j);
List<Object> data = new ArrayList<>(size);
- for (int i = 0; i < size; i++) {
+ for(int i = 0; i < size; i++) {
data.add(in.get(offsets[i]));
}
bundle.appendColumn(objects.meta(j), data);
@@ -119,13 +122,13 @@ public class ShuffleObjectsFilter implements ObjectFilter {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
RandomParameter rndP = new RandomParameter(SEED_ID);
- if (config.grab(rndP)) {
+ if(config.grab(rndP)) {
rnd = rndP.getValue();
}
}
@Override
- protected Object makeInstance() {
+ protected ShuffleObjectsFilter makeInstance() {
return new ShuffleObjectsFilter(rnd);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/SortByLabelFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/selection/SortByLabelFilter.java
index d35d9cde..a6cef5fd 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/SortByLabelFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/selection/SortByLabelFilter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter;
+package de.lmu.ifi.dbs.elki.datasource.filter.selection;
/*
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,9 @@ import java.util.List;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerArrayQuickSort;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerComparator;
@@ -39,6 +41,7 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerComparator;
*
* @apiviz.uses de.lmu.ifi.dbs.elki.data.LabelList oneway - - «reads»
*/
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.SortByLabelFilter" })
public class SortByLabelFilter implements ObjectFilter {
/**
* Class logger
@@ -54,22 +57,22 @@ public class SortByLabelFilter implements ObjectFilter {
@Override
public MultipleObjectsBundle filter(final MultipleObjectsBundle objects) {
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
LOG.debug("Shuffling the data set");
}
// Prepare a reposition array for cheap resorting
final int size = objects.dataLength();
final int[] offsets = new int[size];
- for (int i = 0; i < size; i++) {
+ for(int i = 0; i < size; i++) {
offsets[i] = i;
}
// Sort by labels - identify a label column
final int lblcol;
{
int lblc = -1;
- for (int i = 0; i < objects.metaLength(); i++) {
- if (TypeUtil.GUESSED_LABEL.isAssignableFromType(objects.meta(i))) {
+ for(int i = 0; i < objects.metaLength(); i++) {
+ if(TypeUtil.GUESSED_LABEL.isAssignableFromType(objects.meta(i))) {
lblc = i;
break;
}
@@ -86,11 +89,11 @@ public class SortByLabelFilter implements ObjectFilter {
});
MultipleObjectsBundle bundle = new MultipleObjectsBundle();
- for (int j = 0; j < objects.metaLength(); j++) {
+ for(int j = 0; j < objects.metaLength(); j++) {
// Reorder column accordingly
List<?> in = objects.getColumn(j);
List<Object> data = new ArrayList<>(size);
- for (int i = 0; i < size; i++) {
+ for(int i = 0; i < size; i++) {
data.add(in.get(offsets[i]));
}
bundle.appendColumn(objects.meta(j), data);
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/selection/package-info.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/selection/package-info.java
new file mode 100644
index 00000000..7ec0a3a3
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/selection/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Filters for selecting and sorting data to process.
+ */
+
+/*
+ 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.datasource.filter.selection; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/AbstractSupervisedProjectionVectorFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/AbstractSupervisedProjectionVectorFilter.java
index 462db9eb..8c1ef6cb 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/AbstractSupervisedProjectionVectorFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/AbstractSupervisedProjectionVectorFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter.transform;
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
@@ -33,13 +33,12 @@ import java.util.Map;
import de.lmu.ifi.dbs.elki.data.ClassLabel;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.NumberVector.Factory;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
-import de.lmu.ifi.dbs.elki.datasource.filter.ClassLabelFilter;
import de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter;
+import de.lmu.ifi.dbs.elki.datasource.filter.typeconversions.ClassLabelFilter;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
@@ -60,7 +59,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*
* @param <V> Vector type
*/
-public abstract class AbstractSupervisedProjectionVectorFilter<V extends NumberVector<?>> implements ObjectFilter {
+public abstract class AbstractSupervisedProjectionVectorFilter<V extends NumberVector> implements ObjectFilter {
/**
* The dimensionality to which the data should be reduced.
*/
@@ -114,7 +113,7 @@ public abstract class AbstractSupervisedProjectionVectorFilter<V extends NumberV
List<V> vectorcolumn = (List<V>) column;
final VectorFieldTypeInformation<?> vtype = (VectorFieldTypeInformation<?>) type;
@SuppressWarnings("unchecked")
- NumberVector.Factory<V, ?> factory = (NumberVector.Factory<V, ?>) vtype.getFactory();
+ NumberVector.Factory<V> factory = (NumberVector.Factory<V> ) vtype.getFactory();
int dim = vtype.getDimensionality();
if(tdim > dim) {
@@ -155,7 +154,7 @@ public abstract class AbstractSupervisedProjectionVectorFilter<V extends NumberV
* @param factory Vector factory
* @return output type restriction
*/
- protected SimpleTypeInformation<?> convertedType(SimpleTypeInformation<?> in, Factory<V, ?> factory) {
+ protected SimpleTypeInformation<?> convertedType(SimpleTypeInformation<?> in, NumberVector.Factory<V> factory) {
return new VectorFieldTypeInformation<>(factory, tdim);
}
@@ -206,7 +205,7 @@ public abstract class AbstractSupervisedProjectionVectorFilter<V extends NumberV
*
* @param <V> Vector type
*/
- public abstract static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public abstract static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* The number of dimensions to keep.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/ClassicMultidimensionalScalingTransform.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/ClassicMultidimensionalScalingTransform.java
index d646b489..32024581 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/ClassicMultidimensionalScalingTransform.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/ClassicMultidimensionalScalingTransform.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter.transform;
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,8 +30,9 @@ 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.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.datasource.filter.FilterUtil;
import de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
@@ -54,6 +55,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
+ * @apiviz.composedOf SingularValueDecomposition
+ *
* @param <O> Data type
*/
@Alias({ "mds" })
@@ -66,7 +69,7 @@ public class ClassicMultidimensionalScalingTransform<O> implements ObjectFilter
/**
* Distance function to use.
*/
- PrimitiveDoubleDistanceFunction<? super O> dist = null;
+ PrimitiveDistanceFunction<? super O> dist = null;
/**
* Target dimensionality
@@ -79,7 +82,7 @@ public class ClassicMultidimensionalScalingTransform<O> implements ObjectFilter
* @param tdim Target dimensionality.
* @param dist Distance function to use.
*/
- public ClassicMultidimensionalScalingTransform(int tdim, PrimitiveDoubleDistanceFunction<? super O> dist) {
+ public ClassicMultidimensionalScalingTransform(int tdim, PrimitiveDistanceFunction<? super O> dist) {
super();
this.tdim = tdim;
this.dist = dist;
@@ -105,14 +108,14 @@ public class ClassicMultidimensionalScalingTransform<O> implements ObjectFilter
// Get the replacement type information
@SuppressWarnings("unchecked")
final List<O> castColumn = (List<O>) column;
- NumberVector.Factory<? extends NumberVector<?>, ?> factory = null;
+ NumberVector.Factory<? extends NumberVector> factory = null;
{
if (type instanceof VectorFieldTypeInformation) {
final VectorFieldTypeInformation<?> ctype = (VectorFieldTypeInformation<?>) type;
// Note two-step cast, to make stricter compilers happy.
@SuppressWarnings("unchecked")
- final VectorFieldTypeInformation<? extends NumberVector<?>> vtype = (VectorFieldTypeInformation<? extends NumberVector<?>>) ctype;
- factory = (NumberVector.Factory<? extends NumberVector<?>, ?>) vtype.getFactory();
+ final VectorFieldTypeInformation<? extends NumberVector> vtype = (VectorFieldTypeInformation<? extends NumberVector>) ctype;
+ factory = FilterUtil.guessFactory(vtype);
} else {
factory = DoubleVector.FACTORY;
}
@@ -128,16 +131,12 @@ public class ClassicMultidimensionalScalingTransform<O> implements ObjectFilter
final O ox = castColumn.get(x);
for (int y = x + 1; y < size; y++) {
final O oy = castColumn.get(y);
- double distance = Math.abs(dist.doubleDistance(ox, oy));
+ double distance = Math.abs(dist.distance(ox, oy));
imat[x][y] = distance;
- if (dprog != null) {
- dprog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(dprog);
}
}
- if (dprog != null) {
- dprog.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(dprog);
}
// Adjust distance matrix:
if (dist instanceof SquaredEuclideanDistanceFunction) {
@@ -230,7 +229,7 @@ public class ClassicMultidimensionalScalingTransform<O> implements ObjectFilter
*
* @apiviz.exclude
*/
- public static class Parameterizer<O extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<O extends NumberVector> extends AbstractParameterizer {
/**
* Desired dimensionality.
*/
@@ -249,7 +248,7 @@ public class ClassicMultidimensionalScalingTransform<O> implements ObjectFilter
/**
* Distance function to use.
*/
- PrimitiveDoubleDistanceFunction<? super O> dist = null;
+ PrimitiveDistanceFunction<? super O> dist = null;
@Override
protected void makeOptions(Parameterization config) {
@@ -260,7 +259,7 @@ public class ClassicMultidimensionalScalingTransform<O> implements ObjectFilter
tdim = dimP.intValue();
}
- ObjectParameter<PrimitiveDoubleDistanceFunction<? super O>> distP = new ObjectParameter<>(DISTANCE_ID, PrimitiveDoubleDistanceFunction.class, SquaredEuclideanDistanceFunction.class);
+ ObjectParameter<PrimitiveDistanceFunction<? super O>> distP = new ObjectParameter<>(DISTANCE_ID, PrimitiveDistanceFunction.class, SquaredEuclideanDistanceFunction.class);
if (config.grab(distP)) {
dist = distP.instantiateClass(config);
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/GlobalPrincipalComponentAnalysisTransform.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/GlobalPrincipalComponentAnalysisTransform.java
index 3b4193ad..c6bd02a9 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/GlobalPrincipalComponentAnalysisTransform.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/GlobalPrincipalComponentAnalysisTransform.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter.transform;
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
@@ -55,10 +55,14 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
+ * @apiviz.composedOf PCARunner
+ * @apiviz.composedOf CovarianceMatrix
+ * @apiviz.composedOf EigenPairFilter
+ *
* @param <O> Vector type
*/
@Alias({ "whiten", "whitening", "pca" })
-public class GlobalPrincipalComponentAnalysisTransform<O extends NumberVector<?>> extends AbstractVectorConversionFilter<O, O> {
+public class GlobalPrincipalComponentAnalysisTransform<O extends NumberVector> extends AbstractVectorConversionFilter<O, O> {
/**
* Class logger.
*/
@@ -122,7 +126,7 @@ public class GlobalPrincipalComponentAnalysisTransform<O extends NumberVector<?>
@Override
protected void prepareComplete() {
mean = covmat.getMeanVector().getArrayRef();
- PCAResult pcares = (new PCARunner<O>(null)).processCovarMatrix(covmat.destroyToSampleMatrix());
+ PCAResult pcares = (new PCARunner(null)).processCovarMatrix(covmat.destroyToSampleMatrix());
SortedEigenPairs eps = pcares.getEigenPairs();
covmat = null;
@@ -190,7 +194,7 @@ public class GlobalPrincipalComponentAnalysisTransform<O extends NumberVector<?>
*
* @apiviz.exclude
*/
- public static class Parameterizer<O extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<O extends NumberVector> extends AbstractParameterizer {
/**
* To specify the eigenvectors to keep.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/HistogramJitterFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/HistogramJitterFilter.java
index 453d294e..8c34ce37 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/HistogramJitterFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/HistogramJitterFilter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter;
+package de.lmu.ifi.dbs.elki.datasource.filter.transform;
/*
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,9 @@ import de.lmu.ifi.dbs.elki.data.DoubleVector;
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.datasource.filter.AbstractVectorStreamConversionFilter;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.math.statistics.distribution.ExponentialDistribution;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -55,7 +56,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
* @param <V> Vector type
*/
@Description("Add uniform Jitter to a dataset, while preserving the total vector sum.")
-public class HistogramJitterFilter<V extends NumberVector<?>> extends AbstractVectorStreamConversionFilter<V, V> {
+public class HistogramJitterFilter<V extends NumberVector> extends AbstractVectorStreamConversionFilter<V, V> {
/**
* Jitter amount.
*/
@@ -145,8 +146,8 @@ public class HistogramJitterFilter<V extends NumberVector<?>> extends AbstractVe
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- DoubleParameter jitterP = new DoubleParameter(JITTER_ID);
- jitterP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ DoubleParameter jitterP = new DoubleParameter(JITTER_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
if(config.grab(jitterP)) {
jitter = jitterP.getValue().doubleValue();
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/LatLngToECEFFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/LatLngToECEFFilter.java
index 998c8931..9cb0b492 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/LatLngToECEFFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/LatLngToECEFFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter.transform;
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,10 @@ package de.lmu.ifi.dbs.elki.datasource.filter.transform;
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.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.datasource.filter.AbstractStreamConversionFilter;
+import de.lmu.ifi.dbs.elki.datasource.filter.FilterUtil;
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.optionhandling.AbstractParameterizer;
@@ -39,13 +41,16 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
+ * @apiviz.uses NumberVector
+ * @apiviz.composedOf EarthModel
+ *
* @param <V> Vector type.
*/
-public class LatLngToECEFFilter<V extends NumberVector<?>> extends AbstractStreamConversionFilter<V, V> {
+public class LatLngToECEFFilter<V extends NumberVector> extends AbstractStreamConversionFilter<V, V> {
/**
* Vector factory to use.
*/
- private NumberVector.Factory<V, ?> factory;
+ private NumberVector.Factory<V> factory;
/**
* Earth model to use.
@@ -69,14 +74,13 @@ public class LatLngToECEFFilter<V extends NumberVector<?>> extends AbstractStrea
@Override
protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
- return new VectorFieldTypeInformation<>(NumberVector.class, 2, 2);
+ return TypeUtil.NUMBER_VECTOR_FIELD_2D;
}
@Override
protected SimpleTypeInformation<? super V> convertedType(SimpleTypeInformation<V> in) {
- VectorFieldTypeInformation<V> vin = (VectorFieldTypeInformation<V>) in;
- factory = (NumberVector.Factory<V, ?>) vin.getFactory();
- return new VectorFieldTypeInformation<>(vin.getFactory(), 3, 3, in.getSerializer());
+ factory = FilterUtil.guessFactory(in);
+ return new VectorFieldTypeInformation<>(factory, 3, 3, in.getSerializer());
}
/**
@@ -88,7 +92,7 @@ public class LatLngToECEFFilter<V extends NumberVector<?>> extends AbstractStrea
*
* @param <V> Vector type
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* Earth model to use.
*/
@@ -98,7 +102,7 @@ public class LatLngToECEFFilter<V extends NumberVector<?>> extends AbstractStrea
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/datasource/filter/transform/LinearDiscriminantAnalysisFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/LinearDiscriminantAnalysisFilter.java
index 76546d5c..537bfb20 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/LinearDiscriminantAnalysisFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/LinearDiscriminantAnalysisFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter.transform;
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
@@ -59,7 +59,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
*/
@Alias("lda")
@Reference(authors = "R. A. Fisher", title = "The use of multiple measurements in taxonomic problems", booktitle = "Annals of eugenics 7.2 (1936)", url = "http://dx.doi.org/10.1111/j.1469-1809.1936.tb02137.x")
-public class LinearDiscriminantAnalysisFilter<V extends NumberVector<?>> extends AbstractSupervisedProjectionVectorFilter<V> {
+public class LinearDiscriminantAnalysisFilter<V extends NumberVector> extends AbstractSupervisedProjectionVectorFilter<V> {
/**
* Class logger.
*/
@@ -156,7 +156,7 @@ public class LinearDiscriminantAnalysisFilter<V extends NumberVector<?>> extends
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractSupervisedProjectionVectorFilter.Parameterizer<V> {
+ public static class Parameterizer<V extends NumberVector> extends AbstractSupervisedProjectionVectorFilter.Parameterizer<V> {
@Override
protected LinearDiscriminantAnalysisFilter<V> makeInstance() {
return new LinearDiscriminantAnalysisFilter<>(tdim);
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/LngLatToECEFFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/LngLatToECEFFilter.java
index ea0d4ef2..d5fba25d 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/LngLatToECEFFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/LngLatToECEFFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter.transform;
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,10 @@ package de.lmu.ifi.dbs.elki.datasource.filter.transform;
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.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.datasource.filter.AbstractStreamConversionFilter;
+import de.lmu.ifi.dbs.elki.datasource.filter.FilterUtil;
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.optionhandling.AbstractParameterizer;
@@ -39,13 +41,16 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
+ * @apiviz.uses NumberVector
+ * @apiviz.composedOf EarthModel
+ *
* @param <V> Vector type.
*/
-public class LngLatToECEFFilter<V extends NumberVector<?>> extends AbstractStreamConversionFilter<V, V> {
+public class LngLatToECEFFilter<V extends NumberVector> extends AbstractStreamConversionFilter<V, V> {
/**
* Vector factory to use.
*/
- private NumberVector.Factory<V, ?> factory;
+ private NumberVector.Factory<V> factory;
/**
* Earth model to use.
@@ -69,14 +74,13 @@ public class LngLatToECEFFilter<V extends NumberVector<?>> extends AbstractStrea
@Override
protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
- return new VectorFieldTypeInformation<>(NumberVector.class, 2, 2);
+ return TypeUtil.NUMBER_VECTOR_FIELD_2D;
}
@Override
protected SimpleTypeInformation<? super V> convertedType(SimpleTypeInformation<V> in) {
- VectorFieldTypeInformation<V> vin = (VectorFieldTypeInformation<V>) in;
- factory = (NumberVector.Factory<V, ?>) vin.getFactory();
- return new VectorFieldTypeInformation<>(vin.getFactory(), 3, 3, in.getSerializer());
+ factory = FilterUtil.guessFactory(in);
+ return new VectorFieldTypeInformation<>(factory, 3, 3, in.getSerializer());
}
/**
@@ -88,7 +92,7 @@ public class LngLatToECEFFilter<V extends NumberVector<?>> extends AbstractStrea
*
* @param <V> Vector type
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* Earth model to use.
*/
@@ -98,7 +102,7 @@ public class LngLatToECEFFilter<V extends NumberVector<?>> extends AbstractStrea
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/datasource/filter/transform/NumberVectorFeatureSelectionFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/NumberVectorFeatureSelectionFilter.java
index e6d0d15d..115d77dd 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/NumberVectorFeatureSelectionFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/NumberVectorFeatureSelectionFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter.transform;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -51,7 +51,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntListParameter;
*
* @param <V> Vector type
*/
-public class NumberVectorFeatureSelectionFilter<V extends NumberVector<?>> extends AbstractVectorStreamConversionFilter<V, V> {
+public class NumberVectorFeatureSelectionFilter<V extends NumberVector> extends AbstractVectorStreamConversionFilter<V, V> {
/**
* Keeps the selection of the subspace to project onto.
*/
@@ -99,10 +99,8 @@ public class NumberVectorFeatureSelectionFilter<V extends NumberVector<?>> exten
}
/**
- * <p>
* Provides a BitSet with the bits set to true corresponding to the selected
* attributes in {@link Parameterizer#SELECTED_ATTRIBUTES_ID}.
- * </p>
*
* The index in the BitSet is shifted to the left by one, i.e., index 0 in the
* BitSet relates to the first attribute.
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/NumberVectorRandomFeatureSelectionFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/NumberVectorRandomFeatureSelectionFilter.java
index 4086270c..dfca33ec 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/NumberVectorRandomFeatureSelectionFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/NumberVectorRandomFeatureSelectionFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter.transform;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -32,7 +32,7 @@ import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.datasource.filter.AbstractVectorStreamConversionFilter;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.Util;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -51,7 +51,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
*
* @param <V> vector type
*/
-public class NumberVectorRandomFeatureSelectionFilter<V extends NumberVector<?>> extends AbstractVectorStreamConversionFilter<V, V> {
+public class NumberVectorRandomFeatureSelectionFilter<V extends NumberVector> extends AbstractVectorStreamConversionFilter<V, V> {
/**
* The selected attributes.
*/
@@ -155,10 +155,10 @@ public class NumberVectorRandomFeatureSelectionFilter<V extends NumberVector<?>>
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- IntParameter kP = new IntParameter(NUMBER_SELECTED_ATTRIBUTES_ID, 1);
- kP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ IntParameter kP = new IntParameter(NUMBER_SELECTED_ATTRIBUTES_ID, 1) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
if(config.grab(kP)) {
- k = kP.getValue().intValue();
+ k = kP.intValue();
}
RandomParameter rndP = new RandomParameter(SEED_ID);
if(config.grab(rndP)) {
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/PerturbationFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/PerturbationFilter.java
new file mode 100644
index 00000000..4e5fe9b3
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/PerturbationFilter.java
@@ -0,0 +1,436 @@
+package de.lmu.ifi.dbs.elki.datasource.filter.transform;
+
+/*
+ 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.Random;
+
+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.datasource.filter.AbstractVectorConversionFilter;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.MeanVarianceMinMax;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;
+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;
+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.AllOrNoneMustBeSetGlobalConstraint;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.EqualSizeGlobalConstraint;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleListParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.EnumParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.LongParameter;
+
+/**
+ * A filter to perturb the values by adding micro-noise.
+ *
+ * The added noise is generated, attribute-wise, by a Gaussian with mean=0 and a
+ * specified standard deviation or by a uniform distribution with a specified
+ * range. The standard deviation or the range can be scaled, attribute-wise, to
+ * a given percentage of the original standard deviation in the data
+ * distribution (assuming a Gaussian distribution there), or to a percentage of
+ * the extension in each attribute ({@code maximumValue - minimumValue}).
+ *
+ * This filter has a potentially wide use but has been implemented for the following publication:
+ *
+ * Reference:
+ * <p>
+ * A. Zimek, R. J. G. B. Campello, J. Sander:</br>
+ * Data Perturbation for Outlier Detection Ensembles.<\br>
+ * In: Proc. 26th International Conference on Scientific and Statistical Database Management (SSDBM), Aalborg, Denmark, 2014.
+ * </p>
+ *
+ * @author Arthur Zimek
+ */
+@Title("Data Perturbation for Outlier Detection Ensembles")
+@Description("A filter to perturb a datasset on read by an additive noise component, implemented for use in an outlier ensemble (this reference).")
+@Reference(authors = "A. Zimek, R. J. G. B. Campello, J. Sander",//
+title = "Data Perturbation for Outlier Detection Ensembles", //
+booktitle = "Proc. 26th International Conference on Scientific and Statistical Database Management (SSDBM), Aalborg, Denmark, 2014", //
+url = "http://dx.doi.org/10.1145/2618243.2618257")
+public class PerturbationFilter<V extends NumberVector> extends AbstractVectorConversionFilter<V, V> {
+ /**
+ * Class logger
+ */
+ private static final Logging LOG = Logging.getLogger(PerturbationFilter.class);
+
+ /**
+ * Scaling reference options.
+ *
+ * @author Arthur Zimek
+ *
+ * @apiviz.exclude
+ */
+ public static enum ScalingReference {
+ UNITCUBE, STDDEV, MINMAX
+ }
+
+ /**
+ * Nature of the noise distribution.
+ *
+ * @author Arthur Zimek
+ *
+ * @apiviz.exclude
+ */
+ public static enum NoiseDistribution {
+ GAUSSIAN, UNIFORM
+ }
+
+ /**
+ * Which reference to use for scaling the noise.
+ */
+ private ScalingReference scalingreference;
+
+ /**
+ * Nature of the noise distribution.
+ */
+ private NoiseDistribution noisedistribution;
+
+ /**
+ * Random object to generate the attribute-wise seeds for the noise.
+ */
+ private final Random RANDOM;
+
+ /**
+ * Percentage of the variance of the random noise generation, given the
+ * variance of the corresponding attribute in the data.
+ */
+ private double percentage;
+
+ /**
+ * Temporary storage used during initialization.
+ */
+ private MeanVarianceMinMax[] mvs = null;
+
+ /**
+ * Stores the scaling reference in each dimension.
+ */
+ private double[] scalingreferencevalues = new double[0];
+
+ /**
+ * The random objects to generate noise distributions independently for each
+ * attribute.
+ */
+ private Random[] randomPerAttribute = null;
+
+ /**
+ * Stores the maximum in each dimension.
+ */
+ private double[] maxima;
+
+ /**
+ * Stores the minimum in each dimension.
+ */
+ private double[] minima;
+
+ /**
+ * Stores the dimensionality from the preprocessing.
+ */
+ private int dimensionality = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param seed Seed value, may be {@code null} for a random seed.
+ * @param percentage Relative amount of jitter to add
+ * @param scalingreference Scaling reference
+ * @param minima Preset minimum values. May be {@code null}.
+ * @param maxima Preset maximum values. May be {@code null}.
+ * @param noisedistribution Nature of the noise distribution.
+ */
+ public PerturbationFilter(Long seed, double percentage, ScalingReference scalingreference, double[] minima, double[] maxima, NoiseDistribution noisedistribution) {
+ super();
+ this.percentage = percentage;
+ this.scalingreference = scalingreference;
+ this.minima = minima;
+ this.maxima = maxima;
+ this.noisedistribution = noisedistribution;
+ this.RANDOM = (seed == null) ? new Random() : new Random(seed);
+ }
+
+ @Override
+ protected boolean prepareStart(SimpleTypeInformation<V> in) {
+ if(scalingreference == ScalingReference.MINMAX && minima.length != 0 && maxima.length != 0) {
+ dimensionality = minima.length;
+ scalingreferencevalues = new double[dimensionality];
+ randomPerAttribute = new Random[dimensionality];
+ for(int d = 0; d < dimensionality; d++) {
+ scalingreferencevalues[d] = (maxima[d] - minima[d]) * percentage;
+ if(scalingreferencevalues[d] == 0 || Double.isNaN(scalingreferencevalues[d])) {
+ scalingreferencevalues[d] = percentage;
+ }
+ randomPerAttribute[d] = new Random(RANDOM.nextLong());
+ }
+ return false;
+ }
+ if(scalingreference == ScalingReference.UNITCUBE) {
+ return false;
+ }
+ return (scalingreferencevalues.length == 0);
+ }
+
+ @Override
+ protected void prepareProcessInstance(V featureVector) {
+ // First object? Then init. (We didn't have a dimensionality before!)
+ if(mvs == null) {
+ dimensionality = featureVector.getDimensionality();
+ mvs = MeanVarianceMinMax.newArray(dimensionality);
+ }
+ for(int d = 0; d < featureVector.getDimensionality(); d++) {
+ mvs[d].put(featureVector.doubleValue(d));
+ }
+ }
+
+ @Override
+ protected void prepareComplete() {
+ StringBuilder buf = LOG.isDebuggingFine() ? new StringBuilder() : null;
+ scalingreferencevalues = new double[dimensionality];
+ randomPerAttribute = new Random[dimensionality];
+ if(scalingreference == ScalingReference.STDDEV) {
+ if(buf != null) {
+ buf.append("Standard deviation per attribute: ");
+ }
+ for(int d = 0; d < dimensionality; d++) {
+ scalingreferencevalues[d] = mvs[d].getSampleStddev() * percentage;
+ if(scalingreferencevalues[d] == 0 || Double.isNaN(scalingreferencevalues[d])) {
+ scalingreferencevalues[d] = percentage;
+ }
+ randomPerAttribute[d] = new Random(RANDOM.nextLong());
+ if(buf != null) {
+ buf.append(" ").append(d).append(": ").append(scalingreferencevalues[d] / percentage);
+ }
+ }
+ }
+ else if(scalingreference == ScalingReference.MINMAX && minima.length == 0 && maxima.length == 0) {
+ if(buf != null) {
+ buf.append("extension per attribute: ");
+ }
+ for(int d = 0; d < dimensionality; d++) {
+ scalingreferencevalues[d] = (mvs[d].getMax() - mvs[d].getMin()) * percentage;
+ if(scalingreferencevalues[d] == 0 || Double.isNaN(scalingreferencevalues[d])) {
+ scalingreferencevalues[d] = percentage;
+ }
+ randomPerAttribute[d] = new Random(RANDOM.nextLong());
+ if(buf != null) {
+ buf.append(" ").append(d).append(": ").append(scalingreferencevalues[d] / percentage);
+ }
+ }
+ }
+ mvs = null;
+ if(buf != null) {
+ LOG.debugFine(buf.toString());
+ }
+ }
+
+ @Override
+ protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_FIELD;
+ }
+
+ @Override
+ protected V filterSingleObject(V featureVector) {
+ if(scalingreference == ScalingReference.UNITCUBE && dimensionality == 0) {
+ dimensionality = featureVector.getDimensionality();
+ scalingreferencevalues = new double[dimensionality];
+ randomPerAttribute = new Random[dimensionality];
+ for(int d = 0; d < dimensionality; d++) {
+ scalingreferencevalues[d] = percentage;
+ randomPerAttribute[d] = new Random(RANDOM.nextLong());
+ }
+ }
+ if(scalingreferencevalues.length != featureVector.getDimensionality()) {
+ throw new IllegalArgumentException("FeatureVectors and given Minima/Maxima differ in length.");
+ }
+ double[] values = new double[featureVector.getDimensionality()];
+ for(int d = 0; d < featureVector.getDimensionality(); d++) {
+ if(this.noisedistribution.equals(NoiseDistribution.GAUSSIAN)) {
+ values[d] = featureVector.doubleValue(d) + randomPerAttribute[d].nextGaussian() * scalingreferencevalues[d];
+ }
+ else if(this.noisedistribution.equals(NoiseDistribution.UNIFORM)) {
+ values[d] = featureVector.doubleValue(d) + randomPerAttribute[d].nextDouble() * scalingreferencevalues[d];
+ }
+ }
+ return factory.newNumberVector(values);
+ }
+
+ @Override
+ protected SimpleTypeInformation<? super V> convertedType(SimpleTypeInformation<V> in) {
+ initializeOutputType(in);
+ return in;
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Arthur Zimek
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ /**
+ * Parameter for minimum.
+ */
+ public static final OptionID MINIMA_ID = new OptionID("perturbationfilter.min", "Only used, if " + ScalingReference.MINMAX + " is set as scaling reference: a comma separated concatenation of the minimum values in each dimension assumed as a reference. If no value is specified, the minimum value of the attribute range in this dimension will be taken.");
+
+ /**
+ * Parameter for maximum.
+ */
+ public static final OptionID MAXIMA_ID = new OptionID("perturbationfilter.max", "Only used, if " + ScalingReference.MINMAX + " is set as scaling reference: a comma separated concatenation of the maximum values in each dimension assumed as a reference. If no value is specified, the maximum value of the attribute range in this dimension will be taken.");
+
+ /**
+ * Stores the maximum in each dimension.
+ */
+ private double[] maxima = new double[0];
+
+ /**
+ * Stores the minimum in each dimension.
+ */
+ private double[] minima = new double[0];
+
+ /**
+ * Optional parameter to specify a seed for random Gaussian noise
+ * generation. If unused, system time is used as seed.
+ * <p>
+ * Key: {@code -perturbationfilter.seed}
+ * </p>
+ */
+ public static final OptionID SEED_ID = new OptionID("perturbationfilter.seed", "Seed for random noise generation.");
+
+ /**
+ * Seed for randomly shuffling the rows of the database. If null, system
+ * time is used as seed.
+ */
+ protected Long seed = null;
+
+ /**
+ * Optional parameter to specify a percentage of the standard deviation of
+ * the random Gaussian noise generation, given the standard deviation of the
+ * corresponding attribute in the original data distribution (assuming a
+ * Gaussian there).
+ *
+ * <p>
+ * Key: {@code -perturbationfilter.percentage}
+ * </p>
+ * <p>
+ * Default: <code>0.01</code>
+ * </p>
+ * <p>
+ * Constraint: 0 &lt; percentage &leq;1
+ * </p>
+ */
+ public static final OptionID PERCENTAGE_ID = new OptionID("perturbationfilter.percentage", "Percentage of the standard deviation of the random Gaussian noise generation per attribute, given the standard deviation of the corresponding attribute in the original data distribution (assuming a Gaussian distribution there).");
+
+ /**
+ * Parameter for selecting scaling reference.
+ * <p>
+ * Key: {@code -perturbationfilter.scalingreference}
+ * </p>
+ * <p>
+ * Default: <code>ScalingReference.UNITCUBE</code>
+ * </p>
+ */
+ public static final OptionID SCALINGREFERENCE_ID = new OptionID("perturbationfilter.scalingreference", "The reference for scaling the Gaussian noise. Default is " + ScalingReference.UNITCUBE + ", parameter " + PERCENTAGE_ID.getName() + " will then directly define the standard deviation of all noise Gaussians. For options " + ScalingReference.STDDEV + " and " + ScalingReference.MINMAX + ", the percentage of the attributewise standard deviation or extension, repectively, will define the attributewise standard deviation of the noise Gaussians.");
+
+ /**
+ * Parameter for selecting the noise distribution.
+ *
+ * <p>
+ * Key: {@code -perturbationfilter.noisedistribution}
+ * </p>
+ * <p>
+ * Default: <code>NoiseDistribution.UNIFORM</code>
+ * </p>
+ *
+ */
+ public static final OptionID NOISEDISTRIBUTION_ID = new OptionID("perturbationfilter.noisedistribution", "The nature of the noise distribution, default is " + NoiseDistribution.UNIFORM);
+
+ /**
+ * Percentage of the variance of the random Gaussian noise generation or of
+ * the range of the uniform distribution, given the variance of the
+ * corresponding attribute in the data.
+ */
+ protected double percentage;
+
+ /**
+ * The option which reference to use for scaling the noise.
+ */
+ protected ScalingReference scalingreference;
+
+ /**
+ * The option which nature of noise distribution to choose.
+ */
+ protected NoiseDistribution noisedistribution;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ EnumParameter<ScalingReference> scalingReferenceP = new EnumParameter<>(SCALINGREFERENCE_ID, ScalingReference.class, ScalingReference.UNITCUBE);
+ if(config.grab(scalingReferenceP)) {
+ scalingreference = scalingReferenceP.getValue();
+ }
+ EnumParameter<NoiseDistribution> noisedistributionP = new EnumParameter<>(NOISEDISTRIBUTION_ID, NoiseDistribution.class, NoiseDistribution.UNIFORM);
+ if(config.grab(noisedistributionP)) {
+ noisedistribution = noisedistributionP.getValue();
+ }
+ DoubleParameter percentageP = new DoubleParameter(PERCENTAGE_ID, .01);
+ percentageP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ percentageP.addConstraint(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
+ if(config.grab(percentageP)) {
+ percentage = percentageP.getValue();
+ }
+ LongParameter seedP = new LongParameter(SEED_ID);
+ seedP.setOptional(true);
+ if(config.grab(seedP)) {
+ seed = seedP.getValue();
+ }
+ DoubleListParameter minimaP = new DoubleListParameter(MINIMA_ID);
+ minimaP.setOptional(true);
+ if(config.grab(minimaP)) {
+ minima = ArrayLikeUtil.toPrimitiveDoubleArray(minimaP.getValue());
+ }
+ DoubleListParameter maximaP = new DoubleListParameter(MAXIMA_ID);
+ maximaP.setOptional(true);
+ if(config.grab(maximaP)) {
+ maxima = ArrayLikeUtil.toPrimitiveDoubleArray(maximaP.getValue());
+ }
+
+ config.checkConstraint(new AllOrNoneMustBeSetGlobalConstraint(minimaP, maximaP));
+ config.checkConstraint(new EqualSizeGlobalConstraint(minimaP, maximaP));
+ }
+
+ @Override
+ protected PerturbationFilter<V> makeInstance() {
+ return new PerturbationFilter<>(seed, percentage, scalingreference, minima, maxima, noisedistribution);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/ProjectionFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/ProjectionFilter.java
index af3f4c6e..e58ea3b0 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/ProjectionFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/ProjectionFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.filter.transform;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -37,6 +37,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
+ * @apiviz.composedOf Projection
+ *
* @param <I> Input type
* @param <O> Output type
*/
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/package-info.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/package-info.java
index 7082f103..3a81b989 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/transform/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/datasource/filter/ClassLabelFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/ClassLabelFilter.java
index 020dcb31..582eba65 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/ClassLabelFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/ClassLabelFilter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter;
+package de.lmu.ifi.dbs.elki.datasource.filter.typeconversions;
/*
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,8 @@ import de.lmu.ifi.dbs.elki.data.LabelList;
import de.lmu.ifi.dbs.elki.data.SimpleClassLabel;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
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;
@@ -46,6 +48,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.uses LabelList oneway - - «reads»
* @apiviz.has ClassLabel
*/
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.ClassLabelFilter" })
public class ClassLabelFilter implements ObjectFilter {
/**
* The index of the label to be used as class label, null if no class label is
@@ -180,7 +183,7 @@ public class ClassLabelFilter implements ObjectFilter {
}
@Override
- protected Object makeInstance() {
+ protected ClassLabelFilter makeInstance() {
return new ClassLabelFilter(classLabelIndex, classLabelFactory);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/ClassLabelFromPatternFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/ClassLabelFromPatternFilter.java
index 517eb301..3ced4e2f 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/ClassLabelFromPatternFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/ClassLabelFromPatternFilter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter;
+package de.lmu.ifi.dbs.elki.datasource.filter.typeconversions;
/*
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,8 @@ package de.lmu.ifi.dbs.elki.datasource.filter;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.BitSet;
+import gnu.trove.list.array.TIntArrayList;
+
import java.util.regex.Pattern;
import de.lmu.ifi.dbs.elki.data.LabelList;
@@ -31,6 +32,8 @@ import de.lmu.ifi.dbs.elki.data.SimpleClassLabel;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.datasource.bundle.BundleMeta;
+import de.lmu.ifi.dbs.elki.datasource.filter.AbstractStreamFilter;
+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;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -42,6 +45,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.StringParameter;
*
* @author Erich Schubert
*/
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.ClassLabelFromPatternFilter" })
public class ClassLabelFromPatternFilter extends AbstractStreamFilter {
/**
* Current meta data
@@ -51,7 +55,7 @@ public class ClassLabelFromPatternFilter extends AbstractStreamFilter {
/**
* Bitset of label columns
*/
- BitSet labelcols = new BitSet();
+ TIntArrayList labelcols = new TIntArrayList();
/**
* Label to return for positive matches.
@@ -98,16 +102,16 @@ public class ClassLabelFromPatternFilter extends AbstractStreamFilter {
@Override
public BundleMeta getMeta() {
- if (meta == null) {
+ if(meta == null) {
// Rebuild metadata.
BundleMeta origmeta = source.getMeta();
meta = new BundleMeta(origmeta.size() + 1);
meta.add(TypeUtil.SIMPLE_CLASSLABEL);
labelcols.clear();
- for (int i = 0; i < origmeta.size(); i++) {
+ for(int i = 0; i < origmeta.size(); i++) {
final SimpleTypeInformation<?> orig = origmeta.get(i);
- if (TypeUtil.GUESSED_LABEL.isAssignableFromType(orig)) {
- labelcols.set(i);
+ if(TypeUtil.GUESSED_LABEL.isAssignableFromType(orig)) {
+ labelcols.add(i);
}
meta.add(orig);
}
@@ -117,27 +121,27 @@ public class ClassLabelFromPatternFilter extends AbstractStreamFilter {
@Override
public Object data(int rnum) {
- if (rnum > 0) {
+ if(rnum > 0) {
return source.data(rnum - 1);
}
- if (meta == null) {
+ if(meta == null) {
getMeta(); // Trigger build
}
- for (int i = labelcols.nextSetBit(0); i >= 0; i = labelcols.nextSetBit(i + 1)) {
- Object o = source.data(i);
- if (o == null) {
+ for(int i = 0; i < labelcols.size(); i++) {
+ Object o = source.data(labelcols.get(i));
+ if(o == null) {
continue;
}
- if (o instanceof LabelList) {
+ if(o instanceof LabelList) {
final LabelList ll = (LabelList) o;
for(int j = 0; j < ll.size(); j++) {
- if (pattern.matcher(ll.get(j)).find()) {
+ if(pattern.matcher(ll.get(j)).find()) {
return positive;
}
}
continue;
}
- if (pattern.matcher(o.toString()).find()) {
+ if(pattern.matcher(o.toString()).find()) {
return positive;
}
}
@@ -147,7 +151,7 @@ public class ClassLabelFromPatternFilter extends AbstractStreamFilter {
@Override
public Event nextEvent() {
final Event ev = source.nextEvent();
- if (Event.META_CHANGED.equals(ev)) {
+ if(Event.META_CHANGED.equals(ev)) {
meta = null;
}
return ev;
@@ -191,17 +195,17 @@ public class ClassLabelFromPatternFilter extends AbstractStreamFilter {
super.makeOptions(config);
PatternParameter patternP = new PatternParameter(PATTERN_ID);
- if (config.grab(patternP)) {
+ if(config.grab(patternP)) {
pattern = patternP.getValue();
}
StringParameter positiveP = new StringParameter(POSITIVE_ID, "positive");
- if (config.grab(positiveP)) {
+ if(config.grab(positiveP)) {
positive = positiveP.getValue();
}
StringParameter negativeP = new StringParameter(NEGATIVE_ID, "negative");
- if (config.grab(negativeP)) {
+ if(config.grab(negativeP)) {
negative = negativeP.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/ExternalIDFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/ExternalIDFilter.java
index 17538dc9..3947a7cd 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/ExternalIDFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/ExternalIDFilter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter;
+package de.lmu.ifi.dbs.elki.datasource.filter.typeconversions;
/*
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,8 @@ import de.lmu.ifi.dbs.elki.data.LabelList;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter;
+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;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -44,7 +46,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* @apiviz.uses LabelList oneway - - «reads»
* @apiviz.has ExternalID oneway - - «produces»
*/
-// TODO: use a non-string class for external ids?
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.ExternalIDFilter" })
public class ExternalIDFilter implements ObjectFilter {
/**
* The index of the label to be used as external Id.
@@ -143,7 +145,7 @@ public class ExternalIDFilter implements ObjectFilter {
}
@Override
- protected Object makeInstance() {
+ protected ExternalIDFilter makeInstance() {
return new ExternalIDFilter(externalIdIndex);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/MultivariateTimeSeriesFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/MultivariateTimeSeriesFilter.java
new file mode 100644
index 00000000..97a5d59d
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/MultivariateTimeSeriesFilter.java
@@ -0,0 +1,124 @@
+package de.lmu.ifi.dbs.elki.datasource.filter.typeconversions;
+
+/*
+ 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.data.type.MultivariateSeriesTypeInformation;
+import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.data.type.VectorTypeInformation;
+import de.lmu.ifi.dbs.elki.datasource.filter.AbstractStreamConversionFilter;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+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.constraints.CommonConstraints;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+
+/**
+ * Class to "fold" a flat number vector into a multivariate time series.
+ *
+ * @author Erich Schubert
+ *
+ * @param <V> Vector type
+ */
+public class MultivariateTimeSeriesFilter<V extends FeatureVector<?>> extends AbstractStreamConversionFilter<V, V> {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(MultivariateTimeSeriesFilter.class);
+
+ /**
+ * Number of variates to use.
+ */
+ int variates;
+
+ /**
+ * Constructor.
+ *
+ * @param variates Number of variates.
+ */
+ public MultivariateTimeSeriesFilter(int variates) {
+ super();
+ this.variates = variates;
+ }
+
+ @Override
+ protected V filterSingleObject(V obj) {
+ if(obj.getDimensionality() % variates != 0) {
+ throw new AbortException("Vector length " + obj.getDimensionality() + " not divisible by the number of variates " + variates);
+ }
+ return obj;
+ }
+
+ @Override
+ protected SimpleTypeInformation<? super V> getInputTypeRestriction() {
+ return TypeUtil.FEATURE_VECTORS;
+ }
+
+ @Override
+ protected SimpleTypeInformation<? super V> convertedType(SimpleTypeInformation<V> in) {
+ VectorTypeInformation<V> vin = (VectorTypeInformation<V>) in;
+ return new MultivariateSeriesTypeInformation<>(vin.getFactory(), in.getSerializer(), vin.mindim(), vin.maxdim(), variates);
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <V> Vector type
+ */
+ public static class Parameterizer<V extends FeatureVector<?>> extends AbstractParameterizer {
+ /**
+ * Parameter for specifying the number of variates of this series.
+ */
+ public static final OptionID VARIATES_ID = new OptionID("series.variates", "Number of variates this time series has.");
+
+ /**
+ * Number of variates to use.
+ */
+ int variates;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ IntParameter variatesP = new IntParameter(VARIATES_ID)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(variatesP)) {
+ variates = variatesP.intValue();
+ if(variates == 1) {
+ LOG.warning("For univariate series, you should not need to use this filter.");
+ }
+ }
+ }
+
+ @Override
+ protected MultivariateTimeSeriesFilter<V> makeInstance() {
+ return new MultivariateTimeSeriesFilter<>(variates);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/SparseVectorFieldFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/SparseVectorFieldFilter.java
index 97960907..2b84f0a6 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/SparseVectorFieldFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/SparseVectorFieldFilter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter;
+package de.lmu.ifi.dbs.elki.datasource.filter.typeconversions;
/*
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,10 @@ 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.data.type.VectorFieldTypeInformation;
+import de.lmu.ifi.dbs.elki.datasource.filter.AbstractConversionFilter;
+import de.lmu.ifi.dbs.elki.datasource.filter.FilterUtil;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
/**
* Class that turns sparse float vectors into a proper vector field, by setting
@@ -37,7 +40,8 @@ import de.lmu.ifi.dbs.elki.logging.Logging;
*
* @param <V> Vector type
*/
-public class SparseVectorFieldFilter<V extends SparseNumberVector<?>> extends AbstractConversionFilter<V, V> {
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.SparseVectorFieldFilter" })
+public class SparseVectorFieldFilter<V extends SparseNumberVector> extends AbstractConversionFilter<V, V> {
/**
* Class logger.
*/
@@ -79,7 +83,7 @@ public class SparseVectorFieldFilter<V extends SparseNumberVector<?>> extends Ab
@Override
protected SimpleTypeInformation<? super V> convertedType(SimpleTypeInformation<V> in) {
- SparseNumberVector.Factory<V, ?> factory = (SparseNumberVector.Factory<V, ?>) FilterUtil.guessFactory(in);
+ SparseNumberVector.Factory<V> factory = (SparseNumberVector.Factory<V>) FilterUtil.guessFactory(in);
return new VectorFieldTypeInformation<>(factory, maxdim);
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/SplitNumberVectorFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/SplitNumberVectorFilter.java
index 6ac046ec..81f640df 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/SplitNumberVectorFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/SplitNumberVectorFilter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.filter;
+package de.lmu.ifi.dbs.elki.datasource.filter.typeconversions;
/*
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,11 +27,13 @@ import java.util.ArrayList;
import java.util.List;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.NumberVector.Factory;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.datasource.filter.FilterUtil;
+import de.lmu.ifi.dbs.elki.datasource.filter.ObjectFilter;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
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;
@@ -48,7 +50,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntListParameter;
*
* @param <V> Vector type
*/
-public class SplitNumberVectorFilter<V extends NumberVector<?>> implements ObjectFilter {
+@Alias({ "de.lmu.ifi.dbs.elki.datasource.filter.normalization.SplitNumberVectorFilter" })
+public class SplitNumberVectorFilter<V extends NumberVector> implements ObjectFilter {
/**
* Selected dimensions.
*/
@@ -83,7 +86,7 @@ public class SplitNumberVectorFilter<V extends NumberVector<?>> implements Objec
// Should be a vector type after above test.
@SuppressWarnings("unchecked")
final VectorFieldTypeInformation<V> vtype = VectorFieldTypeInformation.class.cast(type);
- Factory<V, ?> factory = FilterUtil.guessFactory(vtype);
+ NumberVector.Factory<V> factory = FilterUtil.guessFactory(vtype);
// Get the replacement type informations
VectorFieldTypeInformation<V> type1 = new VectorFieldTypeInformation<>(factory, dims.length);
@@ -144,7 +147,7 @@ public class SplitNumberVectorFilter<V extends NumberVector<?>> implements Objec
for(int i = 1; i < dims.length; i++) {
m = Math.max(dims[i], m);
}
- return new VectorFieldTypeInformation<>(NumberVector.class, m, Integer.MAX_VALUE);
+ return VectorFieldTypeInformation.typeRequest(NumberVector.class, m, Integer.MAX_VALUE);
}
/**
@@ -154,7 +157,7 @@ public class SplitNumberVectorFilter<V extends NumberVector<?>> implements Objec
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* The parameter listing the split dimensions.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/package-info.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/package-info.java
new file mode 100644
index 00000000..d582c8d2
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/typeconversions/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Filters to perform data type conversions.
+ */
+
+/*
+ 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.datasource.filter.typeconversions; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/package-info.java b/src/de/lmu/ifi/dbs/elki/datasource/package-info.java
index 98ce5b36..24e8aae6 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/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/datasource/parser/AbstractParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/AbstractParser.java
index e8201db1..53d814ea 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/AbstractParser.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/AbstractParser.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
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,9 +23,11 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.io.Tokenizer;
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;
@@ -45,7 +47,7 @@ public abstract class AbstractParser {
/**
* A pattern defining whitespace.
*/
- public static final String DEFAULT_SEPARATOR = "(\\s+|\\s*[,;]\\s*)";
+ public static final String DEFAULT_SEPARATOR = "\\s*[,;\\s]\\s*";
/**
* A quote pattern
@@ -74,7 +76,7 @@ public abstract class AbstractParser {
/**
* Comment pattern.
*/
- protected Pattern comment = null;
+ private Matcher comment = null;
/**
* String tokenizer.
@@ -91,10 +93,16 @@ public abstract class AbstractParser {
public AbstractParser(Pattern colSep, String quoteChars, Pattern comment) {
super();
this.tokenizer = new Tokenizer(colSep, quoteChars);
- this.comment = comment;
+ this.comment = comment.matcher("");
}
- public static int lengthWithoutLinefeed(String line) {
+ /**
+ * Get the length of the string, not taking trailing linefeeds into account.
+ *
+ * @param line Input line
+ * @return Length
+ */
+ public static int lengthWithoutLinefeed(CharSequence line) {
int length = line.length();
while(length > 0) {
char last = line.charAt(length - 1);
@@ -114,6 +122,26 @@ public abstract class AbstractParser {
protected abstract Logging getLogger();
/**
+ * Cleanup internal data structures.
+ */
+ public void cleanup() {
+ tokenizer.cleanup();
+ if(comment != null) {
+ comment.reset("");
+ }
+ }
+
+ /**
+ * Match a comment line.
+ *
+ * @param line Line to test
+ * @return {@code true} if the line matches the comment pattern.
+ */
+ protected boolean isComment(CharSequence line) {
+ return (comment != null && comment.reset(line).matches());
+ }
+
+ /**
* Returns a string representation of the object.
*
* @return a string representation of the object.
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/AbstractStreamingParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/AbstractStreamingParser.java
index a218638a..9e58aced 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/AbstractStreamingParser.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/AbstractStreamingParser.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
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,18 +23,41 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
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.database.ids.DBIDVar;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.utilities.io.LineReader;
/**
* Base class for streaming parsers.
*
+ * TODO: build our own replacement for {@link BufferedReader}, which recycles
+ * the string builder.
+ *
* @author Erich Schubert
*/
public abstract class AbstractStreamingParser extends AbstractParser implements StreamingParser {
/**
+ * Line reader.
+ */
+ private LineReader reader;
+
+ /**
+ * The buffer we read the data into.
+ */
+ private StringBuilder buf = new StringBuilder();
+
+ /**
+ * Current line number.
+ */
+ private int lineNumber;
+
+ /**
* Constructor.
*
* @param colSep Column separator pattern
@@ -50,4 +73,67 @@ public abstract class AbstractStreamingParser extends AbstractParser implements
this.initStream(in);
return MultipleObjectsBundle.fromStream(this);
}
+
+ @Override
+ public void initStream(InputStream in) {
+ reader = new LineReader(new InputStreamReader(in));
+ lineNumber = 0;
+ }
+
+ /**
+ * Get the current line number.
+ *
+ * @return Current line number
+ */
+ protected int getLineNumber() {
+ return lineNumber;
+ }
+
+ @Override
+ public boolean hasDBIDs() {
+ return false;
+ }
+
+ @Override
+ public boolean assignDBID(DBIDVar var) {
+ var.unset();
+ return false;
+ }
+
+ /**
+ * Read the next line into the tokenizer.
+ *
+ * @return The next line, or {@code null}.
+ */
+ protected boolean nextLineExceptComments() throws IOException {
+ while(reader.readLine(buf.delete(0, buf.length()))) {
+ ++lineNumber;
+ final int len = lengthWithoutLinefeed(buf);
+ if(len > 0 && !isComment(buf)) {
+ tokenizer.initialize(buf, 0, len);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void cleanup() {
+ super.cleanup();
+ try {
+ if(reader != null) {
+ reader.close();
+ }
+ buf.setLength(0);
+ buf.trimToSize();
+ }
+ catch(IOException e) {
+ // Ignore - maybe already closed.
+ }
+ }
+
+ @Override
+ public MultipleObjectsBundle asMultipleObjectsBundle() {
+ return MultipleObjectsBundle.fromStream(this);
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/ArffParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/ArffParser.java
index 50714b81..1c9bf4e9 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/ArffParser.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/ArffParser.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
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
@@ -78,22 +78,22 @@ public class ArffParser implements Parser {
/**
* Arff file marker.
*/
- public static final Pattern ARFF_HEADER_RELATION = Pattern.compile("@relation\\s+(.*)", Pattern.CASE_INSENSITIVE);
+ public static final Matcher ARFF_HEADER_RELATION = Pattern.compile("@relation\\s+(.*)", Pattern.CASE_INSENSITIVE).matcher("");
/**
* Arff attribute declaration marker.
*/
- public static final Pattern ARFF_HEADER_ATTRIBUTE = Pattern.compile("@attribute\\s+([^ ]+|['\"].*?['\"])\\s+(numeric|real|integer|string|double|date(\\s.*)|\\{.*\\})\\s*", Pattern.CASE_INSENSITIVE);
+ public static final Matcher ARFF_HEADER_ATTRIBUTE = Pattern.compile("@attribute\\s+([^ ]+|['\"].*?['\"])\\s+(numeric|real|integer|string|double|date(\\s.*)|\\{.*\\})\\s*", Pattern.CASE_INSENSITIVE).matcher("");
/**
* Arff data marker.
*/
- public static final Pattern ARFF_HEADER_DATA = Pattern.compile("@data\\s*", Pattern.CASE_INSENSITIVE);
+ public static final Matcher ARFF_HEADER_DATA = Pattern.compile("@data\\s*", Pattern.CASE_INSENSITIVE).matcher("");
/**
* Comment pattern.
*/
- public static final Pattern ARFF_COMMENT = Pattern.compile("^\\s*%.*");
+ public static final Matcher ARFF_COMMENT = Pattern.compile("^\\s*%.*").matcher("");
/**
* Pattern to auto-convert columns to external ids.
@@ -108,22 +108,22 @@ public class ArffParser implements Parser {
/**
* Pattern for numeric columns.
*/
- public static final Pattern ARFF_NUMERIC = Pattern.compile("(numeric|real|integer|double)", Pattern.CASE_INSENSITIVE);
+ public static final Matcher ARFF_NUMERIC = Pattern.compile("(numeric|real|integer|double)", Pattern.CASE_INSENSITIVE).matcher("");
/**
* Empty line pattern.
*/
- public static final Pattern EMPTY = Pattern.compile("^\\s*$");
+ public static final Matcher EMPTY = Pattern.compile("^\\s*$").matcher("");
/**
* Pattern to recognize external ids.
*/
- Pattern magic_eid;
+ Matcher magic_eid;
/**
* Pattern to recognize class label columns.
*/
- Pattern magic_class;
+ Matcher magic_class;
/**
* (Reused) buffer for building label lists.
@@ -138,8 +138,8 @@ public class ArffParser implements Parser {
*/
public ArffParser(Pattern magic_eid, Pattern magic_class) {
super();
- this.magic_eid = magic_eid;
- this.magic_class = magic_class;
+ this.magic_eid = magic_eid.matcher("");
+ this.magic_class = magic_class.matcher("");
}
/**
@@ -477,11 +477,11 @@ public class ArffParser implements Parser {
throw new AbortException(ARFF_HEADER_RELATION + " not found in file.");
}
// Skip comments and empty lines
- if(ARFF_COMMENT.matcher(line).matches() || EMPTY.matcher(line).matches()) {
+ if(ARFF_COMMENT.reset(line).matches() || EMPTY.reset(line).matches()) {
continue;
}
// Break on relation statement
- if(ARFF_HEADER_RELATION.matcher(line).matches()) {
+ if(ARFF_HEADER_RELATION.reset(line).matches()) {
break;
}
throw new AbortException("Expected relation declaration: " + line);
@@ -505,15 +505,15 @@ public class ArffParser implements Parser {
throw new AbortException(ARFF_HEADER_DATA + " not found in file.");
}
// Skip comments and empty lines
- if(ARFF_COMMENT.matcher(line).matches() || EMPTY.matcher(line).matches()) {
+ if(ARFF_COMMENT.reset(line).matches() || EMPTY.reset(line).matches()) {
continue;
}
// Break on data statement to continue
- if(ARFF_HEADER_DATA.matcher(line).matches()) {
+ if(ARFF_HEADER_DATA.reset(line).matches()) {
break;
}
// Expect an attribute specification
- Matcher matcher = ARFF_HEADER_ATTRIBUTE.matcher(line);
+ Matcher matcher = ARFF_HEADER_ATTRIBUTE.reset(line);
if(matcher.matches()) {
String name = matcher.group(1);
if(name.charAt(0) == '\'' && name.charAt(name.length() - 1) == '\'') {
@@ -547,7 +547,7 @@ public class ArffParser implements Parser {
private void processColumnTypes(ArrayList<String> names, ArrayList<String> types, int[] targ, TypeInformation[] etyp, int[] dims) {
int next = 0;
for(int i = 0; i < targ.length; i++) {
- if(magic_eid != null && magic_eid.matcher(names.get(i)).matches()) {
+ if(magic_eid != null && magic_eid.reset(names.get(i)).matches()) {
// Turn into an external ID column.
targ[i] = next;
etyp[next] = TypeUtil.EXTERNALID;
@@ -555,7 +555,7 @@ public class ArffParser implements Parser {
next++;
continue;
}
- else if(magic_class != null && magic_class.matcher(names.get(i)).matches()) {
+ else if(magic_class != null && magic_class.reset(names.get(i)).matches()) {
// Type as ClassLabel
targ[i] = next;
etyp[next] = TypeUtil.CLASSLABEL;
@@ -563,7 +563,7 @@ public class ArffParser implements Parser {
next++;
continue;
}
- else if(ARFF_NUMERIC.matcher(types.get(i)).matches()) {
+ else if(ARFF_NUMERIC.reset(types.get(i)).matches()) {
// Create a number vector field
if(next > 0 && TypeUtil.NUMBER_VECTOR_FIELD.equals(etyp[next - 1])) {
targ[i] = next - 1;
@@ -629,6 +629,16 @@ public class ArffParser implements Parser {
}
}
+ @Override
+ public void cleanup() {
+ if (magic_eid != null) {
+ magic_eid.reset("");
+ }
+ if (magic_class != null) {
+ magic_class.reset("");
+ }
+ }
+
/**
* Parameterization class.
*
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/BitVectorLabelParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/BitVectorLabelParser.java
index 26bc38af..cdca7b05 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/BitVectorLabelParser.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/BitVectorLabelParser.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
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,18 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
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.ArrayList;
-import java.util.BitSet;
-import java.util.List;
+import gnu.trove.list.array.TLongArrayList;
+
import java.util.regex.Pattern;
import de.lmu.ifi.dbs.elki.data.BitVector;
import de.lmu.ifi.dbs.elki.data.LabelList;
-import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
-import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
-import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
/**
- * Provides a parser for parsing one BitVector per line, bits separated by
- * whitespace.
+ * Parser for parsing one BitVector per line, bits separated by whitespace.
* <p/>
* Several labels may be given per BitVector. A label must not be parseable as
* Bit. Lines starting with &quot;#&quot; will be ignored.
@@ -53,14 +44,24 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
* @apiviz.has BitVector
*/
@Title("Bit Vector Label Parser")
-@Description("Parses the following format of lines:\n" + "A single line provides a single BitVector. Bits are separated by whitespace. Any substring not containing whitespace is tried to be read as Bit. If this fails, it will be appended to a label. (Thus, any label must not be parseable as Bit.) Empty lines and lines beginning with \"#\" will be ignored. If any BitVector differs in its dimensionality from other BitVectors, the parse method will fail with an Exception.")
-public class BitVectorLabelParser extends AbstractParser implements Parser {
+@Description("Parses the following format of lines:\n" + //
+"A single line provides a single BitVector. Bits are separated by whitespace. " + //
+"Any substring not containing whitespace is tried to be read as Bit. " + //
+"If this fails, it will be appended to a label. " + //
+"(Thus, any label must not be parseable as Bit.) " + //
+"Empty lines and lines beginning with \"#\" will be ignored.")
+public class BitVectorLabelParser extends NumberVectorLabelParser<BitVector> implements Parser {
/**
* Class logger
*/
private static final Logging LOG = Logging.getLogger(BitVectorLabelParser.class);
/**
+ * Buffer, will be reused.
+ */
+ TLongArrayList buf = new TLongArrayList();
+
+ /**
* Constructor.
*
* @param colSep Column separator
@@ -68,57 +69,37 @@ public class BitVectorLabelParser extends AbstractParser implements Parser {
* @param comment Comment pattern
*/
public BitVectorLabelParser(Pattern colSep, String quoteChars, Pattern comment) {
- super(colSep, quoteChars, comment);
+ super(colSep, quoteChars, comment, null, BitVector.FACTORY);
}
@Override
- public MultipleObjectsBundle parse(InputStream in) {
- BufferedReader reader = new BufferedReader(new InputStreamReader(in));
- int lineNumber = 0;
- int dimensionality = -1;
- List<BitVector> vectors = new ArrayList<>();
- List<LabelList> labels = new ArrayList<>();
- ArrayList<String> ll = new ArrayList<>();
- try {
- for(String line; (line = reader.readLine()) != null; lineNumber++) {
- // Skip empty lines and comments
- if(line.length() <= 0 || (comment != null && comment.matcher(line).matches())) {
- continue;
- }
- BitSet bitSet = new BitSet();
- ll.clear();
- int i = 0;
- for(tokenizer.initialize(line, 0, lengthWithoutLinefeed(line)); tokenizer.valid(); tokenizer.advance()) {
- try {
- if(tokenizer.getLongBase10() > 0) {
- bitSet.set(i);
- }
- ++i;
- }
- catch(NumberFormatException e) {
- ll.add(tokenizer.getSubstring());
- }
+ protected boolean parseLineInternal() {
+ int curdim = 0;
+ for(; tokenizer.valid(); tokenizer.advance()) {
+ try {
+ final int word = curdim >>> 6;
+ final int off = curdim & 0x3F;
+ if(word >= buf.size()) { // Ensure size.
+ buf.add(0L);
}
-
- if(dimensionality < 0) {
- dimensionality = i;
- }
- else if(dimensionality != i) {
- throw new IllegalArgumentException("Differing dimensionality in line " + lineNumber + ".");
+ if(tokenizer.getLongBase10() > 0) {
+ buf.set(word, buf.get(word) | (1L << off));
}
-
- vectors.add(new BitVector(bitSet, dimensionality));
- labels.add(LabelList.make(ll));
+ ++curdim;
+ }
+ catch(NumberFormatException e) {
+ labels.add(tokenizer.getSubstring());
}
}
- catch(IOException e) {
- throw new IllegalArgumentException("Error while parsing line " + lineNumber + ".");
+ if(curdim == 0) { // Maybe a label row
+ return false;
}
- return MultipleObjectsBundle.makeSimple(getTypeInformation(dimensionality), vectors, TypeUtil.LABELLIST, labels);
- }
- protected VectorFieldTypeInformation<BitVector> getTypeInformation(int dimensionality) {
- return new VectorFieldTypeInformation<>(BitVector.FACTORY, dimensionality);
+ curvec = new BitVector(buf.toArray(), curdim);
+ curlbl = LabelList.make(labels);
+ buf.clear();
+ labels.clear();
+ return true;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/CategorialDataAsNumberVectorParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/CategorialDataAsNumberVectorParser.java
index 3dd49470..0471ffae 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/CategorialDataAsNumberVectorParser.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/CategorialDataAsNumberVectorParser.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
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,6 +26,7 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
import gnu.trove.map.hash.TObjectIntHashMap;
import java.util.BitSet;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.lmu.ifi.dbs.elki.data.LabelList;
@@ -50,7 +51,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
@Description("This parser expects data in roughly the same format as the NumberVectorLabelParser,\n"//
+ "except that it will enumerate all unique strings to always produce numerical values.\n"//
+ "This way, it can for example handle files that contain lines like 'y,n,y,y,n,y,n'.")
-public class CategorialDataAsNumberVectorParser<V extends NumberVector<?>> extends NumberVectorLabelParser<V> {
+public class CategorialDataAsNumberVectorParser<V extends NumberVector> extends NumberVectorLabelParser<V> {
/**
* Logging class.
*/
@@ -69,14 +70,14 @@ public class CategorialDataAsNumberVectorParser<V extends NumberVector<?>> exten
/**
* Pattern for NaN values.
*/
- Pattern nanpattern = Pattern.compile("\\?");
+ Matcher nanpattern = Pattern.compile("\\?").matcher("Dummy text");
/**
* Constructor with defaults.
*
* @param factory Vector factory
*/
- public CategorialDataAsNumberVectorParser(NumberVector.Factory<V, ?> factory) {
+ public CategorialDataAsNumberVectorParser(NumberVector.Factory<V> factory) {
this(Pattern.compile(DEFAULT_SEPARATOR), QUOTE_CHARS, Pattern.compile(COMMENT_PATTERN), null, factory);
}
@@ -89,7 +90,7 @@ public class CategorialDataAsNumberVectorParser<V extends NumberVector<?>> exten
* @param labelIndices Column indexes that are numeric.
* @param factory Vector factory
*/
- public CategorialDataAsNumberVectorParser(Pattern colSep, String quoteChars, Pattern comment, BitSet labelIndices, NumberVector.Factory<V, ?> factory) {
+ public CategorialDataAsNumberVectorParser(Pattern colSep, String quoteChars, Pattern comment, BitSet labelIndices, NumberVector.Factory<V> factory) {
super(colSep, quoteChars, comment, labelIndices, factory);
}
@@ -103,14 +104,10 @@ public class CategorialDataAsNumberVectorParser<V extends NumberVector<?>> exten
}
@Override
- protected void parseLineInternal(String line) {
- // Split into numerical attributes and labels
- attributes.reset();
- labels.clear();
-
+ protected boolean parseLineInternal() {
int i = 0;
- for(tokenizer.initialize(line, 0, lengthWithoutLinefeed(line)); tokenizer.valid(); tokenizer.advance(), i++) {
- if(labelIndices == null || !labelIndices.get(i)) {
+ for(/* Initialized by nextLineExceptComments */; tokenizer.valid(); tokenizer.advance(), i++) {
+ if(!isLabelColumn(i)) {
try {
double attribute = tokenizer.getDouble();
attributes.add(attribute);
@@ -118,7 +115,7 @@ public class CategorialDataAsNumberVectorParser<V extends NumberVector<?>> exten
}
catch(NumberFormatException e) {
String s = tokenizer.getSubstring();
- if(nanpattern.matcher(s).matches()) {
+ if(nanpattern.reset(s).matches()) {
attributes.add(Double.NaN);
continue;
}
@@ -138,6 +135,9 @@ public class CategorialDataAsNumberVectorParser<V extends NumberVector<?>> exten
// Pass outside via class variables
curvec = createDBObject(attributes, ArrayLikeUtil.TDOUBLELISTADAPTER);
curlbl = LabelList.make(labels);
+ attributes.reset();
+ labels.clear();
+ return true;
}
@Override
@@ -152,7 +152,7 @@ public class CategorialDataAsNumberVectorParser<V extends NumberVector<?>> exten
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends NumberVectorLabelParser.Parameterizer<V> {
+ public static class Parameterizer<V extends NumberVector> extends NumberVectorLabelParser.Parameterizer<V> {
@Override
protected CategorialDataAsNumberVectorParser<V> makeInstance() {
return new CategorialDataAsNumberVectorParser<>(colSep, quoteChars, comment, labelIndices, factory);
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/ClusteringVectorParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/ClusteringVectorParser.java
new file mode 100644
index 00000000..9b812792
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/ClusteringVectorParser.java
@@ -0,0 +1,268 @@
+package de.lmu.ifi.dbs.elki.datasource.parser;
+
+/*
+ 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 gnu.trove.iterator.TIntIntIterator;
+import gnu.trove.iterator.TIntObjectIterator;
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.TIntIntMap;
+import gnu.trove.map.TIntObjectMap;
+import gnu.trove.map.hash.TIntIntHashMap;
+import gnu.trove.map.hash.TIntObjectHashMap;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.regex.Pattern;
+
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.data.LabelList;
+import de.lmu.ifi.dbs.elki.data.model.ClusterModel;
+import de.lmu.ifi.dbs.elki.data.model.Model;
+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.DBIDArrayIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRange;
+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.bundle.BundleMeta;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.result.ClusteringVectorDumper;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+
+/**
+ * Parser for simple clustering results in vector form, as written by
+ * {@link ClusteringVectorDumper}.
+ *
+ * This allows reading the output of <em>multiple</em> clustering runs, and
+ * analyze the results using ELKI algorithm.
+ *
+ * The input format is very simple, each line containing a sequence of cluster
+ * assignments in integer form, and an optional label:
+ *
+ * <pre>
+ * 0 0 1 1 0 First
+ * 0 0 0 1 2 Second
+ * </pre>
+ *
+ * represents two clusterings for 5 objects. The first clustering has two
+ * clusters, the second contains three clusters.
+ *
+ * TODO: this parser currently is quite hacky, and could use a cleanup.
+ *
+ * TODO: support noise, via negative cluster numbers?
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has Clustering
+ */
+public class ClusteringVectorParser extends AbstractStreamingParser {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(ClusteringVectorParser.class);
+
+ /**
+ * Number of different terms observed.
+ */
+ int numterms;
+
+ /**
+ * Metadata.
+ */
+ protected BundleMeta meta;
+
+ /**
+ * Event to report next.
+ */
+ Event nextevent;
+
+ /**
+ * Current clustering.
+ */
+ Clustering<Model> curclu;
+
+ /**
+ * Current labels.
+ */
+ LabelList curlbl;
+
+ /**
+ * Buffers, will be reused.
+ */
+ TIntArrayList buf1 = new TIntArrayList();
+
+ /**
+ * Range of the DBID values.
+ */
+ DBIDRange range = null;
+
+ /**
+ * Buffer for labels.
+ */
+ ArrayList<String> lbl = new ArrayList<>();
+
+ /**
+ * Flag if labels are present.
+ */
+ boolean haslbl;
+
+ /**
+ * Constructor.
+ *
+ * @param colSep Column separator
+ * @param quoteChars Quote character
+ * @param comment Comment pattern
+ */
+ public ClusteringVectorParser(Pattern colSep, String quoteChars, Pattern comment) {
+ super(colSep, quoteChars, comment);
+ }
+
+ @Override
+ public void initStream(InputStream in) {
+ super.initStream(in);
+ range = null; // New range
+ haslbl = false;
+ }
+
+ @Override
+ public Event nextEvent() {
+ if(nextevent != null) {
+ Event ret = nextevent;
+ nextevent = null;
+ return ret;
+ }
+ try {
+ while(nextLineExceptComments()) {
+ buf1.clear();
+ lbl.clear();
+ TIntIntMap csize = new TIntIntHashMap();
+ TIntObjectMap<ModifiableDBIDs> clusters = new TIntObjectHashMap<>();
+ String name = null;
+ for(/* initialized by nextLineExceptComments() */; tokenizer.valid(); tokenizer.advance()) {
+ try {
+ int cnum = (int) tokenizer.getLongBase10();
+ buf1.add(cnum);
+ // Update cluster sizes:
+ if(!csize.increment(cnum)) {
+ csize.put(cnum, 1);
+ }
+ }
+ catch(NumberFormatException e) {
+ final String label = tokenizer.getSubstring();
+ lbl.add(label);
+ if(name == null) {
+ name = label;
+ }
+ }
+ }
+ if(name == null) {
+ name = "Cluster";
+ }
+ // Update meta on first record:
+ boolean metaupdate = (range == null);
+ if(range == null) {
+ range = DBIDUtil.generateStaticDBIDRange(buf1.size());
+ }
+ if(buf1.size() != range.size()) {
+ throw new AbortException("Clusterings do not contain the same number of elements!");
+ }
+ // Build clustering to store in the relation.
+ curclu = new Clustering<>(name, name);
+ for(TIntIntIterator iter = csize.iterator(); iter.hasNext();) {
+ iter.advance();
+ if(iter.value() > 0) {
+ clusters.put(iter.key(), DBIDUtil.newArray(iter.value()));
+ }
+ }
+ DBIDArrayIter iter = range.iter();
+ for(int i = 0; i < buf1.size(); i++) {
+ clusters.get(buf1.get(i)).add(iter.seek(i));
+ }
+ for(TIntObjectIterator<ModifiableDBIDs> iter2 = clusters.iterator(); iter2.hasNext();) {
+ iter2.advance();
+ curclu.addToplevelCluster(new Cluster<Model>(iter2.value(), ClusterModel.CLUSTER));
+ }
+ // Label handling.
+ if(!haslbl && lbl.size() > 0) {
+ haslbl = true;
+ metaupdate = true;
+ }
+ curlbl = LabelList.make(lbl);
+ if(metaupdate) {
+ nextevent = Event.NEXT_OBJECT; // Force a meta update.
+ return Event.META_CHANGED;
+ }
+ return Event.NEXT_OBJECT;
+ }
+ return Event.END_OF_STREAM;
+ }
+ catch(IOException e) {
+ throw new IllegalArgumentException("Error while parsing line " + getLineNumber() + ".");
+ }
+ }
+
+ @Override
+ public Object data(int rnum) {
+ if(rnum == 0) {
+ return curclu;
+ }
+ if(rnum == 1) {
+ return curlbl;
+ }
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ @Override
+ public BundleMeta getMeta() {
+ if(meta == null) {
+ meta = new BundleMeta(haslbl ? 2 : 1);
+ meta.add(new SimpleTypeInformation<>(Clustering.class, "Clusters"));
+ if(haslbl) {
+ meta.add(TypeUtil.LABELLIST);
+ }
+ }
+ return meta;
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractStreamingParser.Parameterizer {
+ @Override
+ protected ClusteringVectorParser makeInstance() {
+ return new ClusteringVectorParser(colSep, quoteChars, comment);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/DoubleVectorLabelParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/DoubleVectorLabelParser.java
deleted file mode 100644
index bf84f2ce..00000000
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/DoubleVectorLabelParser.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package de.lmu.ifi.dbs.elki.datasource.parser;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2011
- 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 java.util.regex.Pattern;
-
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-
-/**
- * <p>
- * Provides a parser for parsing one point per line, attributes separated by
- * whitespace.
- * </p>
- * <p>
- * Several labels may be given per point. A label must not be parseable as
- * double. Lines starting with &quot;#&quot; will be ignored.
- * </p>
- * <p/>
- * <p>
- * An index can be specified to identify an entry to be treated as class label.
- * This index counts all entries (numeric and labels as well) starting with 0.
- * </p>
- *
- * @author Arthur Zimek
- *
- * @apiviz.has DoubleVector
- *
- * @deprecated Use NumberVectorLabelParser instead, which defaults to
- * DoubleVector.
- */
-@Deprecated
-public class DoubleVectorLabelParser extends NumberVectorLabelParser<DoubleVector> {
- /**
- * Class logger
- */
- private static final Logging LOG = Logging.getLogger(DoubleVectorLabelParser.class);
-
- /**
- * Constructor.
- *
- * @param colSep Column separator
- * @param quoteChars Quotation character
- * @param comment Comment pattern
- * @param labelIndices Indices to use as labels
- */
- public DoubleVectorLabelParser(Pattern colSep, String quoteChars, Pattern comment, BitSet labelIndices) {
- super(colSep, quoteChars, comment, labelIndices, DoubleVector.FACTORY);
- }
-
- /**
- * Constructor with default values.
- */
- public DoubleVectorLabelParser() {
- this(Pattern.compile(DEFAULT_SEPARATOR), QUOTE_CHARS, Pattern.compile(COMMENT_PATTERN), new BitSet());
- }
-
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer extends NumberVectorLabelParser.Parameterizer<DoubleVector> {
- @Override
- protected void getFactory(Parameterization config) {
- // Do nothing: not used
- }
-
- @Override
- protected DoubleVectorLabelParser makeInstance() {
- return new DoubleVectorLabelParser(colSep, quoteChars, comment, labelIndices);
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/FloatVectorLabelParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/FloatVectorLabelParser.java
deleted file mode 100644
index 6d800cd8..00000000
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/FloatVectorLabelParser.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package de.lmu.ifi.dbs.elki.datasource.parser;
-/*
-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 java.util.regex.Pattern;
-
-import de.lmu.ifi.dbs.elki.data.FloatVector;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-
-/**
- * <p>
- * Provides a parser for parsing one point per line, attributes separated by
- * whitespace.
- * </p>
- * <p>
- * Numerical values in a line will be parsed as double values but used in float
- * precision only.
- * </p>
- * <p>
- * Several labels may be given per point. A label must not be parseable as
- * double. Lines starting with &quot;#&quot; will be ignored.
- * </p>
- * <p/>
- * <p>
- * An index can be specified to identify an entry to be treated as class label.
- * This index counts all entries (numeric and labels as well) starting with 0.
- * </p>
- *
- * @author Arthur Zimek
- *
- * @apiviz.has FloatVector
- *
- * @deprecated Use NumberVectorLabelParser instead, and use vector type FloatVector.
- */
-@Deprecated
-public class FloatVectorLabelParser extends NumberVectorLabelParser<FloatVector> {
- /**
- * Class logger.
- */
- private static final Logging LOG = Logging.getLogger(FloatVectorLabelParser.class);
-
- /**
- * Constructor.
- *
- * @param colSep Column separator
- * @param quoteChars Quotation character
- * @param comment Comment pattern
- * @param labelIndices Indices to use as labels
- */
- public FloatVectorLabelParser(Pattern colSep, String quoteChars, Pattern comment, BitSet labelIndices) {
- super(colSep, quoteChars, comment, labelIndices, FloatVector.FACTORY);
- }
-
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer extends NumberVectorLabelParser.Parameterizer<FloatVector> {
- @Override
- protected void getFactory(Parameterization config) {
- // Do nothing: not used
- }
-
- @Override
- protected FloatVectorLabelParser makeInstance() {
- return new FloatVectorLabelParser(colSep, quoteChars, comment, labelIndices);
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/LibSVMFormatParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/LibSVMFormatParser.java
new file mode 100644
index 00000000..3a7ac44a
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/LibSVMFormatParser.java
@@ -0,0 +1,151 @@
+package de.lmu.ifi.dbs.elki.datasource.parser;
+
+/*
+ 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.regex.Pattern;
+
+import de.lmu.ifi.dbs.elki.data.LabelList;
+import de.lmu.ifi.dbs.elki.data.SparseFloatVector;
+import de.lmu.ifi.dbs.elki.data.SparseNumberVector;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
+
+/**
+ * Parser to read libSVM format files.
+ *
+ *
+ * The format of libSVM is roughly specified in the README given:
+ *
+ * <pre>
+ * &lt;label&gt; &lt;index1&gt;:&lt;value1&gt; &lt;index2&gt;:&lt;value2&gt; ...
+ * </pre>
+ *
+ * i.e. a mandatory integer class label in the beginning followed by a classic
+ * sparse vector representation of the data. indexes are integers, starting at 1
+ * (Note that ELKI uses 0-based indexing, so we will map these to index-1) to
+ * not always have a constant-0 dimension 0.
+ *
+ * The FAQ states that you can also put comments into the file, separated by a
+ * dash: <tt>#</tt>, but they must not contain colons and are not officially
+ * supported. ELKI will simply stop parsing a line when encountering a
+ * <tt>#</tt>.
+ *
+ * @author Erich Schubert
+ *
+ * @param <V> Vector type
+ */
+public class LibSVMFormatParser<V extends SparseNumberVector> extends SparseNumberVectorLabelParser<V> {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(LibSVMFormatParser.class);
+
+ /**
+ * LibSVM uses whitespace and colons for separation.
+ */
+ public static final Pattern WHITESPACE_PATTERN = Pattern.compile("(\\s+|:)");
+
+ /**
+ * Comment pattern.
+ */
+ public static final Pattern COMMENT_PATTERN = Pattern.compile("#");
+
+ /**
+ * Constructor.
+ *
+ * @param factory Vector factory
+ */
+ public LibSVMFormatParser(SparseNumberVector.Factory<V> factory) {
+ super(WHITESPACE_PATTERN, null, COMMENT_PATTERN, null, factory);
+ }
+
+ @Override
+ protected boolean parseLineInternal() {
+ /* tokenizer initialized by nextLineExceptComments() */
+ int thismax = 0;
+
+ // TODO: rely on the string being numeric for performance
+ // But it might be missing sometimes, or "?"
+ labels.add(tokenizer.getSubstring());
+ tokenizer.advance();
+ haslabels = true; // libSVM always has labels.
+
+ while(tokenizer.valid()) {
+ try {
+ int index = (int) tokenizer.getLongBase10();
+ tokenizer.advance();
+ double attribute = tokenizer.getDouble();
+ tokenizer.advance();
+ thismax = Math.max(thismax, index + 1);
+ values.put(index, attribute);
+ }
+ catch(NumberFormatException e) {
+ String comment = tokenizer.getSubstring();
+ if(comment.charAt(0) == '#') {
+ break;
+ }
+ throw new RuntimeException("Parsing error in line " + getLineNumber() + ": expected data, got " + comment);
+ }
+ }
+ curvec = sparsefactory.newNumberVector(values, thismax);
+ curlbl = LabelList.make(labels);
+ values.clear();
+ labels.clear();
+ return true;
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<V extends SparseNumberVector> extends NumberVectorLabelParser.Parameterizer<V> {
+ @Override
+ protected void getFactory(Parameterization config) {
+ ObjectParameter<SparseNumberVector.Factory<V>> factoryP = new ObjectParameter<>(VECTOR_TYPE_ID, SparseNumberVector.Factory.class, SparseFloatVector.Factory.class);
+ if(config.grab(factoryP)) {
+ factory = factoryP.instantiateClass(config);
+ }
+ }
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ // Avoid additional options: super.makeOptions(config);
+ getFactory(config);
+ }
+
+ @Override
+ protected LibSVMFormatParser<V> makeInstance() {
+ return new LibSVMFormatParser<>((SparseNumberVector.Factory<V>) factory);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/NumberVectorLabelParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/NumberVectorLabelParser.java
index 3fe4af09..e09dcd22 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/NumberVectorLabelParser.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/NumberVectorLabelParser.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
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,13 +25,10 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
import gnu.trove.list.array.TDoubleArrayList;
-import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.BitSet;
-import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;
@@ -46,6 +43,7 @@ import de.lmu.ifi.dbs.elki.datasource.bundle.BundleMeta;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.hash.Unique;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -53,18 +51,14 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntListParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
- * <p>
- * Provides a parser for parsing one point per line, attributes separated by
- * whitespace.
- * </p>
- * <p>
+ * Parser for a simple CSV type of format, with columns separated by the given
+ * pattern (default: whitespace).
+ *
* Several labels may be given per point. A label must not be parseable as
* double. Lines starting with &quot;#&quot; will be ignored.
- * </p>
- * <p>
+ *
* An index can be specified to identify an entry to be treated as class label.
* This index counts all entries (numeric and labels as well) starting with 0.
- * </p>
*
* @author Arthur Zimek
*
@@ -73,7 +67,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @param <V> the type of NumberVector used
*/
-public class NumberVectorLabelParser<V extends NumberVector<?>> extends AbstractStreamingParser {
+public class NumberVectorLabelParser<V extends NumberVector> extends AbstractStreamingParser {
/**
* Logging class.
*/
@@ -82,22 +76,12 @@ public class NumberVectorLabelParser<V extends NumberVector<?>> extends Abstract
/**
* Keeps the indices of the attributes to be treated as a string label.
*/
- protected BitSet labelIndices;
+ private BitSet labelIndices;
/**
* Vector factory class.
*/
- protected NumberVector.Factory<V, ?> factory;
-
- /**
- * Buffer reader.
- */
- private BufferedReader reader;
-
- /**
- * Current line number.
- */
- protected int lineNumber;
+ protected NumberVector.Factory<V> factory;
/**
* Dimensionality reported.
@@ -115,11 +99,6 @@ public class NumberVectorLabelParser<V extends NumberVector<?>> extends Abstract
protected List<String> columnnames = null;
/**
- * Bitset to indicate which columns are not numeric.
- */
- protected BitSet labelcolumns = null;
-
- /**
* Whether or not the data set has labels.
*/
protected boolean haslabels = false;
@@ -147,7 +126,7 @@ public class NumberVectorLabelParser<V extends NumberVector<?>> extends Abstract
/**
* For String unification.
*/
- HashMap<String, String> unique = new HashMap<>();
+ Unique<String> unique = new Unique<>();
/**
* Event to report next.
@@ -159,7 +138,7 @@ public class NumberVectorLabelParser<V extends NumberVector<?>> extends Abstract
*
* @param factory Vector factory
*/
- public NumberVectorLabelParser(NumberVector.Factory<V, ?> factory) {
+ public NumberVectorLabelParser(NumberVector.Factory<V> factory) {
this(Pattern.compile(DEFAULT_SEPARATOR), QUOTE_CHARS, Pattern.compile(COMMENT_PATTERN), null, factory);
}
@@ -172,24 +151,30 @@ public class NumberVectorLabelParser<V extends NumberVector<?>> extends Abstract
* @param labelIndices Column indexes that are numeric.
* @param factory Vector factory
*/
- public NumberVectorLabelParser(Pattern colSep, String quoteChars, Pattern comment, BitSet labelIndices, NumberVector.Factory<V, ?> factory) {
+ public NumberVectorLabelParser(Pattern colSep, String quoteChars, Pattern comment, BitSet labelIndices, NumberVector.Factory<V> factory) {
super(colSep, quoteChars, comment);
this.labelIndices = labelIndices;
this.factory = factory;
}
+ /**
+ * Test if the current column is marked as label column.
+ *
+ * @param col Column number
+ * @return {@code true} when a label column.
+ */
+ protected boolean isLabelColumn(int col) {
+ return labelIndices != null && labelIndices.get(col);
+ }
+
@Override
public void initStream(InputStream in) {
- reader = new BufferedReader(new InputStreamReader(in));
- lineNumber = 1;
+ super.initStream(in);
mindim = Integer.MAX_VALUE;
maxdim = 0;
columnnames = null;
haslabels = false;
- labelcolumns = new BitSet();
- if(labelIndices != null) {
- labelcolumns.or(labelIndices);
- }
+ nextevent = null;
}
@Override
@@ -205,41 +190,37 @@ public class NumberVectorLabelParser<V extends NumberVector<?>> extends Abstract
return ret;
}
try {
- for(String line; (line = reader.readLine()) != null; lineNumber++) {
- // Skip empty lines and comments
- if(line.length() <= 0 || (comment != null && comment.matcher(line).matches())) {
- continue;
- }
- parseLineInternal(line);
- // Maybe a header column?
- if(curvec == null) {
- continue;
- }
- final int curdim = curvec.getDimensionality();
- if(curdim > maxdim || mindim > curdim) {
- mindim = Math.min(mindim, curdim);
- maxdim = Math.max(maxdim, curdim);
- buildMeta();
- nextevent = Event.NEXT_OBJECT;
- return Event.META_CHANGED;
- }
- else if(curlbl != null && meta != null && meta.size() == 1) {
- buildMeta();
- nextevent = Event.NEXT_OBJECT;
- return Event.META_CHANGED;
+ while(nextLineExceptComments()) {
+ if(parseLineInternal()) {
+ final int curdim = curvec.getDimensionality();
+ if(curdim > maxdim || mindim > curdim) {
+ mindim = (curdim < mindim) ? curdim : mindim;
+ maxdim = (curdim > maxdim) ? curdim : maxdim;
+ buildMeta();
+ nextevent = Event.NEXT_OBJECT;
+ return Event.META_CHANGED;
+ }
+ else if(curlbl != null && meta != null && meta.size() == 1) {
+ buildMeta();
+ nextevent = Event.NEXT_OBJECT;
+ return Event.META_CHANGED;
+ }
+ return Event.NEXT_OBJECT;
}
- return Event.NEXT_OBJECT;
}
- reader.close();
- reader = null;
- unique.clear();
return Event.END_OF_STREAM;
}
catch(IOException e) {
- throw new IllegalArgumentException("Error while parsing line " + lineNumber + ".");
+ throw new IllegalArgumentException("Error while parsing line " + getLineNumber() + ".");
}
}
+ @Override
+ public void cleanup() {
+ super.cleanup();
+ unique.clear();
+ }
+
/**
* Update the meta element.
*/
@@ -257,13 +238,10 @@ public class NumberVectorLabelParser<V extends NumberVector<?>> extends Abstract
@Override
public Object data(int rnum) {
- if(rnum == 0) {
- return curvec;
- }
- if(rnum == 1) {
- return curlbl;
+ if(rnum > 1) {
+ throw new ArrayIndexOutOfBoundsException();
}
- throw new ArrayIndexOutOfBoundsException();
+ return (rnum == 0) ? curvec : curlbl;
}
/**
@@ -271,16 +249,14 @@ public class NumberVectorLabelParser<V extends NumberVector<?>> extends Abstract
* as well as block parsing. This saves the building of meta data for each
* line.
*
- * @param line Line to process
+ * @return {@code true} when a valid line was read, {@code false} on a label
+ * row.
*/
- protected void parseLineInternal(String line) {
- attributes.reset();
- labels.clear();
-
+ protected boolean parseLineInternal() {
// Split into numerical attributes and labels
int i = 0;
- for(tokenizer.initialize(line, 0, lengthWithoutLinefeed(line)); tokenizer.valid(); tokenizer.advance(), i++) {
- if(labelIndices == null || !labelIndices.get(i)) {
+ for(/* initialized by nextLineExceptComents()! */; tokenizer.valid(); tokenizer.advance(), i++) {
+ if(!isLabelColumn(i) && !tokenizer.isQuoted()) {
try {
double attribute = tokenizer.getDouble();
attributes.add(attribute);
@@ -288,34 +264,30 @@ public class NumberVectorLabelParser<V extends NumberVector<?>> extends Abstract
}
catch(NumberFormatException e) {
// Ignore attempt, add to labels below.
- labelcolumns.set(i);
}
}
// Else: labels.
- haslabels = true;
- final String lbl = tokenizer.getSubstring();
- String u = unique.get(lbl);
- if(u == null) {
- u = lbl;
- unique.put(u, u);
+ String lbl = tokenizer.getStrippedSubstring();
+ if(lbl.length() > 0) {
+ haslabels = true;
+ lbl = unique.addOrGet(lbl);
+ labels.add(lbl);
}
- labels.add(u);
}
// Maybe a label row?
- if(lineNumber == 1 && attributes.size() == 0) {
+ if(getLineNumber() == 1 && attributes.size() == 0) {
columnnames = new ArrayList<>(labels);
- labelcolumns.clear();
- if(labelIndices != null) {
- labelcolumns.or(labelIndices);
- }
+ haslabels = false;
curvec = null;
curlbl = null;
- haslabels = false;
- return;
+ return false;
}
// Pass outside via class variables
curvec = createDBObject(attributes, ArrayLikeUtil.TDOUBLELISTADAPTER);
curlbl = LabelList.make(labels);
+ attributes.reset();
+ labels.clear();
+ return true;
}
/**
@@ -338,28 +310,28 @@ public class NumberVectorLabelParser<V extends NumberVector<?>> extends Abstract
* @return Prototype object
*/
SimpleTypeInformation<V> getTypeInformation(int mindim, int maxdim) {
+ if(mindim > maxdim) {
+ throw new AbortException("No vectors were read from the input file - cannot determine vector data type.");
+ }
if(mindim == maxdim) {
String[] colnames = null;
if(columnnames != null) {
- if(columnnames.size() - labelcolumns.cardinality() == mindim) {
- colnames = new String[mindim];
- for(int i = 0, j = 0; i < columnnames.size(); i++) {
- if(!labelcolumns.get(i)) {
- colnames[j] = columnnames.get(i);
- j++;
- }
+ colnames = new String[mindim];
+ int j = 0;
+ for(int i = 0; i < mindim; i++) {
+ if(!isLabelColumn(i)) {
+ colnames[j] = columnnames.get(i);
+ j++;
}
}
+ if(j == mindim) {
+ colnames = null; // Did not work
+ }
}
return new VectorFieldTypeInformation<>(factory, mindim, colnames);
}
- else if(mindim < maxdim) {
- // Variable dimensionality - return non-vector field type
- return new VectorTypeInformation<>(factory.getRestrictionClass(), factory.getDefaultSerializer(), mindim, maxdim);
- }
- else {
- throw new AbortException("No vectors were read from the input file - cannot determine vector data type.");
- }
+ // Variable dimensionality - return non-vector field type
+ return new VectorTypeInformation<>(factory, factory.getDefaultSerializer(), mindim, maxdim);
}
@Override
@@ -374,7 +346,7 @@ public class NumberVectorLabelParser<V extends NumberVector<?>> extends Abstract
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParser.Parameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParser.Parameterizer {
/**
* A comma separated list of the indices of labels (may be numeric),
* counting whitespace separated entries in a line starting with 0. The
@@ -402,7 +374,7 @@ public class NumberVectorLabelParser<V extends NumberVector<?>> extends Abstract
/**
* Factory object.
*/
- protected NumberVector.Factory<V, ?> factory;
+ protected NumberVector.Factory<V> factory;
@Override
protected void makeOptions(Parameterization config) {
@@ -417,7 +389,7 @@ public class NumberVectorLabelParser<V extends NumberVector<?>> extends Abstract
* @param config Parameterization
*/
protected void getFactory(Parameterization config) {
- ObjectParameter<NumberVector.Factory<V, ?>> factoryP = new ObjectParameter<>(VECTOR_TYPE_ID, NumberVector.Factory.class, DoubleVector.Factory.class);
+ ObjectParameter<NumberVector.Factory<V>> factoryP = new ObjectParameter<>(VECTOR_TYPE_ID, NumberVector.Factory.class, DoubleVector.Factory.class);
if(config.grab(factoryP)) {
factory = factoryP.instantiateClass(config);
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/Parser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/Parser.java
index a0b4e573..df1dc5f6 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/Parser.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/Parser.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
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.datasource.parser;
import java.io.InputStream;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* A Parser shall provide a ParsingResult by parsing an InputStream.
@@ -37,7 +36,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
* @apiviz.uses InputStream
* @apiviz.has MultipleObjectsBundle oneway - - «create»
*/
-public interface Parser extends Parameterizable {
+public interface Parser {
/**
* Returns a list of the objects parsed from the specified input stream.
*
@@ -45,4 +44,9 @@ public interface Parser extends Parameterizable {
* @return a list containing those objects parsed from the input stream
*/
MultipleObjectsBundle parse(InputStream in);
+
+ /**
+ * Perform cleanup operations after parsing.
+ */
+ void cleanup();
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/SimplePolygonParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/SimplePolygonParser.java
index 457a161b..0283a791 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/SimplePolygonParser.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/SimplePolygonParser.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
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
@@ -95,7 +95,7 @@ public class SimplePolygonParser extends AbstractParser implements Parser {
try {
for(String line; (line = reader.readLine()) != null; lineNumber++) {
// Skip empty lines and comments
- if(line.length() <= 0 || (comment != null && comment.matcher(line).matches())) {
+ if(line.length() <= 0 || isComment(line)) {
continue;
}
Object[] objs = parseLine(line);
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/SimpleTransactionParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/SimpleTransactionParser.java
new file mode 100644
index 00000000..a8ffef4b
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/SimpleTransactionParser.java
@@ -0,0 +1,200 @@
+package de.lmu.ifi.dbs.elki.datasource.parser;
+
+/*
+ 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 gnu.trove.iterator.TObjectIntIterator;
+import gnu.trove.list.array.TLongArrayList;
+import gnu.trove.map.TObjectIntMap;
+import gnu.trove.map.hash.TObjectIntHashMap;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.regex.Pattern;
+
+import de.lmu.ifi.dbs.elki.data.BitVector;
+import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
+import de.lmu.ifi.dbs.elki.data.type.VectorTypeInformation;
+import de.lmu.ifi.dbs.elki.datasource.bundle.BundleMeta;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+
+/**
+ * Simple parser for transactional data, such as market baskets.
+ *
+ * To keep the input format simple and readable, all tokens are assumed to be of
+ * text and separated by whitespace, and each transaction is on a separate line.
+ *
+ * An example file containing two transactions looks like this
+ *
+ * <pre>
+ * bread butter milk
+ * paste tomato basil
+ * </pre>
+ *
+ * TODO: add a parameter to e.g. use the first or last entry as labels instead
+ * of tokens.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has BitVector
+ */
+public class SimpleTransactionParser extends AbstractStreamingParser {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(SimpleTransactionParser.class);
+
+ /**
+ * Number of different terms observed.
+ */
+ int numterms;
+
+ /**
+ * Map.
+ */
+ TObjectIntMap<String> keymap;
+
+ /**
+ * Metadata.
+ */
+ protected BundleMeta meta;
+
+ /**
+ * Event to report next.
+ */
+ Event nextevent;
+
+ /**
+ * Current vector.
+ */
+ BitVector curvec;
+
+ /**
+ * Buffer, will be reused.
+ */
+ TLongArrayList buf = new TLongArrayList();
+
+ /**
+ * Constructor.
+ *
+ * @param colSep Column separator
+ * @param quoteChars Quote character
+ * @param comment Comment pattern
+ */
+ public SimpleTransactionParser(Pattern colSep, String quoteChars, Pattern comment) {
+ super(colSep, quoteChars, comment);
+ keymap = new TObjectIntHashMap<>(1001, .5f, -1);
+ }
+
+ @Override
+ public void initStream(InputStream in) {
+ super.initStream(in);
+ nextevent = Event.META_CHANGED; // Initial event.
+ }
+
+ @Override
+ public Event nextEvent() {
+ if(nextevent != null) {
+ Event ret = nextevent;
+ nextevent = null;
+ return ret;
+ }
+ try {
+ while(nextLineExceptComments()) {
+ // Don't reuse bitsets, will not be copied by BitVector constructor.
+ buf.clear();
+ for(/* initialized by nextLineExceptComments() */; tokenizer.valid(); tokenizer.advance()) {
+ String token = tokenizer.getSubstring();
+ int t = keymap.get(token);
+ if(t < 0) {
+ t = keymap.size();
+ keymap.put(token, t);
+ }
+ final int word = t >>> 6;
+ final int off = t & 0x3F;
+ while(word >= buf.size()) { // Ensure size.
+ buf.add(0L);
+ }
+ buf.set(word, buf.get(word) | (1L << off));
+ }
+ curvec = new BitVector(buf.toArray(), keymap.size());
+ return Event.NEXT_OBJECT;
+ }
+ nextevent = Event.END_OF_STREAM;
+ // Construct final metadata:
+ meta = new BundleMeta(1);
+ String[] colnames = new String[keymap.size()];
+ for(TObjectIntIterator<String> iter = keymap.iterator(); iter.hasNext();) {
+ iter.advance();
+ colnames[iter.value()] = iter.key();
+ }
+ meta.add(new VectorFieldTypeInformation<>(BitVector.FACTORY, colnames.length, colnames));
+ return Event.META_CHANGED; // Force a final meta update.
+ }
+ catch(IOException e) {
+ throw new IllegalArgumentException("Error while parsing line " + getLineNumber() + ".");
+ }
+ }
+
+ @Override
+ public void cleanup() {
+ super.cleanup();
+ curvec = null;
+ }
+
+ @Override
+ public Object data(int rnum) {
+ if(rnum == 0) {
+ return curvec;
+ }
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ @Override
+ public BundleMeta getMeta() {
+ if(meta == null) {
+ meta = new BundleMeta(1);
+ meta.add(new VectorTypeInformation<>(BitVector.FACTORY, BitVector.SHORT_SERIALIZER, 0, numterms));
+ }
+ return meta;
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractStreamingParser.Parameterizer {
+ @Override
+ protected SimpleTransactionParser makeInstance() {
+ return new SimpleTransactionParser(colSep, quoteChars, comment);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/SparseBitVectorLabelParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/SparseBitVectorLabelParser.java
deleted file mode 100644
index 06925e67..00000000
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/SparseBitVectorLabelParser.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package de.lmu.ifi.dbs.elki.datasource.parser;
-
-/*
- 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.ArrayList;
-import java.util.BitSet;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import de.lmu.ifi.dbs.elki.data.BitVector;
-import de.lmu.ifi.dbs.elki.data.LabelList;
-import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
-import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
-import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
-import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
-
-/**
- * Provides a parser for parsing one sparse BitVector per line, where the
- * indices of the one-bits are separated by whitespace. The first index starts
- * with zero.
- * <p/>
- * Several labels may be given per BitVector, a label must not be parseable as
- * an Integer. Lines starting with &quot;#&quot; will be ignored.
- *
- * @author Elke Achtert
- *
- * @apiviz.has BitVector
- */
-@Title("Sparse Bit Vector Label Parser")
-@Description("Parser for the lines of the following format:\n" + "A single line provides a single sparse BitVector. The indices of the one-bits are " + "separated by whitespace. The first index starts with zero. Any substring not containing whitespace is tried to be read as an Integer. " + "If this fails, it will be appended to a label. (Thus, any label must not be parseable as an Integer.) " + "Empty lines and lines beginning with \"#\" will be ignored.")
-public class SparseBitVectorLabelParser extends AbstractParser implements Parser {
- /**
- * Class logger
- */
- private static final Logging LOG = Logging.getLogger(SparseBitVectorLabelParser.class);
-
- /**
- * Constructor.
- *
- * @param colSep Column separator
- * @param quoteChars Quotation character
- * @param comment Comment pattern
- */
- public SparseBitVectorLabelParser(Pattern colSep, String quoteChars, Pattern comment) {
- super(colSep, quoteChars, comment);
- }
-
- @Override
- public MultipleObjectsBundle parse(InputStream in) {
- BufferedReader reader = new BufferedReader(new InputStreamReader(in));
- int lineNumber = 0;
- int dimensionality = -1;
- List<BitVector> vectors = new ArrayList<>();
- List<LabelList> lblc = new ArrayList<>();
- try {
- List<BitSet> bitSets = new ArrayList<>();
- List<LabelList> allLabels = new ArrayList<>();
- ArrayList<String> labels = new ArrayList<>();
- for(String line; (line = reader.readLine()) != null; lineNumber++) {
- // Skip empty lines and comments
- if(line.length() <= 0 || (comment != null && comment.matcher(line).matches())) {
- continue;
- }
- BitSet bitSet = new BitSet();
- labels.clear();
-
- for(tokenizer.initialize(line, 0, lengthWithoutLinefeed(line)); tokenizer.valid(); tokenizer.advance()) {
- try {
- int index = (int) tokenizer.getLongBase10();
- bitSet.set(index);
- dimensionality = Math.max(dimensionality, index);
- }
- catch(NumberFormatException e) {
- labels.add(tokenizer.getSubstring());
- }
- }
-
- bitSets.add(bitSet);
- allLabels.add(LabelList.make(labels));
- }
-
- ++dimensionality;
- for(int i = 0; i < bitSets.size(); i++) {
- vectors.add(new BitVector(bitSets.get(i), dimensionality));
- lblc.add(allLabels.get(i));
- }
- }
- catch(IOException e) {
- throw new IllegalArgumentException("Error while parsing line " + lineNumber + ".");
- }
- return MultipleObjectsBundle.makeSimple(getTypeInformation(dimensionality), vectors, TypeUtil.LABELLIST, lblc);
- }
-
- protected VectorFieldTypeInformation<BitVector> getTypeInformation(int dimensionality) {
- return new VectorFieldTypeInformation<>(BitVector.FACTORY, dimensionality);
- }
-
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer extends AbstractParser.Parameterizer {
- @Override
- protected SparseBitVectorLabelParser makeInstance() {
- return new SparseBitVectorLabelParser(colSep, quoteChars, comment);
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/SparseFloatVectorLabelParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/SparseFloatVectorLabelParser.java
deleted file mode 100644
index 87efbf55..00000000
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/SparseFloatVectorLabelParser.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package de.lmu.ifi.dbs.elki.datasource.parser;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 java.util.regex.Pattern;
-
-import de.lmu.ifi.dbs.elki.data.SparseFloatVector;
-import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
-import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
-
-/**
- * <p>
- * Provides a parser for parsing one point per line, attributes separated by
- * whitespace.
- * </p>
- * <p>
- * Several labels may be given per point. A label must not be parseable as
- * double. Lines starting with &quot;#&quot; will be ignored.
- * </p>
- * <p>
- * A line is expected in the following format: The first entry of each line is
- * the number of attributes with coordinate value not zero. Subsequent entries
- * are of the form <code>index value </code> each, where index is the number of
- * the corresponding dimension, and value is the value of the corresponding
- * attribute. A complet line then could look like this:
- *
- * <pre>
- * 3 7 12.34 8 56.78 11 1.234 objectlabel
- * </pre>
- *
- * where <code>3</code> indicates there are three attributes set,
- * <code>7,8,11</code> are the attributes indexes and there is a non-numerical
- * object label.
- * </p>
- * <p>
- * An index can be specified to identify an entry to be treated as class label.
- * This index counts all entries (numeric and labels as well) starting with 0.
- * </p>
- *
- * @author Arthur Zimek
- *
- * @apiviz.has SparseFloatVector
- *
- * @deprecated Use {@link SparseNumberVectorLabelParser} instead!
- */
-@Title("Sparse Float Vector Label Parser")
-@Description("Parser for the following line format:\n" + "A single line provides a single point. Entries are separated by whitespace. " + "The values will be parsed as floats (resulting in a set of SparseFloatVectors). A line is expected in the following format: The first entry of each line is the number of attributes with coordinate value not zero. Subsequent entries are of the form (index, value), where index is the number of the corresponding dimension, and value is the value of the corresponding attribute." + "Any pair of two subsequent substrings not containing whitespace is tried to be read as int and float. If this fails for the first of the pair (interpreted ans index), it will be appended to a label. (Thus, any label must not be parseable as Integer.) If the float component is not parseable, an exception will be thrown. Empty lines and lines beginning with \"#\" will be ignored.")
-@Deprecated
-public class SparseFloatVectorLabelParser extends SparseNumberVectorLabelParser<SparseFloatVector> {
- /**
- * Constructor.
- *
- * @param colSep Column separator
- * @param quoteChars Quotation character
- * @param comment Comment pattern
- * @param labelIndices Indices to use as labels
- */
- public SparseFloatVectorLabelParser(Pattern colSep, String quoteChars, Pattern comment, BitSet labelIndices) {
- super(colSep, quoteChars, comment, labelIndices, SparseFloatVector.FACTORY);
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer extends SparseNumberVectorLabelParser.Parameterizer<SparseFloatVector> {
- @Override
- protected SparseFloatVectorLabelParser makeInstance() {
- return new SparseFloatVectorLabelParser(colSep, quoteChars, comment, labelIndices);
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/SparseNumberVectorLabelParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/SparseNumberVectorLabelParser.java
index 902d59a9..f9b34c92 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/SparseNumberVectorLabelParser.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/SparseNumberVectorLabelParser.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -44,8 +44,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
* <p>
- * Provides a parser for parsing one point per line, attributes separated by
- * whitespace.
+ * Parser for parsing one point per line, attributes separated by whitespace.
* </p>
* <p>
* Several labels may be given per point. A label must not be parseable as
@@ -56,7 +55,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* the number of attributes with coordinate value not zero. Subsequent entries
* are of the form <code>index value </code> each, where index is the number of
* the corresponding dimension, and value is the value of the corresponding
- * attribute. A complet line then could look like this:
+ * attribute. A complete line then could look like this:
*
* <pre>
* 3 7 12.34 8 56.78 11 1.234 objectlabel
@@ -77,10 +76,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @param <V> vector type
*/
-// FIXME: Maxdim!
@Title("Sparse Vector Label Parser")
@Description("Parser for the following line format:\n" + "A single line provides a single point. Entries are separated by whitespace. " + "The values will be parsed as floats (resulting in a set of SparseFloatVectors). A line is expected in the following format: The first entry of each line is the number of attributes with coordinate value not zero. Subsequent entries are of the form (index, value), where index is the number of the corresponding dimension, and value is the value of the corresponding attribute." + "Any pair of two subsequent substrings not containing whitespace is tried to be read as int and float. If this fails for the first of the pair (interpreted ans index), it will be appended to a label. (Thus, any label must not be parseable as Integer.) If the float component is not parseable, an exception will be thrown. Empty lines and lines beginning with \"#\" will be ignored.")
-public class SparseNumberVectorLabelParser<V extends SparseNumberVector<?>> extends NumberVectorLabelParser<V> {
+public class SparseNumberVectorLabelParser<V extends SparseNumberVector> extends NumberVectorLabelParser<V> {
/**
* Class logger.
*/
@@ -89,7 +87,7 @@ public class SparseNumberVectorLabelParser<V extends SparseNumberVector<?>> exte
/**
* Same as {@link #factory}, but subtype.
*/
- private SparseNumberVector.Factory<V, ?> sparsefactory;
+ protected SparseNumberVector.Factory<V> sparsefactory;
/**
* (Reused) set of values for the number vector.
@@ -110,18 +108,17 @@ public class SparseNumberVectorLabelParser<V extends SparseNumberVector<?>> exte
* @param labelIndices Indices to use as labels
* @param factory Vector factory
*/
- public SparseNumberVectorLabelParser(Pattern colSep, String quoteChars, Pattern comment, BitSet labelIndices, SparseNumberVector.Factory<V, ?> factory) {
+ public SparseNumberVectorLabelParser(Pattern colSep, String quoteChars, Pattern comment, BitSet labelIndices, SparseNumberVector.Factory<V> factory) {
super(colSep, quoteChars, comment, labelIndices, factory);
this.sparsefactory = factory;
}
@Override
- protected void parseLineInternal(String line) {
- tokenizer.initialize(line, 0, lengthWithoutLinefeed(line));
+ protected boolean parseLineInternal() {
+ /* tokenizer initialized by nextLineExceptComments() */
int cardinality = (int) tokenizer.getLongBase10();
+ tokenizer.advance();
- values.clear();
- labels.clear();
int thismax = 0;
while(tokenizer.valid()) {
@@ -130,7 +127,10 @@ public class SparseNumberVectorLabelParser<V extends SparseNumberVector<?>> exte
int index = (int) tokenizer.getLongBase10();
tokenizer.advance();
// Respect labelIndices.
- if(labelIndices == null || !labelIndices.get(index)) {
+ if(!isLabelColumn(index)) {
+ if(!tokenizer.valid()) {
+ throw new AbortException("Parser expected double value, but line ended too early: " + getLineNumber());
+ }
double attribute = tokenizer.getDouble();
thismax = Math.max(thismax, index + 1);
values.put(index, attribute);
@@ -149,6 +149,9 @@ public class SparseNumberVectorLabelParser<V extends SparseNumberVector<?>> exte
}
curvec = sparsefactory.newNumberVector(values, thismax);
curlbl = LabelList.make(labels);
+ values.clear();
+ labels.clear();
+ return true;
}
@Override
@@ -157,7 +160,7 @@ public class SparseNumberVectorLabelParser<V extends SparseNumberVector<?>> exte
return new VectorFieldTypeInformation<>(factory, mindim);
}
else if(mindim < maxdim) {
- return new VectorTypeInformation<>(factory.getRestrictionClass(), factory.getDefaultSerializer(), mindim, maxdim);
+ return new VectorTypeInformation<>(factory, factory.getDefaultSerializer(), mindim, maxdim);
}
throw new AbortException("No vectors were read from the input file - cannot determine vector data type.");
}
@@ -174,10 +177,10 @@ public class SparseNumberVectorLabelParser<V extends SparseNumberVector<?>> exte
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends SparseNumberVector<?>> extends NumberVectorLabelParser.Parameterizer<V> {
+ public static class Parameterizer<V extends SparseNumberVector> extends NumberVectorLabelParser.Parameterizer<V> {
@Override
protected void getFactory(Parameterization config) {
- ObjectParameter<SparseNumberVector.Factory<V, ?>> factoryP = new ObjectParameter<>(VECTOR_TYPE_ID, SparseNumberVector.Factory.class, SparseFloatVector.Factory.class);
+ ObjectParameter<SparseNumberVector.Factory<V>> factoryP = new ObjectParameter<>(VECTOR_TYPE_ID, SparseNumberVector.Factory.class, SparseFloatVector.Factory.class);
if(config.grab(factoryP)) {
factory = factoryP.instantiateClass(config);
}
@@ -185,7 +188,7 @@ public class SparseNumberVectorLabelParser<V extends SparseNumberVector<?>> exte
@Override
protected SparseNumberVectorLabelParser<V> makeInstance() {
- return new SparseNumberVectorLabelParser<>(colSep, quoteChars, comment, labelIndices, (SparseNumberVector.Factory<V, ?>) factory);
+ return new SparseNumberVectorLabelParser<>(colSep, quoteChars, comment, labelIndices, (SparseNumberVector.Factory<V>) factory);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/StreamingParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/StreamingParser.java
index 73d38e3c..23326a32 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/StreamingParser.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/StreamingParser.java
@@ -1,14 +1,10 @@
package de.lmu.ifi.dbs.elki.datasource.parser;
-import java.io.InputStream;
-
-import de.lmu.ifi.dbs.elki.datasource.bundle.BundleStreamSource;
-
/*
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,6 +23,10 @@ import de.lmu.ifi.dbs.elki.datasource.bundle.BundleStreamSource;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.io.InputStream;
+
+import de.lmu.ifi.dbs.elki.datasource.bundle.BundleStreamSource;
+
/**
* Interface for streaming parsers, that may be much more efficient in
* combination with filters.
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/StringParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/StringParser.java
index 6541b881..6e5773ee 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/StringParser.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/StringParser.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
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,6 +29,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.lmu.ifi.dbs.elki.data.LabelList;
@@ -57,7 +58,7 @@ public class StringParser implements Parser {
/**
* Comment pattern.
*/
- Pattern comment;
+ Matcher comment;
/**
* Flag to trim whitespace.
@@ -72,7 +73,7 @@ public class StringParser implements Parser {
*/
public StringParser(Pattern comment, boolean trimWhitespace) {
super();
- this.comment = comment;
+ this.comment = (comment != null) ? comment.matcher("") : null;
this.trimWhitespace = trimWhitespace;
}
@@ -84,9 +85,9 @@ public class StringParser implements Parser {
List<LabelList> labels = new ArrayList<>();
ArrayList<String> ll = new ArrayList<>(1);
try {
- for (String line; (line = reader.readLine()) != null; lineNumber++) {
+ for(String line; (line = reader.readLine()) != null; lineNumber++) {
// Skip empty lines and comments
- if (line.length() <= 0 || (comment != null && comment.matcher(line).matches())) {
+ if(line.length() <= 0 || (comment != null && comment.reset(line).matches())) {
continue;
}
final String val = trimWhitespace ? line.trim() : line;
@@ -95,12 +96,18 @@ public class StringParser implements Parser {
ll.add(val);
labels.add(LabelList.make(ll));
}
- } catch (IOException e) {
+ }
+ catch(IOException e) {
throw new IllegalArgumentException("Error while parsing line " + lineNumber + ".");
}
return MultipleObjectsBundle.makeSimple(TypeUtil.STRING, data, TypeUtil.LABELLIST, labels);
}
+ @Override
+ public void cleanup() {
+ comment.reset("");
+ }
+
/**
* Parameterization class.
*
@@ -129,12 +136,12 @@ public class StringParser implements Parser {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
PatternParameter commentP = new PatternParameter(AbstractParser.Parameterizer.COMMENT_ID, "^\\s*#.*$");
- if (config.grab(commentP)) {
+ if(config.grab(commentP)) {
comment = commentP.getValue();
}
Flag trimP = new Flag(TRIM_ID);
- if (config.grab(trimP)) {
+ if(config.grab(trimP)) {
trimWhitespace = trimP.isTrue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/TermFrequencyParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/TermFrequencyParser.java
index f0ccbf50..c750b687 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/TermFrequencyParser.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/TermFrequencyParser.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.parser;
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
@@ -51,13 +51,16 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* A parser to load term frequency data, which essentially are sparse vectors
* with text keys.
*
+ * If your data does not contain frequencies, you can maybe use
+ * {@link SimpleTransactionParser} instead.
+ *
* @author Erich Schubert
*
- * @apiviz.has SparseFloatVector
+ * @apiviz.has SparseNumberVector
*/
@Title("Term frequency parser")
@Description("Parse a file containing term frequencies. The expected format is 'label term1 <freq> term2 <freq> ...'. Terms must not contain the separator character!")
-public class TermFrequencyParser<V extends SparseNumberVector<?>> extends NumberVectorLabelParser<V> {
+public class TermFrequencyParser<V extends SparseNumberVector> extends NumberVectorLabelParser<V> {
/**
* Class logger.
*/
@@ -81,7 +84,7 @@ public class TermFrequencyParser<V extends SparseNumberVector<?>> extends Number
/**
* Same as {@link #factory}, but subtype.
*/
- private SparseNumberVector.Factory<V, ?> sparsefactory;
+ private SparseNumberVector.Factory<V> sparsefactory;
/**
* (Reused) set of values for the number vector.
@@ -92,7 +95,7 @@ public class TermFrequencyParser<V extends SparseNumberVector<?>> extends Number
* (Reused) label buffer.
*/
ArrayList<String> labels = new ArrayList<>();
-
+
/**
* Constructor.
*
@@ -102,7 +105,7 @@ public class TermFrequencyParser<V extends SparseNumberVector<?>> extends Number
* @param comment Comment pattern
* @param labelIndices Indices to use as labels
*/
- public TermFrequencyParser(boolean normalize, Pattern colSep, String quoteChars, Pattern comment, BitSet labelIndices, SparseNumberVector.Factory<V, ?> factory) {
+ public TermFrequencyParser(boolean normalize, Pattern colSep, String quoteChars, Pattern comment, BitSet labelIndices, SparseNumberVector.Factory<V> factory) {
super(colSep, quoteChars, comment, labelIndices, factory);
this.normalize = normalize;
this.keymap = new TObjectIntHashMap<>(1001, .5f, -1);
@@ -110,42 +113,40 @@ public class TermFrequencyParser<V extends SparseNumberVector<?>> extends Number
}
@Override
- protected void parseLineInternal(String line) {
+ protected boolean parseLineInternal() {
double len = 0;
- values.clear();
- labels.clear();
String curterm = null;
- for(tokenizer.initialize(line, 0, lengthWithoutLinefeed(line)); tokenizer.valid(); tokenizer.advance()) {
+ for(/* initialized by nextLineExceptComments() */; tokenizer.valid(); tokenizer.advance()) {
if(curterm == null) {
curterm = tokenizer.getSubstring();
+ continue;
}
- else {
- try {
- double attribute = tokenizer.getDouble();
- int curdim = keymap.get(curterm);
- if(curdim < 0) {
- curdim = numterms;
- keymap.put(curterm, curdim);
- ++numterms;
- }
- values.put(curdim, attribute);
- len += attribute;
- curterm = null;
+ try {
+ double attribute = tokenizer.getDouble();
+ int curdim = keymap.get(curterm);
+ if(curdim < 0) {
+ curdim = numterms;
+ keymap.put(curterm, curdim);
+ ++numterms;
}
- catch(NumberFormatException e) {
- if(curterm != null) {
- labels.add(curterm);
- }
- curterm = tokenizer.getSubstring();
+ values.put(curdim, attribute);
+ len += attribute;
+ curterm = null;
+ }
+ catch(NumberFormatException e) {
+ if(curterm != null) {
+ labels.add(curterm);
}
+ curterm = tokenizer.getSubstring();
}
}
if(curterm != null) {
labels.add(curterm);
}
+ haslabels |= (labels.size() > 0);
if(normalize) {
- if(Math.abs(len - 1.0) > 1E-10 && len > 1E-10) {
+ if(Math.abs(len - 1.0) > Double.MIN_NORMAL) {
for(TIntDoubleIterator iter = values.iterator(); iter.hasNext();) {
iter.advance();
iter.setValue(iter.value() / len);
@@ -155,6 +156,9 @@ public class TermFrequencyParser<V extends SparseNumberVector<?>> extends Number
curvec = sparsefactory.newNumberVector(values, numterms);
curlbl = LabelList.make(labels);
+ values.clear();
+ labels.clear();
+ return true;
}
@Override
@@ -163,7 +167,7 @@ public class TermFrequencyParser<V extends SparseNumberVector<?>> extends Number
return new VectorFieldTypeInformation<>(factory, mindim);
}
else if(mindim < maxdim) {
- return new VectorTypeInformation<>(factory.getRestrictionClass(), factory.getDefaultSerializer(), mindim, maxdim);
+ return new VectorTypeInformation<>(factory, factory.getDefaultSerializer(), mindim, maxdim);
}
throw new AbortException("No vectors were read from the input file - cannot determine vector data type.");
}
@@ -180,7 +184,7 @@ public class TermFrequencyParser<V extends SparseNumberVector<?>> extends Number
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends SparseNumberVector<?>> extends NumberVectorLabelParser.Parameterizer<V> {
+ public static class Parameterizer<V extends SparseNumberVector> extends NumberVectorLabelParser.Parameterizer<V> {
/**
* Option ID for normalization.
*/
@@ -196,13 +200,13 @@ public class TermFrequencyParser<V extends SparseNumberVector<?>> extends Number
super.makeOptions(config);
Flag normF = new Flag(NORMALIZE_FLAG);
if(config.grab(normF)) {
- normalize = normF.getValue().booleanValue();
+ normalize = normF.isTrue();
}
}
@Override
protected void getFactory(Parameterization config) {
- ObjectParameter<SparseNumberVector.Factory<V, ?>> factoryP = new ObjectParameter<>(VECTOR_TYPE_ID, SparseNumberVector.Factory.class, SparseFloatVector.Factory.class);
+ ObjectParameter<SparseNumberVector.Factory<V>> factoryP = new ObjectParameter<>(VECTOR_TYPE_ID, SparseNumberVector.Factory.class, SparseFloatVector.Factory.class);
if(config.grab(factoryP)) {
factory = factoryP.instantiateClass(config);
}
@@ -210,7 +214,7 @@ public class TermFrequencyParser<V extends SparseNumberVector<?>> extends Number
@Override
protected TermFrequencyParser<V> makeInstance() {
- return new TermFrequencyParser<>(normalize, colSep, quoteChars, comment, labelIndices, (SparseNumberVector.Factory<V, ?>) factory);
+ return new TermFrequencyParser<>(normalize, colSep, quoteChars, comment, labelIndices, (SparseNumberVector.Factory<V>) factory);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/package-info.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/package-info.java
index c21ab31f..fab27a6a 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/package-info.java
@@ -12,14 +12,14 @@
* any {@link de.lmu.ifi.dbs.elki.KDDTask} will
* use the {@link de.lmu.ifi.dbs.elki.database.StaticArrayDatabase} which,
* in turn, will use a {@link de.lmu.ifi.dbs.elki.datasource.FileBasedDatabaseConnection}
- * and a {@link de.lmu.ifi.dbs.elki.datasource.parser.DoubleVectorLabelParser}
+ * and a {@link de.lmu.ifi.dbs.elki.datasource.parser.NumberVectorLabelParser}
* to parse a specified data file creating
* a {@link de.lmu.ifi.dbs.elki.database.StaticArrayDatabase}
* containing {@link de.lmu.ifi.dbs.elki.data.DoubleVector}-Objects.</p>
*
* <p>Thus, the standard procedure to use a data set of a real-valued vector space
* is to prepare the data set in a file of the following format
- * (as suitable to {@link de.lmu.ifi.dbs.elki.datasource.parser.DoubleVectorLabelParser}):
+ * (as suitable to {@link de.lmu.ifi.dbs.elki.datasource.parser.NumberVectorLabelParser}):
* <ul>
* <li>One point per line, attributes separated by whitespace.</li>
* <li>Several labels may be given per point. A label must not be parseable as double.</li>
@@ -42,7 +42,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/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/WeightedNumberVectorDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedNumberVectorDistanceFunction.java
new file mode 100644
index 00000000..a3824a1a
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/WeightedNumberVectorDistanceFunction.java
@@ -0,0 +1,40 @@
+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) 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.utilities.optionhandling.OptionID;
+
+/**
+ * Distance functions where each dimension is assigned a weight.
+ *
+ * @author Erich Schubert
+ *
+ * @param <V> Vector type, usually NumberVector or above.
+ */
+public interface WeightedNumberVectorDistanceFunction<V> extends NumberVectorDistanceFunction<V> {
+ /**
+ * Parameter to set the weights of the weighted distance function.
+ */
+ 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/distancefunction/external/DistanceCacheWriter.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceCacheWriter.java
new file mode 100644
index 00000000..3457d335
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/DistanceCacheWriter.java
@@ -0,0 +1,51 @@
+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/>.
+ */
+
+/**
+ * Interface to plug in the cache storage into the parser.
+ *
+ * @author Erich Schubert
+ */
+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);
+
+ /**
+ * Returns <tt>true</tt> if the specified distance cache contains a distance
+ * value for the specified ids.
+ *
+ * @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
+ */
+ 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/distancefunction/set/package-info.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/package-info.java
new file mode 100644
index 00000000..ddc606f4
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/set/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * 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) 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.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
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/AutomaticEvaluation.java b/src/de/lmu/ifi/dbs/elki/evaluation/AutomaticEvaluation.java
index fe2e1dc5..91202efe 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/AutomaticEvaluation.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/AutomaticEvaluation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation;
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
@@ -36,6 +36,7 @@ import de.lmu.ifi.dbs.elki.evaluation.histogram.ComputeOutlierHistogram;
import de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierPrecisionAtKCurve;
import de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierPrecisionRecallCurve;
import de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierROCCurve;
+import de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierRankingEvaluation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
@@ -73,13 +74,13 @@ public class AutomaticEvaluation implements Evaluator {
protected void autoEvaluateOutliers(HierarchicalResult baseResult, Result newResult) {
Collection<OutlierResult> outliers = ResultUtil.filterResults(newResult, OutlierResult.class);
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
LOG.debug("Number of new outlier results: " + outliers.size());
}
- if (outliers.size() > 0) {
+ if(outliers.size() > 0) {
ResultUtil.ensureClusteringResult(ResultUtil.findDatabase(baseResult), baseResult);
Collection<Clustering<?>> clusterings = ResultUtil.filterResults(baseResult, Clustering.class);
- if (clusterings.size() == 0) {
+ if(clusterings.size() == 0) {
LOG.warning("Could not find a clustering result, even after running 'ensureClusteringResult'?!?");
return;
}
@@ -88,28 +89,30 @@ public class AutomaticEvaluation implements Evaluator {
int min = Integer.MAX_VALUE;
int total = 0;
String label = null;
- if (basec.getAllClusters().size() > 1) {
- for (Cluster<?> c : basec.getAllClusters()) {
+ if(basec.getAllClusters().size() > 1) {
+ for(Cluster<?> c : basec.getAllClusters()) {
final int csize = c.getIDs().size();
total += csize;
- if (csize < min) {
+ if(csize < min) {
min = csize;
label = c.getName();
}
}
}
- if (label == null) {
+ if(label == null) {
LOG.warning("Could not evaluate outlier results, as I could not find a minority label.");
return;
}
- if (min == 1) {
+ if(min == 1) {
LOG.warning("The minority class label had a single object. Try using 'ClassLabelFilter' to identify the class label column.");
}
- if (min > 0.05 * total) {
+ if(min > 0.05 * total) {
LOG.warning("The minority class I discovered (labeled '" + label + "') has " + (min * 100. / total) + "% of objects. Outlier classes should be more rare!");
}
LOG.verbose("Evaluating using minority class: " + label);
Pattern pat = Pattern.compile("^" + Pattern.quote(label) + "$");
+ // Evaluate rankings.
+ new OutlierRankingEvaluation(pat).processNewResult(baseResult, newResult);
// Compute ROC curve
new OutlierROCCurve(pat).processNewResult(baseResult, newResult);
// Compute Precision at k
@@ -123,25 +126,29 @@ public class AutomaticEvaluation implements Evaluator {
protected void autoEvaluateClusterings(HierarchicalResult baseResult, Result newResult) {
Collection<Clustering<?>> clusterings = ResultUtil.filterResults(newResult, Clustering.class);
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
LOG.warning("Number of new clustering results: " + clusterings.size());
}
- for (Iterator<Clustering<?>> c = clusterings.iterator(); c.hasNext();) {
+ for(Iterator<Clustering<?>> c = clusterings.iterator(); c.hasNext();) {
Clustering<?> test = c.next();
- if ("allinone-clustering".equals(test.getShortName())) {
+ if("allinone-clustering".equals(test.getShortName())) {
c.remove();
- } else if ("allinnoise-clustering".equals(test.getShortName())) {
+ }
+ else if("allinnoise-clustering".equals(test.getShortName())) {
c.remove();
- } else if ("bylabel-clustering".equals(test.getShortName())) {
+ }
+ else if("bylabel-clustering".equals(test.getShortName())) {
c.remove();
- } else if ("bymodel-clustering".equals(test.getShortName())) {
+ }
+ else if("bymodel-clustering".equals(test.getShortName())) {
c.remove();
}
}
- if (clusterings.size() > 0) {
+ if(clusterings.size() > 0) {
try {
new EvaluateClustering(new ByLabelClustering(), false, true).processNewResult(baseResult, newResult);
- } catch (NoSupportedDataTypeException e) {
+ }
+ catch(NoSupportedDataTypeException e) {
// Pass - the data probably did not have labels.
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/Evaluator.java b/src/de/lmu/ifi/dbs/elki/evaluation/Evaluator.java
index 140b29ef..b060af13 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/Evaluator.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/Evaluator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation;
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/evaluation/NoAutomaticEvaluation.java b/src/de/lmu/ifi/dbs/elki/evaluation/NoAutomaticEvaluation.java
index 640a8c9d..7d7b4bed 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/NoAutomaticEvaluation.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/NoAutomaticEvaluation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation;
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/evaluation/classification/ConfusionMatrix.java b/src/de/lmu/ifi/dbs/elki/evaluation/classification/ConfusionMatrix.java
new file mode 100644
index 00000000..e7b4cd4f
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/classification/ConfusionMatrix.java
@@ -0,0 +1,359 @@
+package de.lmu.ifi.dbs.elki.evaluation.classification;
+/*
+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.text.NumberFormat;
+import java.util.ArrayList;
+
+import de.lmu.ifi.dbs.elki.data.ClassLabel;
+
+/**
+ * Provides a confusion matrix with some prediction performance measures that
+ * can be derived from a confusion matrix.
+ *
+ * @author Arthur Zimek
+ */
+public class ConfusionMatrix {
+ /**
+ * Holds the confusion matrix. Must be a square matrix. The rows (first index)
+ * give the values which classes are classified as row, the columns (second
+ * index) give the values the class col has been classified as. Thus,
+ * <code>confusion[predicted][real]</code> addresses the number of instances
+ * of class <i>real</i> that have been assigned to the class <i>predicted</i>.
+ */
+ private int[][] confusion;
+
+ /**
+ * Holds the class labels.
+ */
+ private ArrayList<ClassLabel> labels;
+
+ /**
+ * Provides a confusion matrix for the given values.
+ *
+ * @param labels the class labels - must conform the confusion matrix in
+ * length
+ * @param confusion the confusion matrix. Must be a square matrix. The rows
+ * (first index) give the values which classes are classified as row,
+ * the columns (second index) give the values the class col has been
+ * classified as. Thus, <code>confusion[predicted][real]</code>
+ * addresses the number of instances of class <i>real</i> that have
+ * been assigned to the class <i>predicted</i>.
+ * @throws IllegalArgumentException if the confusion matrix is not square or
+ * not complete or if the length of class labels does not conform the
+ * length of the confusion matrix
+ */
+ public ConfusionMatrix(ArrayList<ClassLabel> labels, int[][] confusion) throws IllegalArgumentException {
+ for(int i = 0; i < confusion.length; i++) {
+ if(confusion.length != confusion[i].length) {
+ throw new IllegalArgumentException("Confusion matrix irregular: row-dimension = " + confusion.length + ", col-dimension in col" + i + " = " + confusion[i].length);
+ }
+ }
+ if(confusion.length != labels.size()) {
+ throw new IllegalArgumentException("Number of class labels does not match row dimension of confusion matrix.");
+ }
+ this.confusion = confusion;
+ this.labels = labels;
+ }
+
+ /**
+ * Provides the <i>true positive rate</i>. Aka <i>accuracy</i> or
+ * <i>sensitivity</i> or <i>recall</i>: <code>TP / (TP+FN)</code>.
+ *
+ *
+ * @return the true positive rate
+ */
+ public double truePositiveRate() {
+ return ((double) truePositives()) / (double) totalInstances();
+ }
+
+ /**
+ * Provides the <i>false positive rate</i> for the specified class.
+ *
+ *
+ * @param classindex the index of the class to retrieve the false positive
+ * rate for
+ * @return the false positive rate for the specified class
+ */
+ public double falsePositiveRate(int classindex) {
+ int fp = falsePositives(classindex);
+ int tn = trueNegatives(classindex);
+ return ((double) fp) / ((double) (fp + tn));
+ }
+
+ /**
+ * Provides the <i>false positive rate</i>. Aka <i>false alarm rate</i>:
+ * <code>FP / (FP+TN)</code>.
+ *
+ *
+ * @return the false positive rate
+ */
+ public double falsePositiveRate() {
+ double fpr = 0;
+ for(int i = 0; i < confusion.length; i++) {
+ fpr += falsePositiveRate(i) * colSum(i);
+ }
+ return fpr / totalInstances();
+ }
+
+ /**
+ * Provides the <i>positive predicted value</i> for the specified class.
+ *
+ *
+ * @param classindex the index of the class to retrieve the positive predicted
+ * value for
+ * @return the positive predicted value for the specified class
+ */
+ public double positivePredictedValue(int classindex) {
+ int tp = truePositives(classindex);
+ return (double) tp / ((double) (tp + falsePositives(classindex)));
+ }
+
+ /**
+ * Provides the <i>positive predicted value</i>. Aka <i>precision</i> or
+ * <i>specificity</i>: <code>TP / (TP+FP)</code>.
+ *
+ * @return the positive predicted value
+ */
+ public double positivePredictedValue() {
+ double ppv = 0;
+ for(int i = 0; i < confusion.length; i++) {
+ ppv += positivePredictedValue(i) * colSum(i);
+ }
+ return ppv / totalInstances();
+ }
+
+ /**
+ * The number of correctly classified instances.
+ *
+ *
+ * @return the number of correctly classified instances
+ */
+ public int truePositives() {
+ int tp = 0;
+ for(int i = 0; i < confusion.length; i++) {
+ tp += truePositives(i);
+ }
+ return tp;
+ }
+
+ /**
+ * The number of correctly classified instances belonging to the specified
+ * class.
+ *
+ *
+ * @param classindex the index of the class to retrieve the correctly
+ * classified instances of
+ * @return the number of correctly classified instances belonging to the
+ * specified class
+ */
+ public int truePositives(int classindex) {
+ return confusion[classindex][classindex];
+ }
+
+ /**
+ * Provides the <i>true positive rate</i> for the specified class.
+ *
+ * @param classindex the index of the class to retrieve the true positive rate
+ * for
+ * @return the true positive rate
+ */
+ public double truePositiveRate(int classindex) {
+ int tp = truePositives(classindex);
+ return (double) tp / ((double) (tp + falseNegatives(classindex)));
+ }
+
+ /**
+ * The number of true negatives of the specified class.
+ *
+ *
+ * @param classindex the index of the class to retrieve the true negatives for
+ * @return the number of true negatives of the specified class
+ */
+ public int trueNegatives(int classindex) {
+ int tn = 0;
+ for(int i = 0; i < confusion.length; i++) {
+ for(int j = 0; j < confusion[i].length; j++) {
+ if(i != classindex && j != classindex) {
+ tn += confusion[i][j];
+ }
+ }
+ }
+ return tn;
+ }
+
+ /**
+ * The false positives for the specified class.
+ *
+ *
+ * @param classindex the index of the class to retrieve the false positives
+ * for
+ * @return the false positives for the specified class
+ */
+ public int falsePositives(int classindex) {
+ int fp = 0;
+ for(int i = 0; i < confusion[classindex].length; i++) {
+ if(i != classindex) {
+ fp += confusion[classindex][i];
+ }
+ }
+ return fp;
+ }
+
+ /**
+ * The false negatives for the specified class.
+ *
+ *
+ * @param classindex the index of the class to retrieve the false negatives
+ * for
+ * @return the false negatives for the specified class
+ */
+ public int falseNegatives(int classindex) {
+ int fn = 0;
+ for(int i = 0; i < confusion.length; i++) {
+ if(i != classindex) {
+ fn += confusion[i][classindex];
+ }
+ }
+ return fn;
+ }
+
+ /**
+ * The total number of instances covered by this confusion matrix.
+ *
+ *
+ * @return the total number of instances covered by this confusion matrix
+ */
+ public int totalInstances() {
+ int total = 0;
+ for(int i = 0; i < confusion.length; i++) {
+ for(int j = 0; j < confusion[i].length; j++) {
+ total += confusion[i][j];
+ }
+ }
+ return total;
+ }
+
+ /**
+ * The number of instances present in the specified row. I.e., classified as
+ * class <code>classindex</code>.
+ *
+ *
+ * @param classindex the index of the class the resulting number of instances
+ * has been classified as
+ * @return the number of instances present in the specified row
+ */
+ public int rowSum(int classindex) {
+ int s = 0;
+ for(int i = 0; i < confusion[classindex].length; i++) {
+ s += confusion[classindex][i];
+ }
+ return s;
+ }
+
+ /**
+ * The number of instances present in the specified column. I.e., the
+ * instances of class <code>classindex</code>.
+ *
+ *
+ * @param classindex the index of the class theresulting number of instances
+ * belongs to
+ * @return the number of instances present in the specified column
+ */
+ public int colSum(int classindex) {
+ int s = 0;
+ for(int i = 0; i < confusion.length; i++) {
+ s += confusion[i][classindex];
+ }
+ return s;
+ }
+
+ /**
+ * The number of instances belonging to class <code>trueClassindex</code> and
+ * predicted as <code>predictedClassindex</code>.
+ *
+ *
+ * @param trueClassindex the true class index
+ * @param predictedClassindex the predicted class index
+ * @return the number of instances belonging to class
+ * <code>trueClassindex</code> and predicted as
+ * <code>predictedClassindex</code>
+ */
+ public int value(int trueClassindex, int predictedClassindex) {
+ return confusion[predictedClassindex][trueClassindex];
+ }
+
+ /**
+ * Provides a String representation of this confusion matrix.
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ int max = 0;
+ for(int i = 0; i < confusion.length; i++) {
+ for(int j = 0; j < confusion[i].length; j++) {
+ if(confusion[i][j] > max) {
+ max = confusion[i][j];
+ }
+ }
+ }
+ String classPrefix = "C_";
+ NumberFormat nf = NumberFormat.getInstance();
+ nf.setParseIntegerOnly(true);
+ int labelLength = Integer.toString(labels.size()).length();
+ nf.setMaximumIntegerDigits(labelLength);
+ nf.setMinimumIntegerDigits(labelLength);
+ int cell = Math.max(Integer.toString(max).length(), labelLength + classPrefix.length());
+ String separator = " ";
+ StringBuilder representation = new StringBuilder();
+ for(int i = 1; i <= labels.size(); i++) {
+ representation.append(separator);
+ String label = classPrefix + nf.format(i);
+ int space = cell - labelLength - classPrefix.length();
+ for(int s = 0; s <= space; s++) {
+ representation.append(' ');
+ }
+ representation.append(label);
+ }
+ representation.append('\n');
+ for(int row = 0; row < confusion.length; row++) {
+ for(int col = 0; col < confusion[row].length; col++) {
+ representation.append(separator);
+ String entry = Integer.toString(confusion[row][col]);
+ int space = cell - entry.length();
+ for(int s = 0; s <= space; s++) {
+ representation.append(' ');
+ }
+ representation.append(entry);
+ }
+ representation.append(separator);
+ representation.append(classPrefix);
+ representation.append(nf.format(row + 1));
+ representation.append(": ");
+ representation.append(labels.get(row));
+ representation.append('\n');
+ }
+ return representation.toString();
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/classification/ConfusionMatrixEvaluationResult.java b/src/de/lmu/ifi/dbs/elki/evaluation/classification/ConfusionMatrixEvaluationResult.java
new file mode 100644
index 00000000..6bf0f648
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/classification/ConfusionMatrixEvaluationResult.java
@@ -0,0 +1,92 @@
+package de.lmu.ifi.dbs.elki.evaluation.classification;
+
+/*
+ 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.result.Result;
+import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable;
+import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
+
+/**
+ * Provides the prediction performance measures for a classifier based on the
+ * confusion matrix.
+ *
+ * Note: this API is non-final, and will be refactored soon.
+ *
+ * @author Arthur Zimek
+ */
+public class ConfusionMatrixEvaluationResult implements Result, TextWriteable {
+ /**
+ * Holds the confusion matrix.
+ */
+ private ConfusionMatrix confusionmatrix;
+
+ /**
+ * Holds the used EvaluationProcedure.
+ */
+ private String evaluationName;
+
+ /**
+ * Provides an evaluation based on the given confusion matrix.
+ *
+ * @param confusionmatrix the confusion matrix to provide the prediction
+ * performance measures for
+ * @param evaluationName name of the evaluation procedure used
+ */
+ public ConfusionMatrixEvaluationResult(ConfusionMatrix confusionmatrix, String evaluationName) {
+ super();
+ this.confusionmatrix = confusionmatrix;
+ this.evaluationName = evaluationName;
+ }
+
+ @Override
+ public void writeToText(TextWriterStream out, String label) {
+ out.commentPrintLn("Evaluation:");
+ out.commentPrintLn(evaluationName);
+ // out.println(evaluationProcedure.setting());
+ out.commentPrintLn("Accuracy: \n correctly classified instances: ");
+ out.commentPrintLn(confusionmatrix.truePositives());
+ out.commentPrintLn("true positive rate: ");
+ double tpr = confusionmatrix.truePositiveRate();
+ out.commentPrintLn(tpr);
+ out.commentPrintLn("false positive rate: ");
+ out.commentPrintLn(confusionmatrix.falsePositiveRate());
+ out.commentPrintLn("positive predicted value: ");
+ double ppv = confusionmatrix.positivePredictedValue();
+ out.commentPrintLn(ppv);
+ out.commentPrintLn("F1-measure: ");
+ out.commentPrintLn((2 * ppv * tpr) / (ppv + tpr));
+ out.commentPrintLn("\nconfusion matrix:\n");
+ out.commentPrintLn(confusionmatrix.toString());
+ }
+
+ @Override
+ public String getLongName() {
+ return "confusionmatrixresult";
+ }
+
+ @Override
+ public String getShortName() {
+ return "confusionmatrixresult";
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/AbstractHoldout.java b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/AbstractHoldout.java
new file mode 100644
index 00000000..af10eac0
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/AbstractHoldout.java
@@ -0,0 +1,118 @@
+package de.lmu.ifi.dbs.elki.evaluation.classification.holdout;
+
+/*
+ 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.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+
+import de.lmu.ifi.dbs.elki.data.ClassLabel;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+
+/**
+ * Split a data set for holdout evaluation.
+ *
+ * @author Erich Schubert
+ */
+public abstract class AbstractHoldout implements Holdout {
+ /**
+ * Labels in the current data set.
+ */
+ protected ArrayList<ClassLabel> labels;
+
+ /**
+ * Column containing the class labels.
+ */
+ protected int labelcol;
+
+ /**
+ * Input data bundle.
+ */
+ protected MultipleObjectsBundle bundle;
+
+ @Override
+ public void initialize(MultipleObjectsBundle bundle) {
+ this.bundle = bundle;
+ this.labelcol = findClassLabelColumn(bundle);
+ this.labels = allClassLabels(bundle);
+ }
+
+ @Override
+ public ArrayList<ClassLabel> getLabels() {
+ return labels;
+ }
+
+ /**
+ * Find the class label column in the given data set.
+ *
+ * @param bundle Bundle
+ * @return Class label column
+ */
+ public static int findClassLabelColumn(MultipleObjectsBundle bundle) {
+ for(int i = 0, l = bundle.metaLength(); i < l; ++i) {
+ if(TypeUtil.CLASSLABEL.isAssignableFromType(bundle.meta(i))) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Get an array of all class labels in a given data set.
+ *
+ * @param bundle Bundle
+ * @return Class labels.
+ */
+ public static ArrayList<ClassLabel> allClassLabels(MultipleObjectsBundle bundle) {
+ int col = findClassLabelColumn(bundle);
+ // TODO: automatically infer class labels?
+ if(col < 0) {
+ throw new AbortException("No class label found (try using ClassLabelFilter).");
+ }
+ return allClassLabels(bundle, col);
+ }
+
+ /**
+ * Get an array of all class labels in a given data set.
+ *
+ * @param bundle Bundle
+ * @param col Column
+ * @return Class labels.
+ */
+ public static ArrayList<ClassLabel> allClassLabels(MultipleObjectsBundle bundle, int col) {
+ HashSet<ClassLabel> labels = new HashSet<ClassLabel>();
+ for(int i = 0, l = bundle.dataLength(); i < l; ++i) {
+ Object o = bundle.data(i, col);
+ if(o == null || !(o instanceof ClassLabel)) {
+ continue;
+ }
+ labels.add((ClassLabel) o);
+ }
+ ArrayList<ClassLabel> ret = new ArrayList<>(labels);
+ Collections.sort(ret);
+ return ret;
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/DisjointCrossValidation.java b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/DisjointCrossValidation.java
new file mode 100644
index 00000000..75503018
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/DisjointCrossValidation.java
@@ -0,0 +1,144 @@
+package de.lmu.ifi.dbs.elki.evaluation.classification.holdout;
+
+/*
+ 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.ArrayList;
+import java.util.Random;
+
+import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+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;
+
+/**
+ * DisjointCrossValidationHoldout provides a set of partitions of a database to
+ * perform cross-validation. The test sets are guaranteed to be disjoint.
+ *
+ * @author Arthur Zimek
+ */
+public class DisjointCrossValidation extends RandomizedHoldout {
+ /**
+ * Holds the number of folds, current fold.
+ */
+ protected int nfold, fold;
+
+ /**
+ * Partition assignment and size.
+ */
+ protected int[] assignment, sizes;
+
+ /**
+ * Constructor.
+ *
+ * @param random Random seeding
+ * @param nfold Number of folds.
+ */
+ public DisjointCrossValidation(RandomFactory random, int nfold) {
+ super(random);
+ this.nfold = nfold;
+ }
+
+ @Override
+ public void initialize(MultipleObjectsBundle bundle) {
+ super.initialize(bundle);
+ fold = 0;
+
+ Random rnd = random.getSingleThreadedRandom();
+ sizes = new int[nfold];
+ assignment = new int[bundle.dataLength()];
+ for(int i = 0; i < assignment.length; ++i) {
+ int p = rnd.nextInt(nfold);
+ assignment[i] = p;
+ ++sizes[p];
+ }
+ }
+
+ @Override
+ public int numberOfPartitions() {
+ return nfold;
+ }
+
+ @Override
+ public TrainingAndTestSet nextPartitioning() {
+ if(fold >= nfold) {
+ return null;
+ }
+ final int tesize = sizes[fold], trsize = bundle.dataLength() - tesize;
+ MultipleObjectsBundle training = new MultipleObjectsBundle();
+ MultipleObjectsBundle test = new MultipleObjectsBundle();
+ // Process column-wise.
+ for(int c = 0, cs = bundle.metaLength(); c < cs; ++c) {
+ ArrayList<Object> tr = new ArrayList<>(trsize), te = new ArrayList<>(tesize);
+ for(int i = 0; i < bundle.dataLength(); ++i) {
+ ((assignment[i] != fold) ? tr : te).add(bundle.data(i, c));
+ }
+ training.appendColumn(bundle.meta(c), tr);
+ test.appendColumn(bundle.meta(c), te);
+ }
+
+ ++fold;
+ return new TrainingAndTestSet(training, test, labels);
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends RandomizedHoldout.Parameterizer {
+ /**
+ * Default number of folds.
+ */
+ public static final int N_DEFAULT = 10;
+
+ /**
+ * Parameter for number of folds.
+ */
+ public static final OptionID NFOLD_ID = new OptionID("nfold", "Number of folds for cross-validation.");
+
+ /**
+ * Holds the number of folds.
+ */
+ protected int nfold = N_DEFAULT;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ IntParameter nfoldP = new IntParameter(NFOLD_ID, N_DEFAULT)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(nfoldP)) {
+ nfold = nfoldP.intValue();
+ }
+ }
+
+ @Override
+ protected DisjointCrossValidation makeInstance() {
+ return new DisjointCrossValidation(random, nfold);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/ModifiableDoubleDistanceDBIDList.java b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/Holdout.java
index 4b29e3b6..17cd56ac 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/ModifiableDoubleDistanceDBIDList.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/Holdout.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.database.ids.distance;
+package de.lmu.ifi.dbs.elki.evaluation.classification.holdout;
/*
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,46 +23,45 @@ package de.lmu.ifi.dbs.elki.database.ids.distance;
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.ids.distance.DoubleDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import java.util.ArrayList;
+
+import de.lmu.ifi.dbs.elki.data.ClassLabel;
+import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
/**
- * An object containing Double-DBID-Pairs.
+ * A holdout procedure is to provide a range of partitions of a database to
+ * pairs of training and test data sets.
*
* @author Erich Schubert
*/
-public interface ModifiableDoubleDistanceDBIDList extends DoubleDistanceDBIDList, ModifiableDistanceDBIDList<DoubleDistance> {
+public interface Holdout {
/**
- * Add an element.
- *
- * @deprecated Pass a double value instead.
+ * Initialize the holdout procedure for a data set.
*
- * @param dist Distance
- * @param id ID
+ * @param bundle Data set bundle
*/
- @Override
- @Deprecated
- void add(DoubleDistance dist, DBIDRef id);
+ void initialize(MultipleObjectsBundle bundle);
/**
- * Add an element.
+ * Get the next partitioning of the given holdout.
*
- * @param dist Distance
- * @param id ID
+ * @return Next partitioning of the data set
*/
- void add(double dist, DBIDRef id);
+ TrainingAndTestSet nextPartitioning();
/**
- * Add an element.
+ * Get the <i>sorted</i> class labels present in this data set.
*
- * @param pair Pair to add
+ * For indexing into assignment arrays.
+ *
+ * @return Class labels
*/
- void add(DoubleDistanceDBIDPair pair);
+ ArrayList<ClassLabel> getLabels();
/**
- * Clear the list contents.
+ * How many partitions to test.
+ *
+ * @return Number of partitions.
*/
- void clear();
+ int numberOfPartitions();
}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/LeaveOneOut.java b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/LeaveOneOut.java
new file mode 100644
index 00000000..1059f0a1
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/LeaveOneOut.java
@@ -0,0 +1,82 @@
+package de.lmu.ifi.dbs.elki.evaluation.classification.holdout;
+
+/*
+ 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.ArrayList;
+
+import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+
+/**
+ * A leave-one-out-holdout is to provide a set of partitions of a database where
+ * each instances once hold out as a test instance while the respectively
+ * remaining instances are training instances.
+ *
+ * @author Arthur Zimek
+ */
+public class LeaveOneOut extends AbstractHoldout {
+ /**
+ * Size of the data set.
+ */
+ private int len, pos;
+
+ /**
+ * Constructor.
+ */
+ public LeaveOneOut() {
+ super();
+ }
+
+ @Override
+ public void initialize(MultipleObjectsBundle bundle) {
+ super.initialize(bundle);
+ len = bundle.dataLength();
+ pos = 0;
+ }
+
+ @Override
+ public int numberOfPartitions() {
+ return len;
+ }
+
+ @Override
+ public TrainingAndTestSet nextPartitioning() {
+ if(pos >= len) {
+ return null;
+ }
+ MultipleObjectsBundle training = new MultipleObjectsBundle();
+ MultipleObjectsBundle test = new MultipleObjectsBundle();
+ // Process column-wise.
+ for(int c = 0, cs = bundle.metaLength(); c < cs; ++c) {
+ ArrayList<Object> tr = new ArrayList<>(len - 1), te = new ArrayList<>(1);
+ for(int i = 0; i < bundle.dataLength(); ++i) {
+ ((i != pos) ? tr : te).add(bundle.data(i, c));
+ }
+ training.appendColumn(bundle.meta(c), tr);
+ test.appendColumn(bundle.meta(c), te);
+ }
+
+ ++pos;
+ return new TrainingAndTestSet(training, test, labels);
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/RandomizedCrossValidation.java b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/RandomizedCrossValidation.java
new file mode 100644
index 00000000..99607398
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/RandomizedCrossValidation.java
@@ -0,0 +1,141 @@
+package de.lmu.ifi.dbs.elki.evaluation.classification.holdout;
+
+/*
+ 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.ArrayList;
+import java.util.Random;
+
+import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+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;
+
+/**
+ * RandomizedCrossValidationHoldout provides a set of partitions of a database
+ * to perform cross-validation. The test sets are not guaranteed to be disjoint.
+ *
+ * @author Arthur Zimek
+ */
+public class RandomizedCrossValidation extends RandomizedHoldout {
+ /**
+ * Holds the number of folds, current fold.
+ */
+ protected int nfold, fold;
+
+ /**
+ * Constructor for n-fold cross-validation.
+ *
+ * @param random Random seed
+ * @param nfold Number of folds
+ */
+ public RandomizedCrossValidation(RandomFactory random, int nfold) {
+ super(random);
+ this.nfold = nfold;
+ }
+
+ @Override
+ public void initialize(MultipleObjectsBundle bundle) {
+ super.initialize(bundle);
+ this.fold = 0;
+ }
+
+ @Override
+ public int numberOfPartitions() {
+ return nfold;
+ }
+
+ @Override
+ public TrainingAndTestSet nextPartitioning() {
+ if(fold >= nfold) {
+ return null;
+ }
+ MultipleObjectsBundle training = new MultipleObjectsBundle();
+ MultipleObjectsBundle test = new MultipleObjectsBundle();
+ Random rnd = random.getRandom();
+ int datalen = bundle.dataLength();
+
+ boolean[] assignment = new boolean[datalen];
+ int trsize = 0, tesize = 0;
+ for(int i = 0; i < assignment.length; ++i) {
+ boolean p = rnd.nextInt(nfold) < nfold - 1;
+ assignment[i] = p;
+ @SuppressWarnings("unused")
+ int discard = p ? ++trsize : ++tesize;
+ }
+ // Process column-wise.
+ for(int c = 0, cs = bundle.metaLength(); c < cs; ++c) {
+ ArrayList<Object> tr = new ArrayList<>(trsize), te = new ArrayList<>(tesize);
+ for(int i = 0; i < datalen; ++i) {
+ (assignment[i] ? tr : te).add(bundle.data(i, c));
+ }
+ training.appendColumn(bundle.meta(c), tr);
+ test.appendColumn(bundle.meta(c), te);
+ }
+
+ ++fold;
+ return new TrainingAndTestSet(training, test, labels);
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends RandomizedHoldout.Parameterizer {
+ /**
+ * Parameter for number of folds.
+ */
+ public static final OptionID NFOLD_ID = new OptionID("nfold", "positive number of folds for cross-validation");
+
+ /**
+ * Default number of folds.
+ */
+ public static final int N_DEFAULT = 10;
+
+ /**
+ * Holds the number of folds.
+ */
+ protected int nfold;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ IntParameter nfoldP = new IntParameter(NFOLD_ID)//
+ .setDefaultValue(N_DEFAULT) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(nfoldP)) {
+ nfold = nfoldP.intValue();
+ }
+ }
+
+ @Override
+ protected RandomizedCrossValidation makeInstance() {
+ return new RandomizedCrossValidation(random, nfold);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveHSBColorHistogram.java b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/RandomizedHoldout.java
index d6bf2e6c..6202af48 100644
--- a/src/de/lmu/ifi/dbs/elki/data/images/ComputeNaiveHSBColorHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/RandomizedHoldout.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.data.images;
+package de.lmu.ifi.dbs.elki.evaluation.classification.holdout;
/*
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,57 +23,56 @@ package de.lmu.ifi.dbs.elki.data.images;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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.IntParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
/**
- * Compute color histograms in a Hue-Saturation-Brightness model.
+ * A holdout providing a seed for randomized operations.
*
- * @author Erich Schubert
+ * @author Arthur Zimek
*/
-public class ComputeNaiveHSBColorHistogram extends ComputeHSBColorHistogram {
+public abstract class RandomizedHoldout extends AbstractHoldout {
/**
- * Parameter that specifies the number of bins (per plane) to use.
- *
- * <p>
- * Key: {@code -hsbhist.bpp}
- * </p>
+ * The random generator.
*/
- public static final OptionID BINSPERPLANE_ID = new OptionID("hsbhist.bpp", "Bins per plane for HSV/HSB histogram. This will result in bpp ** 3 bins.");
+ protected RandomFactory random;
/**
- * Constructor.
- *
- * @param quant Number of bins to use.
+ * Sets the parameter seed to the parameterToDescription map.
*/
- public ComputeNaiveHSBColorHistogram(int quant) {
- super(quant, quant, quant);
+ public RandomizedHoldout(RandomFactory random) {
+ super();
+ this.random = random;
}
/**
- * Parameterization class.
+ * Parameterization class
*
* @author Erich Schubert
*
* @apiviz.exclude
*/
- public static class Parameterizer extends AbstractParameterizer {
- protected int quant = 0;
+ public static abstract class Parameterizer extends AbstractParameterizer {
+ /**
+ * Random seeding for holdout evaluation.
+ */
+ public static final OptionID SEED_ID = new OptionID("holdout.seed", "Random generator seed for holdout evaluation.");
+
+ /**
+ * The random generator.
+ */
+ protected RandomFactory random;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final IntParameter param = new IntParameter(BINSPERPLANE_ID);
- if(config.grab(param)) {
- quant = param.getValue();
+ RandomParameter seedP = new RandomParameter(SEED_ID);
+ if(config.grab(seedP)) {
+ random = seedP.getValue();
}
}
-
- @Override
- protected ComputeNaiveHSBColorHistogram makeInstance() {
- return new ComputeNaiveHSBColorHistogram(quant);
- }
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/StratifiedCrossValidation.java b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/StratifiedCrossValidation.java
new file mode 100644
index 00000000..40de7e88
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/StratifiedCrossValidation.java
@@ -0,0 +1,162 @@
+package de.lmu.ifi.dbs.elki.evaluation.classification.holdout;
+
+/*
+ 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 gnu.trove.list.array.TIntArrayList;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import de.lmu.ifi.dbs.elki.data.ClassLabel;
+import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+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.constraints.CommonConstraints;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+
+/**
+ * A stratified n-fold crossvalidation to distribute the data to n buckets where
+ * each bucket exhibits approximately the same distribution of classes as does
+ * the complete data set. The buckets are disjoint. The distribution is
+ * deterministic.
+ *
+ * @author Arthur Zimek
+ */
+public class StratifiedCrossValidation extends AbstractHoldout {
+ /**
+ * Holds the number of folds, current fold.
+ */
+ protected int nfold, fold;
+
+ /**
+ * Partition assignment, sizes
+ */
+ protected int[] assignment, sizes;
+
+ /**
+ * Provides a stratified crossvalidation. Setting parameter N_P to the
+ * OptionHandler.
+ */
+ public StratifiedCrossValidation(int nfold) {
+ super();
+ this.nfold = nfold;
+ }
+
+ @Override
+ public int numberOfPartitions() {
+ return nfold;
+ }
+
+ @Override
+ public void initialize(MultipleObjectsBundle bundle) {
+ super.initialize(bundle);
+ fold = 0;
+ TIntArrayList[] classBuckets = new TIntArrayList[this.labels.size()];
+ for(int i = 0; i < this.labels.size(); i++) {
+ classBuckets[i] = new TIntArrayList();
+ }
+ for(int i = 0, l = bundle.dataLength(); i < l; ++i) {
+ ClassLabel label = (ClassLabel) bundle.data(i, labelcol);
+ if(label == null) {
+ throw new AbortException("Unlabeled instances currently not supported.");
+ }
+ int classIndex = Collections.binarySearch(labels, label);
+ if(classIndex < 0) {
+ throw new AbortException("Label not in label list: " + label);
+ }
+ classBuckets[classIndex].add(i);
+ }
+ // TODO: shuffle the class buckets?
+ sizes = new int[nfold];
+ assignment = new int[bundle.dataLength()];
+ for(TIntArrayList bucket : classBuckets) {
+ for(int i = 0; i < bucket.size(); i++) {
+ assignment[bucket.get(i)] = i % nfold;
+ }
+ }
+ }
+
+ @Override
+ public TrainingAndTestSet nextPartitioning() {
+ if(fold >= nfold) {
+ return null;
+ }
+ final int tesize = sizes[fold], trsize = bundle.dataLength() - tesize;
+ MultipleObjectsBundle training = new MultipleObjectsBundle();
+ MultipleObjectsBundle test = new MultipleObjectsBundle();
+ // Process column-wise.
+ for(int c = 0, cs = bundle.metaLength(); c < cs; ++c) {
+ ArrayList<Object> tr = new ArrayList<>(trsize), te = new ArrayList<>(tesize);
+ for(int i = 0; i < bundle.dataLength(); ++i) {
+ ((assignment[i] != fold) ? tr : te).add(bundle.data(i, c));
+ }
+ training.appendColumn(bundle.meta(c), tr);
+ test.appendColumn(bundle.meta(c), te);
+ }
+
+ ++fold;
+ return new TrainingAndTestSet(training, test, labels);
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Default number of folds.
+ */
+ public static final int N_DEFAULT = 10;
+
+ /**
+ * Parameter for number of folds.
+ */
+ public static final OptionID NFOLD_ID = new OptionID("nfold", "Number of folds for cross-validation");
+
+ /**
+ * Holds the number of folds.
+ */
+ protected int nfold;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ IntParameter nfoldP = new IntParameter(NFOLD_ID, N_DEFAULT)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(nfoldP)) {
+ nfold = nfoldP.intValue();
+ }
+ }
+
+ @Override
+ protected StratifiedCrossValidation makeInstance() {
+ return new StratifiedCrossValidation(nfold);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/TrainingAndTestSet.java b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/TrainingAndTestSet.java
new file mode 100644
index 00000000..a8725e1c
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/TrainingAndTestSet.java
@@ -0,0 +1,89 @@
+package de.lmu.ifi.dbs.elki.evaluation.classification.holdout;
+
+/*
+ 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.ArrayList;
+
+import de.lmu.ifi.dbs.elki.data.ClassLabel;
+import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+
+/**
+ * Wrapper to hold a pair of training and test data sets. The labels of both
+ * training and test set are provided in labels.
+ *
+ * @author Arthur Zimek
+ */
+public class TrainingAndTestSet {
+ /**
+ * The overall labels.
+ */
+ private ArrayList<ClassLabel> labels;
+
+ /**
+ * The training data.
+ */
+ private MultipleObjectsBundle training;
+
+ /**
+ * The test data.
+ */
+ private MultipleObjectsBundle test;
+
+ /**
+ * Provides a pair of training and test data sets out of the given two
+ * databases.
+ */
+ public TrainingAndTestSet(MultipleObjectsBundle training, MultipleObjectsBundle test, ArrayList<ClassLabel> labels) {
+ this.training = training;
+ this.test = test;
+ this.labels = labels;
+ }
+
+ /**
+ * Returns the test data set.
+ *
+ * @return the test data set
+ */
+ public MultipleObjectsBundle getTest() {
+ return test;
+ }
+
+ /**
+ * Returns the training data set.
+ *
+ * @return the training data set
+ */
+ public MultipleObjectsBundle getTraining() {
+ return training;
+ }
+
+ /**
+ * Returns all labels present in the data set.
+ *
+ * @return all labels
+ */
+ public ArrayList<ClassLabel> getLabels() {
+ return labels;
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/package-info.java b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/package-info.java
new file mode 100644
index 00000000..a469dfc3
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/classification/holdout/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Holdout and cross-validation strategies for evaluating classifiers.
+ */
+/*
+ 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.evaluation.classification.holdout;
+
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/classification/package-info.java b/src/de/lmu/ifi/dbs/elki/evaluation/classification/package-info.java
new file mode 100644
index 00000000..a6e3f484
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/classification/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Evaluation of classification algorithms.
+ */
+/*
+ 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.evaluation.classification;
+
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/BCubed.java b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/BCubed.java
index 3353b593..1c84f0e1 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/BCubed.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/BCubed.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.clustering;
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/evaluation/clustering/ClusterContingencyTable.java b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/ClusterContingencyTable.java
index c3f8129f..d5dec735 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/ClusterContingencyTable.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/ClusterContingencyTable.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.clustering;
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,16 +22,15 @@ package de.lmu.ifi.dbs.elki.evaluation.clustering;
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 java.util.Iterator;
import java.util.List;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
/**
* Class storing the contingency table and related data on two clusterings.
@@ -59,14 +58,9 @@ public class ClusterContingencyTable {
protected boolean selfPairing = true;
/**
- * Number of clusters in first
+ * Number of clusters.
*/
- protected int size1 = -1;
-
- /**
- * Number of clusters in second
- */
- protected int size2 = -1;
+ protected int size1 = -1, size2 = -1;
/**
* Contingency matrix
@@ -76,12 +70,7 @@ public class ClusterContingencyTable {
/**
* Noise flags
*/
- protected BitSet noise1 = null;
-
- /**
- * Noise flags
- */
- protected BitSet noise2 = null;
+ protected long[] noise1 = null, noise2 = null;
/**
* Pair counting measures
@@ -135,46 +124,39 @@ public class ClusterContingencyTable {
size1 = cs1.size();
size2 = cs2.size();
contingency = new int[size1 + 2][size2 + 2];
- noise1 = new BitSet(size1);
- noise2 = new BitSet(size2);
+ noise1 = BitsUtil.zero(size1);
+ noise2 = BitsUtil.zero(size2);
// Fill main part of matrix
{
- {
- final Iterator<? extends Cluster<?>> it2 = cs2.iterator();
- for(int i2 = 0; it2.hasNext(); i2++) {
- final Cluster<?> c2 = it2.next();
- if(c2.isNoise()) {
- noise2.set(i2);
- }
- contingency[size1 + 1][i2] = c2.size();
- contingency[size1 + 1][size2] += c2.size();
+ final Iterator<? extends Cluster<?>> it2 = cs2.iterator();
+ for(int i2 = 0; it2.hasNext(); i2++) {
+ final Cluster<?> c2 = it2.next();
+ if(c2.isNoise()) {
+ BitsUtil.setI(noise2, i2);
}
+ contingency[size1 + 1][i2] = c2.size();
+ contingency[size1 + 1][size2] += c2.size();
}
- final Iterator<? extends Cluster<?>> it1 = cs1.iterator();
- for(int i1 = 0; it1.hasNext(); i1++) {
- final Cluster<?> c1 = it1.next();
- if(c1.isNoise()) {
- noise1.set(i1);
- }
- final DBIDs ids = DBIDUtil.ensureSet(c1.getIDs());
- contingency[i1][size2 + 1] = c1.size();
- contingency[size1][size2 + 1] += c1.size();
-
- final Iterator<? extends Cluster<?>> it2 = cs2.iterator();
- for(int i2 = 0; it2.hasNext(); i2++) {
- final Cluster<?> c2 = it2.next();
- int count = 0;
- for(DBIDIter iter = c2.getIDs().iter(); iter.valid(); iter.advance()) {
- if(ids.contains(iter)) {
- count++;
- }
- }
- contingency[i1][i2] = count;
- contingency[i1][size2] += count;
- contingency[size1][i2] += count;
- contingency[size1][size2] += count;
- }
+ }
+ final Iterator<? extends Cluster<?>> it1 = cs1.iterator();
+ for(int i1 = 0; it1.hasNext(); i1++) {
+ final Cluster<?> c1 = it1.next();
+ if(c1.isNoise()) {
+ BitsUtil.setI(noise1, i1);
+ }
+ final DBIDs ids = DBIDUtil.ensureSet(c1.getIDs());
+ contingency[i1][size2 + 1] = c1.size();
+ contingency[size1][size2 + 1] += c1.size();
+
+ final Iterator<? extends Cluster<?>> it2 = cs2.iterator();
+ for(int i2 = 0; it2.hasNext(); i2++) {
+ final Cluster<?> c2 = it2.next();
+ int count = DBIDUtil.intersectionSize(ids, c2.getIDs());
+ contingency[i1][i2] = count;
+ contingency[i1][size2] += count;
+ contingency[size1][i2] += count;
+ contingency[size1][size2] += count;
}
}
}
@@ -196,9 +178,6 @@ public class ClusterContingencyTable {
buf.append('\n');
}
}
- // if(pairconfuse != null) {
- // buf.append(FormatUtil.format(pairconfuse));
- // }
return buf.toString();
}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/EditDistance.java b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/EditDistance.java
index 6bbda98a..41b69de6 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/EditDistance.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/EditDistance.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.evaluation.clustering;
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/evaluation/clustering/Entropy.java b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/Entropy.java
index 58f19f65..654cecbe 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/Entropy.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/Entropy.java
@@ -1,9 +1,10 @@
package de.lmu.ifi.dbs.elki.evaluation.clustering;
+
/*
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
@@ -36,7 +37,10 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
*
* @author Sascha Goldhofer
*/
-@Reference(authors = "Meilă, M.", title = "Comparing clusterings by the variation of information", booktitle = "Learning theory and kernel machines", url = "http://dx.doi.org/10.1007/978-3-540-45167-9_14")
+@Reference(authors = "Meilă, M.", //
+title = "Comparing clusterings by the variation of information", //
+booktitle = "Learning theory and kernel machines", //
+url = "http://dx.doi.org/10.1007/978-3-540-45167-9_14")
public class Entropy {
/**
* Entropy in first
@@ -105,8 +109,8 @@ public class Entropy {
}
/**
- * Get the entropy of the second clustering using Log_2. (not normalized, 0
- * = equal)
+ * Get the entropy of the second clustering using Log_2. (not normalized, 0 =
+ * equal)
*
* @return Entropy of second clustering
*/
@@ -144,8 +148,7 @@ public class Entropy {
}
/**
- * Get Powers entropy (normalized, 0 = equal)
- * Powers = 1 - NMI_Sum
+ * Get Powers entropy (normalized, 0 = equal) Powers = 1 - NMI_Sum
*
* @return Powers
*/
@@ -168,7 +171,7 @@ public class Entropy {
* @return Joint Normalized Mutual information
*/
public double entropyNMIJoint() {
- if (entropyJoint() == 0) {
+ if(entropyJoint() == 0) {
return 0;
}
return (entropyMutualInformation() / entropyJoint());
@@ -207,7 +210,7 @@ public class Entropy {
* @return Sqrt Normalized Mutual information
*/
public double entropyNMISqrt() {
- if (entropyFirst() * entropySecond() <= 0) {
+ if(entropyFirst() * entropySecond() <= 0) {
return entropyMutualInformation();
}
return (entropyMutualInformation() / Math.sqrt(entropyFirst() * entropySecond()));
@@ -223,20 +226,23 @@ public class Entropy {
}
/**
- * Get the normalized variation of information (normalized, 0 = equal)
- * NVI = 1 - NMI_Joint
+ * Get the normalized variation of information (normalized, 0 = equal) NVI = 1
+ * - NMI_Joint
*
* <p>
- * Vinh, N.X. and Epps, J. and Bailey, J.<br />
- * Information theoretic measures for clusterings comparison: is a
- * correction for chance necessary?<br />
- * In: Proc. ICML '09 Proceedings of the 26th Annual International
- * Conference on Machine Learning
+ * Nguyen, X. V. and Epps, J. and Bailey, J.<br />
+ * Information theoretic measures for clusterings comparison: is a correction
+ * for chance necessary?<br />
+ * In: Proc. ICML '09 Proceedings of the 26th Annual International Conference
+ * on Machine Learning
* </p>
*
* @return Normalized Variation of information
*/
- @Reference(authors = "Vinh, N.X. and Epps, J. and Bailey, J.", title = "Information theoretic measures for clusterings comparison: is a correction for chance necessary?", booktitle = "Proc. ICML '09 Proceedings of the 26th Annual International Conference on Machine Learning", url = "http://dx.doi.org/10.1145/1553374.1553511")
+ @Reference(authors = "Nguyen, X. V. and Epps, J. and Bailey, J.", //
+ title = "Information theoretic measures for clusterings comparison: is a correction for chance necessary?", //
+ booktitle = "Proc. ICML '09 Proceedings of the 26th Annual International Conference on Machine Learning", //
+ url = "http://dx.doi.org/10.1145/1553374.1553511")
public double normalizedVariationOfInformation() {
return (1.0 - (entropyMutualInformation() / entropyJoint()));
}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/EvaluateClustering.java b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/EvaluateClustering.java
index 6db25736..2a67dbe2 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/EvaluateClustering.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/EvaluateClustering.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.clustering;
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,12 +32,12 @@ import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.evaluation.Evaluator;
import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.result.BasicResult;
+import de.lmu.ifi.dbs.elki.math.MeanVariance;
+import de.lmu.ifi.dbs.elki.result.EvaluationResult;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
-import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable;
-import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
+import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
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;
@@ -156,7 +156,9 @@ public class EvaluateClustering implements Evaluator {
ClusterContingencyTable contmat = new ClusterContingencyTable(selfPairing, noiseSpecialHandling);
contmat.process(refc, c);
- db.getHierarchy().add(c, new ScoreResult(contmat));
+ ScoreResult sr = new ScoreResult(contmat);
+ sr.addHeader(c.getLongName());
+ db.getHierarchy().add(c, sr);
}
}
@@ -184,7 +186,7 @@ public class EvaluateClustering implements Evaluator {
*
* @apiviz.composedOf ClusterContingencyTable
*/
- public static class ScoreResult extends BasicResult implements TextWriteable {
+ public static class ScoreResult extends EvaluationResult {
/**
* Cluster contingency table
*/
@@ -198,6 +200,43 @@ public class EvaluateClustering implements Evaluator {
public ScoreResult(ClusterContingencyTable contmat) {
super("Cluster-Evalation", "cluster-evaluation");
this.contmat = contmat;
+
+ PairCounting paircount = contmat.getPaircount();
+ MeasurementGroup g = newGroup("Pair counting measures");
+ g.addMeasure("Jaccard", paircount.jaccard(), 0, 1, false);
+ g.addMeasure("F1-Measure", paircount.f1Measure(), 0, 1, false);
+ g.addMeasure("Precision", paircount.precision(), 0, 1, false);
+ g.addMeasure("Recall", paircount.recall(), 0, 1, false);
+ g.addMeasure("Rand", paircount.randIndex(), 0, 1, false);
+ g.addMeasure("ARI", paircount.adjustedRandIndex(), 0, 1, false);
+ g.addMeasure("FowlkesMallows", paircount.fowlkesMallows(), 0, 1, false);
+
+ Entropy entropy = contmat.getEntropy();
+ g = newGroup("Entropy based measures");
+ g.addMeasure("NMI Joint", entropy.entropyNMIJoint(), 0, 1, false);
+ g.addMeasure("NMI Sqrt", entropy.entropyNMISqrt(), 0, 1, false);
+
+ BCubed bcubed = contmat.getBCubed();
+ g = newGroup("BCubed-based measures");
+ g.addMeasure("F1-Measure", bcubed.f1Measure(), 0, 1, false);
+ g.addMeasure("Recall", bcubed.recall(), 0, 1, false);
+ g.addMeasure("Precision", bcubed.precision(), 0, 1, false);
+
+ SetMatchingPurity setm = contmat.getSetMatching();
+ g = newGroup("Set-Matching-based measures");
+ g.addMeasure("F1-Measure", setm.f1Measure(), 0, 1, false);
+ g.addMeasure("Purity", setm.purity(), 0, 1, false);
+ g.addMeasure("Inverse Purity", setm.inversePurity(), 0, 1, false);
+
+ EditDistance edit = contmat.getEdit();
+ g = newGroup("Editing-distance measures");
+ g.addMeasure("F1-Measure", edit.f1Measure(), 0, 1, false);
+ g.addMeasure("Precision", edit.editDistanceFirst(), 0, 1, false);
+ g.addMeasure("Recall", edit.editDistanceSecond(), 0, 1, false);
+
+ MeanVariance gini = contmat.averageSymmetricGini();
+ g = newGroup("Gini measures");
+ g.addMeasure("Mean +-" + FormatUtil.NF4.format(gini.getCount() > 1. ? gini.getSampleStddev() : 0.), gini.getMean(), 0, 1, false);
}
/**
@@ -208,47 +247,6 @@ public class EvaluateClustering implements Evaluator {
public ClusterContingencyTable getContingencyTable() {
return contmat;
}
-
- @Override
- public void writeToText(TextWriterStream out, String label) {
- out.commentPrint("Pair-F1, ");
- out.commentPrint("Pair-Precision, ");
- out.commentPrint("Pair-Recall, ");
- out.commentPrint("Pair-Rand, ");
- out.commentPrint("Pair-AdjustedRand, ");
- out.commentPrint("Pair-FowlkesMallows, ");
- out.commentPrint("Pair-Jaccard, ");
- out.commentPrint("Pair-Mirkin, ");
- out.commentPrint("Entropy-VI, ");
- out.commentPrint("Entropy-NormalizedVI, ");
- out.commentPrint("Entropy-F1, ");
- out.commentPrint("Edit-F1, ");
- out.commentPrint("SM-InvPurity, ");
- out.commentPrint("SM-Purity, ");
- out.commentPrint("SM-F1, ");
- out.commentPrint("BCubed-Precision, ");
- out.commentPrint("BCubed-Recall, ");
- out.commentPrint("BCubed-F1");
- out.flush();
- out.inlinePrint(contmat.getPaircount().f1Measure());
- out.inlinePrint(contmat.getPaircount().precision());
- out.inlinePrint(contmat.getPaircount().recall());
- out.inlinePrint(contmat.getPaircount().randIndex());
- out.inlinePrint(contmat.getPaircount().adjustedRandIndex());
- out.inlinePrint(contmat.getPaircount().fowlkesMallows());
- out.inlinePrint(contmat.getPaircount().jaccard());
- out.inlinePrint(contmat.getPaircount().mirkin());
- out.inlinePrint(contmat.getEntropy().variationOfInformation());
- out.inlinePrint(contmat.getEntropy().normalizedVariationOfInformation());
- out.inlinePrint(contmat.getEdit().f1Measure());
- out.inlinePrint(contmat.getSetMatching().inversePurity());
- out.inlinePrint(contmat.getSetMatching().purity());
- out.inlinePrint(contmat.getSetMatching().f1Measure());
- out.inlinePrint(contmat.getBCubed().precision());
- out.inlinePrint(contmat.getBCubed().recall());
- out.inlinePrint(contmat.getBCubed().f1Measure());
- out.flush();
- }
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/PairCounting.java b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/PairCounting.java
index ef7935d8..cbe8e618 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/PairCounting.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/PairCounting.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.clustering;
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,6 +24,7 @@ package de.lmu.ifi.dbs.elki.evaluation.clustering;
*/
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
/**
@@ -54,16 +55,18 @@ public class PairCounting {
long inBoth = 0, in1 = 0, in2 = 0, total = 0;
// Process first clustering:
{
- for (int i1 = 0; i1 < table.size1; i1++) {
+ for(int i1 = 0; i1 < table.size1; i1++) {
final int size = table.contingency[i1][table.size2 + 1];
- if (table.breakNoiseClusters && table.noise1.get(i1)) {
- if (table.selfPairing) {
+ if(table.breakNoiseClusters && BitsUtil.get(table.noise1, i1)) {
+ if(table.selfPairing) {
in1 += size;
} // else: 0
- } else {
- if (table.selfPairing) {
+ }
+ else {
+ if(table.selfPairing) {
in1 += size * size;
- } else {
+ }
+ else {
in1 += size * (size - 1);
}
}
@@ -71,33 +74,37 @@ public class PairCounting {
}
// Process second clustering:
{
- for (int i2 = 0; i2 < table.size2; i2++) {
+ for(int i2 = 0; i2 < table.size2; i2++) {
final int size = table.contingency[table.size1 + 1][i2];
- if (table.breakNoiseClusters && table.noise2.get(i2)) {
- if (table.selfPairing) {
+ if(table.breakNoiseClusters && BitsUtil.get(table.noise2, i2)) {
+ if(table.selfPairing) {
in2 += size;
} // else: 0
- } else {
- if (table.selfPairing) {
+ }
+ else {
+ if(table.selfPairing) {
in2 += size * size;
- } else {
+ }
+ else {
in2 += size * (size - 1);
}
}
}
}
// Process combinations
- for (int i1 = 0; i1 < table.size1; i1++) {
- for (int i2 = 0; i2 < table.size2; i2++) {
+ for(int i1 = 0; i1 < table.size1; i1++) {
+ for(int i2 = 0; i2 < table.size2; i2++) {
final int size = table.contingency[i1][i2];
- if (table.breakNoiseClusters && (table.noise1.get(i1) || table.noise2.get(i2))) {
- if (table.selfPairing) {
+ if(table.breakNoiseClusters && (BitsUtil.get(table.noise1, i1) || BitsUtil.get(table.noise2, i2))) {
+ if(table.selfPairing) {
inBoth += size;
} // else: 0
- } else {
- if (table.selfPairing) {
+ }
+ else {
+ if(table.selfPairing) {
inBoth += size * size;
- } else {
+ }
+ else {
inBoth += size * (size - 1);
}
}
@@ -105,15 +112,16 @@ public class PairCounting {
}
// The official sum
int tsize = table.contingency[table.size1][table.size2];
- if (table.contingency[table.size1][table.size2 + 1] != tsize || table.contingency[table.size1 + 1][table.size2] != tsize) {
+ if(table.contingency[table.size1][table.size2 + 1] != tsize || table.contingency[table.size1 + 1][table.size2] != tsize) {
LoggingUtil.warning("PairCounting F-Measure is not well defined for overlapping and incomplete clusterings. The number of elements are: " + table.contingency[table.size1][table.size2 + 1] + " != " + table.contingency[table.size1 + 1][table.size2] + " elements.");
}
- if (tsize < 0 || tsize >= MAX_SIZE) {
+ if(tsize < 0 || tsize >= MAX_SIZE) {
LoggingUtil.warning("Your data set size probably is too big for this implementation, which uses only long precision.");
}
- if (table.selfPairing) {
+ if(table.selfPairing) {
total = tsize * tsize;
- } else {
+ }
+ else {
total = tsize * (tsize - 1);
}
long inFirst = in1 - inBoth, inSecond = in2 - inBoth;
@@ -172,7 +180,9 @@ public class PairCounting {
* @return pair-counting Fowlkes-mallows
*/
// TODO: implement for non-flat clusterings!
- @Reference(authors = "Fowlkes, E.B. and Mallows, C.L.", title = "A method for comparing two hierarchical clusterings", booktitle = "Journal of the American Statistical Association, Vol. 78 Issue 383")
+ @Reference(authors = "Fowlkes, E.B. and Mallows, C.L.", //
+ title = "A method for comparing two hierarchical clusterings", //
+ booktitle = "Journal of the American Statistical Association, Vol. 78 Issue 383")
public double fowlkesMallows() {
return Math.sqrt(precision() * recall());
}
@@ -188,7 +198,10 @@ public class PairCounting {
*
* @return The Rand index (RI).
*/
- @Reference(authors = "Rand, W. M.", title = "Objective Criteria for the Evaluation of Clustering Methods", booktitle = "Journal of the American Statistical Association, Vol. 66 Issue 336", url = "http://www.jstor.org/stable/10.2307/2284239")
+ @Reference(authors = "Rand, W. M.", //
+ title = "Objective Criteria for the Evaluation of Clustering Methods", //
+ booktitle = "Journal of the American Statistical Association, Vol. 66 Issue 336", //
+ url = "http://www.jstor.org/stable/10.2307/2284239")
public double randIndex() {
final double sum = pairconfuse[0] + pairconfuse[1] + pairconfuse[2] + pairconfuse[3];
return (pairconfuse[0] + pairconfuse[3]) / sum;
@@ -203,9 +216,10 @@ public class PairCounting {
final double nom = pairconfuse[0] * pairconfuse[3] - pairconfuse[1] * pairconfuse[2];
final long d1 = (pairconfuse[0] + pairconfuse[1]) * (pairconfuse[1] + pairconfuse[3]);
final long d2 = (pairconfuse[0] + pairconfuse[2]) * (pairconfuse[2] + pairconfuse[3]);
- if (d1 + d2 > 0) {
+ if(d1 + d2 > 0) {
return 2 * nom / (d1 + d2);
- } else {
+ }
+ else {
return 1.;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/SetMatchingPurity.java b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/SetMatchingPurity.java
index 1a003117..d37d4693 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/SetMatchingPurity.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/SetMatchingPurity.java
@@ -1,9 +1,10 @@
package de.lmu.ifi.dbs.elki.evaluation.clustering;
+
/*
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
@@ -41,19 +42,29 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* University of Washington, Seattle, Technical Report 418, 2002
* </p>
* <p>
- * Steinbach, M. and Karypis, G. and Kumar, V. and others<br />
+ * Steinbach, M. and Karypis, G. and Kumar, V.<br />
* A comparison of document clustering techniques<br />
* KDD workshop on text mining, 2000
* </p>
+ * <p>
+ * E. Amigó, J. Gonzalo, J. Artiles, and F. Verdejo <br />
+ * A comparison of extrinsic clustering evaluation metrics based on formal
+ * constraints<br />
+ * Inf. Retrieval, vol. 12, no. 5, pp. 461–486, 2009
+ * </p>
*
* @author Sascha Goldhofer
*/
-@Reference(authors = "Meilă, M", title = "Comparing clusterings", booktitle = "University of Washington, Seattle, Technical Report 418, 2002", url = "http://www.stat.washington.edu/mmp/www.stat.washington.edu/mmp/Papers/compare-colt.pdf")
+@Reference(authors = "Meilă, M", //
+title = "Comparing clusterings", //
+booktitle = "University of Washington, Seattle, Technical Report 418, 2002", //
+url = "http://www.stat.washington.edu/mmp/Papers/compare-colt.pdf")
public class SetMatchingPurity {
/**
* Result cache
*/
- protected double smPurity = -1.0, smInversePurity = -1.0, smFFirst = -1.0, smFSecond = - 1.0;
+ protected double smPurity = -1.0, smInversePurity = -1.0, smFFirst = -1.0,
+ smFSecond = -1.0;
/**
* Constructor.
@@ -105,14 +116,17 @@ public class SetMatchingPurity {
*
* @return purity
*/
- @Reference(authors = "Zhao, Y. and Karypis, G.", title = "Criterion functions for document clustering: Experiments and analysis", booktitle = "University of Minnesota, Department of Computer Science, Technical Report 01-40, 2001", url = "http://www-users.cs.umn.edu/~karypis/publications/Papers/PDF/vscluster.pdf")
+ @Reference(authors = "Zhao, Y. and Karypis, G.", //
+ title = "Criterion functions for document clustering: Experiments and analysis", //
+ booktitle = "University of Minnesota, Department of Computer Science, Technical Report 01-40, 2001", //
+ url = "http://www-users.cs.umn.edu/~karypis/publications/Papers/PDF/vscluster.pdf")
public double purity() {
return smPurity;
}
/**
- * Get the set matchings inverse purity (second:first clustering)
- * (normalized, 1 = equal)
+ * Get the set matchings inverse purity (second:first clustering) (normalized,
+ * 1 = equal)
*
* @return Inverse purity
*/
@@ -124,44 +138,57 @@ public class SetMatchingPurity {
* Get the set matching F1-Measure
*
* <p>
- * Steinbach, M. and Karypis, G. and Kumar, V. and others<br />
+ * Steinbach, M. and Karypis, G. and Kumar, V.<br />
* A comparison of document clustering techniques<br />
* KDD workshop on text mining, 2000
* </p>
*
* @return Set Matching F1-Measure
*/
- @Reference(authors = "Steinbach, M. and Karypis, G. and Kumar, V. and others", title = "A comparison of document clustering techniques", booktitle = "KDD workshop on text mining, 2000", url = "http://www-users.itlabs.umn.edu/~karypis/publications/Papers/PDF/doccluster.pdf")
+ @Reference(authors = "Steinbach, M. and Karypis, G. and Kumar, V.", //
+ title = "A comparison of document clustering techniques", //
+ booktitle = "KDD workshop on text mining, 2000", //
+ url = "http://www-users.itlabs.umn.edu/~karypis/publications/Papers/PDF/doccluster.pdf")
public double f1Measure() {
return Util.f1Measure(purity(), inversePurity());
}
-
+
/**
* Get the Van Rijsbergen’s F measure (asymmetric) for first clustering
*
* <p>
* E. Amigó, J. Gonzalo, J. Artiles, and F. Verdejo <br />
- * A comparison of extrinsic clustering evaluation metrics based on formal constraints<br />
+ * A comparison of extrinsic clustering evaluation metrics based on formal
+ * constraints<br />
* Inf. Retrieval, vol. 12, no. 5, pp. 461–486, 2009
* </p>
*
* @return Set Matching F-Measure of first clustering
*/
+ @Reference(authors = "E. Amigó, J. Gonzalo, J. Artiles, and F. Verdejo", //
+ title = "A comparison of extrinsic clustering evaluation metrics based on formal constraints", //
+ booktitle = "Inf. Retrieval, vol. 12, no. 5", //
+ url = "http://dx.doi.org/10.1007/s10791-009-9106-z")
public double fMeasureFirst() {
return smFFirst;
}
-
+
/**
* Get the Van Rijsbergen’s F measure (asymmetric) for second clustering
*
* <p>
* E. Amigó, J. Gonzalo, J. Artiles, and F. Verdejo <br />
- * A comparison of extrinsic clustering evaluation metrics based on formal constraints<br />
+ * A comparison of extrinsic clustering evaluation metrics based on formal
+ * constraints<br />
* Inf. Retrieval, vol. 12, no. 5, pp. 461–486, 2009
* </p>
*
* @return Set Matching F-Measure of second clustering
*/
+ @Reference(authors = "E. Amigó, J. Gonzalo, J. Artiles, and F. Verdejo", //
+ title = "A comparison of extrinsic clustering evaluation metrics based on formal constraints", //
+ booktitle = "Inf. Retrieval, vol. 12, no. 5", //
+ url = "http://dx.doi.org/10.1007/s10791-009-9106-z")
public double fMeasureSecond() {
return smFSecond;
}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/internal/EvaluateSilhouette.java b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/internal/EvaluateSilhouette.java
new file mode 100644
index 00000000..bc2817a6
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/internal/EvaluateSilhouette.java
@@ -0,0 +1,265 @@
+package de.lmu.ifi.dbs.elki.evaluation.clustering.internal;
+
+/*
+ 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.List;
+
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+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.distance.DistanceQuery;
+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.distancefunction.minkowski.EuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.evaluation.Evaluator;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.statistics.DoubleStatistic;
+import de.lmu.ifi.dbs.elki.logging.statistics.LongStatistic;
+import de.lmu.ifi.dbs.elki.math.MeanVariance;
+import de.lmu.ifi.dbs.elki.result.EvaluationResult;
+import de.lmu.ifi.dbs.elki.result.EvaluationResult.MeasurementGroup;
+/*
+ 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.result.HierarchicalResult;
+import de.lmu.ifi.dbs.elki.result.Result;
+import de.lmu.ifi.dbs.elki.result.ResultUtil;
+import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+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.Flag;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
+
+/**
+ * Compute the silhouette of a data set.
+ *
+ * Reference:
+ * <p>
+ * P. J. Rousseeuw<br />
+ * Silhouettes: A graphical aid to the interpretation and validation of cluster
+ * analysis<br />
+ * In: Journal of Computational and Applied Mathematics Volume 20, November 1987
+ * </p>
+ *
+ * TODO: keep all silhouette values, and allow visualization!
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Object type
+ */
+@Reference(authors = "P. J. Rousseeuw", //
+title = "Silhouettes: A graphical aid to the interpretation and validation of cluster analysis", //
+booktitle = "Journal of Computational and Applied Mathematics, Volume 20", //
+url = "http://dx.doi.org/10.1016%2F0377-0427%2887%2990125-7")
+public class EvaluateSilhouette<O> implements Evaluator {
+ /**
+ * Logger for debug output.
+ */
+ private static final Logging LOG = Logging.getLogger(EvaluateSilhouette.class);
+
+ /**
+ * Keep noise "clusters" merged, instead of breaking them into singletons.
+ */
+ private boolean mergenoise = false;
+
+ /**
+ * Distance function to use.
+ */
+ private DistanceFunction<? super O> distance;
+
+ /**
+ * Key for logging statistics.
+ */
+ private String key = EvaluateSilhouette.class.getName();
+
+ /**
+ * Constructor.
+ *
+ * @param distance Distance function
+ * @param mergenoise Flag to treat noise as clusters, instead of breaking them
+ * into singletons.
+ */
+ public EvaluateSilhouette(DistanceFunction<? super O> distance, boolean mergenoise) {
+ super();
+ this.distance = distance;
+ this.mergenoise = mergenoise;
+ }
+
+ /**
+ * Evaluate a single clustering.
+ *
+ * @param db Database
+ * @param rel Data relation
+ * @param dq Distance query
+ * @param c Clustering
+ */
+ public void evaluateClustering(Database db, Relation<O> rel, DistanceQuery<O> dq, Clustering<?> c) {
+ List<? extends Cluster<?>> clusters = c.getAllClusters();
+ MeanVariance msil = new MeanVariance();
+ for(Cluster<?> cluster : clusters) {
+ if(cluster.size() <= 1 || (!mergenoise && cluster.isNoise())) {
+ // As suggested in Rousseeuw, we use 0 for singletons.
+ msil.put(0., cluster.size());
+ continue;
+ }
+ ArrayDBIDs ids = DBIDUtil.ensureArray(cluster.getIDs());
+ double[] as = new double[ids.size()]; // temporary storage.
+ DBIDArrayIter it1 = ids.iter(), it2 = ids.iter();
+ for(it1.seek(0); it1.valid(); it1.advance()) {
+ // a: In-cluster distances
+ double a = as[it1.getOffset()]; // Already computed distances
+ for(it2.seek(it1.getOffset() + 1); it2.valid(); it2.advance()) {
+ final double dist = dq.distance(it1, it2);
+ a += dist;
+ as[it2.getOffset()] += dist;
+ }
+ a /= (ids.size() - 1);
+ // b: other clusters:
+ double min = Double.POSITIVE_INFINITY;
+ for(Cluster<?> ocluster : clusters) {
+ if(ocluster == /* yes, reference identity */cluster) {
+ continue;
+ }
+ if(!mergenoise && ocluster.isNoise()) {
+ // Treat noise cluster as singletons:
+ for(DBIDIter it3 = ocluster.getIDs().iter(); it3.valid(); it3.advance()) {
+ double dist = dq.distance(it1, it3);
+ if(dist < min) {
+ min = dist;
+ }
+ }
+ continue;
+ }
+ final DBIDs oids = ocluster.getIDs();
+ double b = 0.;
+ for(DBIDIter it3 = oids.iter(); it3.valid(); it3.advance()) {
+ b += dq.distance(it1, it3);
+ }
+ b /= oids.size();
+ if(b < min) {
+ min = b;
+ }
+ }
+ msil.put((min - a) / Math.max(min, a));
+ }
+ }
+ if(LOG.isStatistics()) {
+ LOG.statistics(new LongStatistic(key + ".silhouette.noise", mergenoise ? 1L : 0L));
+ LOG.statistics(new DoubleStatistic(key + ".silhouette.mean", msil.getMean()));
+ LOG.statistics(new DoubleStatistic(key + ".silhouette.stddev", msil.getSampleStddev()));
+ }
+
+ EvaluationResult ev = new EvaluationResult("Internal Clustering Evaluation", "internal evaluation");
+ MeasurementGroup g = ev.newGroup("Distance-based Evaluation");
+ g.addMeasure("Silhouette coefficient +-" + FormatUtil.NF2.format(msil.getSampleStddev()), msil.getMean(), -1., 1., 0., false);
+ db.getHierarchy().add(c, ev);
+ }
+
+ @Override
+ public void processNewResult(HierarchicalResult baseResult, Result result) {
+ List<Clustering<?>> crs = ResultUtil.getClusteringResults(result);
+ if(crs.size() < 1) {
+ return;
+ }
+ Database db = ResultUtil.findDatabase(baseResult);
+ Relation<O> rel = db.getRelation(distance.getInputTypeRestriction());
+ DistanceQuery<O> dq = db.getDistanceQuery(rel, distance);
+ for(Clustering<?> c : crs) {
+ evaluateClustering(db, rel, dq, c);
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<O> extends AbstractParameterizer {
+ /**
+ * Parameter for choosing the distance function.
+ */
+ public static final OptionID DISTANCE_ID = new OptionID("silhouette.distance", "Distance function to use for computing the silhouette.");
+
+ /**
+ * Parameter to treat noise as a single cluster.
+ */
+ public static final OptionID MERGENOISE_ID = new OptionID("silhouette.noisecluster", "Treat noise as a cluster, not as singletons.");
+
+ /**
+ * Distance function to use.
+ */
+ private DistanceFunction<? super O> distance;
+
+ /**
+ * Keep noise "clusters" merged.
+ */
+ private boolean mergenoise = false;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ ObjectParameter<DistanceFunction<? super O>> distP = new ObjectParameter<>(DISTANCE_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
+ if(config.grab(distP)) {
+ distance = distP.instantiateClass(config);
+ }
+
+ Flag noiseP = new Flag(MERGENOISE_ID);
+ if(config.grab(noiseP)) {
+ mergenoise = noiseP.isTrue();
+ }
+ }
+
+ @Override
+ protected EvaluateSilhouette<O> makeInstance() {
+ return new EvaluateSilhouette<>(distance, mergenoise);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/internal/package-info.java b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/internal/package-info.java
new file mode 100644
index 00000000..952794c8
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/internal/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * Internal evaluation measures for clusterings.
+ */
+/*
+ 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.evaluation.clustering.internal; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/package-info.java b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/package-info.java
index 7dc244fd..666de5df 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/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/evaluation/clustering/pairsegments/ClusterPairSegmentAnalysis.java b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/ClusterPairSegmentAnalysis.java
index 76508563..dcd972a7 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/ClusterPairSegmentAnalysis.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/ClusterPairSegmentAnalysis.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.evaluation.clustering.pairsegments;
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/evaluation/clustering/pairsegments/Segment.java b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/Segment.java
index 76769d78..a9e2fbc9 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/Segment.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/Segment.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.clustering.pairsegments;
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/evaluation/clustering/pairsegments/Segments.java b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/Segments.java
index b7215579..ced8d726 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/Segments.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/Segments.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.clustering.pairsegments;
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/evaluation/clustering/pairsegments/package-info.java b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/package-info.java
index 01d0d09a..01d3bfa0 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/clustering/pairsegments/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/evaluation/histogram/ComputeOutlierHistogram.java b/src/de/lmu/ifi/dbs/elki/evaluation/histogram/ComputeOutlierHistogram.java
index a9c24172..be06ade2 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/histogram/ComputeOutlierHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/histogram/ComputeOutlierHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.histogram;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -226,12 +226,12 @@ public class ComputeOutlierHistogram implements Evaluator {
ids.removeDBIDs(outlierIds);
// fill histogram with values of each object
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- double result = or.getScores().get(iter);
+ double result = or.getScores().doubleValue(iter);
result = scaling.getScaled(result);
hist.putData(result, negative);
}
for(DBIDIter iter = outlierIds.iter(); iter.valid(); iter.advance()) {
- double result = or.getScores().get(iter);
+ double result = or.getScores().doubleValue(iter);
result = scaling.getScaled(result);
hist.putData(result, positive);
}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/histogram/package-info.java b/src/de/lmu/ifi/dbs/elki/evaluation/histogram/package-info.java
index a07bcc30..6daba3a0 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/histogram/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/histogram/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/evaluation/index/IndexPurity.java b/src/de/lmu/ifi/dbs/elki/evaluation/index/IndexPurity.java
index ac0f3457..7b85387e 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/index/IndexPurity.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/index/IndexPurity.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.index;
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/evaluation/index/IndexStatistics.java b/src/de/lmu/ifi/dbs/elki/evaluation/index/IndexStatistics.java
index f7c9caa8..1ad74141 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/index/IndexStatistics.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/index/IndexStatistics.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.index;
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/evaluation/index/package-info.java b/src/de/lmu/ifi/dbs/elki/evaluation/index/package-info.java
index 67fdaa98..2fdf5caf 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/index/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/index/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/evaluation/outlier/JudgeOutlierScores.java b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/JudgeOutlierScores.java
index 1639515a..ff34f7c0 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/outlier/JudgeOutlierScores.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/JudgeOutlierScores.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.outlier;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -147,12 +147,12 @@ public class JudgeOutlierScores implements Evaluator {
double negscore = 0.0;
// fill histogram with values of each object
for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- double result = or.getScores().get(iter);
+ double result = or.getScores().doubleValue(iter);
result = innerScaling.getScaled(scaling.getScaled(result));
posscore += (1.0 - result);
}
for (DBIDIter iter = outlierIds.iter(); iter.valid(); iter.advance()) {
- double result = or.getScores().get(iter);
+ double result = or.getScores().doubleValue(iter);
result = innerScaling.getScaled(scaling.getScaled(result));
negscore += result;
}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierPrecisionAtKCurve.java b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierPrecisionAtKCurve.java
index 72967d58..f876469c 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierPrecisionAtKCurve.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierPrecisionAtKCurve.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.outlier;
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/evaluation/outlier/OutlierPrecisionRecallCurve.java b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierPrecisionRecallCurve.java
index a3d9d92f..8ac9a559 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierPrecisionRecallCurve.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierPrecisionRecallCurve.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.outlier;
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,7 +31,7 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.evaluation.Evaluator;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.geometry.XYCurve;
@@ -116,7 +116,7 @@ public class OutlierPrecisionRecallCurve implements Evaluator {
}
}
- private XYCurve computePrecisionResult(int size, SetDBIDs ids, DBIDIter iter, Relation<Double> scores) {
+ private XYCurve computePrecisionResult(int size, SetDBIDs ids, DBIDIter iter, DoubleRelation scores) {
final int postot = ids.size();
int poscnt = 0, total = 0;
XYCurve curve = new PRCurve(postot + 2, postot);
@@ -140,7 +140,7 @@ public class OutlierPrecisionRecallCurve implements Evaluator {
}
// defer calculation for ties
if (scores != null) {
- double curscore = scores.get(iter);
+ double curscore = scores.doubleValue(iter);
if (Double.compare(prevscore, curscore) == 0) {
continue;
}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierROCCurve.java b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierROCCurve.java
index 0d92c50a..fc7250c1 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierROCCurve.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierROCCurve.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.outlier;
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,7 +31,10 @@ 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.evaluation.Evaluator;
-import de.lmu.ifi.dbs.elki.evaluation.roc.ROC;
+import de.lmu.ifi.dbs.elki.evaluation.scores.ROCEvaluation;
+import de.lmu.ifi.dbs.elki.evaluation.scores.adapter.DBIDsTest;
+import de.lmu.ifi.dbs.elki.evaluation.scores.adapter.OutlierScoreAdapter;
+import de.lmu.ifi.dbs.elki.evaluation.scores.adapter.SimpleAdapter;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.geometry.XYCurve;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
@@ -103,30 +106,26 @@ public class OutlierROCCurve implements Evaluator {
}
private ROCResult computeROCResult(int size, SetDBIDs positiveids, DBIDs order) {
- if (order.size() != size) {
+ if(order.size() != size) {
throw new IllegalStateException("Iterable result doesn't match database size - incomplete ordering?");
}
- XYCurve roccurve = ROC.materializeROC(new ROC.DBIDsTest(positiveids), new ROC.SimpleAdapter(order.iter()));
+ XYCurve roccurve = ROCEvaluation.materializeROC(new DBIDsTest(positiveids), new SimpleAdapter(order.iter()));
double rocauc = XYCurve.areaUnderCurve(roccurve);
- if (LOG.isVerbose()) {
+ if(LOG.isVerbose()) {
LOG.verbose(ROCAUC_LABEL + ": " + rocauc);
}
- final ROCResult rocresult = new ROCResult(roccurve, rocauc);
-
- return rocresult;
+ return new ROCResult(roccurve, rocauc);
}
private ROCResult computeROCResult(int size, SetDBIDs positiveids, OutlierResult or) {
- XYCurve roccurve = ROC.materializeROC(new ROC.DBIDsTest(positiveids), new ROC.OutlierScoreAdapter(or));
+ XYCurve roccurve = ROCEvaluation.materializeROC(new DBIDsTest(positiveids), new OutlierScoreAdapter(or));
double rocauc = XYCurve.areaUnderCurve(roccurve);
- if (LOG.isVerbose()) {
+ if(LOG.isVerbose()) {
LOG.verbose(ROCAUC_LABEL + ": " + rocauc);
}
- final ROCResult rocresult = new ROCResult(roccurve, rocauc);
-
- return rocresult;
+ return new ROCResult(roccurve, rocauc);
}
@Override
@@ -135,7 +134,7 @@ public class OutlierROCCurve implements Evaluator {
// Prepare
SetDBIDs positiveids = DBIDUtil.ensureSet(DatabaseUtil.getObjectsByLabelMatch(db, positiveClassName));
- if (positiveids.size() == 0) {
+ if(positiveids.size() == 0) {
LOG.warning("Computing a ROC curve failed - no objects matched.");
return;
}
@@ -144,7 +143,7 @@ public class OutlierROCCurve implements Evaluator {
List<OutlierResult> oresults = ResultUtil.getOutlierResults(result);
List<OrderingResult> orderings = ResultUtil.getOrderingResults(result);
// Outlier results are the main use case.
- for (OutlierResult o : oresults) {
+ for(OutlierResult o : oresults) {
db.getHierarchy().add(o, computeROCResult(o.getScores().size(), positiveids, o));
// Process them only once.
orderings.remove(o.getOrdering());
@@ -153,13 +152,13 @@ public class OutlierROCCurve implements Evaluator {
// FIXME: find appropriate place to add the derived result
// otherwise apply an ordering to the database IDs.
- for (OrderingResult or : orderings) {
+ for(OrderingResult or : orderings) {
DBIDs sorted = or.iter(or.getDBIDs());
db.getHierarchy().add(or, computeROCResult(or.getDBIDs().size(), positiveids, sorted));
nonefound = false;
}
- if (nonefound) {
+ if(nonefound) {
return;
// logger.warning("No results found to process with ROC curve analyzer. Got "+iterables.size()+" iterables, "+orderings.size()+" orderings.");
}
@@ -229,7 +228,7 @@ public class OutlierROCCurve implements Evaluator {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
PatternParameter positiveClassNameP = new PatternParameter(POSITIVE_CLASS_NAME_ID);
- if (config.grab(positiveClassNameP)) {
+ if(config.grab(positiveClassNameP)) {
positiveClassName = positiveClassNameP.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierRankingEvaluation.java b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierRankingEvaluation.java
new file mode 100644
index 00000000..f78a9790
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierRankingEvaluation.java
@@ -0,0 +1,211 @@
+package de.lmu.ifi.dbs.elki.evaluation.outlier;
+
+/*
+ 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.List;
+import java.util.regex.Pattern;
+
+import de.lmu.ifi.dbs.elki.database.Database;
+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.evaluation.Evaluator;
+import de.lmu.ifi.dbs.elki.evaluation.scores.AveragePrecisionEvaluation;
+import de.lmu.ifi.dbs.elki.evaluation.scores.MaximumF1Evaluation;
+import de.lmu.ifi.dbs.elki.evaluation.scores.PrecisionAtKEvaluation;
+import de.lmu.ifi.dbs.elki.evaluation.scores.ROCEvaluation;
+import de.lmu.ifi.dbs.elki.evaluation.scores.adapter.DBIDsTest;
+import de.lmu.ifi.dbs.elki.evaluation.scores.adapter.OutlierScoreAdapter;
+import de.lmu.ifi.dbs.elki.evaluation.scores.adapter.SimpleAdapter;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.statistics.DoubleStatistic;
+import de.lmu.ifi.dbs.elki.result.EvaluationResult;
+import de.lmu.ifi.dbs.elki.result.EvaluationResult.MeasurementGroup;
+import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
+import de.lmu.ifi.dbs.elki.result.OrderingResult;
+import de.lmu.ifi.dbs.elki.result.Result;
+import de.lmu.ifi.dbs.elki.result.ResultUtil;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
+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.PatternParameter;
+
+/**
+ * Evaluate outlier scores by their ranking
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.landmark
+ *
+ * @apiviz.uses OutlierResult
+ * @apiviz.has EvaluationResult oneway - - «create»
+ */
+public class OutlierRankingEvaluation implements Evaluator {
+ /**
+ * The logger.
+ */
+ private static final Logging LOG = Logging.getLogger(OutlierRankingEvaluation.class);
+
+ /**
+ * The pattern to identify positive classes.
+ *
+ * <p>
+ * Key: {@code -rocauc.positive}
+ * </p>
+ */
+ public static final OptionID POSITIVE_CLASS_NAME_ID = new OptionID("outliereval.positive", "Class label for the 'positive' class.");
+
+ /**
+ * Stores the "positive" class.
+ */
+ private Pattern positiveClassName;
+
+ /**
+ * Key prefix for statistics logging.
+ */
+ private String key = OutlierRankingEvaluation.class.getName();
+
+ /**
+ * Constructor.
+ *
+ * @param positive_class_name Positive class name pattern
+ */
+ public OutlierRankingEvaluation(Pattern positive_class_name) {
+ super();
+ this.positiveClassName = positive_class_name;
+ }
+
+ private EvaluationResult evaluateOutlierResult(int size, SetDBIDs positiveids, OutlierResult or) {
+ EvaluationResult res = new EvaluationResult("Evaluation of ranking", "ranking-evaluation");
+ DBIDsTest test = new DBIDsTest(positiveids);
+
+ MeasurementGroup g = res.newGroup("Evaluation measures");
+ double rocauc = ROCEvaluation.STATIC.evaluate(test, new OutlierScoreAdapter(or));
+ g.addMeasure("ROC AUC", rocauc, 0., 1. ,.5, false);
+ double avep = AveragePrecisionEvaluation.STATIC.evaluate(test, new OutlierScoreAdapter(or));
+ g.addMeasure("Average Precision", avep, 0., 1., 0., false);
+ double rprec = PrecisionAtKEvaluation.RPRECISION.evaluate(test, new OutlierScoreAdapter(or));
+ g.addMeasure("R-Precision", rprec, 0., 1., 0., false);
+ double maxf1 = MaximumF1Evaluation.STATIC.evaluate(test, new OutlierScoreAdapter(or));
+ g.addMeasure("Maximum F1", maxf1, 0., 1., 0., false);
+ if(LOG.isStatistics()) {
+ LOG.statistics(new DoubleStatistic(key + ".rocauc", rocauc));
+ LOG.statistics(new DoubleStatistic(key + ".precision.average", rocauc));
+ LOG.statistics(new DoubleStatistic(key + ".precision.r", rocauc));
+ LOG.statistics(new DoubleStatistic(key + ".f1.maximum", rocauc));
+ }
+ return res;
+ }
+
+ private EvaluationResult evaluateOrderingResult(int size, SetDBIDs positiveids, DBIDs order) {
+ if(order.size() != size) {
+ throw new IllegalStateException("Iterable result doesn't match database size - incomplete ordering?");
+ }
+
+ EvaluationResult res = new EvaluationResult("Evaluation of ranking", "ranking-evaluation");
+ DBIDsTest test = new DBIDsTest(positiveids);
+
+ MeasurementGroup g = res.newGroup("Evaluation measures");
+ double rocauc = ROCEvaluation.STATIC.evaluate(test, new SimpleAdapter(order.iter()));
+ g.addMeasure("ROC AUC", rocauc, 0., 1. ,.5, false);
+ double avep = AveragePrecisionEvaluation.STATIC.evaluate(test, new SimpleAdapter(order.iter()));
+ g.addMeasure("Average Precision", avep, 0., 1., 0., false);
+ double rprec = PrecisionAtKEvaluation.RPRECISION.evaluate(test, new SimpleAdapter(order.iter()));
+ g.addMeasure("R-Precision", rprec, 0., 1., 0., false);
+ double maxf1 = MaximumF1Evaluation.STATIC.evaluate(test, new SimpleAdapter(order.iter()));
+ g.addMeasure("Maximum F1", maxf1, 0., 1., 0., false);
+ if(LOG.isStatistics()) {
+ LOG.statistics(new DoubleStatistic(key + ".rocauc", rocauc));
+ LOG.statistics(new DoubleStatistic(key + ".precision.average", rocauc));
+ LOG.statistics(new DoubleStatistic(key + ".precision.r", rocauc));
+ LOG.statistics(new DoubleStatistic(key + ".f1.maximum", rocauc));
+ }
+ return res;
+ }
+
+ @Override
+ public void processNewResult(HierarchicalResult baseResult, Result result) {
+ Database db = ResultUtil.findDatabase(baseResult);
+ SetDBIDs positiveids = DBIDUtil.ensureSet(DatabaseUtil.getObjectsByLabelMatch(db, positiveClassName));
+
+ if(positiveids.size() == 0) {
+ LOG.warning("Cannot evaluate outlier results - no objects matched the given pattern.");
+ return;
+ }
+
+ boolean nonefound = true;
+ List<OutlierResult> oresults = ResultUtil.getOutlierResults(result);
+ List<OrderingResult> orderings = ResultUtil.getOrderingResults(result);
+ // Outlier results are the main use case.
+ for(OutlierResult o : oresults) {
+ db.getHierarchy().add(o, evaluateOutlierResult(o.getScores().size(), positiveids, o));
+ // Process them only once.
+ orderings.remove(o.getOrdering());
+ nonefound = false;
+ }
+
+ // FIXME: find appropriate place to add the derived result
+ // otherwise apply an ordering to the database IDs.
+ for(OrderingResult or : orderings) {
+ DBIDs sorted = or.iter(or.getDBIDs());
+ db.getHierarchy().add(or, evaluateOrderingResult(or.getDBIDs().size(), positiveids, sorted));
+ nonefound = false;
+ }
+
+ if(nonefound) {
+ return;
+ // logger.warning("No results found to process with ROC curve analyzer. Got "+iterables.size()+" iterables, "+orderings.size()+" orderings.");
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Pattern for positive class.
+ */
+ protected Pattern positiveClassName = null;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ PatternParameter positiveClassNameP = new PatternParameter(POSITIVE_CLASS_NAME_ID);
+ if(config.grab(positiveClassNameP)) {
+ positiveClassName = positiveClassNameP.getValue();
+ }
+ }
+
+ @Override
+ protected OutlierRankingEvaluation makeInstance() {
+ return new OutlierRankingEvaluation(positiveClassName);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierSmROCCurve.java b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierSmROCCurve.java
index 71ec42f5..3400a4bf 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierSmROCCurve.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierSmROCCurve.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.outlier;
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,7 +30,7 @@ import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.SetDBIDs;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.evaluation.Evaluator;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.geometry.XYCurve;
@@ -60,20 +60,21 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.PatternParameter;
* However, this method has some deficiencies when the mean score is not 0.5, as
* discussed in:
* <p>
- * E. Schubert, R. Wojdanowski, A. Zimek, H.-P. Kriegel<br>
- * On Evaluation of Outlier Rankings and Outlier Scores<br>
+ * E. Schubert, R. Wojdanowski, A. Zimek, H.-P. Kriegel<br />
+ * On Evaluation of Outlier Rankings and Outlier Scores<br />
* In Proceedings of the 12th SIAM International Conference on Data Mining
* (SDM), Anaheim, CA, 2012.
* </p>
*
* @author Erich Schubert
*
- * @apiviz.landmark
- *
* @apiviz.uses OutlierResult
* @apiviz.has SmROCResult oneway - - «create»
*/
-@Reference(authors = "W. Klement, P. A. Flach, N. Japkowicz, S. Matwin", title = "Smooth Receiver Operating Characteristics (smROC) Curves", booktitle = "In: European Conference on Machine Learning and Principles and Practice of Knowledge Discovery in Databases (ECML-PKDD'11)", url = "http://dx.doi.org/10.1007/978-3-642-23783-6_13")
+@Reference(authors = "W. Klement, P. A. Flach, N. Japkowicz, S. Matwin", //
+title = "Smooth Receiver Operating Characteristics (smROC) Curves", //
+booktitle = "In: European Conference on Machine Learning and Principles and Practice of Knowledge Discovery in Databases (ECML-PKDD'11)", //
+url = "http://dx.doi.org/10.1007/978-3-642-23783-6_13")
public class OutlierSmROCCurve implements Evaluator {
/**
* The label we use for marking ROCAUC values.
@@ -101,13 +102,13 @@ public class OutlierSmROCCurve implements Evaluator {
}
private SmROCResult computeSmROCResult(SetDBIDs positiveids, OutlierResult or) {
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
final int size = scores.size();
// Compute mean, for inversion
double mean = 0.0;
for(DBIDIter iditer = scores.iterDBIDs(); iditer.valid(); iditer.advance()) {
- mean += scores.get(iditer) / size;
+ mean += scores.doubleValue(iditer) / size;
}
SmROCResult curve = new SmROCResult(positiveids.size() + 2);
@@ -118,9 +119,9 @@ public class OutlierSmROCCurve implements Evaluator {
int poscnt = 0, negcnt = 0;
double prevscore = Double.NaN;
double x = 0, y = 0;
- for (DBIDIter nei = or.getOrdering().iter(or.getOrdering().getDBIDs()).iter(); nei.valid(); nei.advance()) {
+ for(DBIDIter nei = or.getOrdering().iter(or.getOrdering().getDBIDs()).iter(); nei.valid(); nei.advance()) {
// Analyze next point
- final double curscore = scores.get(nei);
+ final double curscore = scores.doubleValue(nei);
// defer calculation for ties
if(!Double.isNaN(prevscore) && (Double.compare(prevscore, curscore) == 0)) {
// positive or negative match?
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierThresholdClustering.java b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierThresholdClustering.java
index 04233378..5591df3f 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierThresholdClustering.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/OutlierThresholdClustering.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.evaluation.outlier;
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,7 +32,7 @@ import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.evaluation.Evaluator;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
@@ -88,7 +88,7 @@ public class OutlierThresholdClustering implements Evaluator {
}
private Clustering<Model> split(OutlierResult or) {
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
if(scaling instanceof OutlierScalingFunction) {
((OutlierScalingFunction) scaling).prepare(or);
}
@@ -97,7 +97,7 @@ public class OutlierThresholdClustering implements Evaluator {
idlists.add(DBIDUtil.newHashSet());
}
for(DBIDIter iter = scores.getDBIDs().iter(); iter.valid(); iter.advance()) {
- double score = scores.get(iter);
+ double score = scores.doubleValue(iter);
if(scaling != null) {
score = scaling.getScaled(score);
}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/outlier/package-info.java b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/package-info.java
index 1e5e6933..81cf2248 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/outlier/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/outlier/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/evaluation/package-info.java b/src/de/lmu/ifi/dbs/elki/evaluation/package-info.java
index 8b8a96dc..54755c75 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/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/evaluation/roc/ROC.java b/src/de/lmu/ifi/dbs/elki/evaluation/roc/ROC.java
deleted file mode 100644
index 0ca42b29..00000000
--- a/src/de/lmu/ifi/dbs/elki/evaluation/roc/ROC.java
+++ /dev/null
@@ -1,656 +0,0 @@
-package de.lmu.ifi.dbs.elki.evaluation.roc;
-
-/*
- 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.Cluster;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-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.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.math.geometry.XYCurve;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerArrayQuickSort;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerComparator;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.ArrayIter;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter;
-
-/**
- * Compute ROC (Receiver Operating Characteristics) curves.
- *
- * A ROC curve compares the true positive rate (y-axis) and false positive rate
- * (x-axis).
- *
- * It was first used in radio signal detection, but has since found widespread
- * use in information retrieval, in particular for evaluating binary
- * classification problems.
- *
- * ROC curves are particularly useful to evaluate a ranking of objects with
- * respect to a binary classification problem: a random sampling will
- * approximately achieve a ROC value of 0.5, while a perfect separation will
- * achieve 1.0 (all positives first) or 0.0 (all negatives first). In most use
- * cases, a score significantly below 0.5 indicates that the algorithm result
- * has been used the wrong way, and should be used backwards.
- *
- * @author Erich Schubert
- *
- * @apiviz.composedOf ScoreIter
- * @apiviz.composedOf Predicate
- * @apiviz.has XYCurve
- */
-public class ROC {
- /**
- * Iterator for comparing scores.
- *
- * @author Erich Schubert
- */
- public static interface ScoreIter extends Iter {
- /**
- * Test whether the score is the same as the previous objects score.
- *
- * When there is no previous result, implementations should return false!
- *
- * @return Boolean
- */
- boolean tiedToPrevious();
- }
-
- /**
- * Predicate to test whether an object is a true positive or false positive.
- *
- * @author Erich Schubert
- *
- * @param <T> Data type
- */
- public static interface Predicate<T> {
- boolean test(T o);
- }
-
- /**
- * Compute a ROC curve given a set of positive IDs and a sorted list of
- * (comparable, ID)s, where the comparable object is used to decided when two
- * objects are interchangeable.
- *
- * @param <I> Iterator type
- * @param predicate Predicate to test for positive objects
- * @param iter Iterator over results, with ties.
- * @return area under curve
- */
- public static <I extends ScoreIter> XYCurve materializeROC(Predicate<? super I> predicate, I iter) {
- int poscnt = 0, negcnt = 0;
- XYCurve curve = new XYCurve("False Positive Rate", "True Positive Rate");
-
- // start in bottom left
- curve.add(0.0, 0.0);
-
- while (iter.valid()) {
- // positive or negative match?
- do {
- if (predicate.test(iter)) {
- ++poscnt;
- } else {
- ++negcnt;
- }
- iter.advance();
- } // Loop while tied:
- while (iter.valid() && iter.tiedToPrevious());
- // Add a new point.
- curve.addAndSimplify(negcnt, poscnt);
- }
- // Ensure we end up in the top right corner.
- // Simplification will skip this if we already were.
- curve.addAndSimplify(negcnt, poscnt);
- curve.rescale(1. / negcnt, 1. / poscnt);
- return curve;
- }
-
- /**
- * This adapter can be used for an arbitrary collection of Integers, and uses
- * that id1.compareTo(id2) != 0 for id1 != id2 to satisfy the comparability.
- *
- * Note that of course, no id should occur more than once.
- *
- * The ROC values would be incorrect then anyway!
- *
- * @author Erich Schubert
- *
- * @apiviz.composedOf DBIDIter
- */
- public static class SimpleAdapter implements ScoreIter, DBIDRef {
- /**
- * Original Iterator
- */
- private DBIDIter iter;
-
- /**
- * Constructor
- *
- * @param iter Iterator for object IDs
- */
- public SimpleAdapter(DBIDIter iter) {
- super();
- this.iter = iter;
- }
-
- @Override
- public boolean valid() {
- return iter.valid();
- }
-
- @Override
- public void advance() {
- iter.advance();
- }
-
- @Override
- public boolean tiedToPrevious() {
- return false; // No information.
- }
-
- @Override
- public int internalGetIndex() {
- return iter.internalGetIndex();
- }
-
- @Deprecated
- @Override
- public int hashCode() {
- return super.hashCode();
- }
-
- @Deprecated
- @Override
- public boolean equals(Object obj) {
- return super.equals(obj);
- }
- }
-
- /**
- * This adapter can be used for an arbitrary collection of Integers, and uses
- * that id1.compareTo(id2) != 0 for id1 != id2 to satisfy the comparability.
- *
- * Note that of course, no id should occur more than once.
- *
- * The ROC values would be incorrect then anyway!
- *
- * @author Erich Schubert
- *
- * @apiviz.composedOf DistanceDBIDListIter
- *
- * @param <D> Distance type
- */
- public static class DistanceResultAdapter<D extends Distance<D>> implements ScoreIter, DBIDRef {
- /**
- * Original Iterator
- */
- private DistanceDBIDListIter<D> iter;
-
- /**
- * Distance of previous.
- */
- private D prevDist = null;
-
- /**
- * Constructor
- *
- * @param iter Iterator for distance results
- */
- public DistanceResultAdapter(DistanceDBIDListIter<D> iter) {
- super();
- this.iter = iter;
- }
-
- @Override
- public boolean valid() {
- return iter.valid();
- }
-
- @Override
- public void advance() {
- prevDist = iter.getDistance();
- iter.advance();
- }
-
- @Override
- public int internalGetIndex() {
- return iter.internalGetIndex();
- }
-
- @Override
- public boolean tiedToPrevious() {
- return iter.getDistance().equals(prevDist);
- }
-
- @Deprecated
- @Override
- public int hashCode() {
- return super.hashCode();
- }
-
- @Deprecated
- @Override
- public boolean equals(Object obj) {
- return super.equals(obj);
- }
- }
-
- /**
- * This adapter can be used for an arbitrary collection of Integers, and uses
- * that id1.compareTo(id2) != 0 for id1 != id2 to satisfy the comparability.
- *
- * Note that of course, no id should occur more than once.
- *
- * The ROC values would be incorrect then anyway!
- *
- * @author Erich Schubert
- *
- * @apiviz.composedOf OutlierResult
- */
- public static class OutlierScoreAdapter implements ScoreIter, DBIDRef {
- /**
- * Original iterator.
- */
- private DBIDIter iter;
-
- /**
- * Outlier score.
- */
- private Relation<Double> scores;
-
- /**
- * Previous value.
- */
- double prev = Double.NaN;
-
- /**
- * Constructor.
- *
- * @param o Result
- */
- public OutlierScoreAdapter(OutlierResult o) {
- super();
- this.iter = o.getOrdering().iter(o.getScores().getDBIDs()).iter();
- this.scores = o.getScores();
- }
-
- @Override
- public boolean valid() {
- return iter.valid();
- }
-
- @Override
- public void advance() {
- prev = scores.get(iter);
- iter.advance();
- }
-
- @Override
- public boolean tiedToPrevious() {
- return scores.get(iter) == prev;
- }
-
- @Override
- public int internalGetIndex() {
- return iter.internalGetIndex();
- }
-
- @Deprecated
- @Override
- public int hashCode() {
- return super.hashCode();
- }
-
- @Deprecated
- @Override
- public boolean equals(Object obj) {
- return super.equals(obj);
- }
- }
-
- /**
- * Class to iterate over a number vector in decreasing order.
- *
- * @author Erich Schubert
- *
- * @apiviz.composedOf NumberVector
- */
- public static class DecreasingVectorIter implements ScoreIter, IntegerComparator, ArrayIter {
- /**
- * Order of dimensions.
- */
- private int[] sort;
-
- /**
- * Data vector.
- */
- private NumberVector<?> vec;
-
- /**
- * Current position.
- */
- int pos = 0;
-
- /**
- * Constructor.
- *
- * @param vec Vector to iterate over.
- */
- public DecreasingVectorIter(NumberVector<?> vec) {
- this.vec = vec;
- final int dim = vec.getDimensionality();
- this.sort = new int[dim];
- for (int d = 0; d < dim; d++) {
- sort[d] = d;
- }
- IntegerArrayQuickSort.sort(sort, this);
- }
-
- @Override
- public int compare(int x, int y) {
- return Double.compare(vec.doubleValue(y), vec.doubleValue(x));
- }
-
- public int dim() {
- return sort[pos];
- }
-
- @Override
- public boolean valid() {
- return pos < vec.getDimensionality();
- }
-
- @Override
- public void advance() {
- ++pos;
- }
-
- @Override
- public boolean tiedToPrevious() {
- return pos > 0 && Double.compare(vec.doubleValue(sort[pos]), vec.doubleValue(sort[pos - 1])) == 0;
- }
-
- @Override
- public int getOffset() {
- return pos;
- }
-
- @Override
- public void advance(int count) {
- pos += count;
- }
-
- @Override
- public void retract() {
- pos--;
- }
-
- @Override
- public void seek(int off) {
- pos = off;
- }
- }
-
- /**
- * Class to iterate over a number vector in decreasing order.
- *
- * @author Erich Schubert
- *
- * @apiviz.composedOf NumberVector
- */
- public static class IncreasingVectorIter implements ScoreIter, IntegerComparator, ArrayIter {
- /**
- * Order of dimensions.
- */
- private int[] sort;
-
- /**
- * Data vector.
- */
- private NumberVector<?> vec;
-
- /**
- * Current position.
- */
- int pos = 0;
-
- /**
- * Constructor.
- *
- * @param vec Vector to iterate over.
- */
- public IncreasingVectorIter(NumberVector<?> vec) {
- this.vec = vec;
- final int dim = vec.getDimensionality();
- this.sort = new int[dim];
- for (int d = 0; d < dim; d++) {
- sort[d] = d;
- }
- IntegerArrayQuickSort.sort(sort, this);
- }
-
- @Override
- public int compare(int x, int y) {
- return Double.compare(vec.doubleValue(x), vec.doubleValue(y));
- }
-
- public int dim() {
- return sort[pos];
- }
-
- @Override
- public boolean valid() {
- return pos < vec.getDimensionality();
- }
-
- @Override
- public void advance() {
- ++pos;
- }
-
- @Override
- public boolean tiedToPrevious() {
- return pos > 0 && Double.compare(vec.doubleValue(sort[pos]), vec.doubleValue(sort[pos - 1])) == 0;
- }
-
- @Override
- public int getOffset() {
- return pos;
- }
-
- @Override
- public void advance(int count) {
- pos += count;
- }
-
- @Override
- public void retract() {
- pos--;
- }
-
- @Override
- public void seek(int off) {
- pos = off;
- }
- }
-
- /**
- * Class that uses a NumberVector as reference, and considers all non-zero
- * values as positive entries.
- *
- * @apiviz.composedOf NumberVector
- *
- * @author Erich Schubert
- */
- public static class VectorNonZero extends VectorOverThreshold {
- /**
- * Constructor.
- *
- * @param vec Reference vector.
- */
- public VectorNonZero(NumberVector<?> vec) {
- super(vec, 0.);
- }
- }
-
- /**
- * Class that uses a NumberVector as reference, and considers all non-zero
- * values as positive entries.
- *
- * @apiviz.composedOf NumberVector
- *
- * @author Erich Schubert
- */
- public static class VectorOverThreshold implements Predicate<DecreasingVectorIter> {
- /**
- * Vector to use as reference
- */
- NumberVector<?> vec;
-
- /**
- * Threshold
- */
- double threshold;
-
- /**
- * Constructor.
- *
- * @param vec Reference vector.
- * @param threshold Threshold value.
- */
- public VectorOverThreshold(NumberVector<?> vec, double threshold) {
- super();
- this.vec = vec;
- this.threshold = threshold;
- }
-
- @Override
- public boolean test(DecreasingVectorIter o) {
- return Math.abs(vec.doubleValue(o.dim())) > threshold;
- }
- }
-
- /**
- * Class that uses a NumberVector as reference, and considers all zero values
- * as positive entries.
- *
- * @apiviz.composedOf NumberVector
- *
- * @author Erich Schubert
- */
- public static class VectorZero implements Predicate<IncreasingVectorIter> {
- /**
- * Vector to use as reference
- */
- NumberVector<?> vec;
-
- /**
- * Constructor.
- *
- * @param vec Reference vector.
- */
- public VectorZero(NumberVector<?> vec) {
- this.vec = vec;
- }
-
- @Override
- public boolean test(IncreasingVectorIter o) {
- return Math.abs(vec.doubleValue(o.dim())) < Double.MIN_NORMAL;
- }
- }
-
- /**
- * Test predicate using a DBID set as positive elements.
- *
- * @apiviz.composedOf DBIDs
- *
- * @author Erich Schubert
- */
- public static class DBIDsTest implements Predicate<DBIDRef> {
- /**
- * DBID set.
- */
- private DBIDs set;
-
- /**
- * Constructor.
- *
- * @param set Set of positive objects
- */
- public DBIDsTest(DBIDs set) {
- this.set = set;
- }
-
- @Override
- public boolean test(DBIDRef o) {
- return set.contains(o);
- }
- }
-
- /**
- * Compute a ROC curves Area-under-curve for a QueryResult and a Cluster.
- *
- * @param <D> Distance type
- * @param size Database size
- * @param clus Cluster object
- * @param nei Query result
- * @return area under curve
- */
- public static <D extends Distance<D>> double computeROCAUCDistanceResult(int size, Cluster<?> clus, DistanceDBIDList<D> nei) {
- // TODO: ensure the collection has efficient "contains".
- return ROC.computeROCAUCDistanceResult(size, clus.getIDs(), nei);
- }
-
- /**
- * Compute a ROC curves Area-under-curve for a QueryResult and a Cluster.
- *
- * @param <D> Distance type
- * @param size Database size
- * @param ids Collection of positive IDs, should support efficient contains()
- * @param nei Query Result
- * @return area under curve
- */
- public static <D extends Distance<D>> double computeROCAUCDistanceResult(int size, DBIDs ids, DistanceDBIDList<D> nei) {
- // TODO: do not materialize the ROC, but introduce an iterator interface
- XYCurve roc = materializeROC(new DBIDsTest(DBIDUtil.ensureSet(ids)), new DistanceResultAdapter<>(nei.iter()));
- return XYCurve.areaUnderCurve(roc);
- }
-
- /**
- * Compute a ROC curves Area-under-curve for a QueryResult and a Cluster.
- *
- * @param size Database size
- * @param ids Collection of positive IDs, should support efficient contains()
- * @param nei Query Result
- * @return area under curve
- */
- public static double computeROCAUCSimple(int size, DBIDs ids, DBIDs nei) {
- // TODO: do not materialize the ROC, but introduce an iterator interface
- XYCurve roc = materializeROC(new DBIDsTest(DBIDUtil.ensureSet(ids)), new SimpleAdapter(nei.iter()));
- return XYCurve.areaUnderCurve(roc);
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/roc/package-info.java b/src/de/lmu/ifi/dbs/elki/evaluation/roc/package-info.java
deleted file mode 100644
index c6934ba2..00000000
--- a/src/de/lmu/ifi/dbs/elki/evaluation/roc/package-info.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * <p>Evaluation of rankings using ROC AUC (Receiver Operation Characteristics - Area Under Curve)</p>
- *
- * @apiviz.exclude java.util.*
- */
-/*
-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.evaluation.roc; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/AbstractScoreEvaluation.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/AbstractScoreEvaluation.java
new file mode 100644
index 00000000..43de7ebd
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/AbstractScoreEvaluation.java
@@ -0,0 +1,55 @@
+package de.lmu.ifi.dbs.elki.evaluation.scores;
+
+/*
+ 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.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.evaluation.scores.adapter.DBIDsTest;
+import de.lmu.ifi.dbs.elki.evaluation.scores.adapter.DistanceResultAdapter;
+import de.lmu.ifi.dbs.elki.evaluation.scores.adapter.OutlierScoreAdapter;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+
+/**
+ * Abstract base class for evaluating a scoring result.
+ *
+ * @author Erich Schubert
+ */
+public abstract class AbstractScoreEvaluation implements ScoreEvaluation {
+ @Override
+ public double evaluate(Cluster<?> clus, DoubleDBIDList nei) {
+ return evaluate(new DBIDsTest(DBIDUtil.ensureSet(clus.getIDs())), new DistanceResultAdapter(nei.iter()));
+ }
+
+ @Override
+ public double evaluate(DBIDs ids, DoubleDBIDList nei) {
+ return evaluate(new DBIDsTest(DBIDUtil.ensureSet(ids)), new DistanceResultAdapter(nei.iter()));
+ }
+
+ @Override
+ public double evaluate(DBIDs ids, OutlierResult outlier) {
+ return evaluate(new DBIDsTest(DBIDUtil.ensureSet(ids)), new OutlierScoreAdapter(outlier));
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/AveragePrecisionEvaluation.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/AveragePrecisionEvaluation.java
new file mode 100644
index 00000000..bc3d1522
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/AveragePrecisionEvaluation.java
@@ -0,0 +1,76 @@
+package de.lmu.ifi.dbs.elki.evaluation.scores;
+/*
+ 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.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Evaluate using average precision.
+ *
+ * @author Erich Schubert
+ */
+public class AveragePrecisionEvaluation extends AbstractScoreEvaluation {
+ /**
+ * Static instance
+ */
+ public static final AveragePrecisionEvaluation STATIC = new AveragePrecisionEvaluation();
+
+ @Override
+ public <I extends ScoreIter> double evaluate(Predicate<? super I> predicate, I iter) {
+ int poscnt = 0, negcnt = 0, pospre = 0;
+ double acc = 0.;
+ while(iter.valid()) {
+ // positive or negative match?
+ do {
+ if(predicate.test(iter)) {
+ ++poscnt;
+ }
+ else {
+ ++negcnt;
+ }
+ iter.advance();
+ } // Loop while tied:
+ while(iter.valid() && iter.tiedToPrevious());
+ // Add a new point.
+ if(poscnt > pospre) {
+ acc += (poscnt / (double) (poscnt + negcnt)) * (poscnt - pospre);
+ pospre = poscnt;
+ }
+ }
+ return (poscnt > 0) ? acc / poscnt : 0.;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected AveragePrecisionEvaluation makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/MaximumF1Evaluation.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/MaximumF1Evaluation.java
new file mode 100644
index 00000000..bac59b45
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/MaximumF1Evaluation.java
@@ -0,0 +1,76 @@
+package de.lmu.ifi.dbs.elki.evaluation.scores;
+/*
+ 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.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Evaluate using the maximum F1 score.
+ *
+ * @author Erich Schubert
+ */
+public class MaximumF1Evaluation extends AbstractScoreEvaluation {
+ /**
+ * Static instance
+ */
+ public static final MaximumF1Evaluation STATIC = new MaximumF1Evaluation();
+
+ @Override
+ public <I extends ScoreIter> double evaluate(Predicate<? super I> predicate, I iter) {
+ final int postot = predicate.numPositive();
+ int poscnt = 0, cnt = 0;
+ double maxf1 = 0.;
+ while(iter.valid()) {
+ // positive or negative match?
+ do {
+ if(predicate.test(iter)) {
+ ++poscnt;
+ }
+ ++cnt;
+ iter.advance();
+ } // Loop while tied:
+ while(iter.valid() && iter.tiedToPrevious());
+ // New F1 value:
+ double p = poscnt / (double) cnt, r = poscnt / (double) postot;
+ double f1 = 2. * p * r / (p + r);
+ if(f1 > maxf1) {
+ maxf1 = f1;
+ }
+ }
+ return maxf1;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected MaximumF1Evaluation makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/PrecisionAtKEvaluation.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/PrecisionAtKEvaluation.java
new file mode 100644
index 00000000..97ab0abd
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/PrecisionAtKEvaluation.java
@@ -0,0 +1,127 @@
+package de.lmu.ifi.dbs.elki.evaluation.scores;
+/*
+ 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.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;
+
+/**
+ * Evaluate using Precision@k, or R-precision (when {@code k=0}).
+ *
+ * When {@code k=0}, then it is set to the number of positive objects, and the
+ * returned value is the R-precision, or the precision-recall break-even-point
+ * (BEP).
+ *
+ * @author Erich Schubert
+ */
+public class PrecisionAtKEvaluation extends AbstractScoreEvaluation {
+ /**
+ * Static instance
+ */
+ public static final PrecisionAtKEvaluation RPRECISION = new PrecisionAtKEvaluation(0);
+
+ /**
+ * Parameter k.
+ */
+ int k;
+
+ /**
+ * Constructor.
+ *
+ * @param k k to evaluate at. May be 0.
+ */
+ public PrecisionAtKEvaluation(int k) {
+ this.k = k;
+ }
+
+ @Override
+ public <I extends ScoreIter> double evaluate(Predicate<? super I> predicate, I iter) {
+ final int k = (this.k > 0) ? this.k : predicate.numPositive();
+ int total = 0;
+ double score = 0.;
+ while(iter.valid() && total < k) {
+ int posthis = 0, cntthis = 0;
+ // positive or negative match?
+ do {
+ if(predicate.test(iter)) {
+ ++posthis;
+ }
+ ++cntthis;
+ iter.advance();
+ } // Loop while tied:
+ while(iter.valid() && iter.tiedToPrevious());
+ // Special tie computations only when we reach k.
+ if(total + cntthis > k) {
+ // p = posthis / cntthis chance of being positive
+ // n = (k-total) draws.
+ // expected value = n * p
+ score += posthis / (double) cntthis * (k - total);
+ total = k;
+ break;
+ }
+ score += posthis;
+ total += cntthis;
+ }
+ return score / total;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Option ID for the k parameter.
+ */
+ public static final OptionID K_ID = new OptionID("precision.k", //
+ "k value for precision@k. Can be set to 0, to get R-precision, or the precision-recall-break-even-point.");
+
+ /**
+ * K parameter
+ */
+ int k;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ IntParameter kP = new IntParameter(K_ID) //
+ .setDefaultValue(0) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_INT);
+ if(config.grab(kP)) {
+ k = kP.intValue();
+ }
+ }
+
+ @Override
+ protected PrecisionAtKEvaluation makeInstance() {
+ return k > 0 ? new PrecisionAtKEvaluation(k) : RPRECISION;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/ROCEvaluation.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/ROCEvaluation.java
new file mode 100644
index 00000000..1a74d25a
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/ROCEvaluation.java
@@ -0,0 +1,147 @@
+package de.lmu.ifi.dbs.elki.evaluation.scores;
+
+/*
+ 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.math.geometry.XYCurve;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Compute ROC (Receiver Operating Characteristics) curves.
+ *
+ * A ROC curve compares the true positive rate (y-axis) and false positive rate
+ * (x-axis).
+ *
+ * It was first used in radio signal detection, but has since found widespread
+ * use in information retrieval, in particular for evaluating binary
+ * classification problems.
+ *
+ * ROC curves are particularly useful to evaluate a ranking of objects with
+ * respect to a binary classification problem: a random sampling will
+ * approximately achieve a ROC value of 0.5, while a perfect separation will
+ * achieve 1.0 (all positives first) or 0.0 (all negatives first). In most use
+ * cases, a score significantly below 0.5 indicates that the algorithm result
+ * has been used the wrong way, and should be used backwards.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has XYCurve
+ */
+public class ROCEvaluation extends AbstractScoreEvaluation {
+ /**
+ * Static instance
+ */
+ public static final ROCEvaluation STATIC = new ROCEvaluation();
+
+ @Override
+ public <I extends ScoreIter> double evaluate(Predicate<? super I> predicate, I iter) {
+ return computeROCAUC(predicate, iter);
+ }
+
+ /**
+ * Compute a ROC curve given a set of positive IDs and a sorted list of
+ * (comparable, ID)s, where the comparable object is used to decided when two
+ * objects are interchangeable.
+ *
+ * @param <I> Iterator type
+ * @param predicate Predicate to test for positive objects
+ * @param iter Iterator over results, with ties.
+ * @return area under curve
+ */
+ public static <I extends ScoreIter> XYCurve materializeROC(Predicate<? super I> predicate, I iter) {
+ int poscnt = 0, negcnt = 0;
+ XYCurve curve = new XYCurve("False Positive Rate", "True Positive Rate");
+
+ // start in bottom left
+ curve.add(0.0, 0.0);
+
+ while(iter.valid()) {
+ // positive or negative match?
+ do {
+ if(predicate.test(iter)) {
+ ++poscnt;
+ }
+ else {
+ ++negcnt;
+ }
+ iter.advance();
+ } // Loop while tied:
+ while(iter.valid() && iter.tiedToPrevious());
+ // Add a new point.
+ curve.addAndSimplify(negcnt, poscnt);
+ }
+ // Ensure we end up in the top right corner.
+ // Simplification will skip this if we already were.
+ curve.addAndSimplify(negcnt, poscnt);
+ curve.rescale(1. / negcnt, 1. / poscnt);
+ return curve;
+ }
+
+ /**
+ * Compute the area under the ROC curve given a set of positive IDs and a
+ * sorted list of (comparable, ID)s, where the comparable object is used to
+ * decided when two objects are interchangeable.
+ *
+ * @param <I> Iterator type
+ * @param predicate Predicate to test for positive objects
+ * @param iter Iterator over results, with ties.
+ * @return area under curve
+ */
+ public static <I extends ScoreIter> double computeROCAUC(Predicate<? super I> predicate, I iter) {
+ int poscnt = 0, negcnt = 0, pospre = 0, negpre = 0;
+ double acc = 0.;
+ while(iter.valid()) {
+ // positive or negative match?
+ do {
+ if(predicate.test(iter)) {
+ ++poscnt;
+ }
+ else {
+ ++negcnt;
+ }
+ iter.advance();
+ } // Loop while tied:
+ while(iter.valid() && iter.tiedToPrevious());
+ if(negcnt > negpre) {
+ acc += (poscnt + pospre) * .5 * (negcnt - negpre);
+ negpre = negcnt;
+ }
+ pospre = poscnt;
+ }
+ acc /= negcnt * (long) poscnt;
+ return acc == acc ? acc : 0.5; /* Detect NaN */
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected ROCEvaluation makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/ScoreEvaluation.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/ScoreEvaluation.java
new file mode 100644
index 00000000..d32714ad
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/ScoreEvaluation.java
@@ -0,0 +1,114 @@
+package de.lmu.ifi.dbs.elki.evaluation.scores;
+
+/*
+ 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.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter;
+
+/**
+ * Compute ranking/scoring based evaluation measures.
+ *
+ * @author Erich Schubert
+ */
+public interface ScoreEvaluation {
+ /**
+ * Evaluate a given predicate and iterator.
+ *
+ * @param predicate Predicate (for positives)
+ * @param iter Iterator
+ * @return Score
+ * @param <I> Iterator type
+ */
+ <I extends ScoreIter> double evaluate(Predicate<? super I> predicate, I iter);
+
+ /**
+ * Evaluate given a cluster (of positive elements) and a scoring list.
+ *
+ * @param clus Cluster object
+ * @param nei Query result
+ * @return Score
+ */
+ double evaluate(Cluster<?> clus, DoubleDBIDList nei);
+
+ /**
+ * Evaluate given a list of positives and a scoring.
+ *
+ * @param ids Positive IDs, usually a set.
+ * @param nei Query Result
+ * @return Score
+ */
+ double evaluate(DBIDs ids, DoubleDBIDList nei);
+
+ /**
+ * Evaluate given a set of positives and a scoring.
+ *
+ * @param ids Positive IDs, usually a set.
+ * @param outlier Outlier detection result
+ * @return Score
+ */
+ double evaluate(DBIDs ids, OutlierResult outlier);
+
+ /**
+ * Iterator for comparing scores.
+ *
+ * @author Erich Schubert
+ */
+ public static interface ScoreIter extends Iter {
+ /**
+ * Test whether the score is the same as the previous objects score.
+ *
+ * When there is no previous result, implementations should return false!
+ *
+ * @return Boolean
+ */
+ boolean tiedToPrevious();
+ }
+
+ /**
+ * Predicate to test whether an object is a true positive or false positive.
+ *
+ * @author Erich Schubert
+ *
+ * @param <T> Data type
+ */
+ public static interface Predicate<T> {
+ /**
+ * Test a result.
+ *
+ * @param o Object to test
+ * @return {@code true} when positive.
+ */
+ boolean test(T o);
+
+ /**
+ * Return the number of positive ids.
+ *
+ * @return Number of positive elements
+ */
+ int numPositive();
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DBIDRefIter.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DBIDRefIter.java
new file mode 100644
index 00000000..2fdb5978
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DBIDRefIter.java
@@ -0,0 +1,39 @@
+package de.lmu.ifi.dbs.elki.evaluation.scores.adapter;
+
+/*
+ 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.database.ids.DBIDRef;
+
+/**
+ * A score iterator wrapping a DBIDRef object.
+ *
+ * @author Erich Schubert
+ */
+public interface DBIDRefIter {
+ /**
+ * Get the current DBIDRef.
+ *
+ * @return DBID reference
+ */
+ DBIDRef getRef();
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DBIDsTest.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DBIDsTest.java
new file mode 100644
index 00000000..d41c7af4
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DBIDsTest.java
@@ -0,0 +1,59 @@
+package de.lmu.ifi.dbs.elki.evaluation.scores.adapter;
+/*
+ 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.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.evaluation.scores.ScoreEvaluation.Predicate;
+
+/**
+ * Test predicate using a DBID set as positive elements.
+ *
+ * @apiviz.composedOf DBIDs
+ *
+ * @author Erich Schubert
+ */
+public class DBIDsTest implements Predicate<DBIDRefIter> {
+ /**
+ * DBID set.
+ */
+ private DBIDs set;
+
+ /**
+ * Constructor.
+ *
+ * @param set Set of positive objects
+ */
+ public DBIDsTest(DBIDs set) {
+ this.set = set;
+ }
+
+ @Override
+ public boolean test(DBIDRefIter o) {
+ return set.contains(o.getRef());
+ }
+
+ @Override
+ public int numPositive() {
+ return set.size();
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DecreasingVectorIter.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DecreasingVectorIter.java
new file mode 100644
index 00000000..d0a55b19
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DecreasingVectorIter.java
@@ -0,0 +1,116 @@
+package de.lmu.ifi.dbs.elki.evaluation.scores.adapter;
+
+/*
+ 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.evaluation.scores.ScoreEvaluation.ScoreIter;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerArrayQuickSort;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerComparator;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.ArrayIter;
+
+/**
+ * Class to iterate over a number vector in decreasing order.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.composedOf NumberVector
+ */
+public class DecreasingVectorIter implements ScoreIter, IntegerComparator, ArrayIter {
+ /**
+ * Order of dimensions.
+ */
+ private int[] sort;
+
+ /**
+ * Data vector.
+ */
+ private NumberVector vec;
+
+ /**
+ * Current position.
+ */
+ int pos = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param vec Vector to iterate over.
+ */
+ public DecreasingVectorIter(NumberVector vec) {
+ this.vec = vec;
+ final int dim = vec.getDimensionality();
+ this.sort = new int[dim];
+ for(int d = 0; d < dim; d++) {
+ sort[d] = d;
+ }
+ IntegerArrayQuickSort.sort(sort, this);
+ }
+
+ @Override
+ public int compare(int x, int y) {
+ return Double.compare(vec.doubleValue(y), vec.doubleValue(x));
+ }
+
+ public int dim() {
+ return sort[pos];
+ }
+
+ @Override
+ public boolean valid() {
+ return pos < vec.getDimensionality() && pos >= 0;
+ }
+
+ @Override
+ public DecreasingVectorIter advance() {
+ ++pos;
+ return this;
+ }
+
+ @Override
+ public boolean tiedToPrevious() {
+ return pos > 0 && Double.compare(vec.doubleValue(sort[pos]), vec.doubleValue(sort[pos - 1])) == 0;
+ }
+
+ @Override
+ public int getOffset() {
+ return pos;
+ }
+
+ @Override
+ public DecreasingVectorIter advance(int count) {
+ pos += count;
+ return this;
+ }
+
+ @Override
+ public DecreasingVectorIter retract() {
+ pos--;
+ return this;
+ }
+
+ @Override
+ public DecreasingVectorIter seek(int off) {
+ pos = off;
+ return this;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DistanceResultAdapter.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DistanceResultAdapter.java
new file mode 100644
index 00000000..704c38bc
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/DistanceResultAdapter.java
@@ -0,0 +1,92 @@
+package de.lmu.ifi.dbs.elki.evaluation.scores.adapter;
+/*
+ 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.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.evaluation.scores.ScoreEvaluation.ScoreIter;
+
+/**
+ * This adapter is used to process a list of (double, DBID) objects. The list
+ * <em>must</em> be sorted appropriately, the score is only used to detect
+ * ties.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.composedOf DoubleDBIDListIter
+ */
+public class DistanceResultAdapter implements ScoreIter, DBIDRefIter {
+ /**
+ * Original Iterator
+ */
+ protected DoubleDBIDListIter iter;
+
+ /**
+ * Distance of previous.
+ */
+ protected double prevDist = Double.NaN;
+
+ /**
+ * Constructor
+ *
+ * @param iter Iterator for distance results
+ */
+ public DistanceResultAdapter(DoubleDBIDListIter iter) {
+ super();
+ this.iter = iter;
+ }
+
+ @Override
+ public boolean valid() {
+ return iter.valid();
+ }
+
+ @Override
+ public DistanceResultAdapter advance() {
+ prevDist = iter.doubleValue();
+ iter.advance();
+ return this;
+ }
+
+ @Override
+ public DBIDRef getRef() {
+ return iter;
+ }
+
+ @Override
+ public boolean tiedToPrevious() {
+ return iter.doubleValue() == prevDist;
+ }
+
+ @Deprecated
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+ @Deprecated
+ @Override
+ public boolean equals(Object obj) {
+ return super.equals(obj);
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/FilteredDistanceResultAdapter.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/FilteredDistanceResultAdapter.java
new file mode 100644
index 00000000..9a8a2ddc
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/FilteredDistanceResultAdapter.java
@@ -0,0 +1,76 @@
+package de.lmu.ifi.dbs.elki.evaluation.scores.adapter;
+
+/*
+ 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.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+
+/**
+ * This adapter is used to process a list of (double, DBID) objects, but allows
+ * skipping one object in the ranking. The list <em>must</em> be sorted
+ * appropriately, the score is only used to detect ties.
+ *
+ * @author Erich Schubert
+ */
+public class FilteredDistanceResultAdapter extends DistanceResultAdapter {
+ /**
+ * DBID to skip (usually: query object).
+ */
+ DBIDRef skip;
+
+ /**
+ * Constructor
+ *
+ * @param iter Iterator for distance results
+ * @param skip DBID to skip (reference must remain stable!)
+ */
+ public FilteredDistanceResultAdapter(DoubleDBIDListIter iter, DBIDRef skip) {
+ super(iter);
+ this.skip = skip;
+ if(iter.valid() && DBIDUtil.equal(iter, skip)) {
+ iter.advance();
+ }
+ }
+
+ @Override
+ public DistanceResultAdapter advance() {
+ super.advance();
+ if(iter.valid() && DBIDUtil.equal(iter, skip)) {
+ iter.advance();
+ }
+ return this;
+ }
+
+ @Deprecated
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+ @Deprecated
+ @Override
+ public boolean equals(Object obj) {
+ return super.equals(obj);
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/IncreasingVectorIter.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/IncreasingVectorIter.java
new file mode 100644
index 00000000..979dc166
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/IncreasingVectorIter.java
@@ -0,0 +1,116 @@
+package de.lmu.ifi.dbs.elki.evaluation.scores.adapter;
+
+/*
+ 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.evaluation.scores.ScoreEvaluation.ScoreIter;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerArrayQuickSort;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerComparator;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.ArrayIter;
+
+/**
+ * Class to iterate over a number vector in decreasing order.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.composedOf NumberVector
+ */
+public class IncreasingVectorIter implements ScoreIter, IntegerComparator, ArrayIter {
+ /**
+ * Order of dimensions.
+ */
+ private int[] sort;
+
+ /**
+ * Data vector.
+ */
+ private NumberVector vec;
+
+ /**
+ * Current position.
+ */
+ int pos = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param vec Vector to iterate over.
+ */
+ public IncreasingVectorIter(NumberVector vec) {
+ this.vec = vec;
+ final int dim = vec.getDimensionality();
+ this.sort = new int[dim];
+ for(int d = 0; d < dim; d++) {
+ sort[d] = d;
+ }
+ IntegerArrayQuickSort.sort(sort, this);
+ }
+
+ @Override
+ public int compare(int x, int y) {
+ return Double.compare(vec.doubleValue(x), vec.doubleValue(y));
+ }
+
+ public int dim() {
+ return sort[pos];
+ }
+
+ @Override
+ public boolean valid() {
+ return pos < vec.getDimensionality();
+ }
+
+ @Override
+ public IncreasingVectorIter advance() {
+ ++pos;
+ return this;
+ }
+
+ @Override
+ public boolean tiedToPrevious() {
+ return pos > 0 && Double.compare(vec.doubleValue(sort[pos]), vec.doubleValue(sort[pos - 1])) == 0;
+ }
+
+ @Override
+ public int getOffset() {
+ return pos;
+ }
+
+ @Override
+ public IncreasingVectorIter advance(int count) {
+ pos += count;
+ return this;
+ }
+
+ @Override
+ public IncreasingVectorIter retract() {
+ pos--;
+ return this;
+ }
+
+ @Override
+ public IncreasingVectorIter seek(int off) {
+ pos = off;
+ return this;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/OutlierScoreAdapter.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/OutlierScoreAdapter.java
new file mode 100644
index 00000000..a36a57d6
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/OutlierScoreAdapter.java
@@ -0,0 +1,103 @@
+package de.lmu.ifi.dbs.elki.evaluation.scores.adapter;
+
+/*
+ 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.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.evaluation.scores.ScoreEvaluation.ScoreIter;
+import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
+
+/**
+ * This adapter can be used for an arbitrary collection of Integers, and uses
+ * that id1.compareTo(id2) != 0 for id1 != id2 to satisfy the comparability.
+ *
+ * Note that of course, no id should occur more than once.
+ *
+ * The ROC values would be incorrect then anyway!
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.composedOf OutlierResult
+ */
+public class OutlierScoreAdapter implements ScoreIter, DBIDRefIter {
+ /**
+ * Original iterator.
+ */
+ private DBIDIter iter;
+
+ /**
+ * Outlier score.
+ */
+ private DoubleRelation scores;
+
+ /**
+ * Previous value.
+ */
+ double prev = Double.NaN;
+
+ /**
+ * Constructor.
+ *
+ * @param o Result
+ */
+ public OutlierScoreAdapter(OutlierResult o) {
+ super();
+ this.iter = o.getOrdering().iter(o.getScores().getDBIDs()).iter();
+ this.scores = o.getScores();
+ }
+
+ @Override
+ public boolean valid() {
+ return iter.valid();
+ }
+
+ @Override
+ public OutlierScoreAdapter advance() {
+ prev = scores.doubleValue(iter);
+ iter.advance();
+ return this;
+ }
+
+ @Override
+ public boolean tiedToPrevious() {
+ return scores.doubleValue(iter) == prev;
+ }
+
+ @Override
+ public DBIDRef getRef() {
+ return iter;
+ }
+
+ @Deprecated
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+ @Deprecated
+ @Override
+ public boolean equals(Object obj) {
+ return super.equals(obj);
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/MergedDBIDs.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/SimpleAdapter.java
index 7df6975c..beb301a8 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/MergedDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/SimpleAdapter.java
@@ -1,10 +1,9 @@
-package de.lmu.ifi.dbs.elki.database.ids.generic;
-
+package de.lmu.ifi.dbs.elki.evaluation.scores.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
@@ -25,59 +24,66 @@ package de.lmu.ifi.dbs.elki.database.ids.generic;
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.DBIDs;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+import de.lmu.ifi.dbs.elki.evaluation.scores.ScoreEvaluation.ScoreIter;
/**
- * Merge the IDs of multiple layers into one.
+ * This adapter can be used for an arbitrary collection of Integers, and uses
+ * that id1.compareTo(id2) != 0 for id1 != id2 to satisfy the comparability.
+ *
+ * Note that of course, no id should occur more than once.
+ *
+ * The ROC values would be incorrect then anyway!
*
* @author Erich Schubert
*
- * @apiviz.uses de.lmu.ifi.dbs.elki.database.ids.DBIDs
+ * @apiviz.composedOf DBIDIter
*/
-// TODO: include ID mapping?
-public class MergedDBIDs implements DBIDs {
+public class SimpleAdapter implements ScoreIter, DBIDRefIter {
/**
- * Childs to merge
+ * Original Iterator
*/
- DBIDs childs[];
+ private DBIDIter iter;
/**
- * Constructor.
+ * Constructor
*
- * @param childs
+ * @param iter Iterator for object IDs
*/
- public MergedDBIDs(DBIDs... childs) {
+ public SimpleAdapter(DBIDIter iter) {
super();
- this.childs = childs;
+ this.iter = iter;
+ }
+
+ @Override
+ public boolean valid() {
+ return iter.valid();
+ }
+
+ @Override
+ public SimpleAdapter advance() {
+ iter.advance();
+ return this;
}
@Override
- public DBIDIter iter() {
- throw new AbortException("Merged iterators not completely implemented yet!");
+ public boolean tiedToPrevious() {
+ return false; // No information.
}
+ @Deprecated
@Override
- public int size() {
- int si = 0;
- for(DBIDs child : childs) {
- si += child.size();
- }
- return si;
+ public int hashCode() {
+ return super.hashCode();
}
+ @Deprecated
@Override
- public boolean isEmpty() {
- return size() == 0;
+ public boolean equals(Object obj) {
+ return super.equals(obj);
}
@Override
- public boolean contains(DBIDRef o) {
- for(DBIDs child : childs) {
- if(child.contains(o)) {
- return true;
- }
- }
- return false;
+ public DBIDRef getRef() {
+ return iter;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DoubleNorm.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/VectorNonZero.java
index 6ba5246a..cc97006f 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/DoubleNorm.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/VectorNonZero.java
@@ -1,10 +1,9 @@
-package de.lmu.ifi.dbs.elki.distance.distancefunction;
-
+package de.lmu.ifi.dbs.elki.evaluation.scores.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
@@ -23,21 +22,23 @@ 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.data.NumberVector;
/**
- * Interface for norms in the double domain.
+ * Class that uses a NumberVector as reference, and considers all non-zero
+ * values as positive entries.
*
- * @author Erich Schubert
+ * @apiviz.composedOf NumberVector
*
- * @param <O> Object type
+ * @author Erich Schubert
*/
-public interface DoubleNorm<O> extends Norm<O, DoubleDistance>, PrimitiveDoubleDistanceFunction<O> {
+public class VectorNonZero extends VectorOverThreshold {
/**
- * Compute the norm of object obj as double value.
+ * Constructor.
*
- * @param obj Object
- * @return Double
+ * @param vec Reference vector.
*/
- public double doubleNorm(O obj);
+ public VectorNonZero(NumberVector vec) {
+ super(vec, 0.);
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/VectorOverThreshold.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/VectorOverThreshold.java
new file mode 100644
index 00000000..99c24332
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/VectorOverThreshold.java
@@ -0,0 +1,79 @@
+package de.lmu.ifi.dbs.elki.evaluation.scores.adapter;
+/*
+ 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.evaluation.scores.ScoreEvaluation.Predicate;
+
+/**
+ * Class that uses a NumberVector as reference, and considers all non-zero
+ * values as positive entries.
+ *
+ * @apiviz.composedOf NumberVector
+ *
+ * @author Erich Schubert
+ */
+public class VectorOverThreshold implements Predicate<DecreasingVectorIter> {
+ /**
+ * Vector to use as reference
+ */
+ NumberVector vec;
+
+ /**
+ * Threshold
+ */
+ double threshold;
+
+ /**
+ * Number of positive values.
+ */
+ int numpos;
+
+ /**
+ * Constructor.
+ *
+ * @param vec Reference vector.
+ * @param threshold Threshold value.
+ */
+ public VectorOverThreshold(NumberVector vec, double threshold) {
+ super();
+ this.vec = vec;
+ this.threshold = threshold;
+ this.numpos = 0;
+ for(int i = 0, l = vec.getDimensionality(); i < l; i++) {
+ if(vec.doubleValue(i) > threshold) {
+ ++numpos;
+ }
+ }
+ }
+
+ @Override
+ public boolean test(DecreasingVectorIter o) {
+ return Math.abs(vec.doubleValue(o.dim())) > threshold;
+ }
+
+ @Override
+ public int numPositive() {
+ return numpos;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SubspaceProjectionResult.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/VectorZero.java
index 4e03bc78..e7b728fc 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SubspaceProjectionResult.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/VectorZero.java
@@ -1,10 +1,9 @@
-package de.lmu.ifi.dbs.elki.math.linearalgebra;
-
+package de.lmu.ifi.dbs.elki.evaluation.scores.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
@@ -23,44 +22,50 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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.evaluation.scores.ScoreEvaluation.Predicate;
/**
- * Simple class wrapping the result of a subspace projection.
+ * Class that uses a NumberVector as reference, and considers all zero values as
+ * positive entries.
*
- * @author Erich Schubert
+ * @apiviz.composedOf NumberVector
*
- * @apiviz.composedOf Matrix
+ * @author Erich Schubert
*/
-public class SubspaceProjectionResult implements ProjectionResult {
+public class VectorZero implements Predicate<IncreasingVectorIter> {
/**
- * The correlation dimensionality
+ * Vector to use as reference
*/
- private int correlationDimensionality;
-
+ NumberVector vec;
+
/**
- * The similarity matrix
+ * Number of positive values.
*/
- private Matrix similarityMat;
-
+ int numpos;
+
/**
* Constructor.
*
- * @param correlationDimensionality dimensionality
- * @param similarityMat projection matrix
+ * @param vec Reference vector.
*/
- public SubspaceProjectionResult(int correlationDimensionality, Matrix similarityMat) {
- super();
- this.correlationDimensionality = correlationDimensionality;
- this.similarityMat = similarityMat;
+ public VectorZero(NumberVector vec) {
+ this.vec = vec;
+ this.numpos = 0;
+ for(int i = 0, l = vec.getDimensionality(); i < l; i++) {
+ if(Math.abs(vec.doubleValue(i)) < Double.MIN_NORMAL) {
+ ++numpos;
+ }
+ }
}
@Override
- public int getCorrelationDimension() {
- return correlationDimensionality;
+ public boolean test(IncreasingVectorIter o) {
+ return Math.abs(vec.doubleValue(o.dim())) < Double.MIN_NORMAL;
}
@Override
- public Matrix similarityMatrix() {
- return similarityMat;
+ public int numPositive() {
+ return numpos;
}
-}
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/package-info.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/package-info.java
new file mode 100644
index 00000000..746d9a1c
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/adapter/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * Adapter classes for ranking and scoring measures.
+ */
+/*
+ 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.evaluation.scores.adapter; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/scores/package-info.java b/src/de/lmu/ifi/dbs/elki/evaluation/scores/package-info.java
new file mode 100644
index 00000000..d409b7f9
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/scores/package-info.java
@@ -0,0 +1,28 @@
+/**
+ * <p>Evaluation of rankings and scorings.</p>
+ *
+ * @apiviz.exclude java.util.*
+ */
+/*
+ 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.evaluation.scores; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/similaritymatrix/ComputeSimilarityMatrixImage.java b/src/de/lmu/ifi/dbs/elki/evaluation/similaritymatrix/ComputeSimilarityMatrixImage.java
index 90a11583..e09dba3a 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/similaritymatrix/ComputeSimilarityMatrixImage.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/similaritymatrix/ComputeSimilarityMatrixImage.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.evaluation.similaritymatrix;
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
@@ -42,7 +42,6 @@ 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.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.evaluation.Evaluator;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
@@ -90,7 +89,7 @@ public class ComputeSimilarityMatrixImage<O> implements Evaluator {
/**
* The distance function to use
*/
- private DistanceFunction<? super O, ? extends NumberDistance<?, ?>> distanceFunction;
+ private DistanceFunction<? super O> distanceFunction;
/**
* Scaling function to use
@@ -109,7 +108,7 @@ public class ComputeSimilarityMatrixImage<O> implements Evaluator {
* @param scaling Scaling function to use for contrast
* @param skipzero Skip zero values when scaling.
*/
- public ComputeSimilarityMatrixImage(DistanceFunction<? super O, ? extends NumberDistance<?, ?>> distanceFunction, ScalingFunction scaling, boolean skipzero) {
+ public ComputeSimilarityMatrixImage(DistanceFunction<? super O> distanceFunction, ScalingFunction scaling, boolean skipzero) {
super();
this.distanceFunction = distanceFunction;
this.scaling = scaling;
@@ -131,7 +130,7 @@ public class ComputeSimilarityMatrixImage<O> implements Evaluator {
if(order.size() != relation.size()) {
throw new IllegalStateException("Iterable result doesn't match database size - incomplete ordering?");
}
- DistanceQuery<O, ? extends NumberDistance<?, ?>> dq = distanceFunction.instantiate(relation);
+ DistanceQuery<O> dq = distanceFunction.instantiate(relation);
final int size = order.size();
// When the logging is in the outer loop, it's just 2*size (providing enough
@@ -148,16 +147,14 @@ public class ComputeSimilarityMatrixImage<O> implements Evaluator {
for(; id1.valid(); id1.advance()) {
id2.seek(id1.getOffset());
for(; id2.valid(); id2.advance()) {
- final double dist = dq.distance(id1, id2).doubleValue();
+ final double dist = dq.distance(id1, id2);
if(!Double.isNaN(dist) && !Double.isInfinite(dist) /* && dist > 0.0 */) {
if(!skipzero || dist > 0.0) {
minmax.put(dist);
}
}
}
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
}
}
@@ -173,7 +170,7 @@ public class ComputeSimilarityMatrixImage<O> implements Evaluator {
for(int x = 0; x < size && id1.valid(); x++, id1.advance()) {
id2.seek(id1.getOffset());
for(int y = x; y < size && id2.valid(); y++, id2.advance()) {
- double ddist = dq.distance(id1, id2).doubleValue();
+ double ddist = dq.distance(id1, id2);
if(ddist > 0.0) {
ddist = scale.getScaled(ddist);
}
@@ -186,14 +183,10 @@ public class ComputeSimilarityMatrixImage<O> implements Evaluator {
img.setRGB(x, y, col);
img.setRGB(y, x, col);
}
- if(prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
}
}
- if(prog != null) {
- prog.ensureCompleted(LOG);
- }
+ LOG.ensureCompleted(prog);
return new SimilarityMatrix(img, relation, order);
}
@@ -338,7 +331,7 @@ public class ComputeSimilarityMatrixImage<O> implements Evaluator {
/**
* The distance function to use
*/
- private DistanceFunction<O, ? extends NumberDistance<?, ?>> distanceFunction;
+ private DistanceFunction<O> distanceFunction;
/**
* Scaling function to use
@@ -353,7 +346,7 @@ public class ComputeSimilarityMatrixImage<O> implements Evaluator {
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- ObjectParameter<DistanceFunction<O, ? extends NumberDistance<?, ?>>> distanceFunctionP = AbstractAlgorithm.makeParameterDistanceFunction(EuclideanDistanceFunction.class, DistanceFunction.class);
+ ObjectParameter<DistanceFunction<O>> distanceFunctionP = AbstractAlgorithm.makeParameterDistanceFunction(EuclideanDistanceFunction.class, DistanceFunction.class);
if(config.grab(distanceFunctionP)) {
distanceFunction = distanceFunctionP.instantiateClass(config);
}
diff --git a/src/de/lmu/ifi/dbs/elki/evaluation/similaritymatrix/package-info.java b/src/de/lmu/ifi/dbs/elki/evaluation/similaritymatrix/package-info.java
index 4acc0ec6..bcaf0520 100644
--- a/src/de/lmu/ifi/dbs/elki/evaluation/similaritymatrix/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/evaluation/similaritymatrix/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/gui/GUIUtil.java b/src/de/lmu/ifi/dbs/elki/gui/GUIUtil.java
index 27cccded..e48edcea 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/GUIUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/GUIUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui;
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
@@ -110,5 +110,4 @@ public final class GUIUtil {
logger.warning("Could not set the Default Uncaught Exception Handler", e);
}
}
-
}
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractParameterConfigurator.java
index c6883653..6857feba 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractParameterConfigurator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.configurator;
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/gui/configurator/AbstractSingleParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractSingleParameterConfigurator.java
index 240515cd..b37d23cc 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractSingleParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/AbstractSingleParameterConfigurator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.configurator;
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/gui/configurator/ClassListParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java
index 182c7a0a..a49ec23f 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.configurator;
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,20 +27,24 @@ import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.Insets;
-import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import javax.swing.Icon;
import javax.swing.JButton;
-import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import javax.swing.plaf.basic.BasicComboPopup;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
import de.lmu.ifi.dbs.elki.gui.icons.StockIcon;
+import de.lmu.ifi.dbs.elki.gui.util.ClassTree;
+import de.lmu.ifi.dbs.elki.gui.util.ClassTree.ClassNode;
+import de.lmu.ifi.dbs.elki.gui.util.TreePopup;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
@@ -54,8 +58,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
* @author Erich Schubert
*
* @apiviz.uses ClassListParameter
+ * @apiviz.uses ClassTree
*/
public class ClassListParameterConfigurator extends AbstractSingleParameterConfigurator<ClassListParameter<?>> implements ActionListener, ChangeListener {
+ /**
+ * Configurator for children
+ */
final ConfiguratorPanel child;
/**
@@ -74,15 +82,16 @@ public class ClassListParameterConfigurator extends AbstractSingleParameterConfi
final JButton button;
/**
- * The combobox we are abusing to produce the popup
+ * The popup we use.
*/
- final JComboBox<String> combo;
+ final TreePopup popup;
/**
- * The popup menu.
+ * Constructor.
+ *
+ * @param cp Class list parameter
+ * @param parent Parent component
*/
- final SuperPopup popup;
-
public ClassListParameterConfigurator(ClassListParameter<?> cp, JComponent parent) {
super(cp, parent);
textfield = new JTextField();
@@ -95,26 +104,20 @@ public class ClassListParameterConfigurator extends AbstractSingleParameterConfi
button = new JButton(StockIcon.getStockIcon(StockIcon.LIST_ADD));
button.setToolTipText(param.getShortDescription());
button.addActionListener(this);
- // So the first item doesn't get automatically selected
- combo = new JComboBox<>();
- combo.setEditable(true);
- combo.setPrototypeDisplayValue(cp.getRestrictionClass().getSimpleName());
- popup = new SuperPopup(combo);
- // fill dropdown menu
- {
- // Offer the shorthand version of class names.
- String prefix = cp.getRestrictionClass().getPackage().getName() + ".";
- for(Class<?> impl : cp.getKnownImplementations()) {
- String name = impl.getName();
- if(name.startsWith(prefix)) {
- name = name.substring(prefix.length());
- }
- combo.addItem(name);
- }
- }
- combo.addActionListener(this);
+ TreeNode root = ClassTree.build(cp.getKnownImplementations(), cp.getRestrictionClass().getPackage().getName());
+
+ popup = new TreePopup(new DefaultTreeModel(root));
+ popup.getTree().setRootVisible(false);
+ // popup.setPrototypeDisplayValue(cp.getRestrictionClass().getSimpleName());
+ popup.addActionListener(this);
+ Icon classIcon = StockIcon.getStockIcon(StockIcon.GO_NEXT);
+ Icon packageIcon = StockIcon.getStockIcon(StockIcon.PACKAGE);
+ TreePopup.Renderer renderer = (TreePopup.Renderer) popup.getTree().getCellRenderer();
+ renderer.setLeafIcon(classIcon);
+ renderer.setFolderIcon(packageIcon);
+
// setup panel
{
panel = new JPanel();
@@ -156,82 +159,43 @@ public class ClassListParameterConfigurator extends AbstractSingleParameterConfi
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button) {
popup.show(panel);
+ return;
}
- else if(e.getSource() == combo) {
- String newClass = (String) combo.getSelectedItem();
- if(newClass != null && newClass.length() > 0) {
- String val = textfield.getText();
- if(val.length() > 0) {
- val = val + ClassListParameter.LIST_SEP + newClass;
- }
- else {
- val = newClass;
- }
- textfield.setText(val);
- popup.hide();
- fireValueChanged();
- }
- }
- else if(e.getSource() == textfield) {
+ if(e.getSource() == textfield) {
fireValueChanged();
+ return;
}
- else {
- LoggingUtil.warning("actionPerformed triggered by unknown source: " + e.getSource());
- }
- }
-
- // FIXME: Refactor - duplicate code.
- /** @apiviz.exclude */
- class SuperPopup extends BasicComboPopup {
- /**
- * Serial version
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor.
- *
- * @param combo Combo box used for data storage.
- */
- public SuperPopup(JComboBox<String> combo) {
- super(combo);
- }
-
- /**
- * Show the menu on a particular panel.
- *
- * This code is mostly copied from {@link BasicComboPopup#getPopupLocation}
- *
- * @param parent Parent element to show at.
- */
- public void show(JPanel parent) {
- Dimension popupSize = parent.getSize();
- Insets insets = getInsets();
-
- // reduce the width of the scrollpane by the insets so that the popup
- // is the same width as the combo box.
- popupSize.setSize(popupSize.width - (insets.right + insets.left), getPopupHeightForRowCount(comboBox.getMaximumRowCount()));
- Rectangle popupBounds = computePopupBounds(0, comboBox.getBounds().height, popupSize.width, popupSize.height);
- Dimension scrollSize = popupBounds.getSize();
-
- scroller.setMaximumSize(scrollSize);
- scroller.setPreferredSize(scrollSize);
- scroller.setMinimumSize(scrollSize);
-
- list.revalidate();
-
- super.show(parent, 0, parent.getBounds().height);
+ if(e.getSource() == popup) {
+ if(e.getActionCommand() == TreePopup.ACTION_CANCELED) {
+ popup.setVisible(false);
+ textfield.requestFocus();
+ return;
+ }
+ TreePath path = popup.getTree().getSelectionPath();
+ final Object comp = path != null ? path.getLastPathComponent() : null;
+ if(comp instanceof ClassNode) {
+ ClassNode sel = (path != null) ? (ClassNode) comp : null;
+ String newClass = (sel != null) ? sel.getClassName() : null;
+ if(newClass != null && newClass.length() > 0) {
+ String val = textfield.getText();
+ val = (val.length() > 0) ? val + ClassListParameter.LIST_SEP + newClass : newClass;
+ textfield.setText(val);
+ popup.setVisible(false);
+ fireValueChanged();
+ }
+ }
+ return;
}
+ LoggingUtil.warning("actionPerformed triggered by unknown source: " + e.getSource());
}
@Override
public void stateChanged(ChangeEvent e) {
if(e.getSource() == child) {
fireValueChanged();
+ return;
}
- else {
- LoggingUtil.warning("stateChanged triggered by unknown source: " + e.getSource());
- }
+ LoggingUtil.warning("stateChanged triggered by unknown source: " + e.getSource());
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java
index cbe03a4f..8deb72ed 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.configurator;
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,17 +23,31 @@ package de.lmu.ifi.dbs.elki.gui.configurator;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.awt.BorderLayout;
+import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import javax.swing.JComboBox;
+import javax.swing.Icon;
+import javax.swing.JButton;
import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-
+import javax.swing.plaf.basic.BasicArrowButton;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+
+import de.lmu.ifi.dbs.elki.gui.icons.StockIcon;
+import de.lmu.ifi.dbs.elki.gui.util.ClassTree;
+import de.lmu.ifi.dbs.elki.gui.util.ClassTree.ClassNode;
import de.lmu.ifi.dbs.elki.gui.util.DynamicParameters;
+import de.lmu.ifi.dbs.elki.gui.util.TreePopup;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
@@ -49,41 +63,91 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
* @apiviz.uses ClassParameter
*/
public class ClassParameterConfigurator extends AbstractSingleParameterConfigurator<ClassParameter<?>> implements ActionListener, ChangeListener {
- final JComboBox<String> value;
-
+ /**
+ * We need a panel to put our components on.
+ */
+ final JPanel panel;
+
+ /**
+ * Text field to store the name
+ */
+ final JTextField textfield;
+
+ /**
+ * The button to open the file selector
+ */
+ final JButton button;
+
+ /**
+ * The popup we use.
+ */
+ final TreePopup popup;
+
+ /**
+ * Configuration panel for child.
+ */
final ConfiguratorPanel child;
+ /**
+ * Constructor.
+ *
+ * @param cp Class parameter
+ * @param parent Parent component.
+ */
public ClassParameterConfigurator(ClassParameter<?> cp, JComponent parent) {
super(cp, parent);
- // Input field
+ textfield = new JTextField();
+ textfield.setToolTipText(param.getShortDescription());
+ if(cp.isDefined() && !cp.tookDefaultValue()) {
+ textfield.setText(cp.getValueAsString());
+ }
+ textfield.setPreferredSize(new Dimension(400, textfield.getPreferredSize().height));
+ if(!param.tookDefaultValue() && param.isDefined() && param.getGivenValue() != null) {
+ textfield.setText(param.getValueAsString());
+ // FIXME: pre-select the current / default value in tree!
+ }
+
+ // This is a hack, but the BasicArrowButton looks very odd on GTK.
+ if(UIManager.getLookAndFeel().getName().indexOf("GTK") >= 0) {
+ // This is not optimal either, but looks more consistent at least.
+ button = new JButton(StockIcon.getStockIcon(StockIcon.EDIT_FIND));
+ }
+ else {
+ button = new BasicArrowButton(BasicArrowButton.SOUTH);
+ }
+ button.setToolTipText(param.getShortDescription());
+ button.addActionListener(this);
+
+ TreeNode root = ClassTree.build(cp.getKnownImplementations(), cp.getRestrictionClass().getPackage().getName());
+
+ popup = new TreePopup(new DefaultTreeModel(root));
+ popup.getTree().setRootVisible(false);
+ // popup.setPrototypeDisplayValue(cp.getRestrictionClass().getSimpleName());
+ popup.addActionListener(this);
+
+ Icon classIcon = StockIcon.getStockIcon(StockIcon.GO_NEXT);
+ Icon packageIcon = StockIcon.getStockIcon(StockIcon.PACKAGE);
+ TreePopup.Renderer renderer = (TreePopup.Renderer) popup.getTree().getCellRenderer();
+ renderer.setLeafIcon(classIcon);
+ renderer.setFolderIcon(packageIcon);
+
+ // setup panel
{
+ panel = new JPanel();
+ panel.setLayout(new BorderLayout());
+ panel.add(textfield, BorderLayout.CENTER);
+ panel.add(button, BorderLayout.EAST);
+
GridBagConstraints constraints = new GridBagConstraints();
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.weightx = 1.0;
- value = new JComboBox<>();
- value.setToolTipText(param.getShortDescription());
- value.setPrototypeDisplayValue(cp.getRestrictionClass().getSimpleName());
- parent.add(value, constraints);
+ parent.add(panel, constraints);
finishGridRow();
}
- if(!param.tookDefaultValue() && param.isDefined() && param.getGivenValue() != null) {
- value.addItem(param.getValueAsString());
- value.setSelectedIndex(0);
- }
+ // FIXME: re-add "none" option for optional parameters!
+ // FIXME: re-highlight default value!
- // For parameters with a default value, offer using the default
- // For optional parameters, offer not specifying them.
- if(cp.hasDefaultValue()) {
- value.addItem(DynamicParameters.STRING_USE_DEFAULT + cp.getDefaultValueAsString());
- }
- else if(cp.isOptional()) {
- value.addItem(DynamicParameters.STRING_OPTIONAL);
- }
- // Offer the shorthand version of class names.
- for(Class<?> impl : cp.getKnownImplementations()) {
- value.addItem(ClassParameter.canonicalClassName(impl, cp.getRestrictionClass()));
- }
// Child options
{
GridBagConstraints constraints = new GridBagConstraints();
@@ -95,7 +159,6 @@ public class ClassParameterConfigurator extends AbstractSingleParameterConfigura
child.addChangeListener(this);
parent.add(child, constraints);
}
- value.addActionListener(this);
}
@Override
@@ -105,27 +168,44 @@ public class ClassParameterConfigurator extends AbstractSingleParameterConfigura
@Override
public void actionPerformed(ActionEvent e) {
- if(e.getSource() == value) {
- fireValueChanged();
+ if(e.getSource() == button) {
+ popup.show(panel);
+ return;
}
- else {
- LoggingUtil.warning("actionPerformed triggered by unknown source: " + e.getSource());
+ if(e.getSource() == popup) {
+ if (e.getActionCommand() == TreePopup.ACTION_CANCELED) {
+ popup.setVisible(false);
+ textfield.requestFocus();
+ return;
+ }
+ TreePath path = popup.getTree().getSelectionPath();
+ final Object comp = path != null ? path.getLastPathComponent() : null;
+ if(comp instanceof ClassNode) {
+ ClassNode sel = (path != null) ? (ClassNode) comp : null;
+ String newClass = (sel != null) ? sel.getClassName() : null;
+ if(newClass != null && newClass.length() > 0) {
+ textfield.setText(newClass);
+ popup.setVisible(false);
+ fireValueChanged();
+ }
+ }
+ return;
}
+ LoggingUtil.warning("actionPerformed triggered by unknown source: " + e.getSource());
}
@Override
public void stateChanged(ChangeEvent e) {
if(e.getSource() == child) {
fireValueChanged();
+ return;
}
- else {
- LoggingUtil.warning("stateChanged triggered by unknown source: " + e.getSource());
- }
+ LoggingUtil.warning("stateChanged triggered by unknown source: " + e.getSource());
}
@Override
public String getUserInput() {
- String val = (String) value.getSelectedItem();
+ String val = textfield.getText();
if(val.startsWith(DynamicParameters.STRING_USE_DEFAULT)) {
return null;
}
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/ConfiguratorPanel.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/ConfiguratorPanel.java
index 440d5d0a..fc24d7f8 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/ConfiguratorPanel.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/ConfiguratorPanel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.configurator;
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/gui/configurator/EnumParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/EnumParameterConfigurator.java
index f361efa2..4aeed477 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/EnumParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/EnumParameterConfigurator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.configurator;
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/gui/configurator/FileParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/FileParameterConfigurator.java
index 1fce49f0..58880251 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/FileParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/FileParameterConfigurator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.configurator;
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/gui/configurator/FlagParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/FlagParameterConfigurator.java
index 5f73663c..163c11e2 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/FlagParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/FlagParameterConfigurator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.configurator;
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/gui/configurator/ParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/ParameterConfigurator.java
index 6118355c..3e0ce509 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/ParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/ParameterConfigurator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.configurator;
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/gui/configurator/TextParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/TextParameterConfigurator.java
index 411d056d..650a76f2 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/TextParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/TextParameterConfigurator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.configurator;
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/gui/configurator/package-info.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/package-info.java
index cb7ef043..8209d8a3 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/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/gui/icons/StockIcon.java b/src/de/lmu/ifi/dbs/elki/gui/icons/StockIcon.java
index c0550da3..1b213643 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/icons/StockIcon.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/icons/StockIcon.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.icons;
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
@@ -58,6 +58,8 @@ public class StockIcon {
public static final String EDIT_UNDO = "edit-undo";
+ public static final String EDIT_FIND = "edit-find";
+
public static final String EMBLEM_IMPORTANT = "emblem-important";
public static final String GO_BOTTOM = "go-bottom";
@@ -86,8 +88,12 @@ public class StockIcon {
public static final String LIST_REMOVE = "list-remove";
+ public static final String PACKAGE = "package";
+
public static final String PROCESS_STOP = "process-stop";
+ public static final String SYSTEM_SEARCH = "system-search";
+
private static final Map<String, SoftReference<Icon>> iconcache = new HashMap<>();
/**
diff --git a/src/de/lmu/ifi/dbs/elki/gui/icons/copyright-tango-project.txt b/src/de/lmu/ifi/dbs/elki/gui/icons/copyright-tango-project.txt
index d6e91e12..93bf1b6f 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/icons/copyright-tango-project.txt
+++ b/src/de/lmu/ifi/dbs/elki/gui/icons/copyright-tango-project.txt
@@ -20,6 +20,7 @@ document-open.png
document-properties.png
document-save.png
edit-clear.png
+edit-find.png
edit-redo.png
edit-undo.png
emblem-important.png
@@ -36,6 +37,7 @@ go-up.png
help-browser.png
list-add.png
list-remove.png
+package.png
process-stop.png
---
diff --git a/src/de/lmu/ifi/dbs/elki/gui/icons/edit-find.png b/src/de/lmu/ifi/dbs/elki/gui/icons/edit-find.png
new file mode 100644
index 00000000..d072d3cb
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/icons/edit-find.png
Binary files differ
diff --git a/src/de/lmu/ifi/dbs/elki/gui/icons/package-info.java b/src/de/lmu/ifi/dbs/elki/gui/icons/package-info.java
index c7ffb7d0..a07456f2 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/icons/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/icons/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/gui/icons/package.png b/src/de/lmu/ifi/dbs/elki/gui/icons/package.png
new file mode 100644
index 00000000..90154261
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/icons/package.png
Binary files differ
diff --git a/src/de/lmu/ifi/dbs/elki/gui/icons/system-search.png b/src/de/lmu/ifi/dbs/elki/gui/icons/system-search.png
new file mode 100644
index 00000000..fd7f0b07
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/icons/system-search.png
Binary files differ
diff --git a/src/de/lmu/ifi/dbs/elki/gui/minigui/MiniGUI.java b/src/de/lmu/ifi/dbs/elki/gui/minigui/MiniGUI.java
index f60ac69e..9624a0d6 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/minigui/MiniGUI.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/minigui/MiniGUI.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.minigui;
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,6 +24,7 @@ package de.lmu.ifi.dbs.elki.gui.minigui;
*/
import java.awt.Dimension;
+import java.awt.Event;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
@@ -34,9 +35,11 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
+import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
+import javax.swing.AbstractAction;
import javax.swing.AbstractListModel;
import javax.swing.BoxLayout;
import javax.swing.ComboBoxModel;
@@ -46,19 +49,24 @@ import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
+import javax.swing.KeyStroke;
import javax.swing.SwingWorker;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import de.lmu.ifi.dbs.elki.KDDTask;
import de.lmu.ifi.dbs.elki.application.AbstractApplication;
+import de.lmu.ifi.dbs.elki.application.ELKILauncher;
+import de.lmu.ifi.dbs.elki.application.KDDCLIApplication;
import de.lmu.ifi.dbs.elki.gui.GUIUtil;
import de.lmu.ifi.dbs.elki.gui.util.DynamicParameters;
import de.lmu.ifi.dbs.elki.gui.util.LogPanel;
import de.lmu.ifi.dbs.elki.gui.util.ParameterTable;
import de.lmu.ifi.dbs.elki.gui.util.ParametersModel;
import de.lmu.ifi.dbs.elki.gui.util.SavedSettingsFile;
+import de.lmu.ifi.dbs.elki.logging.CLISmartHandler;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration;
import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
@@ -66,6 +74,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.UnspecifiedParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.SerializedParameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
+import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
import de.lmu.ifi.dbs.elki.workflow.LoggingStep;
import de.lmu.ifi.dbs.elki.workflow.OutputStep;
@@ -79,7 +88,7 @@ import de.lmu.ifi.dbs.elki.workflow.OutputStep;
* @apiviz.owns ParameterTable
* @apiviz.owns DynamicParameters
*/
-@Alias({"mini", "minigui"})
+@Alias({ "mini", "minigui" })
public class MiniGUI extends AbstractApplication {
/**
* Filename for saved settings.
@@ -97,6 +106,11 @@ public class MiniGUI extends AbstractApplication {
private static final Logging LOG = Logging.getLogger(MiniGUI.class);
/**
+ * Quit action, for mnemonics.
+ */
+ protected static final String ACTION_QUIT = "quit";
+
+ /**
* The frame
*/
JFrame frame;
@@ -142,6 +156,11 @@ public class MiniGUI extends AbstractApplication {
protected JButton runButton;
/**
+ * Application to configure / run.
+ */
+ private Class<? extends AbstractApplication> maincls = KDDCLIApplication.class;
+
+ /**
* Constructor.
*/
public MiniGUI() {
@@ -305,6 +324,26 @@ public class MiniGUI extends AbstractApplication {
LOG.exception(e);
}
+ {
+ KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_Q, Event.CTRL_MASK);
+ panel.getInputMap().put(key, ACTION_QUIT);
+ }
+ {
+ KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_W, Event.CTRL_MASK);
+ panel.getInputMap().put(key, ACTION_QUIT);
+ }
+ panel.getActionMap().put(ACTION_QUIT, new AbstractAction() {
+ /**
+ * Serial version
+ */
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ frame.dispose();
+ }
+ });
+
// Finalize the frame.
frame.setContentPane(panel);
frame.pack();
@@ -331,7 +370,7 @@ public class MiniGUI extends AbstractApplication {
SerializedParameterization config = new SerializedParameterization(params);
TrackParameters track = new TrackParameters(config);
track.tryInstantiate(LoggingStep.class);
- track.tryInstantiate(KDDTask.class);
+ track.tryInstantiate(maincls);
config.logUnusedParameters();
// config.logAndClearReportedErrors();
final boolean hasErrors = (config.getErrors().size() > 0);
@@ -367,6 +406,18 @@ public class MiniGUI extends AbstractApplication {
}
/**
+ * Auto-load the last task from the history file.
+ */
+ protected void loadLatest() {
+ int size = store.size();
+ if(size > 0) {
+ final Pair<String, ArrayList<String>> pair = store.getElementAt(size - 1);
+ savedSettingsModel.setSelectedItem(pair.first);
+ doSetParameters(pair.second);
+ }
+ }
+
+ /**
* Do a full run of the KDDTask with the specified parameters.
*/
protected void startTask() {
@@ -385,7 +436,7 @@ public class MiniGUI extends AbstractApplication {
public Void doInBackground() {
SerializedParameterization config = new SerializedParameterization(params);
config.tryInstantiate(LoggingStep.class);
- KDDTask task = config.tryInstantiate(KDDTask.class);
+ AbstractApplication task = config.tryInstantiate(maincls);
try {
config.logUnusedParameters();
if(config.getErrors().size() == 0) {
@@ -455,14 +506,41 @@ public class MiniGUI extends AbstractApplication {
try {
final MiniGUI gui = new MiniGUI();
gui.run();
+ List<String> params = Collections.emptyList();
if(args != null && args.length > 0) {
- gui.doSetParameters(Arrays.asList(args));
- }
- else {
- gui.doSetParameters(new ArrayList<String>());
+ params = new ArrayList<>(Arrays.asList(args));
+ // TODO: it would be nicer to use the Parameterization API for this!
+ if(params.size() > 0) {
+ try {
+ gui.maincls = ELKILauncher.findMainClass(params.get(0));
+ params.remove(0); // on success
+ }
+ catch(ClassNotFoundException e) {
+ // Ignore.
+ }
+ }
+ if(params.remove("-minigui.last")) {
+ javax.swing.SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ gui.loadLatest();
+ }
+ });
+ }
+ if(params.remove("-minigui.autorun")) {
+ javax.swing.SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ gui.startTask();
+ }
+ });
+ }
}
+ gui.doSetParameters(params);
}
- catch(UnableToComplyException e) {
+ catch(Exception | Error e) {
+ // Restore error handler, as the GUI is likely broken.
+ LoggingConfiguration.replaceDefaultHandler(new CLISmartHandler());
LOG.exception(e);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/gui/minigui/package-info.java b/src/de/lmu/ifi/dbs/elki/gui/minigui/package-info.java
index 7acb0045..3dd5ea02 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/minigui/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/minigui/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/gui/multistep/MultiStepGUI.java b/src/de/lmu/ifi/dbs/elki/gui/multistep/MultiStepGUI.java
index 11a45d25..31e24ef6 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/multistep/MultiStepGUI.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/multistep/MultiStepGUI.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.multistep;
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
@@ -47,7 +47,9 @@ import de.lmu.ifi.dbs.elki.gui.multistep.panels.OutputTabPanel;
import de.lmu.ifi.dbs.elki.gui.multistep.panels.SavedSettingsTabPanel;
import de.lmu.ifi.dbs.elki.gui.util.LogPanel;
import de.lmu.ifi.dbs.elki.gui.util.SavedSettingsFile;
+import de.lmu.ifi.dbs.elki.logging.CLISmartHandler;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration;
import de.lmu.ifi.dbs.elki.utilities.Alias;
import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
@@ -124,7 +126,8 @@ public class MultiStepGUI extends AbstractApplication {
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
try {
frame.setIconImage(new ImageIcon(KDDTask.class.getResource("elki-icon.png")).getImage());
- } catch (Exception e) {
+ }
+ catch(Exception e) {
// Ignore - icon not found is not fatal.
}
@@ -171,9 +174,11 @@ public class MultiStepGUI extends AbstractApplication {
SavedSettingsFile settings = new SavedSettingsFile(MiniGUI.SAVED_SETTINGS_FILENAME);
try {
settings.load();
- } catch (FileNotFoundException e) {
+ }
+ catch(FileNotFoundException e) {
LOG.warning("Error loading saved settings.", e);
- } catch (IOException e) {
+ }
+ catch(IOException e) {
LOG.exception(e);
}
@@ -250,12 +255,16 @@ public class MultiStepGUI extends AbstractApplication {
try {
final MultiStepGUI gui = new MultiStepGUI();
gui.run();
- if (args != null && args.length > 0) {
+ if(args != null && args.length > 0) {
gui.setParameters(new SerializedParameterization(args));
- } else {
+ }
+ else {
gui.setParameters(new SerializedParameterization());
}
- } catch (UnableToComplyException e) {
+ }
+ catch(Exception | Error e) {
+ // Restore error handler, as the GUI is likely broken.
+ LoggingConfiguration.replaceDefaultHandler(new CLISmartHandler());
LOG.exception(e);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/gui/multistep/package-info.java b/src/de/lmu/ifi/dbs/elki/gui/multistep/package-info.java
index 3e8f11b2..cc3df902 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/multistep/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/multistep/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/gui/multistep/panels/AlgorithmTabPanel.java b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/AlgorithmTabPanel.java
index d6622e8f..7968a5dd 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/AlgorithmTabPanel.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/AlgorithmTabPanel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.multistep.panels;
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/gui/multistep/panels/EvaluationTabPanel.java b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/EvaluationTabPanel.java
index d8d4153c..e89bb187 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/EvaluationTabPanel.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/EvaluationTabPanel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.multistep.panels;
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/gui/multistep/panels/InputTabPanel.java b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/InputTabPanel.java
index 2f4d027b..e2866183 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/InputTabPanel.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/InputTabPanel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.multistep.panels;
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/gui/multistep/panels/LoggingTabPanel.java b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/LoggingTabPanel.java
index c4933673..2495eb03 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/LoggingTabPanel.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/LoggingTabPanel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.multistep.panels;
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/gui/multistep/panels/OutputTabPanel.java b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/OutputTabPanel.java
index 12af18d3..124bbe61 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/OutputTabPanel.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/OutputTabPanel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.multistep.panels;
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/gui/multistep/panels/ParameterTabPanel.java b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/ParameterTabPanel.java
index 667960a1..287f4e48 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/ParameterTabPanel.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/ParameterTabPanel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.multistep.panels;
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
@@ -43,10 +43,9 @@ import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.UnspecifiedParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackedParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Abstract panel, showing particular options.
@@ -219,8 +218,8 @@ public abstract class ParameterTabPanel extends JPanel implements ChangeListener
parameterTable.setEnabled(false);
parameterTable.clear();
- for (Pair<Object, Parameter<?>> pair : track.getAllParameters()) {
- parameterTable.addParameter(pair.first, pair.getSecond(), track);
+ for (TrackedParameter pair : track.getAllParameters()) {
+ parameterTable.addParameter(pair.getOwner(), pair.getParameter(), track);
}
// parameters.updateFromTrackParameters(track);
diff --git a/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/SavedSettingsTabPanel.java b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/SavedSettingsTabPanel.java
index acebdc16..201a99c6 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/SavedSettingsTabPanel.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/SavedSettingsTabPanel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.multistep.panels;
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/gui/multistep/panels/package-info.java b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/package-info.java
index 77d1779d..1ace9d34 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/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/gui/package-info.java b/src/de/lmu/ifi/dbs/elki/gui/package-info.java
index 8fa23e0d..47c29c71 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/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/gui/util/ClassTree.java b/src/de/lmu/ifi/dbs/elki/gui/util/ClassTree.java
new file mode 100644
index 00000000..3071aa7e
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/util/ClassTree.java
@@ -0,0 +1,211 @@
+package de.lmu.ifi.dbs.elki.gui.util;
+
+/*
+ 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.HashMap;
+import java.util.List;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.MutableTreeNode;
+import javax.swing.tree.TreeNode;
+
+/**
+ * Build a tree of available classes for use in Swing UIs.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has TreeNode
+ */
+public class ClassTree {
+ /**
+ * Build the class tree for a given set of choices.
+ *
+ * @param choices Class choices
+ * @param rootpkg Root package name (to strip / hide)
+ * @return Root node.
+ */
+ public static TreeNode build(List<Class<?>> choices, String rootpkg) {
+ MutableTreeNode root = new PackageNode(rootpkg, rootpkg);
+ HashMap<String, MutableTreeNode> lookup = new HashMap<>();
+ if(rootpkg != null) {
+ lookup.put(rootpkg, root);
+ }
+ lookup.put("de.lmu.ifi.dbs.elki", root);
+ lookup.put("", root);
+
+ // Use the shorthand version of class names.
+ String prefix = rootpkg != null ? rootpkg + "." : null;
+
+ for(Class<?> impl : choices) {
+ String name = impl.getName();
+ name = (prefix != null && name.startsWith(prefix)) ? name.substring(prefix.length()) : name;
+ MutableTreeNode c = new ClassNode(impl.getName().substring(impl.getPackage().getName().length() + 1), name);
+
+ MutableTreeNode p = null;
+ int l = name.lastIndexOf('.');
+ while(p == null) {
+ if(l < 0) {
+ p = root;
+ break;
+ }
+ String pname = name.substring(0, l);
+ p = lookup.get(pname);
+ if(p != null) {
+ break;
+ }
+ l = pname.lastIndexOf('.');
+ MutableTreeNode tmp = new PackageNode(l >= 0 ? pname.substring(l + 1) : pname, pname);
+ tmp.insert(c, 0);
+ c = tmp;
+ lookup.put(pname, tmp);
+ name = pname;
+ }
+ p.insert(c, p.getChildCount());
+ }
+ // Simplify tree, except for root node
+ for(int i = 0; i < root.getChildCount(); i++) {
+ MutableTreeNode c = (MutableTreeNode) root.getChildAt(i);
+ MutableTreeNode c2 = simplifyTree(c, null);
+ if(c != c2) {
+ root.remove(i);
+ root.insert(c2, i);
+ }
+ }
+ return root;
+ }
+
+ /**
+ * Simplify the tree.
+ *
+ * @param cur Current node
+ * @param prefix Prefix to add
+ * @return Replacement node
+ */
+ private static MutableTreeNode simplifyTree(MutableTreeNode cur, String prefix) {
+ if(cur instanceof PackageNode) {
+ PackageNode node = (PackageNode) cur;
+ if(node.getChildCount() == 1) {
+ String newprefix = (prefix != null) ? prefix + "." + (String) node.getUserObject() : (String) node.getUserObject();
+ cur = simplifyTree((MutableTreeNode) node.getChildAt(0), newprefix);
+ }
+ else {
+ if(prefix != null) {
+ node.setUserObject(prefix + "." + (String) node.getUserObject());
+ }
+ for(int i = 0; i < node.getChildCount(); i++) {
+ MutableTreeNode c = (MutableTreeNode) node.getChildAt(i);
+ MutableTreeNode c2 = simplifyTree(c, null);
+ if(c != c2) {
+ node.remove(i);
+ node.insert(c2, i);
+ }
+ }
+ }
+ }
+ else if(cur instanceof ClassNode) {
+ ClassNode node = (ClassNode) cur;
+ if(prefix != null) {
+ node.setUserObject(prefix + "." + (String) node.getUserObject());
+ }
+ }
+ return cur;
+ }
+
+ /**
+ * Tree node representing a single class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class PackageNode extends DefaultMutableTreeNode {
+ /**
+ * Serial version
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Class name.
+ */
+ private String pkgname;
+
+ /**
+ * Current class name.
+ *
+ * @param display Displayed name
+ * @param pkgname Actual class name
+ */
+ public PackageNode(String display, String pkgname) {
+ super(display);
+ this.pkgname = pkgname;
+ }
+
+ /**
+ * Return the package name.
+ *
+ * @return Package name
+ */
+ public String getPackageName() {
+ return pkgname;
+ }
+ }
+
+ /**
+ * Tree node representing a single class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class ClassNode extends DefaultMutableTreeNode {
+ /**
+ * Serial version
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Class name.
+ */
+ private String clsname;
+
+ /**
+ * Current class name.
+ *
+ * @param display Displayed name
+ * @param clsname Actual class name
+ */
+ public ClassNode(String display, String clsname) {
+ super(display);
+ this.clsname = clsname;
+ }
+
+ /**
+ * Return the class name.
+ *
+ * @return Class name
+ */
+ public String getClassName() {
+ return clsname;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/gui/util/DynamicParameters.java b/src/de/lmu/ifi/dbs/elki/gui/util/DynamicParameters.java
index d974a6d6..2836b33c 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/util/DynamicParameters.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/util/DynamicParameters.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.util;
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,12 +28,12 @@ import java.util.BitSet;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackedParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.SerializedParameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.StringParameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Wrapper around a set of parameters for ELKI, that may not yet be complete or
@@ -141,8 +141,8 @@ public class DynamicParameters {
*/
public synchronized void updateFromTrackParameters(TrackParameters track) {
parameters.clear();
- for (Pair<Object, Parameter<?>> p : track.getAllParameters()) {
- Parameter<?> option = p.getSecond();
+ for (TrackedParameter p : track.getAllParameters()) {
+ Parameter<?> option = p.getParameter();
String value = null;
if (option.isDefined()) {
if (option.tookDefaultValue()) {
diff --git a/src/de/lmu/ifi/dbs/elki/gui/util/LogPane.java b/src/de/lmu/ifi/dbs/elki/gui/util/LogPane.java
index 4664b852..e19fd752 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/util/LogPane.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/util/LogPane.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.util;
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/gui/util/LogPanel.java b/src/de/lmu/ifi/dbs/elki/gui/util/LogPanel.java
index 11080cc9..99cf50b2 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/util/LogPanel.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/util/LogPanel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.util;
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/gui/util/ParameterTable.java b/src/de/lmu/ifi/dbs/elki/gui/util/ParameterTable.java
index 105242c0..aa94f3ef 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/util/ParameterTable.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/util/ParameterTable.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.util;
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,18 +29,19 @@ import java.awt.Component;
import java.awt.Dimension;
import java.awt.FileDialog;
import java.awt.Frame;
-import java.awt.Insets;
-import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
import java.io.File;
import java.util.BitSet;
import javax.swing.AbstractCellEditor;
import javax.swing.Action;
import javax.swing.ActionMap;
+import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
+import javax.swing.Icon;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComboBox;
@@ -50,11 +51,17 @@ import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
-import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
-
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+
+import de.lmu.ifi.dbs.elki.gui.icons.StockIcon;
+import de.lmu.ifi.dbs.elki.gui.util.ClassTree.ClassNode;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassListParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter;
@@ -134,6 +141,54 @@ public class ParameterTable extends JTable {
col1.setPreferredWidth(150);
TableColumn col2 = this.getColumnModel().getColumn(1);
col2.setPreferredWidth(650);
+ this.addKeyListener(new Handler());
+
+ // Increase row height, to make editors usable.
+ setRowHeight(getRowHeight() + 4);
+ }
+
+ /**
+ * Internal key listener.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ protected class Handler implements KeyListener {
+ @Override
+ public void keyTyped(KeyEvent e) {
+ // ignore
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if((e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) != 0) {
+ if(e.getKeyCode() == KeyEvent.VK_SPACE //
+ || e.getKeyCode() == KeyEvent.VK_ENTER //
+ || e.getKeyCode() == KeyEvent.VK_DOWN //
+ || e.getKeyCode() == KeyEvent.VK_KP_DOWN) {
+ final ParameterTable parent = ParameterTable.this;
+ if(!parent.isEditing()) {
+ int leadRow = parent.getSelectionModel().getLeadSelectionIndex();
+ int leadColumn = parent.getColumnModel().getSelectionModel().getLeadSelectionIndex();
+ parent.editCellAt(leadRow, leadColumn);
+ Component editorComponent = getEditorComponent();
+ // This is a hack, to make the content assist open immediately.
+ if(editorComponent instanceof DispatchingPanel) {
+ KeyListener[] l = ((DispatchingPanel) editorComponent).component.getKeyListeners();
+ for(KeyListener li : l) {
+ li.keyPressed(e);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ // ignore
+ }
}
/**
@@ -156,16 +211,16 @@ public class ParameterTable extends JTable {
@Override
public void setValue(Object value) {
- if (value instanceof String) {
+ if(value instanceof String) {
setText((String) value);
setToolTipText(null);
return;
}
- if (value instanceof DynamicParameters.Node) {
+ if(value instanceof DynamicParameters.Node) {
Parameter<?> o = ((DynamicParameters.Node) value).param;
// Simulate a tree using indentation - there is no JTreeTable AFAICT
StringBuilder buf = new StringBuilder();
- for (int i = 1; i < ((DynamicParameters.Node) value).depth; i++) {
+ for(int i = 1; i < ((DynamicParameters.Node) value).depth; i++) {
buf.append(' ');
}
buf.append(o.getOptionID().getName());
@@ -180,22 +235,27 @@ public class ParameterTable extends JTable {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
- if (!hasFocus) {
- if (row < parameters.size()) {
+ if(!hasFocus) {
+ if(row < parameters.size()) {
BitSet flags = parameters.getNode(row).flags;
// TODO: don't hardcode black - maybe mix the other colors, too?
c.setForeground(Color.BLACK);
- if ((flags.get(DynamicParameters.BIT_INVALID))) {
+ if((flags.get(DynamicParameters.BIT_INVALID))) {
c.setBackground(COLOR_SYNTAX_ERROR);
- } else if ((flags.get(DynamicParameters.BIT_SYNTAX_ERROR))) {
+ }
+ else if((flags.get(DynamicParameters.BIT_SYNTAX_ERROR))) {
c.setBackground(COLOR_SYNTAX_ERROR);
- } else if ((flags.get(DynamicParameters.BIT_INCOMPLETE))) {
+ }
+ else if((flags.get(DynamicParameters.BIT_INCOMPLETE))) {
c.setBackground(COLOR_INCOMPLETE);
- } else if ((flags.get(DynamicParameters.BIT_DEFAULT_VALUE))) {
+ }
+ else if((flags.get(DynamicParameters.BIT_DEFAULT_VALUE))) {
c.setBackground(COLOR_DEFAULT_VALUE);
- } else if ((flags.get(DynamicParameters.BIT_OPTIONAL))) {
+ }
+ else if((flags.get(DynamicParameters.BIT_OPTIONAL))) {
c.setBackground(COLOR_OPTIONAL);
- } else {
+ }
+ else {
c.setBackground(null);
}
}
@@ -209,7 +269,7 @@ public class ParameterTable extends JTable {
*
* @author Erich Schubert
*/
- private class DropdownEditor extends DefaultCellEditor {
+ private class DropdownEditor extends DefaultCellEditor implements KeyListener {
/**
* Serial Version
*/
@@ -236,6 +296,32 @@ public class ParameterTable extends JTable {
panel = new DispatchingPanel((JComponent) comboBox.getEditor().getEditorComponent());
panel.setLayout(new BorderLayout());
panel.add(comboBox, BorderLayout.CENTER);
+ comboBox.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3));
+ }
+
+ @Override
+ public void keyTyped(KeyEvent e) {
+ // Ignore
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if((e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) != 0) {
+ if(e.getKeyCode() == KeyEvent.VK_SPACE //
+ || e.getKeyCode() == KeyEvent.VK_ENTER //
+ || e.getKeyCode() == KeyEvent.VK_DOWN //
+ || e.getKeyCode() == KeyEvent.VK_KP_DOWN) {
+ if(!comboBox.isPopupVisible()) {
+ comboBox.showPopup();
+ e.consume();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ // Ignore
}
@Override
@@ -244,54 +330,40 @@ public class ParameterTable extends JTable {
comboBox.removeAllItems();
// Put the current value in first.
Object val = table.getValueAt(row, column);
- if (val != null && val instanceof String) {
+ if(val != null && val instanceof String) {
String sval = (String) val;
- if (sval.equals(DynamicParameters.STRING_OPTIONAL)) {
+ if(sval.equals(DynamicParameters.STRING_OPTIONAL)) {
sval = "";
}
- if (sval.startsWith(DynamicParameters.STRING_USE_DEFAULT)) {
+ if(sval.startsWith(DynamicParameters.STRING_USE_DEFAULT)) {
sval = "";
}
- if (sval != "") {
+ if(sval != "") {
comboBox.addItem(sval);
comboBox.setSelectedIndex(0);
}
}
- if (row < parameters.size()) {
+ if(row < parameters.size()) {
Parameter<?> option = parameters.getNode(row).param;
- // We can do dropdown choices for class parameters
- if (option instanceof ClassParameter<?>) {
- ClassParameter<?> cp = (ClassParameter<?>) option;
- // For parameters with a default value, offer using the default
- // For optional parameters, offer not specifying them.
- if (cp.hasDefaultValue()) {
- comboBox.addItem(DynamicParameters.STRING_USE_DEFAULT + cp.getDefaultValueAsString());
- } else if (cp.isOptional()) {
- comboBox.addItem(DynamicParameters.STRING_OPTIONAL);
- }
- // Offer the shorthand version of class names.
- for (Class<?> impl : cp.getKnownImplementations()) {
- comboBox.addItem(ClassParameter.canonicalClassName(impl, cp.getRestrictionClass()));
- }
- }
- // and for Flag parameters.
- else if (option instanceof Flag) {
- if (!Flag.SET.equals(val)) {
+ // for Flag parameters.
+ if(option instanceof Flag) {
+ if(!Flag.SET.equals(val)) {
comboBox.addItem(Flag.SET);
}
- if (!Flag.NOT_SET.equals(val)) {
+ if(!Flag.NOT_SET.equals(val)) {
comboBox.addItem(Flag.NOT_SET);
}
}
// and for Enum parameters.
- else if (option instanceof EnumParameter<?>) {
+ else if(option instanceof EnumParameter<?>) {
EnumParameter<?> ep = (EnumParameter<?>) option;
- for (String s : ep.getPossibleValues()) {
- if (ep.hasDefaultValue() && ep.getDefaultValueAsString().equals(s)) {
- if (!(DynamicParameters.STRING_USE_DEFAULT + ep.getDefaultValueAsString()).equals(val)) {
+ for(String s : ep.getPossibleValues()) {
+ if(ep.hasDefaultValue() && ep.getDefaultValueAsString().equals(s)) {
+ if(!(DynamicParameters.STRING_USE_DEFAULT + ep.getDefaultValueAsString()).equals(val)) {
comboBox.addItem(DynamicParameters.STRING_USE_DEFAULT + s);
}
- } else if (!s.equals(val)) {
+ }
+ else if(!s.equals(val)) {
comboBox.addItem(s);
}
}
@@ -307,7 +379,7 @@ public class ParameterTable extends JTable {
*
* @author Erich Schubert
*/
- private class FileNameEditor extends AbstractCellEditor implements TableCellEditor, ActionListener {
+ private class FileNameEditor extends AbstractCellEditor implements TableCellEditor, ActionListener, KeyListener {
/**
* Serial version number
*/
@@ -334,6 +406,11 @@ public class ParameterTable extends JTable {
int mode = FileDialog.LOAD;
/**
+ * Default path.
+ */
+ String defaultpath = (new File(".")).getAbsolutePath();
+
+ /**
* Constructor.
*/
public FileNameEditor() {
@@ -342,6 +419,8 @@ public class ParameterTable extends JTable {
panel.setLayout(new BorderLayout());
panel.add(textfield, BorderLayout.CENTER);
panel.add(button, BorderLayout.EAST);
+ textfield.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3));
+ textfield.addKeyListener(this);
}
/**
@@ -349,38 +428,47 @@ public class ParameterTable extends JTable {
*/
@Override
public void actionPerformed(ActionEvent e) {
- final FileDialog fc = new FileDialog(frame);
- fc.setDirectory((new File(".")).getAbsolutePath());
+ FileDialog fc = new FileDialog(frame);
+ fc.setDirectory(defaultpath);
fc.setMode(mode);
final String curr = textfield.getText();
- if (curr != null && curr.length() > 0) {
+ if(curr != null && curr.length() > 0) {
fc.setFile(curr);
}
fc.setVisible(true);
String filename = fc.getFile();
- if (filename != null) {
+ if(filename != null) {
textfield.setText(new File(fc.getDirectory(), filename).getPath());
}
+ fc.setVisible(false);
fc.dispose();
textfield.requestFocus();
-
- // Swing file chooser. Currently much worse on Linux/GTK.
- // final JFileChooser fc = new JFileChooser(new File("."));
- // final String curr = textfield.getText();
- // if (curr != null && curr.length() > 0) {
- // fc.setSelectedFile(new File(curr));
- // }
- // int returnVal = fc.showOpenDialog(button);
- //
- // if(returnVal == JFileChooser.APPROVE_OPTION) {
- // textfield.setText(fc.getSelectedFile().getPath());
- // }
- // else {
- // // Do nothing on cancel.
- // }
fireEditingStopped();
}
+ @Override
+ public void keyTyped(KeyEvent e) {
+ // Ignore
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if((e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) != 0) {
+ if(e.getKeyCode() == KeyEvent.VK_SPACE //
+ || e.getKeyCode() == KeyEvent.VK_ENTER //
+ || e.getKeyCode() == KeyEvent.VK_DOWN //
+ || e.getKeyCode() == KeyEvent.VK_KP_DOWN) {
+ e.consume();
+ actionPerformed(new ActionEvent(e.getSource(), ActionEvent.ACTION_PERFORMED, "assist"));
+ }
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ // Ignore
+ }
+
/**
* Delegate getCellEditorValue to the text field.
*/
@@ -394,21 +482,16 @@ public class ParameterTable extends JTable {
*/
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
- if (row < parameters.size()) {
+ if(row < parameters.size()) {
Parameter<?> option = parameters.getNode(row).param;
- if (option instanceof FileParameter) {
+ if(option instanceof FileParameter) {
FileParameter fp = (FileParameter) option;
File f = null;
mode = FileParameter.FileType.INPUT_FILE.equals(fp.getFileType()) ? FileDialog.LOAD : FileDialog.SAVE;
- if (fp.isDefined()) {
+ if(fp.isDefined()) {
f = fp.getValue();
}
- if (f != null) {
- String fn = f.getPath();
- textfield.setText(fn);
- } else {
- textfield.setText("");
- }
+ textfield.setText(f != null ? f.getPath() : "");
}
}
textfield.requestFocus();
@@ -417,11 +500,11 @@ public class ParameterTable extends JTable {
}
/**
- * Editor for selecting input and output file and folders names
+ * Editor for choosing classes.
*
* @author Erich Schubert
*/
- private class ClassListEditor extends AbstractCellEditor implements TableCellEditor, ActionListener {
+ private class ClassListEditor extends AbstractCellEditor implements TableCellEditor, ActionListener, KeyListener {
/**
* Serial version number
*/
@@ -443,30 +526,43 @@ public class ParameterTable extends JTable {
final JButton button = new JButton("+");
/**
- * The combobox we are abusing to produce the popup
+ * The popup menu.
*/
- final JComboBox<String> combo = new JComboBox<>();
+ final TreePopup popup;
/**
- * The popup menu.
+ * Tree model
*/
- final SuperPopup popup;
+ private TreeModel model;
+
+ /**
+ * Parameter we are currently editing.
+ */
+ private Parameter<?> option;
/**
* Constructor.
*/
public ClassListEditor() {
+ textfield.addKeyListener(this);
button.addActionListener(this);
- // So the first item doesn't get automatically selected
- combo.setEditable(true);
- combo.addActionListener(this);
- popup = new SuperPopup(combo);
+ model = new DefaultTreeModel(new DefaultMutableTreeNode());
+ popup = new TreePopup(model);
+ popup.getTree().setRootVisible(false);
+ popup.addActionListener(this);
+
+ Icon classIcon = StockIcon.getStockIcon(StockIcon.GO_NEXT);
+ Icon packageIcon = StockIcon.getStockIcon(StockIcon.PACKAGE);
+ TreePopup.Renderer renderer = (TreePopup.Renderer) popup.getTree().getCellRenderer();
+ renderer.setLeafIcon(classIcon);
+ renderer.setFolderIcon(packageIcon);
panel = new DispatchingPanel(textfield);
panel.setLayout(new BorderLayout());
panel.add(textfield, BorderLayout.CENTER);
panel.add(button, BorderLayout.EAST);
+ textfield.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3));
}
/**
@@ -474,80 +570,42 @@ public class ParameterTable extends JTable {
*/
@Override
public void actionPerformed(ActionEvent e) {
- if (e.getSource() == button) {
+ if(e.getSource() == button) {
popup.show(panel);
- } else if (e.getSource() == combo) {
- String newClass = (String) combo.getSelectedItem();
- if (newClass != null && newClass.length() > 0) {
- String val = textfield.getText();
- if (val.equals(DynamicParameters.STRING_OPTIONAL)) {
- val = "";
- }
- if (val.startsWith(DynamicParameters.STRING_USE_DEFAULT)) {
- val = "";
- }
- if (val.length() > 0) {
- val = val + ClassListParameter.LIST_SEP + newClass;
- } else {
- val = newClass;
+ return;
+ }
+ if(e.getSource() == popup) {
+ if(e.getActionCommand() == TreePopup.ACTION_CANCELED) {
+ popup.setVisible(false);
+ textfield.requestFocus();
+ return;
+ }
+ TreePath path = popup.getTree().getSelectionPath();
+ final Object comp = (path != null) ? path.getLastPathComponent() : null;
+ if(comp instanceof ClassNode) {
+ ClassNode sel = (path != null) ? (ClassNode) comp : null;
+ String newClass = (sel != null) ? sel.getClassName() : null;
+ if(newClass != null && newClass.length() > 0) {
+ if(option instanceof ClassListParameter) {
+ String val = textfield.getText();
+ if(val.equals(DynamicParameters.STRING_OPTIONAL) //
+ || val.startsWith(DynamicParameters.STRING_USE_DEFAULT)) {
+ val = "";
+ }
+ val = (val.length() > 0) ? val + ClassListParameter.LIST_SEP + newClass : newClass;
+ textfield.setText(val);
+ }
+ else {
+ textfield.setText(newClass);
+ }
+ popup.setVisible(false);
+ fireEditingStopped();
+ textfield.requestFocus();
}
- textfield.setText(val);
- popup.hide();
}
- fireEditingStopped();
- } else {
- LoggingUtil.warning("Unrecognized action event in ClassListEditor: " + e);
- }
- }
-
- /**
- * Modified popup
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- class SuperPopup extends BasicComboPopup {
- /**
- * Serial version
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor.
- *
- * @param combo Combo box used for data storage.
- */
- public SuperPopup(JComboBox<String> combo) {
- super(combo);
- }
-
- /**
- * Show the menu on a particular panel.
- *
- * This code is mostly copied from
- * {@link BasicComboPopup#getPopupLocation}
- *
- * @param parent Parent element to show at.
- */
- public void show(JPanel parent) {
- Dimension popupSize = parent.getSize();
- Insets insets = getInsets();
-
- // reduce the width of the scrollpane by the insets so that the popup
- // is the same width as the combo box.
- popupSize.setSize(popupSize.width - (insets.right + insets.left), getPopupHeightForRowCount(comboBox.getMaximumRowCount()));
- Rectangle popupBounds = computePopupBounds(0, comboBox.getBounds().height, popupSize.width, popupSize.height);
- Dimension scrollSize = popupBounds.getSize();
-
- scroller.setMaximumSize(scrollSize);
- scroller.setPreferredSize(scrollSize);
- scroller.setMinimumSize(scrollSize);
-
- list.revalidate();
-
- super.show(parent, 0, parent.getBounds().height);
+ return;
}
+ LoggingUtil.warning("Unrecognized action event in ClassListEditor: " + e);
}
/**
@@ -558,36 +616,65 @@ public class ParameterTable extends JTable {
return textfield.getText();
}
+ @Override
+ public void keyTyped(KeyEvent e) {
+ // Ignore
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if((e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) != 0) {
+ if(e.getKeyCode() == KeyEvent.VK_SPACE //
+ || e.getKeyCode() == KeyEvent.VK_ENTER //
+ || e.getKeyCode() == KeyEvent.VK_DOWN //
+ || e.getKeyCode() == KeyEvent.VK_KP_DOWN) {
+ if(!popup.isVisible()) {
+ popup.show(ClassListEditor.this.panel);
+ e.consume();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ // Ignore
+ }
+
/**
* Apply the Editor for a selected option.
*/
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
- combo.removeAllItems();
- if (row < parameters.size()) {
- Parameter<?> option = parameters.getNode(row).param;
+ if(row < parameters.size()) {
+ this.option = parameters.getNode(row).param;
+ TreeNode root;
// We can do dropdown choices for class parameters
- if (option instanceof ClassListParameter<?>) {
+ if(option instanceof ClassListParameter<?>) {
ClassListParameter<?> cp = (ClassListParameter<?>) option;
- // Offer the shorthand version of class names.
- String prefix = cp.getRestrictionClass().getPackage().getName() + ".";
- for (Class<?> impl : cp.getKnownImplementations()) {
- String name = impl.getName();
- if (name.startsWith(prefix)) {
- name = name.substring(prefix.length());
- }
- combo.addItem(name);
- }
+ root = ClassTree.build(cp.getKnownImplementations(), cp.getRestrictionClass().getPackage().getName());
+ button.setText("+");
+ }
+ else if(option instanceof ClassParameter<?>) {
+ ClassParameter<?> cp = (ClassParameter<?>) option;
+ root = ClassTree.build(cp.getKnownImplementations(), cp.getRestrictionClass().getPackage().getName());
+ button.setText("v");
+ }
+ else {
+ root = new DefaultMutableTreeNode();
}
- if (option.isDefined()) {
- if (option.tookDefaultValue()) {
+ if(option.isDefined()) {
+ if(option.tookDefaultValue()) {
textfield.setText(DynamicParameters.STRING_USE_DEFAULT + option.getDefaultValueAsString());
- } else {
+ }
+ else {
textfield.setText(option.getValueAsString());
}
- } else {
+ }
+ else {
textfield.setText("");
}
+ popup.getTree().setModel(new DefaultTreeModel(root));
}
return panel;
}
@@ -642,14 +729,16 @@ public class ParameterTable extends JTable {
final JComboBox<String> combobox = new JComboBox<>();
combobox.setEditable(true);
this.dropdownEditor = new DropdownEditor(combobox);
- this.plaintextEditor = new DefaultCellEditor(new JTextField());
+ JTextField tf = new JTextField();
+ tf.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3));
+ this.plaintextEditor = new DefaultCellEditor(tf);
this.classListEditor = new ClassListEditor();
this.fileNameEditor = new FileNameEditor();
}
@Override
public Object getCellEditorValue() {
- if (activeEditor == null) {
+ if(activeEditor == null) {
return null;
}
return activeEditor.getCellEditorValue();
@@ -657,31 +746,31 @@ public class ParameterTable extends JTable {
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
- if (value instanceof String) {
+ if(value instanceof String) {
String s = (String) value;
- if (s.startsWith(DynamicParameters.STRING_USE_DEFAULT)) {
+ if(s.startsWith(DynamicParameters.STRING_USE_DEFAULT)) {
value = s.substring(DynamicParameters.STRING_USE_DEFAULT.length());
}
}
- if (row < parameters.size()) {
+ if(row < parameters.size()) {
Parameter<?> option = parameters.getNode(row).param;
- if (option instanceof Flag) {
+ if(option instanceof Flag) {
activeEditor = dropdownEditor;
return dropdownEditor.getTableCellEditorComponent(table, value, isSelected, row, column);
}
- if (option instanceof ClassListParameter<?>) {
+ if(option instanceof ClassListParameter<?>) {
activeEditor = classListEditor;
return classListEditor.getTableCellEditorComponent(table, value, isSelected, row, column);
}
- if (option instanceof ClassParameter<?>) {
- activeEditor = dropdownEditor;
- return dropdownEditor.getTableCellEditorComponent(table, value, isSelected, row, column);
+ if(option instanceof ClassParameter<?>) {
+ activeEditor = classListEditor;
+ return classListEditor.getTableCellEditorComponent(table, value, isSelected, row, column);
}
- if (option instanceof FileParameter) {
+ if(option instanceof FileParameter) {
activeEditor = fileNameEditor;
return fileNameEditor.getTableCellEditorComponent(table, value, isSelected, row, column);
}
- if (option instanceof EnumParameter<?>) {
+ if(option instanceof EnumParameter<?>) {
activeEditor = dropdownEditor;
return dropdownEditor.getTableCellEditorComponent(table, value, isSelected, row, column);
}
@@ -733,10 +822,10 @@ public class ParameterTable extends JTable {
InputMap map = component.getInputMap(condition);
ActionMap am = component.getActionMap();
- if (map != null && am != null && isEnabled()) {
+ if(map != null && am != null && isEnabled()) {
Object binding = map.get(ks);
Action action = (binding == null) ? null : am.get(binding);
- if (action != null) {
+ if(action != null) {
return SwingUtilities.notifyAction(action, ks, e, component, e.getModifiers());
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/gui/util/ParametersModel.java b/src/de/lmu/ifi/dbs/elki/gui/util/ParametersModel.java
index 42f0a1af..82a0ee74 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/util/ParametersModel.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/util/ParametersModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.util;
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/gui/util/SavedSettingsFile.java b/src/de/lmu/ifi/dbs/elki/gui/util/SavedSettingsFile.java
index a99b7414..8e614b85 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/util/SavedSettingsFile.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/util/SavedSettingsFile.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.gui.util;
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/gui/util/TreePopup.java b/src/de/lmu/ifi/dbs/elki/gui/util/TreePopup.java
new file mode 100644
index 00000000..60ad0604
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/util/TreePopup.java
@@ -0,0 +1,412 @@
+package de.lmu.ifi.dbs.elki.gui.util;
+
+/*
+ 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.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GraphicsConfiguration;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+import javax.swing.BoxLayout;
+import javax.swing.Icon;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.JTree;
+import javax.swing.ScrollPaneConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import javax.swing.border.LineBorder;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeCellRenderer;
+import javax.swing.tree.TreeModel;
+
+/**
+ * Popup menu that contains a JTree.
+ *
+ * @author Erich Schubert
+ */
+public class TreePopup extends JPopupMenu {
+ /**
+ * Serialization version.
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Action string for confirmed operations (enter or click).
+ */
+ public static final String ACTION_SELECTED = "selected";
+
+ /**
+ * Action string for canceled operations (escape button pressed).
+ */
+ public static final String ACTION_CANCELED = "canceled";
+
+ /**
+ * Tree.
+ */
+ protected JTree tree;
+
+ /**
+ * Scroll pane, containing the tree.
+ */
+ protected JScrollPane scroller;
+
+ /**
+ * Tree model.
+ */
+ private TreeModel model;
+
+ /**
+ * Event handler
+ */
+ private Handler handler = new Handler();
+
+ /**
+ * Border of the popup.
+ */
+ private static Border TREE_BORDER = new LineBorder(Color.BLACK, 1);
+
+ /**
+ * Constructor with an empty tree model.
+ *
+ * This needs to also add a root node, and therefore sets
+ * {@code getTree().setRootVisible(false)}.
+ */
+ public TreePopup() {
+ this(new DefaultTreeModel(new DefaultMutableTreeNode()));
+ tree.setRootVisible(false);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param model Tree model
+ */
+ public TreePopup(TreeModel model) {
+ super();
+ this.setName("TreePopup.popup");
+ this.model = model;
+
+ // UI construction of the popup.
+ tree = createTree();
+ scroller = createScroller();
+ configurePopup();
+ }
+
+ /**
+ * Creates the JList used in the popup to display the items in the combo box
+ * model. This method is called when the UI class is created.
+ *
+ * @return a <code>JList</code> used to display the combo box items
+ */
+ protected JTree createTree() {
+ JTree tree = new JTree(model);
+ tree.setName("TreePopup.tree");
+ tree.setFont(getFont());
+ tree.setForeground(getForeground());
+ tree.setBackground(getBackground());
+ tree.setBorder(null);
+ tree.setFocusable(true);
+ tree.addMouseListener(handler);
+ tree.addKeyListener(handler);
+ tree.setCellRenderer(new Renderer());
+ return tree;
+ }
+
+ /**
+ * Configure the popup display.
+ */
+ protected void configurePopup() {
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ setBorderPainted(true);
+ setBorder(TREE_BORDER);
+ setOpaque(false);
+ add(scroller);
+ setDoubleBuffered(true);
+ setFocusable(false);
+ }
+
+ /**
+ * Creates the scroll pane which houses the scrollable tree.
+ */
+ protected JScrollPane createScroller() {
+ JScrollPane sp = new JScrollPane(tree, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
+ sp.setHorizontalScrollBar(null);
+ sp.setName("TreePopup.scrollPane");
+ sp.setFocusable(false);
+ sp.getVerticalScrollBar().setFocusable(false);
+ sp.setBorder(null);
+ return sp;
+ }
+
+ /**
+ * Access the tree contained.
+ *
+ * @return Tree
+ */
+ public JTree getTree() {
+ return tree;
+ }
+
+ /**
+ * Display the popup, attached to the given component.
+ *
+ * @param parent Parent component
+ */
+ public void show(Component parent) {
+ Dimension parentSize = parent.getSize();
+ Insets insets = getInsets();
+
+ // reduce the width of the scrollpane by the insets so that the popup
+ // is the same width as the combo box.
+ parentSize.setSize(parentSize.width - (insets.right + insets.left), 10 * parentSize.height);
+ Dimension scrollSize = computePopupBounds(parent, 0, getBounds().height, parentSize.width, parentSize.height).getSize();
+
+ scroller.setMaximumSize(scrollSize);
+ scroller.setPreferredSize(scrollSize);
+ scroller.setMinimumSize(scrollSize);
+
+ super.show(parent, 0, parent.getHeight());
+ tree.requestFocusInWindow();
+ }
+
+ protected Rectangle computePopupBounds(Component parent, int px, int py, int pw, int ph) {
+ Toolkit toolkit = Toolkit.getDefaultToolkit();
+ Rectangle screenBounds;
+
+ // Calculate the desktop dimensions relative to the combo box.
+ GraphicsConfiguration gc = parent.getGraphicsConfiguration();
+ Point p = new Point();
+ SwingUtilities.convertPointFromScreen(p, parent);
+ if(gc != null) {
+ Insets screenInsets = toolkit.getScreenInsets(gc);
+ screenBounds = gc.getBounds();
+ screenBounds.width -= (screenInsets.left + screenInsets.right);
+ screenBounds.height -= (screenInsets.top + screenInsets.bottom);
+ screenBounds.x += (p.x + screenInsets.left);
+ screenBounds.y += (p.y + screenInsets.top);
+ }
+ else {
+ screenBounds = new Rectangle(p, toolkit.getScreenSize());
+ }
+
+ Rectangle rect = new Rectangle(px, py, pw, ph);
+ if(py + ph > screenBounds.y + screenBounds.height && ph < screenBounds.height) {
+ rect.y = -rect.height;
+ }
+ return rect;
+ }
+
+ /**
+ * Register an action listener.
+ *
+ * @param listener Action listener
+ */
+ public void addActionListener(ActionListener listener) {
+ listenerList.add(ActionListener.class, listener);
+ }
+
+ /**
+ * Unregister an action listener.
+ *
+ * @param listener Action listener
+ */
+ public void removeActionListener(ActionListener listener) {
+ listenerList.remove(ActionListener.class, listener);
+ }
+
+ /**
+ * Notify action listeners.
+ *
+ * @param event the <code>ActionEvent</code> object
+ */
+ protected void fireActionPerformed(ActionEvent event) {
+ Object[] listeners = listenerList.getListenerList();
+ for(int i = listeners.length - 2; i >= 0; i -= 2) {
+ if(listeners[i] == ActionListener.class) {
+ ((ActionListener) listeners[i + 1]).actionPerformed(event);
+ }
+ }
+ }
+
+ /**
+ * Tree cell render.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public class Renderer extends JPanel implements TreeCellRenderer {
+ /**
+ * Serial version
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Label to render
+ */
+ JLabel label;
+
+ /**
+ * Colors
+ */
+ private Color selbg, defbg, selfg, deffg;
+
+ /**
+ * Icons
+ */
+ private Icon leafIcon, folderIcon;
+
+ /**
+ * Constructor.
+ */
+ protected Renderer() {
+ selbg = UIManager.getColor("Tree.selectionBackground");
+ defbg = UIManager.getColor("Tree.textBackground");
+ selfg = UIManager.getColor("Tree.selectionForeground");
+ deffg = UIManager.getColor("Tree.textForeground");
+
+ setLayout(new BorderLayout());
+ add(label = new JLabel("This should never be rendered."));
+ }
+
+ @Override
+ public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+ label.setText((String) ((DefaultMutableTreeNode) value).getUserObject());
+ setForeground(selected ? selfg : deffg);
+ setBackground(selected ? selbg : defbg);
+ label.setIcon(leaf ? leafIcon : folderIcon);
+ setPreferredSize(new Dimension(1000, label.getPreferredSize().height));
+ return this;
+ }
+
+ /**
+ * Set the leaf icon
+ *
+ * @param leafIcon Leaf icon
+ */
+ public void setLeafIcon(Icon leafIcon) {
+ this.leafIcon = leafIcon;
+ }
+
+ /**
+ * Set the folder icon.
+ *
+ * @param folderIcon Folder icon
+ */
+ public void setFolderIcon(Icon folderIcon) {
+ this.folderIcon = folderIcon;
+ }
+ }
+
+ /**
+ * Event handler class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ protected class Handler implements MouseListener, KeyListener, FocusListener {
+ @Override
+ public void keyTyped(KeyEvent e) {
+ if(e.getKeyChar() == '\n') {
+ e.consume();
+ }
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if(e.getKeyCode() == KeyEvent.VK_ENTER) {
+ fireActionPerformed(new ActionEvent(TreePopup.this, ActionEvent.ACTION_PERFORMED, ACTION_SELECTED, e.getWhen(), e.getModifiers()));
+ e.consume();
+ return;
+ }
+ if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {
+ fireActionPerformed(new ActionEvent(TreePopup.this, ActionEvent.ACTION_PERFORMED, ACTION_CANCELED, e.getWhen(), e.getModifiers()));
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ if(e.getKeyCode() == KeyEvent.VK_ENTER) {
+ e.consume();
+ }
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if(e.getButton() == MouseEvent.BUTTON1) {
+ fireActionPerformed(new ActionEvent(TreePopup.this, ActionEvent.ACTION_PERFORMED, ACTION_SELECTED, e.getWhen(), e.getModifiers()));
+ }
+ // ignore
+ }
+
+ @Override
+ public void mousePressed(MouseEvent e) {
+ // ignore
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ // ignore
+ }
+
+ @Override
+ public void mouseEntered(MouseEvent e) {
+ // ignore
+ }
+
+ @Override
+ public void mouseExited(MouseEvent e) {
+ // ignore
+ }
+
+ @Override
+ public void focusGained(FocusEvent e) {
+ // ignore
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ fireActionPerformed(new ActionEvent(TreePopup.this, ActionEvent.ACTION_PERFORMED, ACTION_CANCELED));
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/gui/util/package-info.java b/src/de/lmu/ifi/dbs/elki/gui/util/package-info.java
index 706f587a..55f3d259 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/util/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/util/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/index/AbstractIndex.java b/src/de/lmu/ifi/dbs/elki/index/AbstractIndex.java
index c9dbf3a0..ab4a1e3a 100644
--- a/src/de/lmu/ifi/dbs/elki/index/AbstractIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/AbstractIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
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/index/AbstractRefiningIndex.java b/src/de/lmu/ifi/dbs/elki/index/AbstractRefiningIndex.java
index b266824a..f196b6ce 100644
--- a/src/de/lmu/ifi/dbs/elki/index/AbstractRefiningIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/AbstractRefiningIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
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,6 @@ import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.AbstractDistanceKNNQuery;
import de.lmu.ifi.dbs.elki.database.query.range.AbstractDistanceRangeQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.statistics.Counter;
@@ -76,14 +75,14 @@ public abstract class AbstractRefiningIndex<O> extends AbstractIndex<O> {
* @param i Increment.
*/
protected void countRefinements(int i) {
- if (refinements != null) {
+ if(refinements != null) {
refinements.increment(i);
}
}
@Override
public void logStatistics() {
- if (refinements != null) {
+ if(refinements != null) {
getLogger().statistics(refinements);
}
}
@@ -106,13 +105,13 @@ public abstract class AbstractRefiningIndex<O> extends AbstractIndex<O> {
*
* @apiviz.excludeSubtypes
*/
- public abstract class AbstractRangeQuery<D extends Distance<D>> extends AbstractDistanceRangeQuery<O, D> {
+ public abstract class AbstractRangeQuery extends AbstractDistanceRangeQuery<O> {
/**
* Constructor.
*
* @param distanceQuery Distance query object
*/
- public AbstractRangeQuery(DistanceQuery<O, D> distanceQuery) {
+ public AbstractRangeQuery(DistanceQuery<O> distanceQuery) {
super(distanceQuery);
}
@@ -123,7 +122,7 @@ public abstract class AbstractRefiningIndex<O> extends AbstractIndex<O> {
* @param q Query object
* @return Distance
*/
- protected D refine(DBIDRef id, O q) {
+ protected double refine(DBIDRef id, O q) {
AbstractRefiningIndex.this.countRefinements(1);
return distanceQuery.distance(q, id);
}
@@ -145,13 +144,13 @@ public abstract class AbstractRefiningIndex<O> extends AbstractIndex<O> {
*
* @apiviz.excludeSubtypes
*/
- public abstract class AbstractKNNQuery<D extends Distance<D>> extends AbstractDistanceKNNQuery<O, D> {
+ public abstract class AbstractKNNQuery extends AbstractDistanceKNNQuery<O> {
/**
* Constructor.
*
* @param distanceQuery Distance query object
*/
- public AbstractKNNQuery(DistanceQuery<O, D> distanceQuery) {
+ public AbstractKNNQuery(DistanceQuery<O> distanceQuery) {
super(distanceQuery);
}
@@ -162,7 +161,7 @@ public abstract class AbstractRefiningIndex<O> extends AbstractIndex<O> {
* @param q Query object
* @return Distance
*/
- protected D refine(DBID id, O q) {
+ protected double refine(DBIDRef id, O q) {
AbstractRefiningIndex.this.countRefinements(1);
return distanceQuery.distance(q, id);
}
diff --git a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveDoubleSimilarityFunction.java b/src/de/lmu/ifi/dbs/elki/index/DistanceIndex.java
index 2d886706..b9094c24 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/similarityfunction/PrimitiveDoubleSimilarityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/index/DistanceIndex.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.distance.similarityfunction;
+package de.lmu.ifi.dbs.elki.index;
/*
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,30 @@ 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;
+import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
/**
- * 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.
+ * Index with support for distance queries (e.g. precomputed distance matrixes,
+ * caches)
*
* @author Erich Schubert
*
+ * @apiviz.landmark
+ * @apiviz.excludeSubtypes
+ * @apiviz.has DistanceQuery oneway - - «provides»
+ *
* @param <O> Object type
*/
-public interface PrimitiveDoubleSimilarityFunction<O> extends PrimitiveSimilarityFunction<O, DoubleDistance> {
+public interface DistanceIndex<O> extends Index {
/**
- * Computes the similarity between two given Objects according to this
- * similarity function.
+ * Get a KNN query object for the given distance query and k.
+ *
+ * This function MAY return null, when the given distance is not supported!
*
- * @param o1 first Object
- * @param o2 second Object
- * @return the similarity between two given Objects according to this
- * similarity function
+ * @param distanceFunction Distance function to use.
+ * @param hints Hints for the optimizer
+ * @return KNN Query object or {@code null}
*/
- double doubleSimilarity(O o1, O o2);
-}
+ DistanceQuery<O> getDistanceQuery(DistanceFunction<? super O> distanceFunction, Object... hints);
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/DynamicIndex.java b/src/de/lmu/ifi/dbs/elki/index/DynamicIndex.java
index 53f6d5fe..c6307dc3 100644
--- a/src/de/lmu/ifi/dbs/elki/index/DynamicIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/DynamicIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
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/index/Index.java b/src/de/lmu/ifi/dbs/elki/index/Index.java
index e2156a04..beb1df1c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/Index.java
+++ b/src/de/lmu/ifi/dbs/elki/index/Index.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
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/index/IndexFactory.java b/src/de/lmu/ifi/dbs/elki/index/IndexFactory.java
index 80ac2ef5..6d82d2c5 100644
--- a/src/de/lmu/ifi/dbs/elki/index/IndexFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/IndexFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
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.index;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Factory interface for indexes.
@@ -39,7 +38,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
* @param <V> Input object type
* @param <I> Index type
*/
-public interface IndexFactory<V, I extends Index> extends Parameterizable {
+public interface IndexFactory<V, I extends Index> {
/**
* Sets the database in the distance function of this index (if existing).
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/KNNIndex.java b/src/de/lmu/ifi/dbs/elki/index/KNNIndex.java
index 0384a437..9944bd80 100644
--- a/src/de/lmu/ifi/dbs/elki/index/KNNIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/KNNIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
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.index;
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.distance.distancevalue.Distance;
/**
* Index with support for kNN queries.
@@ -44,10 +43,9 @@ public interface KNNIndex<O> extends Index {
*
* This function MAY return null, when the given distance is not supported!
*
- * @param <D> Distance type
* @param distanceQuery Distance query
* @param hints Hints for the optimizer
* @return KNN Query object or {@code null}
*/
- <D extends Distance<D>> KNNQuery<O, D> getKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints);
+ KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/PagedIndexFactory.java b/src/de/lmu/ifi/dbs/elki/index/PagedIndexFactory.java
index 211a0fb3..a905f6f2 100644
--- a/src/de/lmu/ifi/dbs/elki/index/PagedIndexFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/PagedIndexFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
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/index/RKNNIndex.java b/src/de/lmu/ifi/dbs/elki/index/RKNNIndex.java
index 5a1f0f84..e5e32842 100644
--- a/src/de/lmu/ifi/dbs/elki/index/RKNNIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/RKNNIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
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.index;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Index with support for kNN queries.
@@ -44,10 +43,9 @@ public interface RKNNIndex<O> extends Index {
*
* This function MAY return null, when the given distance is not supported!
*
- * @param <D> Distance type
* @param distanceQuery Distance query
* @param hints Hints for the optimizer
* @return KNN Query object or {@code null}
*/
- <D extends Distance<D>> RKNNQuery<O, D> getRKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints);
+ RKNNQuery<O> getRKNNQuery(DistanceQuery<O> distanceQuery, Object... hints);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/RangeIndex.java b/src/de/lmu/ifi/dbs/elki/index/RangeIndex.java
index cc5b7493..7a951c0b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/RangeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/RangeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
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.index;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Index with support for kNN queries.
@@ -44,10 +43,9 @@ public interface RangeIndex<O> extends Index {
*
* This function MAY return null, when the given distance is not supported!
*
- * @param <D> Distance type
* @param distanceQuery Distance query
* @param hints Hints for the optimizer
* @return KNN Query object or {@code null}
*/
- <D extends Distance<D>> RangeQuery<O, D> getRangeQuery(DistanceQuery<O, D> distanceQuery, Object... hints);
+ RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/distancematrix/PrecomputedDistanceMatrix.java b/src/de/lmu/ifi/dbs/elki/index/distancematrix/PrecomputedDistanceMatrix.java
new file mode 100644
index 00000000..83612236
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/distancematrix/PrecomputedDistanceMatrix.java
@@ -0,0 +1,293 @@
+package de.lmu.ifi.dbs.elki.index.distancematrix;
+
+/*
+ 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.type.TypeInformation;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRange;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+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.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.index.AbstractIndex;
+import de.lmu.ifi.dbs.elki.index.DistanceIndex;
+import de.lmu.ifi.dbs.elki.index.IndexFactory;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.logging.statistics.LongStatistic;
+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.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
+
+/**
+ * Distance matrix, for precomputing similarity for a small data set.
+ *
+ * This class uses a linear memory layout (not a ragged array), and assumes
+ * symmetry as well as strictness. This way, it only stores the upper triangle
+ * matrix with double precision. It has to store (n-1) * (n-2) distance values
+ * in memory, requiring 8 * (n-1) * (n-2) bytes. Since Java has a size limit of
+ * arrays of 31 bits (signed integer), we can store at most 2^16 objects
+ * (precisely, 65536 objects) in a single array, which needs about 16 GB of RAM.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has PrecomputedDistanceQuery
+ *
+ * @param <O> Object type
+ */
+public class PrecomputedDistanceMatrix<O> extends AbstractIndex<O> implements DistanceIndex<O> {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(PrecomputedDistanceMatrix.class);
+
+ /**
+ * Nested distance function.
+ */
+ final protected DistanceFunction<? super O> distanceFunction;
+
+ /**
+ * Nested distance query.
+ */
+ protected DistanceQuery<O> distanceQuery;
+
+ /**
+ * Distance matrix.
+ */
+ private double[] matrix = null;
+
+ /**
+ * DBID range.
+ */
+ private DBIDRange ids;
+
+ /**
+ * Size of DBID range.
+ */
+ private int size;
+
+ /**
+ * Constructor.
+ *
+ * @param relation Data relation
+ * @param distanceFunction Distance function
+ */
+ public PrecomputedDistanceMatrix(Relation<O> relation, DistanceFunction<? super O> distanceFunction) {
+ super(relation);
+ this.distanceFunction = distanceFunction;
+
+ if(!distanceFunction.isSymmetric()) {
+ throw new AbortException("Distance matrixes currently only support symmetric distance functions (Patches welcome).");
+ }
+ }
+
+ @Override
+ public void initialize() {
+ DBIDs rids = relation.getDBIDs();
+ if(!(rids instanceof DBIDRange)) {
+ throw new AbortException("Distance matrixes are currently only supported for DBID ranges (as used by static databases) for performance reasons (Patches welcome).");
+ }
+ ids = (DBIDRange) rids;
+ size = ids.size();
+ if(size > 65536) {
+ throw new AbortException("Distance matrixes currently have a limit of 65536 objects (~16 GB). After this, the array size exceeds the Java integer range, and a different data structure needs to be used.");
+ }
+
+ distanceQuery = distanceFunction.instantiate(relation);
+
+ int msize = triangleSize(size);
+ matrix = new double[msize];
+ DBIDArrayIter ix = ids.iter(), iy = ids.iter();
+
+ FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Precomputing distance matrix", msize, LOG) : null;
+ int pos = 0;
+ for(ix.seek(0); ix.valid(); ix.advance()) {
+ // y < x -- must match {@link #getOffset}!
+ for(iy.seek(0); iy.getOffset() < ix.getOffset(); iy.advance()) {
+ matrix[pos] = distanceQuery.distance(ix, iy);
+ pos++;
+ LOG.incrementProcessed(prog);
+ }
+ }
+ LOG.ensureCompleted(prog);
+ }
+
+ /**
+ * Compute the size of a complete x by x triangle (minus diagonal)
+ *
+ * @param x Offset
+ * @return Size of complete triangle
+ */
+ protected static int triangleSize(int x) {
+ return (x * (x - 1)) >>> 1;
+ }
+
+ /**
+ * Array offset computation.
+ *
+ * @param x X parameter
+ * @param y Y parameter
+ * @return Array offset
+ */
+ private int getOffset(int x, int y) {
+ return (y < x) ? (triangleSize(x) + y) : (triangleSize(y) + x);
+ }
+
+ @Override
+ public void logStatistics() {
+ if(matrix != null) {
+ LOG.statistics(new LongStatistic(this.getClass().getName() + ".matrix-size", matrix.length));
+ }
+ }
+
+ @Override
+ public String getLongName() {
+ return "Precomputed Distance Matrix";
+ }
+
+ @Override
+ public String getShortName() {
+ return "distance-matrix";
+ }
+
+ @Override
+ public DistanceQuery<O> getDistanceQuery(DistanceFunction<? super O> distanceFunction, Object... hints) {
+ if(this.distanceQuery.getDistanceFunction().equals(distanceFunction)) {
+ return new PrecomputedDistanceQuery();
+ }
+ return null;
+ }
+
+ /**
+ * Distance query using the precomputed matrix.
+ *
+ * @author Erich Schubert
+ */
+ private class PrecomputedDistanceQuery implements DistanceQuery<O> {
+ @Override
+ public double distance(DBIDRef id1, DBIDRef id2) {
+ final int x = ids.getOffset(id1), y = ids.getOffset(id2);
+ return (x != y) ? matrix[getOffset(x, y)] : 0.;
+ }
+
+ @Override
+ public double distance(O o1, DBIDRef id2) {
+ return distanceQuery.distance(o1, id2);
+ }
+
+ @Override
+ public double distance(DBIDRef id1, O o2) {
+ return distanceQuery.distance(id1, o2);
+ }
+
+ @Override
+ public double distance(O o1, O o2) {
+ return distanceQuery.distance(o1, o2);
+ }
+
+ @Override
+ public DistanceFunction<? super O> getDistanceFunction() {
+ return distanceQuery.getDistanceFunction();
+ }
+
+ @Override
+ public Relation<? extends O> getRelation() {
+ return relation;
+ }
+ }
+
+ /**
+ * Factory for the index.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has PrecomputedDistanceMatrix
+ *
+ * @param <O> Object type
+ */
+ public static class Factory<O> implements IndexFactory<O, PrecomputedDistanceMatrix<O>> {
+ /**
+ * Nested distance function.
+ */
+ final protected DistanceFunction<? super O> distanceFunction;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceFunction Distance function
+ */
+ public Factory(DistanceFunction<? super O> distanceFunction) {
+ super();
+ this.distanceFunction = distanceFunction;
+ }
+
+ @Override
+ public PrecomputedDistanceMatrix<O> instantiate(Relation<O> relation) {
+ return new PrecomputedDistanceMatrix<>(relation, distanceFunction);
+ }
+
+ @Override
+ public TypeInformation getInputTypeRestriction() {
+ return distanceFunction.getInputTypeRestriction();
+ }
+
+ /**
+ * Parameterizer.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <O> Object type
+ */
+ public static class Parameterizer<O> extends AbstractParameterizer {
+ /**
+ * Option parameter for the precomputed distance matrix.
+ */
+ public static final OptionID DISTANCE_ID = new OptionID("matrix.distance", "Distance function for the precomputed distance matrix.");
+
+ /**
+ * Nested distance function.
+ */
+ protected DistanceFunction<? super O> distanceFunction;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ ObjectParameter<DistanceFunction<? super O>> distanceP = new ObjectParameter<>(DISTANCE_ID, DistanceFunction.class);
+ if(config.grab(distanceP)) {
+ distanceFunction = distanceP.instantiateClass(config);
+ }
+ }
+
+ @Override
+ protected Factory<O> makeInstance() {
+ return new Factory<>(distanceFunction);
+ }
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/index/distancematrix/package-info.java b/src/de/lmu/ifi/dbs/elki/index/distancematrix/package-info.java
new file mode 100644
index 00000000..08593048
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/distancematrix/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Precomputed distance matrix.
+ */
+
+/*
+ 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.index.distancematrix; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/idistance/InMemoryIDistanceIndex.java b/src/de/lmu/ifi/dbs/elki/index/idistance/InMemoryIDistanceIndex.java
new file mode 100644
index 00000000..926e77ad
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/idistance/InMemoryIDistanceIndex.java
@@ -0,0 +1,559 @@
+package de.lmu.ifi.dbs.elki.index.idistance;
+
+/*
+ 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.algorithm.clustering.kmeans.initialization.KMedoidsInitialization;
+import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
+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.query.range.RangeQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.index.AbstractRefiningIndex;
+import de.lmu.ifi.dbs.elki.index.IndexFactory;
+import de.lmu.ifi.dbs.elki.index.KNNIndex;
+import de.lmu.ifi.dbs.elki.index.RangeIndex;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.statistics.DoubleStatistic;
+import de.lmu.ifi.dbs.elki.logging.statistics.LongStatistic;
+import de.lmu.ifi.dbs.elki.math.MeanVarianceMinMax;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+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;
+import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
+
+/**
+ * In-memory iDistance index, a metric indexing method using a reference point
+ * embedding.
+ *
+ * <b>Important note:</b> we are currently using a different query strategy. The
+ * original publication discusses queries based on repeated <em>radius</em>
+ * queries. We use a strategy based on shrinking spheres, iteratively refined
+ * starting with the closes reference point. We also do not use a B+-tree as
+ * data structure, but simple in-memory lists. Therefore, we cannot report page
+ * accesses needed.
+ *
+ * Feel free to contribute improved query strategies. All the code is
+ * essentially here, you only need to query every reference point list, not just
+ * the best.
+ *
+ * Reference:
+ * <p>
+ * C. Yu, B. C. Ooi, K. L. Tan, H. V. Jagadish<br />
+ * Indexing the Distance: An Efficient Method to KNN Processing.<br />
+ * In Proceedings of the 27th International Conference on Very Large Data Bases
+ * </p>
+ *
+ * <p>
+ * H. V. Jagadish, B. C. Ooi, K. L. Tan, C. Yu, R. Zhang<br />
+ * iDistance: An adaptive B+-tree based indexing method for nearest neighbor
+ * search.<br />
+ * ACM Transactions on Database Systems (TODS), 30(2), 364-397.
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Object type
+ */
+@Reference(authors = "C. Yu, B. C. Ooi, K. L. Tan, H. V. Jagadish", title = "Indexing the distance: An efficient method to knn processing", booktitle = "In Proceedings of the 27th International Conference on Very Large Data Bases", url = "http://www.vldb.org/conf/2001/P421.pdf")
+public class InMemoryIDistanceIndex<O> extends AbstractRefiningIndex<O> implements RangeIndex<O>, KNNIndex<O> {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(InMemoryIDistanceIndex.class);
+
+ /**
+ * Distance query.
+ */
+ private DistanceQuery<O> distanceQuery;
+
+ /**
+ * Initialization method.
+ */
+ private KMedoidsInitialization<O> initialization;
+
+ /**
+ * Number of reference points.
+ */
+ private int numref;
+
+ /**
+ * Reference points.
+ */
+ private ArrayDBIDs referencepoints;
+
+ /**
+ * The actual index.
+ */
+ private ModifiableDoubleDBIDList[] index;
+
+ /**
+ * Second reference, for documentation generation.
+ */
+ @Reference(authors = "H. V. Jagadish, B. C. Ooi, K. L. Tan, C. Yu, R. Zhang", title = "iDistance: An adaptive B+-tree based indexing method for nearest neighbor search", booktitle = "ACM Transactions on Database Systems (TODS), 30(2), 364-397")
+ public static final Void SECOND_REFERENCE = null;
+
+ /**
+ * Constructor.
+ *
+ * @param relation Data relation
+ * @param distance Distance
+ * @param initialization Initialization method
+ * @param numref Number of reference points
+ */
+ public InMemoryIDistanceIndex(Relation<O> relation, DistanceQuery<O> distance, KMedoidsInitialization<O> initialization, int numref) {
+ super(relation);
+ this.distanceQuery = distance;
+ this.initialization = initialization;
+ this.numref = numref;
+ if(!distance.getDistanceFunction().isMetric()) {
+ LOG.warning("iDistance assumes metric distance functions.\n" //
+ + distance.getDistanceFunction().getClass() + " does not report itself as metric.\n" //
+ + "iDistance will run, but may yield approximate results.");
+ }
+ }
+
+ @Override
+ public void initialize() {
+ referencepoints = DBIDUtil.ensureArray(initialization.chooseInitialMedoids(numref, relation.getDBIDs(), distanceQuery));
+ final int k = referencepoints.size(); // should be the same k anyway.
+ index = new ModifiableDoubleDBIDList[k];
+ for(int i = 0; i < k; i++) {
+ index[i] = DBIDUtil.newDistanceDBIDList(relation.size() / (2 * k));
+ }
+ // TODO: add optimized codepath for primitive distances.
+ DBIDArrayIter riter = referencepoints.iter();
+ for(DBIDIter oiter = relation.iterDBIDs(); oiter.valid(); oiter.advance()) {
+ double bestd = Double.POSITIVE_INFINITY;
+ int besti = -1;
+ for(riter.seek(0); riter.valid(); riter.advance()) {
+ double dist = distanceQuery.distance(oiter, riter);
+ if(dist < bestd) {
+ bestd = dist;
+ besti = riter.getOffset();
+ }
+ }
+ assert (besti >= 0 && besti < k);
+ index[besti].add(bestd, oiter);
+ }
+
+ // Sort index.
+ for(int i = 0; i < k; i++) {
+ index[i].sort();
+ }
+ }
+
+ @Override
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ // Query on the relation we index
+ if(distanceQuery.getRelation() != relation) {
+ return null;
+ }
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
+ if(!this.getDistanceFunction().equals(distanceFunction)) {
+ if(LOG.isDebugging()) {
+ LOG.debug("Distance function not supported by index - or 'equals' not implemented right!");
+ }
+ return null;
+ }
+ return new IDistanceKNNQuery(distanceQuery);
+ }
+
+ @Override
+ public RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ // Query on the relation we index
+ if(distanceQuery.getRelation() != relation) {
+ return null;
+ }
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
+ if(!this.getDistanceFunction().equals(distanceFunction)) {
+ if(LOG.isDebugging()) {
+ LOG.debug("Distance function not supported by index - or 'equals' not implemented right!");
+ }
+ return null;
+ }
+ return new IDistanceRangeQuery(distanceQuery);
+ }
+
+ /**
+ * Distance function.
+ *
+ * @return Distance function
+ */
+ private DistanceFunction<? super O> getDistanceFunction() {
+ return distanceQuery.getDistanceFunction();
+ }
+
+ @Override
+ public String getLongName() {
+ return "iDistance index";
+ }
+
+ @Override
+ public String getShortName() {
+ return "idistance-index";
+ }
+
+ @Override
+ public Logging getLogger() {
+ return LOG;
+ }
+
+ @Override
+ public void logStatistics() {
+ super.logStatistics();
+ MeanVarianceMinMax mm = new MeanVarianceMinMax();
+ for(int i = 0; i < index.length; i++) {
+ mm.put(index[i].size());
+ }
+ LOG.statistics(new LongStatistic(InMemoryIDistanceIndex.class.getName() + ".size.min", (int) mm.getMin()));
+ LOG.statistics(new DoubleStatistic(InMemoryIDistanceIndex.class.getName() + ".size.mean", mm.getMean()));
+ LOG.statistics(new LongStatistic(InMemoryIDistanceIndex.class.getName() + ".size.max", (int) mm.getMax()));
+ }
+
+ /**
+ * Sort the reference points by distance to the query object
+ *
+ * @param distanceQuery Distance query
+ * @param obj Query object
+ * @param referencepoints Iterator for reference points
+ * @return Sorted array.
+ */
+ protected static <O> DoubleIntPair[] rankReferencePoints(DistanceQuery<O> distanceQuery, O obj, ArrayDBIDs referencepoints) {
+ DoubleIntPair[] priority = new DoubleIntPair[referencepoints.size()];
+ // Compute distances to reference points.
+ for(DBIDArrayIter iter = referencepoints.iter(); iter.valid(); iter.advance()) {
+ final int i = iter.getOffset();
+ final double dist = distanceQuery.distance(obj, iter);
+ priority[i] = new DoubleIntPair(dist, i);
+ }
+ Arrays.sort(priority);
+ return priority;
+ }
+
+ /**
+ * Seek an iterator to the desired position, using binary search.
+ *
+ * @param index Index to search
+ * @param iter Iterator
+ * @param val Distance to search to
+ */
+ protected static void binarySearch(ModifiableDoubleDBIDList index, DoubleDBIDListIter iter, double val) {
+ // Binary search. TODO: move this into the DoubleDBIDList class.
+ int left = 0, right = index.size();
+ while(left < right) {
+ final int mid = (left + right) >>> 1;
+ final double curd = iter.seek(mid).doubleValue();
+ if(val < curd) {
+ right = mid;
+ }
+ else if(val > curd) {
+ left = mid + 1;
+ }
+ else {
+ left = mid;
+ break;
+ }
+ }
+ if(left >= index.size()) {
+ --left;
+ }
+ iter.seek(left);
+ }
+
+ /**
+ * kNN query implementation.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ protected class IDistanceKNNQuery extends AbstractRefiningIndex<O>.AbstractKNNQuery {
+ /**
+ * Constructor.
+ *
+ * @param distanceQuery Distance query
+ */
+ public IDistanceKNNQuery(DistanceQuery<O> distanceQuery) {
+ super(distanceQuery);
+ }
+
+ @Override
+ public KNNList getKNNForObject(O obj, int k) {
+ DoubleIntPair[] priority = rankReferencePoints(distanceQuery, obj, referencepoints);
+ // Approximate kNN search. We do not check _every_ list.
+ KNNHeap heap = DBIDUtil.newHeap(k);
+
+ for(DoubleIntPair pair : priority) {
+ final ModifiableDoubleDBIDList nindex = index[pair.second];
+ final double refd = pair.first;
+
+ final DoubleDBIDListIter ifwd = nindex.iter(), ibwd = nindex.iter();
+ binarySearch(nindex, ibwd, refd);
+ ifwd.seek(ibwd.getOffset() + 1);
+
+ // This assumes a metric, as we exploit triangle inequality:
+ // Lower bound for candidates further from the reference object:
+ // d(candidate, reference) <= d(candidate, query) + d(query, reference)
+ // d(candidate, reference) - d(query, reference) <= d(candidate, query)
+ double lbfwd = ifwd.valid() ? Math.abs(ifwd.doubleValue() - refd) : Double.NaN;
+ // Lower bound for candidates closer to the reference object:
+ // d(query, reference) <= d(query, candidate) + d(candidate, reference)
+ // d(query, reference) - d(candidate, reference) <= d(query, candidate)
+ double lbbwd = ibwd.valid() ? Math.abs(ibwd.doubleValue() - refd) : Double.NaN;
+ // Current query radius.
+ double kdist = heap.getKNNDistance();
+ while(true) {
+ // Handle NaN carefully.
+ if(!(lbfwd <= kdist) && !(lbbwd <= kdist)) {
+ break;
+ }
+ // Careful: NaN handling: not NaN and not worse than fwd (may be NaN).
+ if(lbfwd <= kdist && !(lbfwd > lbbwd)) {
+ final double dist = refine(ifwd, obj);
+ if(dist <= kdist) {
+ heap.insert(dist, ifwd);
+ kdist = heap.getKNNDistance();
+ }
+ // Advance iterator:
+ ifwd.advance();
+ lbfwd = ifwd.valid() ? Math.abs(ifwd.doubleValue() - refd) : Double.NaN;
+ }
+ if(lbbwd <= kdist && !(lbbwd > lbfwd)) {
+ final double dist = refine(ibwd, obj);
+ if(dist <= kdist) {
+ heap.insert(dist, ibwd);
+ kdist = heap.getKNNDistance();
+ }
+ // Retract iterator:
+ ibwd.retract();
+ lbbwd = ibwd.valid() ? Math.abs(ibwd.doubleValue() - refd) : Double.NaN;
+ }
+ }
+ }
+
+ return heap.toKNNList();
+ }
+ }
+
+ /**
+ * Exact Range query implementation.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ protected class IDistanceRangeQuery extends AbstractRefiningIndex<O>.AbstractRangeQuery {
+ /**
+ * Constructor.
+ *
+ * @param distanceQuery Distance query
+ */
+ public IDistanceRangeQuery(DistanceQuery<O> distanceQuery) {
+ super(distanceQuery);
+ }
+
+ @Override
+ public DoubleDBIDList getRangeForObject(O obj, double range) {
+ DoubleIntPair[] priority = rankReferencePoints(distanceQuery, obj, referencepoints);
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
+ for(DoubleIntPair pair : priority) {
+ final ModifiableDoubleDBIDList nindex = index[pair.second];
+ final double refd = pair.first;
+
+ DoubleDBIDListIter ifwd = nindex.iter(), ibwd = nindex.iter();
+ binarySearch(nindex, ibwd, refd);
+ ifwd.seek(ibwd.getOffset() + 1);
+
+ // This assumes a metric, as we exploit triangle inequality:
+ // Lower bound for candidates further from the reference object:
+ // d(candidate, reference) <= d(candidate, query) + d(query, reference)
+ // d(candidate, reference) - d(query, reference) <= d(candidate, query)
+ double lbfwd = ifwd.valid() ? Math.abs(ifwd.doubleValue() - refd) : Double.NaN;
+ // Lower bound for candidates closer to the reference object:
+ // d(query, reference) <= d(query, candidate) + d(candidate, reference)
+ // d(query, reference) - d(candidate, reference) <= d(query, candidate)
+ double lbbwd = ibwd.valid() ? Math.abs(ibwd.doubleValue() - refd) : Double.NaN;
+ while(true) {
+ // Handle NaN carefully.
+ if(!(lbfwd <= range) && !(lbbwd <= range)) {
+ break;
+ }
+ // Careful: NaN handling: not NaN and not worse than fwd (may be NaN).
+ if(lbfwd <= range && !(lbfwd > lbbwd)) {
+ final double dist = refine(ifwd, obj);
+ if(dist <= range) {
+ result.add(dist, ifwd);
+ }
+ // Advance iterator:
+ ifwd.advance();
+ lbfwd = ifwd.valid() ? Math.abs(ifwd.doubleValue() - refd) : Double.NaN;
+ }
+ if(lbbwd <= range && !(lbbwd > lbfwd)) {
+ final double dist = refine(ibwd, obj);
+ if(dist <= range) {
+ result.add(dist, ibwd);
+ }
+ // Retract iterator:
+ ibwd.retract();
+ lbbwd = ibwd.valid() ? Math.abs(ibwd.doubleValue() - refd) : Double.NaN;
+ }
+ }
+ }
+ result.sort();
+ return result;
+ }
+ }
+
+ /**
+ * Index factory for iDistance indexes.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has InMemoryIDistanceIndex
+ *
+ * @param <V> Data type.
+ */
+ public static class Factory<V> implements IndexFactory<V, InMemoryIDistanceIndex<V>> {
+ /**
+ * Distance function to use.
+ */
+ DistanceFunction<? super V> distance;
+
+ /**
+ * Initialization method.
+ */
+ KMedoidsInitialization<V> initialization;
+
+ /**
+ * Number of reference points
+ */
+ int k;
+
+ /**
+ * Constructor.
+ *
+ * @param distance Distance function
+ * @param initialization Initialization method
+ * @param k Number of reference points
+ */
+ public Factory(DistanceFunction<? super V> distance, KMedoidsInitialization<V> initialization, int k) {
+ super();
+ this.distance = distance;
+ this.initialization = initialization;
+ this.k = k;
+ }
+
+ @Override
+ public InMemoryIDistanceIndex<V> instantiate(Relation<V> relation) {
+ return new InMemoryIDistanceIndex<>(relation, distance.instantiate(relation), initialization, k);
+ }
+
+ @Override
+ public TypeInformation getInputTypeRestriction() {
+ return distance.getInputTypeRestriction();
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <V> object type.
+ */
+ public static class Parameterizer<V> extends AbstractParameterizer {
+ /**
+ * Parameter for the distance function
+ */
+ public static final OptionID DISTANCE_ID = new OptionID("idistance.distance", "Distance function to build the index for.");
+
+ /**
+ * Initialization method.
+ */
+ public static final OptionID REFERENCE_ID = new OptionID("idistance.reference", "Method to choose the reference points.");
+
+ /**
+ * Number of reference points.
+ */
+ public static final OptionID K_ID = new OptionID("idistance.k", "Number of reference points to use.");
+
+ /**
+ * Distance function to use.
+ */
+ DistanceFunction<? super V> distance;
+
+ /**
+ * Initialization method.
+ */
+ KMedoidsInitialization<V> initialization;
+
+ /**
+ * Number of reference points
+ */
+ int k;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ ObjectParameter<DistanceFunction<? super V>> distanceP = new ObjectParameter<>(DISTANCE_ID, DistanceFunction.class);
+ if(config.grab(distanceP)) {
+ distance = distanceP.instantiateClass(config);
+ }
+
+ ObjectParameter<KMedoidsInitialization<V>> initializationP = new ObjectParameter<>(REFERENCE_ID, KMedoidsInitialization.class);
+ if(config.grab(initializationP)) {
+ initialization = initializationP.instantiateClass(config);
+ }
+
+ IntParameter kP = new IntParameter(K_ID)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(kP)) {
+ k = kP.intValue();
+ }
+ }
+
+ @Override
+ protected InMemoryIDistanceIndex.Factory<V> makeInstance() {
+ return new InMemoryIDistanceIndex.Factory<>(distance, initialization, k);
+ }
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/index/idistance/package-info.java b/src/de/lmu/ifi/dbs/elki/index/idistance/package-info.java
new file mode 100644
index 00000000..7b1fb9a7
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/idistance/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * iDistance is a distance based indexing technique, using a reference points embedding.
+ */
+
+/*
+ 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.index.idistance; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/invertedlist/InMemoryInvertedIndex.java b/src/de/lmu/ifi/dbs/elki/index/invertedlist/InMemoryInvertedIndex.java
new file mode 100644
index 00000000..91d2da7a
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/invertedlist/InMemoryInvertedIndex.java
@@ -0,0 +1,474 @@
+package de.lmu.ifi.dbs.elki.index.invertedlist;
+
+/*
+ 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.ArrayList;
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.SparseNumberVector;
+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.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
+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.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.AbstractDistanceKNNQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.database.query.range.AbstractDistanceRangeQuery;
+import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.ArcCosineDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.CosineDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.index.AbstractIndex;
+import de.lmu.ifi.dbs.elki.index.IndexFactory;
+import de.lmu.ifi.dbs.elki.index.KNNIndex;
+import de.lmu.ifi.dbs.elki.index.RangeIndex;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.statistics.DoubleStatistic;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Simple index using inverted lists.
+ *
+ * @author Erich Schubert
+ *
+ * @param <V> Vector type
+ */
+public class InMemoryInvertedIndex<V extends NumberVector> extends AbstractIndex<V> implements KNNIndex<V>, RangeIndex<V> {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(InMemoryInvertedIndex.class);
+
+ /**
+ * Inverted index.
+ */
+ ArrayList<ModifiableDoubleDBIDList> index;
+
+ /**
+ * Length storage.
+ */
+ WritableDoubleDataStore length;
+
+ /**
+ * Constructor.
+ *
+ * @param relation Data.
+ */
+ public InMemoryInvertedIndex(Relation<V> relation) {
+ super(relation);
+ }
+
+ @Override
+ public void initialize() {
+ if(index != null) {
+ LOG.warning("Index was already initialized!");
+ }
+ index = new ArrayList<>();
+ length = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_DB);
+ for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
+ V obj = relation.get(iter);
+ if(obj instanceof SparseNumberVector) {
+ indexSparse(iter, (SparseNumberVector) obj);
+ }
+ else {
+ indexDense(iter, obj);
+ }
+ }
+ // Sort indexes
+ long count = 0L;
+ for(ModifiableDoubleDBIDList column : index) {
+ column.sort();
+ count += column.size();
+ }
+ double sparsity = count / (index.size() * (double) relation.size());
+ if(sparsity > .2) {
+ LOG.warning("Inverted list indexes only perform well for very sparse data. Your data set has a sparsity of " + sparsity);
+ }
+ }
+
+ /**
+ * Index a single (sparse) instance.
+ *
+ * @param ref Object reference
+ * @param obj Object to index.
+ */
+ private void indexSparse(DBIDRef ref, SparseNumberVector obj) {
+ double len = 0.;
+ for(int iter = obj.iter(); obj.iterValid(iter); iter = obj.iterAdvance(iter)) {
+ final int dim = obj.iterDim(iter);
+ final double val = obj.iterDoubleValue(iter);
+ if(val == 0. || val != val) {
+ continue;
+ }
+ len += val * val;
+ getOrCreateColumn(dim).add(val, ref);
+ }
+ length.put(ref, len);
+ }
+
+ /**
+ * Index a single (dense) instance.
+ *
+ * @param ref Object reference
+ * @param obj Object to index.
+ */
+ private void indexDense(DBIDRef ref, V obj) {
+ double len = 0.;
+ for(int dim = 0, max = obj.getDimensionality(); dim < max; dim++) {
+ final double val = obj.doubleValue(dim);
+ if(val == 0. || val != val) {
+ continue;
+ }
+ len += val * val;
+ getOrCreateColumn(dim).add(val, ref);
+ }
+ length.put(ref, Math.sqrt(len));
+ }
+
+ /**
+ * Get (or create) a column.
+ *
+ * @param dim Dimension
+ * @return Column
+ */
+ private ModifiableDoubleDBIDList getOrCreateColumn(int dim) {
+ while(dim >= index.size()) {
+ index.add(DBIDUtil.newDistanceDBIDList());
+ }
+ return index.get(dim);
+ }
+
+ /**
+ * Query the most similar objects, sparse version.
+ *
+ * @param obj Query object
+ * @param scores Score storage
+ * @param cands Non-zero objects set
+ * @return Result
+ */
+ private double naiveQuerySparse(SparseNumberVector obj, WritableDoubleDataStore scores, HashSetModifiableDBIDs cands) {
+ double len = 0.; // Length of query object, for final normalization
+ for(int iter = obj.iter(); obj.iterValid(iter); iter = obj.iterAdvance(iter)) {
+ final int dim = obj.iterDim(iter);
+ final double val = obj.iterDoubleValue(iter);
+ if(val == 0. || val != val) {
+ continue;
+ }
+ len += val * val;
+ // No matching documents in index:
+ if(dim >= index.size()) {
+ continue;
+ }
+ ModifiableDoubleDBIDList column = index.get(dim);
+ for(DoubleDBIDListIter n = column.iter(); n.valid(); n.advance()) {
+ scores.increment(n, n.doubleValue() * val);
+ cands.add(n);
+ }
+ }
+ return Math.sqrt(len);
+ }
+
+ /**
+ * Query the most similar objects, dense version.
+ *
+ * @param obj Query object
+ * @param scores Score storage
+ * @param cands Non-zero objects set
+ * @return Result
+ */
+ private double naiveQueryDense(NumberVector obj, WritableDoubleDataStore scores, HashSetModifiableDBIDs cands) {
+ double len = 0.; // Length of query object, for final normalization
+ for(int dim = 0, max = obj.getDimensionality(); dim < max; dim++) {
+ final double val = obj.doubleValue(dim);
+ if(val == 0. || val != val) {
+ continue;
+ }
+ len += val * val;
+ // No matching documents in index:
+ if(dim >= index.size()) {
+ continue;
+ }
+ ModifiableDoubleDBIDList column = index.get(dim);
+ for(DoubleDBIDListIter n = column.iter(); n.valid(); n.advance()) {
+ scores.increment(n, n.doubleValue() * val);
+ cands.add(n);
+ }
+ }
+ return Math.sqrt(len);
+ }
+
+ /**
+ * Query the most similar objects, abstract version.
+ *
+ * @param obj Query object
+ * @param scores Score storage (must be initialized with zeros!)
+ * @param cands Non-zero objects set (must be empty)
+ * @return Result
+ */
+ private double naiveQuery(V obj, WritableDoubleDataStore scores, HashSetModifiableDBIDs cands) {
+ if(obj instanceof SparseNumberVector) {
+ return naiveQuerySparse((SparseNumberVector) obj, scores, cands);
+ }
+ else {
+ return naiveQueryDense(obj, scores, cands);
+ }
+ }
+
+ @Override
+ public void logStatistics() {
+ long count = 0L;
+ for(ModifiableDoubleDBIDList column : index) {
+ count += column.size();
+ }
+ double sparsity = count / (index.size() * (double) relation.size());
+ LOG.statistics(new DoubleStatistic(this.getClass().getName() + ".sparsity", sparsity));
+ }
+
+ @Override
+ public KNNQuery<V> getKNNQuery(DistanceQuery<V> distanceQuery, Object... hints) {
+ DistanceFunction<? super V> df = distanceQuery.getDistanceFunction();
+ if(df instanceof CosineDistanceFunction) {
+ return new CosineKNNQuery(distanceQuery);
+ }
+ if(df instanceof ArcCosineDistanceFunction) {
+ return new ArcCosineKNNQuery(distanceQuery);
+ }
+ return null;
+ }
+
+ @Override
+ public RangeQuery<V> getRangeQuery(DistanceQuery<V> distanceQuery, Object... hints) {
+ DistanceFunction<? super V> df = distanceQuery.getDistanceFunction();
+ if(df instanceof CosineDistanceFunction) {
+ return new CosineRangeQuery(distanceQuery);
+ }
+ if(df instanceof ArcCosineDistanceFunction) {
+ return new ArcCosineRangeQuery(distanceQuery);
+ }
+ return null;
+ }
+
+ @Override
+ public String getLongName() {
+ return "Inverted lists index";
+ }
+
+ @Override
+ public String getShortName() {
+ return "inverted-lists";
+ }
+
+ /**
+ * kNN query object, for cosine distance.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ protected class CosineKNNQuery extends AbstractDistanceKNNQuery<V> {
+ /**
+ * Constructor.
+ *
+ * @param distanceQuery Distance query
+ */
+ public CosineKNNQuery(DistanceQuery<V> distanceQuery) {
+ super(distanceQuery);
+ }
+
+ @Override
+ public KNNList getKNNForObject(V obj, int k) {
+ HashSetModifiableDBIDs cands = DBIDUtil.newHashSet();
+ WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(cands, //
+ DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, 0.);
+ double len = naiveQuery(obj, scores, cands);
+ // TODO: delay the division by len!
+ KNNHeap heap = DBIDUtil.newHeap(k);
+ for(DBIDIter n = cands.iter(); n.valid(); n.advance()) {
+ double dist = 1. - scores.doubleValue(n) / (length.doubleValue(n) * len);
+ if(heap.getKNNDistance() >= dist) {
+ heap.insert(dist, n);
+ }
+ }
+
+ return heap.toKNNList();
+ }
+ }
+
+ /**
+ * kNN query object, for arc cosine distance.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ protected class ArcCosineKNNQuery extends AbstractDistanceKNNQuery<V> {
+ /**
+ * Constructor.
+ *
+ * @param distanceQuery Distance query
+ */
+ public ArcCosineKNNQuery(DistanceQuery<V> distanceQuery) {
+ super(distanceQuery);
+ }
+
+ @Override
+ public KNNList getKNNForObject(V obj, int k) {
+ HashSetModifiableDBIDs cands = DBIDUtil.newHashSet();
+ WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(cands, //
+ DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, 0.);
+ double len = naiveQuery(obj, scores, cands);
+ // TODO: delay the division by len and acos!
+ KNNHeap heap = DBIDUtil.newHeap(k);
+ for(DBIDIter n = cands.iter(); n.valid(); n.advance()) {
+ double dist = Math.acos(scores.doubleValue(n) / (length.doubleValue(n) * len));
+ if(heap.getKNNDistance() >= dist) {
+ heap.insert(dist, n);
+ }
+ }
+
+ return heap.toKNNList();
+ }
+ }
+
+ /**
+ * kNN query object, for cosine distance.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ protected class CosineRangeQuery extends AbstractDistanceRangeQuery<V> {
+ /**
+ * Constructor.
+ *
+ * @param distanceQuery Distance query
+ */
+ public CosineRangeQuery(DistanceQuery<V> distanceQuery) {
+ super(distanceQuery);
+ }
+
+ @Override
+ public DoubleDBIDList getRangeForObject(V obj, double range) {
+ HashSetModifiableDBIDs cands = DBIDUtil.newHashSet();
+ WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(cands, //
+ DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, 0.);
+ double len = naiveQuery(obj, scores, cands);
+ ModifiableDoubleDBIDList list = DBIDUtil.newDistanceDBIDList();
+ // dist = 1 - sim/len <-> sim = len * (1-dist)
+ double simrange = (1. - range) * len;
+ for(DBIDIter n = cands.iter(); n.valid(); n.advance()) {
+ double sim = scores.doubleValue(n) / length.doubleValue(n);
+ if(sim >= simrange) {
+ list.add(1. - sim / len, n);
+ }
+ }
+ list.sort();
+ return list;
+ }
+ }
+
+ /**
+ * kNN query object, for cosine distance.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ protected class ArcCosineRangeQuery extends AbstractDistanceRangeQuery<V> {
+ /**
+ * Constructor.
+ *
+ * @param distanceQuery Distance query
+ */
+ public ArcCosineRangeQuery(DistanceQuery<V> distanceQuery) {
+ super(distanceQuery);
+ }
+
+ @Override
+ public DoubleDBIDList getRangeForObject(V obj, double range) {
+ HashSetModifiableDBIDs cands = DBIDUtil.newHashSet();
+ WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(cands, //
+ DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, 0.);
+ double len = naiveQuery(obj, scores, cands);
+ // dist = acos(sim/len) <-> sim = cos(dist)*len
+ double simrange = Math.cos(range) * len;
+ ModifiableDoubleDBIDList list = DBIDUtil.newDistanceDBIDList();
+ for(DBIDIter n = cands.iter(); n.valid(); n.advance()) {
+ double sim = scores.doubleValue(n) / length.doubleValue(n);
+ if(sim >= simrange) {
+ list.add(Math.acos(sim / len), n);
+ }
+ }
+ list.sort();
+ return list;
+ }
+ }
+
+ /**
+ * Index factory
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has InMemoryInvertedIndex
+ *
+ * @param <V> Vector type
+ */
+ public static class Factory<V extends NumberVector> implements IndexFactory<V, InMemoryInvertedIndex<V>> {
+ @Override
+ public InMemoryInvertedIndex<V> instantiate(Relation<V> relation) {
+ return new InMemoryInvertedIndex<>(relation);
+ }
+
+ @Override
+ public TypeInformation getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_VARIABLE_LENGTH;
+ }
+
+ /**
+ * Parameterizer for inverted list index.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <V> Vector type
+ */
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
+ @Override
+ protected Factory<V> makeInstance() {
+ return new Factory<>();
+ }
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/index/invertedlist/package-info.java b/src/de/lmu/ifi/dbs/elki/index/invertedlist/package-info.java
new file mode 100644
index 00000000..55c00f7d
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/invertedlist/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Indexes using inverted lists.
+ */
+
+/*
+ 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.index.invertedlist; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/lsh/InMemoryLSHIndex.java b/src/de/lmu/ifi/dbs/elki/index/lsh/InMemoryLSHIndex.java
index 8ae3cd69..1915e0ce 100644
--- a/src/de/lmu/ifi/dbs/elki/index/lsh/InMemoryLSHIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/lsh/InMemoryLSHIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.lsh;
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,18 +32,17 @@ import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
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.query.range.RangeQuery;
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.Distance;
import de.lmu.ifi.dbs.elki.index.AbstractRefiningIndex;
import de.lmu.ifi.dbs.elki.index.IndexFactory;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
@@ -65,6 +64,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
+ * @apiviz.has LocalitySensitiveHashFunctionFamily
+ * @apiviz.has Instance
+ *
* @param <V> Object type to index
*/
public class InMemoryLSHIndex<V> implements IndexFactory<V, InMemoryLSHIndex<V>.Instance> {
@@ -79,7 +81,7 @@ public class InMemoryLSHIndex<V> implements IndexFactory<V, InMemoryLSHIndex<V>.
LocalitySensitiveHashFunctionFamily<? super V> family;
/**
- * Number of hash functions for each table.
+ * Number of hash tables to use.
*/
int l;
@@ -116,6 +118,8 @@ public class InMemoryLSHIndex<V> implements IndexFactory<V, InMemoryLSHIndex<V>.
* Instance of a LSH index for a single relation.
*
* @author Erich Schubert
+ *
+ * @apiviz.has LocalitySensitiveHashFunction
*/
public class Instance extends AbstractRefiningIndex<V> implements KNNIndex<V>, RangeIndex<V> {
/**
@@ -188,13 +192,9 @@ public class InMemoryLSHIndex<V> implements IndexFactory<V, InMemoryLSHIndex<V>.
table.put(bucket, newbuck);
}
}
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
- }
- if(progress != null) {
- progress.ensureCompleted(LOG);
+ LOG.incrementProcessed(progress);
}
+ LOG.ensureCompleted(progress);
if(LOG.isStatistics()) {
int min = Integer.MAX_VALUE, max = 0;
for(int i = 0; i < numhash; i++) {
@@ -210,8 +210,8 @@ public class InMemoryLSHIndex<V> implements IndexFactory<V, InMemoryLSHIndex<V>.
}
}
}
- LOG.statistics(new LongStatistic(this.getClass().getName() + ".fill.min", max));
- LOG.statistics(new LongStatistic(this.getClass().getName() + ".fill.max", min));
+ LOG.statistics(new LongStatistic(this.getClass().getName() + ".fill.min", min));
+ LOG.statistics(new LongStatistic(this.getClass().getName() + ".fill.max", max));
LOG.statistics(new LongStatistic(this.getClass().getName() + ".hashtables", hashtables.size()));
}
}
@@ -222,31 +222,31 @@ public class InMemoryLSHIndex<V> implements IndexFactory<V, InMemoryLSHIndex<V>.
}
@Override
- public <D extends Distance<D>> KNNQuery<V, D> getKNNQuery(DistanceQuery<V, D> distanceQuery, Object... hints) {
+ public KNNQuery<V> getKNNQuery(DistanceQuery<V> distanceQuery, Object... hints) {
for(Object hint : hints) {
if(DatabaseQuery.HINT_EXACT.equals(hint)) {
return null;
}
}
- DistanceFunction<? super V, D> df = distanceQuery.getDistanceFunction();
+ DistanceFunction<? super V> df = distanceQuery.getDistanceFunction();
if(!family.isCompatible(df)) {
return null;
}
- return (KNNQuery<V, D>) new LSHKNNQuery<>(distanceQuery);
+ return new LSHKNNQuery(distanceQuery);
}
@Override
- public <D extends Distance<D>> RangeQuery<V, D> getRangeQuery(DistanceQuery<V, D> distanceQuery, Object... hints) {
+ public RangeQuery<V> getRangeQuery(DistanceQuery<V> distanceQuery, Object... hints) {
for(Object hint : hints) {
if(DatabaseQuery.HINT_EXACT.equals(hint)) {
return null;
}
}
- DistanceFunction<? super V, D> df = distanceQuery.getDistanceFunction();
+ DistanceFunction<? super V> df = distanceQuery.getDistanceFunction();
if(!family.isCompatible(df)) {
return null;
}
- return (RangeQuery<V, D>) new LSHRangeQuery<>(distanceQuery);
+ return new LSHRangeQuery(distanceQuery);
}
/**
@@ -255,21 +255,19 @@ public class InMemoryLSHIndex<V> implements IndexFactory<V, InMemoryLSHIndex<V>.
* @author Erich Schubert
*
* @apiviz.exclude
- *
- * @param <D> Distance type
*/
- protected class LSHKNNQuery<D extends Distance<D>> extends AbstractKNNQuery<D> {
+ protected class LSHKNNQuery extends AbstractKNNQuery {
/**
* Constructor.
*
* @param distanceQuery
*/
- public LSHKNNQuery(DistanceQuery<V, D> distanceQuery) {
+ public LSHKNNQuery(DistanceQuery<V> distanceQuery) {
super(distanceQuery);
}
@Override
- public KNNList<D> getKNNForObject(V obj, int k) {
+ public KNNList getKNNForObject(V obj, int k) {
ModifiableDBIDs candidates = null;
final int numhash = hashtables.size();
for(int i = 0; i < numhash; i++) {
@@ -292,9 +290,9 @@ public class InMemoryLSHIndex<V> implements IndexFactory<V, InMemoryLSHIndex<V>.
}
// Refine.
- KNNHeap<D> heap = DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k);
+ KNNHeap heap = DBIDUtil.newHeap(k);
for(DBIDIter iter = candidates.iter(); iter.valid(); iter.advance()) {
- final D dist = distanceQuery.distance(obj, iter);
+ final double dist = distanceQuery.distance(obj, iter);
super.incRefinements(1);
heap.insert(dist, iter);
}
@@ -308,21 +306,19 @@ public class InMemoryLSHIndex<V> implements IndexFactory<V, InMemoryLSHIndex<V>.
* @author Erich Schubert
*
* @apiviz.exclude
- *
- * @param <D> Distance type
*/
- protected class LSHRangeQuery<D extends Distance<D>> extends AbstractRangeQuery<D> {
+ protected class LSHRangeQuery extends AbstractRangeQuery {
/**
* Constructor.
*
* @param distanceQuery
*/
- public LSHRangeQuery(DistanceQuery<V, D> distanceQuery) {
+ public LSHRangeQuery(DistanceQuery<V> distanceQuery) {
super(distanceQuery);
}
@Override
- public DistanceDBIDList<D> getRangeForObject(V obj, D range) {
+ public DoubleDBIDList getRangeForObject(V obj, double range) {
ModifiableDBIDs candidates = DBIDUtil.newHashSet();
final int numhash = hashtables.size();
for(int i = 0; i < numhash; i++) {
@@ -339,11 +335,11 @@ public class InMemoryLSHIndex<V> implements IndexFactory<V, InMemoryLSHIndex<V>.
}
// Refine.
- GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>();
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
for(DBIDIter iter = candidates.iter(); iter.valid(); iter.advance()) {
- final D dist = distanceQuery.distance(obj, iter);
+ final double dist = distanceQuery.distance(obj, iter);
super.incRefinements(1);
- if(range.compareTo(dist) >= 0) {
+ if(dist <= range) {
result.add(dist, iter);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/AbstractHashFunctionFamily.java b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/AbstractProjectedHashFunctionFamily.java
index 1c5502eb..d101ff2c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/AbstractHashFunctionFamily.java
+++ b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/AbstractProjectedHashFunctionFamily.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.lsh.hashfamilies;
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,7 +34,7 @@ import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.index.lsh.hashfunctions.LocalitySensitiveHashFunction;
import de.lmu.ifi.dbs.elki.index.lsh.hashfunctions.MultipleProjectionsLocalitySensitiveHashFunction;
import de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections.RandomProjectionFamily;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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;
@@ -47,8 +47,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
* Abstract base class for projection based hash functions.
*
* @author Erich Schubert
+ *
+ * @apiviz.uses RandomProjectionFamily
+ * @apiviz.has MultipleProjectionsLocalitySensitiveHashFunction
*/
-public abstract class AbstractHashFunctionFamily implements LocalitySensitiveHashFunctionFamily<NumberVector<?>> {
+public abstract class AbstractProjectedHashFunctionFamily implements LocalitySensitiveHashFunctionFamily<NumberVector> {
/**
* Random generator to use.
*/
@@ -77,7 +80,7 @@ public abstract class AbstractHashFunctionFamily implements LocalitySensitiveHas
* @param width Bin width
* @param k Number of projections for each hash function.
*/
- public AbstractHashFunctionFamily(RandomFactory random, RandomProjectionFamily proj, double width, int k) {
+ public AbstractProjectedHashFunctionFamily(RandomFactory random, RandomProjectionFamily proj, double width, int k) {
super();
this.random = random;
this.proj = proj;
@@ -86,9 +89,9 @@ public abstract class AbstractHashFunctionFamily implements LocalitySensitiveHas
}
@Override
- public ArrayList<? extends LocalitySensitiveHashFunction<? super NumberVector<?>>> generateHashFunctions(Relation<? extends NumberVector<?>> relation, int l) {
+ public ArrayList<? extends LocalitySensitiveHashFunction<? super NumberVector>> generateHashFunctions(Relation<? extends NumberVector> relation, int l) {
int dim = RelationUtil.dimensionality(relation);
- ArrayList<LocalitySensitiveHashFunction<? super NumberVector<?>>> ps = new ArrayList<>(l);
+ ArrayList<LocalitySensitiveHashFunction<? super NumberVector>> ps = new ArrayList<>(l);
final Random rnd = random.getSingleThreadedRandom();
for(int i = 0; i < l; i++) {
RandomProjectionFamily.Projection mat = proj.generateProjection(dim, k);
diff --git a/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/EuclideanHashFunctionFamily.java b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/EuclideanHashFunctionFamily.java
index 0aa983e5..0bb229d6 100644
--- a/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/EuclideanHashFunctionFamily.java
+++ b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/EuclideanHashFunctionFamily.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.lsh.hashfamilies;
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.index.lsh.hashfamilies;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
import de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections.GaussianRandomProjectionFamily;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
/**
@@ -39,9 +39,14 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* </p>
*
* @author Erich Schubert
+ *
+ * @apiviz.uses GaussianRandomProjectionFamily
*/
-@Reference(authors = "M. Datar and N. Immorlica and P. Indyk and V. S. Mirrokni", title = "Locality-sensitive hashing scheme based on p-stable distributions", booktitle = "Proc. 20th annual symposium on Computational geometry", url = "http://dx.doi.org/10.1145/997817.997857")
-public class EuclideanHashFunctionFamily extends AbstractHashFunctionFamily {
+@Reference(authors = "M. Datar and N. Immorlica and P. Indyk and V. S. Mirrokni", //
+title = "Locality-sensitive hashing scheme based on p-stable distributions", //
+booktitle = "Proc. 20th annual symposium on Computational geometry", //
+url = "http://dx.doi.org/10.1145/997817.997857")
+public class EuclideanHashFunctionFamily extends AbstractProjectedHashFunctionFamily {
/**
* Constructor.
*
@@ -54,7 +59,7 @@ public class EuclideanHashFunctionFamily extends AbstractHashFunctionFamily {
}
@Override
- public boolean isCompatible(DistanceFunction<?, ?> df) {
+ public boolean isCompatible(DistanceFunction<?> df) {
return EuclideanDistanceFunction.class.isInstance(df);
}
@@ -65,7 +70,7 @@ public class EuclideanHashFunctionFamily extends AbstractHashFunctionFamily {
*
* @apiviz.exclude
*/
- public static class Parameterizer extends AbstractHashFunctionFamily.Parameterizer {
+ public static class Parameterizer extends AbstractProjectedHashFunctionFamily.Parameterizer {
@Override
protected EuclideanHashFunctionFamily makeInstance() {
return new EuclideanHashFunctionFamily(random, width, k);
diff --git a/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/LocalitySensitiveHashFunctionFamily.java b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/LocalitySensitiveHashFunctionFamily.java
index 4d3468bb..14608145 100644
--- a/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/LocalitySensitiveHashFunctionFamily.java
+++ b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/LocalitySensitiveHashFunctionFamily.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.lsh.hashfamilies;
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
@@ -49,10 +49,10 @@ public interface LocalitySensitiveHashFunctionFamily<V> {
* Generate hash functions for the given relation.
*
* @param relation Relation to index
- * @param k number of hash functions per table.
+ * @param l Number of hash tables to use
* @return Family of hash functions
*/
- ArrayList<? extends LocalitySensitiveHashFunction<? super V>> generateHashFunctions(Relation<? extends V> relation, int k);
+ ArrayList<? extends LocalitySensitiveHashFunction<? super V>> generateHashFunctions(Relation<? extends V> relation, int l);
/**
* Check whether the given distance function can be accelerated using this
@@ -61,5 +61,5 @@ public interface LocalitySensitiveHashFunctionFamily<V> {
* @param df Distance function.
* @return {@code true} when appropriate.
*/
- boolean isCompatible(DistanceFunction<?, ?> df);
+ boolean isCompatible(DistanceFunction<?> df);
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/ManhattanHashFunctionFamily.java b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/ManhattanHashFunctionFamily.java
index a117c44c..6a68f763 100644
--- a/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/ManhattanHashFunctionFamily.java
+++ b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/ManhattanHashFunctionFamily.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.lsh.hashfamilies;
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 @@ package de.lmu.ifi.dbs.elki.index.lsh.hashfamilies;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.ManhattanDistanceFunction;
import de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections.CauchyRandomProjectionFamily;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
/**
@@ -40,9 +40,14 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* </p>
*
* @author Erich Schubert
+ *
+ * @apiviz.uses CauchyRandomProjectionFamily
*/
-@Reference(authors = "M. Datar and N. Immorlica and P. Indyk and V. S. Mirrokni", title = "Locality-sensitive hashing scheme based on p-stable distributions", booktitle = "Proc. 20th annual symposium on Computational geometry", url = "http://dx.doi.org/10.1145/997817.997857")
-public class ManhattanHashFunctionFamily extends AbstractHashFunctionFamily {
+@Reference(authors = "M. Datar and N. Immorlica and P. Indyk and V. S. Mirrokni", //
+title = "Locality-sensitive hashing scheme based on p-stable distributions", //
+booktitle = "Proc. 20th annual symposium on Computational geometry", //
+url = "http://dx.doi.org/10.1145/997817.997857")
+public class ManhattanHashFunctionFamily extends AbstractProjectedHashFunctionFamily {
/**
* Constructor.
*
@@ -55,7 +60,7 @@ public class ManhattanHashFunctionFamily extends AbstractHashFunctionFamily {
}
@Override
- public boolean isCompatible(DistanceFunction<?, ?> df) {
+ public boolean isCompatible(DistanceFunction<?> df) {
// TODO: also allow HistogramIntersectionDistance?
return ManhattanDistanceFunction.class.isInstance(df);
}
@@ -67,7 +72,7 @@ public class ManhattanHashFunctionFamily extends AbstractHashFunctionFamily {
*
* @apiviz.exclude
*/
- public static class Parameterizer extends AbstractHashFunctionFamily.Parameterizer {
+ public static class Parameterizer extends AbstractProjectedHashFunctionFamily.Parameterizer {
@Override
protected ManhattanHashFunctionFamily makeInstance() {
return new ManhattanHashFunctionFamily(random, width, k);
diff --git a/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/package-info.java b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/package-info.java
index 5afa0489..84a3a244 100644
--- a/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfamilies/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/index/lsh/hashfunctions/LocalitySensitiveHashFunction.java b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfunctions/LocalitySensitiveHashFunction.java
index c43f60a5..8186c2e4 100644
--- a/src/de/lmu/ifi/dbs/elki/index/lsh/hashfunctions/LocalitySensitiveHashFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfunctions/LocalitySensitiveHashFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.lsh.hashfunctions;
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/index/lsh/hashfunctions/MultipleProjectionsLocalitySensitiveHashFunction.java b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfunctions/MultipleProjectionsLocalitySensitiveHashFunction.java
index 59f31b0a..ba352108 100644
--- a/src/de/lmu/ifi/dbs/elki/index/lsh/hashfunctions/MultipleProjectionsLocalitySensitiveHashFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfunctions/MultipleProjectionsLocalitySensitiveHashFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.lsh.hashfunctions;
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
@@ -41,8 +41,11 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
*
* @author Erich Schubert
*/
-@Reference(authors = "M. Datar and N. Immorlica and P. Indyk and V. S. Mirrokni", title = "Locality-sensitive hashing scheme based on p-stable distributions", booktitle = "Proc. 20th annual symposium on Computational geometry", url = "http://dx.doi.org/10.1145/997817.997857")
-public class MultipleProjectionsLocalitySensitiveHashFunction implements LocalitySensitiveHashFunction<NumberVector<?>> {
+@Reference(authors = "M. Datar and N. Immorlica and P. Indyk and V. S. Mirrokni", //
+title = "Locality-sensitive hashing scheme based on p-stable distributions", //
+booktitle = "Proc. 20th annual symposium on Computational geometry", //
+url = "http://dx.doi.org/10.1145/997817.997857")
+public class MultipleProjectionsLocalitySensitiveHashFunction implements LocalitySensitiveHashFunction<NumberVector> {
/**
* Projection matrix.
*/
@@ -54,9 +57,9 @@ public class MultipleProjectionsLocalitySensitiveHashFunction implements Localit
double[] shift;
/**
- * Scaling factor.
+ * Scaling factor: inverse of width.
*/
- double width;
+ double iwidth;
/**
* Random numbers for mixing the hash codes of the individual functions
@@ -73,28 +76,33 @@ public class MultipleProjectionsLocalitySensitiveHashFunction implements Localit
public MultipleProjectionsLocalitySensitiveHashFunction(RandomProjectionFamily.Projection projection, double width, Random rnd) {
super();
this.projection = projection;
- this.width = width;
+ this.iwidth = 1. / width;
// Generate random shifts:
final int num = projection.getOutputDimensionality();
this.shift = new double[num];
this.randoms1 = new int[num];
- for (int i = 0; i < num; i++) {
+ for(int i = 0; i < num; i++) {
shift[i] = rnd.nextDouble() * width;
// Produce a large random number; although 7FFFFFFF would likely be large
// enough, we try to stick to the suggested approach (which assumes
// unsigned integers).
- randoms1[i] = (rnd.nextInt(0x7FFFFFFD) << 1) + rnd.nextInt(1) + 1;
+ randoms1[i] = (rnd.nextInt(0x10000D) << 16) + rnd.nextInt(0xFFFFD) + 1;
}
}
+ /**
+ * Bit mask for signed int to unsigned long conversion.
+ */
+ private final static long MASK32 = 0xFFFFFFFFL;
+
@Override
- public int hashObject(NumberVector<?> vec) {
+ public int hashObject(NumberVector vec) {
long t1sum = 0L;
// Project the vector:
final double[] proj = projection.project(vec);
- for (int i = 0; i < shift.length; i++) {
- int ai = (int) Math.floor((proj[i] + shift[i]) / width);
- t1sum += randoms1[i] * (long) ai;
+ for(int i = 0; i < shift.length; i++) {
+ int ai = (int) Math.floor((proj[i] + shift[i]) * iwidth);
+ t1sum += (randoms1[i] & MASK32) * ai; // unsigned math!
}
return fastModPrime(t1sum);
}
@@ -111,7 +119,7 @@ public class MultipleProjectionsLocalitySensitiveHashFunction implements Localit
// Use fast multiplication with 5 for high:
int alpha = ((int) data) + (high << 2 + high);
// Note that in Java, PRIME will be negative.
- if (alpha < 0 && alpha > -5) {
+ if(alpha < 0 && alpha > -5) {
alpha = alpha + 5;
}
return alpha;
diff --git a/src/de/lmu/ifi/dbs/elki/index/lsh/hashfunctions/package-info.java b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfunctions/package-info.java
index e30550f6..d06249db 100644
--- a/src/de/lmu/ifi/dbs/elki/index/lsh/hashfunctions/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/lsh/hashfunctions/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/index/lsh/package-info.java b/src/de/lmu/ifi/dbs/elki/index/lsh/package-info.java
index 78eb59f7..62409f05 100644
--- a/src/de/lmu/ifi/dbs/elki/index/lsh/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/lsh/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/index/package-info.java b/src/de/lmu/ifi/dbs/elki/index/package-info.java
index f985629d..91151b3c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/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/index/preprocessed/AbstractPreprocessorIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/AbstractPreprocessorIndex.java
index 720efc56..0314fb86 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/AbstractPreprocessorIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/AbstractPreprocessorIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed;
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/index/preprocessed/LocalProjectionIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/LocalProjectionIndex.java
index 0229c4e5..1f3b8ff8 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/LocalProjectionIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/LocalProjectionIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed;
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.math.linearalgebra.ProjectionResult;
* @param <V> Vector type
* @param <P> Projection result type
*/
-public interface LocalProjectionIndex<V extends NumberVector<?>, P extends ProjectionResult> extends Index {
+public interface LocalProjectionIndex<V extends NumberVector, P extends ProjectionResult> extends Index {
/**
* Get the precomputed local projection for a particular object ID.
*
@@ -60,7 +60,7 @@ public interface LocalProjectionIndex<V extends NumberVector<?>, P extends Proje
* @param <V> Vector type
* @param <I> Index type
*/
- public static interface Factory<V extends NumberVector<?>, I extends LocalProjectionIndex<V, ?>> extends IndexFactory<V, I> {
+ public static interface Factory<V extends NumberVector, I extends LocalProjectionIndex<V, ?>> extends IndexFactory<V, I> {
/**
* Instantiate the index for a given database.
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/AbstractMaterializeKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/AbstractMaterializeKNNPreprocessor.java
index 927678c2..9c950d95 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/AbstractMaterializeKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/AbstractMaterializeKNNPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
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,14 +28,13 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
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.ids.KNNList;
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.query.knn.PreprocessorKNNQuery;
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.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.index.IndexFactory;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
import de.lmu.ifi.dbs.elki.index.preprocessed.AbstractPreprocessorIndex;
@@ -52,10 +51,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
- * @param <T> Result type
*/
-public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D>, T extends KNNList<D>> extends AbstractPreprocessorIndex<O, T> implements KNNIndex<O> {
+public abstract class AbstractMaterializeKNNPreprocessor<O> extends AbstractPreprocessorIndex<O, KNNList> implements KNNIndex<O> {
/**
* The query k value.
*/
@@ -64,12 +61,12 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
/**
* The distance function to be used.
*/
- protected final DistanceFunction<? super O, D> distanceFunction;
+ protected final DistanceFunction<? super O> distanceFunction;
/**
* The distance query we used.
*/
- protected final DistanceQuery<O, D> distanceQuery;
+ protected final DistanceQuery<O> distanceQuery;
/**
* Constructor.
@@ -78,7 +75,7 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
* @param distanceFunction Distance function
* @param k k
*/
- public AbstractMaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, int k) {
+ public AbstractMaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O> distanceFunction, int k) {
super(relation);
this.k = k;
this.distanceFunction = distanceFunction;
@@ -86,20 +83,11 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
}
/**
- * Get the distance factory.
- *
- * @return distance factory
- */
- public D getDistanceFactory() {
- return distanceFunction.getDistanceFactory();
- }
-
- /**
* The distance query we used.
*
* @return Distance query
*/
- public DistanceQuery<O, D> getDistanceQuery() {
+ public DistanceQuery<O> getDistanceQuery() {
return distanceQuery;
}
@@ -123,7 +111,7 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
* @param id Object ID
* @return Neighbors
*/
- public KNNList<D> get(DBIDRef id) {
+ public KNNList get(DBIDRef id) {
if(storage == null) {
if(getLogger().isDebugging()) {
getLogger().debug("Running kNN preprocessor: " + this.getClass());
@@ -137,7 +125,7 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
* Create the default storage.
*/
void createStorage() {
- WritableDataStore<T> s = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT, KNNList.class);
+ WritableDataStore<KNNList> s = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT, KNNList.class);
storage = s;
}
@@ -155,7 +143,7 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
@SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> KNNQuery<O, S> getKNNQuery(DistanceQuery<O, S> distQ, Object... hints) {
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distQ, Object... hints) {
if(!this.distanceFunction.equals(distQ.getDistanceFunction())) {
return null;
}
@@ -169,8 +157,8 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
}
}
// To make compilers happy:
- AbstractMaterializeKNNPreprocessor<?, ?, ?> tmp = this;
- return new PreprocessorKNNQuery<>(relation, (AbstractMaterializeKNNPreprocessor<O, S, KNNList<S>>) tmp);
+ AbstractMaterializeKNNPreprocessor<?> tmp = this;
+ return new PreprocessorKNNQuery<>(relation, (AbstractMaterializeKNNPreprocessor<O>) tmp);
}
/**
@@ -183,9 +171,8 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
* @apiviz.uses AbstractMaterializeKNNPreprocessor oneway - - «create»
*
* @param <O> The object type
- * @param <D> The distance type
*/
- public abstract static class Factory<O, D extends Distance<D>, T extends KNNList<D>> implements IndexFactory<O, KNNIndex<O>> {
+ public abstract static class Factory<O> implements IndexFactory<O, KNNIndex<O>> {
/**
* Parameter to specify the number of nearest neighbors of an object to be
* materialized. must be an integer greater than 1.
@@ -216,7 +203,7 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
/**
* Hold the distance function to be used.
*/
- protected DistanceFunction<? super O, D> distanceFunction;
+ protected DistanceFunction<? super O> distanceFunction;
/**
* Index factory.
@@ -224,14 +211,14 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
* @param k k parameter
* @param distanceFunction distance function
*/
- public Factory(int k, DistanceFunction<? super O, D> distanceFunction) {
+ public Factory(int k, DistanceFunction<? super O> distanceFunction) {
super();
this.k = k;
this.distanceFunction = distanceFunction;
}
@Override
- public abstract AbstractMaterializeKNNPreprocessor<O, D, T> instantiate(Relation<O> relation);
+ public abstract AbstractMaterializeKNNPreprocessor<O> instantiate(Relation<O> relation);
/**
* Get the distance function.
@@ -239,19 +226,10 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
* @return Distance function
*/
// TODO: hide this?
- public DistanceFunction<? super O, D> getDistanceFunction() {
+ public DistanceFunction<? super O> getDistanceFunction() {
return distanceFunction;
}
- /**
- * Get the distance factory.
- *
- * @return Distance factory
- */
- public D getDistanceFactory() {
- return distanceFunction.getDistanceFactory();
- }
-
@Override
public TypeInformation getInputTypeRestriction() {
return distanceFunction.getInputTypeRestriction();
@@ -263,8 +241,10 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
* @author Erich Schubert
*
* @apiviz.exclude
+ *
+ * @param <O> Object type
*/
- public abstract static class Parameterizer<O, D extends Distance<D>> extends AbstractParameterizer {
+ public abstract static class Parameterizer<O> extends AbstractParameterizer {
/**
* Holds the value of {@link #K_ID}.
*/
@@ -273,7 +253,7 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
/**
* Hold the distance function to be used.
*/
- protected DistanceFunction<? super O, D> distanceFunction;
+ protected DistanceFunction<? super O> distanceFunction;
@Override
protected void makeOptions(Parameterization config) {
@@ -286,14 +266,14 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
}
// distance function
- final ObjectParameter<DistanceFunction<? super O, D>> distanceFunctionP = new ObjectParameter<>(DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
+ final ObjectParameter<DistanceFunction<? super O>> distanceFunctionP = new ObjectParameter<>(DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
if(config.grab(distanceFunctionP)) {
distanceFunction = distanceFunctionP.instantiateClass(config);
}
}
@Override
- protected abstract Factory<O, D, ?> makeInstance();
+ protected abstract Factory<O> makeInstance();
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/CachedDoubleDistanceKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/CachedDoubleDistanceKNNPreprocessor.java
index c36948be..eec9e812 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/CachedDoubleDistanceKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/CachedDoubleDistanceKNNPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
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,20 +29,16 @@ import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
-import java.util.ArrayList;
import de.lmu.ifi.dbs.elki.application.cache.CacheDoubleDistanceKNNLists;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.DoubleDistanceDBIDPairKNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
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.logging.Logging;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
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.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
@@ -54,7 +50,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
*
* @param <O> Object type
*/
-public class CachedDoubleDistanceKNNPreprocessor<O> extends AbstractMaterializeKNNPreprocessor<O, DoubleDistance, DoubleDistanceKNNList> {
+public class CachedDoubleDistanceKNNPreprocessor<O> extends AbstractMaterializeKNNPreprocessor<O> {
/**
* File to load.
*/
@@ -68,7 +64,7 @@ public class CachedDoubleDistanceKNNPreprocessor<O> extends AbstractMaterializeK
* @param k K
* @param file File to load
*/
- public CachedDoubleDistanceKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O, DoubleDistance> distanceFunction, int k, File file) {
+ public CachedDoubleDistanceKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O> distanceFunction, int k, File file) {
super(relation, distanceFunction, k);
this.filename = file;
}
@@ -86,28 +82,31 @@ public class CachedDoubleDistanceKNNPreprocessor<O> extends AbstractMaterializeK
FileChannel channel = file.getChannel()) {
// check magic header
int header = file.readInt();
- if (header != CacheDoubleDistanceKNNLists.KNN_CACHE_MAGIC) {
+ if(header != CacheDoubleDistanceKNNLists.KNN_CACHE_MAGIC) {
throw new AbortException("Cache magic number does not match.");
}
MappedByteBuffer buffer = channel.map(MapMode.READ_ONLY, 4, file.length() - 4);
- for (DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
int dbid = ByteArrayUtil.readUnsignedVarint(buffer);
int nnsize = ByteArrayUtil.readUnsignedVarint(buffer);
- if (nnsize < k) {
+ if(nnsize < k) {
throw new AbortException("kNN cache contains fewer than k objects!");
}
- ArrayList<DoubleDistanceDBIDPair> col = new ArrayList<>(nnsize);
- for (int i = 0; i < nnsize; i++) {
+ // FIXME: avoid the KNNHeap to KNNList roundtrip.
+ // FIXME: use a DBIDVar instead of importInteger.
+ KNNHeap knn = DBIDUtil.newHeap(k);
+ for(int i = 0; i < nnsize; i++) {
int nid = ByteArrayUtil.readUnsignedVarint(buffer);
double dist = buffer.getDouble();
- col.add(DBIDUtil.newDistancePair(dist, DBIDUtil.importInteger(nid)));
+ knn.insert(dist, DBIDUtil.importInteger(nid));
}
- storage.put(DBIDUtil.importInteger(dbid), new DoubleDistanceDBIDPairKNNList(col, nnsize));
+ storage.put(DBIDUtil.importInteger(dbid), knn.toKNNList());
}
- if (buffer.hasRemaining()) {
+ if(buffer.hasRemaining()) {
LOG.warning("kNN cache has " + buffer.remaining() + " bytes remaining!");
}
- } catch (IOException e) {
+ }
+ catch(IOException e) {
throw new AbortException("I/O error in loading kNN cache: " + e.getMessage(), e);
}
}
@@ -143,7 +142,7 @@ public class CachedDoubleDistanceKNNPreprocessor<O> extends AbstractMaterializeK
*
* @param <O> The object type
*/
- public static class Factory<O> extends AbstractMaterializeKNNPreprocessor.Factory<O, DoubleDistance, DoubleDistanceKNNList> {
+ public static class Factory<O> extends AbstractMaterializeKNNPreprocessor.Factory<O> {
/**
* Filename to load.
*/
@@ -156,7 +155,7 @@ public class CachedDoubleDistanceKNNPreprocessor<O> extends AbstractMaterializeK
* @param distanceFunction distance function
* @param filename Cache file
*/
- public Factory(int k, DistanceFunction<? super O, DoubleDistance> distanceFunction, File filename) {
+ public Factory(int k, DistanceFunction<? super O> distanceFunction, File filename) {
super(k, distanceFunction);
this.filename = filename;
}
@@ -174,7 +173,7 @@ public class CachedDoubleDistanceKNNPreprocessor<O> extends AbstractMaterializeK
*
* @apiviz.exclude
*/
- public static class Parameterizer<O> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<O, DoubleDistance> {
+ public static class Parameterizer<O> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<O> {
/**
* Option ID for the kNN file.
*/
@@ -191,7 +190,7 @@ public class CachedDoubleDistanceKNNPreprocessor<O> extends AbstractMaterializeK
// Input file parameter
final FileParameter cpar = new FileParameter(CACHE_ID, FileParameter.FileType.INPUT_FILE);
- if (config.grab(cpar)) {
+ if(config.grab(cpar)) {
filename = cpar.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNChangeEvent.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNChangeEvent.java
index 275c1c97..888c1c22 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNChangeEvent.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNChangeEvent.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
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/index/preprocessed/knn/KNNJoinMaterializeKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNJoinMaterializeKNNPreprocessor.java
index 44100604..8f55b519 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNJoinMaterializeKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNJoinMaterializeKNNPreprocessor.java
@@ -1,20 +1,10 @@
package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
-import de.lmu.ifi.dbs.elki.algorithm.KNNJoin;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-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.Distance;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTreeNode;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-
/*
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,6 +22,13 @@ import de.lmu.ifi.dbs.elki.logging.Logging;
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.algorithm.KNNJoin;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTreeNode;
+import de.lmu.ifi.dbs.elki.logging.Logging;
/**
* Class to materialize the kNN using a spatial join on an R-tree.
@@ -39,9 +36,8 @@ import de.lmu.ifi.dbs.elki.logging.Logging;
* @author Erich Schubert
*
* @param <V> vector type
- * @param <D> distance type
*/
-public class KNNJoinMaterializeKNNPreprocessor<V extends NumberVector<?>, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor<V, D, KNNList<D>> {
+public class KNNJoinMaterializeKNNPreprocessor<V extends NumberVector> extends AbstractMaterializeKNNPreprocessor<V> {
/**
* Logging class.
*/
@@ -54,14 +50,14 @@ public class KNNJoinMaterializeKNNPreprocessor<V extends NumberVector<?>, D exte
* @param distanceFunction Distance function
* @param k k
*/
- public KNNJoinMaterializeKNNPreprocessor(Relation<V> relation, DistanceFunction<? super V, D> distanceFunction, int k) {
+ public KNNJoinMaterializeKNNPreprocessor(Relation<V> relation, DistanceFunction<? super V> distanceFunction, int k) {
super(relation, distanceFunction, k);
}
@Override
protected void preprocess() {
// Run KNNJoin
- KNNJoin<V, D, ?, ?> knnjoin = new KNNJoin<V, D, RStarTreeNode, SpatialEntry>(distanceFunction, k);
+ KNNJoin<V, ?, ?> knnjoin = new KNNJoin<V, RStarTreeNode, SpatialEntry>(distanceFunction, k);
storage = knnjoin.run(relation.getDatabase(), relation);
}
@@ -95,21 +91,20 @@ public class KNNJoinMaterializeKNNPreprocessor<V extends NumberVector<?>, D exte
* @apiviz.uses AbstractMaterializeKNNPreprocessor oneway - - «create»
*
* @param <O> The object type
- * @param <D> The distance type
*/
- public static class Factory<O extends NumberVector<?>, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory<O, D, KNNList<D>> {
+ public static class Factory<O extends NumberVector> extends AbstractMaterializeKNNPreprocessor.Factory<O> {
/**
* Constructor.
*
* @param k K
* @param distanceFunction distance function
*/
- public Factory(int k, DistanceFunction<? super O, D> distanceFunction) {
+ public Factory(int k, DistanceFunction<? super O> distanceFunction) {
super(k, distanceFunction);
}
@Override
- public KNNJoinMaterializeKNNPreprocessor<O, D> instantiate(Relation<O> relation) {
+ public KNNJoinMaterializeKNNPreprocessor<O> instantiate(Relation<O> relation) {
return new KNNJoinMaterializeKNNPreprocessor<>(relation, distanceFunction, k);
}
@@ -121,11 +116,10 @@ public class KNNJoinMaterializeKNNPreprocessor<V extends NumberVector<?>, D exte
* @apiviz.exclude
*
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O extends NumberVector<?>, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<O, D> {
+ public static class Parameterizer<O extends NumberVector> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<O> {
@Override
- protected KNNJoinMaterializeKNNPreprocessor.Factory<O, D> makeInstance() {
+ protected KNNJoinMaterializeKNNPreprocessor.Factory<O> makeInstance() {
return new KNNJoinMaterializeKNNPreprocessor.Factory<>(k, distanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNListener.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNListener.java
index 8c78cdc0..e26106de 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNListener.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNListener.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
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/index/preprocessed/knn/MaterializeKNNAndRKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNAndRKNNPreprocessor.java
index fba2b168..49e23dde 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNAndRKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNAndRKNNPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
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.index.preprocessed.knn;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;
@@ -40,22 +39,19 @@ 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.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.ids.SetDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.rknn.PreprocessorRKNNQuery;
import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery;
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.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distanceresultlist.DistanceDBIDResultUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.index.RKNNIndex;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
@@ -70,12 +66,12 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
* @author Elke Achtert
*
* @param <O> the type of database objects the preprocessor can be applied to
- * @param <D> the type of distance the used distance function will return
+ * @param the type of distance the used distance function will return
*/
// TODO: rewrite the double optimization. Maybe use a specialized subclass?
@Title("Materialize kNN and RkNN Neighborhood preprocessor")
@Description("Materializes the k nearest neighbors and the reverse k nearest neighbors of objects of a database.")
-public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends MaterializeKNNPreprocessor<O, D> implements RKNNIndex<O> {
+public class MaterializeKNNAndRKNNPreprocessor<O> extends MaterializeKNNPreprocessor<O> implements RKNNIndex<O> {
/**
* Logger to use.
*/
@@ -84,12 +80,7 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
/**
* Additional data storage for RkNN.
*/
- private WritableDataStore<TreeSet<DistanceDBIDPair<D>>> materialized_RkNN;
-
- /**
- * Use optimizations for double values
- */
- protected boolean doubleOptimize;
+ private WritableDataStore<TreeSet<DoubleDBIDPair>> materialized_RkNN;
/**
* Constructor.
@@ -98,9 +89,8 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
* @param distanceFunction the distance function to use
* @param k query k
*/
- public MaterializeKNNAndRKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, int k) {
+ public MaterializeKNNAndRKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O> distanceFunction, int k) {
super(relation, distanceFunction, k);
- this.doubleOptimize = DistanceUtil.isDoubleDistanceFunction(distanceFunction);
}
@Override
@@ -118,39 +108,30 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
*/
private void materializeKNNAndRKNNs(ArrayDBIDs ids, FiniteProgress progress) {
// add an empty list to each rknn
- Comparator<? super DistanceDBIDPair<D>> comp = DistanceDBIDResultUtil.distanceComparator();
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
if(materialized_RkNN.get(iter) == null) {
- materialized_RkNN.put(iter, new TreeSet<>(comp));
+ materialized_RkNN.put(iter, new TreeSet<DoubleDBIDPair>());
}
}
// knn query
- List<? extends KNNList<D>> kNNList = knnQuery.getKNNForBulkDBIDs(ids, k);
+ List<? extends KNNList> kNNList = knnQuery.getKNNForBulkDBIDs(ids, k);
int i = 0;
for(DBIDIter id = ids.iter(); id.valid(); id.advance(), i++) {
- KNNList<D> kNNs = kNNList.get(i);
+ KNNList kNNs = kNNList.get(i);
storage.put(id, kNNs);
- for(DistanceDBIDListIter<D> iter = kNNs.iter(); iter.valid(); iter.advance()) {
- TreeSet<DistanceDBIDPair<D>> rknns = materialized_RkNN.get(iter);
+ for(DoubleDBIDListIter iter = kNNs.iter(); iter.valid(); iter.advance()) {
+ TreeSet<DoubleDBIDPair> rknns = materialized_RkNN.get(iter);
rknns.add(makePair(iter, id));
}
- if(progress != null) {
- progress.incrementProcessed(getLogger());
- }
+ getLogger().incrementProcessed(progress);
}
- if(progress != null) {
- progress.ensureCompleted(getLogger());
- }
+ getLogger().ensureCompleted(progress);
}
- @SuppressWarnings("unchecked")
- private DistanceDBIDPair<D> makePair(DistanceDBIDListIter<D> iter, DBIDIter id) {
- if(doubleOptimize) {
- return (DistanceDBIDPair<D>) DBIDUtil.newDistancePair(((DoubleDistanceDBIDPair) iter.getDistancePair()).doubleDistance(), id);
- }
- return DBIDUtil.newDistancePair(iter.getDistance(), id);
+ private DoubleDBIDPair makePair(DoubleDBIDListIter iter, DBIDIter id) {
+ return DBIDUtil.newPair(iter.getPair().doubleValue(), id);
}
@Override
@@ -159,26 +140,18 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
ArrayDBIDs aids = DBIDUtil.ensureArray(ids);
// materialize the new kNNs and RkNNs
- if(stepprog != null) {
- stepprog.beginStep(1, "New insertions ocurred, materialize their new kNNs and RkNNs.", getLogger());
- }
+ getLogger().beginStep(stepprog, 1, "New insertions ocurred, materialize their new kNNs and RkNNs.");
materializeKNNAndRKNNs(aids, null);
// update the old kNNs and RkNNs
- if(stepprog != null) {
- stepprog.beginStep(2, "New insertions ocurred, update the affected kNNs and RkNNs.", getLogger());
- }
+ getLogger().beginStep(stepprog, 2, "New insertions ocurred, update the affected kNNs and RkNNs.");
ArrayDBIDs rkNN_ids = updateKNNsAndRkNNs(ids);
// inform listener
- if(stepprog != null) {
- stepprog.beginStep(3, "New insertions ocurred, inform listeners.", getLogger());
- }
+ getLogger().beginStep(stepprog, 3, "New insertions ocurred, inform listeners.");
fireKNNsInserted(ids, rkNN_ids);
- if(stepprog != null) {
- stepprog.ensureCompleted(getLogger());
- }
+ getLogger().ensureCompleted(stepprog);
}
/**
@@ -193,13 +166,13 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
ArrayModifiableDBIDs rkNN_ids = DBIDUtil.newArray();
DBIDs oldids = DBIDUtil.difference(relation.getDBIDs(), ids);
for(DBIDIter id = oldids.iter(); id.valid(); id.advance()) {
- KNNList<D> oldkNNs = storage.get(id);
- D knnDist = oldkNNs.getKNNDistance();
+ KNNList oldkNNs = storage.get(id);
+ double knnDist = oldkNNs.getKNNDistance();
// look for new kNNs
- KNNHeap<D> heap = null;
+ KNNHeap heap = null;
for(DBIDIter newid = ids.iter(); newid.valid(); newid.advance()) {
- D dist = distanceQuery.distance(id, newid);
- if(dist.compareTo(knnDist) <= 0) {
+ double dist = distanceQuery.distance(id, newid);
+ if(dist <= knnDist) {
// New id changes the kNNs of oldid.
if(heap == null) {
heap = DBIDUtil.newHeap(oldkNNs);
@@ -209,18 +182,18 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
}
// kNNs for oldid have changed:
if(heap != null) {
- KNNList<D> newkNNs = heap.toKNNList();
+ KNNList newkNNs = heap.toKNNList();
storage.put(id, newkNNs);
// get the difference
int i = 0;
int j = 0;
- GenericDistanceDBIDList<D> added = new GenericDistanceDBIDList<>();
- GenericDistanceDBIDList<D> removed = new GenericDistanceDBIDList<>();
+ ModifiableDoubleDBIDList added = DBIDUtil.newDistanceDBIDList();
+ ModifiableDoubleDBIDList removed = DBIDUtil.newDistanceDBIDList();
// TODO: use iterators.
while(i < oldkNNs.size() && j < newkNNs.size()) {
- DistanceDBIDPair<D> drp1 = oldkNNs.get(i);
- DistanceDBIDPair<D> drp2 = newkNNs.get(j);
+ DoubleDBIDPair drp1 = oldkNNs.get(i);
+ DoubleDBIDPair drp2 = newkNNs.get(j);
// NOTE: we assume that on ties they are ordered the same way!
if(!DBIDUtil.equal(drp1, drp2)) {
added.add(drp2);
@@ -240,13 +213,13 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
}
}
// add new RkNN
- for(DistanceDBIDListIter<D> newnn = added.iter(); newnn.valid(); newnn.advance()) {
- TreeSet<DistanceDBIDPair<D>> rknns = materialized_RkNN.get(newnn);
+ for(DoubleDBIDListIter newnn = added.iter(); newnn.valid(); newnn.advance()) {
+ TreeSet<DoubleDBIDPair> rknns = materialized_RkNN.get(newnn);
rknns.add(makePair(newnn, id));
}
// remove old RkNN
- for(DistanceDBIDListIter<D> oldnn = removed.iter(); oldnn.valid(); oldnn.advance()) {
- TreeSet<DistanceDBIDPair<D>> rknns = materialized_RkNN.get(oldnn);
+ for(DoubleDBIDListIter oldnn = removed.iter(); oldnn.valid(); oldnn.advance()) {
+ TreeSet<DoubleDBIDPair> rknns = materialized_RkNN.get(oldnn);
rknns.remove(makePair(oldnn, id));
}
@@ -262,12 +235,10 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
ArrayDBIDs aids = DBIDUtil.ensureArray(ids);
// delete the materialized (old) kNNs and RkNNs
- if(stepprog != null) {
- stepprog.beginStep(1, "New deletions ocurred, remove their materialized kNNs and RkNNs.", getLogger());
- }
+ getLogger().beginStep(stepprog, 1, "New deletions ocurred, remove their materialized kNNs and RkNNs.");
// Temporary storage of removed lists
- List<KNNList<D>> kNNs = new ArrayList<>(ids.size());
- List<TreeSet<DistanceDBIDPair<D>>> rkNNs = new ArrayList<>(ids.size());
+ List<KNNList> kNNs = new ArrayList<>(ids.size());
+ List<TreeSet<DoubleDBIDPair>> rkNNs = new ArrayList<>(ids.size());
for(DBIDIter iter = aids.iter(); iter.valid(); iter.advance()) {
kNNs.add(storage.get(iter));
storage.delete(iter);
@@ -279,16 +250,14 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
ArrayDBIDs rkNN_ids = affectedRkNN(rkNNs, aids);
// update the affected kNNs and RkNNs
- if(stepprog != null) {
- stepprog.beginStep(2, "New deletions ocurred, update the affected kNNs and RkNNs.", getLogger());
- }
+ getLogger().beginStep(stepprog, 2, "New deletions ocurred, update the affected kNNs and RkNNs.");
// Recompute the kNN for affected objects (in rkNN lists)
{
- List<? extends KNNList<D>> kNNList = knnQuery.getKNNForBulkDBIDs(rkNN_ids, k);
+ List<? extends KNNList> kNNList = knnQuery.getKNNForBulkDBIDs(rkNN_ids, k);
int i = 0;
for(DBIDIter reknn = rkNN_ids.iter(); reknn.valid(); reknn.advance(), i++) {
storage.put(reknn, kNNList.get(i));
- for(DistanceDBIDListIter<D> it = kNNList.get(i).iter(); it.valid(); it.advance()) {
+ for(DoubleDBIDListIter it = kNNList.get(i).iter(); it.valid(); it.advance()) {
materialized_RkNN.get(it).add(makePair(it, reknn));
}
}
@@ -297,8 +266,8 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
{
SetDBIDs idsSet = DBIDUtil.ensureSet(ids);
for(DBIDIter nn = kNN_ids.iter(); nn.valid(); nn.advance()) {
- TreeSet<DistanceDBIDPair<D>> rkNN = materialized_RkNN.get(nn);
- for(Iterator<DistanceDBIDPair<D>> it = rkNN.iterator(); it.hasNext();) {
+ TreeSet<DoubleDBIDPair> rkNN = materialized_RkNN.get(nn);
+ for(Iterator<DoubleDBIDPair> it = rkNN.iterator(); it.hasNext();) {
if(idsSet.contains(it.next())) {
it.remove();
}
@@ -307,14 +276,10 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
}
// inform listener
- if(stepprog != null) {
- stepprog.beginStep(3, "New deletions ocurred, inform listeners.", getLogger());
- }
+ getLogger().beginStep(stepprog, 3, "New deletions ocurred, inform listeners.");
fireKNNsRemoved(ids, rkNN_ids);
- if(stepprog != null) {
- stepprog.ensureCompleted(getLogger());
- }
+ getLogger().ensureCompleted(stepprog);
}
/**
@@ -324,9 +289,9 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
* @param remove the ids to remove
* @return the DBIDs in the given collection
*/
- protected ArrayDBIDs affectedkNN(List<? extends KNNList<D>> extraxt, DBIDs remove) {
+ protected ArrayDBIDs affectedkNN(List<? extends KNNList> extraxt, DBIDs remove) {
HashSetModifiableDBIDs ids = DBIDUtil.newHashSet();
- for(KNNList<D> drps : extraxt) {
+ for(KNNList drps : extraxt) {
for(DBIDIter iter = drps.iter(); iter.valid(); iter.advance()) {
ids.add(iter);
}
@@ -343,10 +308,10 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
* @param remove the ids to remove
* @return the DBIDs in the given collection
*/
- protected ArrayDBIDs affectedRkNN(List<? extends Collection<DistanceDBIDPair<D>>> extraxt, DBIDs remove) {
+ protected ArrayDBIDs affectedRkNN(List<? extends Collection<DoubleDBIDPair>> extraxt, DBIDs remove) {
HashSetModifiableDBIDs ids = DBIDUtil.newHashSet();
- for(Collection<DistanceDBIDPair<D>> drps : extraxt) {
- for(DistanceDBIDPair<D> drp : drps) {
+ for(Collection<DoubleDBIDPair> drps : extraxt) {
+ for(DoubleDBIDPair drp : drps) {
ids.add(drp);
}
}
@@ -361,7 +326,7 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
* @param id the query id
* @return the kNNs
*/
- public KNNList<D> getKNN(DBID id) {
+ public KNNList getKNN(DBID id) {
return storage.get(id);
}
@@ -371,22 +336,21 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
* @param id the query id
* @return the RkNNs
*/
- public GenericDistanceDBIDList<D> getRKNN(DBIDRef id) {
- TreeSet<DistanceDBIDPair<D>> rKNN = materialized_RkNN.get(id);
+ public DoubleDBIDList getRKNN(DBIDRef id) {
+ TreeSet<DoubleDBIDPair> rKNN = materialized_RkNN.get(id);
if(rKNN == null) {
return null;
}
- GenericDistanceDBIDList<D> ret = new GenericDistanceDBIDList<>(rKNN.size());
- for(DistanceDBIDPair<D> pair : rKNN) {
+ ModifiableDoubleDBIDList ret = DBIDUtil.newDistanceDBIDList(rKNN.size());
+ for(DoubleDBIDPair pair : rKNN) {
ret.add(pair);
}
ret.sort();
return ret;
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> RKNNQuery<O, S> getRKNNQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
+ public RKNNQuery<O> getRKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
if(!this.distanceFunction.equals(distanceQuery.getDistanceFunction())) {
return null;
}
@@ -399,7 +363,7 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
break;
}
}
- return new PreprocessorRKNNQuery<>(relation, (MaterializeKNNAndRKNNPreprocessor<O, S>) this);
+ return new PreprocessorRKNNQuery<>(relation, this);
}
@Override
@@ -423,22 +387,22 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
* @author Elke Achtert
*
* @param <O> The object type
- * @param <D> The distance type
+ * @param The distance type
*/
- public static class Factory<O, D extends Distance<D>> extends MaterializeKNNPreprocessor.Factory<O, D> {
+ public static class Factory<O> extends MaterializeKNNPreprocessor.Factory<O> {
/**
* Constructor.
*
* @param k k
* @param distanceFunction distance function
*/
- public Factory(int k, DistanceFunction<? super O, D> distanceFunction) {
+ public Factory(int k, DistanceFunction<? super O> distanceFunction) {
super(k, distanceFunction);
}
@Override
- public MaterializeKNNAndRKNNPreprocessor<O, D> instantiate(Relation<O> relation) {
- MaterializeKNNAndRKNNPreprocessor<O, D> instance = new MaterializeKNNAndRKNNPreprocessor<>(relation, distanceFunction, k);
+ public MaterializeKNNAndRKNNPreprocessor<O> instantiate(Relation<O> relation) {
+ MaterializeKNNAndRKNNPreprocessor<O> instance = new MaterializeKNNAndRKNNPreprocessor<>(relation, distanceFunction, k);
return instance;
}
@@ -449,9 +413,9 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends Distance<D>> extends MaterializeKNNPreprocessor.Factory.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends MaterializeKNNPreprocessor.Factory.Parameterizer<O> {
@Override
- protected Factory<O, D> makeInstance() {
+ protected Factory<O> makeInstance() {
return new Factory<>(k, distanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNPreprocessor.java
index 50ef21ed..ef48e4cb 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
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
@@ -33,14 +33,13 @@ 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.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.ids.SetDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-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.knn.KNNQuery;
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.Distance;
import de.lmu.ifi.dbs.elki.index.DynamicIndex;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
@@ -63,11 +62,10 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
* @apiviz.has KNNListener
*
* @param <O> the type of database objects the preprocessor can be applied to
- * @param <D> the type of distance the used distance function will return
*/
@Title("Materialize kNN Neighborhood preprocessor")
@Description("Materializes the k nearest neighbors of objects of a database.")
-public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor<O, D, KNNList<D>> implements DynamicIndex {
+public class MaterializeKNNPreprocessor<O> extends AbstractMaterializeKNNPreprocessor<O> implements DynamicIndex {
/**
* Logger to use.
*/
@@ -83,7 +81,7 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
/**
* KNNQuery instance to use.
*/
- protected final KNNQuery<O, D> knnQuery;
+ protected final KNNQuery<O> knnQuery;
/**
* Holds the listener.
@@ -97,7 +95,7 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
* @param distanceFunction the distance function to use
* @param k query k
*/
- public MaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, int k) {
+ public MaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O> distanceFunction, int k) {
super(relation, distanceFunction, k);
this.knnQuery = relation.getDatabase().getKNNQuery(distanceQuery, k, DatabaseQuery.HINT_BULK, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_NO_CACHE);
}
@@ -111,42 +109,33 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs());
- if (LOG.isStatistics()) {
+ if(LOG.isStatistics()) {
LOG.statistics(new LongStatistic(this.getClass().getName() + ".k", k));
}
- Duration duration = LOG.isStatistics() ? LOG.newDuration(this.getClass().getName() + ".precomputation-time") : null;
- if (duration != null) {
- duration.begin();
- }
+ Duration duration = LOG.isStatistics() ? LOG.newDuration(this.getClass().getName() + ".precomputation-time").begin() : null;
FiniteProgress progress = getLogger().isVerbose() ? new FiniteProgress("Materializing k nearest neighbors (k=" + k + ")", ids.size(), getLogger()) : null;
// Try bulk
- List<? extends KNNList<D>> kNNList = null;
- if (usebulk) {
+ List<? extends KNNList> kNNList = null;
+ if(usebulk) {
kNNList = knnQuery.getKNNForBulkDBIDs(ids, k);
- if (kNNList != null) {
+ if(kNNList != null) {
int i = 0;
- for (DBIDIter id = ids.iter(); id.valid(); id.advance(), i++) {
+ for(DBIDIter id = ids.iter(); id.valid(); id.advance(), i++) {
storage.put(id, kNNList.get(i));
- if (progress != null) {
- progress.incrementProcessed(getLogger());
- }
+ getLogger().incrementProcessed(progress);
}
}
- } else {
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- KNNList<D> knn = knnQuery.getKNNForDBID(iter, k);
+ }
+ else {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ KNNList knn = knnQuery.getKNNForDBID(iter, k);
storage.put(iter, knn);
- if (progress != null) {
- progress.incrementProcessed(getLogger());
- }
+ getLogger().incrementProcessed(progress);
}
}
- if (progress != null) {
- progress.ensureCompleted(getLogger());
- }
- if (duration != null) {
- duration.end();
- LOG.statistics(duration);
+ getLogger().ensureCompleted(progress);
+ if(duration != null) {
+ LOG.statistics(duration.end());
}
}
@@ -157,9 +146,10 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
@Override
public void insertAll(DBIDs ids) {
- if (storage == null && ids.size() > 0) {
+ if(storage == null && ids.size() > 0) {
preprocess();
- } else {
+ }
+ else {
objectsInserted(ids);
}
}
@@ -186,32 +176,24 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
ArrayDBIDs aids = DBIDUtil.ensureArray(ids);
// materialize the new kNNs
- if (stepprog != null) {
- stepprog.beginStep(1, "New insertions ocurred, materialize their new kNNs.", getLogger());
- }
+ getLogger().beginStep(stepprog, 1, "New insertions ocurred, materialize their new kNNs.");
// Bulk-query kNNs
- List<? extends KNNList<D>> kNNList = knnQuery.getKNNForBulkDBIDs(aids, k);
+ List<? extends KNNList> kNNList = knnQuery.getKNNForBulkDBIDs(aids, k);
// Store in storage
DBIDIter iter = aids.iter();
- for (int i = 0; i < aids.size(); i++, iter.advance()) {
+ for(int i = 0; i < aids.size(); i++, iter.advance()) {
storage.put(iter, kNNList.get(i));
}
// update the affected kNNs
- if (stepprog != null) {
- stepprog.beginStep(2, "New insertions ocurred, update the affected kNNs.", getLogger());
- }
+ getLogger().beginStep(stepprog, 2, "New insertions ocurred, update the affected kNNs.");
ArrayDBIDs rkNN_ids = updateKNNsAfterInsertion(ids);
// inform listener
- if (stepprog != null) {
- stepprog.beginStep(3, "New insertions ocurred, inform listeners.", getLogger());
- }
+ getLogger().beginStep(stepprog, 3, "New insertions ocurred, inform listeners.");
fireKNNsInserted(ids, rkNN_ids);
- if (stepprog != null) {
- stepprog.setCompleted(getLogger());
- }
+ getLogger().setCompleted(stepprog);
}
/**
@@ -225,21 +207,21 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
private ArrayDBIDs updateKNNsAfterInsertion(DBIDs ids) {
ArrayModifiableDBIDs rkNN_ids = DBIDUtil.newArray();
DBIDs oldids = DBIDUtil.difference(relation.getDBIDs(), ids);
- for (DBIDIter iter = oldids.iter(); iter.valid(); iter.advance()) {
- KNNList<D> kNNs = storage.get(iter);
- D knnDist = kNNs.get(kNNs.size() - 1).getDistance();
+ for(DBIDIter iter = oldids.iter(); iter.valid(); iter.advance()) {
+ KNNList kNNs = storage.get(iter);
+ double knnDist = kNNs.getKNNDistance();
// look for new kNNs
- KNNHeap<D> heap = null;
- for (DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) {
- D dist = distanceQuery.distance(iter, iter2);
- if (dist.compareTo(knnDist) <= 0) {
- if (heap == null) {
+ KNNHeap heap = null;
+ for(DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) {
+ double dist = distanceQuery.distance(iter, iter2);
+ if(dist <= knnDist) {
+ if(heap == null) {
heap = DBIDUtil.newHeap(kNNs);
}
heap.insert(dist, iter2);
}
}
- if (heap != null) {
+ if(heap != null) {
kNNs = heap.toKNNList();
storage.put(iter, kNNs);
rkNN_ids.add(iter);
@@ -258,10 +240,10 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
private ArrayDBIDs updateKNNsAfterDeletion(DBIDs ids) {
SetDBIDs idsSet = DBIDUtil.ensureSet(ids);
ArrayModifiableDBIDs rkNN_ids = DBIDUtil.newArray();
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- KNNList<D> kNNs = storage.get(iditer);
- for (DBIDIter it = kNNs.iter(); it.valid(); it.advance()) {
- if (idsSet.contains(it)) {
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ KNNList kNNs = storage.get(iditer);
+ for(DBIDIter it = kNNs.iter(); it.valid(); it.advance()) {
+ if(idsSet.contains(it)) {
rkNN_ids.add(iditer);
break;
}
@@ -269,9 +251,9 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
}
// update the kNNs of the RkNNs
- List<? extends KNNList<D>> kNNList = knnQuery.getKNNForBulkDBIDs(rkNN_ids, k);
+ List<? extends KNNList> kNNList = knnQuery.getKNNForBulkDBIDs(rkNN_ids, k);
DBIDIter iter = rkNN_ids.iter();
- for (int i = 0; i < rkNN_ids.size(); i++, iter.advance()) {
+ for(int i = 0; i < rkNN_ids.size(); i++, iter.advance()) {
storage.put(iter, kNNList.get(i));
}
@@ -288,28 +270,20 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
StepProgress stepprog = getLogger().isVerbose() ? new StepProgress(3) : null;
// delete the materialized (old) kNNs
- if (stepprog != null) {
- stepprog.beginStep(1, "New deletions ocurred, remove their materialized kNNs.", getLogger());
- }
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ getLogger().beginStep(stepprog, 1, "New deletions ocurred, remove their materialized kNNs.");
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
storage.delete(iter);
}
// update the affected kNNs
- if (stepprog != null) {
- stepprog.beginStep(2, "New deletions ocurred, update the affected kNNs.", getLogger());
- }
+ getLogger().beginStep(stepprog, 2, "New deletions ocurred, update the affected kNNs.");
ArrayDBIDs rkNN_ids = updateKNNsAfterDeletion(ids);
// inform listener
- if (stepprog != null) {
- stepprog.beginStep(3, "New deletions ocurred, inform listeners.", getLogger());
- }
+ getLogger().beginStep(stepprog, 3, "New deletions ocurred, inform listeners.");
fireKNNsRemoved(ids, rkNN_ids);
- if (stepprog != null) {
- stepprog.ensureCompleted(getLogger());
- }
+ getLogger().ensureCompleted(stepprog);
}
/**
@@ -324,8 +298,8 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
protected void fireKNNsInserted(DBIDs insertions, DBIDs updates) {
KNNChangeEvent e = new KNNChangeEvent(this, KNNChangeEvent.Type.INSERT, insertions, updates);
Object[] listeners = listenerList.getListenerList();
- for (int i = listeners.length - 2; i >= 0; i -= 2) {
- if (listeners[i] == KNNListener.class) {
+ for(int i = listeners.length - 2; i >= 0; i -= 2) {
+ if(listeners[i] == KNNListener.class) {
((KNNListener) listeners[i + 1]).kNNsChanged(e);
}
}
@@ -342,8 +316,8 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
protected void fireKNNsRemoved(DBIDs removals, DBIDs updates) {
KNNChangeEvent e = new KNNChangeEvent(this, KNNChangeEvent.Type.DELETE, removals, updates);
Object[] listeners = listenerList.getListenerList();
- for (int i = listeners.length - 2; i >= 0; i -= 2) {
- if (listeners[i] == KNNListener.class) {
+ for(int i = listeners.length - 2; i >= 0; i -= 2) {
+ if(listeners[i] == KNNListener.class) {
((KNNListener) listeners[i + 1]).kNNsChanged(e);
}
}
@@ -403,22 +377,21 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
* @apiviz.uses MaterializeKNNPreprocessor oneway - - «create»
*
* @param <O> The object type
- * @param <D> The distance type
*/
- public static class Factory<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory<O, D, KNNList<D>> {
+ public static class Factory<O> extends AbstractMaterializeKNNPreprocessor.Factory<O> {
/**
* Index factory.
*
* @param k k parameter
* @param distanceFunction distance function
*/
- public Factory(int k, DistanceFunction<? super O, D> distanceFunction) {
+ public Factory(int k, DistanceFunction<? super O> distanceFunction) {
super(k, distanceFunction);
}
@Override
- public MaterializeKNNPreprocessor<O, D> instantiate(Relation<O> relation) {
- MaterializeKNNPreprocessor<O, D> instance = new MaterializeKNNPreprocessor<>(relation, distanceFunction, k);
+ public MaterializeKNNPreprocessor<O> instantiate(Relation<O> relation) {
+ MaterializeKNNPreprocessor<O> instance = new MaterializeKNNPreprocessor<>(relation, distanceFunction, k);
return instance;
}
@@ -429,9 +402,9 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<O> {
@Override
- protected Factory<O, D> makeInstance() {
+ protected Factory<O> makeInstance() {
return new Factory<>(k, distanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MetricalIndexApproximationMaterializeKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MetricalIndexApproximationMaterializeKNNPreprocessor.java
index 43798fbc..b3e73abb 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MetricalIndexApproximationMaterializeKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MetricalIndexApproximationMaterializeKNNPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
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,10 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import gnu.trove.impl.Constants;
+import gnu.trove.map.hash.TObjectDoubleHashMap;
+
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import de.lmu.ifi.dbs.elki.data.NumberVector;
@@ -32,12 +34,10 @@ import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
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.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.index.tree.LeafEntry;
import de.lmu.ifi.dbs.elki.index.tree.Node;
import de.lmu.ifi.dbs.elki.index.tree.metrical.MetricalIndexTree;
@@ -63,13 +63,12 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
* @apiviz.uses MetricalIndexTree
*
* @param <O> the type of database objects the preprocessor can be applied to
- * @param <D> the type of distance the used distance function will return
* @param <N> the type of spatial nodes in the spatial index
* @param <E> the type of spatial entries in the spatial index
*/
@Title("Spatial Approximation Materialize kNN Preprocessor")
@Description("Caterializes the (approximate) k nearest neighbors of objects of a database using a spatial approximation.")
-public class MetricalIndexApproximationMaterializeKNNPreprocessor<O extends NumberVector<?>, D extends Distance<D>, N extends Node<E>, E extends MTreeEntry> extends AbstractMaterializeKNNPreprocessor<O, D, KNNList<D>> {
+public class MetricalIndexApproximationMaterializeKNNPreprocessor<O extends NumberVector, N extends Node<E>, E extends MTreeEntry> extends AbstractMaterializeKNNPreprocessor<O> {
/**
* Logger to use
*/
@@ -82,15 +81,15 @@ public class MetricalIndexApproximationMaterializeKNNPreprocessor<O extends Numb
* @param distanceFunction the distance function to use
* @param k query k
*/
- public MetricalIndexApproximationMaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, int k) {
+ public MetricalIndexApproximationMaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O> distanceFunction, int k) {
super(relation, distanceFunction, k);
}
@Override
protected void preprocess() {
- DistanceQuery<O, D> distanceQuery = relation.getDatabase().getDistanceQuery(relation, distanceFunction);
+ DistanceQuery<O> distanceQuery = relation.getDatabase().getDistanceQuery(relation, distanceFunction);
- MetricalIndexTree<O, D, N, E> index = getMetricalIndex(relation);
+ MetricalIndexTree<O, N, E> index = getMetricalIndex(relation);
createStorage();
MeanVariance pagesize = new MeanVariance();
@@ -113,13 +112,13 @@ public class MetricalIndexApproximationMaterializeKNNPreprocessor<O extends Numb
for(int i = 0; i < size; i++) {
ids.add(((LeafEntry) node.getEntry(i)).getDBID());
}
- HashMap<DBIDPair, D> cache = new HashMap<>((size * size * 3) >> 2);
+ TObjectDoubleHashMap<DBIDPair> cache = new TObjectDoubleHashMap<>((size * size * 3) >> 2, Constants.DEFAULT_LOAD_FACTOR, Double.NaN);
for(DBIDIter id = ids.iter(); id.valid(); id.advance()) {
- KNNHeap<D> kNN = DBIDUtil.newHeap(distanceFunction.getDistanceFactory(), k);
+ KNNHeap kNN = DBIDUtil.newHeap(k);
for(DBIDIter id2 = ids.iter(); id2.valid(); id2.advance()) {
DBIDPair key = DBIDUtil.newPair(id, id2);
- D d = cache.remove(key);
- if(d != null) {
+ double d = cache.remove(key);
+ if(d == d) { // Not NaN
// consume the previous result.
kNN.insert(d, id2);
}
@@ -140,13 +139,9 @@ public class MetricalIndexApproximationMaterializeKNNPreprocessor<O extends Numb
getLogger().warning("Cache should be empty after each run, but still has " + cache.size() + " elements.");
}
}
- if(progress != null) {
- progress.incrementProcessed(getLogger());
- }
- }
- if(progress != null) {
- progress.ensureCompleted(getLogger());
+ getLogger().incrementProcessed(progress);
}
+ getLogger().ensureCompleted(progress);
if(getLogger().isVerbose()) {
getLogger().verbose("Average page size = " + pagesize.getMean() + " +- " + pagesize.getSampleStddev());
getLogger().verbose("On average, " + ksize.getMean() + " +- " + ksize.getSampleStddev() + " neighbors returned.");
@@ -161,9 +156,9 @@ public class MetricalIndexApproximationMaterializeKNNPreprocessor<O extends Numb
* @return Metrical index
* @throws IllegalStateException when the cast fails.
*/
- private MetricalIndexTree<O, D, N, E> getMetricalIndex(Relation<O> relation) throws IllegalStateException {
- Class<MetricalIndexTree<O, D, N, E>> mcls = ClassGenericsUtil.uglyCastIntoSubclass(MetricalIndexTree.class);
- ArrayList<MetricalIndexTree<O, D, N, E>> indexes = ResultUtil.filterResults(relation.getDatabase(), mcls);
+ private MetricalIndexTree<O, N, E> getMetricalIndex(Relation<O> relation) throws IllegalStateException {
+ Class<MetricalIndexTree<O, N, E>> mcls = ClassGenericsUtil.uglyCastIntoSubclass(MetricalIndexTree.class);
+ ArrayList<MetricalIndexTree<O, N, E>> indexes = ResultUtil.filterResults(relation.getDatabase(), mcls);
// FIXME: check we got the right the representation
if(indexes.size() == 1) {
return indexes.get(0);
@@ -204,24 +199,23 @@ public class MetricalIndexApproximationMaterializeKNNPreprocessor<O extends Numb
* - «create»
*
* @param <O> the type of database objects the preprocessor can be applied to
- * @param <D> the type of distance the used distance function will return
* @param <N> the type of spatial nodes in the spatial index
* @param <E> the type of spatial entries in the spatial index
*/
- public static class Factory<O extends NumberVector<?>, D extends Distance<D>, N extends Node<E>, E extends MTreeEntry> extends AbstractMaterializeKNNPreprocessor.Factory<O, D, KNNList<D>> {
+ public static class Factory<O extends NumberVector, N extends Node<E>, E extends MTreeEntry> extends AbstractMaterializeKNNPreprocessor.Factory<O> {
/**
* Constructor.
*
* @param k k
* @param distanceFunction distance function
*/
- public Factory(int k, DistanceFunction<? super O, D> distanceFunction) {
+ public Factory(int k, DistanceFunction<? super O> distanceFunction) {
super(k, distanceFunction);
}
@Override
- public MetricalIndexApproximationMaterializeKNNPreprocessor<O, D, N, E> instantiate(Relation<O> relation) {
- MetricalIndexApproximationMaterializeKNNPreprocessor<O, D, N, E> instance = new MetricalIndexApproximationMaterializeKNNPreprocessor<>(relation, distanceFunction, k);
+ public MetricalIndexApproximationMaterializeKNNPreprocessor<O, N, E> instantiate(Relation<O> relation) {
+ MetricalIndexApproximationMaterializeKNNPreprocessor<O, N, E> instance = new MetricalIndexApproximationMaterializeKNNPreprocessor<>(relation, distanceFunction, k);
return instance;
}
@@ -232,9 +226,9 @@ public class MetricalIndexApproximationMaterializeKNNPreprocessor<O extends Numb
*
* @apiviz.exclude
*/
- public static class Parameterizer<O extends NumberVector<?>, D extends Distance<D>, N extends Node<E>, E extends MTreeEntry> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<O, D> {
+ public static class Parameterizer<O extends NumberVector, N extends Node<E>, E extends MTreeEntry> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<O> {
@Override
- protected Factory<O, D, N, E> makeInstance() {
+ protected Factory<O, N, E> makeInstance() {
return new Factory<>(k, distanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/PartitionApproximationMaterializeKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/PartitionApproximationMaterializeKNNPreprocessor.java
index b6cc5103..ef276e78 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/PartitionApproximationMaterializeKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/PartitionApproximationMaterializeKNNPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
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,24 +23,23 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.HashMap;
-
+import gnu.trove.impl.Constants;
+import gnu.trove.map.hash.TObjectDoubleHashMap;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
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.DBIDPair;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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.OptionID;
@@ -58,11 +57,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
* @author Erich Schubert
*
* @param <O> the type of database objects the preprocessor can be applied to
- * @param <D> the type of distance the used distance function will return
*/
@Title("Partitioning Approximate kNN Preprocessor")
@Description("Caterializes the (approximate) k nearest neighbors of objects of a database by partitioning and only computing kNN within each partition.")
-public class PartitionApproximationMaterializeKNNPreprocessor<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor<O, D, KNNList<D>> {
+public class PartitionApproximationMaterializeKNNPreprocessor<O> extends AbstractMaterializeKNNPreprocessor<O> {
/**
* Logger to use
*/
@@ -87,7 +85,7 @@ public class PartitionApproximationMaterializeKNNPreprocessor<O, D extends Dista
* @param partitions Number of partitions
* @param rnd Random number generator
*/
- public PartitionApproximationMaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, int k, int partitions, RandomFactory rnd) {
+ public PartitionApproximationMaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O> distanceFunction, int k, int partitions, RandomFactory rnd) {
super(relation, distanceFunction, k);
this.partitions = partitions;
this.rnd = rnd;
@@ -95,7 +93,7 @@ public class PartitionApproximationMaterializeKNNPreprocessor<O, D extends Dista
@Override
protected void preprocess() {
- DistanceQuery<O, D> distanceQuery = relation.getDatabase().getDistanceQuery(relation, distanceFunction);
+ DistanceQuery<O> distanceQuery = relation.getDatabase().getDistanceQuery(relation, distanceFunction);
storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC, KNNList.class);
MeanVariance ksize = new MeanVariance();
if(LOG.isVerbose()) {
@@ -109,13 +107,13 @@ public class PartitionApproximationMaterializeKNNPreprocessor<O, D extends Dista
for(int part = 0; part < partitions; part++) {
final ArrayDBIDs ids = parts[part];
final int size = ids.size();
- HashMap<DBIDPair, D> cache = new HashMap<>((size * size * 3) >> 3);
+ TObjectDoubleHashMap<DBIDPair> cache = new TObjectDoubleHashMap<>((size * size * 3) >> 3, Constants.DEFAULT_LOAD_FACTOR, Double.NaN);
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- KNNHeap<D> kNN = DBIDUtil.newHeap(distanceFunction.getDistanceFactory(), k);
+ KNNHeap kNN = DBIDUtil.newHeap(k);
for(DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) {
DBIDPair key = DBIDUtil.newPair(iter, iter2);
- D d = cache.remove(key);
- if(d != null) {
+ double d = cache.remove(key);
+ if(d == d) { // Not NaN
// consume the previous result.
kNN.insert(d, iter2);
}
@@ -136,13 +134,9 @@ public class PartitionApproximationMaterializeKNNPreprocessor<O, D extends Dista
LOG.warning("Cache should be empty after each run, but still has " + cache.size() + " elements.");
}
}
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
- }
- if(progress != null) {
- progress.ensureCompleted(LOG);
+ LOG.incrementProcessed(progress);
}
+ LOG.ensureCompleted(progress);
if(LOG.isVerbose()) {
LOG.verbose("On average, " + ksize.getMean() + " +- " + ksize.getSampleStddev() + " neighbors returned.");
}
@@ -178,9 +172,8 @@ public class PartitionApproximationMaterializeKNNPreprocessor<O, D extends Dista
* «create»
*
* @param <O> The object type
- * @param <D> The distance type
*/
- public static class Factory<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory<O, D, KNNList<D>> {
+ public static class Factory<O> extends AbstractMaterializeKNNPreprocessor.Factory<O> {
/**
* The number of partitions to use
*/
@@ -199,15 +192,15 @@ public class PartitionApproximationMaterializeKNNPreprocessor<O, D extends Dista
* @param partitions number of partitions
* @param rnd
*/
- public Factory(int k, DistanceFunction<? super O, D> distanceFunction, int partitions, RandomFactory rnd) {
+ public Factory(int k, DistanceFunction<? super O> distanceFunction, int partitions, RandomFactory rnd) {
super(k, distanceFunction);
this.partitions = partitions;
this.rnd = rnd;
}
@Override
- public PartitionApproximationMaterializeKNNPreprocessor<O, D> instantiate(Relation<O> relation) {
- PartitionApproximationMaterializeKNNPreprocessor<O, D> instance = new PartitionApproximationMaterializeKNNPreprocessor<>(relation, distanceFunction, k, partitions, rnd);
+ public PartitionApproximationMaterializeKNNPreprocessor<O> instantiate(Relation<O> relation) {
+ PartitionApproximationMaterializeKNNPreprocessor<O> instance = new PartitionApproximationMaterializeKNNPreprocessor<>(relation, distanceFunction, k, partitions, rnd);
return instance;
}
@@ -218,7 +211,7 @@ public class PartitionApproximationMaterializeKNNPreprocessor<O, D extends Dista
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<O> {
/**
* Parameter to specify the number of partitions to use for materializing
* the kNN. Must be an integer greater than 1.
@@ -261,7 +254,7 @@ public class PartitionApproximationMaterializeKNNPreprocessor<O, D extends Dista
}
@Override
- protected Factory<O, D> makeInstance() {
+ protected Factory<O> makeInstance() {
return new Factory<>(k, distanceFunction, partitions, rnd);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/RandomSampleKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/RandomSampleKNNPreprocessor.java
index 87b5a3c0..0f07713f 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/RandomSampleKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/RandomSampleKNNPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
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,15 +29,14 @@ 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.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -60,10 +59,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
@Reference(title = "Subsampling for Efficient and Effective Unsupervised Outlier Detection Ensembles", authors = "A. Zimek and M. Gaudet and R. J. G. B. Campello and J. Sander", booktitle = "Proc. 19th ACM SIGKDD International Conference on Knowledge Discovery and Data Mining, KDD '13")
-public class RandomSampleKNNPreprocessor<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor<O, D, KNNList<D>> {
+public class RandomSampleKNNPreprocessor<O> extends AbstractMaterializeKNNPreprocessor<O> {
/**
* Logger
*/
@@ -88,7 +86,7 @@ public class RandomSampleKNNPreprocessor<O, D extends Distance<D>> extends Abstr
* @param share Relative share
* @param rnd Random generator
*/
- public RandomSampleKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, int k, double share, RandomFactory rnd) {
+ public RandomSampleKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O> distanceFunction, int k, double share, RandomFactory rnd) {
super(relation, distanceFunction, k);
this.share = share;
this.rnd = rnd;
@@ -96,7 +94,7 @@ public class RandomSampleKNNPreprocessor<O, D extends Distance<D>> extends Abstr
@Override
protected void preprocess() {
- DistanceQuery<O, D> distanceQuery = relation.getDatabase().getDistanceQuery(relation, distanceFunction);
+ DistanceQuery<O> distanceQuery = relation.getDatabase().getDistanceQuery(relation, distanceFunction);
storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC, KNNList.class);
FiniteProgress progress = getLogger().isVerbose() ? new FiniteProgress("Materializing random-sample k nearest neighbors (k=" + k + ")", relation.size(), getLogger()) : null;
@@ -104,23 +102,19 @@ public class RandomSampleKNNPreprocessor<O, D extends Distance<D>> extends Abstr
final int samplesize = (int) (ids.size() * share);
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- KNNHeap<D> kNN = DBIDUtil.newHeap(distanceFunction.getDistanceFactory(), k);
+ KNNHeap kNN = DBIDUtil.newHeap(k);
DBIDs rsamp = DBIDUtil.randomSample(ids, samplesize, rnd);
for(DBIDIter iter2 = rsamp.iter(); iter2.valid(); iter2.advance()) {
- D dist = distanceQuery.distance(iter, iter2);
+ double dist = distanceQuery.distance(iter, iter2);
kNN.insert(dist, iter2);
}
storage.put(iter, kNN.toKNNList());
- if(progress != null) {
- progress.incrementProcessed(getLogger());
- }
+ getLogger().incrementProcessed(progress);
}
- if(progress != null) {
- progress.ensureCompleted(getLogger());
- }
+ getLogger().ensureCompleted(progress);
}
@Override
@@ -153,9 +147,8 @@ public class RandomSampleKNNPreprocessor<O, D extends Distance<D>> extends Abstr
* @apiviz.uses AbstractMaterializeKNNPreprocessor oneway - - «create»
*
* @param <O> The object type
- * @param <D> The distance type
*/
- public static class Factory<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory<O, D, KNNList<D>> {
+ public static class Factory<O> extends AbstractMaterializeKNNPreprocessor.Factory<O> {
/**
* Relative share of objects to get
*/
@@ -174,14 +167,14 @@ public class RandomSampleKNNPreprocessor<O, D extends Distance<D>> extends Abstr
* @param share Sample size (relative)
* @param rnd Random generator
*/
- public Factory(int k, DistanceFunction<? super O, D> distanceFunction, double share, RandomFactory rnd) {
+ public Factory(int k, DistanceFunction<? super O> distanceFunction, double share, RandomFactory rnd) {
super(k, distanceFunction);
this.share = share;
this.rnd = rnd;
}
@Override
- public RandomSampleKNNPreprocessor<O, D> instantiate(Relation<O> relation) {
+ public RandomSampleKNNPreprocessor<O> instantiate(Relation<O> relation) {
return new RandomSampleKNNPreprocessor<>(relation, distanceFunction, k, share, rnd);
}
@@ -193,9 +186,8 @@ public class RandomSampleKNNPreprocessor<O, D extends Distance<D>> extends Abstr
* @apiviz.exclude
*
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<O> {
/**
* Parameter to specify how many objects to consider for computing the
* kNN.
@@ -241,7 +233,7 @@ public class RandomSampleKNNPreprocessor<O, D extends Distance<D>> extends Abstr
}
@Override
- protected RandomSampleKNNPreprocessor.Factory<O, D> makeInstance() {
+ protected RandomSampleKNNPreprocessor.Factory<O> makeInstance() {
return new RandomSampleKNNPreprocessor.Factory<>(k, distanceFunction, share, rnd);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/SpatialApproximationMaterializeKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/SpatialApproximationMaterializeKNNPreprocessor.java
index 83f8f6d8..cd363091 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/SpatialApproximationMaterializeKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/SpatialApproximationMaterializeKNNPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
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,10 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import gnu.trove.impl.Constants;
+import gnu.trove.map.hash.TObjectDoubleHashMap;
+
import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
import de.lmu.ifi.dbs.elki.data.NumberVector;
@@ -34,12 +36,11 @@ import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
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.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.index.tree.LeafEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialIndexTree;
@@ -64,13 +65,12 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
*
* @apiviz.uses SpatialIndexTree
*
- * @param <D> the type of distance the used distance function will return
* @param <N> the type of spatial nodes in the spatial index
* @param <E> the type of spatial entries in the spatial index
*/
@Title("Spatial Approximation Materialize kNN Preprocessor")
@Description("Caterializes the (approximate) k nearest neighbors of objects of a database using a spatial approximation.")
-public class SpatialApproximationMaterializeKNNPreprocessor<O extends NumberVector<?>, D extends Distance<D>, N extends SpatialNode<N, E>, E extends SpatialEntry> extends AbstractMaterializeKNNPreprocessor<O, D, KNNList<D>> {
+public class SpatialApproximationMaterializeKNNPreprocessor<O extends NumberVector, N extends SpatialNode<N, E>, E extends SpatialEntry> extends AbstractMaterializeKNNPreprocessor<O> {
/**
* Logger to use
*/
@@ -83,13 +83,13 @@ public class SpatialApproximationMaterializeKNNPreprocessor<O extends NumberVect
* @param distanceFunction the distance function to use
* @param k query k
*/
- public SpatialApproximationMaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, int k) {
+ public SpatialApproximationMaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O> distanceFunction, int k) {
super(relation, distanceFunction, k);
}
@Override
protected void preprocess() {
- DistanceQuery<O, D> distanceQuery = relation.getDatabase().getDistanceQuery(relation, distanceFunction);
+ DistanceQuery<O> distanceQuery = relation.getDatabase().getDistanceQuery(relation, distanceFunction);
Collection<SpatialIndexTree<N, E>> indexes = ResultUtil.filterResults(relation, SpatialIndexTree.class);
if(indexes.size() != 1) {
@@ -118,13 +118,13 @@ public class SpatialApproximationMaterializeKNNPreprocessor<O extends NumberVect
for(int i = 0; i < size; i++) {
ids.add(((LeafEntry) node.getEntry(i)).getDBID());
}
- HashMap<DBIDPair, D> cache = new HashMap<>((size * size * 3) >> 3);
+ TObjectDoubleHashMap<DBIDPair> cache = new TObjectDoubleHashMap<>((size * size * 3) >> 3, Constants.DEFAULT_LOAD_FACTOR, Double.NaN);
for(DBIDIter id = ids.iter(); id.valid(); id.advance()) {
- KNNHeap<D> kNN = DBIDUtil.newHeap(distanceFunction.getDistanceFactory(), k);
+ KNNHeap kNN = DBIDUtil.newHeap(k);
for(DBIDIter id2 = ids.iter(); id2.valid(); id2.advance()) {
DBIDPair key = DBIDUtil.newPair(id, id2);
- D d = cache.remove(key);
- if(d != null) {
+ double d = cache.remove(key);
+ if(d == d) { // Not NaN
// consume the previous result.
kNN.insert(d, id2);
}
@@ -145,13 +145,9 @@ public class SpatialApproximationMaterializeKNNPreprocessor<O extends NumberVect
getLogger().warning("Cache should be empty after each run, but still has " + cache.size() + " elements.");
}
}
- if(progress != null) {
- progress.incrementProcessed(getLogger());
- }
- }
- if(progress != null) {
- progress.ensureCompleted(getLogger());
+ getLogger().incrementProcessed(progress);
}
+ getLogger().ensureCompleted(progress);
if(getLogger().isVerbose()) {
getLogger().verbose("Average page size = " + pagesize.getMean() + " +- " + pagesize.getSampleStddev());
getLogger().verbose("On average, " + ksize.getMean() + " +- " + ksize.getSampleStddev() + " neighbors returned.");
@@ -187,24 +183,23 @@ public class SpatialApproximationMaterializeKNNPreprocessor<O extends NumberVect
* @apiviz.uses SpatialApproximationMaterializeKNNPreprocessor oneway - -
* «create»
*
- * @param <D> the type of distance the used distance function will return
* @param <N> the type of spatial nodes in the spatial index
* @param <E> the type of spatial entries in the spatial index
*/
- public static class Factory<D extends Distance<D>, N extends SpatialNode<N, E>, E extends SpatialEntry> extends AbstractMaterializeKNNPreprocessor.Factory<NumberVector<?>, D, KNNList<D>> {
+ public static class Factory<N extends SpatialNode<N, E>, E extends SpatialEntry> extends AbstractMaterializeKNNPreprocessor.Factory<NumberVector> {
/**
* Constructor.
*
* @param k k
* @param distanceFunction distance function
*/
- public Factory(int k, DistanceFunction<? super NumberVector<?>, D> distanceFunction) {
+ public Factory(int k, DistanceFunction<? super NumberVector> distanceFunction) {
super(k, distanceFunction);
}
@Override
- public SpatialApproximationMaterializeKNNPreprocessor<NumberVector<?>, D, N, E> instantiate(Relation<NumberVector<?>> relation) {
- SpatialApproximationMaterializeKNNPreprocessor<NumberVector<?>, D, N, E> instance = new SpatialApproximationMaterializeKNNPreprocessor<>(relation, distanceFunction, k);
+ public SpatialApproximationMaterializeKNNPreprocessor<NumberVector, N, E> instantiate(Relation<NumberVector> relation) {
+ SpatialApproximationMaterializeKNNPreprocessor<NumberVector, N, E> instance = new SpatialApproximationMaterializeKNNPreprocessor<>(relation, distanceFunction, k);
return instance;
}
@@ -215,9 +210,9 @@ public class SpatialApproximationMaterializeKNNPreprocessor<O extends NumberVect
*
* @apiviz.exclude
*/
- public static class Parameterizer<D extends Distance<D>, N extends SpatialNode<N, E>, E extends SpatialEntry> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<NumberVector<?>, D> {
+ public static class Parameterizer<N extends SpatialNode<N, E>, E extends SpatialEntry> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<NumberVector> {
@Override
- protected Factory<D, N, E> makeInstance() {
+ protected Factory<N, E> makeInstance() {
return new Factory<>(k, distanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/package-info.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/package-info.java
index 47339bb4..f5e3d978 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/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/index/preprocessed/localpca/AbstractFilteredPCAIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/AbstractFilteredPCAIndex.java
index 67a2effc..9599e310 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/AbstractFilteredPCAIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/AbstractFilteredPCAIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.localpca;
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,11 +29,10 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
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.distance.DistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
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.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.index.preprocessed.AbstractPreprocessorIndex;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredResult;
@@ -44,7 +43,6 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
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.Parameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
@@ -61,11 +59,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
// TODO: loosen DoubleDistance restriction.
@Title("Local PCA Preprocessor")
@Description("Materializes the local PCA and the locally weighted matrix of objects of a database.")
-public abstract class AbstractFilteredPCAIndex<NV extends NumberVector<?>> extends AbstractPreprocessorIndex<NV, PCAFilteredResult> implements FilteredLocalPCAIndex<NV> {
+public abstract class AbstractFilteredPCAIndex<NV extends NumberVector> extends AbstractPreprocessorIndex<NV, PCAFilteredResult> implements FilteredLocalPCAIndex<NV> {
/**
* PCA utility object.
*/
- protected final PCAFilteredRunner<NV> pca;
+ protected final PCAFilteredRunner pca;
/**
* Constructor.
@@ -73,7 +71,7 @@ public abstract class AbstractFilteredPCAIndex<NV extends NumberVector<?>> exten
* @param relation Relation to use
* @param pca PCA runner to use
*/
- public AbstractFilteredPCAIndex(Relation<NV> relation, PCAFilteredRunner<NV> pca) {
+ public AbstractFilteredPCAIndex(Relation<NV> relation, PCAFilteredRunner pca) {
super(relation);
this.pca = pca;
}
@@ -97,19 +95,15 @@ public abstract class AbstractFilteredPCAIndex<NV extends NumberVector<?>> exten
// TODO: use a bulk operation?
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- DistanceDBIDList<DoubleDistance> objects = objectsForPCA(iditer);
+ DoubleDBIDList objects = objectsForPCA(iditer);
PCAFilteredResult pcares = pca.processQueryResult(objects, relation);
storage.put(iditer, pcares);
- if(progress != null) {
- progress.incrementProcessed(getLogger());
- }
- }
- if(progress != null) {
- progress.ensureCompleted(getLogger());
+ getLogger().incrementProcessed(progress);
}
+ getLogger().ensureCompleted(progress);
long end = System.currentTimeMillis();
if(getLogger().isVerbose()) {
@@ -134,7 +128,7 @@ public abstract class AbstractFilteredPCAIndex<NV extends NumberVector<?>> exten
* @return the list of the objects (i.e. the ids and the distances to the
* query object) to be considered within the PCA
*/
- protected abstract DistanceDBIDList<DoubleDistance> objectsForPCA(DBIDRef id);
+ protected abstract DoubleDBIDList objectsForPCA(DBIDRef id);
/**
* Factory class.
@@ -144,7 +138,7 @@ public abstract class AbstractFilteredPCAIndex<NV extends NumberVector<?>> exten
* @apiviz.stereotype factory
* @apiviz.uses AbstractFilteredPCAIndex oneway - - «create»
*/
- public abstract static class Factory<NV extends NumberVector<?>, I extends AbstractFilteredPCAIndex<NV>> implements FilteredLocalPCAIndex.Factory<NV, I>, Parameterizable {
+ public abstract static class Factory<NV extends NumberVector, I extends AbstractFilteredPCAIndex<NV>> implements FilteredLocalPCAIndex.Factory<NV, I> {
/**
* Parameter to specify the distance function used for running PCA.
*
@@ -156,12 +150,12 @@ public abstract class AbstractFilteredPCAIndex<NV extends NumberVector<?>> exten
* Holds the instance of the distance function specified by
* {@link #PCA_DISTANCE_ID}.
*/
- protected DistanceFunction<NV, DoubleDistance> pcaDistanceFunction;
+ protected DistanceFunction<NV> pcaDistanceFunction;
/**
* PCA utility object.
*/
- protected PCAFilteredRunner<NV> pca;
+ protected PCAFilteredRunner pca;
/**
* Constructor.
@@ -169,7 +163,7 @@ public abstract class AbstractFilteredPCAIndex<NV extends NumberVector<?>> exten
* @param pcaDistanceFunction distance Function
* @param pca PCA runner
*/
- public Factory(DistanceFunction<NV, DoubleDistance> pcaDistanceFunction, PCAFilteredRunner<NV> pca) {
+ public Factory(DistanceFunction<NV> pcaDistanceFunction, PCAFilteredRunner pca) {
super();
this.pcaDistanceFunction = pcaDistanceFunction;
this.pca = pca;
@@ -190,28 +184,28 @@ public abstract class AbstractFilteredPCAIndex<NV extends NumberVector<?>> exten
*
* @apiviz.exclude
*/
- public abstract static class Parameterizer<NV extends NumberVector<?>, I extends AbstractFilteredPCAIndex<NV>> extends AbstractParameterizer {
+ public abstract static class Parameterizer<NV extends NumberVector, I extends AbstractFilteredPCAIndex<NV>> extends AbstractParameterizer {
/**
* Holds the instance of the distance function specified by
* {@link #PCA_DISTANCE_ID}.
*/
- protected DistanceFunction<NV, DoubleDistance> pcaDistanceFunction;
+ protected DistanceFunction<NV> pcaDistanceFunction;
/**
* PCA utility object.
*/
- protected PCAFilteredRunner<NV> pca;
+ protected PCAFilteredRunner pca;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final ObjectParameter<DistanceFunction<NV, DoubleDistance>> pcaDistanceFunctionP = new ObjectParameter<>(PCA_DISTANCE_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
+ final ObjectParameter<DistanceFunction<NV>> pcaDistanceFunctionP = new ObjectParameter<>(PCA_DISTANCE_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
if(config.grab(pcaDistanceFunctionP)) {
pcaDistanceFunction = pcaDistanceFunctionP.instantiateClass(config);
}
- Class<PCAFilteredRunner<NV>> cls = ClassGenericsUtil.uglyCastIntoSubclass(PCAFilteredRunner.class);
+ Class<PCAFilteredRunner> cls = ClassGenericsUtil.uglyCastIntoSubclass(PCAFilteredRunner.class);
pca = config.tryInstantiate(cls);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/FilteredLocalPCAIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/FilteredLocalPCAIndex.java
index 2d64cbc0..85b98643 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/FilteredLocalPCAIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/FilteredLocalPCAIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.localpca;
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
@@ -36,7 +36,7 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredResult;
*
* @param <NV> Vector type
*/
-public interface FilteredLocalPCAIndex<NV extends NumberVector<?>> extends LocalProjectionIndex<NV, PCAFilteredResult> {
+public interface FilteredLocalPCAIndex<NV extends NumberVector> extends LocalProjectionIndex<NV, PCAFilteredResult> {
/**
* Get the precomputed local PCA for a particular object ID.
*
@@ -57,7 +57,7 @@ public interface FilteredLocalPCAIndex<NV extends NumberVector<?>> extends Local
* @param <NV> Vector type
* @param <I> Index type produced
*/
- public static interface Factory<NV extends NumberVector<?>, I extends FilteredLocalPCAIndex<NV>> extends LocalProjectionIndex.Factory<NV, I> {
+ public static interface Factory<NV extends NumberVector, I extends FilteredLocalPCAIndex<NV>> extends LocalProjectionIndex.Factory<NV, I> {
/**
* Instantiate the index for a given database.
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/KNNQueryFilteredPCAIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/KNNQueryFilteredPCAIndex.java
index 89c10bf2..49197bda 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/KNNQueryFilteredPCAIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/KNNQueryFilteredPCAIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.localpca;
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,12 +26,11 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.localpca;
import de.lmu.ifi.dbs.elki.data.NumberVector;
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.ids.KNNList;
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.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredRunner;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
@@ -53,10 +52,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*
* @param <NV> Vector type
*/
-// TODO: loosen DoubleDistance restriction.
@Title("Knn Query Based Local PCA Preprocessor")
@Description("Materializes the local PCA and the locally weighted matrix of objects of a database. The PCA is based on k nearest neighbor queries.")
-public class KNNQueryFilteredPCAIndex<NV extends NumberVector<?>> extends AbstractFilteredPCAIndex<NV> {
+public class KNNQueryFilteredPCAIndex<NV extends NumberVector> extends AbstractFilteredPCAIndex<NV> {
/**
* Logger.
*/
@@ -65,10 +63,10 @@ public class KNNQueryFilteredPCAIndex<NV extends NumberVector<?>> extends Abstra
/**
* The kNN query instance we use.
*/
- private final KNNQuery<NV, DoubleDistance> knnQuery;
+ private final KNNQuery<NV> knnQuery;
/**
- * Query k.
+ * Number of neighbors to query.
*/
private final int k;
@@ -80,7 +78,7 @@ public class KNNQueryFilteredPCAIndex<NV extends NumberVector<?>> extends Abstra
* @param knnQuery KNN Query to use
* @param k k value
*/
- public KNNQueryFilteredPCAIndex(Relation<NV> relation, PCAFilteredRunner<NV> pca, KNNQuery<NV, DoubleDistance> knnQuery, int k) {
+ public KNNQueryFilteredPCAIndex(Relation<NV> relation, PCAFilteredRunner pca, KNNQuery<NV> knnQuery, int k) {
super(relation, pca);
this.knnQuery = knnQuery;
this.k = k;
@@ -92,7 +90,7 @@ public class KNNQueryFilteredPCAIndex<NV extends NumberVector<?>> extends Abstra
}
@Override
- protected KNNList<DoubleDistance> objectsForPCA(DBIDRef id) {
+ protected KNNList objectsForPCA(DBIDRef id) {
return knnQuery.getKNNForDBID(id, k);
}
@@ -125,25 +123,11 @@ public class KNNQueryFilteredPCAIndex<NV extends NumberVector<?>> extends Abstra
* @apiviz.landmark
* @apiviz.uses KNNQueryFilteredPCAIndex oneway - - «create»
*/
- public static class Factory<V extends NumberVector<?>> extends AbstractFilteredPCAIndex.Factory<V, KNNQueryFilteredPCAIndex<V>> {
+ public static class Factory<V extends NumberVector> extends AbstractFilteredPCAIndex.Factory<V, KNNQueryFilteredPCAIndex<V>> {
/**
- * Optional parameter to specify the number of nearest neighbors considered
- * in the PCA, must be an integer greater than 0. If this parameter is not
- * set, k is set to three times of the dimensionality of the database
- * objects.
- * <p>
- * Key: {@code -localpca.k}
- * </p>
- * <p>
- * Default value: three times of the dimensionality of the database objects
- * </p>
+ * Number of neighbors to query.
*/
- public static final OptionID K_ID = new OptionID("localpca.k", "The number of nearest neighbors considered in the PCA. " + "If this parameter is not set, k ist set to three " + "times of the dimensionality of the database objects.");
-
- /**
- * Holds the value of {@link #K_ID}.
- */
- private Integer k = null;
+ private int k;
/**
* Constructor.
@@ -152,7 +136,7 @@ public class KNNQueryFilteredPCAIndex<NV extends NumberVector<?>> extends Abstra
* @param pca PCA class
* @param k k
*/
- public Factory(DistanceFunction<V, DoubleDistance> pcaDistanceFunction, PCAFilteredRunner<V> pca, Integer k) {
+ public Factory(DistanceFunction<V> pcaDistanceFunction, PCAFilteredRunner pca, int k) {
super(pcaDistanceFunction, pca);
this.k = k;
}
@@ -160,7 +144,7 @@ public class KNNQueryFilteredPCAIndex<NV extends NumberVector<?>> extends Abstra
@Override
public KNNQueryFilteredPCAIndex<V> instantiate(Relation<V> relation) {
// TODO: set bulk flag, once the parent class supports bulk.
- KNNQuery<V, DoubleDistance> knnquery = QueryUtil.getKNNQuery(relation, pcaDistanceFunction, k);
+ KNNQuery<V> knnquery = QueryUtil.getKNNQuery(relation, pcaDistanceFunction, k);
return new KNNQueryFilteredPCAIndex<>(relation, pca, knnquery, k);
}
@@ -171,16 +155,34 @@ public class KNNQueryFilteredPCAIndex<NV extends NumberVector<?>> extends Abstra
*
* @apiviz.exclude
*/
- public static class Parameterizer<NV extends NumberVector<?>> extends AbstractFilteredPCAIndex.Factory.Parameterizer<NV, KNNQueryFilteredPCAIndex<NV>> {
+ public static class Parameterizer<NV extends NumberVector> extends AbstractFilteredPCAIndex.Factory.Parameterizer<NV, KNNQueryFilteredPCAIndex<NV>> {
+ /**
+ * Optional parameter to specify the number of nearest neighbors
+ * considered in the PCA, must be an integer greater than 0. If this
+ * parameter is not set, k is set to three times of the dimensionality of
+ * the database objects.
+ * <p>
+ * Key: {@code -localpca.k}
+ * </p>
+ * <p>
+ * Default value: three times of the dimensionality of the database
+ * objects
+ * </p>
+ */
+ public static final OptionID K_ID = new OptionID("localpca.k", "The number of nearest neighbors considered in the PCA. " + "If this parameter is not set, k ist set to three " + "times of the dimensionality of the database objects.");
+
+ /**
+ * Number of neighbors to query.
+ */
protected int k = 0;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final IntParameter kP = new IntParameter(K_ID);
- kP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ final IntParameter kP = new IntParameter(K_ID) //
+ .addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
if(config.grab(kP)) {
- k = kP.getValue();
+ k = kP.intValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/RangeQueryFilteredPCAIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/RangeQueryFilteredPCAIndex.java
deleted file mode 100644
index 03b49df3..00000000
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/RangeQueryFilteredPCAIndex.java
+++ /dev/null
@@ -1,178 +0,0 @@
-package de.lmu.ifi.dbs.elki.index.preprocessed.localpca;
-
-/*
- 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.QueryUtil;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
-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.logging.Logging;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredRunner;
-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.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DistanceParameter;
-
-/**
- * Provides the local neighborhood to be considered in the PCA as the neighbors
- * within an epsilon range query of an object.
- *
- * @author Elke Achtert
- * @author Erich Schubert
- *
- * @apiviz.uses RangeQuery
- *
- * @param <NV> Vector type
- */
-@Title("Range Query Based Local PCA Preprocessor")
-@Description("Materializes the local PCA and the locally weighted matrix of objects of a database. The PCA is based on epsilon range queries.")
-public class RangeQueryFilteredPCAIndex<NV extends NumberVector<?>> extends AbstractFilteredPCAIndex<NV> {
- // TODO: lose DoubleDistance restriction.
- /**
- * Logger.
- */
- private static final Logging LOG = Logging.getLogger(RangeQueryFilteredPCAIndex.class);
-
- /**
- * The kNN query instance we use.
- */
- private final RangeQuery<NV, DoubleDistance> rangeQuery;
-
- /**
- * Query epsilon.
- */
- private final DoubleDistance epsilon;
-
- /**
- * Constructor.
- *
- * @param database Database to use
- * @param pca PCA Runner to use
- * @param rangeQuery Range Query to use
- * @param epsilon Query range
- */
- public RangeQueryFilteredPCAIndex(Relation<NV> database, PCAFilteredRunner<NV> pca, RangeQuery<NV, DoubleDistance> rangeQuery, DoubleDistance epsilon) {
- super(database, pca);
- this.rangeQuery = rangeQuery;
- this.epsilon = epsilon;
- }
-
- @Override
- protected DistanceDBIDList<DoubleDistance> objectsForPCA(DBIDRef id) {
- return rangeQuery.getRangeForDBID(id, epsilon);
- }
-
- @Override
- public String getLongName() {
- return "kNN-based local filtered PCA";
- }
-
- @Override
- public String getShortName() {
- return "kNNFilteredPCA";
- }
-
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-
- @Override
- public void logStatistics() {
- // No statistics to log.
- }
-
- /**
- * Factory class.
- *
- * @author Erich Schubert
- *
- * @apiviz.stereotype factory
- * @apiviz.uses RangeQueryFilteredPCAIndex oneway - - «create»
- */
- public static class Factory<V extends NumberVector<?>> extends AbstractFilteredPCAIndex.Factory<V, RangeQueryFilteredPCAIndex<V>> {
- /**
- * Parameter to specify the maximum radius of the neighborhood to be
- * considered in the PCA, must be suitable to the distance function
- * specified.
- *
- * Key: {@code -localpca.epsilon}
- */
- public static final OptionID EPSILON_ID = new OptionID("localpca.epsilon", "The maximum radius of the neighborhood to be considered in the PCA.");
-
- /**
- * Holds the value of {@link #EPSILON_ID}.
- */
- protected DoubleDistance epsilon;
-
- /**
- * Constructor.
- *
- * @param pcaDistanceFunction distance function
- * @param pca PCA
- * @param epsilon range value
- */
- public Factory(DistanceFunction<V, DoubleDistance> pcaDistanceFunction, PCAFilteredRunner<V> pca, DoubleDistance epsilon) {
- super(pcaDistanceFunction, pca);
- this.epsilon = epsilon;
- }
-
- @Override
- public RangeQueryFilteredPCAIndex<V> instantiate(Relation<V> relation) {
- // TODO: set bulk flag, once the parent class supports bulk.
- RangeQuery<V, DoubleDistance> rangequery = QueryUtil.getRangeQuery(relation, pcaDistanceFunction);
- return new RangeQueryFilteredPCAIndex<>(relation, pca, rangequery, epsilon);
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<NV extends NumberVector<?>> extends AbstractFilteredPCAIndex.Factory.Parameterizer<NV, RangeQueryFilteredPCAIndex<NV>> {
- protected DoubleDistance epsilon = null;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- DistanceParameter<DoubleDistance> epsilonP = new DistanceParameter<>(EPSILON_ID, pcaDistanceFunction != null ? pcaDistanceFunction.getDistanceFactory() : null);
- if(config.grab(epsilonP)) {
- epsilon = epsilonP.getValue();
- }
- }
-
- @Override
- protected Factory<NV> makeInstance() {
- return new Factory<>(pcaDistanceFunction, pca, epsilon);
- }
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/package-info.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/package-info.java
index 536dbb3c..a44b99a3 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/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/index/preprocessed/package-info.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/package-info.java
index 2edb1244..8107fe74 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/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/index/preprocessed/preference/AbstractPreferenceVectorIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/AbstractPreferenceVectorIndex.java
index dd43e027..80753ace 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/AbstractPreferenceVectorIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/AbstractPreferenceVectorIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.preference;
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,15 +23,12 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.preference;
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.type.TypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.index.preprocessed.AbstractPreprocessorIndex;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Abstract base class for preference vector based algorithms.
@@ -40,7 +37,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
*
* @param <NV> Number vector
*/
-public abstract class AbstractPreferenceVectorIndex<NV extends NumberVector<?>> extends AbstractPreprocessorIndex<NV, BitSet> implements PreferenceVectorIndex<NV> {
+public abstract class AbstractPreferenceVectorIndex<NV extends NumberVector> extends AbstractPreprocessorIndex<NV, long[]> implements PreferenceVectorIndex<NV> {
/**
* Constructor.
*
@@ -51,7 +48,7 @@ public abstract class AbstractPreferenceVectorIndex<NV extends NumberVector<?>>
}
@Override
- public BitSet getPreferenceVector(DBIDRef objid) {
+ public long[] getPreferenceVector(DBIDRef objid) {
if(storage == null) {
initialize();
}
@@ -66,7 +63,7 @@ public abstract class AbstractPreferenceVectorIndex<NV extends NumberVector<?>>
* @apiviz.stereotype factory
* @apiviz.uses AbstractPreferenceVectorIndex oneway - - «create»
*/
- public abstract static class Factory<V extends NumberVector<?>, I extends PreferenceVectorIndex<V>> implements PreferenceVectorIndex.Factory<V, I>, Parameterizable {
+ public abstract static class Factory<V extends NumberVector, I extends PreferenceVectorIndex<V>> implements PreferenceVectorIndex.Factory<V, I> {
@Override
public abstract I instantiate(Relation<V> relation);
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java
index 99a13a23..ccc04d45 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.preference;
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,17 +25,17 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.preference;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import de.lmu.ifi.dbs.elki.algorithm.APRIORI;
-import de.lmu.ifi.dbs.elki.data.Bit;
+import de.lmu.ifi.dbs.elki.algorithm.itemsetmining.APRIORI;
+import de.lmu.ifi.dbs.elki.algorithm.itemsetmining.Itemset;
import de.lmu.ifi.dbs.elki.data.BitVector;
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.VectorFieldTypeInformation;
+import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.HashmapDatabase;
import de.lmu.ifi.dbs.elki.database.UpdatableDatabase;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
@@ -43,23 +43,21 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.DoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.datasource.bundle.SingleObjectBundle;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.OnedimensionalDistanceFunction;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.result.AprioriResult;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
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;
@@ -78,7 +76,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* @param <V> Vector type
*/
@Description("Computes the preference vector of objects of a certain database according to the DiSH algorithm.")
-public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends AbstractPreferenceVectorIndex<V> implements PreferenceVectorIndex<V> {
+public class DiSHPreferenceVectorIndex<V extends NumberVector> extends AbstractPreferenceVectorIndex<V> implements PreferenceVectorIndex<V> {
/**
* Logger to use.
*/
@@ -103,7 +101,7 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
/**
* The epsilon value for each dimension.
*/
- protected DoubleDistance[] epsilon;
+ protected double[] epsilon;
/**
* Threshold for minimum number of points in the neighborhood.
@@ -123,7 +121,7 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
* @param minpts MinPts value
* @param strategy Strategy
*/
- public DiSHPreferenceVectorIndex(Relation<V> relation, DoubleDistance[] epsilon, int minpts, Strategy strategy) {
+ public DiSHPreferenceVectorIndex(Relation<V> relation, double[] epsilon, int minpts, Strategy strategy) {
super(relation);
this.epsilon = epsilon;
this.minpts = minpts;
@@ -136,7 +134,7 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
throw new IllegalArgumentException(ExceptionMessages.DATABASE_EMPTY);
}
- storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, BitSet.class);
+ storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, long[].class);
if(LOG.isDebugging()) {
StringBuilder msg = new StringBuilder();
@@ -152,13 +150,13 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
// only one epsilon value specified
int dim = RelationUtil.dimensionality(relation);
if(epsilon.length == 1 && dim != 1) {
- DoubleDistance eps = epsilon[0];
- epsilon = new DoubleDistance[dim];
+ double eps = epsilon[0];
+ epsilon = new double[dim];
Arrays.fill(epsilon, eps);
}
// epsilons as string
- RangeQuery<V, DoubleDistance>[] rangeQueries = initRangeQueries(relation, dim);
+ RangeQuery<V>[] rangeQueries = initRangeQueries(relation, dim);
for(DBIDIter it = relation.iterDBIDs(); it.valid(); it.advance()) {
StringBuilder msg = new StringBuilder();
@@ -172,7 +170,7 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
// determine neighbors in each dimension
ModifiableDBIDs[] allNeighbors = new ModifiableDBIDs[dim];
for(int d = 0; d < dim; d++) {
- DistanceDBIDList<DoubleDistance> qrList = rangeQueries[d].getRangeForDBID(it, epsilon[d]);
+ DoubleDBIDList qrList = rangeQueries[d].getRangeForDBID(it, epsilon[d]);
allNeighbors[d] = DBIDUtil.newHashSet(qrList);
}
@@ -184,24 +182,15 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
}
}
- try {
- storage.put(it, determinePreferenceVector(relation, allNeighbors, msg));
- }
- catch(UnableToComplyException e) {
- throw new IllegalStateException(e);
- }
+ storage.put(it, determinePreferenceVector(relation, allNeighbors, msg));
if(LOG.isDebugging()) {
LOG.debugFine(msg.toString());
}
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
- }
- if(progress != null) {
- progress.ensureCompleted(LOG);
+ LOG.incrementProcessed(progress);
}
+ LOG.ensureCompleted(progress);
long end = System.currentTimeMillis();
// TODO: re-add timing code!
@@ -218,10 +207,8 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
* @param neighborIDs the list of ids of the neighbors in each dimension
* @param msg a string buffer for debug messages
* @return the preference vector
- *
- * @throws de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException
*/
- private BitSet determinePreferenceVector(Relation<V> relation, ModifiableDBIDs[] neighborIDs, StringBuilder msg) throws UnableToComplyException {
+ private long[] determinePreferenceVector(Relation<V> relation, ModifiableDBIDs[] neighborIDs, StringBuilder msg) {
if(strategy.equals(Strategy.APRIORI)) {
return determinePreferenceVectorByApriori(relation, neighborIDs, msg);
}
@@ -240,31 +227,25 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
* @param neighborIDs the list of ids of the neighbors in each dimension
* @param msg a string buffer for debug messages
* @return the preference vector
- *
- * @throws de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException
- *
*/
- private BitSet determinePreferenceVectorByApriori(Relation<V> relation, ModifiableDBIDs[] neighborIDs, StringBuilder msg) throws UnableToComplyException {
+ private long[] determinePreferenceVectorByApriori(Relation<V> relation, ModifiableDBIDs[] neighborIDs, StringBuilder msg) {
int dimensionality = neighborIDs.length;
// database for apriori
UpdatableDatabase apriori_db = new HashmapDatabase();
- SimpleTypeInformation<?> bitmeta = new VectorFieldTypeInformation<>(BitVector.class, dimensionality);
+ SimpleTypeInformation<?> bitmeta = VectorFieldTypeInformation.typeRequest(BitVector.class, dimensionality, dimensionality);
for(DBIDIter it = relation.iterDBIDs(); it.valid(); it.advance()) {
- Bit[] bits = new Bit[dimensionality];
+ long[] bits = BitsUtil.zero(dimensionality);
boolean allFalse = true;
for(int d = 0; d < dimensionality; d++) {
if(neighborIDs[d].contains(it)) {
- bits[d] = Bit.TRUE;
+ BitsUtil.setI(bits, d);
allFalse = false;
}
- else {
- bits[d] = Bit.FALSE;
- }
}
if(!allFalse) {
SingleObjectBundle oaa = new SingleObjectBundle();
- oaa.append(bitmeta, new BitVector(bits));
+ oaa.append(bitmeta, new BitVector(bits, dimensionality));
apriori_db.insert(oaa);
}
}
@@ -272,27 +253,24 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
AprioriResult aprioriResult = apriori.run(apriori_db);
// result of apriori
- List<BitSet> frequentItemsets = aprioriResult.getSolution();
- Map<BitSet, Integer> supports = aprioriResult.getSupports();
+ List<Itemset> frequentItemsets = aprioriResult.getItemsets();
if(LOG.isDebugging()) {
msg.append("\n Frequent itemsets: ").append(frequentItemsets);
- msg.append("\n All supports: ").append(supports);
}
int maxSupport = 0;
int maxCardinality = 0;
- BitSet preferenceVector = new BitSet();
- for(BitSet bitSet : frequentItemsets) {
- int cardinality = bitSet.cardinality();
- if((maxCardinality < cardinality) || (maxCardinality == cardinality && maxSupport == supports.get(bitSet))) {
- preferenceVector = bitSet;
- maxCardinality = cardinality;
- maxSupport = supports.get(bitSet);
+ long[] preferenceVector = BitsUtil.zero(dimensionality);
+ for(Itemset itemset : frequentItemsets) {
+ if((maxCardinality < itemset.length()) || (maxCardinality == itemset.length() && maxSupport == itemset.getSupport())) {
+ preferenceVector = itemset.getItems();
+ maxCardinality = itemset.length();
+ maxSupport = itemset.getSupport();
}
}
if(LOG.isDebugging()) {
msg.append("\n preference ");
- msg.append(FormatUtil.format(dimensionality, preferenceVector));
+ msg.append(BitsUtil.toStringLow(preferenceVector, dimensionality));
msg.append('\n');
LOG.debugFine(msg.toString());
}
@@ -307,9 +285,9 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
* @param msg a string buffer for debug messages
* @return the preference vector
*/
- private BitSet determinePreferenceVectorByMaxIntersection(ModifiableDBIDs[] neighborIDs, StringBuilder msg) {
+ private long[] determinePreferenceVectorByMaxIntersection(ModifiableDBIDs[] neighborIDs, StringBuilder msg) {
int dimensionality = neighborIDs.length;
- BitSet preferenceVector = new BitSet(dimensionality);
+ long[] preferenceVector = BitsUtil.zero(dimensionality);
Map<Integer, ModifiableDBIDs> candidates = new HashMap<>(dimensionality);
for(int i = 0; i < dimensionality; i++) {
@@ -325,7 +303,7 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
if(!candidates.isEmpty()) {
int i = max(candidates);
ModifiableDBIDs intersection = candidates.remove(i);
- preferenceVector.set(i);
+ BitsUtil.setI(preferenceVector, i);
while(!candidates.isEmpty()) {
ModifiableDBIDs newIntersection = DBIDUtil.newHashSet();
i = maxIntersection(candidates, intersection, newIntersection);
@@ -338,14 +316,14 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
break;
}
else {
- preferenceVector.set(i);
+ BitsUtil.setI(preferenceVector, i);
}
}
}
if(LOG.isDebugging()) {
msg.append("\n preference ");
- msg.append(FormatUtil.format(dimensionality, preferenceVector));
+ msg.append(BitsUtil.toStringLow(preferenceVector, dimensionality));
msg.append('\n');
LOG.debug(msg.toString());
}
@@ -405,11 +383,12 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
* @return the dimension selecting distancefunctions to determine the
* preference vectors
*/
- private RangeQuery<V, DoubleDistance>[] initRangeQueries(Relation<V> relation, int dimensionality) {
- Class<RangeQuery<V, DoubleDistance>> rqcls = ClassGenericsUtil.uglyCastIntoSubclass(RangeQuery.class);
- RangeQuery<V, DoubleDistance>[] rangeQueries = ClassGenericsUtil.newArrayOfNull(dimensionality, rqcls);
+ private RangeQuery<V>[] initRangeQueries(Relation<V> relation, int dimensionality) {
+ Database db = relation.getDatabase();
+ Class<RangeQuery<V>> rqcls = ClassGenericsUtil.uglyCastIntoSubclass(RangeQuery.class);
+ RangeQuery<V>[] rangeQueries = ClassGenericsUtil.newArrayOfNull(dimensionality, rqcls);
for(int d = 0; d < dimensionality; d++) {
- rangeQueries[d] = relation.getDatabase().getRangeQuery(new PrimitiveDistanceQuery<>(relation, new DimensionSelectingDistanceFunction(d)));
+ rangeQueries[d] = db.getRangeQuery(new PrimitiveDistanceQuery<>(relation, new OnedimensionalDistanceFunction(d)));
}
return rangeQueries;
}
@@ -444,11 +423,11 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
*
* @param <V> Vector type
*/
- public static class Factory<V extends NumberVector<?>> extends AbstractPreferenceVectorIndex.Factory<V, DiSHPreferenceVectorIndex<V>> {
+ public static class Factory<V extends NumberVector> extends AbstractPreferenceVectorIndex.Factory<V, DiSHPreferenceVectorIndex<V>> {
/**
* The default value for epsilon.
*/
- public static final DoubleDistance DEFAULT_EPSILON = new DoubleDistance(0.001);
+ public static final double DEFAULT_EPSILON = 0.001;
/**
* A comma separated list of positive doubles specifying the maximum radius
@@ -509,7 +488,7 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
/**
* The epsilon value for each dimension.
*/
- protected DoubleDistance[] epsilon;
+ protected double[] epsilon;
/**
* Threshold for minimum number of points in the neighborhood.
@@ -528,7 +507,7 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
* @param minpts Minpts
* @param strategy Strategy
*/
- public Factory(DoubleDistance[] epsilon, int minpts, Strategy strategy) {
+ public Factory(double[] epsilon, int minpts, Strategy strategy) {
super();
this.epsilon = epsilon;
this.minpts = minpts;
@@ -556,11 +535,11 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* The epsilon value for each dimension.
*/
- protected DoubleDistance[] epsilon;
+ protected double[] epsilon;
/**
* Threshold for minimum number of points in the neighborhood.
@@ -584,16 +563,16 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
// parameter epsilon
// todo: constraint auf positive werte
List<Double> defaultEps = new ArrayList<>();
- defaultEps.add(DEFAULT_EPSILON.doubleValue());
+ defaultEps.add(DEFAULT_EPSILON);
final DoubleListParameter epsilonP = new DoubleListParameter(EPSILON_ID, true);
epsilonP.setDefaultValue(defaultEps);
if(config.grab(epsilonP)) {
List<Double> eps_list = epsilonP.getValue();
- epsilon = new DoubleDistance[eps_list.size()];
+ epsilon = new double[eps_list.size()];
for(int d = 0; d < eps_list.size(); d++) {
- epsilon[d] = new DoubleDistance(eps_list.get(d));
- if(epsilon[d].doubleValue() < 0) {
+ epsilon[d] = eps_list.get(d);
+ if(epsilon[d] < 0) {
config.reportError(new WrongParameterValueException(epsilonP, eps_list.toString()));
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/HiSCPreferenceVectorIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/HiSCPreferenceVectorIndex.java
index 8ead8458..843e4eda 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/HiSCPreferenceVectorIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/HiSCPreferenceVectorIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.preference;
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,6 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.preference;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.BitSet;
-
import de.lmu.ifi.dbs.elki.algorithm.clustering.subspace.HiSC;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.QueryUtil;
@@ -34,15 +32,14 @@ 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.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
-import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
@@ -66,7 +63,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*/
@Title("HiSC Preprocessor")
@Description("Computes the preference vector of objects of a certain database according to the HiSC algorithm.")
-public class HiSCPreferenceVectorIndex<V extends NumberVector<?>> extends AbstractPreferenceVectorIndex<V> implements PreferenceVectorIndex<V> {
+public class HiSCPreferenceVectorIndex<V extends NumberVector> extends AbstractPreferenceVectorIndex<V> implements PreferenceVectorIndex<V> {
/**
* Logger to use.
*/
@@ -101,14 +98,14 @@ public class HiSCPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
throw new IllegalArgumentException(ExceptionMessages.DATABASE_EMPTY);
}
- storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, BitSet.class);
+ storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, long[].class);
StringBuilder msg = new StringBuilder();
long start = System.currentTimeMillis();
FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("Preprocessing preference vector", relation.size(), LOG) : null;
- KNNQuery<V, DoubleDistance> knnQuery = QueryUtil.getKNNQuery(relation, EuclideanDistanceFunction.STATIC, k);
+ KNNQuery<V> knnQuery = QueryUtil.getKNNQuery(relation, EuclideanDistanceFunction.STATIC, k);
for(DBIDIter it = relation.iterDBIDs(); it.valid(); it.advance()) {
if(LOG.isDebugging()) {
@@ -117,17 +114,13 @@ public class HiSCPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
msg.append("\n knns: ");
}
- KNNList<DoubleDistance> knns = knnQuery.getKNNForDBID(it, k);
- BitSet preferenceVector = determinePreferenceVector(relation, it, knns, msg);
+ KNNList knns = knnQuery.getKNNForDBID(it, k);
+ long[] preferenceVector = determinePreferenceVector(relation, it, knns, msg);
storage.put(it, preferenceVector);
- if(progress != null) {
- progress.incrementProcessed(LOG);
- }
- }
- if(progress != null) {
- progress.ensureCompleted(LOG);
+ LOG.incrementProcessed(progress);
}
+ LOG.ensureCompleted(progress);
if(LOG.isDebugging()) {
LOG.debugFine(msg.toString());
@@ -151,24 +144,24 @@ public class HiSCPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
* @param msg a string buffer for debug messages
* @return the preference vector
*/
- private BitSet determinePreferenceVector(Relation<V> relation, DBIDRef id, DBIDs neighborIDs, StringBuilder msg) {
+ private long[] determinePreferenceVector(Relation<V> relation, DBIDRef id, DBIDs neighborIDs, StringBuilder msg) {
// variances
- double[] variances = DatabaseUtil.variances(relation, relation.get(id), neighborIDs);
+ double[] variances = RelationUtil.variances(relation, relation.get(id), neighborIDs);
// preference vector
- BitSet preferenceVector = new BitSet(variances.length);
+ long[] preferenceVector = BitsUtil.zero(variances.length);
for(int d = 0; d < variances.length; d++) {
if(variances[d] < alpha) {
- preferenceVector.set(d);
+ BitsUtil.setI(preferenceVector, d);
}
}
if(msg != null && LOG.isDebugging()) {
msg.append("\nalpha ").append(alpha);
msg.append("\nvariances ");
- msg.append(FormatUtil.format(variances, ", ", 4));
+ msg.append(FormatUtil.format(variances, ", ", FormatUtil.NF4));
msg.append("\npreference ");
- msg.append(FormatUtil.format(variances.length, preferenceVector));
+ msg.append(BitsUtil.toStringLow(preferenceVector, variances.length));
}
return preferenceVector;
@@ -204,7 +197,7 @@ public class HiSCPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
*
* @param <V> Vector type
*/
- public static class Factory<V extends NumberVector<?>> extends AbstractPreferenceVectorIndex.Factory<V, HiSCPreferenceVectorIndex<V>> {
+ public static class Factory<V extends NumberVector> extends AbstractPreferenceVectorIndex.Factory<V, HiSCPreferenceVectorIndex<V>> {
/**
* The default value for alpha.
*/
@@ -276,7 +269,7 @@ public class HiSCPreferenceVectorIndex<V extends NumberVector<?>> extends Abstra
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* Holds the value of parameter {@link #ALPHA_ID}.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/PreferenceVectorIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/PreferenceVectorIndex.java
index 87a9d3dd..45d88dd5 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/PreferenceVectorIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/PreferenceVectorIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.preference;
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,6 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.preference;
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.DBIDRef;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
@@ -38,14 +36,14 @@ import de.lmu.ifi.dbs.elki.index.IndexFactory;
*
* @param <NV> Vector type
*/
-public interface PreferenceVectorIndex<NV extends NumberVector<?>> extends Index {
+public interface PreferenceVectorIndex<NV extends NumberVector> extends Index {
/**
* Get the precomputed preference vector for a particular object ID.
*
* @param id Object ID
* @return Matrix
*/
- public BitSet getPreferenceVector(DBIDRef id);
+ public long[] getPreferenceVector(DBIDRef id);
/**
* Factory interface
@@ -58,7 +56,7 @@ public interface PreferenceVectorIndex<NV extends NumberVector<?>> extends Index
* @param <V> vector type
* @param <I> index type
*/
- public static interface Factory<V extends NumberVector<?>, I extends PreferenceVectorIndex<V>> extends IndexFactory<V, I> {
+ public static interface Factory<V extends NumberVector, I extends PreferenceVectorIndex<V>> extends IndexFactory<V, I> {
/**
* Instantiate the index for a given database.
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/package-info.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/package-info.java
index e840bfd0..f912afb7 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/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/index/preprocessed/snn/SharedNearestNeighborIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborIndex.java
index cdb1d0bb..89089847 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.snn;
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/index/preprocessed/snn/SharedNearestNeighborPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborPreprocessor.java
index 650e2169..a327abf7 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.snn;
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,12 +32,11 @@ import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
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.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
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.distancefunction.DistanceFunction;
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.index.preprocessed.AbstractPreprocessorIndex;
import de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNPreprocessor;
import de.lmu.ifi.dbs.elki.logging.Logging;
@@ -46,7 +45,6 @@ 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.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
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;
@@ -69,11 +67,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.has DistanceFunction
*
* @param <O> the type of database objects the preprocessor can be applied to
- * @param <D> the type of distance the used distance function will return
*/
@Title("Shared nearest neighbor Preprocessor")
@Description("Computes the k nearest neighbors of objects of a certain database.")
-public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends AbstractPreprocessorIndex<O, ArrayDBIDs> implements SharedNearestNeighborIndex<O> {
+public class SharedNearestNeighborPreprocessor<O> extends AbstractPreprocessorIndex<O, ArrayDBIDs> implements SharedNearestNeighborIndex<O> {
/**
* Get a logger for this class.
*/
@@ -87,7 +84,7 @@ public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends
/**
* Hold the distance function to be used.
*/
- protected DistanceFunction<O, D> distanceFunction;
+ protected DistanceFunction<O> distanceFunction;
/**
* Constructor.
@@ -96,7 +93,7 @@ public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends
* @param numberOfNeighbors Number of neighbors
* @param distanceFunction Distance function
*/
- public SharedNearestNeighborPreprocessor(Relation<O> relation, int numberOfNeighbors, DistanceFunction<O, D> distanceFunction) {
+ public SharedNearestNeighborPreprocessor(Relation<O> relation, int numberOfNeighbors, DistanceFunction<O> distanceFunction) {
super(relation);
this.numberOfNeighbors = numberOfNeighbors;
this.distanceFunction = distanceFunction;
@@ -108,12 +105,12 @@ public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends
getLogger().verbose("Assigning nearest neighbor lists to database objects");
}
storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, ArrayDBIDs.class);
- KNNQuery<O, D> knnquery = QueryUtil.getKNNQuery(relation, distanceFunction, numberOfNeighbors);
+ KNNQuery<O> knnquery = QueryUtil.getKNNQuery(relation, distanceFunction, numberOfNeighbors);
FiniteProgress progress = getLogger().isVerbose() ? new FiniteProgress("assigning nearest neighbor lists", relation.size(), getLogger()) : null;
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
ArrayModifiableDBIDs neighbors = DBIDUtil.newArray(numberOfNeighbors);
- KNNList<D> kNN = knnquery.getKNNForDBID(iditer, numberOfNeighbors);
+ DBIDs kNN = knnquery.getKNNForDBID(iditer, numberOfNeighbors);
for(DBIDIter iter = kNN.iter(); iter.valid(); iter.advance()) {
// if(!id.equals(nid)) {
neighbors.add(iter);
@@ -125,13 +122,9 @@ public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends
}
neighbors.sort();
storage.put(iditer, neighbors);
- if(progress != null) {
- progress.incrementProcessed(getLogger());
- }
- }
- if(progress != null) {
- progress.ensureCompleted(getLogger());
+ getLogger().incrementProcessed(progress);
}
+ getLogger().ensureCompleted(progress);
}
@Override
@@ -180,7 +173,7 @@ public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends
* @apiviz.stereotype factory
* @apiviz.uses SharedNearestNeighborPreprocessor oneway - - «create»
*/
- public static class Factory<O, D extends Distance<D>> implements SharedNearestNeighborIndex.Factory<O, SharedNearestNeighborPreprocessor<O, D>>, Parameterizable {
+ public static class Factory<O> implements SharedNearestNeighborIndex.Factory<O, SharedNearestNeighborPreprocessor<O>> {
/**
* Parameter to indicate the number of neighbors to be taken into account
* for the shared-nearest-neighbor similarity.
@@ -215,7 +208,7 @@ public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends
/**
* Hold the distance function to be used.
*/
- protected DistanceFunction<O, D> distanceFunction;
+ protected DistanceFunction<O> distanceFunction;
/**
* Constructor.
@@ -223,14 +216,14 @@ public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends
* @param numberOfNeighbors Number of neighbors
* @param distanceFunction Distance function
*/
- public Factory(int numberOfNeighbors, DistanceFunction<O, D> distanceFunction) {
+ public Factory(int numberOfNeighbors, DistanceFunction<O> distanceFunction) {
super();
this.numberOfNeighbors = numberOfNeighbors;
this.distanceFunction = distanceFunction;
}
@Override
- public SharedNearestNeighborPreprocessor<O, D> instantiate(Relation<O> relation) {
+ public SharedNearestNeighborPreprocessor<O> instantiate(Relation<O> relation) {
return new SharedNearestNeighborPreprocessor<>(relation, numberOfNeighbors, distanceFunction);
}
@@ -256,7 +249,7 @@ public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractParameterizer {
+ public static class Parameterizer<O> extends AbstractParameterizer {
/**
* Holds the number of nearest neighbors to be used.
*/
@@ -265,7 +258,7 @@ public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends
/**
* Hold the distance function to be used.
*/
- protected DistanceFunction<O, D> distanceFunction;
+ protected DistanceFunction<O> distanceFunction;
@Override
protected void makeOptions(Parameterization config) {
@@ -276,14 +269,14 @@ public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends
numberOfNeighbors = numberOfNeighborsP.getValue();
}
- final ObjectParameter<DistanceFunction<O, D>> distanceFunctionP = new ObjectParameter<>(DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
+ final ObjectParameter<DistanceFunction<O>> distanceFunctionP = new ObjectParameter<>(DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
if(config.grab(distanceFunctionP)) {
distanceFunction = distanceFunctionP.instantiateClass(config);
}
}
@Override
- protected Factory<O, D> makeInstance() {
+ protected Factory<O> makeInstance() {
return new Factory<>(numberOfNeighbors, distanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/package-info.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/package-info.java
index 5612f655..8c81623c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/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/index/preprocessed/subspaceproj/AbstractSubspaceProjectionIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/AbstractSubspaceProjectionIndex.java
deleted file mode 100644
index a219444e..00000000
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/AbstractSubspaceProjectionIndex.java
+++ /dev/null
@@ -1,272 +0,0 @@
-package de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj;
-
-/*
- 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.algorithm.clustering.AbstractProjectedDBSCAN;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-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.QueryUtil;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
-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.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
-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.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.AbstractPreprocessorIndex;
-import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.ProjectionResult;
-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.ExceptionMessages;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
-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.DistanceParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
-
-/**
- * Abstract base class for a local PCA based index.
- *
- * @author Elke Achtert
- * @author Erich Schubert
- *
- * @apiviz.has DistanceFunction
- *
- * @param <NV> Vector type
- */
-@Title("Local PCA Preprocessor")
-@Description("Materializes the local PCA and the locally weighted matrix of objects of a database.")
-public abstract class AbstractSubspaceProjectionIndex<NV extends NumberVector<?>, D extends Distance<D>, P extends ProjectionResult> extends AbstractPreprocessorIndex<NV, P> implements SubspaceProjectionIndex<NV, P> {
- /**
- * Contains the value of parameter epsilon;
- */
- protected D epsilon;
-
- /**
- * The distance function for the variance analysis.
- */
- protected DistanceFunction<NV, D> rangeQueryDistanceFunction;
-
- /**
- * Holds the value of parameter minpts.
- */
- protected int minpts;
-
- /**
- * Constructor.
- *
- * @param relation Relation
- * @param epsilon Maximum Epsilon
- * @param rangeQueryDistanceFunction range query
- * @param minpts Minpts
- */
- public AbstractSubspaceProjectionIndex(Relation<NV> relation, D epsilon, DistanceFunction<NV, D> rangeQueryDistanceFunction, int minpts) {
- super(relation);
- this.epsilon = epsilon;
- this.rangeQueryDistanceFunction = rangeQueryDistanceFunction;
- this.minpts = minpts;
- }
-
- @Override
- public void initialize() {
- if(relation == null || relation.size() <= 0) {
- throw new IllegalArgumentException(ExceptionMessages.DATABASE_EMPTY);
- }
- if(storage != null) {
- // Preprocessor was already run.
- return;
- }
- storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, ProjectionResult.class);
-
- long start = System.currentTimeMillis();
- RangeQuery<NV, D> rangeQuery = QueryUtil.getRangeQuery(relation, rangeQueryDistanceFunction);
-
- FiniteProgress progress = getLogger().isVerbose() ? new FiniteProgress(this.getClass().getName(), relation.size(), getLogger()) : null;
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- DistanceDBIDList<D> neighbors = rangeQuery.getRangeForDBID(iditer, epsilon);
-
- final P pres;
- if(neighbors.size() >= minpts) {
- pres = computeProjection(iditer, neighbors, relation);
- }
- else {
- DistanceDBIDPair<D> firstQR = neighbors.iter().getDistancePair();
- GenericDistanceDBIDList<D> newne = new GenericDistanceDBIDList<>();
- newne.add(firstQR);
- pres = computeProjection(iditer, newne, relation);
- }
- storage.put(iditer, pres);
-
- if(progress != null) {
- progress.incrementProcessed(getLogger());
- }
- }
- if(progress != null) {
- progress.ensureCompleted(getLogger());
- }
-
- long end = System.currentTimeMillis();
- // TODO: re-add timing code!
- if(true) {
- long elapsedTime = end - start;
- getLogger().verbose(this.getClass().getName() + " runtime: " + elapsedTime + " milliseconds.");
- }
- }
-
- @Override
- public P getLocalProjection(DBIDRef objid) {
- if(storage == null) {
- initialize();
- }
- return storage.get(objid);
- }
-
- /**
- * This method implements the type of variance analysis to be computed for a
- * given point.
- * <p/>
- * Example1: for 4C, this method should implement a PCA for the given point.
- * Example2: for PreDeCon, this method should implement a simple axis-parallel
- * variance analysis.
- *
- * @param id the given point
- * @param neighbors the neighbors as query results of the given point
- * @param relation the database for which the preprocessing is performed
- *
- * @return local subspace projection
- */
- protected abstract P computeProjection(DBIDRef id, DistanceDBIDList<D> neighbors, Relation<NV> relation);
-
- /**
- * Factory class
- *
- * @author Erich Schubert
- *
- * @apiviz.stereotype factory
- * @apiviz.uses AbstractSubspaceProjectionIndex oneway - - «create»
- */
- public abstract static class Factory<NV extends NumberVector<?>, D extends Distance<D>, I extends AbstractSubspaceProjectionIndex<NV, D, ?>> implements SubspaceProjectionIndex.Factory<NV, I>, Parameterizable {
- /**
- * Contains the value of parameter epsilon;
- */
- protected D epsilon;
-
- /**
- * The distance function for the variance analysis.
- */
- protected DistanceFunction<NV, D> rangeQueryDistanceFunction;
-
- /**
- * Holds the value of parameter minpts.
- */
- protected int minpts;
-
- /**
- * Constructor.
- *
- * @param epsilon
- * @param rangeQueryDistanceFunction
- * @param minpts
- */
- public Factory(D epsilon, DistanceFunction<NV, D> rangeQueryDistanceFunction, int minpts) {
- super();
- this.epsilon = epsilon;
- this.rangeQueryDistanceFunction = rangeQueryDistanceFunction;
- this.minpts = minpts;
- }
-
- @Override
- public abstract I instantiate(Relation<NV> relation);
-
- @Override
- public TypeInformation getInputTypeRestriction() {
- return TypeUtil.NUMBER_VECTOR_FIELD;
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public abstract static class Parameterizer<NV extends NumberVector<?>, D extends Distance<D>, C> extends AbstractParameterizer {
- /**
- * Contains the value of parameter epsilon;
- */
- protected D epsilon = null;
-
- /**
- * The distance function for the variance analysis.
- */
- protected DistanceFunction<NV, D> rangeQueryDistanceFunction = null;
-
- /**
- * Holds the value of parameter minpts.
- */
- protected int minpts = 0;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- configRangeQueryDistanceFunction(config);
- configEpsilon(config, rangeQueryDistanceFunction);
- configMinPts(config);
- }
-
- protected void configRangeQueryDistanceFunction(Parameterization config) {
- ObjectParameter<DistanceFunction<NV, D>> rangeQueryDistanceP = new ObjectParameter<>(AbstractProjectedDBSCAN.INNER_DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
- if(config.grab(rangeQueryDistanceP)) {
- rangeQueryDistanceFunction = rangeQueryDistanceP.instantiateClass(config);
- }
- }
-
- protected void configEpsilon(Parameterization config, DistanceFunction<NV, D> rangeQueryDistanceFunction) {
- D distanceParser = rangeQueryDistanceFunction != null ? rangeQueryDistanceFunction.getDistanceFactory() : null;
- DistanceParameter<D> epsilonP = new DistanceParameter<>(AbstractProjectedDBSCAN.EPSILON_ID, distanceParser);
- // parameter epsilon
- if(config.grab(epsilonP)) {
- epsilon = epsilonP.getValue();
- }
- }
-
- protected void configMinPts(Parameterization config) {
- IntParameter minptsP = new IntParameter(AbstractProjectedDBSCAN.MINPTS_ID);
- minptsP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
- if(config.grab(minptsP)) {
- minpts = minptsP.intValue();
- }
- }
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/FourCSubspaceIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/FourCSubspaceIndex.java
deleted file mode 100644
index 35aaa40c..00000000
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/FourCSubspaceIndex.java
+++ /dev/null
@@ -1,260 +0,0 @@
-package de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj;
-
-/*
- 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.ArrayList;
-
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-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.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-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.Distance;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.LimitEigenPairFilter;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredResult;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredRunner;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-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.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GlobalParameterConstraint;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.ParameterConstraint;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.ParameterFlagGlobalConstraint;
-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.DoubleParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
-
-/**
- * Preprocessor for 4C local dimensionality and locally weighted matrix
- * assignment to objects of a certain database.
- *
- * @author Arthur Zimek
- *
- * @apiviz.composedOf PCAFilteredRunner
- *
- * @param <V> Vector type
- * @param <D> Distance type
- */
-@Title("4C Preprocessor")
-@Description("Computes the local dimensionality and locally weighted matrix of objects of a certain database according to the 4C algorithm.\n" + "The PCA is based on epsilon range queries.")
-public class FourCSubspaceIndex<V extends NumberVector<?>, D extends Distance<D>> extends AbstractSubspaceProjectionIndex<V, D, PCAFilteredResult> {
- /**
- * Our logger
- */
- private static final Logging LOG = Logging.getLogger(FourCSubspaceIndex.class);
-
- /**
- * The Filtered PCA Runner
- */
- private PCAFilteredRunner<V> pca;
-
- /**
- * Full constructor.
- *
- * @param relation Relation
- * @param epsilon Epsilon value
- * @param rangeQueryDistanceFunction
- * @param minpts MinPts value
- * @param pca PCA runner
- */
- public FourCSubspaceIndex(Relation<V> relation, D epsilon, DistanceFunction<V, D> rangeQueryDistanceFunction, int minpts, PCAFilteredRunner<V> pca) {
- super(relation, epsilon, rangeQueryDistanceFunction, minpts);
- this.pca = pca;
- }
-
- @Override
- protected PCAFilteredResult computeProjection(DBIDRef id, DistanceDBIDList<D> neighbors, Relation<V> database) {
- ModifiableDBIDs ids = DBIDUtil.newArray(neighbors.size());
- for(DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
- ids.add(neighbor);
- }
- PCAFilteredResult pcares = pca.processIds(ids, database);
-
- if(LOG.isDebugging()) {
- StringBuilder msg = new StringBuilder();
- msg.append(id).append(' '); // .append(database.getObjectLabelQuery().get(id));
- msg.append("\ncorrDim ").append(pcares.getCorrelationDimension());
- LOG.debugFine(msg.toString());
- }
- return pcares;
- }
-
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-
- @Override
- public String getLongName() {
- return "4C local Subspaces";
- }
-
- @Override
- public String getShortName() {
- return "4C-subspaces";
- }
-
- @Override
- public void logStatistics() {
- // No statistics to log.
- }
-
- /**
- * Factory class for 4C preprocessors.
- *
- * @author Erich Schubert
- *
- * @apiviz.stereotype factory
- * @apiviz.uses FourCSubspaceIndex oneway - - «creates»
- *
- * @param <V> Vector type
- * @param <D> Distance type
- */
- public static class Factory<V extends NumberVector<?>, D extends Distance<D>> extends AbstractSubspaceProjectionIndex.Factory<V, D, FourCSubspaceIndex<V, D>> {
- /**
- * The default value for delta.
- */
- public static final double DEFAULT_DELTA = LimitEigenPairFilter.DEFAULT_DELTA;
-
- /**
- * The Filtered PCA Runner
- */
- private PCAFilteredRunner<V> pca;
-
- /**
- * Constructor.
- *
- * @param epsilon
- * @param rangeQueryDistanceFunction
- * @param minpts
- * @param pca
- */
- public Factory(D epsilon, DistanceFunction<V, D> rangeQueryDistanceFunction, int minpts, PCAFilteredRunner<V> pca) {
- super(epsilon, rangeQueryDistanceFunction, minpts);
- this.pca = pca;
- }
-
- @Override
- public FourCSubspaceIndex<V, D> instantiate(Relation<V> relation) {
- return new FourCSubspaceIndex<>(relation, epsilon, rangeQueryDistanceFunction, minpts, pca);
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<V extends NumberVector<?>, D extends Distance<D>> extends AbstractSubspaceProjectionIndex.Factory.Parameterizer<V, D, Factory<V, D>> {
- /**
- * The Filtered PCA Runner
- */
- private PCAFilteredRunner<V> pca;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- // flag absolute
- boolean absolute = false;
- Flag absoluteF = new Flag(LimitEigenPairFilter.EIGENPAIR_FILTER_ABSOLUTE);
- if(config.grab(absoluteF)) {
- absolute = absoluteF.isTrue();
- }
-
- // Parameter delta
- double delta = 0.0;
- DoubleParameter deltaP = new DoubleParameter(LimitEigenPairFilter.EIGENPAIR_FILTER_DELTA, DEFAULT_DELTA);
- deltaP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
- if(config.grab(deltaP)) {
- delta = deltaP.doubleValue();
- }
- // Absolute flag doesn't have a sensible default value for delta.
- if(absolute && deltaP.tookDefaultValue()) {
- config.reportError(new WrongParameterValueException("Illegal parameter setting: " + "Flag " + absoluteF.getName() + " is set, " + "but no value for " + deltaP.getName() + " is specified."));
- }
-
- // if (optionHandler.isSet(DELTA_P)) {
- // delta = (Double) optionHandler.getOptionValue(DELTA_P);
- // try {
- // if (!absolute && delta < 0 || delta > 1)
- // throw new WrongParameterValueException(DELTA_P, "delta", DELTA_D);
- // } catch (NumberFormatException e) {
- // throw new WrongParameterValueException(DELTA_P, "delta", DELTA_D, e);
- // }
- // } else if (!absolute) {
- // delta = LimitEigenPairFilter.DEFAULT_DELTA;
- // } else {
- // throw new WrongParameterValueException("Illegal parameter setting: "
- // +
- // "Flag " + ABSOLUTE_F + " is set, " + "but no value for " + DELTA_P +
- // " is specified.");
- // }
-
- // Parameterize PCA
- ListParameterization pcaParameters = new ListParameterization();
- // eigen pair filter
- pcaParameters.addParameter(PCAFilteredRunner.PCA_EIGENPAIR_FILTER, LimitEigenPairFilter.class.getName());
- // abs
- if(absolute) {
- pcaParameters.addFlag(LimitEigenPairFilter.EIGENPAIR_FILTER_ABSOLUTE);
- }
- // delta
- pcaParameters.addParameter(LimitEigenPairFilter.EIGENPAIR_FILTER_DELTA, delta);
- // big value
- pcaParameters.addParameter(PCAFilteredRunner.BIG_ID, 50);
- // small value
- pcaParameters.addParameter(PCAFilteredRunner.SMALL_ID, 1);
- Class<PCAFilteredRunner<V>> cls = ClassGenericsUtil.uglyCastIntoSubclass(PCAFilteredRunner.class);
- pca = pcaParameters.tryInstantiate(cls);
- for(ParameterException e : pcaParameters.getErrors()) {
- LoggingUtil.warning("Error in internal parameterization: " + e.getMessage());
- }
-
- final ArrayList<ParameterConstraint<? super Double>> deltaCons = new ArrayList<>();
- // TODO: this constraint is already set in the parameter itself, since
- // it
- // also applies to the relative case, right? -- erich
- // deltaCons.add(CommonConstraints.NONNEGATIVE_DOUBLE);
- deltaCons.add(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
-
- GlobalParameterConstraint gpc = new ParameterFlagGlobalConstraint<>(deltaP, deltaCons, absoluteF, false);
- config.checkConstraint(gpc);
- }
-
- @Override
- protected Factory<V, D> makeInstance() {
- return new Factory<>(epsilon, rangeQueryDistanceFunction, minpts, pca);
- }
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/PreDeConSubspaceIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/PreDeConSubspaceIndex.java
deleted file mode 100644
index ca322224..00000000
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/PreDeConSubspaceIndex.java
+++ /dev/null
@@ -1,254 +0,0 @@
-package de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj;
-
-/*
- 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.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-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.Distance;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.SubspaceProjectionResult;
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-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.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;
-
-/**
- * Preprocessor for PreDeCon local dimensionality and locally weighted matrix
- * assignment to objects of a certain database.
- *
- * @author Peer Kröger
- *
- * @apiviz.has SubspaceProjectionResult
- *
- * @param <D> Distance type
- * @param <V> Vector type
- */
-@Title("PreDeCon Preprocessor")
-@Description("Computes the projected dimension of objects of a certain database according to the PreDeCon algorithm.\n" + "The variance analysis is based on epsilon range queries.")
-public class PreDeConSubspaceIndex<V extends NumberVector<?>, D extends Distance<D>> extends AbstractSubspaceProjectionIndex<V, D, SubspaceProjectionResult> {
- /**
- * The logger for this class.
- */
- private static final Logging LOG = Logging.getLogger(PreDeConSubspaceIndex.class);
-
- /**
- * The threshold for small eigenvalues.
- */
- protected double delta;
-
- /**
- * The kappa value for generating the variance vector.
- */
- private final int kappa = 50;
-
- /**
- * Constructor.
- *
- * @param relation Relation
- * @param epsilon Epsilon value
- * @param rangeQueryDistanceFunction range query distance
- * @param minpts Minpts parameter
- * @param delta Delta value
- */
- public PreDeConSubspaceIndex(Relation<V> relation, D epsilon, DistanceFunction<V, D> rangeQueryDistanceFunction, int minpts, double delta) {
- super(relation, epsilon, rangeQueryDistanceFunction, minpts);
- this.delta = delta;
- }
-
- @Override
- protected SubspaceProjectionResult computeProjection(DBIDRef id, DistanceDBIDList<D> neighbors, Relation<V> database) {
- StringBuilder msg = null;
-
- int referenceSetSize = neighbors.size();
- V obj = database.get(id);
-
- if(getLogger().isDebugging()) {
- msg = new StringBuilder();
- msg.append("referenceSetSize = ").append(referenceSetSize);
- msg.append("\ndelta = ").append(delta);
- }
-
- if(referenceSetSize == 0) {
- throw new RuntimeException("Reference Set Size = 0. This should never happen!");
- }
-
- // prepare similarity matrix
- int dim = obj.getDimensionality();
- Matrix simMatrix = new Matrix(dim, dim, 0);
- for(int i = 0; i < dim; i++) {
- simMatrix.set(i, i, 1);
- }
-
- // prepare projected dimensionality
- int projDim = 0;
-
- // start variance analysis
- double[] sum = new double[dim];
- for(DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
- V o = database.get(neighbor);
- for(int d = 0; d < dim; d++) {
- final double diff = obj.doubleValue(d) - o.doubleValue(d);
- sum[d] += diff * diff;
- }
- }
-
- for(int d = 0; d < dim; d++) {
- if(Math.sqrt(sum[d]) / referenceSetSize <= delta) {
- if(msg != null) {
- msg.append("\nsum[").append(d).append("]= ").append(sum[d]);
- msg.append("\n Math.sqrt(sum[d]) / referenceSetSize)= ").append(Math.sqrt(sum[d]) / referenceSetSize);
- }
- // projDim++;
- simMatrix.set(d, d, kappa);
- }
- else {
- // bug in paper?
- projDim++;
- }
- }
-
- if(projDim == 0) {
- if(msg != null) {
- // msg.append("\nprojDim == 0!");
- }
- projDim = dim;
- }
-
- if(msg != null) {
- msg.append("\nprojDim ");
- // .append(database.getObjectLabelQuery().get(id));
- msg.append(": ").append(projDim);
- msg.append("\nsimMatrix ");
- // .append(database.getObjectLabelQuery().get(id));
- msg.append(": ").append(FormatUtil.format(simMatrix, FormatUtil.NF4));
- getLogger().debugFine(msg.toString());
- }
-
- return new SubspaceProjectionResult(projDim, simMatrix);
- }
-
- @Override
- public String getLongName() {
- return "PreDeCon Subspaces";
- }
-
- @Override
- public String getShortName() {
- return "PreDeCon-subsp";
- }
-
- @Override
- protected Logging getLogger() {
- return LOG;
- }
-
- @Override
- public void logStatistics() {
- // No statistics to log.
- }
-
- /**
- * Factory.
- *
- * @author Erich Schubert
- *
- * @apiviz.stereotype factory
- * @apiviz.uses PreDeConSubspaceIndex oneway - - «creates»
- *
- * @param <V> Vector type
- * @param <D> Distance type
- */
- public static class Factory<V extends NumberVector<?>, D extends Distance<D>> extends AbstractSubspaceProjectionIndex.Factory<V, D, PreDeConSubspaceIndex<V, D>> {
- /**
- * The default value for delta.
- */
- public static final double DEFAULT_DELTA = 0.01;
-
- /**
- * Parameter for Delta.
- */
- public static final OptionID DELTA_ID = new OptionID("predecon.delta", "a double between 0 and 1 specifying the threshold for small Eigenvalues (default is delta = " + DEFAULT_DELTA + ").");
-
- /**
- * The threshold for small eigenvalues.
- */
- protected double delta;
-
- /**
- * Constructor.
- *
- * @param epsilon
- * @param rangeQueryDistanceFunction
- * @param minpts
- * @param delta
- */
- public Factory(D epsilon, DistanceFunction<V, D> rangeQueryDistanceFunction, int minpts, double delta) {
- super(epsilon, rangeQueryDistanceFunction, minpts);
- this.delta = delta;
- }
-
- @Override
- public PreDeConSubspaceIndex<V, D> instantiate(Relation<V> relation) {
- return new PreDeConSubspaceIndex<>(relation, epsilon, rangeQueryDistanceFunction, minpts, delta);
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer<V extends NumberVector<?>, D extends Distance<D>> extends AbstractSubspaceProjectionIndex.Factory.Parameterizer<V, D, Factory<V, D>> {
- /**
- * The threshold for small eigenvalues.
- */
- protected double delta;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- DoubleParameter deltaP = new DoubleParameter(DELTA_ID, DEFAULT_DELTA);
- deltaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
- deltaP.addConstraint(CommonConstraints.LESS_THAN_ONE_DOUBLE);
- if(config.grab(deltaP)) {
- delta = deltaP.doubleValue();
- }
- }
-
- @Override
- protected Factory<V, D> makeInstance() {
- return new Factory<>(epsilon, rangeQueryDistanceFunction, minpts, delta);
- }
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/SubspaceProjectionIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/SubspaceProjectionIndex.java
deleted file mode 100644
index f0fbbd35..00000000
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/SubspaceProjectionIndex.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj;
-
-/*
- 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.index.preprocessed.LocalProjectionIndex;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.ProjectionResult;
-
-/**
- * Interface for an index providing local subspaces.
- *
- * @author Erich Schubert
- *
- * @apiviz.landmark
- *
- * @param <NV> Vector type
- */
-public interface SubspaceProjectionIndex<NV extends NumberVector<?>, P extends ProjectionResult> extends LocalProjectionIndex<NV, P> {
- /**
- * Get the precomputed local subspace for a particular object ID.
- *
- * @param objid Object ID
- * @return Matrix
- */
- @Override
- public P getLocalProjection(DBIDRef objid);
-
- /**
- * Factory interface
- *
- * @author Erich Schubert
- *
- * @apiviz.landmark
- * @apiviz.stereotype factory
- * @apiviz.uses SubspaceProjectionIndex oneway - - «create»
- *
- * @param <NV> Vector type
- * @param <I> Index type produced
- */
- public static interface Factory<NV extends NumberVector<?>, I extends SubspaceProjectionIndex<NV, ?>> extends LocalProjectionIndex.Factory<NV, I> {
- /**
- * Instantiate the index for a given database.
- *
- * @param relation Relation
- *
- * @return Index
- */
- @Override
- public I instantiate(Relation<NV> relation);
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/projected/LatLngAsECEFIndex.java b/src/de/lmu/ifi/dbs/elki/index/projected/LatLngAsECEFIndex.java
index 8449996b..efa88eb0 100644
--- a/src/de/lmu/ifi/dbs/elki/index/projected/LatLngAsECEFIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/projected/LatLngAsECEFIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.projected;
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
@@ -42,8 +42,6 @@ import de.lmu.ifi.dbs.elki.database.relation.ProjectedView;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LatLngDistanceFunction;
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.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.index.Index;
import de.lmu.ifi.dbs.elki.index.IndexFactory;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
@@ -77,9 +75,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
+ * @apiviz.composedOf LatLngToECEFProjection
+ *
* @param <O> Object type
*/
-public class LatLngAsECEFIndex<O extends NumberVector<?>> extends ProjectedIndex<O, O> {
+public class LatLngAsECEFIndex<O extends NumberVector> extends ProjectedIndex<O, O> {
/**
* Constructor.
*
@@ -105,77 +105,77 @@ public class LatLngAsECEFIndex<O extends NumberVector<?>> extends ProjectedIndex
@SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> KNNQuery<O, D> getKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
- if (!(inner instanceof KNNIndex)) {
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ if(!(inner instanceof KNNIndex)) {
return null;
}
- if (distanceQuery.getRelation() != relation) {
+ if(distanceQuery.getRelation() != relation) {
return null;
}
- if (!LatLngDistanceFunction.class.isInstance(distanceQuery.getDistanceFunction())) {
+ if(!LatLngDistanceFunction.class.isInstance(distanceQuery.getDistanceFunction())) {
return null;
}
- for (Object o : hints) {
- if (o == DatabaseQuery.HINT_EXACT) {
+ for(Object o : hints) {
+ if(o == DatabaseQuery.HINT_EXACT) {
return null;
}
}
- SpatialPrimitiveDistanceQuery<O, DoubleDistance> innerQuery = EuclideanDistanceFunction.STATIC.instantiate(view);
- KNNQuery<O, DoubleDistance> innerq = ((KNNIndex<O>) inner).getKNNQuery(innerQuery, hints);
- if (innerq == null) {
+ SpatialPrimitiveDistanceQuery<O> innerQuery = EuclideanDistanceFunction.STATIC.instantiate(view);
+ KNNQuery<O> innerq = ((KNNIndex<O>) inner).getKNNQuery(innerQuery, hints);
+ if(innerq == null) {
return null;
}
- return (KNNQuery<O, D>) new ProjectedKNNQuery<DoubleDistance>((DistanceQuery<O, DoubleDistance>) distanceQuery, innerq);
+ return new ProjectedKNNQuery(distanceQuery, innerq);
}
@SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> RangeQuery<O, D> getRangeQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
- if (!(inner instanceof RangeIndex)) {
+ public RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ if(!(inner instanceof RangeIndex)) {
return null;
}
- if (distanceQuery.getRelation() != relation) {
+ if(distanceQuery.getRelation() != relation) {
return null;
}
- if (!LatLngDistanceFunction.class.isInstance(distanceQuery.getDistanceFunction())) {
+ if(!LatLngDistanceFunction.class.isInstance(distanceQuery.getDistanceFunction())) {
return null;
}
- for (Object o : hints) {
- if (o == DatabaseQuery.HINT_EXACT) {
+ for(Object o : hints) {
+ if(o == DatabaseQuery.HINT_EXACT) {
return null;
}
}
- SpatialPrimitiveDistanceQuery<O, DoubleDistance> innerQuery = EuclideanDistanceFunction.STATIC.instantiate(view);
- RangeQuery<O, DoubleDistance> innerq = ((RangeIndex<O>) inner).getRangeQuery(innerQuery, hints);
- if (innerq == null) {
+ SpatialPrimitiveDistanceQuery<O> innerQuery = EuclideanDistanceFunction.STATIC.instantiate(view);
+ RangeQuery<O> innerq = ((RangeIndex<O>) inner).getRangeQuery(innerQuery, hints);
+ if(innerq == null) {
return null;
}
- return (RangeQuery<O, D>) new ProjectedRangeQuery<DoubleDistance>((DistanceQuery<O, DoubleDistance>) distanceQuery, innerq);
+ return new ProjectedRangeQuery(distanceQuery, innerq);
}
@SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> RKNNQuery<O, D> getRKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
- if (!(inner instanceof RKNNIndex)) {
+ public RKNNQuery<O> getRKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ if(!(inner instanceof RKNNIndex)) {
return null;
}
- if (distanceQuery.getRelation() != relation) {
+ if(distanceQuery.getRelation() != relation) {
return null;
}
- if (!LatLngDistanceFunction.class.isInstance(distanceQuery.getDistanceFunction())) {
+ if(!LatLngDistanceFunction.class.isInstance(distanceQuery.getDistanceFunction())) {
return null;
}
- for (Object o : hints) {
- if (o == DatabaseQuery.HINT_EXACT) {
+ for(Object o : hints) {
+ if(o == DatabaseQuery.HINT_EXACT) {
return null;
}
}
- SpatialPrimitiveDistanceQuery<O, DoubleDistance> innerQuery = EuclideanDistanceFunction.STATIC.instantiate(view);
- RKNNQuery<O, DoubleDistance> innerq = ((RKNNIndex<O>) inner).getRKNNQuery(innerQuery, hints);
- if (innerq == null) {
+ SpatialPrimitiveDistanceQuery<O> innerQuery = EuclideanDistanceFunction.STATIC.instantiate(view);
+ RKNNQuery<O> innerq = ((RKNNIndex<O>) inner).getRKNNQuery(innerQuery, hints);
+ if(innerq == null) {
return null;
}
- return (RKNNQuery<O, D>) new ProjectedRKNNQuery<DoubleDistance>((DistanceQuery<O, DoubleDistance>) distanceQuery, innerq);
+ return new ProjectedRKNNQuery(distanceQuery, innerq);
}
/**
@@ -187,7 +187,7 @@ public class LatLngAsECEFIndex<O extends NumberVector<?>> extends ProjectedIndex
*
* @param <O> Data type.
*/
- public static class Factory<O extends NumberVector<?>> extends ProjectedIndex.Factory<O, O> {
+ public static class Factory<O extends NumberVector> extends ProjectedIndex.Factory<O, O> {
/**
* Disable refinement of distances.
*/
@@ -207,23 +207,24 @@ public class LatLngAsECEFIndex<O extends NumberVector<?>> extends ProjectedIndex
@Override
public ProjectedIndex<O, O> instantiate(Relation<O> relation) {
- if (!proj.getInputDataTypeInformation().isAssignableFromType(relation.getDataTypeInformation())) {
+ if(!proj.getInputDataTypeInformation().isAssignableFromType(relation.getDataTypeInformation())) {
return null;
}
proj.initialize(relation.getDataTypeInformation());
final Relation<O> view;
- if (materialize) {
+ if(materialize) {
DBIDs ids = relation.getDBIDs();
WritableDataStore<O> content = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_DB, proj.getOutputDataTypeInformation().getRestrictionClass());
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
content.put(iter, proj.project(relation.get(iter)));
}
view = new MaterializedRelation<>("ECEF Projection", "ecef-projection", proj.getOutputDataTypeInformation(), content, ids);
- } else {
+ }
+ else {
view = new ProjectedView<>(relation, proj);
}
Index inneri = inner.instantiate(view);
- if (inneri == null) {
+ if(inneri == null) {
return null;
}
return new LatLngAsECEFIndex<>(relation, proj, view, inneri, norefine);
@@ -238,7 +239,7 @@ public class LatLngAsECEFIndex<O extends NumberVector<?>> extends ProjectedIndex
*
* @param <O> Outer object type.
*/
- public static class Parameterizer<O extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<O extends NumberVector> extends AbstractParameterizer {
/**
* Inner index factory.
*/
@@ -263,22 +264,22 @@ public class LatLngAsECEFIndex<O extends NumberVector<?>> extends ProjectedIndex
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);
}
ObjectParameter<IndexFactory<O, ?>> innerP = new ObjectParameter<>(ProjectedIndex.Factory.Parameterizer.INDEX_ID, IndexFactory.class);
- if (config.grab(innerP)) {
+ if(config.grab(innerP)) {
inner = innerP.instantiateClass(config);
}
Flag materializeF = new Flag(ProjectedIndex.Factory.Parameterizer.MATERIALIZE_FLAG);
- if (config.grab(materializeF)) {
+ if(config.grab(materializeF)) {
materialize = materializeF.isTrue();
}
Flag norefineF = new Flag(ProjectedIndex.Factory.Parameterizer.DISABLE_REFINE_FLAG);
- if (config.grab(norefineF)) {
+ if(config.grab(norefineF)) {
norefine = norefineF.isTrue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/projected/LngLatAsECEFIndex.java b/src/de/lmu/ifi/dbs/elki/index/projected/LngLatAsECEFIndex.java
index 4bf97659..23d6ae96 100644
--- a/src/de/lmu/ifi/dbs/elki/index/projected/LngLatAsECEFIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/projected/LngLatAsECEFIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.projected;
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
@@ -42,8 +42,6 @@ import de.lmu.ifi.dbs.elki.database.relation.ProjectedView;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.geo.LngLatDistanceFunction;
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.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.index.Index;
import de.lmu.ifi.dbs.elki.index.IndexFactory;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
@@ -77,9 +75,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
+ * @apiviz.composedOf LngLatToECEFProjection
+ *
* @param <O> Object type
*/
-public class LngLatAsECEFIndex<O extends NumberVector<?>> extends ProjectedIndex<O, O> {
+public class LngLatAsECEFIndex<O extends NumberVector> extends ProjectedIndex<O, O> {
/**
* Constructor.
*
@@ -105,7 +105,7 @@ public class LngLatAsECEFIndex<O extends NumberVector<?>> extends ProjectedIndex
@SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> KNNQuery<O, D> getKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
if (!(inner instanceof KNNIndex)) {
return null;
}
@@ -120,17 +120,17 @@ public class LngLatAsECEFIndex<O extends NumberVector<?>> extends ProjectedIndex
return null;
}
}
- SpatialPrimitiveDistanceQuery<O, DoubleDistance> innerQuery = EuclideanDistanceFunction.STATIC.instantiate(view);
- KNNQuery<O, DoubleDistance> innerq = ((KNNIndex<O>) inner).getKNNQuery(innerQuery, hints);
+ SpatialPrimitiveDistanceQuery<O> innerQuery = EuclideanDistanceFunction.STATIC.instantiate(view);
+ KNNQuery<O> innerq = ((KNNIndex<O>) inner).getKNNQuery(innerQuery, hints);
if (innerq == null) {
return null;
}
- return (KNNQuery<O, D>) new ProjectedKNNQuery<DoubleDistance>((DistanceQuery<O, DoubleDistance>) distanceQuery, innerq);
+ return new ProjectedKNNQuery(distanceQuery, innerq);
}
@SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> RangeQuery<O, D> getRangeQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
+ public RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
if (!(inner instanceof RangeIndex)) {
return null;
}
@@ -145,17 +145,17 @@ public class LngLatAsECEFIndex<O extends NumberVector<?>> extends ProjectedIndex
return null;
}
}
- SpatialPrimitiveDistanceQuery<O, DoubleDistance> innerQuery = EuclideanDistanceFunction.STATIC.instantiate(view);
- RangeQuery<O, DoubleDistance> innerq = ((RangeIndex<O>) inner).getRangeQuery(innerQuery, hints);
+ SpatialPrimitiveDistanceQuery<O> innerQuery = EuclideanDistanceFunction.STATIC.instantiate(view);
+ RangeQuery<O> innerq = ((RangeIndex<O>) inner).getRangeQuery(innerQuery, hints);
if (innerq == null) {
return null;
}
- return (RangeQuery<O, D>) new ProjectedRangeQuery<DoubleDistance>((DistanceQuery<O, DoubleDistance>) distanceQuery, innerq);
+ return new ProjectedRangeQuery(distanceQuery, innerq);
}
@SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> RKNNQuery<O, D> getRKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
+ public RKNNQuery<O> getRKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
if (!(inner instanceof RKNNIndex)) {
return null;
}
@@ -170,12 +170,12 @@ public class LngLatAsECEFIndex<O extends NumberVector<?>> extends ProjectedIndex
return null;
}
}
- SpatialPrimitiveDistanceQuery<O, DoubleDistance> innerQuery = EuclideanDistanceFunction.STATIC.instantiate(view);
- RKNNQuery<O, DoubleDistance> innerq = ((RKNNIndex<O>) inner).getRKNNQuery(innerQuery, hints);
+ SpatialPrimitiveDistanceQuery<O> innerQuery = EuclideanDistanceFunction.STATIC.instantiate(view);
+ RKNNQuery<O> innerq = ((RKNNIndex<O>) inner).getRKNNQuery(innerQuery, hints);
if (innerq == null) {
return null;
}
- return (RKNNQuery<O, D>) new ProjectedRKNNQuery<DoubleDistance>((DistanceQuery<O, DoubleDistance>) distanceQuery, innerq);
+ return new ProjectedRKNNQuery(distanceQuery, innerq);
}
/**
@@ -187,7 +187,7 @@ public class LngLatAsECEFIndex<O extends NumberVector<?>> extends ProjectedIndex
*
* @param <O> Data type.
*/
- public static class Factory<O extends NumberVector<?>> extends ProjectedIndex.Factory<O, O> {
+ public static class Factory<O extends NumberVector> extends ProjectedIndex.Factory<O, O> {
/**
* Constructor.
*
@@ -233,7 +233,7 @@ public class LngLatAsECEFIndex<O extends NumberVector<?>> extends ProjectedIndex
*
* @param <O> Outer object type.
*/
- public static class Parameterizer<O extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<O extends NumberVector> extends AbstractParameterizer {
/**
* Inner index factory.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/index/projected/PINN.java b/src/de/lmu/ifi/dbs/elki/index/projected/PINN.java
index b3e617b8..2294455a 100644
--- a/src/de/lmu/ifi/dbs/elki/index/projected/PINN.java
+++ b/src/de/lmu/ifi/dbs/elki/index/projected/PINN.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.projected;
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.projection.RandomProjection;
import de.lmu.ifi.dbs.elki.index.IndexFactory;
import de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections.AchlioptasRandomProjectionFamily;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -57,7 +57,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
* @param <O> Object type
*/
@Reference(title = "Finding local anomalies in very high dimensional space", authors = "T. de Vries, S. Chawla, M. E. Houle", booktitle = "Proc. IEEE 10th International Conference on Data Mining (ICDM)", url = "http://dx.doi.org/10.1109/ICDM.2010.151")
-public class PINN<O extends NumberVector<?>> extends ProjectedIndex.Factory<O, O> {
+public class PINN<O extends NumberVector> extends ProjectedIndex.Factory<O, O> {
/**
* Constructor.
*
@@ -80,7 +80,7 @@ public class PINN<O extends NumberVector<?>> extends ProjectedIndex.Factory<O, O
*
* @param <O> Outer object type.
*/
- public static class Parameterizer<O extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<O extends NumberVector> extends AbstractParameterizer {
/**
* Target dimensionality.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/index/projected/ProjectedIndex.java b/src/de/lmu/ifi/dbs/elki/index/projected/ProjectedIndex.java
index f71ced70..0d876dea 100644
--- a/src/de/lmu/ifi/dbs/elki/index/projected/ProjectedIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/projected/ProjectedIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.projected;
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
@@ -35,15 +35,11 @@ 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.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPairList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDoubleDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
@@ -54,9 +50,6 @@ import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
import de.lmu.ifi.dbs.elki.database.relation.ProjectedView;
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.distancefunction.PrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.index.Index;
import de.lmu.ifi.dbs.elki.index.IndexFactory;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
@@ -87,9 +80,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
- * @apiviz.composedOf ProjectedKNNQuery
- * @apiviz.composedOf ProjectedRangeQuery
- * @apiviz.composedOf ProjectedRKNNQuery
+ * @apiviz.composedOf Projection
+ * @apiviz.has ProjectedKNNQuery
+ * @apiviz.has ProjectedRangeQuery
+ * @apiviz.has ProjectedRKNNQuery
*
* @param <O> Outer object type.
* @param <I> Inner object type.
@@ -189,7 +183,7 @@ public class ProjectedIndex<O, I> implements KNNIndex<O>, RKNNIndex<O>, RangeInd
}
@Override
- public <D extends Distance<D>> KNNQuery<O, D> getKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
if(!(inner instanceof KNNIndex)) {
return null;
}
@@ -202,17 +196,17 @@ public class ProjectedIndex<O, I> implements KNNIndex<O>, RKNNIndex<O>, RangeInd
}
}
@SuppressWarnings("unchecked")
- DistanceQuery<I, D> innerQuery = ((DistanceFunction<? super I, D>) distanceQuery.getDistanceFunction()).instantiate(view);
+ DistanceQuery<I> innerQuery = ((DistanceFunction<? super I>) distanceQuery.getDistanceFunction()).instantiate(view);
@SuppressWarnings("unchecked")
- KNNQuery<I, D> innerq = ((KNNIndex<I>) inner).getKNNQuery(innerQuery, hints);
+ KNNQuery<I> innerq = ((KNNIndex<I>) inner).getKNNQuery(innerQuery, hints);
if(innerq == null) {
return null;
}
- return new ProjectedKNNQuery<>(distanceQuery, innerq);
+ return new ProjectedKNNQuery(distanceQuery, innerq);
}
@Override
- public <D extends Distance<D>> RangeQuery<O, D> getRangeQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
+ public RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
if(!(inner instanceof RangeIndex)) {
return null;
}
@@ -225,17 +219,17 @@ public class ProjectedIndex<O, I> implements KNNIndex<O>, RKNNIndex<O>, RangeInd
}
}
@SuppressWarnings("unchecked")
- DistanceQuery<I, D> innerQuery = ((DistanceFunction<? super I, D>) distanceQuery.getDistanceFunction()).instantiate(view);
+ DistanceQuery<I> innerQuery = ((DistanceFunction<? super I>) distanceQuery.getDistanceFunction()).instantiate(view);
@SuppressWarnings("unchecked")
- RangeQuery<I, D> innerq = ((RangeIndex<I>) inner).getRangeQuery(innerQuery, hints);
+ RangeQuery<I> innerq = ((RangeIndex<I>) inner).getRangeQuery(innerQuery, hints);
if(innerq == null) {
return null;
}
- return new ProjectedRangeQuery<>(distanceQuery, innerq);
+ return new ProjectedRangeQuery(distanceQuery, innerq);
}
@Override
- public <D extends Distance<D>> RKNNQuery<O, D> getRKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
+ public RKNNQuery<O> getRKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
if(!(inner instanceof RKNNIndex)) {
return null;
}
@@ -248,13 +242,13 @@ public class ProjectedIndex<O, I> implements KNNIndex<O>, RKNNIndex<O>, RangeInd
}
}
@SuppressWarnings("unchecked")
- DistanceQuery<I, D> innerQuery = ((DistanceFunction<? super I, D>) distanceQuery.getDistanceFunction()).instantiate(view);
+ DistanceQuery<I> innerQuery = ((DistanceFunction<? super I>) distanceQuery.getDistanceFunction()).instantiate(view);
@SuppressWarnings("unchecked")
- RKNNQuery<I, D> innerq = ((RKNNIndex<I>) inner).getRKNNQuery(innerQuery, hints);
+ RKNNQuery<I> innerq = ((RKNNIndex<I>) inner).getRKNNQuery(innerQuery, hints);
if(innerq == null) {
return null;
}
- return new ProjectedRKNNQuery<>(distanceQuery, innerq);
+ return new ProjectedRKNNQuery(distanceQuery, innerq);
}
/**
@@ -262,66 +256,54 @@ public class ProjectedIndex<O, I> implements KNNIndex<O>, RKNNIndex<O>, RangeInd
*
* @author Erich Schubert
*
- * @param <D> Distance type
+ * @param Distance type
*/
- class ProjectedKNNQuery<D extends Distance<D>> implements KNNQuery<O, D> {
+ class ProjectedKNNQuery implements KNNQuery<O> {
/**
* Inner kNN query.
*/
- KNNQuery<I, D> inner;
+ KNNQuery<I> inner;
/**
* Distance query for refinement.
*/
- DistanceQuery<O, D> distq;
+ DistanceQuery<O> distq;
/**
* Constructor.
*
* @param inner Inner kNN query.
*/
- public ProjectedKNNQuery(DistanceQuery<O, D> distanceQuery, KNNQuery<I, D> inner) {
+ public ProjectedKNNQuery(DistanceQuery<O> distanceQuery, KNNQuery<I> inner) {
super();
this.inner = inner;
this.distq = distanceQuery;
}
@Override
- public KNNList<D> getKNNForDBID(DBIDRef id, int k) {
+ public KNNList getKNNForDBID(DBIDRef id, int k) {
// So we have to project the query point only once:
return getKNNForObject(relation.get(id), k);
}
@Override
- public List<? extends KNNList<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ public List<? extends KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
return inner.getKNNForBulkDBIDs(ids, k);
}
- @SuppressWarnings("unchecked")
@Override
- public KNNList<D> getKNNForObject(O obj, int k) {
+ public KNNList getKNNForObject(O obj, int k) {
final I pobj = proj.project(obj);
if(norefine) {
return inner.getKNNForObject(pobj, k);
}
- KNNList<D> ilist = inner.getKNNForObject(pobj, (int) Math.ceil(k * kmulti));
- if(distq.getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction) {
- PrimitiveDoubleDistanceFunction<? super O> df = (PrimitiveDoubleDistanceFunction<? super O>) distq.getDistanceFunction();
- DoubleDistanceKNNHeap heap = DBIDUtil.newDoubleDistanceHeap(k);
- for(DistanceDBIDListIter<D> iter = ilist.iter(); iter.valid(); iter.advance()) {
- heap.insert(df.doubleDistance(obj, distq.getRelation().get(iter)), iter);
- countRefinement();
- }
- return (KNNList<D>) heap.toKNNList();
- }
- else {
- KNNHeap<D> heap = DBIDUtil.newHeap(distq.getDistanceFactory(), k);
- for(DistanceDBIDListIter<D> iter = ilist.iter(); iter.valid(); iter.advance()) {
- heap.insert(distq.distance(obj, iter), iter);
- countRefinement();
- }
- return heap.toKNNList();
+ KNNList ilist = inner.getKNNForObject(pobj, (int) Math.ceil(k * kmulti));
+ KNNHeap heap = DBIDUtil.newHeap(k);
+ for(DoubleDBIDListIter iter = ilist.iter(); iter.valid(); iter.advance()) {
+ heap.insert(distq.distance(obj, iter), iter);
+ countRefinement();
}
+ return heap.toKNNList();
}
}
@@ -330,62 +312,46 @@ public class ProjectedIndex<O, I> implements KNNIndex<O>, RKNNIndex<O>, RangeInd
*
* @author Erich Schubert
*
- * @param <D> Distance type
+ * @param Distance type
*/
- class ProjectedRangeQuery<D extends Distance<D>> extends AbstractDistanceRangeQuery<O, D> {
+ class ProjectedRangeQuery extends AbstractDistanceRangeQuery<O> {
/**
* Inner range query.
*/
- RangeQuery<I, D> inner;
+ RangeQuery<I> inner;
/**
* Constructor.
*
* @param inner Inner range query.
*/
- public ProjectedRangeQuery(DistanceQuery<O, D> distanceQuery, RangeQuery<I, D> inner) {
+ public ProjectedRangeQuery(DistanceQuery<O> distanceQuery, RangeQuery<I> inner) {
super(distanceQuery);
this.inner = inner;
}
@Override
- public DistanceDBIDList<D> getRangeForDBID(DBIDRef id, D range) {
+ public DoubleDBIDList getRangeForDBID(DBIDRef id, double range) {
// So we have to project the query point only once:
return getRangeForObject(relation.get(id), range);
}
- @SuppressWarnings({ "unchecked" })
@Override
- public DistanceDBIDList<D> getRangeForObject(O obj, D range) {
+ public DoubleDBIDList getRangeForObject(O obj, double range) {
final I pobj = proj.project(obj);
- DistanceDBIDList<D> ilist = inner.getRangeForObject(pobj, range);
+ DoubleDBIDList ilist = inner.getRangeForObject(pobj, range);
if(norefine) {
return ilist;
}
- if(distanceQuery.getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction) {
- PrimitiveDoubleDistanceFunction<? super O> df = (PrimitiveDoubleDistanceFunction<? super O>) distanceQuery.getDistanceFunction();
- double drange = ((DoubleDistance) range).doubleValue();
- ModifiableDoubleDistanceDBIDList olist = new DoubleDistanceDBIDPairList(ilist.size());
- for(DistanceDBIDListIter<D> iter = ilist.iter(); iter.valid(); iter.advance()) {
- final double dist = df.doubleDistance(obj, distanceQuery.getRelation().get(iter));
- countRefinement();
- if(dist <= drange) {
- olist.add(dist, iter);
- }
- }
- return (DistanceDBIDList<D>) olist;
- }
- else {
- ModifiableDistanceDBIDList<D> olist = new GenericDistanceDBIDList<>(ilist.size());
- for(DistanceDBIDListIter<D> iter = ilist.iter(); iter.valid(); iter.advance()) {
- D dist = distanceQuery.distance(obj, iter);
- countRefinement();
- if(range.compareTo(dist) <= 0) {
- olist.add(dist, iter);
- }
+ ModifiableDoubleDBIDList olist = DBIDUtil.newDistanceDBIDList(ilist.size());
+ for(DoubleDBIDListIter iter = ilist.iter(); iter.valid(); iter.advance()) {
+ double dist = distanceQuery.distance(obj, iter);
+ countRefinement();
+ if(range <= dist) {
+ olist.add(dist, iter);
}
- return olist;
}
+ return olist;
}
}
@@ -394,67 +360,54 @@ public class ProjectedIndex<O, I> implements KNNIndex<O>, RKNNIndex<O>, RangeInd
*
* @author Erich Schubert
*
- * @param <D> Distance type
+ * @param Distance type
*/
- class ProjectedRKNNQuery<D extends Distance<D>> implements RKNNQuery<O, D> {
+ class ProjectedRKNNQuery implements RKNNQuery<O> {
/**
* Inner RkNN query.
*/
- RKNNQuery<I, D> inner;
+ RKNNQuery<I> inner;
/**
* Distance query for refinement.
*/
- DistanceQuery<O, D> distq;
+ DistanceQuery<O> distq;
/**
* Constructor.
*
* @param inner Inner RkNN query.
*/
- public ProjectedRKNNQuery(DistanceQuery<O, D> distanceQuery, RKNNQuery<I, D> inner) {
+ public ProjectedRKNNQuery(DistanceQuery<O> distanceQuery, RKNNQuery<I> inner) {
super();
this.inner = inner;
this.distq = distanceQuery;
}
@Override
- public DistanceDBIDList<D> getRKNNForDBID(DBIDRef id, int k) {
+ public DoubleDBIDList getRKNNForDBID(DBIDRef id, int k) {
// So we have to project the query point only once:
return getRKNNForObject(relation.get(id), k);
}
- @SuppressWarnings("unchecked")
@Override
- public DistanceDBIDList<D> getRKNNForObject(O obj, int k) {
+ public DoubleDBIDList getRKNNForObject(O obj, int k) {
final I pobj = proj.project(obj);
if(norefine) {
return inner.getRKNNForObject(pobj, k);
}
- DistanceDBIDList<D> ilist = inner.getRKNNForObject(pobj, (int) Math.ceil(k * kmulti));
- if(distq.getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction) {
- PrimitiveDoubleDistanceFunction<? super O> df = (PrimitiveDoubleDistanceFunction<? super O>) distq.getDistanceFunction();
- ModifiableDoubleDistanceDBIDList olist = new DoubleDistanceDBIDPairList(ilist.size());
- for(DistanceDBIDListIter<D> iter = ilist.iter(); iter.valid(); iter.advance()) {
- final double dist = df.doubleDistance(obj, distq.getRelation().get(iter));
- countRefinement();
- olist.add(dist, iter);
- }
- return (DistanceDBIDList<D>) olist;
- }
- else {
- ModifiableDistanceDBIDList<D> olist = new GenericDistanceDBIDList<>(ilist.size());
- for(DistanceDBIDListIter<D> iter = ilist.iter(); iter.valid(); iter.advance()) {
- D dist = distq.distance(obj, iter);
- countRefinement();
- olist.add(dist, iter);
- }
- return olist;
+ DoubleDBIDList ilist = inner.getRKNNForObject(pobj, (int) Math.ceil(k * kmulti));
+ ModifiableDoubleDBIDList olist = DBIDUtil.newDistanceDBIDList(ilist.size());
+ for(DoubleDBIDListIter iter = ilist.iter(); iter.valid(); iter.advance()) {
+ double dist = distq.distance(obj, iter);
+ countRefinement();
+ olist.add(dist, iter);
}
+ return olist;
}
@Override
- public List<? extends DistanceDBIDList<D>> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ public List<? extends DoubleDBIDList> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
return inner.getRKNNForBulkDBIDs(ids, k);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/projected/package-info.java b/src/de/lmu/ifi/dbs/elki/index/projected/package-info.java
index 8a311292..3dc9c2af 100644
--- a/src/de/lmu/ifi/dbs/elki/index/projected/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/projected/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/index/tree/AbstractDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/AbstractDirectoryEntry.java
index a75a49eb..ebd36547 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/AbstractDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/AbstractDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
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
@@ -46,7 +46,7 @@ public abstract class AbstractDirectoryEntry implements DirectoryEntry {
}
/**
- * Provides a new AbstractEntry with the specified id.
+ * Constructor.
*
* @param id the id of the object (node or data object) represented by this
* entry.
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/AbstractLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/AbstractLeafEntry.java
index 15c8c589..b36bf72d 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/AbstractLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/AbstractLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
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
@@ -49,7 +49,7 @@ public abstract class AbstractLeafEntry implements LeafEntry {
}
/**
- * Provides a new AbstractEntry with the specified id.
+ * Constructor.
*
* @param id the id of the object (node or data object) represented by this
* entry.
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/AbstractNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/AbstractNode.java
index 2748b76e..444f62cc 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/AbstractNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/AbstractNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
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/index/tree/BreadthFirstEnumeration.java b/src/de/lmu/ifi/dbs/elki/index/tree/BreadthFirstEnumeration.java
index ec33050b..bbb1e0cc 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/BreadthFirstEnumeration.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/BreadthFirstEnumeration.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
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 java.util.NoSuchElementException;
import java.util.Queue;
/**
- * Provides a breadth first enumeration over the nodes of an index structure.
+ * Breadth first enumeration over the nodes of an index structure.
*
* @author Elke Achtert
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/DirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/DirectoryEntry.java
index c7d74f13..a89157e0 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/DirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/DirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
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/index/tree/Entry.java b/src/de/lmu/ifi/dbs/elki/index/tree/Entry.java
index c9c5e90a..1f2aa21c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/Entry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/Entry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
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/index/tree/IndexTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/IndexTree.java
index ee3bd5d6..92bc4c1b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/IndexTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/IndexTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
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/index/tree/IndexTreePath.java b/src/de/lmu/ifi/dbs/elki/index/tree/IndexTreePath.java
index d9534e91..5b63d39f 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/IndexTreePath.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/IndexTreePath.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
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/index/tree/LeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/LeafEntry.java
index d020c8b1..6ede0ce4 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/LeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/LeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
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/index/tree/Node.java b/src/de/lmu/ifi/dbs/elki/index/tree/Node.java
index 9f393f52..7831bfdd 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/Node.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/Node.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
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/index/tree/TreeIndexHeader.java b/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexHeader.java
index 42688ef0..b1d6e42d 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexHeader.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexHeader.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
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/index/tree/TreeIndexPathComponent.java b/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexPathComponent.java
index 1ef146cf..95276bad 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexPathComponent.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexPathComponent.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
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/index/tree/metrical/MetricalIndexTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/MetricalIndexTree.java
index 2494eb39..b1b323e9 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/MetricalIndexTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/MetricalIndexTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical;
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.index.tree.metrical;
import java.util.List;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.index.tree.Entry;
import de.lmu.ifi.dbs.elki.index.tree.IndexTree;
import de.lmu.ifi.dbs.elki.index.tree.Node;
@@ -38,11 +37,10 @@ import de.lmu.ifi.dbs.elki.persistent.PageFile;
* @author Elke Achtert
*
* @param <O> the type of objects stored in the index
- * @param <D> the type of Distance used in the metrical index
* @param <N> the type of nodes used in the metrical index
* @param <E> the type of entries used in the metrical index
*/
-public abstract class MetricalIndexTree<O, D extends Distance<D>, N extends Node<E>, E extends Entry> extends IndexTree<N, E> {
+public abstract class MetricalIndexTree<O, N extends Node<E>, E extends Entry> extends IndexTree<N, E> {
/**
* Constructor.
*
@@ -57,7 +55,7 @@ public abstract class MetricalIndexTree<O, D extends Distance<D>, N extends Node
*
* @return the distance function of this metrical index
*/
- public abstract DistanceFunction<? super O, D> getDistanceFunction();
+ public abstract DistanceFunction<? super O> getDistanceFunction();
/**
* Returns a list of entries pointing to the leaf nodes of this spatial index.
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTree.java
index 61ca9116..f1ef3b9b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants;
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,7 +30,6 @@ import java.util.List;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.BreadthFirstEnumeration;
import de.lmu.ifi.dbs.elki.index.tree.IndexTreePath;
import de.lmu.ifi.dbs.elki.index.tree.TreeIndexPathComponent;
@@ -54,12 +53,11 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
* @apiviz.excludeSubtypes
*
* @param <O> the type of DatabaseObject to be stored in the metrical index
- * @param <D> the type of Distance used in the metrical index
* @param <N> the type of MetricalNode used in the metrical index
* @param <E> the type of MetricalEntry used in the metrical index
* @param <S> the type to store settings in.
*/
-public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry, S extends MTreeSettings<O, D, N, E>> extends MetricalIndexTree<O, D, N, E> {
+public abstract class AbstractMTree<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry, S extends MTreeSettings<O, N, E>> extends MetricalIndexTree<O, N, E> {
/**
* Debugging flag: do extra integrity checks.
*/
@@ -87,20 +85,11 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
}
@Override
- public final DistanceFunction<? super O, D> getDistanceFunction() {
+ public final DistanceFunction<? super O> getDistanceFunction() {
return settings.distanceFunction;
}
/**
- * Get the distance factory.
- *
- * @return the distance factory used
- */
- public final D getDistanceFactory() {
- return settings.distanceFunction.getDistanceFactory();
- }
-
- /**
* Returns a string representation of this M-Tree by performing a breadth
* first enumeration on the tree and adding the string representation of the
* visited nodes and their entries to the result.
@@ -117,8 +106,8 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
N node = getRoot();
- while (!node.isLeaf()) {
- if (node.getNumEntries() > 0) {
+ while(!node.isLeaf()) {
+ if(node.getNumEntries() > 0) {
E entry = node.getEntry(0);
node = getNode(entry);
levels++;
@@ -126,20 +115,22 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
}
BreadthFirstEnumeration<N, E> enumeration = new BreadthFirstEnumeration<>(this, getRootPath());
- while (enumeration.hasMoreElements()) {
+ while(enumeration.hasMoreElements()) {
IndexTreePath<E> path = enumeration.nextElement();
E entry = path.getLastPathComponent().getEntry();
- if (entry.isLeafEntry()) {
+ if(entry.isLeafEntry()) {
objects++;
result.append("\n ").append(entry.toString());
- } else {
+ }
+ else {
node = getNode(entry);
result.append("\n\n").append(node).append(", numEntries = ").append(node.getNumEntries());
result.append("\n").append(entry.toString());
- if (node.isLeaf()) {
+ if(node.isLeaf()) {
leafNodes++;
- } else {
+ }
+ else {
dirNodes++;
}
}
@@ -165,27 +156,27 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
*/
// todo: implement a bulk load for M-Tree and remove this method
public void insert(E entry, boolean withPreInsert) {
- if (getLogger().isDebugging()) {
+ if(getLogger().isDebugging()) {
getLogger().debugFine("insert " + entry.getRoutingObjectID() + "\n");
}
- if (!initialized) {
+ if(!initialized) {
initialize(entry);
}
// choose subtree for insertion
IndexTreePath<E> subtree = settings.insertStrategy.choosePath(this, entry);
- if (getLogger().isDebugging()) {
+ if(getLogger().isDebugging()) {
getLogger().debugFine("insertion-subtree " + subtree + "\n");
}
// determine parent distance
E parentEntry = subtree.getLastPathComponent().getEntry();
- double parentDistance = distance(parentEntry.getRoutingObjectID(), entry.getRoutingObjectID()).doubleValue();
+ double parentDistance = distance(parentEntry.getRoutingObjectID(), entry.getRoutingObjectID());
entry.setParentDistance(parentDistance);
// create leaf entry and do pre insert
- if (withPreInsert) {
+ if(withPreInsert) {
preInsert(entry);
}
@@ -198,8 +189,8 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
adjustTree(subtree);
// test
- if (EXTRA_INTEGRITY_CHECKS) {
- if (withPreInsert) {
+ if(EXTRA_INTEGRITY_CHECKS) {
+ if(withPreInsert) {
getRoot().integrityCheck(this, getRootEntry());
}
}
@@ -211,10 +202,10 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
* @param entries Entries to insert
*/
public void insertAll(List<E> entries) {
- if (!initialized && entries.size() > 0) {
+ if(!initialized && entries.size() > 0) {
initialize(entries.get(0));
}
- for (E entry : entries) {
+ for(E entry : entries) {
insert(entry, false);
}
}
@@ -236,9 +227,9 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
protected final List<DoubleIntPair> getSortedEntries(N node, DBID q) {
List<DoubleIntPair> result = new ArrayList<>();
- for (int i = 0; i < node.getNumEntries(); i++) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
E entry = node.getEntry(i);
- double distance = distance(entry.getRoutingObjectID(), q).doubleValue();
+ double distance = distance(entry.getRoutingObjectID(), q);
double radius = entry.getCoveringRadius();
double minDist = (radius > distance) ? 0.0 : distance - radius;
@@ -256,7 +247,7 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
* @param id2 the second id
* @return the distance between the two specified ids
*/
- public abstract D distance(DBIDRef id1, DBIDRef id2);
+ public abstract double distance(DBIDRef id1, DBIDRef id2);
/**
* Returns the distance between the routing object of two entries.
@@ -265,7 +256,7 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
* @param e2 Second entry
* @return the distance between the two routing objects
*/
- public final D distance(E e1, E e2) {
+ public final double distance(E e1, E e2) {
return distance(e1.getRoutingObjectID(), e2.getRoutingObjectID());
}
@@ -286,7 +277,7 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
* @param subtree the subtree to be adjusted
*/
private void adjustTree(IndexTreePath<E> subtree) {
- if (getLogger().isDebugging()) {
+ if(getLogger().isDebugging()) {
getLogger().debugFine("Adjust tree " + subtree + "\n");
}
@@ -295,7 +286,7 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
N node = getNode(subtree.getLastPathComponent().getEntry());
// overflow in node; split the node
- if (hasOverflow(node)) {
+ if(hasOverflow(node)) {
// do the split
Assignments<E> assignments = settings.splitStrategy.split(this, node);
final N newNode = node.isLeaf() ? createNewLeafNode() : createNewDirectoryNode();
@@ -303,12 +294,12 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
List<E> entries1 = new ArrayList<>(assignments.getFirstAssignments().size());
List<E> entries2 = new ArrayList<>(assignments.getSecondAssignments().size());
// Store final parent distances:
- for (DistanceEntry<E> ent : assignments.getFirstAssignments()) {
+ for(DistanceEntry<E> ent : assignments.getFirstAssignments()) {
final E e = ent.getEntry();
e.setParentDistance(ent.getDistance());
entries1.add(e);
}
- for (DistanceEntry<E> ent : assignments.getSecondAssignments()) {
+ for(DistanceEntry<E> ent : assignments.getSecondAssignments()) {
final E e = ent.getEntry();
e.setParentDistance(ent.getDistance());
entries2.add(e);
@@ -319,14 +310,14 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
writeNode(node);
writeNode(newNode);
- if (getLogger().isDebugging()) {
+ if(getLogger().isDebugging()) {
String msg = "Split Node " + node.getPageID() + " (" + this.getClass() + ")\n" + " newNode " + newNode.getPageID() + "\n" + " firstPromoted " + assignments.getFirstRoutingObject() + "\n" + " firstAssignments(" + node.getPageID() + ") " + assignments.getFirstAssignments() + "\n" + " firstCR " + assignments.getFirstCoveringRadius() + "\n" + " secondPromoted " + assignments.getSecondRoutingObject() + "\n" + " secondAssignments(" + newNode.getPageID() + ") " + assignments.getSecondAssignments() + "\n" + " secondCR " + assignments.getSecondCoveringRadius() + "\n";
getLogger().debugFine(msg);
}
// if root was split: create a new root that points the two split
// nodes
- if (isRoot(node)) {
+ if(isRoot(node)) {
// FIXME: stimmen die parentDistance der Kinder in node & splitNode?
IndexTreePath<E> newRootPath = createNewRoot(node, newNode, assignments.getFirstRoutingObject(), assignments.getSecondRoutingObject());
adjustTree(newRootPath);
@@ -336,16 +327,16 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
// get the parent and add the new split node
E parentEntry = subtree.getParentPath().getLastPathComponent().getEntry();
N parent = getNode(parentEntry);
- if (getLogger().isDebugging()) {
+ if(getLogger().isDebugging()) {
getLogger().debugFine("parent " + parent);
}
- double parentDistance2 = distance(parentEntry.getRoutingObjectID(), assignments.getSecondRoutingObject()).doubleValue();
+ double parentDistance2 = distance(parentEntry.getRoutingObjectID(), assignments.getSecondRoutingObject());
// logger.warning("parent: "+parent.toString()+" split: " +
// splitNode.toString()+ " dist:"+parentDistance2);
parent.addDirectoryEntry(createNewDirectoryEntry(newNode, assignments.getSecondRoutingObject(), parentDistance2));
// adjust the entry representing the (old) node, that has been split
- double parentDistance1 = distance(parentEntry.getRoutingObjectID(), assignments.getFirstRoutingObject()).doubleValue();
+ double parentDistance1 = distance(parentEntry.getRoutingObjectID(), assignments.getFirstRoutingObject());
// logger.warning("parent: "+parent.toString()+" node: " +
// node.toString()+ " dist:"+parentDistance1);
node.adjustEntry(parent.getEntry(nodeIndex), assignments.getFirstRoutingObject(), parentDistance1, this);
@@ -358,7 +349,7 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
// no overflow, only adjust parameters of the entry representing the
// node
else {
- if (!isRoot(node)) {
+ if(!isRoot(node)) {
E parentEntry = subtree.getParentPath().getLastPathComponent().getEntry();
N parent = getNode(parentEntry);
int index = subtree.getLastPathComponent().getIndex();
@@ -385,7 +376,7 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
* otherwise
*/
private boolean hasOverflow(N node) {
- if (node.isLeaf()) {
+ if(node.isLeaf()) {
return node.getNumEntries() == leafCapacity;
}
@@ -411,9 +402,9 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
// switch the ids
oldRoot.setPageID(root.getPageID());
- if (!oldRoot.isLeaf()) {
+ if(!oldRoot.isLeaf()) {
// FIXME: what is happening here?
- for (int i = 0; i < oldRoot.getNumEntries(); i++) {
+ for(int i = 0; i < oldRoot.getNumEntries(); i++) {
N node = getNode(oldRoot.getEntry(i));
writeNode(node);
}
@@ -437,7 +428,7 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
writeNode(root);
writeNode(oldRoot);
writeNode(newNode);
- if (getLogger().isDebugging()) {
+ if(getLogger().isDebugging()) {
String msg = "Create new Root: ID=" + root.getPageID();
msg += "\nchild1 " + oldRoot;
msg += "\nchild2 " + newNode;
@@ -451,13 +442,13 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
public List<E> getLeaves() {
List<E> result = new ArrayList<>();
BreadthFirstEnumeration<N, E> enumeration = new BreadthFirstEnumeration<>(this, getRootPath());
- while (enumeration.hasMoreElements()) {
+ while(enumeration.hasMoreElements()) {
IndexTreePath<E> path = enumeration.nextElement();
E entry = path.getLastPathComponent().getEntry();
- if (!entry.isLeafEntry()) {
+ if(!entry.isLeafEntry()) {
// TODO: any way to skip unnecessary reads?
N node = getNode(entry);
- if (node.isLeaf()) {
+ if(node.isLeaf()) {
result.add(entry);
}
}
@@ -474,8 +465,8 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
int levels = 0;
N node = getRoot();
- while (!node.isLeaf()) {
- if (node.getNumEntries() > 0) {
+ while(!node.isLeaf()) {
+ if(node.getNumEntries() > 0) {
E entry = node.getEntry(0);
node = getNode(entry);
levels++;
@@ -488,7 +479,7 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
public void logStatistics() {
super.logStatistics();
Logging log = getLogger();
- if (log.isStatistics()) {
+ if(log.isStatistics()) {
log.statistics(new LongStatistic(this.getClass().getName() + ".height", getHeight()));
statistics.logStatistics();
}
@@ -532,7 +523,7 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
* Count a distance computation.
*/
public void countDistanceCalculation() {
- if (distanceCalcs != null) {
+ if(distanceCalcs != null) {
distanceCalcs.increment();
}
}
@@ -541,7 +532,7 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
* Count a knn query invocation.
*/
public void countKNNQuery() {
- if (knnQueries != null) {
+ if(knnQueries != null) {
knnQueries.increment();
}
}
@@ -550,7 +541,7 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
* Count a range query invocation.
*/
public void countRangeQuery() {
- if (rangeQueries != null) {
+ if(rangeQueries != null) {
rangeQueries.increment();
}
}
@@ -560,13 +551,13 @@ public abstract class AbstractMTree<O, D extends NumberDistance<D, ?>, N extends
*/
public void logStatistics() {
Logging log = getLogger();
- if (statistics.distanceCalcs != null) {
+ if(statistics.distanceCalcs != null) {
log.statistics(statistics.distanceCalcs);
}
- if (statistics.knnQueries != null) {
+ if(statistics.knnQueries != null) {
log.statistics(statistics.knnQueries);
}
- if (statistics.rangeQueries != null) {
+ if(statistics.rangeQueries != null) {
log.statistics(statistics.rangeQueries);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeFactory.java
index 7a0baa8a..458bf96b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants;
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.index.tree.metrical.mtreevariants;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.Index;
import de.lmu.ifi.dbs.elki.index.PagedIndexFactory;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.insert.MTreeInsert;
@@ -48,12 +47,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.excludeSubtypes
*
* @param <O> Object type
- * @param <D> Distance type
* @param <N> Node type
* @param <E> Entry type
* @param <I> Index type
*/
-public abstract class AbstractMTreeFactory<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry, I extends AbstractMTree<O, D, N, E, S> & Index, S extends MTreeSettings<O, D, N, E>> extends PagedIndexFactory<O, I> {
+public abstract class AbstractMTreeFactory<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry, I extends AbstractMTree<O, N, E, S> & Index, S extends MTreeSettings<O, N, E>> extends PagedIndexFactory<O, I> {
/**
* Tree settings.
*/
@@ -82,7 +80,7 @@ public abstract class AbstractMTreeFactory<O, D extends NumberDistance<D, ?>, N
*
* @apiviz.exclude
*/
- public abstract static class Parameterizer<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry, S extends MTreeSettings<O, D, N, E>> extends PagedIndexFactory.Parameterizer<O> {
+ public abstract static class Parameterizer<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry, S extends MTreeSettings<O, N, E>> extends PagedIndexFactory.Parameterizer<O> {
/**
* Parameter to specify the distance function to determine the distance
* between database objects, must extend
@@ -122,15 +120,15 @@ public abstract class AbstractMTreeFactory<O, D extends NumberDistance<D, ?>, N
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
settings = makeSettings();
- ObjectParameter<DistanceFunction<O, D>> distanceFunctionP = new ObjectParameter<>(DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
+ ObjectParameter<DistanceFunction<O>> distanceFunctionP = new ObjectParameter<>(DISTANCE_FUNCTION_ID, DistanceFunction.class, EuclideanDistanceFunction.class);
if (config.grab(distanceFunctionP)) {
settings.distanceFunction = distanceFunctionP.instantiateClass(config);
}
- ObjectParameter<MTreeSplit<O, D, N, E>> splitStrategyP = new ObjectParameter<>(SPLIT_STRATEGY_ID, MTreeSplit.class, MMRadSplit.class);
+ ObjectParameter<MTreeSplit<O, N, E>> splitStrategyP = new ObjectParameter<>(SPLIT_STRATEGY_ID, MTreeSplit.class, MMRadSplit.class);
if (config.grab(splitStrategyP)) {
settings.splitStrategy = splitStrategyP.instantiateClass(config);
}
- ObjectParameter<MTreeInsert<O, D, N, E>> insertStrategyP = new ObjectParameter<>(INSERT_STRATEGY_ID, MTreeInsert.class, MinimumEnlargementInsert.class);
+ ObjectParameter<MTreeInsert<O, N, E>> insertStrategyP = new ObjectParameter<>(INSERT_STRATEGY_ID, MTreeInsert.class, MinimumEnlargementInsert.class);
if (config.grab(insertStrategyP)) {
settings.insertStrategy = insertStrategyP.instantiateClass(config);
}
@@ -139,6 +137,6 @@ public abstract class AbstractMTreeFactory<O, D extends NumberDistance<D, ?>, N
abstract protected S makeSettings();
@Override
- protected abstract AbstractMTreeFactory<O, D, N, E, ?, ?> makeInstance();
+ protected abstract AbstractMTreeFactory<O, N, E, ?, ?> makeInstance();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeNode.java
index 1c1f486c..98b51b44 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants;
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.index.tree.metrical.mtreevariants;
import java.util.logging.Logger;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.AbstractNode;
import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration;
@@ -39,11 +38,10 @@ import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration;
* @apiviz.excludeSubtypes
*
* @param <O> the type of DatabaseObject to be stored in the M-Tree
- * @param <D> the type of Distance used in the M-Tree
* @param <N> the type of AbstractMTreeNode used in the M-Tree
* @param <E> the type of MetricalEntry used in the M-Tree
*/
-public abstract class AbstractMTreeNode<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry> extends AbstractNode<E> {
+public abstract class AbstractMTreeNode<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry> extends AbstractNode<E> {
/**
* Empty constructor for Externalizable interface.
*/
@@ -73,14 +71,14 @@ public abstract class AbstractMTreeNode<O, D extends NumberDistance<D, ?>, N ext
* the routing object of the parent node
* @param mTree the M-Tree object holding this node
*/
- public void adjustEntry(E entry, DBID routingObjectID, double parentDistance, AbstractMTree<O, D, N, E, ?> mTree) {
+ public void adjustEntry(E entry, DBID routingObjectID, double parentDistance, AbstractMTree<O, N, E, ?> mTree) {
entry.setRoutingObjectID(routingObjectID);
entry.setParentDistance(parentDistance);
entry.setCoveringRadius(coveringRadius(entry.getRoutingObjectID(), mTree));
for (int i = 0; i < getNumEntries(); i++) {
E childEntry = getEntry(i);
- double dist = mTree.distance(routingObjectID, childEntry.getRoutingObjectID()).doubleValue();
+ double dist = mTree.distance(routingObjectID, childEntry.getRoutingObjectID());
childEntry.setParentDistance(dist);
}
}
@@ -92,11 +90,11 @@ public abstract class AbstractMTreeNode<O, D extends NumberDistance<D, ?>, N ext
* @param mTree the M-Tree
* @return the covering radius of this node
*/
- public double coveringRadius(DBID routingObjectID, AbstractMTree<O, D, N, E, ?> mTree) {
+ public double coveringRadius(DBID routingObjectID, AbstractMTree<O, N, E, ?> mTree) {
double coveringRadius = 0.;
for (int i = 0; i < getNumEntries(); i++) {
E entry = getEntry(i);
- double distance = mTree.distance(entry.getRoutingObjectID(), routingObjectID).doubleValue() + entry.getCoveringRadius();
+ double distance = mTree.distance(entry.getRoutingObjectID(), routingObjectID) + entry.getCoveringRadius();
coveringRadius = Math.max(coveringRadius, distance);
}
return coveringRadius;
@@ -109,7 +107,7 @@ public abstract class AbstractMTreeNode<O, D extends NumberDistance<D, ?>, N ext
* @param entry the entry representing this node
*/
@SuppressWarnings("unchecked")
- public final void integrityCheck(AbstractMTree<O, D, N, E, ?> mTree, E entry) {
+ public final void integrityCheck(AbstractMTree<O, N, E, ?> mTree, E entry) {
// leaf node
if (isLeaf()) {
for (int i = 0; i < getCapacity(); i++) {
@@ -174,10 +172,10 @@ public abstract class AbstractMTreeNode<O, D extends NumberDistance<D, ?>, N ext
* @param index the index of the entry in the parents child arry
* @param mTree the M-Tree holding this node
*/
- protected void integrityCheckParameters(E parentEntry, N parent, int index, AbstractMTree<O, D, N, E, ?> mTree) {
+ protected void integrityCheckParameters(E parentEntry, N parent, int index, AbstractMTree<O, N, E, ?> mTree) {
// test if parent distance is correctly set
E entry = parent.getEntry(index);
- double parentDistance = mTree.distance(entry.getRoutingObjectID(), parentEntry.getRoutingObjectID()).doubleValue();
+ double parentDistance = mTree.distance(entry.getRoutingObjectID(), parentEntry.getRoutingObjectID());
if (Math.abs(entry.getParentDistance() - parentDistance) > 1E-10) {
throw new RuntimeException("Wrong parent distance in node " + parent.getPageID() + " at index " + index + " (child " + entry + ")" + "\nsoll: " + parentDistance + ",\n ist: " + entry.getParentDistance());
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeDirectoryEntry.java
index 92d0a7ea..ea2cd416 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants;
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
@@ -66,7 +66,7 @@ public class MTreeDirectoryEntry extends AbstractDirectoryEntry implements MTree
}
/**
- * Provides a new MTreeDirectoryEntry with the given parameters.
+ * Constructor.
*
* @param objectID the id of the routing object
* @param parentDistance the distance from the routing object of this entry to
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeEntry.java
index 66628087..ebae6a4f 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants;
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/index/tree/metrical/mtreevariants/MTreeLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeLeafEntry.java
index cfb22bac..c53cc4d6 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants;
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
@@ -58,7 +58,7 @@ public class MTreeLeafEntry extends AbstractLeafEntry implements MTreeEntry {
}
/**
- * Provides a new MTreeLeafEntry object with the given parameters.
+ * Constructor.
*
* @param objectID the id of the underlying data object
* @param parentDistance the distance from the underlying data object to its
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeSettings.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeSettings.java
index 59f6e598..46a0851a 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeSettings.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeSettings.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants;
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.index.tree.metrical.mtreevariants;
*/
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.insert.MTreeInsert;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.split.MTreeSplit;
@@ -34,23 +33,22 @@ import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.split.MT
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
* @param <N> Node type
* @param <E> Entry type
*/
-public class MTreeSettings<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry> {
+public class MTreeSettings<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry> {
/**
* Holds the instance of the trees distance function.
*/
- protected DistanceFunction<? super O, D> distanceFunction;
+ protected DistanceFunction<? super O> distanceFunction;
/**
* Splitting strategy.
*/
- protected MTreeSplit<O, D, N, E> splitStrategy;
+ protected MTreeSplit<O, N, E> splitStrategy;
/**
* Insertion strategy.
*/
- protected MTreeInsert<O, D, N, E> insertStrategy;
+ protected MTreeInsert<O, N, E> insertStrategy;
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTree.java
index aec4410e..2f71f540 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees;
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,12 +31,11 @@ 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.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
@@ -51,21 +50,20 @@ import de.lmu.ifi.dbs.elki.persistent.PageFile;
*
* @author Elke Achtert
* @param <O> the type of DatabaseObject to be stored in the metrical index
- * @param <D> the type of Distance used in the metrical index
* @param <N> the type of MetricalNode used in the metrical index
* @param <E> the type of MetricalEntry used in the metrical index
* @param <S> the type of Settings kept.
*/
-public abstract class AbstractMkTree<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry, S extends MTreeSettings<O, D, N, E>> extends AbstractMTree<O, D, N, E, S> {
+public abstract class AbstractMkTree<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry, S extends MTreeSettings<O, N, E>> extends AbstractMTree<O, N, E, S> {
/**
* Internal class for performing knn queries
*/
- protected KNNQuery<O, D> knnq;
+ protected KNNQuery<O> knnq;
/**
* Distance query to use.
*/
- private DistanceQuery<O, D> distanceQuery;
+ private DistanceQuery<O> distanceQuery;
/**
* Constructor.
@@ -82,9 +80,9 @@ public abstract class AbstractMkTree<O, D extends NumberDistance<D, ?>, N extend
}
@Override
- public D distance(DBIDRef id1, DBIDRef id2) {
- if (id1 == null || id2 == null) {
- return getDistanceFactory().undefinedDistance();
+ public double distance(DBIDRef id1, DBIDRef id2) {
+ if(id1 == null || id2 == null) {
+ return Double.NaN;
}
statistics.countDistanceCalculation();
return distanceQuery.distance(id1, id2);
@@ -98,7 +96,7 @@ public abstract class AbstractMkTree<O, D extends NumberDistance<D, ?>, N extend
* @param k the number of nearest neighbors to be returned
* @return a List of the query results
*/
- public abstract DistanceDBIDList<D> reverseKNNQuery(final DBIDRef id, int k);
+ public abstract DoubleDBIDList reverseKNNQuery(final DBIDRef id, int k);
/**
* Performs a batch k-nearest neighbor query for a list of query objects.
@@ -111,9 +109,9 @@ public abstract class AbstractMkTree<O, D extends NumberDistance<D, ?>, N extend
* @deprecated Change to use by-object NN lookups instead.
*/
@Deprecated
- protected final Map<DBID, KNNList<D>> batchNN(N node, DBIDs ids, int kmax) {
- Map<DBID, KNNList<D>> res = new HashMap<>(ids.size());
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ protected final Map<DBID, KNNList> batchNN(N node, DBIDs ids, int kmax) {
+ Map<DBID, KNNList> res = new HashMap<>(ids.size());
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
DBID id = DBIDUtil.deref(iter);
res.put(id, knnq.getKNNForDBID(id, kmax));
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnified.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnified.java
index 455d372a..4c43e667 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnified.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnified.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees;
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,10 +28,9 @@ import java.util.Map;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.TreeIndexHeader;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
@@ -48,12 +47,11 @@ import de.lmu.ifi.dbs.elki.persistent.PageFile;
* @apiviz.composedOf MkTreeSettings
*
* @param <O> the type of DatabaseObject to be stored in the metrical index
- * @param <D> the type of Distance used in the metrical index
* @param <N> the type of MetricalNode used in the metrical index
* @param <E> the type of MetricalEntry used in the metrical index
* @param <S> the type of Settings used.
*/
-public abstract class AbstractMkTreeUnified<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry, S extends MkTreeSettings<O, D, N, E>> extends AbstractMkTree<O, D, N, E, S> {
+public abstract class AbstractMkTreeUnified<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry, S extends MkTreeSettings<O, N, E>> extends AbstractMkTree<O, N, E, S> {
/**
* Constructor.
*
@@ -92,7 +90,7 @@ public abstract class AbstractMkTreeUnified<O, D extends NumberDistance<D, ?>, N
}
// do batch nn
- Map<DBID, KNNList<D>> knnLists = batchNN(getRoot(), ids, settings.k_max);
+ Map<DBID, KNNList> knnLists = batchNN(getRoot(), ids, settings.k_max);
// adjust the knn distances
kNNdistanceAdjustment(getRootEntry(), knnLists);
@@ -108,7 +106,7 @@ public abstract class AbstractMkTreeUnified<O, D extends NumberDistance<D, ?>, N
* @param entry the root entry of the current subtree
* @param knnLists a map of knn lists for each leaf entry
*/
- protected abstract void kNNdistanceAdjustment(E entry, Map<DBID, KNNList<D>> knnLists);
+ protected abstract void kNNdistanceAdjustment(E entry, Map<DBID, KNNList> knnLists);
/**
* Get the value of k_max.
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnifiedFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnifiedFactory.java
index 996b2438..9997713d 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnifiedFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnifiedFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees;
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.index.tree.metrical.mtreevariants.mktrees;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.Index;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeFactory;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
@@ -43,12 +42,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* @apiviz.uses AbstractMkTreeUnified oneway - - «create»
*
* @param <O> Object type
- * @param <D> Distance type
* @param <N> Node type
* @param <E> Entry type
* @param <I> Index type
*/
-public abstract class AbstractMkTreeUnifiedFactory<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry, I extends AbstractMkTree<O, D, N, E, S> & Index, S extends MkTreeSettings<O, D, N, E>> extends AbstractMTreeFactory<O, D, N, E, I, S> {
+public abstract class AbstractMkTreeUnifiedFactory<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry, I extends AbstractMkTree<O, N, E, S> & Index, S extends MkTreeSettings<O, N, E>> extends AbstractMTreeFactory<O, N, E, I, S> {
/**
* Constructor.
*
@@ -66,7 +64,7 @@ public abstract class AbstractMkTreeUnifiedFactory<O, D extends NumberDistance<D
*
* @apiviz.exclude
*/
- public abstract static class Parameterizer<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry, S extends MkTreeSettings<O, D, N, E>> extends AbstractMTreeFactory.Parameterizer<O, D, N, E, S> {
+ public abstract static class Parameterizer<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry, S extends MkTreeSettings<O, N, E>> extends AbstractMTreeFactory.Parameterizer<O, N, E, S> {
/**
* Parameter specifying the maximal number k of reverse k nearest neighbors
* to be supported, must be an integer greater than 0.
@@ -88,6 +86,6 @@ public abstract class AbstractMkTreeUnifiedFactory<O, D extends NumberDistance<D
}
@Override
- protected abstract AbstractMkTreeUnifiedFactory<O, D, N, E, ?, S> makeInstance();
+ protected abstract AbstractMkTreeUnifiedFactory<O, N, E, ?, S> makeInstance();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/MkTreeHeader.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/MkTreeHeader.java
index ff49d789..47f0eda0 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/MkTreeHeader.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/MkTreeHeader.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees;
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/index/tree/metrical/mtreevariants/mktrees/MkTreeSettings.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/MkTreeSettings.java
index 6a957bd7..8d5fa450 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/MkTreeSettings.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/MkTreeSettings.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees;
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.index.tree.metrical.mtreevariants.mktrees;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeSettings;
@@ -34,11 +33,10 @@ import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeSettings;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
* @param <N> Node type
* @param <E> Entry type
*/
-public class MkTreeSettings<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry> extends MTreeSettings<O, D, N, E> {
+public class MkTreeSettings<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry> extends MTreeSettings<O, N, E> {
/**
* Holds the maximum value of k to support.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppDirectoryEntry.java
index fd6f6bab..89d0cba1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
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
@@ -56,7 +56,7 @@ class MkAppDirectoryEntry extends MTreeDirectoryEntry implements MkAppEntry {
}
/**
- * Provides a new MkCoPDirectoryEntry with the given parameters.
+ * Constructor.
*
* @param objectID the id of the routing object
* @param parentDistance the distance from the object to its parent
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java
index 5424f6f1..54cfcc29 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
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/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppLeafEntry.java
index e1f2305a..c2f81af2 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
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
@@ -56,7 +56,7 @@ class MkAppLeafEntry extends MTreeLeafEntry implements MkAppEntry {
}
/**
- * Provides a new MkAppLeafEntry with the given parameters.
+ * Constructor.
*
* @param objectID the id of the underlying data object
* @param parentDistance the distance from the underlying data object to its
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTree.java
index 1ff0a030..41a83fcf 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
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.index.tree.metrical.mtreevariants.mktrees.mkapp;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -33,22 +32,21 @@ 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.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.LeafEntry;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.AbstractMkTree;
import de.lmu.ifi.dbs.elki.index.tree.query.GenericMTreeDistanceSearchCandidate;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.statistics.PolynomialRegression;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.UpdatableHeap;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
/**
* MkAppTree is a metrical index structure based on the concepts of the M-Tree
@@ -61,9 +59,8 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.UpdatableHeap;
* @apiviz.has MkAppTreeNode oneway - - contains
*
* @param <O> the type of DatabaseObject to be stored in the metrical index
- * @param <D> the type of NumberDistance used in the metrical index
*/
-public class MkAppTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree<O, D, MkAppTreeNode<O, D>, MkAppEntry, MkAppTreeSettings<O, D>> {
+public class MkAppTree<O> extends AbstractMkTree<O, MkAppTreeNode<O>, MkAppEntry, MkAppTreeSettings<O>> {
/**
* The logger for this class.
*/
@@ -76,7 +73,7 @@ public class MkAppTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @param pageFile Page file
* @param settings Tree settings
*/
- public MkAppTree(Relation<O> relation, PageFile<MkAppTreeNode<O, D>> pageFile, MkAppTreeSettings<O, D> settings) {
+ public MkAppTree(Relation<O> relation, PageFile<MkAppTreeNode<O>> pageFile, MkAppTreeSettings<O> settings) {
super(relation, pageFile, settings);
}
@@ -103,34 +100,34 @@ public class MkAppTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
*/
@Override
public void insertAll(List<MkAppEntry> entries) {
- if (entries.isEmpty()) {
+ if(entries.isEmpty()) {
return;
}
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
LOG.debugFine("insert " + entries + "\n");
}
- if (!initialized) {
+ if(!initialized) {
initialize(entries.get(0));
}
ModifiableDBIDs ids = DBIDUtil.newArray(entries.size());
// insert
- for (MkAppEntry entry : entries) {
+ for(MkAppEntry entry : entries) {
ids.add(entry.getRoutingObjectID());
// insert the object
super.insert(entry, false);
}
// do batch nn
- Map<DBID, KNNList<D>> knnLists = batchNN(getRoot(), ids, settings.k_max + 1);
+ Map<DBID, KNNList> knnLists = batchNN(getRoot(), ids, settings.k_max + 1);
// adjust the knn distances
adjustApproximatedKNNDistances(getRootEntry(), knnLists);
- if (EXTRA_INTEGRITY_CHECKS) {
+ if(EXTRA_INTEGRITY_CHECKS) {
getRoot().integrityCheck(this, getRootEntry());
}
}
@@ -144,49 +141,48 @@ public class MkAppTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @return a List of the query results
*/
@Override
- public DistanceDBIDList<D> reverseKNNQuery(DBIDRef id, int k) {
- GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>();
+ public DoubleDBIDList reverseKNNQuery(DBIDRef id, int k) {
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
final Heap<GenericMTreeDistanceSearchCandidate> pq = new UpdatableHeap<>();
// push root
pq.add(new GenericMTreeDistanceSearchCandidate(0., getRootID(), null));
// search in tree
- while (!pq.isEmpty()) {
+ while(!pq.isEmpty()) {
GenericMTreeDistanceSearchCandidate pqNode = pq.poll();
// FIXME: cache the distance to the routing object in the queue node!
- MkAppTreeNode<O, D> node = getNode(pqNode.nodeID);
+ MkAppTreeNode<O> node = getNode(pqNode.nodeID);
// directory node
- if (!node.isLeaf()) {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ if(!node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MkAppEntry entry = node.getEntry(i);
- double distance = distance(entry.getRoutingObjectID(), id).doubleValue();
+ double distance = distance(entry.getRoutingObjectID(), id);
double minDist = (entry.getCoveringRadius() > distance) ? 0. : distance - entry.getCoveringRadius();
double approxValue = settings.log ? Math.exp(entry.approximatedValueAt(k)) : entry.approximatedValueAt(k);
- if (approxValue < 0) {
+ if(approxValue < 0) {
approxValue = 0;
}
- if (minDist <= approxValue) {
+ if(minDist <= approxValue) {
pq.add(new GenericMTreeDistanceSearchCandidate(minDist, getPageID(entry), entry.getRoutingObjectID()));
}
}
}
// data node
else {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MkAppLeafEntry entry = (MkAppLeafEntry) node.getEntry(i);
- D distance = distance(entry.getRoutingObjectID(), id);
+ double distance = distance(entry.getRoutingObjectID(), id);
double approxValue = settings.log ? StrictMath.exp(entry.approximatedValueAt(k)) : entry.approximatedValueAt(k);
- if (approxValue < 0) {
+ if(approxValue < 0) {
approxValue = 0;
}
- D approximatedKnnDist = getDistanceFactory().fromDouble(approxValue);
- if (distance.compareTo(approximatedKnnDist) <= 0) {
+ if(distance <= approxValue) {
result.add(distance, entry.getRoutingObjectID());
}
}
@@ -213,7 +209,7 @@ public class MkAppTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
// overhead = index(4), numEntries(4), id(4), isLeaf(0.125)
double overhead = 12.125;
- if (getPageSize() - overhead < 0) {
+ if(getPageSize() - overhead < 0) {
throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!");
}
@@ -221,11 +217,11 @@ public class MkAppTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
// coveringRadius + parentDistance + approx) + 1
dirCapacity = (int) (getPageSize() - overhead) / (4 + 4 + distanceSize + distanceSize + (settings.p + 1) * 4 + 2) + 1;
- if (dirCapacity <= 1) {
+ if(dirCapacity <= 1) {
throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!");
}
- if (dirCapacity < 10) {
+ if(dirCapacity < 10) {
LOG.warning("Page size is choosen too small! Maximum number of entries " + "in a directory node = " + (dirCapacity - 1));
}
@@ -234,39 +230,37 @@ public class MkAppTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
// approx) + 1
leafCapacity = (int) (getPageSize() - overhead) / (4 + distanceSize + (settings.p + 1) * 4 + 2) + 1;
- if (leafCapacity <= 1) {
+ if(leafCapacity <= 1) {
throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!");
}
- if (leafCapacity < 10) {
+ if(leafCapacity < 10) {
LOG.warning("Page size is choosen too small! Maximum number of entries " + "in a leaf node = " + (leafCapacity - 1));
}
initialized = true;
- if (LOG.isVerbose()) {
+ if(LOG.isVerbose()) {
LOG.verbose("Directory Capacity: " + (dirCapacity - 1) + "\nLeaf Capacity: " + (leafCapacity - 1));
}
}
- private List<D> getMeanKNNList(DBIDs ids, Map<DBID, KNNList<D>> knnLists) {
+ private double[] getMeanKNNList(DBIDs ids, Map<DBID, KNNList> knnLists) {
double[] means = new double[settings.k_max];
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
DBID id = DBIDUtil.deref(iter);
- KNNList<D> knns = knnLists.get(id);
+ KNNList knns = knnLists.get(id);
int k = 0;
- for (DistanceDBIDListIter<D> it = knns.iter(); k < settings.k_max && it.valid(); it.advance(), k++) {
- means[k] += it.getDistance().doubleValue();
+ for(DoubleDBIDListIter it = knns.iter(); k < settings.k_max && it.valid(); it.advance(), k++) {
+ means[k] += it.doubleValue();
}
}
- List<D> result = new ArrayList<>();
- for (int k = 0; k < settings.k_max; k++) {
+ for(int k = 0; k < settings.k_max; k++) {
means[k] /= ids.size();
- result.add(getDistanceFactory().fromDouble(means[k]));
}
- return result;
+ return means;
}
/**
@@ -275,19 +269,20 @@ public class MkAppTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @param entry the root entry of the current subtree
* @param knnLists a map of knn lists for each leaf entry
*/
- private void adjustApproximatedKNNDistances(MkAppEntry entry, Map<DBID, KNNList<D>> knnLists) {
- MkAppTreeNode<O, D> node = getNode(entry);
+ private void adjustApproximatedKNNDistances(MkAppEntry entry, Map<DBID, KNNList> knnLists) {
+ MkAppTreeNode<O> node = getNode(entry);
- if (node.isLeaf()) {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ if(node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MkAppLeafEntry leafEntry = (MkAppLeafEntry) node.getEntry(i);
// approximateKnnDistances(leafEntry,
// getKNNList(leafEntry.getRoutingObjectID(), knnLists));
PolynomialApproximation approx = approximateKnnDistances(getMeanKNNList(leafEntry.getDBID(), knnLists));
leafEntry.setKnnDistanceApproximation(approx);
}
- } else {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ }
+ else {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MkAppEntry dirEntry = node.getEntry(i);
adjustApproximatedKNNDistances(dirEntry, knnLists);
}
@@ -307,15 +302,16 @@ public class MkAppTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @param result the result list containing the ids of the leaf entries stored
* in the specified subtree
*/
- private void leafEntryIDs(MkAppTreeNode<O, D> node, ModifiableDBIDs result) {
- if (node.isLeaf()) {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ private void leafEntryIDs(MkAppTreeNode<O> node, ModifiableDBIDs result) {
+ if(node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MkAppEntry entry = node.getEntry(i);
result.add(((LeafEntry) entry).getDBID());
}
- } else {
- for (int i = 0; i < node.getNumEntries(); i++) {
- MkAppTreeNode<O, D> childNode = getNode(node.getEntry(i));
+ }
+ else {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ MkAppTreeNode<O> childNode = getNode(node.getEntry(i));
leafEntryIDs(childNode, result);
}
}
@@ -327,17 +323,18 @@ public class MkAppTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @param knnDistances the knn-distances of the leaf entry
* @return the polynomial approximation of the specified knn-distances.
*/
- private PolynomialApproximation approximateKnnDistances(List<D> knnDistances) {
+ private PolynomialApproximation approximateKnnDistances(double[] knnDistances) {
StringBuilder msg = new StringBuilder();
// count the zero distances (necessary of log-log space is used)
int k_0 = 0;
- if (settings.log) {
- for (int i = 0; i < settings.k_max; i++) {
- double dist = knnDistances.get(i).doubleValue();
- if (dist == 0) {
+ if(settings.log) {
+ for(int i = 0; i < settings.k_max; i++) {
+ double dist = knnDistances[i];
+ if(dist == 0) {
k_0++;
- } else {
+ }
+ else {
break;
}
}
@@ -346,20 +343,21 @@ public class MkAppTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
de.lmu.ifi.dbs.elki.math.linearalgebra.Vector x = new de.lmu.ifi.dbs.elki.math.linearalgebra.Vector(settings.k_max - k_0);
de.lmu.ifi.dbs.elki.math.linearalgebra.Vector y = new de.lmu.ifi.dbs.elki.math.linearalgebra.Vector(settings.k_max - k_0);
- for (int k = 0; k < settings.k_max - k_0; k++) {
- if (settings.log) {
+ for(int k = 0; k < settings.k_max - k_0; k++) {
+ if(settings.log) {
x.set(k, Math.log(k + k_0));
- y.set(k, Math.log(knnDistances.get(k + k_0).doubleValue()));
- } else {
+ y.set(k, Math.log(knnDistances[k + k_0]));
+ }
+ else {
x.set(k, k + k_0);
- y.set(k, knnDistances.get(k + k_0).doubleValue());
+ y.set(k, knnDistances[k + k_0]);
}
}
PolynomialRegression regression = new PolynomialRegression(y, x, settings.p);
PolynomialApproximation approximation = new PolynomialApproximation(regression.getEstimatedCoefficients().getArrayCopy());
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
msg.append("approximation ").append(approximation);
LOG.debugFine(msg.toString());
}
@@ -373,7 +371,7 @@ public class MkAppTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @return a new leaf node
*/
@Override
- protected MkAppTreeNode<O, D> createNewLeafNode() {
+ protected MkAppTreeNode<O> createNewLeafNode() {
return new MkAppTreeNode<>(leafCapacity, true);
}
@@ -383,7 +381,7 @@ public class MkAppTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @return a new directory node
*/
@Override
- protected MkAppTreeNode<O, D> createNewDirectoryNode() {
+ protected MkAppTreeNode<O> createNewDirectoryNode() {
return new MkAppTreeNode<>(dirCapacity, false);
}
@@ -396,7 +394,7 @@ public class MkAppTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* the routing object of the parent node
*/
@Override
- protected MkAppEntry createNewDirectoryEntry(MkAppTreeNode<O, D> node, DBID routingObjectID, double parentDistance) {
+ protected MkAppEntry createNewDirectoryEntry(MkAppTreeNode<O> node, DBID routingObjectID, double parentDistance) {
return new MkAppDirectoryEntry(routingObjectID, parentDistance, node.getPageID(), node.coveringRadius(routingObjectID, this), null);
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeFactory.java
index 1d4b7fe4..0bffdd29 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
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.index.tree.metrical.mtreevariants.mktrees.mkapp;
*/
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeFactory;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
import de.lmu.ifi.dbs.elki.persistent.PageFileFactory;
@@ -44,9 +43,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* @apiviz.uses MkAppTreeIndex oneway - - «create»
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class MkAppTreeFactory<O, D extends NumberDistance<D, ?>> extends AbstractMTreeFactory<O, D, MkAppTreeNode<O, D>, MkAppEntry, MkAppTreeIndex<O, D>, MkAppTreeSettings<O, D>> {
+public class MkAppTreeFactory<O> extends AbstractMTreeFactory<O, MkAppTreeNode<O>, MkAppEntry, MkAppTreeIndex<O>, MkAppTreeSettings<O>> {
/**
* Parameter for nolog
*/
@@ -68,17 +66,17 @@ public class MkAppTreeFactory<O, D extends NumberDistance<D, ?>> extends Abstrac
* @param pageFileFactory Data storage
* @param settings Tree settings
*/
- public MkAppTreeFactory(PageFileFactory<?> pageFileFactory, MkAppTreeSettings<O, D> settings) {
+ public MkAppTreeFactory(PageFileFactory<?> pageFileFactory, MkAppTreeSettings<O> settings) {
super(pageFileFactory, settings);
}
@Override
- public MkAppTreeIndex<O, D> instantiate(Relation<O> relation) {
- PageFile<MkAppTreeNode<O, D>> pagefile = makePageFile(getNodeClass());
+ public MkAppTreeIndex<O> instantiate(Relation<O> relation) {
+ PageFile<MkAppTreeNode<O>> pagefile = makePageFile(getNodeClass());
return new MkAppTreeIndex<>(relation, pagefile, settings);
}
- protected Class<MkAppTreeNode<O, D>> getNodeClass() {
+ protected Class<MkAppTreeNode<O>> getNodeClass() {
return ClassGenericsUtil.uglyCastIntoSubclass(MkAppTreeNode.class);
}
@@ -88,8 +86,10 @@ public class MkAppTreeFactory<O, D extends NumberDistance<D, ?>> extends Abstrac
* @author Erich Schubert
*
* @apiviz.exclude
+ *
+ * @param <O> Object type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractMTreeFactory.Parameterizer<O, D, MkAppTreeNode<O, D>, MkAppEntry, MkAppTreeSettings<O, D>> {
+ public static class Parameterizer<O> extends AbstractMTreeFactory.Parameterizer<O, MkAppTreeNode<O>, MkAppEntry, MkAppTreeSettings<O>> {
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
@@ -112,12 +112,12 @@ public class MkAppTreeFactory<O, D extends NumberDistance<D, ?>> extends Abstrac
}
@Override
- protected MkAppTreeFactory<O, D> makeInstance() {
+ protected MkAppTreeFactory<O> makeInstance() {
return new MkAppTreeFactory<>(pageFileFactory, settings);
}
@Override
- protected MkAppTreeSettings<O, D> makeSettings() {
+ protected MkAppTreeSettings<O> makeSettings() {
return new MkAppTreeSettings<>();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeIndex.java
index 2a630bf0..5db5d03c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
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
@@ -36,8 +36,6 @@ import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery;
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.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
import de.lmu.ifi.dbs.elki.index.RKNNIndex;
import de.lmu.ifi.dbs.elki.index.RangeIndex;
@@ -51,9 +49,8 @@ import de.lmu.ifi.dbs.elki.persistent.PageFile;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class MkAppTreeIndex<O, D extends NumberDistance<D, ?>> extends MkAppTree<O, D> implements RangeIndex<O>, KNNIndex<O>, RKNNIndex<O> {
+public class MkAppTreeIndex<O> extends MkAppTree<O> implements RangeIndex<O>, KNNIndex<O>, RKNNIndex<O> {
/**
* The relation indexed
*/
@@ -66,7 +63,7 @@ public class MkAppTreeIndex<O, D extends NumberDistance<D, ?>> extends MkAppTree
* @param pageFile Page file
* @param settings Tree settings
*/
- public MkAppTreeIndex(Relation<O> relation, PageFile<MkAppTreeNode<O, D>> pageFile, MkAppTreeSettings<O, D> settings) {
+ public MkAppTreeIndex(Relation<O> relation, PageFile<MkAppTreeNode<O>> pageFile, MkAppTreeSettings<O> settings) {
super(relation, pageFile, settings);
this.relation = relation;
}
@@ -95,14 +92,13 @@ public class MkAppTreeIndex<O, D extends NumberDistance<D, ?>> extends MkAppTree
insertAll(objs);
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> KNNQuery<O, S> getKNNQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
// Query on the relation we index
if (distanceQuery.getRelation() != relation) {
return null;
}
- DistanceFunction<? super O, D> distanceFunction = (DistanceFunction<? super O, D>) distanceQuery.getDistanceFunction();
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
if (!this.getDistanceFunction().equals(distanceFunction)) {
if (getLogger().isDebugging()) {
getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!");
@@ -115,18 +111,16 @@ public class MkAppTreeIndex<O, D extends NumberDistance<D, ?>> extends MkAppTree
return null;
}
}
- DistanceQuery<O, D> dq = distanceFunction.instantiate(relation);
- return (KNNQuery<O, S>) MTreeQueryUtil.getKNNQuery(this, dq, hints);
+ return MTreeQueryUtil.getKNNQuery(this, distanceQuery, hints);
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> RangeQuery<O, S> getRangeQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
+ public RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
// Query on the relation we index
if (distanceQuery.getRelation() != relation) {
return null;
}
- DistanceFunction<? super O, D> distanceFunction = (DistanceFunction<? super O, D>) distanceQuery.getDistanceFunction();
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
if (!this.getDistanceFunction().equals(distanceFunction)) {
if (getLogger().isDebugging()) {
getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!");
@@ -139,14 +133,12 @@ public class MkAppTreeIndex<O, D extends NumberDistance<D, ?>> extends MkAppTree
return null;
}
}
- DistanceQuery<O, D> dq = distanceFunction.instantiate(relation);
- return (RangeQuery<O, S>) MTreeQueryUtil.getRangeQuery(this, dq, hints);
+ return MTreeQueryUtil.getRangeQuery(this, distanceQuery, hints);
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> RKNNQuery<O, S> getRKNNQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
- DistanceFunction<? super O, D> distanceFunction = (DistanceFunction<? super O, D>) distanceQuery.getDistanceFunction();
+ public RKNNQuery<O> getRKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
if (!this.getDistanceFunction().equals(distanceFunction)) {
if (getLogger().isDebugging()) {
getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!");
@@ -159,8 +151,7 @@ public class MkAppTreeIndex<O, D extends NumberDistance<D, ?>> extends MkAppTree
return null;
}
}
- DistanceQuery<O, D> dq = distanceFunction.instantiate(relation);
- return (RKNNQuery<O, S>) new MkTreeRKNNQuery<>(this, dq);
+ return (RKNNQuery<O>) new MkTreeRKNNQuery<>(this, distanceQuery);
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeNode.java
index 29609274..e9eb66b3 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
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 java.util.Arrays;
import java.util.logging.Logger;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration;
@@ -41,9 +40,8 @@ import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
* @apiviz.has MkAppEntry oneway - - contains
*
* @param <O> object type
- * @param <D> distance type
*/
-class MkAppTreeNode<O, D extends NumberDistance<D, ?>> extends AbstractMTreeNode<O, D, MkAppTreeNode<O, D>, MkAppEntry> {
+class MkAppTreeNode<O> extends AbstractMTreeNode<O, MkAppTreeNode<O>, MkAppEntry> {
private static final long serialVersionUID = 2;
/**
@@ -92,7 +90,7 @@ class MkAppTreeNode<O, D extends NumberDistance<D, ?>> extends AbstractMTreeNode
if(LoggingConfiguration.DEBUG) {
StringBuilder msg = new StringBuilder();
- msg.append("b " + FormatUtil.format(b, 4));
+ msg.append("b " + FormatUtil.format(b, FormatUtil.NF4));
Logger.getLogger(this.getClass().getName()).fine(msg.toString());
}
@@ -109,13 +107,13 @@ class MkAppTreeNode<O, D extends NumberDistance<D, ?>> extends AbstractMTreeNode
* @param mTree the M-Tree object holding this node
*/
@Override
- public void adjustEntry(MkAppEntry entry, DBID routingObjectID, double parentDistance, AbstractMTree<O, D, MkAppTreeNode<O, D>, MkAppEntry, ?> mTree) {
+ public void adjustEntry(MkAppEntry entry, DBID routingObjectID, double parentDistance, AbstractMTree<O, MkAppTreeNode<O>, MkAppEntry, ?> mTree) {
super.adjustEntry(entry, routingObjectID, parentDistance, mTree);
// entry.setKnnDistanceApproximation(knnDistanceApproximation());
}
@Override
- protected void integrityCheckParameters(MkAppEntry parentEntry, MkAppTreeNode<O, D> parent, int index, AbstractMTree<O, D, MkAppTreeNode<O, D>, MkAppEntry, ?> mTree) {
+ protected void integrityCheckParameters(MkAppEntry parentEntry, MkAppTreeNode<O> parent, int index, AbstractMTree<O, MkAppTreeNode<O>, MkAppEntry, ?> mTree) {
super.integrityCheckParameters(parentEntry, parent, index, mTree);
MkAppEntry entry = parent.getEntry(index);
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeSettings.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeSettings.java
index b9e0b8aa..3871586e 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeSettings.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeSettings.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
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.index.tree.metrical.mtreevariants.mktrees.mkapp;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.MkTreeSettings;
/**
@@ -32,9 +31,8 @@ import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.MkTreeSetti
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class MkAppTreeSettings<O, D extends NumberDistance<D, ?>> extends MkTreeSettings<O, D, MkAppTreeNode<O, D>, MkAppEntry> {
+public class MkAppTreeSettings<O> extends MkTreeSettings<O, MkAppTreeNode<O>, MkAppEntry> {
/**
* Parameter p.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/PolynomialApproximation.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/PolynomialApproximation.java
index f156c607..7d801a81 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/PolynomialApproximation.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/PolynomialApproximation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
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 java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
-import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
/**
@@ -149,6 +148,6 @@ public class PolynomialApproximation implements Externalizable {
*/
@Override
public String toString() {
- return FormatUtil.format(b, 4);
+ return FormatUtil.format(b, FormatUtil.NF4);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/package-info.java
index 7b897fe3..c7597169 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/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/index/tree/metrical/mtreevariants/mktrees/mkcop/ApproximationLine.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ApproximationLine.java
index 318c437b..bae501f3 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ApproximationLine.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ApproximationLine.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
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/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java
index fe0e20b0..7cdb0728 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
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/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPDirectoryEntry.java
index 8b6282a3..aeb8e0ce 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
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
@@ -56,7 +56,7 @@ class MkCoPDirectoryEntry extends MTreeDirectoryEntry implements MkCoPEntry {
}
/**
- * Provides a new MkCoPDirectoryEntry with the given parameters.
+ * Constructor.
*
* @param objectID the id of the routing object
* @param parentDistance the distance from the object to its parent
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java
index ae569d03..393a6c72 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
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/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPLeafEntry.java
index 7d241eba..b4b78ec5 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
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
@@ -61,7 +61,7 @@ class MkCoPLeafEntry extends MTreeLeafEntry implements MkCoPEntry {
}
/**
- * Provides a new MkCoPLeafEntry with the given parameters.
+ * Constructor.
*
* @param objectID the id of the underlying data object
* @param parentDistance the distance from the underlying data object to its
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java
index b98d6821..126013b1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
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,21 +31,20 @@ 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.DBIDRef;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.AbstractMkTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.MkTreeSettings;
import de.lmu.ifi.dbs.elki.index.tree.query.GenericMTreeDistanceSearchCandidate;
import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
/**
* MkCopTree is a metrical index structure based on the concepts of the M-Tree
@@ -58,9 +57,8 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap;
* @apiviz.has ConvexHull
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree<O, D, MkCoPTreeNode<O, D>, MkCoPEntry, MkTreeSettings<O, D, MkCoPTreeNode<O, D>, MkCoPEntry>> {
+public class MkCoPTree<O> extends AbstractMkTree<O, MkCoPTreeNode<O>, MkCoPEntry, MkTreeSettings<O, MkCoPTreeNode<O>, MkCoPEntry>> {
/**
* The logger for this class.
*/
@@ -78,11 +76,11 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @param pagefile Page file
* @param settings Tree settings
*/
- public MkCoPTree(Relation<O> relation, PageFile<MkCoPTreeNode<O, D>> pagefile, MkTreeSettings<O, D, MkCoPTreeNode<O, D>, MkCoPEntry> settings) {
+ public MkCoPTree(Relation<O> relation, PageFile<MkCoPTreeNode<O>> pagefile, MkTreeSettings<O, MkCoPTreeNode<O>, MkCoPEntry> settings) {
super(relation, pagefile, settings);
// init log k
log_k = new double[settings.k_max];
- for (int k = 1; k <= settings.k_max; k++) {
+ for(int k = 1; k <= settings.k_max; k++) {
log_k[k - 1] = Math.log(k);
}
}
@@ -105,34 +103,34 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
@Override
public void insertAll(List<MkCoPEntry> entries) {
- if (entries.isEmpty()) {
+ if(entries.isEmpty()) {
return;
}
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
LOG.debugFine("insert " + entries + "\n");
}
- if (!initialized) {
+ if(!initialized) {
initialize(entries.get(0));
}
ModifiableDBIDs ids = DBIDUtil.newArray(entries.size());
// insert
- for (MkCoPEntry entry : entries) {
+ for(MkCoPEntry entry : entries) {
ids.add(entry.getRoutingObjectID());
// insert the object
super.insert(entry, false);
}
// perform nearest neighbor queries
- Map<DBID, KNNList<D>> knnLists = batchNN(getRoot(), ids, settings.k_max);
+ Map<DBID, KNNList> knnLists = batchNN(getRoot(), ids, settings.k_max);
// adjust the knn distances
adjustApproximatedKNNDistances(getRootEntry(), knnLists);
- if (EXTRA_INTEGRITY_CHECKS) {
+ if(EXTRA_INTEGRITY_CHECKS) {
getRoot().integrityCheck(this, getRootEntry());
}
}
@@ -146,17 +144,17 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @return a List of the query results
*/
@Override
- public DistanceDBIDList<D> reverseKNNQuery(DBIDRef id, int k) {
- if (k > settings.k_max) {
+ public DoubleDBIDList reverseKNNQuery(DBIDRef id, int k) {
+ if(k > settings.k_max) {
throw new IllegalArgumentException("Parameter k has to be less or equal than " + "parameter kmax of the MCop-Tree!");
}
- GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>();
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
ModifiableDBIDs candidates = DBIDUtil.newArray();
doReverseKNNQuery(k, id, result, candidates);
// refinement of candidates
- Map<DBID, KNNList<D>> knnLists = batchNN(getRoot(), candidates, k);
+ Map<DBID, KNNList> knnLists = batchNN(getRoot(), candidates, k);
result.sort();
// Collections.sort(candidates);
@@ -165,12 +163,12 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
// rkNNStatistics.addCandidates(candidates.size());
// rkNNStatistics.addTrueHits(result.size());
- for (DBIDIter iter = candidates.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = candidates.iter(); iter.valid(); iter.advance()) {
DBID cid = DBIDUtil.deref(iter);
- KNNList<D> cands = knnLists.get(cid);
- for (DistanceDBIDListIter<D> iter2 = cands.iter(); iter2.valid(); iter2.advance()) {
- if (DBIDUtil.equal(id, iter2)) {
- result.add(iter2.getDistance(), cid);
+ KNNList cands = knnLists.get(cid);
+ for(DoubleDBIDListIter iter2 = cands.iter(); iter2.valid(); iter2.advance()) {
+ if(DBIDUtil.equal(id, iter2)) {
+ result.add(iter2.doubleValue(), cid);
break;
}
}
@@ -200,7 +198,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
// overhead = index(4), numEntries(4), id(4), isLeaf(0.125)
double overhead = 12.125;
- if (getPageSize() - overhead < 0) {
+ if(getPageSize() - overhead < 0) {
throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!");
}
@@ -208,11 +206,11 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
// coveringRadius + parentDistance + consApprox) + 1
dirCapacity = (int) (getPageSize() - overhead) / (4 + 4 + distanceSize + distanceSize + 10) + 1;
- if (dirCapacity <= 1) {
+ if(dirCapacity <= 1) {
throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!");
}
- if (dirCapacity < 10) {
+ if(dirCapacity < 10) {
LOG.warning("Page size is choosen too small! Maximum number of entries " + "in a directory node = " + (dirCapacity - 1));
}
@@ -221,17 +219,17 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
// consApprox + progrApprox) + 1
leafCapacity = (int) (getPageSize() - overhead) / (4 + distanceSize + 2 * 10) + 1;
- if (leafCapacity <= 1) {
+ if(leafCapacity <= 1) {
throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!");
}
- if (leafCapacity < 10) {
+ if(leafCapacity < 10) {
LOG.warning("Page size is choosen too small! Maximum number of entries " + "in a leaf node = " + (leafCapacity - 1));
}
initialized = true;
- if (LOG.isVerbose()) {
+ if(LOG.isVerbose()) {
LOG.verbose("Directory Capacity: " + (dirCapacity - 1) + "\nLeaf Capacity: " + (leafCapacity - 1));
}
}
@@ -245,45 +243,46 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @param candidates holds possible candidates for the result (they need a
* refinement)
*/
- private void doReverseKNNQuery(int k, DBIDRef q, GenericDistanceDBIDList<D> result, ModifiableDBIDs candidates) {
+ private void doReverseKNNQuery(int k, DBIDRef q, ModifiableDoubleDBIDList result, ModifiableDBIDs candidates) {
final ComparableMinHeap<GenericMTreeDistanceSearchCandidate> pq = new ComparableMinHeap<>();
// push root
pq.add(new GenericMTreeDistanceSearchCandidate(0., getRootID(), null));
// search in tree
- while (!pq.isEmpty()) {
+ while(!pq.isEmpty()) {
GenericMTreeDistanceSearchCandidate pqNode = pq.poll();
// FIXME: cache the distance to the routing object in the queue node!
- MkCoPTreeNode<O, D> node = getNode(pqNode.nodeID);
+ MkCoPTreeNode<O> node = getNode(pqNode.nodeID);
// directory node
- if (!node.isLeaf()) {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ if(!node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MkCoPEntry entry = node.getEntry(i);
- double distance = distance(entry.getRoutingObjectID(), q).doubleValue();
+ double distance = distance(entry.getRoutingObjectID(), q);
double minDist = entry.getCoveringRadius() > distance ? 0. : distance - entry.getCoveringRadius();
double approximatedKnnDist_cons = entry.approximateConservativeKnnDistance(k);
- if (minDist <= approximatedKnnDist_cons) {
+ if(minDist <= approximatedKnnDist_cons) {
pq.add(new GenericMTreeDistanceSearchCandidate(minDist, getPageID(entry), entry.getRoutingObjectID()));
}
}
}
// data node
else {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MkCoPLeafEntry entry = (MkCoPLeafEntry) node.getEntry(i);
- D distance = distance(entry.getRoutingObjectID(), q);
+ double distance = distance(entry.getRoutingObjectID(), q);
double approximatedKnnDist_prog = entry.approximateProgressiveKnnDistance(k);
- if (distance.doubleValue() <= approximatedKnnDist_prog) {
+ if(distance <= approximatedKnnDist_prog) {
result.add(distance, entry.getRoutingObjectID());
- } else {
+ }
+ else {
double approximatedKnnDist_cons = entry.approximateConservativeKnnDistance(k);
- double diff = distance.doubleValue() - approximatedKnnDist_cons;
- if (diff <= 1E-10) {
+ double diff = distance - approximatedKnnDist_cons;
+ if(diff <= 1E-10) {
candidates.add(entry.getRoutingObjectID());
}
}
@@ -298,16 +297,17 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @param entry the root entry of the current subtree
* @param knnLists a map of knn lists for each leaf entry
*/
- private void adjustApproximatedKNNDistances(MkCoPEntry entry, Map<DBID, KNNList<D>> knnLists) {
- MkCoPTreeNode<O, D> node = getNode(entry);
+ private void adjustApproximatedKNNDistances(MkCoPEntry entry, Map<DBID, KNNList> knnLists) {
+ MkCoPTreeNode<O> node = getNode(entry);
- if (node.isLeaf()) {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ if(node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MkCoPLeafEntry leafEntry = (MkCoPLeafEntry) node.getEntry(i);
approximateKnnDistances(leafEntry, knnLists.get(leafEntry.getRoutingObjectID()));
}
- } else {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ }
+ else {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MkCoPEntry dirEntry = node.getEntry(i);
adjustApproximatedKNNDistances(dirEntry, knnLists);
}
@@ -323,7 +323,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
private double ssqerr(int k0, int kmax, double[] logk, double[] log_kDist, double m, double t) {
int k = kmax - k0;
double result = 0;
- for (int i = 0; i < k; i++) {
+ for(int i = 0; i < k; i++) {
// double h = log_kDist[i] - (m * (logk[i] - logk[0]) + t); ???
double h = log_kDist[i] - m * logk[i] - t;
result += h * h;
@@ -349,19 +349,20 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @param knnDistances TODO: Spezialbehandlung fuer identische Punkte in DB
* (insbes. Distanz 0)
*/
- private void approximateKnnDistances(MkCoPLeafEntry entry, KNNList<D> knnDistances) {
+ private void approximateKnnDistances(MkCoPLeafEntry entry, KNNList knnDistances) {
StringBuilder msg = LOG.isDebugging() ? new StringBuilder() : null;
- if (msg != null) {
+ if(msg != null) {
msg.append("\nknnDistances ").append(knnDistances);
}
// count the zero distances
int k_0 = 0;
- for (int i = 0; i < settings.k_max; i++) {
- double dist = knnDistances.get(i).getDistance().doubleValue();
- if (dist == 0) {
+ for(int i = 0; i < settings.k_max; i++) {
+ double dist = knnDistances.get(i).doubleValue();
+ if(dist == 0) {
k_0++;
- } else {
+ }
+ else {
break;
}
}
@@ -374,8 +375,8 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
double sum_log_k_kDist = 0;
double[] log_kDist = new double[settings.k_max - k_0];
- for (int i = 0; i < settings.k_max - k_0; i++) {
- double dist = knnDistances.get(i + k_0).getDistance().doubleValue();
+ for(int i = 0; i < settings.k_max - k_0; i++) {
+ double dist = knnDistances.get(i + k_0).doubleValue();
log_kDist[i] = Math.log(dist);
sum_log_kDist += log_kDist[i];
sum_log_k_kDist += log_kDist[i] * log_k[i];
@@ -384,12 +385,12 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
double sum_log_k = 0;
double sum_log_k2 = 0;
// noinspection ForLoopReplaceableByForEach
- for (int i = 0; i < log_k.length; i++) {
+ for(int i = 0; i < log_k.length; i++) {
sum_log_k += log_k[i];
sum_log_k2 += (log_k[i] * log_k[i]);
}
- if (msg != null) {
+ if(msg != null) {
msg.append("\nk_0 ").append(k_0);
msg.append("\nk_max ").append(settings.k_max);
msg.append("\nlog_k(").append(log_k.length).append(") ").append(FormatUtil.format(log_k));
@@ -412,12 +413,12 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
double err1 = ssqerr(k_0, settings.k_max, log_k, log_kDist, conservative.getM(), conservative.getT());
double err2 = ssqerr(k_0, settings.k_max, log_k, log_kDist, c2.getM(), c2.getT());
- if (msg != null) {
+ if(msg != null) {
msg.append("err1 ").append(err1);
msg.append("err2 ").append(err2);
}
- if (err1 > err2 && err1 - err2 > 0.000000001) {
+ if(err1 > err2 && err1 - err2 > 0.000000001) {
// if (err1 > err2) {
StringBuilder warning = new StringBuilder();
@@ -431,7 +432,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
warning.append("\nconservative1 ").append(conservative);
warning.append("\nconservative2 ").append(c2);
- for (int i = 0; i < u; i++) {
+ for(int i = 0; i < u; i++) {
warning.append("\nlog_k[").append(upperHull[i]).append("] = ").append(log_k[upperHull[i]]);
warning.append("\nlog_kDist[").append(upperHull[i]).append("] = ").append(log_kDist[upperHull[i]]);
}
@@ -444,7 +445,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
entry.setConservativeKnnDistanceApproximation(conservative);
entry.setProgressiveKnnDistanceApproximation(progressive);
- if (msg != null) {
+ if(msg != null) {
LOG.debugFine(msg.toString());
}
}
@@ -470,12 +471,12 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
double low_m = 0.0;
double low_t = 0.0;
- for (int i = 1; i < l; i++) {
+ for(int i = 1; i < l; i++) {
double cur_m = (log_kDist[lowerHull[i]] - log_kDist[lowerHull[i - 1]]) / (log_k[lowerHull[i]] - log_k[lowerHull[i - 1]]);
double cur_t = log_kDist[lowerHull[i]] - cur_m * log_k[lowerHull[i]];
double cur_error = ssqerr(k_0, settings.k_max, log_k, log_kDist, cur_m, cur_t);
msg.append(" Segment = ").append(i).append(" m = ").append(cur_m).append(" t = ").append(cur_t).append(" lowerror = ").append(cur_error).append("\n");
- if (cur_error < low_error) {
+ if(cur_error < low_error) {
low_error = cur_error;
low_m = cur_m;
low_t = cur_t;
@@ -484,13 +485,13 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
// linear search on all points of the lower convex hull
boolean is_right = true; // NEEDED FOR PROOF CHECK
- for (int i = 0; i < l; i++) {
+ for(int i = 0; i < l; i++) {
double cur_m = optimize(k_0, settings.k_max, sum_log_k, sum_log_k2, log_k[lowerHull[i]], log_kDist[lowerHull[i]], sum_log_k_kDist, sum_log_kDist);
double cur_t = log_kDist[lowerHull[i]] - cur_m * log_k[lowerHull[i]];
// only valid if both neighboring points are underneath y=mx+t
- if ((i == 0 || log_kDist[lowerHull[i - 1]] >= log_kDist[lowerHull[i]] - cur_m * (log_k[lowerHull[i]] - log_k[lowerHull[i - 1]])) && (i == l - 1 || log_kDist[lowerHull[i + 1]] >= log_kDist[lowerHull[i]] + cur_m * (log_k[lowerHull[i + 1]] - log_k[lowerHull[i]]))) {
+ if((i == 0 || log_kDist[lowerHull[i - 1]] >= log_kDist[lowerHull[i]] - cur_m * (log_k[lowerHull[i]] - log_k[lowerHull[i - 1]])) && (i == l - 1 || log_kDist[lowerHull[i + 1]] >= log_kDist[lowerHull[i]] + cur_m * (log_k[lowerHull[i + 1]] - log_k[lowerHull[i]]))) {
double cur_error = ssqerr(k_0, settings.k_max, log_k, log_kDist, cur_m, cur_t);
- if (cur_error < low_error) {
+ if(cur_error < low_error) {
low_error = cur_error;
low_m = cur_m;
low_t = cur_t;
@@ -498,9 +499,9 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
}
// check proof of bisection search
- if (!(i > 0 && log_kDist[lowerHull[i - 1]] < log_kDist[lowerHull[i]] - cur_m * (log_k[lowerHull[i]] - log_k[lowerHull[i - 1]])) && !is_right) {
+ if(!(i > 0 && log_kDist[lowerHull[i - 1]] < log_kDist[lowerHull[i]] - cur_m * (log_k[lowerHull[i]] - log_k[lowerHull[i - 1]])) && !is_right) {
// warning("ERROR lower: The bisection search will not work properly !");
- if (!(i < l - 1 && log_kDist[lowerHull[i + 1]] < log_kDist[lowerHull[i]] + cur_m * (log_k[lowerHull[i + 1]] - log_k[lowerHull[i]]))) {
+ if(!(i < l - 1 && log_kDist[lowerHull[i + 1]] < log_kDist[lowerHull[i]] + cur_m * (log_k[lowerHull[i + 1]] - log_k[lowerHull[i]]))) {
is_right = false;
}
}
@@ -519,14 +520,14 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
ApproximationLine approx = null;
double error = Double.POSITIVE_INFINITY;
- for (int i = 0; i < u - 1; i++) {
+ for(int i = 0; i < u - 1; i++) {
int ii = upperHull[i];
int jj = upperHull[i + 1];
double current_m = (log_kDist[jj] - log_kDist[ii]) / (log_k[jj] - log_k[ii]);
double current_t = log_kDist[ii] - current_m * log_k[ii];
ApproximationLine current_approx = new ApproximationLine(k_0, current_m, current_t);
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
msg.append("\nlog_kDist[").append(jj).append("] ").append(log_kDist[jj]);
msg.append("\nlog_kDist[").append(ii).append("] ").append(log_kDist[ii]);
msg.append("\nlog_k[").append(jj).append("] ").append(log_k[jj]);
@@ -537,22 +538,22 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
boolean ok = true;
double currentError = 0;
- for (int k = k_0; k <= settings.k_max; k++) {
+ for(int k = k_0; k <= settings.k_max; k++) {
double appDist = current_approx.getValueAt(k);
- if (appDist < log_kDist[k - k_0] && log_kDist[k - k_0] - appDist > 0.000000001) {
+ if(appDist < log_kDist[k - k_0] && log_kDist[k - k_0] - appDist > 0.000000001) {
ok = false;
break;
}
currentError += (appDist - log_kDist[k - k_0]);
}
- if (ok && currentError < error) {
+ if(ok && currentError < error) {
approx = current_approx;
error = currentError;
}
}
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
msg.append("\nupper Approx ").append(approx);
LOG.debugFine(msg.toString());
}
@@ -570,7 +571,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
int k_0 = settings.k_max - upperHull.length + 1;
int a = u / 2;
- while (marked.size() != u) {
+ while(marked.size() != u) {
marked.add(a);
double x_a = log_k[upperHull[a]];
double y_a = log_kDist[upperHull[a]];
@@ -578,7 +579,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
double m_a = optimize(k_0, settings.k_max, sum_log_k, sum_log_k2, x_a, y_a, sum_log_k_kDist, sum_log_kDist);
double t_a = y_a - m_a * x_a;
- if (msg != null) {
+ if(msg != null) {
msg.append("\na=").append(a).append(" m_a=").append(m_a).append(", t_a=").append(t_a);
msg.append("\n err ").append(ssqerr(k_0, settings.k_max, log_k, log_kDist, m_a, m_a));
}
@@ -591,23 +592,24 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
boolean lessThanPre = a == 0 || y_p <= m_a * x_p + t_a;
boolean lessThanSuc = a == u || y_s <= m_a * x_s + t_a;
- if (lessThanPre && lessThanSuc) {
+ if(lessThanPre && lessThanSuc) {
ApproximationLine appr = new ApproximationLine(k_0, m_a, t_a);
- if (msg != null) {
+ if(msg != null) {
msg.append("\n1 anchor = ").append(a);
LOG.debugFine(msg.toString());
}
return appr;
- } else if (!lessThanPre) {
- if (marked.contains(a - 1)) {
+ }
+ else if(!lessThanPre) {
+ if(marked.contains(a - 1)) {
m_a = (y_a - y_p) / (x_a - x_p);
- if (y_a == y_p) {
+ if(y_a == y_p) {
m_a = 0;
}
t_a = y_a - m_a * x_a;
ApproximationLine appr = new ApproximationLine(k_0, m_a, t_a);
- if (msg != null) {
+ if(msg != null) {
msg.append("2 anchor = ").append(a);
msg.append(" appr1 ").append(appr);
msg.append(" x_a ").append(x_a).append(", y_a ").append(y_a);
@@ -617,25 +619,28 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
LOG.debugFine(msg.toString());
}
return appr;
- } else {
+ }
+ else {
a = a - 1;
}
- } else {
- if (marked.contains(a + 1)) {
+ }
+ else {
+ if(marked.contains(a + 1)) {
m_a = (y_a - y_s) / (x_a - x_s);
- if (y_a == y_p) {
+ if(y_a == y_p) {
m_a = 0;
}
t_a = y_a - m_a * x_a;
ApproximationLine appr = new ApproximationLine(k_0, m_a, t_a);
- if (msg != null) {
+ if(msg != null) {
msg.append("3 anchor = ").append(a).append(" -- ").append((a + 1));
msg.append(" appr2 ").append(appr);
LOG.debugFine(msg.toString());
}
return appr;
- } else {
+ }
+ else {
a = a + 1;
}
}
@@ -657,11 +662,11 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
double upp_error = Double.MAX_VALUE;
double upp_m = 0.0;
double upp_t = 0.0;
- for (int i = 1; i < u; i++) {
+ for(int i = 1; i < u; i++) {
double cur_m = (log_kDist[upperHull[i]] - log_kDist[upperHull[i - 1]]) / (log_k[upperHull[i]] - log_k[upperHull[i - 1]]);
double cur_t = log_kDist[upperHull[i]] - cur_m * log_k[upperHull[i]];
double cur_error = ssqerr(k_0, settings.k_max, log_k, log_kDist, cur_m, cur_t);
- if (cur_error < upp_error) {
+ if(cur_error < upp_error) {
upp_error = cur_error;
upp_m = cur_m;
upp_t = cur_t;
@@ -669,13 +674,13 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
}
// linear search on all points of the upper convex hull
boolean is_left = true; // NEEDED FOR PROOF CHECK
- for (int i = 0; i < u; i++) {
+ for(int i = 0; i < u; i++) {
double cur_m = optimize(k_0, settings.k_max, sum_log_k, sum_log_k2, log_k[upperHull[i]], log_kDist[upperHull[i]], sum_log_k_kDist, sum_log_kDist);
double cur_t = log_kDist[upperHull[i]] - cur_m * log_k[upperHull[i]];
// only valid if both neighboring points are underneath y=mx+t
- if ((i == 0 || log_kDist[upperHull[i - 1]] <= log_kDist[upperHull[i]] - cur_m * (log_k[upperHull[i]] - log_k[upperHull[i - 1]])) && (i == u - 1 || log_kDist[upperHull[i + 1]] <= log_kDist[upperHull[i]] + cur_m * (log_k[upperHull[i + 1]] - log_k[upperHull[i]]))) {
+ if((i == 0 || log_kDist[upperHull[i - 1]] <= log_kDist[upperHull[i]] - cur_m * (log_k[upperHull[i]] - log_k[upperHull[i - 1]])) && (i == u - 1 || log_kDist[upperHull[i + 1]] <= log_kDist[upperHull[i]] + cur_m * (log_k[upperHull[i + 1]] - log_k[upperHull[i]]))) {
double cur_error = ssqerr(k_0, settings.k_max, log_k, log_kDist, cur_m, cur_t);
- if (cur_error < upp_error) {
+ if(cur_error < upp_error) {
upp_error = cur_error;
upp_m = cur_m;
upp_t = cur_t;
@@ -683,12 +688,12 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
}
// check proof of bisection search
- if (!(i > 0 && log_kDist[upperHull[i - 1]] > log_kDist[upperHull[i]] - cur_m * (log_k[upperHull[i]] - log_k[upperHull[i - 1]])) && !is_left) {
+ if(!(i > 0 && log_kDist[upperHull[i - 1]] > log_kDist[upperHull[i]] - cur_m * (log_k[upperHull[i]] - log_k[upperHull[i - 1]])) && !is_left) {
// warning("ERROR upper: The bisection search will not work properly !"
// +
// "\n" + Util.format(log_kDist));
}
- if (!(i < u - 1 && log_kDist[upperHull[i + 1]] > log_kDist[upperHull[i]] + cur_m * (log_k[upperHull[i + 1]] - log_k[upperHull[i]]))) {
+ if(!(i < u - 1 && log_kDist[upperHull[i + 1]] > log_kDist[upperHull[i]] + cur_m * (log_k[upperHull[i + 1]] - log_k[upperHull[i]]))) {
is_left = false;
}
}
@@ -703,7 +708,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @return a new leaf node
*/
@Override
- protected MkCoPTreeNode<O, D> createNewLeafNode() {
+ protected MkCoPTreeNode<O> createNewLeafNode() {
return new MkCoPTreeNode<>(leafCapacity, true);
}
@@ -713,7 +718,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @return a new directory node
*/
@Override
- protected MkCoPTreeNode<O, D> createNewDirectoryNode() {
+ protected MkCoPTreeNode<O> createNewDirectoryNode() {
return new MkCoPTreeNode<>(dirCapacity, false);
}
@@ -726,7 +731,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* the routing object of the parent node
*/
@Override
- protected MkCoPEntry createNewDirectoryEntry(MkCoPTreeNode<O, D> node, DBID routingObjectID, double parentDistance) {
+ protected MkCoPEntry createNewDirectoryEntry(MkCoPTreeNode<O> node, DBID routingObjectID, double parentDistance) {
return new MkCoPDirectoryEntry(routingObjectID, parentDistance, node.getPageID(), node.coveringRadius(routingObjectID, this), null);
// node.conservativeKnnDistanceApproximation(k_max));
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeIndex.java
index 96def76b..1cce0a01 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
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
@@ -36,8 +36,6 @@ import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery;
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.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
import de.lmu.ifi.dbs.elki.index.RKNNIndex;
import de.lmu.ifi.dbs.elki.index.RangeIndex;
@@ -52,9 +50,8 @@ import de.lmu.ifi.dbs.elki.persistent.PageFile;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class MkCoPTreeIndex<O, D extends NumberDistance<D, ?>> extends MkCoPTree<O, D> implements RangeIndex<O>, KNNIndex<O>, RKNNIndex<O> {
+public class MkCoPTreeIndex<O> extends MkCoPTree<O> implements RangeIndex<O>, KNNIndex<O>, RKNNIndex<O> {
/**
* Relation indexed
*/
@@ -67,7 +64,7 @@ public class MkCoPTreeIndex<O, D extends NumberDistance<D, ?>> extends MkCoPTree
* @param pageFile Page file
* @param settings Tree settings
*/
- public MkCoPTreeIndex(Relation<O> relation, PageFile<MkCoPTreeNode<O, D>> pageFile, MkTreeSettings<O, D, MkCoPTreeNode<O, D>, MkCoPEntry> settings) {
+ public MkCoPTreeIndex(Relation<O> relation, PageFile<MkCoPTreeNode<O>> pageFile, MkTreeSettings<O, MkCoPTreeNode<O>, MkCoPEntry> settings) {
super(relation, pageFile, settings);
this.relation = relation;
}
@@ -89,7 +86,7 @@ public class MkCoPTreeIndex<O, D extends NumberDistance<D, ?>> extends MkCoPTree
public void initialize() {
super.initialize();
List<MkCoPEntry> objs = new ArrayList<>(relation.size());
- for (DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
DBID id = DBIDUtil.deref(iter); // FIXME: expensive
final O object = relation.get(id);
objs.add(createNewLeafEntry(id, object, Double.NaN));
@@ -97,72 +94,66 @@ public class MkCoPTreeIndex<O, D extends NumberDistance<D, ?>> extends MkCoPTree
insertAll(objs);
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> KNNQuery<O, S> getKNNQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
// Query on the relation we index
- if (distanceQuery.getRelation() != relation) {
+ if(distanceQuery.getRelation() != relation) {
return null;
}
- DistanceFunction<? super O, D> distanceFunction = (DistanceFunction<? super O, D>) distanceQuery.getDistanceFunction();
- if (!this.getDistanceFunction().equals(distanceFunction)) {
- if (getLogger().isDebugging()) {
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
+ if(!this.getDistanceFunction().equals(distanceFunction)) {
+ if(getLogger().isDebugging()) {
getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!");
}
return null;
}
// Bulk is not yet supported
- for (Object hint : hints) {
- if (hint == DatabaseQuery.HINT_BULK) {
+ for(Object hint : hints) {
+ if(hint == DatabaseQuery.HINT_BULK) {
return null;
}
}
- DistanceQuery<O, D> dq = distanceFunction.instantiate(relation);
- return (KNNQuery<O, S>) MTreeQueryUtil.getKNNQuery(this, dq, hints);
+ return MTreeQueryUtil.getKNNQuery(this, distanceQuery, hints);
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> RangeQuery<O, S> getRangeQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
+ public RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
// Query on the relation we index
- if (distanceQuery.getRelation() != relation) {
+ if(distanceQuery.getRelation() != relation) {
return null;
}
- DistanceFunction<? super O, D> distanceFunction = (DistanceFunction<? super O, D>) distanceQuery.getDistanceFunction();
- if (!this.getDistanceFunction().equals(distanceFunction)) {
- if (getLogger().isDebugging()) {
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
+ if(!this.getDistanceFunction().equals(distanceFunction)) {
+ if(getLogger().isDebugging()) {
getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!");
}
return null;
}
// Bulk is not yet supported
- for (Object hint : hints) {
- if (hint == DatabaseQuery.HINT_BULK) {
+ for(Object hint : hints) {
+ if(hint == DatabaseQuery.HINT_BULK) {
return null;
}
}
- DistanceQuery<O, D> dq = distanceFunction.instantiate(relation);
- return (RangeQuery<O, S>) MTreeQueryUtil.getRangeQuery(this, dq, hints);
+ return MTreeQueryUtil.getRangeQuery(this, distanceQuery, hints);
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> RKNNQuery<O, S> getRKNNQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
- DistanceFunction<? super O, D> distanceFunction = (DistanceFunction<? super O, D>) distanceQuery.getDistanceFunction();
- if (!this.getDistanceFunction().equals(distanceFunction)) {
- if (getLogger().isDebugging()) {
+ public RKNNQuery<O> getRKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
+ if(!this.getDistanceFunction().equals(distanceFunction)) {
+ if(getLogger().isDebugging()) {
getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!");
}
return null;
}
// Bulk is not yet supported
- for (Object hint : hints) {
- if (hint == DatabaseQuery.HINT_BULK) {
+ for(Object hint : hints) {
+ if(hint == DatabaseQuery.HINT_BULK) {
return null;
}
}
- DistanceQuery<O, D> dq = distanceFunction.instantiate(relation);
- return (RKNNQuery<O, S>) new MkTreeRKNNQuery<>(this, dq);
+ return new MkTreeRKNNQuery<>(this, distanceQuery);
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeNode.java
index 79a9c6cc..dcaa7e05 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
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.index.tree.metrical.mtreevariants.mktrees.mkcop;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
@@ -36,9 +35,8 @@ import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
* @apiviz.has MkCoPEntry oneway - - contains
*
* @param <O> object type
- * @param <D> distance type
*/
-class MkCoPTreeNode<O, D extends NumberDistance<D, ?>> extends AbstractMTreeNode<O, D, MkCoPTreeNode<O, D>, MkCoPEntry> {
+class MkCoPTreeNode<O> extends AbstractMTreeNode<O, MkCoPTreeNode<O>, MkCoPEntry> {
/**
* Serial version UID
*/
@@ -142,7 +140,7 @@ class MkCoPTreeNode<O, D extends NumberDistance<D, ?>> extends AbstractMTreeNode
}
@Override
- public void adjustEntry(MkCoPEntry entry, DBID routingObjectID, double parentDistance, AbstractMTree<O, D, MkCoPTreeNode<O, D>, MkCoPEntry, ?> mTree) {
+ public void adjustEntry(MkCoPEntry entry, DBID routingObjectID, double parentDistance, AbstractMTree<O, MkCoPTreeNode<O>, MkCoPEntry, ?> mTree) {
super.adjustEntry(entry, routingObjectID, parentDistance, mTree);
// adjust conservative distance approximation
// int k_max = ((MkCoPTree<O,D>) mTree).getK_max();
@@ -150,11 +148,11 @@ class MkCoPTreeNode<O, D extends NumberDistance<D, ?>> extends AbstractMTreeNode
}
@Override
- protected void integrityCheckParameters(MkCoPEntry parentEntry, MkCoPTreeNode<O, D> parent, int index, AbstractMTree<O, D, MkCoPTreeNode<O, D>, MkCoPEntry, ?> mTree) {
+ protected void integrityCheckParameters(MkCoPEntry parentEntry, MkCoPTreeNode<O> parent, int index, AbstractMTree<O, MkCoPTreeNode<O>, MkCoPEntry, ?> mTree) {
super.integrityCheckParameters(parentEntry, parent, index, mTree);
// test conservative approximation
MkCoPEntry entry = parent.getEntry(index);
- int k_max = ((MkCoPTree<O, D>) mTree).getK_max();
+ int k_max = ((MkCoPTree<O>) mTree).getK_max();
ApproximationLine approx = conservativeKnnDistanceApproximation(k_max);
if(!entry.getConservativeKnnDistanceApproximation().equals(approx)) {
String soll = approx.toString();
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCopTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCopTreeFactory.java
index fa7afbe2..e6b0ab12 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCopTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCopTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
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.index.tree.metrical.mtreevariants.mktrees.mkcop;
*/
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeFactory;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.MkTreeSettings;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
@@ -44,9 +43,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* @apiviz.uses MkCoPTreeIndex oneway - - «create»
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class MkCopTreeFactory<O, D extends NumberDistance<D, ?>> extends AbstractMTreeFactory<O, D, MkCoPTreeNode<O, D>, MkCoPEntry, MkCoPTreeIndex<O, D>, MkTreeSettings<O, D, MkCoPTreeNode<O, D>, MkCoPEntry>> {
+public class MkCopTreeFactory<O> extends AbstractMTreeFactory<O, MkCoPTreeNode<O>, MkCoPEntry, MkCoPTreeIndex<O>, MkTreeSettings<O, MkCoPTreeNode<O>, MkCoPEntry>> {
/**
* Parameter for k
*/
@@ -58,17 +56,17 @@ public class MkCopTreeFactory<O, D extends NumberDistance<D, ?>> extends Abstrac
* @param pageFileFactory Data storage
* @param settings Tree settings
*/
- public MkCopTreeFactory(PageFileFactory<?> pageFileFactory, MkTreeSettings<O, D, MkCoPTreeNode<O, D>, MkCoPEntry> settings) {
+ public MkCopTreeFactory(PageFileFactory<?> pageFileFactory, MkTreeSettings<O, MkCoPTreeNode<O>, MkCoPEntry> settings) {
super(pageFileFactory, settings);
}
@Override
- public MkCoPTreeIndex<O, D> instantiate(Relation<O> relation) {
- PageFile<MkCoPTreeNode<O, D>> pagefile = makePageFile(getNodeClass());
+ public MkCoPTreeIndex<O> instantiate(Relation<O> relation) {
+ PageFile<MkCoPTreeNode<O>> pagefile = makePageFile(getNodeClass());
return new MkCoPTreeIndex<>(relation, pagefile, settings);
}
- protected Class<MkCoPTreeNode<O, D>> getNodeClass() {
+ protected Class<MkCoPTreeNode<O>> getNodeClass() {
return ClassGenericsUtil.uglyCastIntoSubclass(MkCoPTreeNode.class);
}
@@ -78,8 +76,10 @@ public class MkCopTreeFactory<O, D extends NumberDistance<D, ?>> extends Abstrac
* @author Erich Schubert
*
* @apiviz.exclude
+ *
+ * @param <O> Object type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractMTreeFactory.Parameterizer<O, D, MkCoPTreeNode<O, D>, MkCoPEntry, MkTreeSettings<O, D, MkCoPTreeNode<O, D>, MkCoPEntry>> {
+ public static class Parameterizer<O> extends AbstractMTreeFactory.Parameterizer<O, MkCoPTreeNode<O>, MkCoPEntry, MkTreeSettings<O, MkCoPTreeNode<O>, MkCoPEntry>> {
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
@@ -91,12 +91,12 @@ public class MkCopTreeFactory<O, D extends NumberDistance<D, ?>> extends Abstrac
}
@Override
- protected MkCopTreeFactory<O, D> makeInstance() {
+ protected MkCopTreeFactory<O> makeInstance() {
return new MkCopTreeFactory<>(pageFileFactory, settings);
}
@Override
- protected MkTreeSettings<O, D, MkCoPTreeNode<O, D>, MkCoPEntry> makeSettings() {
+ protected MkTreeSettings<O, MkCoPTreeNode<O>, MkCoPEntry> makeSettings() {
return new MkTreeSettings<>();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/package-info.java
index c767c565..4adea565 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/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/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxDirectoryEntry.java
index b3e39ca0..1cd28215 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax;
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
@@ -57,7 +57,7 @@ class MkMaxDirectoryEntry extends MTreeDirectoryEntry implements MkMaxEntry {
}
/**
- * Provides a new MkMaxDirectoryEntry with the given parameters.
+ * Constructor.
*
* @param objectID the id of the routing object
* @param parentDistance the distance from the routing object of this entry to
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxEntry.java
index 9e5133c9..5db6d22c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax;
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/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxLeafEntry.java
index d49f18ec..274e6a68 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax;
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
@@ -56,7 +56,7 @@ class MkMaxLeafEntry extends MTreeLeafEntry implements MkMaxEntry {
}
/**
- * Provides a new MkMaxLeafEntry with the given parameters.
+ * Constructor.
*
* @param objectID the id of the underlying data object
* @param parentDistance the distance from the underlying data object to its
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTree.java
index e3e4f71f..d099533b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax;
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,20 +30,18 @@ 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.DBIDRef;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.AbstractMkTreeUnified;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.MkTreeSettings;
import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
/**
@@ -57,9 +55,8 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
* @apiviz.has MkMaxTreeNode oneway - - contains
*
* @param <O> the type of DatabaseObject to be stored in the MkMaxTree
- * @param <D> the type of Distance used in the MkMaxTree
*/
-public class MkMaxTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTreeUnified<O, D, MkMaxTreeNode<O, D>, MkMaxEntry, MkTreeSettings<O, D, MkMaxTreeNode<O, D>, MkMaxEntry>> {
+public class MkMaxTree<O> extends AbstractMkTreeUnified<O, MkMaxTreeNode<O>, MkMaxEntry, MkTreeSettings<O, MkMaxTreeNode<O>, MkMaxEntry>> {
/**
* The logger for this class.
*/
@@ -72,7 +69,7 @@ public class MkMaxTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @param pagefile Page file
* @param settings Tree settings
*/
- public MkMaxTree(Relation<O> relation, PageFile<MkMaxTreeNode<O, D>> pagefile, MkTreeSettings<O, D, MkMaxTreeNode<O, D>, MkMaxEntry> settings) {
+ public MkMaxTree(Relation<O> relation, PageFile<MkMaxTreeNode<O>> pagefile, MkTreeSettings<O, MkMaxTreeNode<O>, MkMaxEntry> settings) {
super(relation, pagefile, settings);
}
@@ -83,13 +80,13 @@ public class MkMaxTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* in a second step.
*/
@Override
- public DistanceDBIDList<D> reverseKNNQuery(DBIDRef id, int k) {
+ public DoubleDBIDList reverseKNNQuery(DBIDRef id, int k) {
if (k > this.getKmax()) {
throw new IllegalArgumentException("Parameter k has to be equal or less than " + "parameter k of the MkMax-Tree!");
}
// get the candidates
- GenericDistanceDBIDList<D> candidates = new GenericDistanceDBIDList<>();
+ ModifiableDoubleDBIDList candidates = DBIDUtil.newDistanceDBIDList();
doReverseKNNQuery(id, getRoot(), null, candidates);
if (k == this.getKmax()) {
@@ -105,15 +102,15 @@ public class MkMaxTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
for (DBIDIter candidate = candidates.iter(); candidate.valid(); candidate.advance()) {
candidateIDs.add(candidate);
}
- Map<DBID, KNNList<D>> knnLists = batchNN(getRoot(), candidateIDs, k);
+ Map<DBID, KNNList> knnLists = batchNN(getRoot(), candidateIDs, k);
- GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>();
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
for (DBIDIter iter = candidateIDs.iter(); iter.valid(); iter.advance()) {
DBID cid = DBIDUtil.deref(iter);
- KNNList<D> cands = knnLists.get(cid);
- for (DistanceDBIDListIter<D> iter2 = cands.iter(); iter2.valid(); iter2.advance()) {
+ KNNList cands = knnLists.get(cid);
+ for (DoubleDBIDListIter iter2 = cands.iter(); iter2.valid(); iter2.advance()) {
if (DBIDUtil.equal(id, iter2)) {
- result.add(iter2.getDistance(), cid);
+ result.add(iter2.doubleValue(), cid);
break;
}
}
@@ -132,7 +129,7 @@ public class MkMaxTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
*/
@Override
protected void preInsert(MkMaxEntry entry) {
- KNNHeap<D> knns_o = DBIDUtil.newHeap(getDistanceFactory(), getKmax());
+ KNNHeap knns_o = DBIDUtil.newHeap(getKmax());
preInsert(entry, getRootEntry(), knns_o);
}
@@ -140,13 +137,13 @@ public class MkMaxTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* Adjusts the knn distance in the subtree of the specified root entry.
*/
@Override
- protected void kNNdistanceAdjustment(MkMaxEntry entry, Map<DBID, KNNList<D>> knnLists) {
- MkMaxTreeNode<O, D> node = getNode(entry);
+ protected void kNNdistanceAdjustment(MkMaxEntry entry, Map<DBID, KNNList> knnLists) {
+ MkMaxTreeNode<O> node = getNode(entry);
double knnDist_node = 0.;
if (node.isLeaf()) {
for (int i = 0; i < node.getNumEntries(); i++) {
MkMaxEntry leafEntry = node.getEntry(i);
- leafEntry.setKnnDistance(knnLists.get(leafEntry.getRoutingObjectID()).getKNNDistance().doubleValue());
+ leafEntry.setKnnDistance(knnLists.get(leafEntry.getRoutingObjectID()).getKNNDistance());
knnDist_node = Math.max(knnDist_node, leafEntry.getKnnDistance());
}
} else {
@@ -170,13 +167,13 @@ public class MkMaxTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @param node_entry the entry representing the node
* @param result the list for the query result
*/
- private void doReverseKNNQuery(DBIDRef q, MkMaxTreeNode<O, D> node, MkMaxEntry node_entry, ModifiableDistanceDBIDList<D> result) {
+ private void doReverseKNNQuery(DBIDRef q, MkMaxTreeNode<O> node, MkMaxEntry node_entry, ModifiableDoubleDBIDList result) {
// data node
if (node.isLeaf()) {
for (int i = 0; i < node.getNumEntries(); i++) {
MkMaxEntry entry = node.getEntry(i);
- D distance = distance(entry.getRoutingObjectID(), q);
- if (distance.doubleValue() <= entry.getKnnDistance()) {
+ double distance = distance(entry.getRoutingObjectID(), q);
+ if (distance <= entry.getKnnDistance()) {
result.add(distance, entry.getRoutingObjectID());
}
}
@@ -188,11 +185,11 @@ public class MkMaxTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
MkMaxEntry entry = node.getEntry(i);
double node_knnDist = node_entry != null ? node_entry.getKnnDistance() : Double.POSITIVE_INFINITY;
- double distance = distance(entry.getRoutingObjectID(), q).doubleValue();
+ double distance = distance(entry.getRoutingObjectID(), q);
double minDist = (entry.getCoveringRadius() > distance) ? 0.0 : distance - entry.getCoveringRadius();
if (minDist <= node_knnDist) {
- MkMaxTreeNode<O, D> childNode = getNode(entry);
+ MkMaxTreeNode<O> childNode = getNode(entry);
doReverseKNNQuery(q, childNode, entry, result);
}
}
@@ -206,39 +203,39 @@ public class MkMaxTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @param nodeEntry the entry representing the root of the current subtree
* @param knns_q the knns of q
*/
- private void preInsert(MkMaxEntry q, MkMaxEntry nodeEntry, KNNHeap<D> knns_q) {
+ private void preInsert(MkMaxEntry q, MkMaxEntry nodeEntry, KNNHeap knns_q) {
if (LOG.isDebugging()) {
LOG.debugFine("preInsert " + q + " - " + nodeEntry + "\n");
}
- double knnDist_q = knns_q.getKNNDistance().doubleValue();
- MkMaxTreeNode<O, D> node = getNode(nodeEntry);
+ double knnDist_q = knns_q.getKNNDistance();
+ MkMaxTreeNode<O> node = getNode(nodeEntry);
double knnDist_node = 0.;
// leaf node
if (node.isLeaf()) {
for (int i = 0; i < node.getNumEntries(); i++) {
MkMaxEntry p = node.getEntry(i);
- D dist_pq = distance(p.getRoutingObjectID(), q.getRoutingObjectID());
+ double dist_pq = distance(p.getRoutingObjectID(), q.getRoutingObjectID());
// p is nearer to q than the farthest kNN-candidate of q
// ==> p becomes a knn-candidate
- if (dist_pq.doubleValue() <= knnDist_q) {
+ if (dist_pq <= knnDist_q) {
knns_q.insert(dist_pq, p.getRoutingObjectID());
if (knns_q.size() >= getKmax()) {
- knnDist_q = knns_q.getKNNDistance().doubleValue();
+ knnDist_q = knns_q.getKNNDistance();
q.setKnnDistance(knnDist_q);
}
}
// p is nearer to q than to its farthest knn-candidate
// q becomes knn of p
- if (dist_pq.doubleValue() <= p.getKnnDistance()) {
- KNNList<D> knns_p = knnq.getKNNForDBID(p.getRoutingObjectID(), getKmax() - 1);
+ if (dist_pq <= p.getKnnDistance()) {
+ KNNList knns_p = knnq.getKNNForDBID(p.getRoutingObjectID(), getKmax() - 1);
if (knns_p.size() + 1 < getKmax()) {
p.setKnnDistance(Double.NaN);
} else {
- double knnDist_p = Math.max(dist_pq.doubleValue(), knns_p.getKNNDistance().doubleValue());
+ double knnDist_p = Math.max(dist_pq, knns_p.getKNNDistance());
p.setKnnDistance(knnDist_p);
}
}
@@ -254,7 +251,7 @@ public class MkMaxTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
if (distEntry.second < entry_knnDist || distEntry.second < knnDist_q) {
preInsert(q, dirEntry, knns_q);
- knnDist_q = knns_q.getKNNDistance().doubleValue();
+ knnDist_q = knns_q.getKNNDistance();
}
knnDist_node = Math.max(knnDist_node, dirEntry.getKnnDistance());
}
@@ -305,7 +302,7 @@ public class MkMaxTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @return a new MkMaxTreeNode which is a leaf node
*/
@Override
- protected MkMaxTreeNode<O, D> createNewLeafNode() {
+ protected MkMaxTreeNode<O> createNewLeafNode() {
return new MkMaxTreeNode<>(leafCapacity, true);
}
@@ -313,7 +310,7 @@ public class MkMaxTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @return a new MkMaxTreeNode which is a directory node
*/
@Override
- protected MkMaxTreeNode<O, D> createNewDirectoryNode() {
+ protected MkMaxTreeNode<O> createNewDirectoryNode() {
return new MkMaxTreeNode<>(dirCapacity, false);
}
@@ -321,7 +318,7 @@ public class MkMaxTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @return a new MkMaxDirectoryEntry representing the specified node
*/
@Override
- protected MkMaxEntry createNewDirectoryEntry(MkMaxTreeNode<O, D> node, DBID routingObjectID, double parentDistance) {
+ protected MkMaxEntry createNewDirectoryEntry(MkMaxTreeNode<O> node, DBID routingObjectID, double parentDistance) {
return new MkMaxDirectoryEntry(routingObjectID, parentDistance, node.getPageID(), node.coveringRadius(routingObjectID, this), node.kNNDistance());
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeFactory.java
index a03006f4..0838e6b6 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax;
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.index.tree.metrical.mtreevariants.mktrees.mkmax;
*/
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.AbstractMkTreeUnifiedFactory;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.MkTreeSettings;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
@@ -40,26 +39,25 @@ import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
* @apiviz.uses MkMaxTreeIndex oneway - - «create»
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class MkMaxTreeFactory<O, D extends NumberDistance<D, ?>> extends AbstractMkTreeUnifiedFactory<O, D, MkMaxTreeNode<O, D>, MkMaxEntry, MkMaxTreeIndex<O, D>, MkTreeSettings<O, D, MkMaxTreeNode<O, D>, MkMaxEntry>> {
+public class MkMaxTreeFactory<O> extends AbstractMkTreeUnifiedFactory<O, MkMaxTreeNode<O>, MkMaxEntry, MkMaxTreeIndex<O>, MkTreeSettings<O, MkMaxTreeNode<O>, MkMaxEntry>> {
/**
* Constructor.
*
* @param pageFileFactory Data storage
* @param settings Tree settings
*/
- public MkMaxTreeFactory(PageFileFactory<?> pageFileFactory, MkTreeSettings<O, D, MkMaxTreeNode<O, D>, MkMaxEntry> settings) {
+ public MkMaxTreeFactory(PageFileFactory<?> pageFileFactory, MkTreeSettings<O, MkMaxTreeNode<O>, MkMaxEntry> settings) {
super(pageFileFactory, settings);
}
@Override
- public MkMaxTreeIndex<O, D> instantiate(Relation<O> relation) {
- PageFile<MkMaxTreeNode<O, D>> pagefile = makePageFile(getNodeClass());
+ public MkMaxTreeIndex<O> instantiate(Relation<O> relation) {
+ PageFile<MkMaxTreeNode<O>> pagefile = makePageFile(getNodeClass());
return new MkMaxTreeIndex<>(relation, pagefile, settings);
}
- protected Class<MkMaxTreeNode<O, D>> getNodeClass() {
+ protected Class<MkMaxTreeNode<O>> getNodeClass() {
return ClassGenericsUtil.uglyCastIntoSubclass(MkMaxTreeNode.class);
}
@@ -69,15 +67,17 @@ public class MkMaxTreeFactory<O, D extends NumberDistance<D, ?>> extends Abstrac
* @author Erich Schubert
*
* @apiviz.exclude
+ *
+ * @param <O> Object type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractMkTreeUnifiedFactory.Parameterizer<O, D, MkMaxTreeNode<O, D>, MkMaxEntry, MkTreeSettings<O, D, MkMaxTreeNode<O, D>, MkMaxEntry>> {
+ public static class Parameterizer<O> extends AbstractMkTreeUnifiedFactory.Parameterizer<O, MkMaxTreeNode<O>, MkMaxEntry, MkTreeSettings<O, MkMaxTreeNode<O>, MkMaxEntry>> {
@Override
- protected MkMaxTreeFactory<O, D> makeInstance() {
+ protected MkMaxTreeFactory<O> makeInstance() {
return new MkMaxTreeFactory<>(pageFileFactory, settings);
}
@Override
- protected MkTreeSettings<O, D, MkMaxTreeNode<O, D>, MkMaxEntry> makeSettings() {
+ protected MkTreeSettings<O, MkMaxTreeNode<O>, MkMaxEntry> makeSettings() {
return new MkTreeSettings<>();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeIndex.java
index 482c86eb..4468e8b3 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax;
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,7 +31,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.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
@@ -39,8 +39,6 @@ import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery;
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.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.DynamicIndex;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
import de.lmu.ifi.dbs.elki.index.RKNNIndex;
@@ -58,9 +56,8 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
* @author Elke Achtert
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class MkMaxTreeIndex<O, D extends NumberDistance<D, ?>> extends MkMaxTree<O, D> implements RangeIndex<O>, KNNIndex<O>, RKNNIndex<O>, DynamicIndex {
+public class MkMaxTreeIndex<O> extends MkMaxTree<O> implements RangeIndex<O>, KNNIndex<O>, RKNNIndex<O>, DynamicIndex {
/**
* Relation indexed.
*/
@@ -73,7 +70,7 @@ public class MkMaxTreeIndex<O, D extends NumberDistance<D, ?>> extends MkMaxTree
* @param pagefile Page file
* @param settings Tree settings
*/
- public MkMaxTreeIndex(Relation<O> relation, PageFile<MkMaxTreeNode<O, D>> pagefile, MkTreeSettings<O, D, MkMaxTreeNode<O, D>, MkMaxEntry> settings) {
+ public MkMaxTreeIndex(Relation<O> relation, PageFile<MkMaxTreeNode<O>> pagefile, MkTreeSettings<O, MkMaxTreeNode<O>, MkMaxEntry> settings) {
super(relation, pagefile, settings);
this.relation = relation;
}
@@ -82,8 +79,8 @@ public class MkMaxTreeIndex<O, D extends NumberDistance<D, ?>> extends MkMaxTree
* @return a new MkMaxLeafEntry representing the specified data object
*/
protected MkMaxLeafEntry createNewLeafEntry(DBID id, O object, double parentDistance) {
- KNNList<D> knns = knnq.getKNNForObject(object, getKmax() - 1);
- double knnDistance = knns.getKNNDistance().doubleValue();
+ KNNList knns = knnq.getKNNForObject(object, getKmax() - 1);
+ double knnDistance = knns.getKNNDistance();
return new MkMaxLeafEntry(id, parentDistance, knnDistance);
}
@@ -133,14 +130,13 @@ public class MkMaxTreeIndex<O, D extends NumberDistance<D, ?>> extends MkMaxTree
throw new NotImplementedException(ExceptionMessages.UNSUPPORTED_NOT_YET);
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> KNNQuery<O, S> getKNNQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
// Query on the relation we index
if (distanceQuery.getRelation() != relation) {
return null;
}
- DistanceFunction<? super O, D> distanceFunction = (DistanceFunction<? super O, D>) distanceQuery.getDistanceFunction();
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
if (!this.getDistanceFunction().equals(distanceFunction)) {
if (getLogger().isDebugging()) {
getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!");
@@ -153,18 +149,16 @@ public class MkMaxTreeIndex<O, D extends NumberDistance<D, ?>> extends MkMaxTree
return null;
}
}
- DistanceQuery<O, D> dq = distanceFunction.instantiate(relation);
- return (KNNQuery<O, S>) MTreeQueryUtil.getKNNQuery(this, dq, hints);
+ return MTreeQueryUtil.getKNNQuery(this, distanceQuery, hints);
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> RangeQuery<O, S> getRangeQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
+ public RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
// Query on the relation we index
if (distanceQuery.getRelation() != relation) {
return null;
}
- DistanceFunction<? super O, D> distanceFunction = (DistanceFunction<? super O, D>) distanceQuery.getDistanceFunction();
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
if (!this.getDistanceFunction().equals(distanceFunction)) {
if (getLogger().isDebugging()) {
getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!");
@@ -177,14 +171,12 @@ public class MkMaxTreeIndex<O, D extends NumberDistance<D, ?>> extends MkMaxTree
return null;
}
}
- DistanceQuery<O, D> dq = distanceFunction.instantiate(relation);
- return (RangeQuery<O, S>) MTreeQueryUtil.getRangeQuery(this, dq);
+ return MTreeQueryUtil.getRangeQuery(this, distanceQuery);
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> RKNNQuery<O, S> getRKNNQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
- DistanceFunction<? super O, D> distanceFunction = (DistanceFunction<? super O, D>) distanceQuery.getDistanceFunction();
+ public RKNNQuery<O> getRKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
if (!this.getDistanceFunction().equals(distanceFunction)) {
if (getLogger().isDebugging()) {
getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!");
@@ -197,8 +189,7 @@ public class MkMaxTreeIndex<O, D extends NumberDistance<D, ?>> extends MkMaxTree
return null;
}
}
- DistanceQuery<O, D> dq = distanceFunction.instantiate(relation);
- return (RKNNQuery<O, S>) new MkTreeRKNNQuery<>(this, dq);
+ return new MkTreeRKNNQuery<>(this, distanceQuery);
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeNode.java
index 84c8bdc4..0f9588aa 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax;
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.index.tree.metrical.mtreevariants.mktrees.mkmax;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
@@ -36,9 +35,8 @@ import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
* @apiviz.has MkMaxEntry oneway - - contains
*
* @param <O> the type of DatabaseObject to be stored in the MkMaxTree
- * @param <D> the type of Distance used in the MkMaxTree
*/
-class MkMaxTreeNode<O, D extends NumberDistance<D, ?>> extends AbstractMTreeNode<O, D, MkMaxTreeNode<O, D>, MkMaxEntry> {
+class MkMaxTreeNode<O> extends AbstractMTreeNode<O, MkMaxTreeNode<O>, MkMaxEntry> {
/**
* Serial version
*/
@@ -70,7 +68,7 @@ class MkMaxTreeNode<O, D extends NumberDistance<D, ?>> extends AbstractMTreeNode
*/
protected double kNNDistance() {
double knnDist = 0.;
- for (int i = 0; i < getNumEntries(); i++) {
+ for(int i = 0; i < getNumEntries(); i++) {
MkMaxEntry entry = getEntry(i);
knnDist = Math.max(knnDist, entry.getKnnDistance());
}
@@ -83,7 +81,7 @@ class MkMaxTreeNode<O, D extends NumberDistance<D, ?>> extends AbstractMTreeNode
* all its entries.
*/
@Override
- public void adjustEntry(MkMaxEntry entry, DBID routingObjectID, double parentDistance, AbstractMTree<O, D, MkMaxTreeNode<O, D>, MkMaxEntry, ?> mTree) {
+ public void adjustEntry(MkMaxEntry entry, DBID routingObjectID, double parentDistance, AbstractMTree<O, MkMaxTreeNode<O>, MkMaxEntry, ?> mTree) {
super.adjustEntry(entry, routingObjectID, parentDistance, mTree);
// adjust knn distance
entry.setKnnDistance(kNNDistance());
@@ -94,12 +92,12 @@ class MkMaxTreeNode<O, D extends NumberDistance<D, ?>> extends AbstractMTreeNode
* node is correctly set.
*/
@Override
- protected void integrityCheckParameters(MkMaxEntry parentEntry, MkMaxTreeNode<O, D> parent, int index, AbstractMTree<O, D, MkMaxTreeNode<O, D>, MkMaxEntry, ?> mTree) {
+ protected void integrityCheckParameters(MkMaxEntry parentEntry, MkMaxTreeNode<O> parent, int index, AbstractMTree<O, MkMaxTreeNode<O>, MkMaxEntry, ?> mTree) {
super.integrityCheckParameters(parentEntry, parent, index, mTree);
// test if knn distance is correctly set
MkMaxEntry entry = parent.getEntry(index);
double knnDistance = kNNDistance();
- if (Math.abs(entry.getKnnDistance() - knnDistance) > 0) {
+ if(Math.abs(entry.getKnnDistance() - knnDistance) > 0) {
throw new RuntimeException("Wrong knnDistance in node " + parent.getPageID() + " at index " + index + " (child " + entry + ")" + "\nsoll: " + knnDistance + ",\n ist: " + entry.getKnnDistance());
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/package-info.java
index 7bd90d66..5b368d2e 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/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/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabDirectoryEntry.java
index 9f088448..c8c9e040 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab;
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
@@ -53,7 +53,7 @@ class MkTabDirectoryEntry extends MTreeDirectoryEntry implements MkTabEntry {
}
/**
- * Provides a new MkMaxDirectoryEntry with the given parameters.
+ * Constructor.
*
* @param objectID the id of the routing object
* @param parentDistance the distance from the routing object of this entry to
@@ -113,7 +113,6 @@ class MkTabDirectoryEntry extends MTreeDirectoryEntry implements MkTabEntry {
* cannot be found.
*/
@Override
- @SuppressWarnings("unchecked")
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
super.readExternal(in);
int k_max = in.readInt();
@@ -132,7 +131,6 @@ class MkTabDirectoryEntry extends MTreeDirectoryEntry implements MkTabEntry {
* knnDistances as this entry.
*/
@Override
- @SuppressWarnings("unchecked")
public boolean equals(Object o) {
if (this == o) {
return true;
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabEntry.java
index a741ed5b..f8e48f2a 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab;
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/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabLeafEntry.java
index 969ba781..122d031e 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab;
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
@@ -53,7 +53,7 @@ class MkTabLeafEntry extends MTreeLeafEntry implements MkTabEntry {
}
/**
- * Provides a new MkMaxLeafEntry with the given parameters.
+ * Constructor.
*
* @param objectID the id of the underlying data object
* @param parentDistance the distance from the underlying data object to its
@@ -115,7 +115,6 @@ class MkTabLeafEntry extends MTreeLeafEntry implements MkTabEntry {
* cannot be found.
*/
@Override
- @SuppressWarnings("unchecked")
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
super.readExternal(in);
int k_max = in.readInt();
@@ -133,7 +132,6 @@ class MkTabLeafEntry extends MTreeLeafEntry implements MkTabEntry {
* and has the same parameter k_max and knnDistances as this entry.
*/
@Override
- @SuppressWarnings("unchecked")
public boolean equals(Object o) {
if (this == o) {
return true;
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTree.java
index 481392cb..3a377420 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab;
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,17 +27,17 @@ import java.util.Map;
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.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.AbstractMkTreeUnified;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.MkTreeSettings;
import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
/**
* MkTabTree is a metrical index structure based on the concepts of the M-Tree
@@ -50,9 +50,8 @@ import de.lmu.ifi.dbs.elki.persistent.PageFile;
* @apiviz.has MkTabTreeNode oneway - - contains
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class MkTabTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTreeUnified<O, D, MkTabTreeNode<O, D>, MkTabEntry, MkTreeSettings<O, D, MkTabTreeNode<O, D>, MkTabEntry>> {
+public class MkTabTree<O> extends AbstractMkTreeUnified<O, MkTabTreeNode<O>, MkTabEntry, MkTreeSettings<O, MkTabTreeNode<O>, MkTabEntry>> {
/**
* The logger for this class.
*/
@@ -65,7 +64,7 @@ public class MkTabTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @param pagefile Page file
* @param settings Settings
*/
- public MkTabTree(Relation<O> relation, PageFile<MkTabTreeNode<O, D>> pagefile, MkTreeSettings<O, D, MkTabTreeNode<O, D>, MkTabEntry> settings) {
+ public MkTabTree(Relation<O> relation, PageFile<MkTabTreeNode<O>> pagefile, MkTreeSettings<O, MkTabTreeNode<O>, MkTabEntry> settings) {
super(relation, pagefile, settings);
}
@@ -88,12 +87,12 @@ public class MkTabTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
}
@Override
- public DistanceDBIDList<D> reverseKNNQuery(DBIDRef id, int k) {
- if (k > this.getKmax()) {
+ public DoubleDBIDList reverseKNNQuery(DBIDRef id, int k) {
+ if(k > this.getKmax()) {
throw new IllegalArgumentException("Parameter k has to be less or equal than " + "parameter kmax of the MkTab-Tree!");
}
- GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>();
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
doReverseKNNQuery(k, id, null, getRoot(), result);
result.sort();
@@ -106,7 +105,7 @@ public class MkTabTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
// overhead = index(4), numEntries(4), id(4), isLeaf(0.125)
double overhead = 12.125;
- if (getPageSize() - overhead < 0) {
+ if(getPageSize() - overhead < 0) {
throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!");
}
@@ -114,11 +113,11 @@ public class MkTabTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
// coveringRadius + parentDistance + kmax + kmax * knnDistance) + 1
dirCapacity = (int) (getPageSize() - overhead) / (4 + 4 + distanceSize + distanceSize + 4 + getKmax() * distanceSize) + 1;
- if (dirCapacity <= 1) {
+ if(dirCapacity <= 1) {
throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!");
}
- if (dirCapacity < 10) {
+ if(dirCapacity < 10) {
LOG.warning("Page size is choosen too small! Maximum number of entries " + "in a directory node = " + (dirCapacity - 1));
}
@@ -126,34 +125,35 @@ public class MkTabTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
// kmax + kmax * knnDistance) + 1
leafCapacity = (int) (getPageSize() - overhead) / (4 + distanceSize + 4 + getKmax() * distanceSize) + 1;
- if (leafCapacity <= 1) {
+ if(leafCapacity <= 1) {
throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!");
}
- if (leafCapacity < 10) {
+ if(leafCapacity < 10) {
LOG.warning("Page size is choosen too small! Maximum number of entries " + "in a leaf node = " + (leafCapacity - 1));
}
}
@Override
- protected void kNNdistanceAdjustment(MkTabEntry entry, Map<DBID, KNNList<D>> knnLists) {
- MkTabTreeNode<O, D> node = getNode(entry);
+ protected void kNNdistanceAdjustment(MkTabEntry entry, Map<DBID, KNNList> knnLists) {
+ MkTabTreeNode<O> node = getNode(entry);
double[] knnDistances_node = initKnnDistanceList();
- if (node.isLeaf()) {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ if(node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MkTabEntry leafEntry = node.getEntry(i);
- KNNList<D> knns = knnLists.get(getPageID(leafEntry));
+ KNNList knns = knnLists.get(getPageID(leafEntry));
double[] distances = new double[knns.size()];
int j = 0;
- for (DistanceDBIDListIter<D> iter = knns.iter(); iter.valid(); iter.advance(), j++) {
- distances[i] = iter.getDistance().doubleValue();
+ for(DoubleDBIDListIter iter = knns.iter(); iter.valid(); iter.advance(), j++) {
+ distances[j] = iter.doubleValue();
}
leafEntry.setKnnDistances(distances);
// FIXME: save copy
knnDistances_node = max(knnDistances_node, leafEntry.getKnnDistances());
}
- } else {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ }
+ else {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MkTabEntry dirEntry = node.getEntry(i);
kNNdistanceAdjustment(dirEntry, knnLists);
// FIXME: save copy
@@ -164,7 +164,7 @@ public class MkTabTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
}
@Override
- protected MkTabTreeNode<O, D> createNewLeafNode() {
+ protected MkTabTreeNode<O> createNewLeafNode() {
return new MkTabTreeNode<>(leafCapacity, true);
}
@@ -174,7 +174,7 @@ public class MkTabTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @return a new directory node
*/
@Override
- protected MkTabTreeNode<O, D> createNewDirectoryNode() {
+ protected MkTabTreeNode<O> createNewDirectoryNode() {
return new MkTabTreeNode<>(dirCapacity, false);
}
@@ -187,7 +187,7 @@ public class MkTabTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* the routing object of the parent node
*/
@Override
- protected MkTabEntry createNewDirectoryEntry(MkTabTreeNode<O, D> node, DBID routingObjectID, double parentDistance) {
+ protected MkTabEntry createNewDirectoryEntry(MkTabTreeNode<O> node, DBID routingObjectID, double parentDistance) {
return new MkTabDirectoryEntry(routingObjectID, parentDistance, node.getPageID(), node.coveringRadius(routingObjectID, this), node.kNNDistances());
}
@@ -213,13 +213,13 @@ public class MkTabTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* @param node the root of the subtree
* @param result the list holding the query result
*/
- private void doReverseKNNQuery(int k, DBIDRef q, MkTabEntry node_entry, MkTabTreeNode<O, D> node, GenericDistanceDBIDList<D> result) {
+ private void doReverseKNNQuery(int k, DBIDRef q, MkTabEntry node_entry, MkTabTreeNode<O> node, ModifiableDoubleDBIDList result) {
// data node
- if (node.isLeaf()) {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ if(node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MkTabEntry entry = node.getEntry(i);
- D distance = distance(entry.getRoutingObjectID(), q);
- if (distance.doubleValue() <= entry.getKnnDistance(k)) {
+ double distance = distance(entry.getRoutingObjectID(), q);
+ if(distance <= entry.getKnnDistance(k)) {
result.add(distance, entry.getRoutingObjectID());
}
}
@@ -227,15 +227,15 @@ public class MkTabTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
// directory node
else {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MkTabEntry entry = node.getEntry(i);
double node_knnDist = node_entry != null ? node_entry.getKnnDistance(k) : Double.POSITIVE_INFINITY;
- double distance = distance(entry.getRoutingObjectID(), q).doubleValue();
+ double distance = distance(entry.getRoutingObjectID(), q);
double minDist = (entry.getCoveringRadius() > distance) ? 0. : distance - entry.getCoveringRadius();
- if (minDist <= node_knnDist) {
- MkTabTreeNode<O, D> childNode = getNode(entry);
+ if(minDist <= node_knnDist) {
+ MkTabTreeNode<O> childNode = getNode(entry);
doReverseKNNQuery(k, q, entry, childNode, result);
}
}
@@ -252,12 +252,12 @@ public class MkTabTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree
* in each index
*/
private double[] max(double[] distances1, double[] distances2) {
- if (distances1.length != distances2.length) {
+ if(distances1.length != distances2.length) {
throw new RuntimeException("different lengths!");
}
double[] result = new double[distances1.length];
- for (int i = 0; i < distances1.length; i++) {
+ for(int i = 0; i < distances1.length; i++) {
result[i] = Math.max(distances1[i], distances2[i]);
}
return result;
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeFactory.java
index 9ede76ad..565735f1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab;
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.index.tree.metrical.mtreevariants.mktrees.mktab;
*/
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.AbstractMkTreeUnifiedFactory;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.MkTreeSettings;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
@@ -40,26 +39,25 @@ import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
* @apiviz.uses MkTabTreeIndex oneway - - «create»
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class MkTabTreeFactory<O, D extends NumberDistance<D, ?>> extends AbstractMkTreeUnifiedFactory<O, D, MkTabTreeNode<O, D>, MkTabEntry, MkTabTreeIndex<O, D>, MkTreeSettings<O, D, MkTabTreeNode<O, D>, MkTabEntry>> {
+public class MkTabTreeFactory<O> extends AbstractMkTreeUnifiedFactory<O, MkTabTreeNode<O>, MkTabEntry, MkTabTreeIndex<O>, MkTreeSettings<O, MkTabTreeNode<O>, MkTabEntry>> {
/**
* Constructor.
*
* @param pageFileFactory Data storage
* @param settings Tree settings
*/
- public MkTabTreeFactory(PageFileFactory<?> pageFileFactory, MkTreeSettings<O, D, MkTabTreeNode<O, D>, MkTabEntry> settings) {
+ public MkTabTreeFactory(PageFileFactory<?> pageFileFactory, MkTreeSettings<O, MkTabTreeNode<O>, MkTabEntry> settings) {
super(pageFileFactory, settings);
}
@Override
- public MkTabTreeIndex<O, D> instantiate(Relation<O> relation) {
- PageFile<MkTabTreeNode<O, D>> pagefile = makePageFile(getNodeClass());
+ public MkTabTreeIndex<O> instantiate(Relation<O> relation) {
+ PageFile<MkTabTreeNode<O>> pagefile = makePageFile(getNodeClass());
return new MkTabTreeIndex<>(relation, pagefile, settings);
}
- protected Class<MkTabTreeNode<O, D>> getNodeClass() {
+ protected Class<MkTabTreeNode<O>> getNodeClass() {
return ClassGenericsUtil.uglyCastIntoSubclass(MkTabTreeNode.class);
}
@@ -70,14 +68,14 @@ public class MkTabTreeFactory<O, D extends NumberDistance<D, ?>> extends Abstrac
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractMkTreeUnifiedFactory.Parameterizer<O, D, MkTabTreeNode<O, D>, MkTabEntry, MkTreeSettings<O, D, MkTabTreeNode<O, D>, MkTabEntry>> {
+ public static class Parameterizer<O> extends AbstractMkTreeUnifiedFactory.Parameterizer<O, MkTabTreeNode<O>, MkTabEntry, MkTreeSettings<O, MkTabTreeNode<O>, MkTabEntry>> {
@Override
- protected MkTabTreeFactory<O, D> makeInstance() {
+ protected MkTabTreeFactory<O> makeInstance() {
return new MkTabTreeFactory<>(pageFileFactory, settings);
}
@Override
- protected MkTreeSettings<O, D, MkTabTreeNode<O, D>, MkTabEntry> makeSettings() {
+ protected MkTreeSettings<O, MkTabTreeNode<O>, MkTabEntry> makeSettings() {
return new MkTreeSettings<>();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeIndex.java
index 150f03e8..713514ff 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab;
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,8 @@ import java.util.List;
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.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
@@ -38,8 +38,6 @@ import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery;
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.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
import de.lmu.ifi.dbs.elki.index.RKNNIndex;
import de.lmu.ifi.dbs.elki.index.RangeIndex;
@@ -54,9 +52,8 @@ import de.lmu.ifi.dbs.elki.persistent.PageFile;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class MkTabTreeIndex<O, D extends NumberDistance<D, ?>> extends MkTabTree<O, D> implements RangeIndex<O>, KNNIndex<O>, RKNNIndex<O> {
+public class MkTabTreeIndex<O> extends MkTabTree<O> implements RangeIndex<O>, KNNIndex<O>, RKNNIndex<O> {
/**
* The relation indexed.
*/
@@ -69,7 +66,7 @@ public class MkTabTreeIndex<O, D extends NumberDistance<D, ?>> extends MkTabTree
* @param pagefile Page file
* @param settings Tree settings
*/
- public MkTabTreeIndex(Relation<O> relation, PageFile<MkTabTreeNode<O, D>> pagefile, MkTreeSettings<O, D, MkTabTreeNode<O, D>, MkTabEntry> settings) {
+ public MkTabTreeIndex(Relation<O> relation, PageFile<MkTabTreeNode<O>> pagefile, MkTreeSettings<O, MkTabTreeNode<O>, MkTabEntry> settings) {
super(relation, pagefile, settings);
this.relation = relation;
}
@@ -93,11 +90,11 @@ public class MkTabTreeIndex<O, D extends NumberDistance<D, ?>> extends MkTabTree
* @return the knn distance of the object with the specified id
*/
private double[] knnDistances(O object) {
- KNNList<D> knns = knnq.getKNNForObject(object, getKmax() - 1);
+ KNNList knns = knnq.getKNNForObject(object, getKmax() - 1);
double[] distances = new double[getKmax()];
int i = 0;
- for (DistanceDBIDListIter<D> iter = knns.iter(); iter.valid() && i < getKmax(); iter.advance(), i++) {
- distances[i] = iter.getDistance().doubleValue();
+ for (DoubleDBIDListIter iter = knns.iter(); iter.valid() && i < getKmax(); iter.advance(), i++) {
+ distances[i] = iter.doubleValue();
}
return distances;
}
@@ -114,14 +111,13 @@ public class MkTabTreeIndex<O, D extends NumberDistance<D, ?>> extends MkTabTree
insertAll(objs);
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> KNNQuery<O, S> getKNNQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
// Query on the relation we index
if (distanceQuery.getRelation() != relation) {
return null;
}
- DistanceFunction<? super O, D> distanceFunction = (DistanceFunction<? super O, D>) distanceQuery.getDistanceFunction();
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
if (!this.getDistanceFunction().equals(distanceFunction)) {
if (getLogger().isDebugging()) {
getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!");
@@ -134,18 +130,16 @@ public class MkTabTreeIndex<O, D extends NumberDistance<D, ?>> extends MkTabTree
return null;
}
}
- DistanceQuery<O, D> dq = distanceFunction.instantiate(relation);
- return (KNNQuery<O, S>) MTreeQueryUtil.getKNNQuery(this, dq, hints);
+ return MTreeQueryUtil.getKNNQuery(this, distanceQuery, hints);
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> RangeQuery<O, S> getRangeQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
+ public RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
// Query on the relation we index
if (distanceQuery.getRelation() != relation) {
return null;
}
- DistanceFunction<? super O, D> distanceFunction = (DistanceFunction<? super O, D>) distanceQuery.getDistanceFunction();
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
if (!this.getDistanceFunction().equals(distanceFunction)) {
if (getLogger().isDebugging()) {
getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!");
@@ -158,14 +152,12 @@ public class MkTabTreeIndex<O, D extends NumberDistance<D, ?>> extends MkTabTree
return null;
}
}
- DistanceQuery<O, D> dq = distanceFunction.instantiate(relation);
- return (RangeQuery<O, S>) MTreeQueryUtil.getRangeQuery(this, dq);
+ return MTreeQueryUtil.getRangeQuery(this, distanceQuery);
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> RKNNQuery<O, S> getRKNNQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
- DistanceFunction<? super O, D> distanceFunction = (DistanceFunction<? super O, D>) distanceQuery.getDistanceFunction();
+ public RKNNQuery<O> getRKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
if (!this.getDistanceFunction().equals(distanceFunction)) {
if (getLogger().isDebugging()) {
getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!");
@@ -178,8 +170,7 @@ public class MkTabTreeIndex<O, D extends NumberDistance<D, ?>> extends MkTabTree
return null;
}
}
- DistanceQuery<O, D> dq = distanceFunction.instantiate(relation);
- return (RKNNQuery<O, S>) new MkTreeRKNNQuery<>(this, dq);
+ return new MkTreeRKNNQuery<>(this, distanceQuery);
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeNode.java
index 1942a78b..913a3261 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab;
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.index.tree.metrical.mtreevariants.mktrees.mktab;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
@@ -36,9 +35,8 @@ import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
* @apiviz.has MkTabEntry oneway - - contains
*
* @param <O> object type
- * @param <D> distance type
*/
-class MkTabTreeNode<O, D extends NumberDistance<D, ?>> extends AbstractMTreeNode<O, D, MkTabTreeNode<O, D>, MkTabEntry> {
+class MkTabTreeNode<O> extends AbstractMTreeNode<O, MkTabTreeNode<O>, MkTabEntry> {
private static final long serialVersionUID = 2;
/**
@@ -81,7 +79,7 @@ class MkTabTreeNode<O, D extends NumberDistance<D, ?>> extends AbstractMTreeNode
}
@Override
- public void adjustEntry(MkTabEntry entry, DBID routingObjectID, double parentDistance, AbstractMTree<O, D, MkTabTreeNode<O, D>, MkTabEntry, ?> mTree) {
+ public void adjustEntry(MkTabEntry entry, DBID routingObjectID, double parentDistance, AbstractMTree<O, MkTabTreeNode<O>, MkTabEntry, ?> mTree) {
super.adjustEntry(entry, routingObjectID, parentDistance, mTree);
// adjust knn distances
entry.setKnnDistances(kNNDistances());
@@ -96,7 +94,7 @@ class MkTabTreeNode<O, D extends NumberDistance<D, ?>> extends AbstractMTreeNode
* @param mTree the underlying M-Tree
*/
@Override
- protected void integrityCheckParameters(MkTabEntry parentEntry, MkTabTreeNode<O, D> parent, int index, AbstractMTree<O, D, MkTabTreeNode<O, D>, MkTabEntry, ?> mTree) {
+ protected void integrityCheckParameters(MkTabEntry parentEntry, MkTabTreeNode<O> parent, int index, AbstractMTree<O, MkTabTreeNode<O>, MkTabEntry, ?> mTree) {
super.integrityCheckParameters(parentEntry, parent, index, mTree);
// test knn distances
MkTabEntry entry = parent.getEntry(index);
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/package-info.java
index ed3e24d3..8b81f375 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/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/index/tree/metrical/mtreevariants/mktrees/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/package-info.java
index 13b23e16..976b3436 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/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/index/tree/metrical/mtreevariants/mtree/MTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTree.java
index 1b3d1481..78a8b95e 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mtree;
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.index.tree.metrical.mtreevariants.mtree;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeDirectoryEntry;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
@@ -53,12 +52,11 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
* @apiviz.has MTreeNode oneway - - contains
*
* @param <O> the type of DatabaseObject to be stored in the metrical index
- * @param <D> the type of Distance used in the metrical index
*/
@Title("M-Tree")
@Description("Efficient Access Method for Similarity Search in Metric Spaces")
@Reference(authors = "P. Ciaccia, M. Patella, P. Zezula", title = "M-tree: An Efficient Access Method for Similarity Search in Metric Spaces", booktitle = "VLDB'97, Proceedings of 23rd International Conference on Very Large Data Bases, August 25-29, 1997, Athens, Greece", url = "http://www.vldb.org/conf/1997/P426.PDF")
-abstract public class MTree<O, D extends NumberDistance<D, ?>> extends AbstractMTree<O, D, MTreeNode<O, D>, MTreeEntry, MTreeSettings<O, D, MTreeNode<O, D>, MTreeEntry>> {
+abstract public class MTree<O> extends AbstractMTree<O, MTreeNode<O>, MTreeEntry, MTreeSettings<O, MTreeNode<O>, MTreeEntry>> {
/**
* The logger for this class.
*/
@@ -70,7 +68,7 @@ abstract public class MTree<O, D extends NumberDistance<D, ?>> extends AbstractM
* @param pagefile Page file
* @param settings Tree settings
*/
- public MTree(PageFile<MTreeNode<O, D>> pagefile, MTreeSettings<O, D, MTreeNode<O, D>, MTreeEntry> settings) {
+ public MTree(PageFile<MTreeNode<O>> pagefile, MTreeSettings<O, MTreeNode<O>, MTreeEntry> settings) {
super(pagefile, settings);
}
@@ -86,7 +84,7 @@ abstract public class MTree<O, D extends NumberDistance<D, ?>> extends AbstractM
* @return a new MTreeDirectoryEntry representing the specified node
*/
@Override
- protected MTreeEntry createNewDirectoryEntry(MTreeNode<O, D> node, DBID routingObjectID, double parentDistance) {
+ protected MTreeEntry createNewDirectoryEntry(MTreeNode<O> node, DBID routingObjectID, double parentDistance) {
return new MTreeDirectoryEntry(routingObjectID, parentDistance, node.getPageID(), node.coveringRadius(routingObjectID, this));
}
@@ -103,7 +101,7 @@ abstract public class MTree<O, D extends NumberDistance<D, ?>> extends AbstractM
* @return a new MTreeNode which is a leaf node
*/
@Override
- protected MTreeNode<O, D> createNewLeafNode() {
+ protected MTreeNode<O> createNewLeafNode() {
return new MTreeNode<>(leafCapacity, true);
}
@@ -111,7 +109,7 @@ abstract public class MTree<O, D extends NumberDistance<D, ?>> extends AbstractM
* @return a new MTreeNode which is a directory node
*/
@Override
- protected MTreeNode<O, D> createNewDirectoryNode() {
+ protected MTreeNode<O> createNewDirectoryNode() {
return new MTreeNode<>(dirCapacity, false);
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeFactory.java
index dbc27511..1d6a06a6 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mtree;
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.index.tree.metrical.mtreevariants.mtree;
*/
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeFactory;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeSettings;
@@ -42,27 +41,26 @@ import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
* @apiviz.uses MTreeIndex oneway - - «create»
*
* @param <O> Object type
- * @param <D> Distance type
*/
@Alias({ "mtree", "m" })
-public class MTreeFactory<O, D extends NumberDistance<D, ?>> extends AbstractMTreeFactory<O, D, MTreeNode<O, D>, MTreeEntry, MTreeIndex<O, D>, MTreeSettings<O, D, MTreeNode<O, D>, MTreeEntry>> {
+public class MTreeFactory<O> extends AbstractMTreeFactory<O, MTreeNode<O>, MTreeEntry, MTreeIndex<O>, MTreeSettings<O, MTreeNode<O>, MTreeEntry>> {
/**
* Constructor.
*
* @param pageFileFactory Data storage
* @param settings Tree settings
*/
- public MTreeFactory(PageFileFactory<?> pageFileFactory, MTreeSettings<O, D, MTreeNode<O, D>, MTreeEntry> settings) {
+ public MTreeFactory(PageFileFactory<?> pageFileFactory, MTreeSettings<O, MTreeNode<O>, MTreeEntry> settings) {
super(pageFileFactory, settings);
}
@Override
- public MTreeIndex<O, D> instantiate(Relation<O> relation) {
- PageFile<MTreeNode<O, D>> pagefile = makePageFile(getNodeClass());
+ public MTreeIndex<O> instantiate(Relation<O> relation) {
+ PageFile<MTreeNode<O>> pagefile = makePageFile(getNodeClass());
return new MTreeIndex<>(relation, pagefile, settings);
}
- protected Class<MTreeNode<O, D>> getNodeClass() {
+ protected Class<MTreeNode<O>> getNodeClass() {
return ClassGenericsUtil.uglyCastIntoSubclass(MTreeNode.class);
}
@@ -72,15 +70,17 @@ public class MTreeFactory<O, D extends NumberDistance<D, ?>> extends AbstractMTr
* @author Erich Schubert
*
* @apiviz.exclude
+ *
+ * @param <O> Object type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractMTreeFactory.Parameterizer<O, D, MTreeNode<O, D>, MTreeEntry, MTreeSettings<O, D, MTreeNode<O, D>, MTreeEntry>> {
+ public static class Parameterizer<O> extends AbstractMTreeFactory.Parameterizer<O, MTreeNode<O>, MTreeEntry, MTreeSettings<O, MTreeNode<O>, MTreeEntry>> {
@Override
- protected MTreeFactory<O, D> makeInstance() {
+ protected MTreeFactory<O> makeInstance() {
return new MTreeFactory<>(pageFileFactory, settings);
}
@Override
- protected MTreeSettings<O, D, MTreeNode<O, D>, MTreeEntry> makeSettings() {
+ protected MTreeSettings<O, MTreeNode<O>, MTreeEntry> makeSettings() {
return new MTreeSettings<>();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeIndex.java
index 32908a1e..e5dd8972 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mtree;
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
@@ -39,8 +39,6 @@ import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
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.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.DynamicIndex;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
import de.lmu.ifi.dbs.elki.index.RangeIndex;
@@ -48,10 +46,10 @@ import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeLeafEntry;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeSettings;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.MTreeQueryUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
/**
* Class for using an m-tree as database index.
@@ -59,9 +57,8 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class MTreeIndex<O, D extends NumberDistance<D, ?>> extends MTree<O, D> implements RangeIndex<O>, KNNIndex<O>, DynamicIndex {
+public class MTreeIndex<O> extends MTree<O> implements RangeIndex<O>, KNNIndex<O>, DynamicIndex {
/**
* The relation indexed.
*/
@@ -70,7 +67,7 @@ public class MTreeIndex<O, D extends NumberDistance<D, ?>> extends MTree<O, D> i
/**
* The distance query.
*/
- protected DistanceQuery<O, D> distanceQuery;
+ protected DistanceQuery<O> distanceQuery;
/**
* Constructor.
@@ -79,16 +76,16 @@ public class MTreeIndex<O, D extends NumberDistance<D, ?>> extends MTree<O, D> i
* @param pagefile Page file
* @param settings Tree settings
*/
- public MTreeIndex(Relation<O> relation, PageFile<MTreeNode<O, D>> pagefile, MTreeSettings<O, D, MTreeNode<O, D>, MTreeEntry> settings) {
+ public MTreeIndex(Relation<O> relation, PageFile<MTreeNode<O>> pagefile, MTreeSettings<O, MTreeNode<O>, MTreeEntry> settings) {
super(pagefile, settings);
this.relation = relation;
this.distanceQuery = getDistanceFunction().instantiate(relation);
}
@Override
- public D distance(DBIDRef id1, DBIDRef id2) {
+ public double distance(DBIDRef id1, DBIDRef id2) {
if (id1 == null || id2 == null) {
- return getDistanceFactory().undefinedDistance();
+ return Double.NaN;
}
statistics.countDistanceCalculation();
return distanceQuery.distance(id1, id2);
@@ -196,14 +193,13 @@ public class MTreeIndex<O, D extends NumberDistance<D, ?>> extends MTree<O, D> i
throw new NotImplementedException(ExceptionMessages.UNSUPPORTED_NOT_YET);
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> KNNQuery<O, S> getKNNQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
// Query on the relation we index
if (distanceQuery.getRelation() != relation) {
return null;
}
- DistanceFunction<? super O, D> distanceFunction = (DistanceFunction<? super O, D>) distanceQuery.getDistanceFunction();
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
if (!this.getDistanceFunction().equals(distanceFunction)) {
if (getLogger().isDebugging()) {
getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!");
@@ -216,18 +212,17 @@ public class MTreeIndex<O, D extends NumberDistance<D, ?>> extends MTree<O, D> i
return null;
}
}
- DistanceQuery<O, D> dq = distanceFunction.instantiate(relation);
- return (KNNQuery<O, S>) MTreeQueryUtil.getKNNQuery(this, dq, hints);
+ DistanceQuery<O> dq = distanceFunction.instantiate(relation);
+ return MTreeQueryUtil.getKNNQuery(this, dq, hints);
}
- @SuppressWarnings("unchecked")
@Override
- public <S extends Distance<S>> RangeQuery<O, S> getRangeQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
+ public RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
// Query on the relation we index
if (distanceQuery.getRelation() != relation) {
return null;
}
- DistanceFunction<? super O, D> distanceFunction = (DistanceFunction<? super O, D>) distanceQuery.getDistanceFunction();
+ DistanceFunction<? super O> distanceFunction = (DistanceFunction<? super O>) distanceQuery.getDistanceFunction();
if (!this.getDistanceFunction().equals(distanceFunction)) {
if (getLogger().isDebugging()) {
getLogger().debug("Distance function not supported by index - or 'equals' not implemented right!");
@@ -240,8 +235,8 @@ public class MTreeIndex<O, D extends NumberDistance<D, ?>> extends MTree<O, D> i
return null;
}
}
- DistanceQuery<O, D> dq = distanceFunction.instantiate(relation);
- return (RangeQuery<O, S>) MTreeQueryUtil.getRangeQuery(this, dq);
+ DistanceQuery<O> dq = distanceFunction.instantiate(relation);
+ return MTreeQueryUtil.getRangeQuery(this, dq);
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeNode.java
index b3aa77fb..61dc7594 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mtree;
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.index.tree.metrical.mtreevariants.mtree;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
@@ -32,9 +31,8 @@ import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
*
* @author Elke Achtert
* @param <O> Object type
- * @param <D> Distance type
*/
-public class MTreeNode<O, D extends NumberDistance<D, ?>> extends AbstractMTreeNode<O, D, MTreeNode<O, D>, MTreeEntry> {
+public class MTreeNode<O> extends AbstractMTreeNode<O, MTreeNode<O>, MTreeEntry> {
/**
* Serial version
*/
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/package-info.java
index c10d683b..aec2fd17 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/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/index/tree/metrical/mtreevariants/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/package-info.java
index 03a4a4d6..922a299a 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/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/index/tree/metrical/mtreevariants/query/DoubleDistanceMetricalIndexKNNQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/DoubleDistanceMetricalIndexKNNQuery.java
deleted file mode 100644
index b55b9fd0..00000000
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/DoubleDistanceMetricalIndexKNNQuery.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query;
-
-/*
- 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.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.database.query.knn.AbstractDistanceKNNQuery;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.index.tree.DirectoryEntry;
-import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
-import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
-import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
-import de.lmu.ifi.dbs.elki.index.tree.query.DoubleMTreeDistanceSearchCandidate;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap;
-
-/**
- * Instance of a KNN query for a particular spatial index.
- *
- * @author Erich Schubert
- *
- * @apiviz.uses AbstractMTree
- *
- * @param <O> Object type
- */
-public class DoubleDistanceMetricalIndexKNNQuery<O> extends AbstractDistanceKNNQuery<O, DoubleDistance> {
- /**
- * The index to use
- */
- protected final AbstractMTree<O, DoubleDistance, ?, ?, ?> index;
-
- /**
- * Distance function
- */
- protected PrimitiveDoubleDistanceFunction<? super O> distf;
-
- /**
- * Constructor.
- *
- * @param index Index to use
- * @param distanceQuery Distance query used
- * @param distf Distance function
- */
- public DoubleDistanceMetricalIndexKNNQuery(AbstractMTree<O, DoubleDistance, ?, ?, ?> index, DistanceQuery<O, DoubleDistance> distanceQuery, PrimitiveDoubleDistanceFunction<? super O> distf) {
- super(distanceQuery);
- this.index = index;
- this.distf = distf;
- }
-
- @Override
- public KNNList<DoubleDistance> getKNNForObject(O q, int k) {
- if (k < 1) {
- throw new IllegalArgumentException("At least one object has to be requested!");
- }
- index.statistics.countKNNQuery();
-
- DoubleDistanceKNNHeap knnList = DBIDUtil.newDoubleDistanceHeap(k);
- double d_k = Double.POSITIVE_INFINITY;
-
- final ComparableMinHeap<DoubleMTreeDistanceSearchCandidate> pq = new ComparableMinHeap<>();
-
- // Push the root node
- pq.add(new DoubleMTreeDistanceSearchCandidate(0, index.getRootID(), null, 0));
-
- // search in tree
- while (!pq.isEmpty()) {
- DoubleMTreeDistanceSearchCandidate pqNode = pq.poll();
- DBID id_p = pqNode.routingObjectID;
- double d1 = pqNode.routingDistance;
-
- if (knnList.size() >= k && pqNode.mindist > d_k) {
- break;
- }
-
- AbstractMTreeNode<?, DoubleDistance, ?, ?> node = index.getNode(pqNode.nodeID);
-
- // directory node
- if (!node.isLeaf()) {
- for (int i = 0; i < node.getNumEntries(); i++) {
- final MTreeEntry entry = node.getEntry(i);
- final DBID id_i = entry.getRoutingObjectID();
- double or_i = entry.getCoveringRadius();
- double d2 = id_p != null ? entry.getParentDistance() : 0;
- double diff = Math.abs(d1 - d2);
-
- if (diff <= d_k + or_i) {
- final O ob_i = relation.get(id_i);
- double d3 = distf.doubleDistance(ob_i, q);
- index.statistics.countDistanceCalculation();
- double d_min = Math.max(d3 - or_i, 0);
- if (d_min <= d_k) {
- pq.add(new DoubleMTreeDistanceSearchCandidate(d_min, ((DirectoryEntry) entry).getPageID(), id_i, d3));
- }
- }
- }
- }
- // data node
- else {
- for (int i = 0; i < node.getNumEntries(); i++) {
- final MTreeEntry entry = node.getEntry(i);
- final DBID id_i = entry.getRoutingObjectID();
- double d2 = id_p != null ? entry.getParentDistance() : 0;
- double diff = Math.abs(d1 - d2);
-
- if (diff <= d_k) {
- final O o_i = relation.get(id_i);
- double d3 = distf.doubleDistance(o_i, q);
- index.statistics.countDistanceCalculation();
- if (d3 <= d_k) {
- knnList.insert(d3, id_i);
- d_k = knnList.doubleKNNDistance();
- }
- }
- }
- }
- }
- return knnList.toKNNList();
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/DoubleDistanceMetricalIndexRangeQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/DoubleDistanceMetricalIndexRangeQuery.java
deleted file mode 100644
index 714498d4..00000000
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/DoubleDistanceMetricalIndexRangeQuery.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query;
-
-/*
- 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.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPairList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDoubleDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.database.query.range.AbstractDistanceRangeQuery;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.index.tree.DirectoryEntry;
-import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
-import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
-import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
-
-/**
- * Instance of a range query for a particular spatial index.
- *
- * @author Erich Schubert
- *
- * @apiviz.uses AbstractMTree
- */
-public class DoubleDistanceMetricalIndexRangeQuery<O> extends AbstractDistanceRangeQuery<O, DoubleDistance> {
- /**
- * The index to use
- */
- protected final AbstractMTree<O, DoubleDistance, ?, ?, ?> index;
-
- /**
- * Distance function
- */
- protected PrimitiveDoubleDistanceFunction<? super O> distf;
-
- /**
- * Constructor.
- *
- * @param index Index to use
- * @param distanceQuery Distance query used
- * @param distf Distance function
- */
- public DoubleDistanceMetricalIndexRangeQuery(AbstractMTree<O, DoubleDistance, ?, ?, ?> index, DistanceQuery<O, DoubleDistance> distanceQuery, PrimitiveDoubleDistanceFunction<? super O> distf) {
- super(distanceQuery);
- this.index = index;
- this.distf = distf;
- }
-
- /**
- * Performs a range query on the specified subtree. It recursively traverses
- * all paths from the specified node, which cannot be excluded from leading to
- * qualifying objects.
- *
- * @param id_p the routing object of the specified node
- * @param node the root of the subtree to be traversed
- * @param q the query object
- * @param r_q the query range
- * @param result the list holding the query results
- */
- private void doRangeQuery(DBID id_p, AbstractMTreeNode<O, DoubleDistance, ?, ?> node, O q, double r_q, ModifiableDoubleDistanceDBIDList result) {
- final O o_p = id_p != null ? relation.get(id_p) : null;
- double d1 = 0.;
- if (id_p != null) {
- d1 = distf.doubleDistance(o_p, q);
- index.statistics.countDistanceCalculation();
- }
- if (!node.isLeaf()) {
- for (int i = 0; i < node.getNumEntries(); i++) {
- MTreeEntry entry = node.getEntry(i);
-
- double r_or = entry.getCoveringRadius();
- double d2 = id_p != null ? entry.getParentDistance() : 0;
- double diff = Math.abs(d1 - d2);
-
- double sum = r_q + r_or;
-
- if (diff <= sum) {
- DBID id_r = entry.getRoutingObjectID();
- double d3 = distf.doubleDistance(relation.get(id_r), q);
- index.statistics.countDistanceCalculation();
- if (d3 <= sum) {
- AbstractMTreeNode<O, DoubleDistance, ?, ?> child = index.getNode(((DirectoryEntry) entry).getPageID());
- doRangeQuery(id_r, child, q, r_q, result);
- }
- }
- }
- } else {
- for (int i = 0; i < node.getNumEntries(); i++) {
- MTreeEntry entry = node.getEntry(i);
-
- double d2 = id_p != null ? entry.getParentDistance() : 0;
- double diff = Math.abs(d1 - d2);
-
- if (diff <= r_q) {
- DBID id_j = entry.getRoutingObjectID();
- O o_j = relation.get(id_j);
- double d3 = distf.doubleDistance(o_j, q);
- index.statistics.countDistanceCalculation();
- if (d3 <= r_q) {
- result.add(d3, id_j);
- }
- }
- }
- }
- }
-
- @Override
- public DistanceDBIDList<DoubleDistance> getRangeForObject(O obj, DoubleDistance range) {
- final DoubleDistanceDBIDPairList result = new DoubleDistanceDBIDPairList();
-
- doRangeQuery(null, index.getRoot(), obj, range.doubleValue(), result);
- index.statistics.countRangeQuery();
- result.sort();
- return result;
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MTreeQueryUtil.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MTreeQueryUtil.java
index cc27b383..8bd0ceb0 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MTreeQueryUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MTreeQueryUtil.java
@@ -3,17 +3,13 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query;
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.query.range.RangeQuery;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-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.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
/*
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
@@ -43,23 +39,12 @@ public final class MTreeQueryUtil {
* possible.
*
* @param <O> Object type
- * @param <D> Distance type
* @param tree Tree to query
* @param distanceQuery distance query
* @param hints Optimizer hints
* @return Query object
*/
- @SuppressWarnings({ "cast", "unchecked" })
- public static <O, D extends NumberDistance<D, ?>> KNNQuery<O, D> getKNNQuery(AbstractMTree<O, D, ?, ?, ?> tree, DistanceQuery<O, D> distanceQuery, Object... hints) {
- DistanceFunction<? super O, D> df = distanceQuery.getDistanceFunction();
- // Can we use an optimized query?
- if (df instanceof PrimitiveDoubleDistanceFunction) {
- PrimitiveDoubleDistanceFunction<? super O> dfc = (PrimitiveDoubleDistanceFunction<? super O>) df;
- AbstractMTree<O, DoubleDistance, ?, ?, ?> treec = (AbstractMTree<O, DoubleDistance, ?, ?, ?>) tree;
- DistanceQuery<O, DoubleDistance> dqc = (DistanceQuery<O, DoubleDistance>) distanceQuery;
- KNNQuery<O, ?> q = new DoubleDistanceMetricalIndexKNNQuery<>(treec, dqc, dfc);
- return (KNNQuery<O, D>) q;
- }
+ public static <O> KNNQuery<O> getKNNQuery(AbstractMTree<O, ?, ?, ?> tree, DistanceQuery<O> distanceQuery, Object... hints) {
return new MetricalIndexKNNQuery<>(tree, distanceQuery);
}
@@ -68,23 +53,12 @@ public final class MTreeQueryUtil {
* possible.
*
* @param <O> Object type
- * @param <D> Distance type
* @param tree Tree to query
* @param distanceQuery distance query
* @param hints Optimizer hints
* @return Query object
*/
- @SuppressWarnings({ "cast", "unchecked" })
- public static <O, D extends NumberDistance<D, ?>> RangeQuery<O, D> getRangeQuery(AbstractMTree<O, D, ?, ?, ?> tree, DistanceQuery<O, D> distanceQuery, Object... hints) {
- DistanceFunction<? super O, D> df = distanceQuery.getDistanceFunction();
- // Can we use an optimized query?
- if (df instanceof PrimitiveDoubleDistanceFunction) {
- PrimitiveDoubleDistanceFunction<? super O> dfc = (PrimitiveDoubleDistanceFunction<? super O>) df;
- AbstractMTree<O, DoubleDistance, ?, ?, ?> treec = (AbstractMTree<O, DoubleDistance, ?, ?, ?>) tree;
- DistanceQuery<O, DoubleDistance> dqc = (DistanceQuery<O, DoubleDistance>) distanceQuery;
- RangeQuery<O, ?> q = new DoubleDistanceMetricalIndexRangeQuery<>(treec, dqc, dfc);
- return (RangeQuery<O, D>) q;
- }
+ public static <O> RangeQuery<O> getRangeQuery(AbstractMTree<O, ?, ?, ?> tree, DistanceQuery<O> distanceQuery, Object... hints) {
return new MetricalIndexRangeQuery<>(tree, distanceQuery);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexKNNQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexKNNQuery.java
index f21bac82..d839bed3 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexKNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query;
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,11 +25,10 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.AbstractDistanceKNNQuery;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.DirectoryEntry;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
@@ -43,15 +42,15 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap;
* @author Erich Schubert
*
* @apiviz.uses AbstractMTree
+ * @apiviz.uses DoubleMTreeDistanceSearchCandidate
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class MetricalIndexKNNQuery<O, D extends NumberDistance<D, ?>> extends AbstractDistanceKNNQuery<O, D> {
+public class MetricalIndexKNNQuery<O> extends AbstractDistanceKNNQuery<O> {
/**
* The index to use
*/
- protected final AbstractMTree<O, D, ?, ?, ?> index;
+ protected final AbstractMTree<O, ?, ?, ?> index;
/**
* Constructor.
@@ -59,41 +58,41 @@ public class MetricalIndexKNNQuery<O, D extends NumberDistance<D, ?>> extends Ab
* @param index Index to use
* @param distanceQuery Distance query used
*/
- public MetricalIndexKNNQuery(AbstractMTree<O, D, ?, ?, ?> index, DistanceQuery<O, D> distanceQuery) {
+ public MetricalIndexKNNQuery(AbstractMTree<O, ?, ?, ?> index, DistanceQuery<O> distanceQuery) {
super(distanceQuery);
this.index = index;
}
@Override
- public KNNList<D> getKNNForObject(O q, int k) {
- if (k < 1) {
+ public KNNList getKNNForObject(O q, int k) {
+ if(k < 1) {
throw new IllegalArgumentException("At least one object has to be requested!");
}
index.statistics.countKNNQuery();
- KNNHeap<D> knnList = DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k);
- D d_k = knnList.getKNNDistance();
+ KNNHeap knnList = DBIDUtil.newHeap(k);
+ double d_k = Double.POSITIVE_INFINITY;
final ComparableMinHeap<DoubleMTreeDistanceSearchCandidate> pq = new ComparableMinHeap<>();
- // push root
+ // Push the root node
pq.add(new DoubleMTreeDistanceSearchCandidate(0., index.getRootID(), null, 0.));
// search in tree
- while (!pq.isEmpty()) {
+ while(!pq.isEmpty()) {
DoubleMTreeDistanceSearchCandidate pqNode = pq.poll();
- if (knnList.size() >= k && pqNode.mindist > d_k.doubleValue()) {
+ if(knnList.size() >= k && pqNode.mindist > d_k) {
break;
}
- AbstractMTreeNode<?, D, ?, ?> node = index.getNode(pqNode.nodeID);
+ AbstractMTreeNode<?, ?, ?> node = index.getNode(pqNode.nodeID);
DBID id_p = pqNode.routingObjectID;
double d1 = pqNode.routingDistance;
// directory node
- if (!node.isLeaf()) {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ if(!node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MTreeEntry entry = node.getEntry(i);
DBID o_r = entry.getRoutingObjectID();
double r_or = entry.getCoveringRadius();
@@ -101,13 +100,13 @@ public class MetricalIndexKNNQuery<O, D extends NumberDistance<D, ?>> extends Ab
double diff = Math.abs(d1 - d2);
- double sum = d_k.doubleValue() + r_or;
+ double sum = d_k + r_or;
- if (diff <= sum) {
- double d3 = distanceQuery.distance(o_r, q).doubleValue();
+ if(diff <= sum) {
+ double d3 = distanceQuery.distance(o_r, q);
index.statistics.countDistanceCalculation();
double d_min = Math.max(d3 - r_or, 0.);
- if (d_min <= d_k.doubleValue()) {
+ if(d_min <= d_k) {
pq.add(new DoubleMTreeDistanceSearchCandidate(d_min, ((DirectoryEntry) entry).getPageID(), o_r, d3));
}
}
@@ -115,7 +114,7 @@ public class MetricalIndexKNNQuery<O, D extends NumberDistance<D, ?>> extends Ab
}
// data node
else {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MTreeEntry entry = node.getEntry(i);
DBID o_j = entry.getRoutingObjectID();
@@ -123,10 +122,10 @@ public class MetricalIndexKNNQuery<O, D extends NumberDistance<D, ?>> extends Ab
double diff = Math.abs(d1 - d2);
- if (diff <= d_k.doubleValue()) {
- D d3 = distanceQuery.distance(o_j, q);
+ if(diff <= d_k) {
+ double d3 = distanceQuery.distance(o_j, q);
index.statistics.countDistanceCalculation();
- if (d3.compareTo(d_k) <= 0) {
+ if(d3 <= d_k) {
knnList.insert(d3, o_j);
d_k = knnList.getKNNDistance();
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexRangeQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexRangeQuery.java
index fedf8ddb..b992977c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexRangeQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexRangeQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query;
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,11 +24,11 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.range.AbstractDistanceRangeQuery;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.DirectoryEntry;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
@@ -40,12 +40,14 @@ import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
* @author Erich Schubert
*
* @apiviz.uses AbstractMTree
+ *
+ * @param <O> Object type
*/
-public class MetricalIndexRangeQuery<O, D extends NumberDistance<D, ?>> extends AbstractDistanceRangeQuery<O, D> {
+public class MetricalIndexRangeQuery<O> extends AbstractDistanceRangeQuery<O> {
/**
* The index to use
*/
- protected final AbstractMTree<O, D, ?, ?, ?> index;
+ protected final AbstractMTree<O, ?, ?, ?> index;
/**
* Constructor.
@@ -53,7 +55,7 @@ public class MetricalIndexRangeQuery<O, D extends NumberDistance<D, ?>> extends
* @param index Index to use
* @param distanceQuery Distance query used
*/
- public MetricalIndexRangeQuery(AbstractMTree<O, D, ?, ?, ?> index, DistanceQuery<O, D> distanceQuery) {
+ public MetricalIndexRangeQuery(AbstractMTree<O, ?, ?, ?> index, DistanceQuery<O> distanceQuery) {
super(distanceQuery);
this.index = index;
}
@@ -65,18 +67,18 @@ public class MetricalIndexRangeQuery<O, D extends NumberDistance<D, ?>> extends
*
* @param o_p the routing object of the specified node
* @param node the root of the subtree to be traversed
- * @param q the id of the query object
+ * @param q the query object
* @param r_q the query range
* @param result the list holding the query results
*/
- private void doRangeQuery(DBID o_p, AbstractMTreeNode<O, D, ?, ?> node, O q, D r_q, GenericDistanceDBIDList<D> result) {
+ private void doRangeQuery(DBID o_p, AbstractMTreeNode<O, ?, ?> node, O q, double r_q, ModifiableDoubleDBIDList result) {
double d1 = 0.;
- if (o_p != null) {
- d1 = distanceQuery.distance(o_p, q).doubleValue();
+ if(o_p != null) {
+ d1 = distanceQuery.distance(o_p, q);
index.statistics.countDistanceCalculation();
}
- if (!node.isLeaf()) {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ if(!node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MTreeEntry entry = node.getEntry(i);
DBID o_r = entry.getRoutingObjectID();
@@ -84,19 +86,20 @@ public class MetricalIndexRangeQuery<O, D extends NumberDistance<D, ?>> extends
double d2 = o_p != null ? entry.getParentDistance() : 0.;
double diff = Math.abs(d1 - d2);
- double sum = r_q.doubleValue() + r_or;
+ double sum = r_q + r_or;
- if (diff <= sum) {
- D d3 = distanceQuery.distance(o_r, q);
+ if(diff <= sum) {
+ double d3 = distanceQuery.distance(o_r, q);
index.statistics.countDistanceCalculation();
- if (d3.doubleValue() <= sum) {
- AbstractMTreeNode<O, D, ?, ?> child = index.getNode(((DirectoryEntry) entry).getPageID());
+ if(d3 <= sum) {
+ AbstractMTreeNode<O, ?, ?> child = index.getNode(((DirectoryEntry) entry).getPageID());
doRangeQuery(o_r, child, q, r_q, result);
}
}
}
- } else {
- for (int i = 0; i < node.getNumEntries(); i++) {
+ }
+ else {
+ for(int i = 0; i < node.getNumEntries(); i++) {
MTreeEntry entry = node.getEntry(i);
DBID o_j = entry.getRoutingObjectID();
@@ -104,10 +107,10 @@ public class MetricalIndexRangeQuery<O, D extends NumberDistance<D, ?>> extends
double diff = Math.abs(d1 - d2);
- if (diff <= r_q.doubleValue()) {
- D d3 = distanceQuery.distance(o_j, q);
+ if(diff <= r_q) {
+ double d3 = distanceQuery.distance(o_j, q);
index.statistics.countDistanceCalculation();
- if (d3.compareTo(r_q) <= 0) {
+ if(d3 <= r_q) {
result.add(d3, o_j);
}
}
@@ -116,8 +119,8 @@ public class MetricalIndexRangeQuery<O, D extends NumberDistance<D, ?>> extends
}
@Override
- public DistanceDBIDList<D> getRangeForObject(O obj, D range) {
- final GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>();
+ public DoubleDBIDList getRangeForObject(O obj, double range) {
+ final ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
doRangeQuery(null, index.getRoot(), obj, range, result);
index.statistics.countRangeQuery();
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MkTreeRKNNQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MkTreeRKNNQuery.java
index c8cec69f..a00e44a9 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MkTreeRKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MkTreeRKNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query;
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 java.util.List;
import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.rknn.AbstractRKNNQuery;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.AbstractMkTree;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
@@ -43,11 +42,11 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
*
* @apiviz.uses AbstractMkTree
*/
-public class MkTreeRKNNQuery<O, D extends NumberDistance<D, ?>> extends AbstractRKNNQuery<O, D> {
+public class MkTreeRKNNQuery<O> extends AbstractRKNNQuery<O> {
/**
* The index to use
*/
- protected final AbstractMkTree<O, D, ?, ?, ?> index;
+ protected final AbstractMkTree<O, ?, ?, ?> index;
/**
* Constructor.
@@ -55,23 +54,23 @@ public class MkTreeRKNNQuery<O, D extends NumberDistance<D, ?>> extends Abstract
* @param index Index to use
* @param distanceQuery Distance query used
*/
- public MkTreeRKNNQuery(AbstractMkTree<O, D, ?, ?, ?> index, DistanceQuery<O, D> distanceQuery) {
+ public MkTreeRKNNQuery(AbstractMkTree<O, ?, ?, ?> index, DistanceQuery<O> distanceQuery) {
super(distanceQuery);
this.index = index;
}
@Override
- public DistanceDBIDList<D> getRKNNForObject(O obj, int k) {
+ public DoubleDBIDList getRKNNForObject(O obj, int k) {
throw new AbortException("Preprocessor KNN query only supports ID queries.");
}
@Override
- public DistanceDBIDList<D> getRKNNForDBID(DBIDRef id, int k) {
+ public DoubleDBIDList getRKNNForDBID(DBIDRef id, int k) {
return index.reverseKNNQuery(id, k);
}
@Override
- public List<? extends DistanceDBIDList<D>> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ public List<? extends DoubleDBIDList> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
// TODO: implement
throw new NotImplementedException(ExceptionMessages.UNSUPPORTED_NOT_YET);
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/package-info.java
index a975fdff..5ad2593c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/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/index/tree/metrical/mtreevariants/strategies/insert/MTreeInsert.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/insert/MTreeInsert.java
index 65fc3768..5fff4143 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/insert/MTreeInsert.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/insert/MTreeInsert.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.insert;
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,7 +22,6 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.insert;
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.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.IndexTreePath;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
@@ -38,7 +37,7 @@ import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
*
* @author Erich Schubert
*/
-public interface MTreeInsert<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry> {
+public interface MTreeInsert<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry> {
/**
* Choose the subpath to insert into.
*
@@ -46,5 +45,5 @@ public interface MTreeInsert<O, D extends NumberDistance<D, ?>, N extends Abstra
* @param object Object to insert
* @return Path to insertion node
*/
- IndexTreePath<E> choosePath(AbstractMTree<O, D, N, E, ?> tree, E object);
+ IndexTreePath<E> choosePath(AbstractMTree<O, N, E, ?> tree, E object);
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/insert/MinimumEnlargementInsert.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/insert/MinimumEnlargementInsert.java
index f848f5f4..cb410a8d 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/insert/MinimumEnlargementInsert.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/insert/MinimumEnlargementInsert.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.insert;
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,7 +22,6 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.insert;
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.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.IndexTreePath;
import de.lmu.ifi.dbs.elki.index.tree.TreeIndexPathComponent;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
@@ -44,9 +43,9 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* @author Erich Schubert
*/
@Reference(authors = "P. Ciaccia, M. Patella, P. Zezula", title = "M-tree: An Efficient Access Method for Similarity Search in Metric Spaces", booktitle = "VLDB'97, Proceedings of 23rd International Conference on Very Large Data Bases, August 25-29, 1997, Athens, Greece", url = "http://www.vldb.org/conf/1997/P426.PDF")
-public class MinimumEnlargementInsert<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry> implements MTreeInsert<O, D, N, E> {
+public class MinimumEnlargementInsert<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry> implements MTreeInsert<O, N, E> {
@Override
- public IndexTreePath<E> choosePath(AbstractMTree<O, D, N, E, ?> tree, E object) {
+ public IndexTreePath<E> choosePath(AbstractMTree<O, N, E, ?> tree, E object) {
return choosePath(tree, object, tree.getRootPath());
}
@@ -59,7 +58,7 @@ public class MinimumEnlargementInsert<O, D extends NumberDistance<D, ?>, N exten
* @param subtree the subtree to be tested for insertion
* @return the path of the appropriate subtree to insert the given object
*/
- private IndexTreePath<E> choosePath(AbstractMTree<O, D, N, E, ?> tree, E object, IndexTreePath<E> subtree) {
+ private IndexTreePath<E> choosePath(AbstractMTree<O, N, E, ?> tree, E object, IndexTreePath<E> subtree) {
N node = tree.getNode(subtree.getLastPathComponent().getEntry());
// leaf
@@ -75,7 +74,7 @@ public class MinimumEnlargementInsert<O, D extends NumberDistance<D, ?>, N exten
{
bestIdx = 0;
bestEntry = node.getEntry(0);
- bestDistance = tree.distance(object.getRoutingObjectID(), bestEntry.getRoutingObjectID()).doubleValue();
+ bestDistance = tree.distance(object.getRoutingObjectID(), bestEntry.getRoutingObjectID());
if (bestDistance <= bestEntry.getCoveringRadius()) {
enlarge = 0.;
} else {
@@ -86,7 +85,7 @@ public class MinimumEnlargementInsert<O, D extends NumberDistance<D, ?>, N exten
// Iterate over remaining
for (int i = 1; i < node.getNumEntries(); i++) {
E entry = node.getEntry(i);
- double distance = tree.distance(object.getRoutingObjectID(), entry.getRoutingObjectID()).doubleValue();
+ double distance = tree.distance(object.getRoutingObjectID(), entry.getRoutingObjectID());
if (distance <= entry.getCoveringRadius()) {
if (enlarge > 0. || distance < bestDistance) {
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/insert/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/insert/package-info.java
index 64a85c2d..655611c6 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/insert/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/insert/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/index/tree/metrical/mtreevariants/strategies/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/package-info.java
index 0d019cf3..61d2d899 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/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/index/tree/metrical/mtreevariants/strategies/split/Assignments.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/Assignments.java
index 1079a141..cbf7e3eb 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/Assignments.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/Assignments.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.split;
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
@@ -69,7 +69,7 @@ public class Assignments<E extends MTreeEntry> {
private List<DistanceEntry<E>> secondAssignments;
/**
- * Provides an assignment during a split of an MTree node.
+ * Constructor.
*
* @param id1 the first routing object
* @param id2 the second routing object
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/DistanceEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/DistanceEntry.java
index 642e5a63..4df9aa59 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/DistanceEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/DistanceEntry.java
@@ -6,7 +6,7 @@ import de.lmu.ifi.dbs.elki.index.tree.Entry;
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/index/tree/metrical/mtreevariants/strategies/split/MLBDistSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MLBDistSplit.java
index d294d5b3..e24e87ed 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MLBDistSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MLBDistSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.split;
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.index.tree.metrical.mtreevariants.strategies.split;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
@@ -45,12 +44,11 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* @author Elke Achtert
*
* @param <O> the type of DatabaseObject to be stored in the M-Tree
- * @param <D> the type of Distance used in the M-Tree
* @param <N> the type of AbstractMTreeNode used in the M-Tree
* @param <E> the type of MetricalEntry used in the M-Tree
*/
@Reference(authors = "P. Ciaccia, M. Patella, P. Zezula", title = "M-tree: An Efficient Access Method for Similarity Search in Metric Spaces", booktitle = "VLDB'97, Proceedings of 23rd International Conference on Very Large Data Bases, August 25-29, 1997, Athens, Greece", url = "http://www.vldb.org/conf/1997/P426.PDF")
-public class MLBDistSplit<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry> extends MTreeSplit<O, D, N, E> {
+public class MLBDistSplit<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry> extends MTreeSplit<O, N, E> {
/**
* Creates a new split object.
*/
@@ -70,19 +68,19 @@ public class MLBDistSplit<O, D extends NumberDistance<D, ?>, N extends AbstractM
* @param node the node to be split
*/
@Override
- public Assignments<E> split(AbstractMTree<O, D, N, E, ?> tree, N node) {
+ public Assignments<E> split(AbstractMTree<O, N, E, ?> tree, N node) {
DBID firstPromoted = null;
DBID secondPromoted = null;
// choose first and second routing object
double currentMaxDist = 0.;
- for (int i = 0; i < node.getNumEntries(); i++) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
DBID id1 = node.getEntry(i).getRoutingObjectID();
- for (int j = i + 1; j < node.getNumEntries(); j++) {
+ for(int j = i + 1; j < node.getNumEntries(); j++) {
DBID id2 = node.getEntry(j).getRoutingObjectID();
- double distance = tree.distance(id1, id2).doubleValue();
- if (distance >= currentMaxDist) {
+ double distance = tree.distance(id1, id2);
+ if(distance >= currentMaxDist) {
firstPromoted = id1;
secondPromoted = id2;
currentMaxDist = distance;
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MMRadSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MMRadSplit.java
index 232df088..2d3fd7f8 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MMRadSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MMRadSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.split;
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.index.tree.metrical.mtreevariants.strategies.split;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
@@ -44,12 +43,11 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* @author Elke Achtert
*
* @param <O> the type of DatabaseObject to be stored in the M-Tree
- * @param <D> the type of Distance used in the M-Tree
* @param <N> the type of AbstractMTreeNode used in the M-Tree
* @param <E> the type of MetricalEntry used in the M-Tree
*/
@Reference(authors = "P. Ciaccia, M. Patella, P. Zezula", title = "M-tree: An Efficient Access Method for Similarity Search in Metric Spaces", booktitle = "VLDB'97, Proceedings of 23rd International Conference on Very Large Data Bases, August 25-29, 1997, Athens, Greece", url = "http://www.vldb.org/conf/1997/P426.PDF")
-public class MMRadSplit<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry> extends MTreeSplit<O, D, N, E> {
+public class MMRadSplit<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry> extends MTreeSplit<O, N, E> {
/**
* Creates a new split object.
*/
@@ -67,17 +65,17 @@ public class MMRadSplit<O, D extends NumberDistance<D, ?>, N extends AbstractMTr
* @param node the node to be split
*/
@Override
- public Assignments<E> split(AbstractMTree<O, D, N, E, ?> tree, N node) {
+ public Assignments<E> split(AbstractMTree<O, N, E, ?> tree, N node) {
double miSumCR = Double.POSITIVE_INFINITY;
double[] distanceMatrix = computeDistanceMatrix(tree, node);
Assignments<E> bestAssignment = null;
- for (int i = 0; i < node.getNumEntries(); i++) {
- for (int j = i + 1; j < node.getNumEntries(); j++) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ for(int j = i + 1; j < node.getNumEntries(); j++) {
Assignments<E> currentAssignments = balancedPartition(tree, node, i, j, distanceMatrix);
double maxCR = Math.max(currentAssignments.getFirstCoveringRadius(), currentAssignments.getSecondCoveringRadius());
- if (maxCR < miSumCR) {
+ if(maxCR < miSumCR) {
miSumCR = maxCR;
bestAssignment = currentAssignments;
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MRadSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MRadSplit.java
index 5de15356..3feb9d87 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MRadSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MRadSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.split;
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.index.tree.metrical.mtreevariants.strategies.split;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
@@ -44,12 +43,11 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* @author Elke Achtert
*
* @param <O> the type of DatabaseObject to be stored in the M-Tree
- * @param <D> the type of Distance used in the M-Tree
* @param <N> the type of AbstractMTreeNode used in the M-Tree
* @param <E> the type of MetricalEntry used in the M-Tree
*/
@Reference(authors = "P. Ciaccia, M. Patella, P. Zezula", title = "M-tree: An Efficient Access Method for Similarity Search in Metric Spaces", booktitle = "VLDB'97, Proceedings of 23rd International Conference on Very Large Data Bases, August 25-29, 1997, Athens, Greece", url = "http://www.vldb.org/conf/1997/P426.PDF")
-public class MRadSplit<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry> extends MTreeSplit<O, D, N, E> {
+public class MRadSplit<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry> extends MTreeSplit<O, N, E> {
/**
* Creates a new split object.
*/
@@ -67,17 +65,17 @@ public class MRadSplit<O, D extends NumberDistance<D, ?>, N extends AbstractMTre
* @param node the node to be split
*/
@Override
- public Assignments<E> split(AbstractMTree<O, D, N, E, ?> tree, N node) {
+ public Assignments<E> split(AbstractMTree<O, N, E, ?> tree, N node) {
double miSumCR = Double.POSITIVE_INFINITY;
double[] distanceMatrix = computeDistanceMatrix(tree, node);
Assignments<E> bestAssignment = null;
- for (int i = 0; i < node.getNumEntries(); i++) {
- for (int j = i + 1; j < node.getNumEntries(); j++) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ for(int j = i + 1; j < node.getNumEntries(); j++) {
Assignments<E> currentAssignments = balancedPartition(tree, node, i, j, distanceMatrix);
double sumCR = currentAssignments.getFirstCoveringRadius() + currentAssignments.getSecondCoveringRadius();
- if (sumCR < miSumCR) {
+ if(sumCR < miSumCR) {
miSumCR = sumCR;
bestAssignment = currentAssignments;
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MTreeSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MTreeSplit.java
index 167b5368..89b323a7 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MTreeSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/MTreeSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.split;
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,7 +30,6 @@ import java.util.List;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
@@ -43,11 +42,10 @@ import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
* @apiviz.composedOf Assignments
*
* @param <O> the type of DatabaseObject to be stored in the M-Tree
- * @param <D> the type of Distance used in the M-Tree
* @param <N> the type of AbstractMTreeNode used in the M-Tree
* @param <E> the type of MetricalEntry used in the M-Tree
*/
-public abstract class MTreeSplit<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry> {
+public abstract class MTreeSplit<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry> {
/**
* Compute the pairwise distances in the given node.
*
@@ -55,18 +53,20 @@ public abstract class MTreeSplit<O, D extends NumberDistance<D, ?>, N extends Ab
* @param node Node
* @return Distance matrix
*/
- protected double[] computeDistanceMatrix(AbstractMTree<O, D, N, E, ?> tree, N node) {
+ protected double[] computeDistanceMatrix(AbstractMTree<O, N, E, ?> tree, N node) {
final int n = node.getNumEntries();
double[] distancematrix = new double[n * n];
// Build distance matrix
- for (int i = 0; i < n; i++) {
+ for(int i = 0; i < n; i++) {
E ei = node.getEntry(i);
- for (int j = 0; j < n; j++) {
- if (i == j) {
+ for(int j = 0; j < n; j++) {
+ if(i == j) {
distancematrix[i * n + j] = 0.0;
- } else if (i < j) {
- distancematrix[i * n + j] = tree.distance(ei, node.getEntry(j)).doubleValue();
- } else { // i > j
+ }
+ else if(i < j) {
+ distancematrix[i * n + j] = tree.distance(ei, node.getEntry(j));
+ }
+ else { // i > j
distancematrix[i * n + j] = distancematrix[j * n + i];
}
}
@@ -84,7 +84,7 @@ public abstract class MTreeSplit<O, D extends NumberDistance<D, ?>, N extends Ab
* @return an assignment that holds a balanced partition of the entries of the
* specified node
*/
- Assignments<E> balancedPartition(AbstractMTree<O, D, N, E, ?> tree, N node, DBID routingObject1, DBID routingObject2) {
+ Assignments<E> balancedPartition(AbstractMTree<O, N, E, ?> tree, N node, DBID routingObject1, DBID routingObject2) {
BitSet assigned = new BitSet(node.getNumEntries());
List<DistanceEntry<E>> assigned1 = new ArrayList<>(node.getCapacity());
List<DistanceEntry<E>> assigned2 = new ArrayList<>(node.getCapacity());
@@ -96,20 +96,20 @@ public abstract class MTreeSplit<O, D extends NumberDistance<D, ?>, N extends Ab
List<DistanceEntry<E>> list2 = new ArrayList<>();
// determine the nearest neighbors
- for (int i = 0; i < node.getNumEntries(); i++) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
final E ent = node.getEntry(i);
DBID id = ent.getRoutingObjectID();
- if (DBIDUtil.equal(id, routingObject1)) {
+ if(DBIDUtil.equal(id, routingObject1)) {
assigned1.add(new DistanceEntry<>(ent, 0., i));
continue;
}
- if (DBIDUtil.equal(id, routingObject2)) {
+ if(DBIDUtil.equal(id, routingObject2)) {
assigned2.add(new DistanceEntry<>(ent, 0., i));
continue;
}
// determine the distance of o to o1 / o2
- double d1 = tree.distance(routingObject1, id).doubleValue();
- double d2 = tree.distance(routingObject2, id).doubleValue();
+ double d1 = tree.distance(routingObject1, id);
+ double d2 = tree.distance(routingObject2, id);
list1.add(new DistanceEntry<>(ent, d1, i));
list2.add(new DistanceEntry<>(ent, d2, i));
@@ -117,10 +117,10 @@ public abstract class MTreeSplit<O, D extends NumberDistance<D, ?>, N extends Ab
Collections.sort(list1, Collections.reverseOrder());
Collections.sort(list2, Collections.reverseOrder());
- for (int i = 2; i < node.getNumEntries(); i++) {
+ for(int i = 2; i < node.getNumEntries(); i++) {
currentCR1 = assignNN(assigned, assigned1, list1, currentCR1, node.isLeaf());
i++;
- if (i < node.getNumEntries()) {
+ if(i < node.getNumEntries()) {
currentCR2 = assignNN(assigned, assigned2, list2, currentCR2, node.isLeaf());
}
}
@@ -138,7 +138,7 @@ public abstract class MTreeSplit<O, D extends NumberDistance<D, ?>, N extends Ab
* @return an assignment that holds a balanced partition of the entries of the
* specified node
*/
- Assignments<E> balancedPartition(AbstractMTree<O, D, N, E, ?> tree, N node, int routingEntNum1, int routingEntNum2, double[] distanceMatrix) {
+ Assignments<E> balancedPartition(AbstractMTree<O, N, E, ?> tree, N node, int routingEntNum1, int routingEntNum2, double[] distanceMatrix) {
final int n = node.getNumEntries();
BitSet assigned = new BitSet(node.getNumEntries());
List<DistanceEntry<E>> assigned1 = new ArrayList<>(node.getCapacity());
@@ -152,14 +152,14 @@ public abstract class MTreeSplit<O, D extends NumberDistance<D, ?>, N extends Ab
DBID routingObject1 = null, routingObject2 = null;
// determine the nearest neighbors
- for (int i = 0; i < node.getNumEntries(); i++) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
final E ent = node.getEntry(i);
- if (i == routingEntNum1) {
+ if(i == routingEntNum1) {
routingObject1 = ent.getRoutingObjectID();
assigned1.add(new DistanceEntry<>(ent, 0., i));
continue;
}
- if (i == routingEntNum2) {
+ if(i == routingEntNum2) {
routingObject2 = ent.getRoutingObjectID();
assigned2.add(new DistanceEntry<>(ent, 0., i));
continue;
@@ -174,10 +174,10 @@ public abstract class MTreeSplit<O, D extends NumberDistance<D, ?>, N extends Ab
Collections.sort(list1, Collections.reverseOrder());
Collections.sort(list2, Collections.reverseOrder());
- for (int i = 2; i < node.getNumEntries(); i++) {
+ for(int i = 2; i < node.getNumEntries(); i++) {
currentCR1 = assignNN(assigned, assigned1, list1, currentCR1, node.isLeaf());
i++;
- if (i < node.getNumEntries()) {
+ if(i < node.getNumEntries()) {
currentCR2 = assignNN(assigned, assigned2, list2, currentCR2, node.isLeaf());
}
}
@@ -199,15 +199,16 @@ public abstract class MTreeSplit<O, D extends NumberDistance<D, ?>, N extends Ab
private double assignNN(BitSet assigned, List<DistanceEntry<E>> assigned1, List<DistanceEntry<E>> list, double currentCR, boolean isLeaf) {
// Remove last unassigned:
DistanceEntry<E> distEntry = list.remove(list.size() - 1);
- while (assigned.get(distEntry.getIndex())) {
+ while(assigned.get(distEntry.getIndex())) {
distEntry = list.remove(list.size() - 1);
}
assigned1.add(distEntry);
assigned.set(distEntry.getIndex());
- if (isLeaf) {
+ if(isLeaf) {
return Math.max(currentCR, distEntry.getDistance());
- } else {
+ }
+ else {
return Math.max(currentCR, distEntry.getDistance() + (distEntry.getEntry()).getCoveringRadius());
}
}
@@ -219,5 +220,5 @@ public abstract class MTreeSplit<O, D extends NumberDistance<D, ?>, N extends Ab
* @param node Node to split
* @return the assignments of this split
*/
- abstract public Assignments<E> split(AbstractMTree<O, D, N, E, ?> tree, N node);
+ abstract public Assignments<E> split(AbstractMTree<O, N, E, ?> tree, N node);
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/RandomSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/RandomSplit.java
index ca54f51a..68a4edd1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/RandomSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/RandomSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.split;
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,11 +26,10 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.strategies.split;
import java.util.Random;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -55,12 +54,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
* @author Elke Achtert
*
* @param <O> the type of DatabaseObject to be stored in the M-Tree
- * @param <D> the type of Distance used in the M-Tree
* @param <N> the type of AbstractMTreeNode used in the M-Tree
* @param <E> the type of MetricalEntry used in the M-Tree
*/
@Reference(authors = "P. Ciaccia, M. Patella, P. Zezula", title = "M-tree: An Efficient Access Method for Similarity Search in Metric Spaces", booktitle = "VLDB'97, Proceedings of 23rd International Conference on Very Large Data Bases, August 25-29, 1997, Athens, Greece", url = "http://www.vldb.org/conf/1997/P426.PDF")
-public class RandomSplit<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry> extends MTreeSplit<O, D, N, E> {
+public class RandomSplit<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry> extends MTreeSplit<O, N, E> {
/**
* Random generator.
*/
@@ -84,10 +82,10 @@ public class RandomSplit<O, D extends NumberDistance<D, ?>, N extends AbstractMT
* @param node the node to be split
*/
@Override
- public Assignments<E> split(AbstractMTree<O, D, N, E, ?> tree, N node) {
+ public Assignments<E> split(AbstractMTree<O, N, E, ?> tree, N node) {
int pos1 = random.nextInt(node.getNumEntries());
int pos2 = random.nextInt(node.getNumEntries() - 1);
- if (pos2 >= pos1) {
+ if(pos2 >= pos1) {
++pos2;
}
DBID id1 = node.getEntry(pos1).getRoutingObjectID();
@@ -104,11 +102,10 @@ public class RandomSplit<O, D extends NumberDistance<D, ?>, N extends AbstractMT
* @apiviz.exclude
*
* @param <O> the type of DatabaseObject to be stored in the M-Tree
- * @param <D> the type of Distance used in the M-Tree
* @param <N> the type of AbstractMTreeNode used in the M-Tree
* @param <E> the type of MetricalEntry used in the M-Tree
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<O, D, N, E>, E extends MTreeEntry> extends AbstractParameterizer {
+ public static class Parameterizer<O, N extends AbstractMTreeNode<O, N, E>, E extends MTreeEntry> extends AbstractParameterizer {
/**
* Option ID for the random generator.
*/
@@ -123,13 +120,13 @@ public class RandomSplit<O, D extends NumberDistance<D, ?>, N extends AbstractMT
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
RandomParameter rndP = new RandomParameter(RANDOM_ID);
- if (config.grab(rndP)) {
+ if(config.grab(rndP)) {
rnd = rndP.getValue();
}
}
@Override
- protected RandomSplit<O, D, N, E> makeInstance() {
+ protected RandomSplit<O, N, E> makeInstance() {
return new RandomSplit<>(rnd);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/package-info.java
index ed0fd729..57c0d978 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/strategies/split/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/index/tree/metrical/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/package-info.java
index b1a76d8b..eb9afac1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/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/index/tree/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/package-info.java
index 6c34473f..0ab8843c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/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/index/tree/query/DoubleDistanceSearchCandidate.java b/src/de/lmu/ifi/dbs/elki/index/tree/query/DoubleDistanceSearchCandidate.java
index fd9ee2f9..949bb96a 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/query/DoubleDistanceSearchCandidate.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/query/DoubleDistanceSearchCandidate.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.query;
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/index/tree/query/DoubleMTreeDistanceSearchCandidate.java b/src/de/lmu/ifi/dbs/elki/index/tree/query/DoubleMTreeDistanceSearchCandidate.java
index 3be9ff09..8139c23b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/query/DoubleMTreeDistanceSearchCandidate.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/query/DoubleMTreeDistanceSearchCandidate.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.query;
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/index/tree/query/GenericDistanceSearchCandidate.java b/src/de/lmu/ifi/dbs/elki/index/tree/query/GenericDistanceSearchCandidate.java
deleted file mode 100644
index 278dec60..00000000
--- a/src/de/lmu/ifi/dbs/elki/index/tree/query/GenericDistanceSearchCandidate.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package de.lmu.ifi.dbs.elki.index.tree.query;
-
-/*
- 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.distance.distancevalue.Distance;
-
-/**
- * Candidate for expansion in a distance search (generic implementation).
- *
- * @author Erich Schubert
- *
- * @param <D> Distance type
- */
-public class GenericDistanceSearchCandidate<D extends Distance<D>> implements Comparable<GenericDistanceSearchCandidate<D>> {
- /**
- * Distance value
- */
- public D mindist;
-
- /**
- * Page id
- */
- public int nodeID;
-
- /**
- * Constructor.
- *
- * @param mindist The minimum distance to this candidate
- * @param pagenr The page number of this candidate
- */
- public GenericDistanceSearchCandidate(final D mindist, final int pagenr) {
- super();
- this.mindist = mindist;
- this.nodeID = pagenr;
- }
-
- @Override
- public boolean equals(Object obj) {
- final GenericDistanceSearchCandidate<?> other = (GenericDistanceSearchCandidate<?>) obj;
- return this.nodeID == other.nodeID;
- }
-
- @Override
- public int compareTo(GenericDistanceSearchCandidate<D> o) {
- return this.mindist.compareTo(o.mindist);
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/query/GenericMTreeDistanceSearchCandidate.java b/src/de/lmu/ifi/dbs/elki/index/tree/query/GenericMTreeDistanceSearchCandidate.java
index cbe0451e..ca5c81d1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/query/GenericMTreeDistanceSearchCandidate.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/query/GenericMTreeDistanceSearchCandidate.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.query;
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/index/tree/query/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/query/package-info.java
index 29976738..98ccffc5 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/query/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/query/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/index/tree/spatial/SpatialDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialDirectoryEntry.java
index 4a131cbf..ee7adf51 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial;
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/index/tree/spatial/SpatialEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialEntry.java
index 4fe55adf..94c7bf33 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial;
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/index/tree/spatial/SpatialIndexTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialIndexTree.java
index b4bd5208..ad3ae29c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialIndexTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialIndexTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial;
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/index/tree/spatial/SpatialNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialNode.java
index 449992a2..27913d36 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial;
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/index/tree/spatial/SpatialPair.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPair.java
index f69b1dd1..bc0c6c94 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPair.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial;
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/index/tree/spatial/SpatialPointLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPointLeafEntry.java
index d79893b0..61dbf7d7 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPointLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPointLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial;
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
@@ -39,7 +39,7 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
*
* @author Elke Achtert
*/
-public class SpatialPointLeafEntry extends AbstractLeafEntry implements SpatialEntry, NumberVector<Double> {
+public class SpatialPointLeafEntry extends AbstractLeafEntry implements SpatialEntry, NumberVector {
/**
* Serial version.
*/
@@ -74,7 +74,7 @@ public class SpatialPointLeafEntry extends AbstractLeafEntry implements SpatialE
* @param id Object id
* @param vector Number vector
*/
- public SpatialPointLeafEntry(DBID id, NumberVector<?> vector) {
+ public SpatialPointLeafEntry(DBID id, NumberVector vector) {
super(id);
int dim = vector.getDimensionality();
this.values = new double[dim];
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/kd/MinimalisticMemoryKDTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/kd/MinimalisticMemoryKDTree.java
index ce1da63c..c55a454d 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/kd/MinimalisticMemoryKDTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/kd/MinimalisticMemoryKDTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.kd;
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,10 +31,10 @@ import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPairList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDoubleDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.AbstractDistanceKNNQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
@@ -43,12 +43,10 @@ import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
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.distancefunction.DistanceFunction;
-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.minkowski.LPNormDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseLPNormDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.index.AbstractIndex;
import de.lmu.ifi.dbs.elki.index.IndexFactory;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
@@ -73,7 +71,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* @param <O> Vector type
*/
@Reference(authors = "J. L. Bentley", title = "Multidimensional binary search trees used for associative searching", booktitle = "Communications of the ACM, Vol. 18 Issue 9, Sept. 1975", url = "http://dx.doi.org/10.1145/361002.361007")
-public class MinimalisticMemoryKDTree<O extends NumberVector<?>> extends AbstractIndex<O> implements KNNIndex<O>, RangeIndex<O> {
+public class MinimalisticMemoryKDTree<O extends NumberVector> extends AbstractIndex<O> implements KNNIndex<O>, RangeIndex<O> {
/**
* Class logger
*/
@@ -187,36 +185,34 @@ public class MinimalisticMemoryKDTree<O extends NumberVector<?>> extends Abstrac
}
}
- @SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> KNNQuery<O, D> getKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
- DistanceFunction<? super O, D> df = distanceQuery.getDistanceFunction();
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ DistanceFunction<? super O> df = distanceQuery.getDistanceFunction();
// TODO: if we know this works for other distance functions, add them, too!
if(df instanceof LPNormDistanceFunction) {
- return (KNNQuery<O, D>) new KDTreeKNNQuery((DistanceQuery<O, DoubleDistance>) distanceQuery, (DoubleNorm<? super O>) df);
+ return new KDTreeKNNQuery(distanceQuery, (Norm<? super O>) df);
}
if(df instanceof SquaredEuclideanDistanceFunction) {
- return (KNNQuery<O, D>) new KDTreeKNNQuery((DistanceQuery<O, DoubleDistance>) distanceQuery, (DoubleNorm<? super O>) df);
+ return new KDTreeKNNQuery(distanceQuery, (Norm<? super O>) df);
}
if(df instanceof SparseLPNormDistanceFunction) {
- return (KNNQuery<O, D>) new KDTreeKNNQuery((DistanceQuery<O, DoubleDistance>) distanceQuery, (DoubleNorm<? super O>) df);
+ return new KDTreeKNNQuery(distanceQuery, (Norm<? super O>) df);
}
return null;
}
- @SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> RangeQuery<O, D> getRangeQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
- DistanceFunction<? super O, D> df = distanceQuery.getDistanceFunction();
+ public RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ DistanceFunction<? super O> df = distanceQuery.getDistanceFunction();
// TODO: if we know this works for other distance functions, add them, too!
if(df instanceof LPNormDistanceFunction) {
- return (RangeQuery<O, D>) new KDTreeRangeQuery((DistanceQuery<O, DoubleDistance>) distanceQuery, (DoubleNorm<? super O>) df);
+ return new KDTreeRangeQuery(distanceQuery, (Norm<? super O>) df);
}
if(df instanceof SquaredEuclideanDistanceFunction) {
- return (RangeQuery<O, D>) new KDTreeRangeQuery((DistanceQuery<O, DoubleDistance>) distanceQuery, (DoubleNorm<? super O>) df);
+ return new KDTreeRangeQuery(distanceQuery, (Norm<? super O>) df);
}
if(df instanceof SparseLPNormDistanceFunction) {
- return (RangeQuery<O, D>) new KDTreeRangeQuery((DistanceQuery<O, DoubleDistance>) distanceQuery, (DoubleNorm<? super O>) df);
+ return new KDTreeRangeQuery(distanceQuery, (Norm<? super O>) df);
}
return null;
}
@@ -226,11 +222,11 @@ public class MinimalisticMemoryKDTree<O extends NumberVector<?>> extends Abstrac
*
* @author Erich Schubert
*/
- public class KDTreeKNNQuery extends AbstractDistanceKNNQuery<O, DoubleDistance> {
+ public class KDTreeKNNQuery extends AbstractDistanceKNNQuery<O> {
/**
* Norm to use.
*/
- private DoubleNorm<? super O> norm;
+ private Norm<? super O> norm;
/**
* Constructor.
@@ -238,14 +234,14 @@ public class MinimalisticMemoryKDTree<O extends NumberVector<?>> extends Abstrac
* @param distanceQuery Distance query
* @param norm Norm to use
*/
- public KDTreeKNNQuery(DistanceQuery<O, DoubleDistance> distanceQuery, DoubleNorm<? super O> norm) {
+ public KDTreeKNNQuery(DistanceQuery<O> distanceQuery, Norm<? super O> norm) {
super(distanceQuery);
this.norm = norm;
}
@Override
- public KNNList<DoubleDistance> getKNNForObject(O obj, int k) {
- final DoubleDistanceKNNHeap knns = DBIDUtil.newDoubleDistanceHeap(k);
+ public KNNList getKNNForObject(O obj, int k) {
+ final KNNHeap knns = DBIDUtil.newHeap(k);
kdKNNSearch(0, sorted.size(), 0, obj, knns, sorted.iter(), Double.POSITIVE_INFINITY);
return knns.toKNNList();
}
@@ -262,7 +258,7 @@ public class MinimalisticMemoryKDTree<O extends NumberVector<?>> extends Abstrac
* @param maxdist Current upper bound of kNN distance.
* @return New upper bound of kNN distance.
*/
- private double kdKNNSearch(int left, int right, int axis, O query, DoubleDistanceKNNHeap knns, DBIDArrayIter iter, double maxdist) {
+ private double kdKNNSearch(int left, int right, int axis, O query, KNNHeap knns, DBIDArrayIter iter, double maxdist) {
// Look at current node:
final int middle = (left + right) >>> 1;
iter.seek(middle);
@@ -280,12 +276,12 @@ public class MinimalisticMemoryKDTree<O extends NumberVector<?>> extends Abstrac
// Exact match chance (delta == 0)!
// process first, then descend both sides.
if(onleft && onright) {
- double dist = norm.doubleDistance(query, split);
+ double dist = norm.distance(query, split);
countDistanceComputation();
if(dist <= maxdist) {
iter.seek(middle);
knns.insert(dist, iter);
- maxdist = knns.doubleKNNDistance();
+ maxdist = knns.getKNNDistance();
}
if(left < middle) {
maxdist = kdKNNSearch(left, middle, next, query, knns, iter, maxdist);
@@ -301,12 +297,12 @@ public class MinimalisticMemoryKDTree<O extends NumberVector<?>> extends Abstrac
}
// Look at splitting element (unless already above):
if(Math.abs(delta) <= maxdist) {
- double dist = norm.doubleDistance(query, split);
+ double dist = norm.distance(query, split);
countDistanceComputation();
if(dist <= maxdist) {
iter.seek(middle);
knns.insert(dist, iter);
- maxdist = knns.doubleKNNDistance();
+ maxdist = knns.getKNNDistance();
}
}
if((middle + 1 < right) && (Math.abs(delta) <= maxdist)) {
@@ -319,12 +315,12 @@ public class MinimalisticMemoryKDTree<O extends NumberVector<?>> extends Abstrac
}
// Look at splitting element (unless already above):
if(Math.abs(delta) <= maxdist) {
- double dist = norm.doubleDistance(query, split);
+ double dist = norm.distance(query, split);
countDistanceComputation();
if(dist <= maxdist) {
iter.seek(middle);
knns.insert(dist, iter);
- maxdist = knns.doubleKNNDistance();
+ maxdist = knns.getKNNDistance();
}
}
if((left < middle) && (Math.abs(delta) <= maxdist)) {
@@ -341,11 +337,11 @@ public class MinimalisticMemoryKDTree<O extends NumberVector<?>> extends Abstrac
*
* @author Erich Schubert
*/
- public class KDTreeRangeQuery extends AbstractDistanceRangeQuery<O, DoubleDistance> {
+ public class KDTreeRangeQuery extends AbstractDistanceRangeQuery<O> {
/**
* Norm to use.
*/
- private DoubleNorm<? super O> norm;
+ private Norm<? super O> norm;
/**
* Constructor.
@@ -353,15 +349,15 @@ public class MinimalisticMemoryKDTree<O extends NumberVector<?>> extends Abstrac
* @param distanceQuery Distance query
* @param norm Norm to use
*/
- public KDTreeRangeQuery(DistanceQuery<O, DoubleDistance> distanceQuery, DoubleNorm<? super O> norm) {
+ public KDTreeRangeQuery(DistanceQuery<O> distanceQuery, Norm<? super O> norm) {
super(distanceQuery);
this.norm = norm;
}
@Override
- public DoubleDistanceDBIDPairList getRangeForObject(O obj, DoubleDistance range) {
- final DoubleDistanceDBIDPairList res = new DoubleDistanceDBIDPairList();
- kdRangeSearch(0, sorted.size(), 0, obj, res, sorted.iter(), range.doubleValue());
+ public DoubleDBIDList getRangeForObject(O obj, double range) {
+ final ModifiableDoubleDBIDList res = DBIDUtil.newDistanceDBIDList();
+ kdRangeSearch(0, sorted.size(), 0, obj, res, sorted.iter(), range);
res.sort();
return res;
}
@@ -377,7 +373,7 @@ public class MinimalisticMemoryKDTree<O extends NumberVector<?>> extends Abstrac
* @param iter Iterator variable (reduces memory footprint!)
* @param radius Query radius
*/
- private void kdRangeSearch(int left, int right, int axis, O query, ModifiableDoubleDistanceDBIDList res, DBIDArrayIter iter, double radius) {
+ private void kdRangeSearch(int left, int right, int axis, O query, ModifiableDoubleDBIDList res, DBIDArrayIter iter, double radius) {
// Look at current node:
final int middle = (left + right) >>> 1;
iter.seek(middle);
@@ -395,7 +391,7 @@ public class MinimalisticMemoryKDTree<O extends NumberVector<?>> extends Abstrac
// Current object:
if(close) {
- double dist = norm.doubleDistance(query, split);
+ double dist = norm.distance(query, split);
countDistanceComputation();
if(dist <= radius) {
iter.seek(middle);
@@ -421,8 +417,8 @@ public class MinimalisticMemoryKDTree<O extends NumberVector<?>> extends Abstrac
*
* @param <O> Vector type
*/
- @Alias({"minikd", "kd"})
- public static class Factory<O extends NumberVector<?>> implements IndexFactory<O, MinimalisticMemoryKDTree<O>> {
+ @Alias({ "minikd", "kd" })
+ public static class Factory<O extends NumberVector> implements IndexFactory<O, MinimalisticMemoryKDTree<O>> {
/**
* Constructor. Trivial parameterizable.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/kd/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/kd/package-info.java
index 88a42c2d..eab62562 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/kd/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/kd/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/index/tree/spatial/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/package-info.java
index 7fbdd2ac..d69e1516 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/package-info.java
@@ -1,11 +1,13 @@
/**
* <p>Tree-based index structures for <em>spatial</em> indexing.</p>
+ *
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.tree.spatial.rstarvariants.deliclu
*/
/*
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/index/tree/spatial/rstarvariants/AbstractRStarTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTree.java
index 63c8e8fa..8b0e5998 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants;
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/index/tree/spatial/rstarvariants/AbstractRStarTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeFactory.java
index 70e9f747..b51bfe10 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants;
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
@@ -56,7 +56,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @param <E> Entry type
* @param <I> Index type
*/
-public abstract class AbstractRStarTreeFactory<O extends NumberVector<?>, N extends AbstractRStarTreeNode<N, E>, E extends SpatialEntry, I extends AbstractRStarTree<N, E, S> & Index, S extends AbstractRTreeSettings> extends PagedIndexFactory<O, I> {
+public abstract class AbstractRStarTreeFactory<O extends NumberVector, N extends AbstractRStarTreeNode<N, E>, E extends SpatialEntry, I extends AbstractRStarTree<N, E, S> & Index, S extends AbstractRTreeSettings> extends PagedIndexFactory<O, I> {
/**
* Tree settings
*/
@@ -88,7 +88,7 @@ public abstract class AbstractRStarTreeFactory<O extends NumberVector<?>, N exte
* @param <O> Object type
* @param <S> Settings class
*/
- public abstract static class Parameterizer<O extends NumberVector<?>, S extends AbstractRTreeSettings> extends PagedIndexFactory.Parameterizer<O> {
+ public abstract static class Parameterizer<O extends NumberVector, S extends AbstractRTreeSettings> extends PagedIndexFactory.Parameterizer<O> {
/**
* Fast-insertion parameter. Optional.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeNode.java
index 6b5fc2f0..18f22ceb 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants;
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/index/tree/spatial/rstarvariants/AbstractRTreeSettings.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRTreeSettings.java
index f876be13..40a2aa6c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRTreeSettings.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRTreeSettings.java
@@ -12,7 +12,7 @@ import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split.Top
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/index/tree/spatial/rstarvariants/NonFlatRStarTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/NonFlatRStarTree.java
index 8a4f530f..eb04eec7 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/NonFlatRStarTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/NonFlatRStarTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants;
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/index/tree/spatial/rstarvariants/deliclu/DeLiCluDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluDirectoryEntry.java
index 510120c9..eab4a7d6 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
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/index/tree/spatial/rstarvariants/deliclu/DeLiCluEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluEntry.java
index f72b7d8d..8478c0b5 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
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/index/tree/spatial/rstarvariants/deliclu/DeLiCluLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluLeafEntry.java
index 741ab840..a2c8490b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
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
@@ -62,7 +62,7 @@ public class DeLiCluLeafEntry extends SpatialPointLeafEntry implements DeLiCluEn
* @param id the unique id of the underlying data object
* @param vector the vector to store
*/
- public DeLiCluLeafEntry(DBID id, NumberVector<?> vector) {
+ public DeLiCluLeafEntry(DBID id, NumberVector vector) {
super(id, vector);
this.hasHandled = false;
this.hasUnhandled = true;
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluNode.java
index 7b3221c3..4fc22177 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
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
@@ -61,7 +61,7 @@ public class DeLiCluNode extends AbstractRStarTreeNode<DeLiCluNode, DeLiCluEntry
* handled data objects
*/
public boolean hasHandled() {
- for(int i = 1; i < getNumEntries(); i++) {
+ for(int i = 0; i < getNumEntries(); i++) {
boolean handled = getEntry(i).hasHandled();
if(handled) {
return true;
@@ -78,7 +78,7 @@ public class DeLiCluNode extends AbstractRStarTreeNode<DeLiCluNode, DeLiCluEntry
* unhandled data objects
*/
public boolean hasUnhandled() {
- for(int i = 1; i < getNumEntries(); i++) {
+ for(int i = 0; i < getNumEntries(); i++) {
boolean handled = getEntry(i).hasUnhandled();
if(handled) {
return true;
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTree.java
index 33366763..a2adca7f 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
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/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeFactory.java
index a63b8004..b7770e79 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
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.persistent.PageFileFactory;
*
* @param <O> Object type
*/
-public class DeLiCluTreeFactory<O extends NumberVector<?>> extends AbstractRStarTreeFactory<O, DeLiCluNode, DeLiCluEntry, DeLiCluTreeIndex<O>, AbstractRTreeSettings> {
+public class DeLiCluTreeFactory<O extends NumberVector> extends AbstractRStarTreeFactory<O, DeLiCluNode, DeLiCluEntry, DeLiCluTreeIndex<O>, AbstractRTreeSettings> {
/**
* Constructor.
*
@@ -69,7 +69,7 @@ public class DeLiCluTreeFactory<O extends NumberVector<?>> extends AbstractRStar
*
* @apiviz.exclude
*/
- public static class Parameterizer<O extends NumberVector<?>> extends AbstractRStarTreeFactory.Parameterizer<O, AbstractRTreeSettings> {
+ public static class Parameterizer<O extends NumberVector> extends AbstractRStarTreeFactory.Parameterizer<O, AbstractRTreeSettings> {
@Override
protected DeLiCluTreeFactory<O> makeInstance() {
return new DeLiCluTreeFactory<>(pageFileFactory, settings);
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeIndex.java
index 67c9c9e0..6bc6c171 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
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
@@ -37,7 +37,6 @@ import de.lmu.ifi.dbs.elki.database.query.distance.SpatialDistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
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.DynamicIndex;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
import de.lmu.ifi.dbs.elki.index.RangeIndex;
@@ -56,7 +55,7 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
*
* @param <O> Object type
*/
-public class DeLiCluTreeIndex<O extends NumberVector<?>> extends DeLiCluTree implements KNNIndex<O>, RangeIndex<O>, DynamicIndex {
+public class DeLiCluTreeIndex<O extends NumberVector> extends DeLiCluTree implements KNNIndex<O>, RangeIndex<O>, DynamicIndex {
/**
* The relation we index.
*/
@@ -97,14 +96,14 @@ public class DeLiCluTreeIndex<O extends NumberVector<?>> extends DeLiCluTree imp
* @return the path of node ids from the root to the objects's parent
*/
public synchronized List<TreeIndexPathComponent<DeLiCluEntry>> setHandled(DBID id, O obj) {
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
LOG.debugFine("setHandled " + id + ", " + obj + "\n");
}
// find the leaf node containing o
IndexTreePath<DeLiCluEntry> pathToObject = findPathToObject(getRootPath(), obj, id);
- if (pathToObject == null) {
+ if(pathToObject == null) {
throw new AbortException("Object not found in setHandled.");
}
@@ -113,12 +112,12 @@ public class DeLiCluTreeIndex<O extends NumberVector<?>> extends DeLiCluTree imp
entry.setHasHandled(true);
entry.setHasUnhandled(false);
- for (IndexTreePath<DeLiCluEntry> path = pathToObject; path.getParentPath() != null; path = path.getParentPath()) {
+ for(IndexTreePath<DeLiCluEntry> path = pathToObject; path.getParentPath() != null; path = path.getParentPath()) {
DeLiCluEntry parentEntry = path.getParentPath().getLastPathComponent().getEntry();
DeLiCluNode node = getNode(parentEntry);
boolean hasHandled = false;
boolean hasUnhandled = false;
- for (int i = 0; i < node.getNumEntries(); i++) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
final DeLiCluEntry nodeEntry = node.getEntry(i);
hasHandled = hasHandled || nodeEntry.hasHandled();
hasUnhandled = hasUnhandled || nodeEntry.hasUnhandled();
@@ -154,19 +153,20 @@ public class DeLiCluTreeIndex<O extends NumberVector<?>> extends DeLiCluTree imp
*/
@Override
public final void insertAll(DBIDs ids) {
- if (ids.isEmpty() || (ids.size() == 1)) {
+ if(ids.isEmpty() || (ids.size() == 1)) {
return;
}
// Make an example leaf
- if (canBulkLoad()) {
+ if(canBulkLoad()) {
List<DeLiCluEntry> leafs = new ArrayList<>(ids.size());
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
leafs.add(createNewLeafEntry(DBIDUtil.deref(iter)));
}
bulkLoad(leafs);
- } else {
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ }
+ else {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
insert(iter);
}
}
@@ -185,7 +185,7 @@ public class DeLiCluTreeIndex<O extends NumberVector<?>> extends DeLiCluTree imp
// find the leaf node containing o
O obj = relation.get(id);
IndexTreePath<DeLiCluEntry> deletionPath = findPathToObject(getRootPath(), obj, id);
- if (deletionPath == null) {
+ if(deletionPath == null) {
return false;
}
deletePath(deletionPath);
@@ -194,36 +194,36 @@ public class DeLiCluTreeIndex<O extends NumberVector<?>> extends DeLiCluTree imp
@Override
public void deleteAll(DBIDs ids) {
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
delete(DBIDUtil.deref(iter));
}
}
@Override
- public <D extends Distance<D>> RangeQuery<O, D> getRangeQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
+ public RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
// Query on the relation we index
- if (distanceQuery.getRelation() != relation) {
+ if(distanceQuery.getRelation() != relation) {
return null;
}
// Can we support this distance function - spatial distances only!
- if (!(distanceQuery instanceof SpatialDistanceQuery)) {
+ if(!(distanceQuery instanceof SpatialDistanceQuery)) {
return null;
}
- SpatialDistanceQuery<O, D> dq = (SpatialDistanceQuery<O, D>) distanceQuery;
+ SpatialDistanceQuery<O> dq = (SpatialDistanceQuery<O>) distanceQuery;
return RStarTreeUtil.getRangeQuery(this, dq, hints);
}
@Override
- public <D extends Distance<D>> KNNQuery<O, D> getKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
// Query on the relation we index
- if (distanceQuery.getRelation() != relation) {
+ if(distanceQuery.getRelation() != relation) {
return null;
}
// Can we support this distance function - spatial distances only!
- if (!(distanceQuery instanceof SpatialDistanceQuery)) {
+ if(!(distanceQuery instanceof SpatialDistanceQuery)) {
return null;
}
- SpatialDistanceQuery<O, D> dq = (SpatialDistanceQuery<O, D>) distanceQuery;
+ SpatialDistanceQuery<O> dq = (SpatialDistanceQuery<O>) distanceQuery;
return RStarTreeUtil.getKNNQuery(this, dq, hints);
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/package-info.java
index f8bec8cb..e17df1ca 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/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/index/tree/spatial/rstarvariants/flat/FlatRStarTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTree.java
new file mode 100644
index 00000000..498abc58
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTree.java
@@ -0,0 +1,228 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.flat;
+
+/*
+ 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.List;
+
+import de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox;
+import de.lmu.ifi.dbs.elki.index.tree.TreeIndexHeader;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRTreeSettings;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.persistent.PageFile;
+
+/**
+ * FlatRTree is a spatial index structure based on a R*-Tree but with a flat
+ * directory. Apart from organizing the objects it also provides several methods
+ * to search for certain object in the structure and ensures persistence.
+ *
+ * @author Elke Achtert
+ *
+ * @apiviz.has FlatRStarTreeNode oneway - - contains
+ */
+public class FlatRStarTree extends AbstractRStarTree<FlatRStarTreeNode, SpatialEntry, AbstractRTreeSettings> {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(FlatRStarTree.class);
+
+ /**
+ * The root of this flat RTree.
+ */
+ private FlatRStarTreeNode root;
+
+ /**
+ * Constructor.
+ *
+ * @param pagefile Page file
+ * @param settings Tree settings
+ */
+ public FlatRStarTree(PageFile<FlatRStarTreeNode> pagefile, AbstractRTreeSettings settings) {
+ super(pagefile, settings);
+ }
+
+ /**
+ * Initializes the flat RTree from an existing persistent file.
+ */
+ @Override
+ public void initializeFromFile(TreeIndexHeader header, PageFile<FlatRStarTreeNode> file) {
+ super.initializeFromFile(header, file);
+
+ // reconstruct root
+ int nextPageID = file.getNextPageID();
+ dirCapacity = nextPageID;
+ root = createNewDirectoryNode();
+ for(int i = 1; i < nextPageID; i++) {
+ FlatRStarTreeNode node = getNode(i);
+ root.addDirectoryEntry(createNewDirectoryEntry(node));
+ }
+
+ if(LOG.isDebugging()) {
+ LOG.debugFine("root: " + root + " with " + nextPageID + " leafNodes.");
+ }
+ }
+
+ /**
+ * Returns the root node of this RTree.
+ *
+ * @return the root node of this RTree
+ */
+ @Override
+ public FlatRStarTreeNode getRoot() {
+ return root;
+ }
+
+ /**
+ * Returns the height of this FlatRTree.
+ *
+ * @return 2
+ */
+ @Override
+ protected int computeHeight() {
+ return 2;
+ }
+
+ /**
+ * Performs a bulk load on this RTree with the specified data. Is called by
+ * the constructor and should be overwritten by subclasses if necessary.
+ */
+ @Override
+ protected void bulkLoad(List<SpatialEntry> spatialObjects) {
+ if(!initialized) {
+ initialize(spatialObjects.get(0));
+ }
+ // create leaf nodes
+ getFile().setNextPageID(getRootID() + 1);
+ List<SpatialEntry> nodes = createBulkLeafNodes(spatialObjects);
+ int numNodes = nodes.size();
+ if(LOG.isDebugging()) {
+ LOG.debugFine(" numLeafNodes = " + numNodes);
+ }
+
+ // create root
+ root = createNewDirectoryNode();
+ root.setPageID(getRootID());
+ for(SpatialEntry entry : nodes) {
+ root.addDirectoryEntry(entry);
+ }
+ numNodes++;
+ setHeight(2);
+
+ if(LOG.isDebugging()) {
+ StringBuilder msg = new StringBuilder();
+ msg.append(" root = ").append(getRoot());
+ msg.append("\n numNodes = ").append(numNodes);
+ msg.append("\n height = ").append(getHeight());
+ LOG.debugFine(msg.toString() + "\n");
+ }
+ doExtraIntegrityChecks();
+ }
+
+ @Override
+ protected void createEmptyRoot(SpatialEntry exampleLeaf) {
+ root = createNewDirectoryNode();
+ root.setPageID(getRootID());
+
+ getFile().setNextPageID(getRootID() + 1);
+ FlatRStarTreeNode leaf = createNewLeafNode();
+ writeNode(leaf);
+ ModifiableHyperBoundingBox mbr = new ModifiableHyperBoundingBox(new double[exampleLeaf.getDimensionality()], new double[exampleLeaf.getDimensionality()]);
+ root.addDirectoryEntry(new SpatialDirectoryEntry(leaf.getPageID(), mbr));
+
+ setHeight(2);
+ }
+
+ /**
+ * Returns true if in the specified node an overflow occurred, false
+ * otherwise.
+ *
+ * @param node the node to be tested for overflow
+ * @return true if in the specified node an overflow occurred, false otherwise
+ */
+ @Override
+ protected boolean hasOverflow(FlatRStarTreeNode node) {
+ if(node.isLeaf()) {
+ return node.getNumEntries() == leafCapacity;
+ }
+ else if(node.getNumEntries() == node.getCapacity()) {
+ node.increaseEntries();
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if in the specified node an underflow occurred, false
+ * otherwise.
+ *
+ * @param node the node to be tested for underflow
+ * @return true if in the specified node an underflow occurred, false
+ * otherwise
+ */
+ @Override
+ protected boolean hasUnderflow(FlatRStarTreeNode node) {
+ if(node.isLeaf()) {
+ return node.getNumEntries() < leafMinimum;
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * Creates a new leaf node with the specified capacity.
+ *
+ * @return a new leaf node
+ */
+ @Override
+ protected FlatRStarTreeNode createNewLeafNode() {
+ return new FlatRStarTreeNode(leafCapacity, true);
+ }
+
+ /**
+ * Creates a new directory node with the specified capacity.
+ *
+ * @return a new directory node
+ */
+ @Override
+ protected FlatRStarTreeNode createNewDirectoryNode() {
+ return new FlatRStarTreeNode(dirCapacity, false);
+ }
+
+ @Override
+ protected SpatialEntry createNewDirectoryEntry(FlatRStarTreeNode node) {
+ return new SpatialDirectoryEntry(node.getPageID(), node.computeMBR());
+ }
+
+ @Override
+ protected SpatialEntry createRootEntry() {
+ return new SpatialDirectoryEntry(0, null);
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTreeFactory.java
new file mode 100644
index 00000000..ea631ecd
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTreeFactory.java
@@ -0,0 +1,84 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.flat;
+
+/*
+ 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.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeFactory;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRTreeSettings;
+import de.lmu.ifi.dbs.elki.persistent.PageFile;
+import de.lmu.ifi.dbs.elki.persistent.PageFileFactory;
+
+/**
+ * Factory for flat R*-Trees.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.stereotype factory
+ * @apiviz.uses FlatRStarTreeIndex oneway - - «create»
+ *
+ * @param <O> Object type
+ */
+public class FlatRStarTreeFactory<O extends NumberVector> extends AbstractRStarTreeFactory<O, FlatRStarTreeNode, SpatialEntry, FlatRStarTreeIndex<O>, AbstractRTreeSettings> {
+ /**
+ * Constructor.
+ *
+ * @param pageFileFactory Data storage
+ * @param settings Index settings
+ */
+ public FlatRStarTreeFactory(PageFileFactory<?> pageFileFactory, AbstractRTreeSettings settings) {
+ super(pageFileFactory, settings);
+ }
+
+ @Override
+ public FlatRStarTreeIndex<O> instantiate(Relation<O> relation) {
+ PageFile<FlatRStarTreeNode> pagefile = makePageFile(getNodeClass());
+ FlatRStarTreeIndex<O> index = new FlatRStarTreeIndex<>(relation, pagefile, settings);
+ return index;
+ }
+
+ protected Class<FlatRStarTreeNode> getNodeClass() {
+ return FlatRStarTreeNode.class;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<O extends NumberVector> extends AbstractRStarTreeFactory.Parameterizer<O, AbstractRTreeSettings> {
+ @Override
+ protected FlatRStarTreeFactory<O> makeInstance() {
+ return new FlatRStarTreeFactory<>(pageFileFactory, settings);
+ }
+
+ @Override
+ protected AbstractRTreeSettings createSettings() {
+ return new AbstractRTreeSettings();
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTreeIndex.java
new file mode 100644
index 00000000..6b5204e5
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTreeIndex.java
@@ -0,0 +1,203 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.flat;
+
+/*
+ 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.ArrayList;
+import java.util.List;
+
+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.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.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.distance.SpatialDistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.index.DynamicIndex;
+import de.lmu.ifi.dbs.elki.index.KNNIndex;
+import de.lmu.ifi.dbs.elki.index.RangeIndex;
+import de.lmu.ifi.dbs.elki.index.tree.IndexTreePath;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialPointLeafEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRTreeSettings;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query.RStarTreeUtil;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.persistent.PageFile;
+
+/**
+ * The common use of the flat rstar tree: indexing number vectors.
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Object type
+ */
+public class FlatRStarTreeIndex<O extends NumberVector> extends FlatRStarTree implements RangeIndex<O>, KNNIndex<O>, DynamicIndex {
+ /**
+ * The relation we index
+ */
+ private Relation<O> relation;
+
+ /**
+ * Constructor.
+ *
+ * @param relation Relation to index
+ * @param pagefile Page file
+ * @param settings Tree settings
+ */
+ public FlatRStarTreeIndex(Relation<O> relation, PageFile<FlatRStarTreeNode> pagefile, AbstractRTreeSettings settings) {
+ super(pagefile, settings);
+ this.relation = relation;
+ }
+
+ /**
+ * The appropriate logger for this index.
+ */
+ private static final Logging LOG = Logging.getLogger(FlatRStarTreeIndex.class);
+
+ /**
+ * Wrap a vector as spatial point leaf entry.
+ *
+ * @param id Object DBID
+ * @return spatial leaf
+ */
+ protected SpatialEntry createNewLeafEntry(DBID id) {
+ return new SpatialPointLeafEntry(id, relation.get(id));
+ }
+
+ @Override
+ public void initialize() {
+ super.initialize();
+ insertAll(relation.getDBIDs());
+ }
+
+ /**
+ * Inserts the specified real vector object into this index.
+ *
+ * @param id the object id that was inserted
+ */
+ @Override
+ public final void insert(DBIDRef id) {
+ insertLeaf(createNewLeafEntry(DBIDUtil.deref(id)));
+ }
+
+ /**
+ * Inserts the specified objects into this index. If a bulk load mode is
+ * implemented, the objects are inserted in one bulk.
+ *
+ * @param ids the objects to be inserted
+ */
+ @Override
+ public final void insertAll(DBIDs ids) {
+ if(ids.isEmpty() || (ids.size() == 1)) {
+ return;
+ }
+
+ // Make an example leaf
+ if(canBulkLoad()) {
+ List<SpatialEntry> leafs = new ArrayList<>(ids.size());
+ for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ leafs.add(createNewLeafEntry(DBIDUtil.deref(iter)));
+ }
+ bulkLoad(leafs);
+ }
+ else {
+ for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ insert(iter);
+ }
+ }
+
+ doExtraIntegrityChecks();
+ }
+
+ /**
+ * Deletes the specified object from this index.
+ *
+ * @return true if this index did contain the object with the specified id,
+ * false otherwise
+ */
+ @Override
+ public final boolean delete(DBIDRef id) {
+ // find the leaf node containing o
+ O obj = relation.get(id);
+ IndexTreePath<SpatialEntry> deletionPath = findPathToObject(getRootPath(), obj, id);
+ if(deletionPath == null) {
+ return false;
+ }
+ deletePath(deletionPath);
+ return true;
+ }
+
+ @Override
+ public void deleteAll(DBIDs ids) {
+ for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ delete(DBIDUtil.deref(iter));
+ }
+ }
+
+ @Override
+ public RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ // Query on the relation we index
+ if(distanceQuery.getRelation() != relation) {
+ return null;
+ }
+ // Can we support this distance function - spatial distances only!
+ if(!(distanceQuery instanceof SpatialDistanceQuery)) {
+ return null;
+ }
+ SpatialDistanceQuery<O> dq = (SpatialDistanceQuery<O>) distanceQuery;
+ return RStarTreeUtil.getRangeQuery(this, dq, hints);
+ }
+
+ @Override
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ // Query on the relation we index
+ if(distanceQuery.getRelation() != relation) {
+ return null;
+ }
+ // Can we support this distance function - spatial distances only!
+ if(!(distanceQuery instanceof SpatialDistanceQuery)) {
+ return null;
+ }
+ SpatialDistanceQuery<O> dq = (SpatialDistanceQuery<O>) distanceQuery;
+ return RStarTreeUtil.getKNNQuery(this, dq, hints);
+ }
+
+ @Override
+ public String getLongName() {
+ return "Flat R*-Tree";
+ }
+
+ @Override
+ public String getShortName() {
+ return "flatrstartree";
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTreeNode.java
new file mode 100644
index 00000000..7015577d
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/FlatRStarTreeNode.java
@@ -0,0 +1,81 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.flat;
+
+/*
+ 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.index.tree.spatial.SpatialEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeNode;
+import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
+
+/**
+ * Represents a node in a flat R*-Tree.
+ *
+ * @author Elke Achtert
+ */
+public class FlatRStarTreeNode extends AbstractRStarTreeNode<FlatRStarTreeNode, SpatialEntry> {
+ /**
+ * Serial version
+ */
+ private static final long serialVersionUID = 1;
+
+ /**
+ * Empty constructor for Externalizable interface.
+ */
+ public FlatRStarTreeNode() {
+ // empty constructor
+ }
+
+ /**
+ * Deletes the entry at the specified index and shifts all entries after the
+ * index to left.
+ *
+ * @param index the index at which the entry is to be deleted
+ */
+ @Override
+ public boolean deleteEntry(int index) {
+ if(this.getPageID() == 0 && index == 0 && getNumEntries() == 1) {
+ return false;
+ }
+ return super.deleteEntry(index);
+ }
+
+ /**
+ * Creates a new FlatRStarTreeNode with the specified parameters.
+ *
+ * @param capacity the capacity (maximum number of entries plus 1 for
+ * overflow) of this node
+ * @param isLeaf indicates whether this node is a leaf node
+ */
+ public FlatRStarTreeNode(int capacity, boolean isLeaf) {
+ super(capacity, isLeaf, SpatialEntry.class);
+ }
+
+ /**
+ * Increases the length of the entries array to entries.length + 1.
+ */
+ public final void increaseEntries() {
+ SpatialEntry[] tmp = entries;
+ entries = ClassGenericsUtil.newArrayOfNull(tmp.length + 1, SpatialEntry.class);
+ System.arraycopy(tmp, 0, entries, 0, tmp.length);
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/package-info.java
index 4c529c66..fd092666 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/package-info.java
@@ -1,11 +1,11 @@
/**
- * <p>Index using a preprocessed local subspaces.</p>
+ * <p>{@link de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.flat.FlatRStarTree}</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
@@ -23,4 +23,4 @@ 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.index.preprocessed.subspaceproj; \ No newline at end of file
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.flat; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/package-info.java
index e50cc513..aa47110c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/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/index/tree/spatial/rstarvariants/query/EuclideanRStarTreeKNNQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/EuclideanRStarTreeKNNQuery.java
new file mode 100644
index 00000000..e1763d3e
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/EuclideanRStarTreeKNNQuery.java
@@ -0,0 +1,167 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query;
+
+/*
+ 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.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.database.QueryUtil;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
+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.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.index.tree.query.DoubleDistanceSearchCandidate;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialPointLeafEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeNode;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+
+/**
+ * Instance of a KNN query for a particular spatial index.
+ *
+ * Reference:
+ * <p>
+ * G. R. Hjaltason, H. Samet<br />
+ * Ranking in spatial databases<br />
+ * In: 4th Symposium on Advances in Spatial Databases, SSD'95
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.uses EuclideanDistanceFunction
+ * @apiviz.uses SquaredEuclideanDistanceFunction
+ */
+@Reference(authors = "G. R. Hjaltason, H. Samet", //
+title = "Ranking in spatial databases", //
+booktitle = "Advances in Spatial Databases - 4th Symposium, SSD'95", //
+url = "http://dx.doi.org/10.1007/3-540-60159-7_6")
+public class EuclideanRStarTreeKNNQuery<O extends NumberVector> extends RStarTreeKNNQuery<O> {
+ /**
+ * Squared euclidean distance function.
+ */
+ private static final SquaredEuclideanDistanceFunction SQUARED = SquaredEuclideanDistanceFunction.STATIC;
+
+ /**
+ * Constructor.
+ *
+ * @param tree Index to use
+ * @param relation Data relation to query
+ */
+ public EuclideanRStarTreeKNNQuery(AbstractRStarTree<?, ?, ?> tree, Relation<? extends O> relation) {
+ super(tree, relation, EuclideanDistanceFunction.STATIC);
+ }
+
+ @Override
+ public KNNList getKNNForObject(O obj, int k) {
+ if(k < 1) {
+ throw new IllegalArgumentException("At least one neighbor has to be requested!");
+ }
+ tree.statistics.countKNNQuery();
+
+ final KNNHeap knnList = DBIDUtil.newHeap(k);
+ final ComparableMinHeap<DoubleDistanceSearchCandidate> pq = new ComparableMinHeap<>(Math.min(knnList.getK() << 1, 21));
+
+ // expand root
+ double maxDist = expandNode(obj, knnList, pq, Double.MAX_VALUE, tree.getRootID());
+
+ // search in tree
+ while(!pq.isEmpty()) {
+ DoubleDistanceSearchCandidate pqNode = pq.poll();
+
+ if(pqNode.mindist > maxDist) {
+ break;
+ }
+ maxDist = expandNode(obj, knnList, pq, maxDist, pqNode.nodeID);
+ }
+ return QueryUtil.applySqrt(knnList.toKNNList());
+ }
+
+ private double expandNode(O object, KNNHeap knnList, final ComparableMinHeap<DoubleDistanceSearchCandidate> pq, double maxDist, final int nodeID) {
+ AbstractRStarTreeNode<?, ?> node = tree.getNode(nodeID);
+ // data node
+ if(node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ SpatialPointLeafEntry entry = (SpatialPointLeafEntry) node.getEntry(i);
+ double distance = SQUARED.minDist(entry, object);
+ tree.statistics.countDistanceCalculation();
+ if(distance <= maxDist) {
+ maxDist = knnList.insert(distance, entry.getDBID());
+ }
+ }
+ }
+ // directory node
+ else {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ SpatialDirectoryEntry entry = (SpatialDirectoryEntry) node.getEntry(i);
+ double distance = SQUARED.minDist(entry, object);
+ tree.statistics.countDistanceCalculation();
+ // Greedy expand, bypassing the queue
+ if(distance <= 0) {
+ expandNode(object, knnList, pq, maxDist, entry.getPageID());
+ }
+ else {
+ if(distance <= maxDist) {
+ pq.add(new DoubleDistanceSearchCandidate(distance, entry.getPageID()));
+ }
+ }
+ }
+ }
+ return maxDist;
+ }
+
+ @Override
+ public List<KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ if(k < 1) {
+ throw new IllegalArgumentException("At least one enumeration has to be requested!");
+ }
+
+ // While this works, it seems to be slow at least for large sets!
+ // TODO: use a DataStore instead of a map.
+ final Map<DBID, KNNHeap> knnLists = new HashMap<>(ids.size());
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ DBID id = DBIDUtil.deref(iter);
+ knnLists.put(id, DBIDUtil.newHeap(k));
+ }
+
+ batchNN(tree.getRoot(), knnLists);
+
+ List<KNNList> result = new ArrayList<>();
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ DBID id = DBIDUtil.deref(iter);
+ tree.statistics.countKNNQuery();
+ result.add(QueryUtil.applySqrt(knnLists.get(id).toKNNList()));
+ }
+ return result;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/EuclideanRStarTreeRangeQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/EuclideanRStarTreeRangeQuery.java
new file mode 100644
index 00000000..0fcb633b
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/EuclideanRStarTreeRangeQuery.java
@@ -0,0 +1,120 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query;
+
+/*
+ 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.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialPointLeafEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeNode;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+
+/**
+ * Instance of a range query for a particular spatial index.
+ *
+ * Reference:
+ * <p>
+ * J. Kuan, P. Lewis<br />
+ * Fast k nearest neighbour search for R-tree family<br />
+ * In Proc. Int. Conf Information, Communications and Signal Processing, ICICS
+ * 1997
+ * </p>
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.uses EuclideanDistanceFunction
+ * @apiviz.uses SquaredEuclideanDistanceFunction
+ */
+@Reference(authors = "J. Kuan, P. Lewis", title = "Fast k nearest neighbour search for R-tree family", booktitle = "Proc. Int. Conf Information, Communications and Signal Processing, ICICS 1997", url = "http://dx.doi.org/10.1109/ICICS.1997.652114")
+public class EuclideanRStarTreeRangeQuery<O extends NumberVector> extends RStarTreeRangeQuery<O> {
+ /**
+ * Squared euclidean distance function.
+ */
+ private static final SquaredEuclideanDistanceFunction SQUARED = SquaredEuclideanDistanceFunction.STATIC;
+
+ /**
+ * Constructor.
+ *
+ * @param tree Index to use
+ * @param relation Relation to use.
+ */
+ public EuclideanRStarTreeRangeQuery(AbstractRStarTree<?, ?, ?> tree, Relation<? extends O> relation) {
+ super(tree, relation, EuclideanDistanceFunction.STATIC);
+ }
+
+ @Override
+ public DoubleDBIDList getRangeForObject(O object, double range) {
+ tree.statistics.countRangeQuery();
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
+
+ final double sqepsilon = range * range;
+
+ // Processing queue.
+ int[] pq = new int[101];
+ int ps = 0;
+ pq[ps++] = tree.getRootID();
+
+ // search in tree
+ while(ps > 0) {
+ int pqNode = pq[--ps]; // Pop last.
+ AbstractRStarTreeNode<?, ?> node = tree.getNode(pqNode);
+ final int numEntries = node.getNumEntries();
+
+ if(node.isLeaf()) {
+ for(int i = 0; i < numEntries; i++) {
+ SpatialPointLeafEntry entry = (SpatialPointLeafEntry) node.getEntry(i);
+ double distance = SQUARED.minDist(object, entry);
+ tree.statistics.countDistanceCalculation();
+ if(distance <= sqepsilon) {
+ result.add(Math.sqrt(distance), entry.getDBID());
+ }
+ }
+ }
+ else {
+ for(int i = 0; i < numEntries; i++) {
+ SpatialDirectoryEntry entry = (SpatialDirectoryEntry) node.getEntry(i);
+ double distance = SQUARED.minDist(object, entry);
+ if(distance <= sqepsilon) {
+ if(ps == pq.length) { // Resize:
+ pq = Arrays.copyOf(pq, pq.length + (pq.length >>> 1));
+ }
+ pq[ps++] = entry.getEntryID();
+ }
+ }
+ }
+ }
+
+ // sort the result according to the distances
+ result.sort();
+ return result;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeKNNQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeKNNQuery.java
deleted file mode 100644
index 229758ea..00000000
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeKNNQuery.java
+++ /dev/null
@@ -1,243 +0,0 @@
-package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query;
-
-/*
- 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.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
-import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
-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.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.query.distance.SpatialDistanceQuery;
-import de.lmu.ifi.dbs.elki.database.query.knn.AbstractDistanceKNNQuery;
-import de.lmu.ifi.dbs.elki.distance.DistanceUtil;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.index.tree.DirectoryEntry;
-import de.lmu.ifi.dbs.elki.index.tree.LeafEntry;
-import de.lmu.ifi.dbs.elki.index.tree.query.GenericDistanceSearchCandidate;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeNode;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap;
-import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
-import de.lmu.ifi.dbs.elki.utilities.pairs.FCPair;
-
-/**
- * Instance of a KNN query for a particular spatial index.
- *
- * Reference:
- * <p>
- * G. R. Hjaltason, H. Samet<br />
- * Ranking in spatial databases<br />
- * In: 4th Symposium on Advances in Spatial Databases, SSD'95
- * </p>
- *
- * @author Erich Schubert
- *
- * @apiviz.uses AbstractRStarTree
- * @apiviz.uses SpatialPrimitiveDistanceFunction
- */
-@Reference(authors = "G. R. Hjaltason, H. Samet", title = "Ranking in spatial databases", booktitle = "Advances in Spatial Databases - 4th Symposium, SSD'95", url = "http://dx.doi.org/10.1007/3-540-60159-7_6")
-public class GenericRStarTreeKNNQuery<O extends SpatialComparable, D extends Distance<D>> extends AbstractDistanceKNNQuery<O, D> {
- /**
- * The index to use
- */
- protected final AbstractRStarTree<?, ?, ?> tree;
-
- /**
- * Spatial primitive distance function
- */
- protected final SpatialPrimitiveDistanceFunction<? super O, D> distanceFunction;
-
- /**
- * Constructor.
- *
- * @param tree Index to use
- * @param distanceQuery Distance query to use
- */
- public GenericRStarTreeKNNQuery(AbstractRStarTree<?, ?, ?> tree, SpatialDistanceQuery<O, D> distanceQuery) {
- super(distanceQuery);
- this.tree = tree;
- this.distanceFunction = distanceQuery.getDistanceFunction();
- }
-
- /**
- * Performs a batch knn query.
- *
- * @param node the node for which the query should be performed
- * @param knnLists a map containing the knn lists for each query objects
- */
- protected void batchNN(AbstractRStarTreeNode<?, ?> node, Map<DBID, KNNHeap<D>> knnLists) {
- if(node.isLeaf()) {
- for(int i = 0; i < node.getNumEntries(); i++) {
- SpatialEntry p = node.getEntry(i);
- for(Entry<DBID, KNNHeap<D>> ent : knnLists.entrySet()) {
- final DBID q = ent.getKey();
- final KNNHeap<D> knns_q = ent.getValue();
- D knn_q_maxDist = knns_q.getKNNDistance();
-
- DBID pid = ((LeafEntry) p).getDBID();
- // FIXME: objects are NOT accessible by DBID in a plain rtree context!
- D dist_pq = distanceQuery.distance(pid, q);
- tree.statistics.countDistanceCalculation();
- if(dist_pq.compareTo(knn_q_maxDist) <= 0) {
- knns_q.insert(dist_pq, pid);
- }
- }
- }
- }
- else {
- ModifiableDBIDs ids = DBIDUtil.newArray(knnLists.size());
- for(DBID id : knnLists.keySet()) {
- ids.add(id);
- }
- List<FCPair<D, SpatialEntry>> entries = getSortedEntries(node, ids);
- for(FCPair<D, SpatialEntry> distEntry : entries) {
- D minDist = distEntry.first;
- for(Entry<DBID, KNNHeap<D>> ent : knnLists.entrySet()) {
- final KNNHeap<D> knns_q = ent.getValue();
- D knn_q_maxDist = knns_q.getKNNDistance();
-
- if(minDist.compareTo(knn_q_maxDist) <= 0) {
- SpatialEntry entry = distEntry.second;
- AbstractRStarTreeNode<?, ?> child = tree.getNode(((DirectoryEntry) entry).getPageID().intValue());
- batchNN(child, knnLists);
- break;
- }
- }
- }
- }
- }
-
- /**
- * Sorts the entries of the specified node according to their minimum distance
- * to the specified objects.
- *
- * @param node the node
- * @param ids the id of the objects
- * @return a list of the sorted entries
- */
- protected List<FCPair<D, SpatialEntry>> getSortedEntries(AbstractRStarTreeNode<?, ?> node, DBIDs ids) {
- List<FCPair<D, SpatialEntry>> result = new ArrayList<>();
-
- for(int i = 0; i < node.getNumEntries(); i++) {
- SpatialEntry entry = node.getEntry(i);
- D minMinDist = distanceQuery.getDistanceFactory().infiniteDistance();
- for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- D minDist = distanceFunction.minDist(entry, relation.get(iter));
- tree.statistics.countDistanceCalculation();
- minMinDist = DistanceUtil.min(minDist, minMinDist);
- }
- result.add(new FCPair<>(minMinDist, entry));
- }
-
- Collections.sort(result);
- return result;
- }
-
- @Override
- public KNNList<D> getKNNForObject(O obj, int k) {
- final KNNHeap<D> knnList = DBIDUtil.newHeap(distanceFunction.getDistanceFactory(), k);
- final ComparableMinHeap<GenericDistanceSearchCandidate<D>> pq = new ComparableMinHeap<>(Math.min(knnList.getK() << 1, 20));
- tree.statistics.countKNNQuery();
-
- // push root
- pq.add(new GenericDistanceSearchCandidate<>(distanceFunction.getDistanceFactory().nullDistance(), tree.getRootID()));
- D maxDist = distanceFunction.getDistanceFactory().infiniteDistance();
-
- // search in tree
- while(!pq.isEmpty()) {
- GenericDistanceSearchCandidate<D> pqNode = pq.poll();
-
- if(pqNode.mindist.compareTo(maxDist) > 0) {
- break;
- }
- maxDist = expandNode(obj, knnList, pq, maxDist, pqNode.nodeID);
- }
- return knnList.toKNNList();
- }
-
- private D expandNode(O object, KNNHeap<D> knnList, final ComparableMinHeap<GenericDistanceSearchCandidate<D>> pq, D maxDist, final int nodeID) {
- AbstractRStarTreeNode<?, ?> node = tree.getNode(nodeID);
- // data node
- if(node.isLeaf()) {
- for(int i = 0; i < node.getNumEntries(); i++) {
- SpatialEntry entry = node.getEntry(i);
- D distance = distanceFunction.minDist(entry, object);
- tree.statistics.countDistanceCalculation();
- if(distance.compareTo(maxDist) <= 0) {
- knnList.insert(distance, ((LeafEntry) entry).getDBID());
- maxDist = knnList.getKNNDistance();
- }
- }
- }
- // directory node
- else {
- for(int i = 0; i < node.getNumEntries(); i++) {
- SpatialEntry entry = node.getEntry(i);
- D distance = distanceFunction.minDist(entry, object);
- tree.statistics.countDistanceCalculation();
- // Greedy expand, bypassing the queue
- if(distance.isNullDistance()) {
- expandNode(object, knnList, pq, maxDist, ((DirectoryEntry) entry).getPageID());
- }
- else {
- if(distance.compareTo(maxDist) <= 0) {
- pq.add(new GenericDistanceSearchCandidate<>(distance, ((DirectoryEntry) entry).getPageID()));
- }
- }
- }
- }
- return maxDist;
- }
-
- @Override
- public List<KNNList<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
- // While this works, it seems to be slow at least for large sets!
- final Map<DBID, KNNHeap<D>> knnLists = new HashMap<>(ids.size());
- for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- knnLists.put(DBIDUtil.deref(iter), DBIDUtil.newHeap(distanceFunction.getDistanceFactory(), k));
- }
-
- batchNN(tree.getRoot(), knnLists);
-
- List<KNNList<D>> result = new ArrayList<>();
- for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- tree.statistics.countKNNQuery();
- result.add(knnLists.get(DBIDUtil.deref(iter)).toKNNList());
- }
- return result;
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeRangeQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeRangeQuery.java
deleted file mode 100644
index 16a3393a..00000000
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeRangeQuery.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query;
-
-/*
- 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.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.query.distance.SpatialDistanceQuery;
-import de.lmu.ifi.dbs.elki.database.query.range.AbstractDistanceRangeQuery;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.index.tree.DirectoryEntry;
-import de.lmu.ifi.dbs.elki.index.tree.LeafEntry;
-import de.lmu.ifi.dbs.elki.index.tree.query.GenericDistanceSearchCandidate;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeNode;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap;
-import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
-
-/**
- * Instance of a range query for a particular spatial index.
- *
- * Reference:
- * <p>
- * J. Kuan, P. Lewis<br />
- * Fast k nearest neighbour search for R-tree family<br />
- * In Proc. Int. Conf Information, Communications and Signal Processing, ICICS
- * 1997
- * </p>
- *
- * @author Erich Schubert
- *
- * @apiviz.uses AbstractRStarTree
- * @apiviz.uses SpatialPrimitiveDistanceFunction
- */
-@Reference(authors = "J. Kuan, P. Lewis", title = "Fast k nearest neighbour search for R-tree family", booktitle = "Proc. Int. Conf Information, Communications and Signal Processing, ICICS 1997", url = "http://dx.doi.org/10.1109/ICICS.1997.652114")
-public class GenericRStarTreeRangeQuery<O extends SpatialComparable, D extends Distance<D>> extends AbstractDistanceRangeQuery<O, D> {
- /**
- * The index to use
- */
- protected final AbstractRStarTree<?, ?, ?> tree;
-
- /**
- * Spatial primitive distance function
- */
- protected final SpatialPrimitiveDistanceFunction<? super O, D> distanceFunction;
-
- /**
- * Constructor.
- *
- * @param tree Index to use
- * @param distanceQuery Distance query to use
- */
- public GenericRStarTreeRangeQuery(AbstractRStarTree<?, ?, ?> tree, SpatialDistanceQuery<O, D> distanceQuery) {
- super(distanceQuery);
- this.tree = tree;
- this.distanceFunction = distanceQuery.getDistanceFunction();
- }
-
- /**
- * Perform the actual query process.
- *
- * @param object Query object
- * @param epsilon Query range
- * @return Objects contained in query range.
- */
- protected DistanceDBIDList<D> doRangeQuery(O object, D epsilon) {
- final GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>();
- final ComparableMinHeap<GenericDistanceSearchCandidate<D>> pq = new ComparableMinHeap<>();
- tree.statistics.countRangeQuery();
-
- // push root
- pq.add(new GenericDistanceSearchCandidate<>(distanceFunction.getDistanceFactory().nullDistance(), tree.getRootID()));
-
- // search in tree
- while(!pq.isEmpty()) {
- GenericDistanceSearchCandidate<D> pqNode = pq.poll();
- if(pqNode.mindist.compareTo(epsilon) > 0) {
- break;
- }
-
- AbstractRStarTreeNode<?, ?> node = tree.getNode(pqNode.nodeID);
- final int numEntries = node.getNumEntries();
-
- for(int i = 0; i < numEntries; i++) {
- D distance = distanceFunction.minDist(node.getEntry(i), object);
- tree.statistics.countDistanceCalculation();
- if(distance.compareTo(epsilon) <= 0) {
- if(node.isLeaf()) {
- LeafEntry entry = (LeafEntry) node.getEntry(i);
- result.add(distance, entry.getDBID());
- }
- else {
- DirectoryEntry entry = (DirectoryEntry) node.getEntry(i);
- pq.add(new GenericDistanceSearchCandidate<>(distance, entry.getEntryID()));
- }
- }
- }
- }
-
- // sort the result according to the distances
- result.sort();
- return result;
- }
-
- @Override
- public DistanceDBIDList<D> getRangeForObject(O obj, D range) {
- return doRangeQuery(obj, range);
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeKNNQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeKNNQuery.java
index 472e4b57..f0e6e01e 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeKNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query;
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,16 +34,15 @@ import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
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.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.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.database.ids.integer.DoubleDistanceIntegerDBIDKNNHeap;
-import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.database.query.knn.AbstractDistanceKNNQuery;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+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.distancefunction.SpatialPrimitiveDistanceFunction;
import de.lmu.ifi.dbs.elki.index.tree.DirectoryEntry;
import de.lmu.ifi.dbs.elki.index.tree.LeafEntry;
import de.lmu.ifi.dbs.elki.index.tree.query.DoubleDistanceSearchCandidate;
@@ -68,41 +67,56 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* @author Erich Schubert
*
* @apiviz.uses AbstractRStarTree
- * @apiviz.uses SpatialPrimitiveDoubleDistanceFunction
+ * @apiviz.uses SpatialPrimitiveDistanceFunction
+ * @apiviz.uses DoubleDistanceSearchCandidate
*/
-@Reference(authors = "G. R. Hjaltason, H. Samet", title = "Ranking in spatial databases", booktitle = "Advances in Spatial Databases - 4th Symposium, SSD'95", url = "http://dx.doi.org/10.1007/3-540-60159-7_6")
-public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extends AbstractDistanceKNNQuery<O, DoubleDistance> {
+@Reference(authors = "G. R. Hjaltason, H. Samet", //
+title = "Ranking in spatial databases", //
+booktitle = "Advances in Spatial Databases - 4th Symposium, SSD'95", //
+url = "http://dx.doi.org/10.1007/3-540-60159-7_6")
+public class RStarTreeKNNQuery<O extends SpatialComparable> implements KNNQuery<O> {
/**
* The index to use
*/
protected final AbstractRStarTree<?, ?, ?> tree;
/**
- * Spatial primitive distance function
+ * Spatial primitive distance function.
*/
- protected final SpatialPrimitiveDoubleDistanceFunction<? super O> distanceFunction;
+ protected final SpatialPrimitiveDistanceFunction<? super O> distanceFunction;
+
+ /**
+ * Relation we query.
+ */
+ protected Relation<? extends O> relation;
/**
* Constructor.
*
* @param tree Index to use
- * @param distanceQuery Distance query to use
+ * @param relation Data relation to query
* @param distanceFunction Distance function
*/
- public DoubleDistanceRStarTreeKNNQuery(AbstractRStarTree<?, ?, ?> tree, DistanceQuery<O, DoubleDistance> distanceQuery, SpatialPrimitiveDoubleDistanceFunction<? super O> distanceFunction) {
- super(distanceQuery);
+ public RStarTreeKNNQuery(AbstractRStarTree<?, ?, ?> tree, Relation<? extends O> relation, SpatialPrimitiveDistanceFunction<? super O> distanceFunction) {
+ super();
+ this.relation = relation;
this.tree = tree;
this.distanceFunction = distanceFunction;
}
@Override
- public DoubleDistanceKNNList getKNNForObject(O obj, int k) {
+ public KNNList getKNNForDBID(DBIDRef id, int k) {
+ return getKNNForObject(relation.get(id), k);
+ }
+
+ @Override
+ public KNNList getKNNForObject(O obj, int k) {
if(k < 1) {
throw new IllegalArgumentException("At least one neighbor has to be requested!");
}
tree.statistics.countKNNQuery();
- final DoubleDistanceKNNHeap knnList = new DoubleDistanceIntegerDBIDKNNHeap(k);
+ final KNNHeap knnList = DBIDUtil.newHeap(k);
final ComparableMinHeap<DoubleDistanceSearchCandidate> pq = new ComparableMinHeap<>(Math.min(knnList.getK() << 1, 21));
// expand root
@@ -120,13 +134,13 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
return knnList.toKNNList();
}
- private double expandNode(O object, DoubleDistanceKNNHeap knnList, final ComparableMinHeap<DoubleDistanceSearchCandidate> pq, double maxDist, final int nodeID) {
+ private double expandNode(O object, KNNHeap knnList, final ComparableMinHeap<DoubleDistanceSearchCandidate> pq, double maxDist, final int nodeID) {
AbstractRStarTreeNode<?, ?> node = tree.getNode(nodeID);
// data node
if(node.isLeaf()) {
for(int i = 0; i < node.getNumEntries(); i++) {
SpatialPointLeafEntry entry = (SpatialPointLeafEntry) node.getEntry(i);
- double distance = distanceFunction.doubleMinDist(entry, object);
+ double distance = distanceFunction.minDist(entry, object);
tree.statistics.countDistanceCalculation();
if(distance <= maxDist) {
maxDist = knnList.insert(distance, entry.getDBID());
@@ -137,7 +151,7 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
else {
for(int i = 0; i < node.getNumEntries(); i++) {
SpatialDirectoryEntry entry = (SpatialDirectoryEntry) node.getEntry(i);
- double distance = distanceFunction.doubleMinDist(entry, object);
+ double distance = distanceFunction.minDist(entry, object);
tree.statistics.countDistanceCalculation();
// Greedy expand, bypassing the queue
if(distance <= 0) {
@@ -159,19 +173,19 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
* @param node the node for which the query should be performed
* @param knnLists a map containing the knn lists for each query objects
*/
- protected void batchNN(AbstractRStarTreeNode<?, ?> node, Map<DBID, DoubleDistanceKNNHeap> knnLists) {
+ protected void batchNN(AbstractRStarTreeNode<?, ?> node, Map<DBID, KNNHeap> knnLists) {
if(node.isLeaf()) {
for(int i = 0; i < node.getNumEntries(); i++) {
SpatialEntry p = node.getEntry(i);
- for(Entry<DBID, DoubleDistanceKNNHeap> ent : knnLists.entrySet()) {
+ for(Entry<DBID, KNNHeap> ent : knnLists.entrySet()) {
final DBID q = ent.getKey();
- final DoubleDistanceKNNHeap knns_q = ent.getValue();
- double knn_q_maxDist = knns_q.doubleKNNDistance();
+ final KNNHeap knns_q = ent.getValue();
+ double knn_q_maxDist = knns_q.getKNNDistance();
DBID pid = ((LeafEntry) p).getDBID();
// FIXME: objects are NOT accessible by DBID in a plain R-tree
// context!
- double dist_pq = distanceFunction.doubleDistance(relation.get(pid), relation.get(q));
+ double dist_pq = distanceFunction.distance(relation.get(pid), relation.get(q));
tree.statistics.countDistanceCalculation();
if(dist_pq <= knn_q_maxDist) {
knns_q.insert(dist_pq, pid);
@@ -187,9 +201,9 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
List<DoubleDistanceEntry> entries = getSortedEntries(node, ids);
for(DoubleDistanceEntry distEntry : entries) {
double minDist = distEntry.distance;
- for(Entry<DBID, DoubleDistanceKNNHeap> ent : knnLists.entrySet()) {
- final DoubleDistanceKNNHeap knns_q = ent.getValue();
- double knn_q_maxDist = knns_q.doubleKNNDistance();
+ for(Entry<DBID, KNNHeap> ent : knnLists.entrySet()) {
+ final KNNHeap knns_q = ent.getValue();
+ double knn_q_maxDist = knns_q.getKNNDistance();
if(minDist <= knn_q_maxDist) {
SpatialEntry entry = distEntry.entry;
@@ -217,7 +231,7 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
SpatialEntry entry = node.getEntry(i);
double minMinDist = Double.MAX_VALUE;
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- double minDist = distanceFunction.doubleMinDist(entry, relation.get(iter));
+ double minDist = distanceFunction.minDist(entry, relation.get(iter));
tree.statistics.countDistanceCalculation();
minMinDist = Math.min(minDist, minMinDist);
}
@@ -235,7 +249,7 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
*
* @apiviz.hidden
*/
- class DoubleDistanceEntry implements Comparable<DoubleDistanceEntry> {
+ static class DoubleDistanceEntry implements Comparable<DoubleDistanceEntry> {
/**
* Referenced entry
*/
@@ -264,22 +278,22 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
}
@Override
- public List<DoubleDistanceKNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ public List<KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
if(k < 1) {
throw new IllegalArgumentException("At least one enumeration has to be requested!");
}
// While this works, it seems to be slow at least for large sets!
// TODO: use a DataStore instead of a map.
- final Map<DBID, DoubleDistanceKNNHeap> knnLists = new HashMap<>(ids.size());
+ final Map<DBID, KNNHeap> knnLists = new HashMap<>(ids.size());
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
DBID id = DBIDUtil.deref(iter);
- knnLists.put(id, new DoubleDistanceIntegerDBIDKNNHeap(k));
+ knnLists.put(id, DBIDUtil.newHeap(k));
}
batchNN(tree.getRoot(), knnLists);
- List<DoubleDistanceKNNList> result = new ArrayList<>();
+ List<KNNList> result = new ArrayList<>();
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
DBID id = DBIDUtil.deref(iter);
tree.statistics.countKNNQuery();
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeRangeQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeRangeQuery.java
index 4fe2719e..aad67fed 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeRangeQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeRangeQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query;
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,13 +26,13 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.integer.DoubleDistanceIntegerDBIDList;
-import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.database.query.range.AbstractDistanceRangeQuery;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+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.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialPointLeafEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
@@ -53,10 +53,10 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* @author Erich Schubert
*
* @apiviz.uses AbstractRStarTree
- * @apiviz.uses SpatialPrimitiveDoubleDistanceFunction
+ * @apiviz.uses SpatialPrimitiveDistanceFunction
*/
@Reference(authors = "J. Kuan, P. Lewis", title = "Fast k nearest neighbour search for R-tree family", booktitle = "Proc. Int. Conf Information, Communications and Signal Processing, ICICS 1997", url = "http://dx.doi.org/10.1109/ICICS.1997.652114")
-public class DoubleDistanceRStarTreeRangeQuery<O extends SpatialComparable> extends AbstractDistanceRangeQuery<O, DoubleDistance> {
+public class RStarTreeRangeQuery<O extends SpatialComparable> implements RangeQuery<O> {
/**
* The index to use
*/
@@ -65,31 +65,36 @@ public class DoubleDistanceRStarTreeRangeQuery<O extends SpatialComparable> exte
/**
* Spatial primitive distance function
*/
- protected final SpatialPrimitiveDoubleDistanceFunction<? super O> distanceFunction;
+ protected final SpatialPrimitiveDistanceFunction<? super O> distanceFunction;
+
+ /**
+ * Relation we query.
+ */
+ protected Relation<? extends O> relation;
/**
* Constructor.
*
* @param tree Index to use
- * @param distanceQuery Distance query to use
+ * @param relation Data relation to query
* @param distanceFunction Distance function
*/
- public DoubleDistanceRStarTreeRangeQuery(AbstractRStarTree<?, ?, ?> tree, DistanceQuery<O, DoubleDistance> distanceQuery, SpatialPrimitiveDoubleDistanceFunction<? super O> distanceFunction) {
- super(distanceQuery);
+ public RStarTreeRangeQuery(AbstractRStarTree<?, ?, ?> tree, Relation<? extends O> relation, SpatialPrimitiveDistanceFunction<? super O> distanceFunction) {
+ super();
+ this.relation = relation;
this.tree = tree;
this.distanceFunction = distanceFunction;
}
- /**
- * Perform the actual query process.
- *
- * @param object Query object
- * @param epsilon Query range
- * @return Objects contained in query range.
- */
- protected DoubleDistanceDBIDList doRangeQuery(O object, double epsilon) {
+ @Override
+ public DoubleDBIDList getRangeForDBID(DBIDRef id, double range) {
+ return getRangeForObject(relation.get(id), range);
+ }
+
+ @Override
+ public DoubleDBIDList getRangeForObject(O obj, double range) {
tree.statistics.countRangeQuery();
- final DoubleDistanceIntegerDBIDList result = new DoubleDistanceIntegerDBIDList();
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
// Processing queue.
int[] pq = new int[101];
@@ -105,9 +110,9 @@ public class DoubleDistanceRStarTreeRangeQuery<O extends SpatialComparable> exte
if(node.isLeaf()) {
for(int i = 0; i < numEntries; i++) {
SpatialPointLeafEntry entry = (SpatialPointLeafEntry) node.getEntry(i);
- double distance = distanceFunction.doubleMinDist(object, entry);
+ double distance = distanceFunction.minDist(obj, entry);
tree.statistics.countDistanceCalculation();
- if(distance <= epsilon) {
+ if(distance <= range) {
result.add(distance, entry.getDBID());
}
}
@@ -115,8 +120,8 @@ public class DoubleDistanceRStarTreeRangeQuery<O extends SpatialComparable> exte
else {
for(int i = 0; i < numEntries; i++) {
SpatialDirectoryEntry entry = (SpatialDirectoryEntry) node.getEntry(i);
- double distance = distanceFunction.doubleMinDist(object, entry);
- if(distance <= epsilon) {
+ double distance = distanceFunction.minDist(obj, entry);
+ if(distance <= range) {
if(ps == pq.length) {
pq = Arrays.copyOf(pq, pq.length + (pq.length >>> 1));
}
@@ -130,9 +135,4 @@ public class DoubleDistanceRStarTreeRangeQuery<O extends SpatialComparable> exte
result.sort();
return result;
}
-
- @Override
- public DistanceDBIDList<DoubleDistance> getRangeForObject(O obj, DoubleDistance range) {
- return doRangeQuery(obj, range.doubleValue());
- }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeUtil.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeUtil.java
index 46c814ee..d76cb504 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query;
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,15 +23,14 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query;
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.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.distance.SpatialDistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction;
-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.distancefunction.minkowski.EuclideanDistanceFunction;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
/**
@@ -42,10 +41,8 @@ import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
* @apiviz.landmark
*
* @apiviz.uses AbstractRStarTree
- * @apiviz.uses DoubleDistanceRStarTreeKNNQuery
- * @apiviz.uses DoubleDistanceRStarTreeRangeQuery
- * @apiviz.uses GenericRStarTreeKNNQuery
- * @apiviz.uses GenericRStarTreeRangeQuery
+ * @apiviz.uses EuclideanRStarTreeKNNQuery
+ * @apiviz.uses EuclideanRStarTreeRangeQuery
* @apiviz.has RangeQuery
* @apiviz.has KNNQuery
*/
@@ -55,24 +52,19 @@ public final class RStarTreeUtil {
* possible.
*
* @param <O> Object type
- * @param <D> Distance type
* @param tree Tree to query
* @param distanceQuery distance query
* @param hints Optimizer hints
* @return Query object
*/
@SuppressWarnings({ "cast", "unchecked" })
- public static <O extends SpatialComparable, D extends Distance<D>> RangeQuery<O, D> getRangeQuery(AbstractRStarTree<?, ?, ?> tree, SpatialDistanceQuery<O, D> distanceQuery, Object... hints) {
+ public static <O extends SpatialComparable> RangeQuery<O> getRangeQuery(AbstractRStarTree<?, ?, ?> tree, SpatialDistanceQuery<O> distanceQuery, Object... hints) {
// Can we support this distance function - spatial distances only!
- SpatialPrimitiveDistanceFunction<? super O, D> df = distanceQuery.getDistanceFunction();
- // Can we use an optimized query?
- if(df instanceof SpatialPrimitiveDoubleDistanceFunction) {
- DistanceQuery<O, DoubleDistance> dqc = (DistanceQuery<O, DoubleDistance>) DistanceQuery.class.cast(distanceQuery);
- SpatialPrimitiveDoubleDistanceFunction<? super O> dfc = (SpatialPrimitiveDoubleDistanceFunction<? super O>) SpatialPrimitiveDoubleDistanceFunction.class.cast(df);
- RangeQuery<O, ?> q = new DoubleDistanceRStarTreeRangeQuery<>(tree, dqc, dfc);
- return (RangeQuery<O, D>) q;
+ SpatialPrimitiveDistanceFunction<? super O> df = distanceQuery.getDistanceFunction();
+ if(EuclideanDistanceFunction.STATIC.equals(df)) {
+ return (RangeQuery<O>) new EuclideanRStarTreeRangeQuery<>(tree, (Relation<NumberVector>) distanceQuery.getRelation());
}
- return new GenericRStarTreeRangeQuery<>(tree, distanceQuery);
+ return new RStarTreeRangeQuery<>(tree, distanceQuery.getRelation(), df);
}
/**
@@ -80,23 +72,18 @@ public final class RStarTreeUtil {
* possible.
*
* @param <O> Object type
- * @param <D> Distance type
* @param tree Tree to query
* @param distanceQuery distance query
* @param hints Optimizer hints
* @return Query object
*/
@SuppressWarnings({ "cast", "unchecked" })
- public static <O extends SpatialComparable, D extends Distance<D>> KNNQuery<O, D> getKNNQuery(AbstractRStarTree<?, ?, ?> tree, SpatialDistanceQuery<O, D> distanceQuery, Object... hints) {
+ public static <O extends SpatialComparable> KNNQuery<O> getKNNQuery(AbstractRStarTree<?, ?, ?> tree, SpatialDistanceQuery<O> distanceQuery, Object... hints) {
// Can we support this distance function - spatial distances only!
- SpatialPrimitiveDistanceFunction<? super O, D> df = distanceQuery.getDistanceFunction();
- // Can we use an optimized query?
- if(df instanceof SpatialPrimitiveDoubleDistanceFunction) {
- DistanceQuery<O, DoubleDistance> dqc = (DistanceQuery<O, DoubleDistance>) DistanceQuery.class.cast(distanceQuery);
- SpatialPrimitiveDoubleDistanceFunction<? super O> dfc = (SpatialPrimitiveDoubleDistanceFunction<? super O>) SpatialPrimitiveDoubleDistanceFunction.class.cast(df);
- KNNQuery<O, ?> q = new DoubleDistanceRStarTreeKNNQuery<>(tree, dqc, dfc);
- return (KNNQuery<O, D>) q;
+ SpatialPrimitiveDistanceFunction<? super O> df = distanceQuery.getDistanceFunction();
+ if(EuclideanDistanceFunction.STATIC.equals(df)) {
+ return (KNNQuery<O>) new EuclideanRStarTreeKNNQuery<>(tree, (Relation<NumberVector>) distanceQuery.getRelation());
}
- return new GenericRStarTreeKNNQuery<>(tree, distanceQuery);
+ return new RStarTreeKNNQuery<>(tree, distanceQuery.getRelation(), df);
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/package-info.java
index 69bcd3d0..35dd34e7 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/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/index/tree/spatial/rstarvariants/rdknn/RdKNNDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNDirectoryEntry.java
new file mode 100644
index 00000000..b824bc77
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNDirectoryEntry.java
@@ -0,0 +1,129 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rdknn;
+
+/*
+ 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.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry;
+
+/**
+ * Represents an entry in a directory node of an RdKNN-Tree. Additionally to a
+ * SpatialDirectoryEntry a RdKNNDirectoryEntry holds the knn distance of the
+ * underlying RdKNN-Tree node.
+ *
+ * @author Elke Achtert
+ * @param Distance type
+ */
+public class RdKNNDirectoryEntry extends SpatialDirectoryEntry implements RdKNNEntry {
+ private static final long serialVersionUID = 2;
+
+ /**
+ * The aggregated knn distance of this entry.
+ */
+ private double knnDistance;
+
+ /**
+ * Empty constructor for serialization purposes.
+ */
+ public RdKNNDirectoryEntry() {
+ // empty constructor
+ }
+
+ /**
+ * Constructs a new RDkNNDirectoryEntry object with the given parameters.
+ *
+ * @param id the unique id of the underlying node
+ * @param mbr the minimum bounding rectangle of the underlying node
+ * @param knnDistance the aggregated knn distance of this entry
+ */
+ public RdKNNDirectoryEntry(int id, ModifiableHyperBoundingBox mbr, double knnDistance) {
+ super(id, mbr);
+ this.knnDistance = knnDistance;
+ }
+
+ @Override
+ public double getKnnDistance() {
+ return knnDistance;
+ }
+
+ @Override
+ public void setKnnDistance(double knnDistance) {
+ this.knnDistance = knnDistance;
+ }
+
+ /**
+ * Calls the super method and writes the knn distance of this entry to the
+ * specified stream.
+ *
+ * @param out the stream to write the object to
+ * @throws java.io.IOException Includes any I/O exceptions that may occur
+ */
+ @Override
+ public void writeExternal(ObjectOutput out) throws IOException {
+ super.writeExternal(out);
+ out.writeDouble(knnDistance);
+ }
+
+ /**
+ * Calls the super method and reads the knn distance of this entry from the
+ * specified input stream.
+ *
+ * @param in the stream to read data from in order to restore the object
+ * @throws java.io.IOException if I/O errors occur
+ * @throws ClassNotFoundException If the class for an object being restored
+ * cannot be found.
+ */
+ @Override
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ super.readExternal(in);
+ this.knnDistance = in.readDouble();
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this one.
+ *
+ * @param o the object to be tested
+ * @return true, if the super method returns true and o is an
+ * RDkNNDirectoryEntry and has the same knnDistance as this entry.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if(this == o) {
+ return true;
+ }
+ if(o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ if(!super.equals(o)) {
+ return false;
+ }
+
+ final RdKNNDirectoryEntry that = (RdKNNDirectoryEntry) o;
+
+ return knnDistance == that.knnDistance;
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNEntry.java
new file mode 100644
index 00000000..f96a6419
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNEntry.java
@@ -0,0 +1,49 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rdknn;
+
+/*
+ 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.index.tree.spatial.SpatialEntry;
+
+/**
+ * Defines the requirements for an entry in an RdKNN-Tree node. Additionally to
+ * an entry in an R*-Tree an RDkNNEntry holds the knn distance of the underlying
+ * data object or RdKNN-Tree node.
+ *
+ * @author Elke Achtert
+ */
+interface RdKNNEntry extends SpatialEntry {
+ /**
+ * Returns the knn distance of this entry.
+ *
+ * @return the knn distance of this entry
+ */
+ public double getKnnDistance();
+
+ /**
+ * Sets the knn distance of this entry.
+ *
+ * @param knnDistance the knn distance to be set
+ */
+ public void setKnnDistance(double knnDistance);
+}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNLeafEntry.java
new file mode 100644
index 00000000..6d665eb9
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNLeafEntry.java
@@ -0,0 +1,129 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rdknn;
+
+/*
+ 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.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialPointLeafEntry;
+
+/**
+ * Represents an entry in a leaf node of an RdKNN-Tree. Additionally to a
+ * SpatialLeafEntry a RdKNNLeafEntry holds the knn distance of the underlying
+ * data object.
+ *
+ * @author Elke Achtert
+ */
+public class RdKNNLeafEntry extends SpatialPointLeafEntry implements RdKNNEntry {
+ private static final long serialVersionUID = 2;
+
+ /**
+ * The knn distance of the underlying data object.
+ */
+ private double knnDistance;
+
+ /**
+ * Empty constructor for serialization purposes.
+ */
+ public RdKNNLeafEntry() {
+ super();
+ }
+
+ /**
+ * Constructs a new RDkNNLeafEntry object with the given parameters.
+ *
+ * @param id the unique id of the underlying data object
+ * @param vector the underlying data object
+ * @param knnDistance the knn distance of the underlying data object
+ */
+ public RdKNNLeafEntry(DBID id, NumberVector vector, double knnDistance) {
+ super(id, vector);
+ this.knnDistance = knnDistance;
+ }
+
+ @Override
+ public double getKnnDistance() {
+ return knnDistance;
+ }
+
+ @Override
+ public void setKnnDistance(double knnDistance) {
+ this.knnDistance = knnDistance;
+ }
+
+ /**
+ * Calls the super method and writes the knn distance of this entry to the
+ * specified stream.
+ *
+ * @param out the stream to write the object to
+ * @throws java.io.IOException Includes any I/O exceptions that may occur
+ */
+ @Override
+ public void writeExternal(ObjectOutput out) throws IOException {
+ super.writeExternal(out);
+ out.writeDouble(knnDistance);
+ }
+
+ /**
+ * Calls the super method and reads the knn distance of this entry from the
+ * specified input stream.
+ *
+ * @param in the stream to read data from in order to restore the object
+ * @throws java.io.IOException if I/O errors occur
+ * @throws ClassNotFoundException If the class for an object being restored
+ * cannot be found.
+ */
+ @Override
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ super.readExternal(in);
+ this.knnDistance = in.readDouble();
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this one.
+ *
+ * @param o the object to be tested
+ * @return true, if the super method returns true and o is an RDkNNLeafEntry
+ * and has the same knnDistance as this entry.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if(this == o) {
+ return true;
+ }
+ if(o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ if(!super.equals(o)) {
+ return false;
+ }
+
+ final RdKNNLeafEntry that = (RdKNNLeafEntry) o;
+
+ return knnDistance == that.knnDistance;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNNode.java
new file mode 100644
index 00000000..89e231b4
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNNode.java
@@ -0,0 +1,96 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rdknn;
+
+/*
+ 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.index.tree.spatial.rstarvariants.AbstractRStarTreeNode;
+
+/**
+ * Represents a node in a RDkNN-Tree.
+ *
+ * @author Elke Achtert
+ *
+ * @apiviz.has RdKNNEntry oneway - - contains
+ */
+public class RdKNNNode extends AbstractRStarTreeNode<RdKNNNode, RdKNNEntry> {
+ private static final long serialVersionUID = 1;
+
+ /**
+ * Empty constructor for Externalizable interface.
+ */
+ public RdKNNNode() {
+ // empty constructor
+ }
+
+ /**
+ * Creates a new RdKNNNode object.
+ *
+ * @param capacity the capacity (maximum number of entries plus 1 for
+ * overflow) of this node
+ * @param isLeaf indicates whether this node is a leaf node
+ */
+ public RdKNNNode(int capacity, boolean isLeaf) {
+ super(capacity, isLeaf, RdKNNEntry.class);
+ }
+
+ /**
+ * Computes and returns the aggregated knn distance of this node
+ *
+ * @return the aggregated knn distance of this node
+ */
+ protected double kNNDistance() {
+ double result = getEntry(0).getKnnDistance();
+ for(int i = 1; i < getNumEntries(); i++) {
+ double knnDistance = getEntry(i).getKnnDistance();
+ result = (result < knnDistance) ? knnDistance : result;
+ }
+ return result;
+ }
+
+ @Override
+ public boolean adjustEntry(RdKNNEntry entry) {
+ boolean changed = super.adjustEntry(entry);
+ entry.setKnnDistance(kNNDistance());
+ return changed;
+ }
+
+ /**
+ * Tests, if the parameters of the entry representing this node, are correctly
+ * set. Subclasses may need to overwrite this method.
+ *
+ * @param parent the parent holding the entry representing this node
+ * @param index the index of the entry in the parents child array
+ */
+ @Override
+ protected void integrityCheckParameters(RdKNNNode parent, int index) {
+ super.integrityCheckParameters(parent, index);
+ // test if knn distance is correctly set
+ RdKNNEntry entry = parent.getEntry(index);
+ double knnDistance = kNNDistance();
+ if(entry.getKnnDistance() != knnDistance) {
+ double soll = knnDistance;
+ double ist = entry.getKnnDistance();
+ throw new RuntimeException("Wrong knnDistance in node " + parent.getPageID() + " at index " + index + " (child " + entry + ")" + "\nsoll: " + soll + ",\n ist: " + ist);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNTree.java
new file mode 100644
index 00000000..374e9592
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNTree.java
@@ -0,0 +1,672 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rdknn;
+
+/*
+ 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.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+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.ArrayDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
+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.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.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.distance.SpatialDistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
+import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.index.DynamicIndex;
+import de.lmu.ifi.dbs.elki.index.KNNIndex;
+import de.lmu.ifi.dbs.elki.index.RKNNIndex;
+import de.lmu.ifi.dbs.elki.index.RangeIndex;
+import de.lmu.ifi.dbs.elki.index.tree.IndexTreePath;
+import de.lmu.ifi.dbs.elki.index.tree.LeafEntry;
+import de.lmu.ifi.dbs.elki.index.tree.TreeIndexHeader;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeNode;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.NonFlatRStarTree;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query.RStarTreeUtil;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.persistent.PageFile;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleObjPair;
+
+/**
+ * RDkNNTree is a spatial index structure based on the concepts of the R*-Tree
+ * supporting efficient processing of reverse k nearest neighbor queries. The
+ * k-nn distance is stored in each entry of a node.
+ * <p/>
+ * TODO: noch nicht fertig!!!
+ *
+ * @author Elke Achtert
+ *
+ * @apiviz.has RdKNNNode
+ * @apiviz.has RdKNNTreeHeader
+ *
+ * @param <O> Object type
+ */
+// FIXME: currently does not yet return RKNNQuery objects!
+public class RdKNNTree<O extends NumberVector> extends NonFlatRStarTree<RdKNNNode, RdKNNEntry, RdkNNSettings<O>> implements RangeIndex<O>, KNNIndex<O>, RKNNIndex<O>, DynamicIndex {
+ /**
+ * The logger for this class.
+ */
+ private static final Logging LOG = Logging.getLogger(RdKNNTree.class);
+
+ /**
+ * The distance function.
+ */
+ private SpatialDistanceQuery<O> distanceQuery;
+
+ /**
+ * Internal knn query object, for updating the rKNN.
+ */
+ protected KNNQuery<O> knnQuery;
+
+ /**
+ * The relation we query.
+ */
+ private Relation<O> relation;
+
+ /**
+ * Constructor.
+ *
+ * @param relation Relation to index
+ * @param pagefile Data storage
+ * @param settings Tree settings
+ */
+ public RdKNNTree(Relation<O> relation, PageFile<RdKNNNode> pagefile, RdkNNSettings<O> settings) {
+ super(pagefile, settings);
+ this.relation = relation;
+ this.distanceQuery = settings.distanceFunction.instantiate(relation);
+ this.knnQuery = relation.getDatabase().getKNNQuery(distanceQuery);
+ }
+
+ /**
+ * Performs necessary operations before inserting the specified entry.
+ *
+ * @param entry the entry to be inserted
+ */
+ @Override
+ protected void preInsert(RdKNNEntry entry) {
+ KNNHeap knns_o = DBIDUtil.newHeap(settings.k_max);
+ preInsert(entry, getRootEntry(), knns_o);
+ }
+
+ /**
+ * Performs necessary operations after deleting the specified object.
+ */
+ @Override
+ protected void postDelete(RdKNNEntry entry) {
+ // reverse knn of o
+ ModifiableDoubleDBIDList rnns = DBIDUtil.newDistanceDBIDList();
+ doReverseKNN(getRoot(), ((RdKNNLeafEntry) entry).getDBID(), rnns);
+
+ // knn of rnn
+ ArrayModifiableDBIDs ids = DBIDUtil.newArray(rnns);
+ ids.sort();
+ List<? extends KNNList> knnLists = knnQuery.getKNNForBulkDBIDs(ids, settings.k_max);
+
+ // adjust knn distances
+ adjustKNNDistance(getRootEntry(), ids, knnLists);
+ }
+
+ /**
+ * Performs a bulk load on this RTree with the specified data. Is called by
+ * the constructor and should be overwritten by subclasses if necessary.
+ */
+ @Override
+ protected void bulkLoad(List<RdKNNEntry> entries) {
+ super.bulkLoad(entries);
+
+ // adjust all knn distances
+ ArrayModifiableDBIDs ids = DBIDUtil.newArray(entries.size());
+ for(RdKNNEntry entry : entries) {
+ DBID id = ((RdKNNLeafEntry) entry).getDBID();
+ ids.add(id);
+ }
+ ids.sort();
+ List<? extends KNNList> knnLists = knnQuery.getKNNForBulkDBIDs(ids, settings.k_max);
+ adjustKNNDistance(getRootEntry(), ids, knnLists);
+
+ // test
+ doExtraIntegrityChecks();
+ }
+
+ public DoubleDBIDList reverseKNNQuery(DBID oid, int k, SpatialPrimitiveDistanceFunction<? super O> distanceFunction, KNNQuery<O> knnQuery) {
+ checkDistanceFunction(distanceFunction);
+ if(k > settings.k_max) {
+ throw new IllegalArgumentException("Parameter k is not supported, k > k_max: " + k + " > " + settings.k_max);
+ }
+
+ // get candidates
+ ModifiableDoubleDBIDList candidates = DBIDUtil.newDistanceDBIDList();
+ doReverseKNN(getRoot(), oid, candidates);
+
+ if(k == settings.k_max) {
+ candidates.sort();
+ return candidates;
+ }
+
+ // refinement of candidates, if k < k_max
+ ArrayModifiableDBIDs candidateIDs = DBIDUtil.newArray(candidates);
+ candidateIDs.sort();
+ List<? extends KNNList> knnLists = knnQuery.getKNNForBulkDBIDs(candidateIDs, k);
+
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
+ int i = 0;
+ for(DBIDIter iter = candidateIDs.iter(); iter.valid(); iter.advance(), i++) {
+ for(DoubleDBIDListIter qr = knnLists.get(i).iter(); qr.valid(); qr.advance()) {
+ if(DBIDUtil.equal(oid, qr)) {
+ result.add(qr.doubleValue(), iter);
+ break;
+ }
+ }
+ }
+
+ result.sort();
+ return result;
+ }
+
+ public List<ModifiableDoubleDBIDList> bulkReverseKNNQueryForID(DBIDs ids, int k, SpatialPrimitiveDistanceFunction<? super O> distanceFunction, KNNQuery<O> knnQuery) {
+ checkDistanceFunction(distanceFunction);
+ if(k > settings.k_max) {
+ throw new IllegalArgumentException("Parameter k is not supported, k > k_max: " + k + " > " + settings.k_max);
+ }
+
+ // get candidates
+ Map<DBID, ModifiableDoubleDBIDList> candidateMap = new HashMap<>();
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ DBID id = DBIDUtil.deref(iter);
+ candidateMap.put(id, DBIDUtil.newDistanceDBIDList());
+ }
+ doBulkReverseKNN(getRoot(), ids, candidateMap);
+
+ if(k == settings.k_max) {
+ List<ModifiableDoubleDBIDList> resultList = new ArrayList<>();
+ for(ModifiableDoubleDBIDList candidates : candidateMap.values()) {
+ candidates.sort();
+ resultList.add(candidates);
+ }
+ return resultList;
+ }
+
+ // refinement of candidates, if k < k_max
+ // perform a knn query for the candidates
+ ArrayModifiableDBIDs candidateIDs = DBIDUtil.newArray();
+ for(ModifiableDoubleDBIDList candidates : candidateMap.values()) {
+ candidateIDs.addDBIDs(candidates);
+ }
+ candidateIDs.sort();
+ List<? extends KNNList> knnLists = knnQuery.getKNNForBulkDBIDs(candidateIDs, k);
+
+ // and add candidate c to the result if o is a knn of c
+ List<ModifiableDoubleDBIDList> resultList = new ArrayList<>();
+ for(DBID id : candidateMap.keySet()) {
+ ModifiableDoubleDBIDList candidates = candidateMap.get(id);
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
+ for(DoubleDBIDListIter candidate = candidates.iter(); candidate.valid(); candidate.advance()) {
+ int pos = candidateIDs.binarySearch(candidate);
+ assert (pos >= 0);
+ for(DoubleDBIDListIter qr = knnLists.get(pos).iter(); qr.valid(); qr.advance()) {
+ if(DBIDUtil.equal(id, qr)) {
+ result.add(qr.doubleValue(), candidate);
+ break;
+ }
+ }
+ }
+ resultList.add(result);
+ }
+ return resultList;
+ }
+
+ @Override
+ protected TreeIndexHeader createHeader() {
+ return new RdKNNTreeHeader(getPageSize(), dirCapacity, leafCapacity, dirMinimum, leafCapacity, settings.k_max);
+ }
+
+ @Override
+ protected void initializeCapacities(RdKNNEntry exampleLeaf) {
+ int dimensionality = exampleLeaf.getDimensionality();
+ int distanceSize = ByteArrayUtil.SIZE_DOUBLE;
+
+ // overhead = index(4), numEntries(4), parentID(4), id(4), isLeaf(0.125)
+ double overhead = 16.125;
+ if(getPageSize() - overhead < 0) {
+ throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!");
+ }
+
+ // dirCapacity = (pageSize - overhead) / (childID + childMBR + knnDistance)
+ // + 1
+ dirCapacity = (int) ((getPageSize() - overhead) / (4 + 16 * dimensionality + distanceSize)) + 1;
+
+ if(dirCapacity <= 1) {
+ throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!");
+ }
+
+ if(dirCapacity < 10) {
+ LOG.warning("Page size is choosen too small! Maximum number of entries " + "in a directory node = " + (dirCapacity - 1));
+ }
+
+ // minimum entries per directory node
+ dirMinimum = (int) Math.round((dirCapacity - 1) * 0.5);
+ if(dirMinimum < 2) {
+ dirMinimum = 2;
+ }
+
+ // leafCapacity = (pageSize - overhead) / (childID + childValues +
+ // knnDistance) + 1
+ leafCapacity = (int) ((getPageSize() - overhead) / (4 + 8 * dimensionality + distanceSize)) + 1;
+
+ if(leafCapacity <= 1) {
+ throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!");
+ }
+
+ if(leafCapacity < 10) {
+ LOG.warning("Page size is choosen too small! Maximum number of entries " + "in a leaf node = " + (leafCapacity - 1));
+ }
+
+ // minimum entries per leaf node
+ leafMinimum = (int) Math.round((leafCapacity - 1) * 0.5);
+ if(leafMinimum < 2) {
+ leafMinimum = 2;
+ }
+
+ if(LOG.isVerbose()) {
+ LOG.verbose("Directory Capacity: " + dirCapacity + "\nLeaf Capacity: " + leafCapacity);
+ }
+ }
+
+ /**
+ * Sorts the entries of the specified node according to their minimum distance
+ * to the specified object.
+ *
+ * @param node the node
+ * @param q the query object
+ * @param distanceFunction the distance function for computing the distances
+ * @return a list of the sorted entries
+ */
+ // TODO: move somewhere else?
+ protected List<DoubleObjPair<RdKNNEntry>> getSortedEntries(AbstractRStarTreeNode<?, ?> node, SpatialComparable q, SpatialPrimitiveDistanceFunction<?> distanceFunction) {
+ List<DoubleObjPair<RdKNNEntry>> result = new ArrayList<>();
+
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ RdKNNEntry entry = (RdKNNEntry) node.getEntry(i);
+ double minDist = distanceFunction.minDist(entry, q);
+ result.add(new DoubleObjPair<>(minDist, entry));
+ }
+
+ Collections.sort(result);
+ return result;
+ }
+
+ /**
+ * Adapts the knn distances before insertion of entry q.
+ *
+ * @param q the entry to be inserted
+ * @param nodeEntry the entry representing the root of the current subtree
+ * @param knns_q the knns of q
+ */
+ private void preInsert(RdKNNEntry q, RdKNNEntry nodeEntry, KNNHeap knns_q) {
+ double knnDist_q = knns_q.getKNNDistance();
+ RdKNNNode node = getNode(nodeEntry);
+ double knnDist_node = 0.;
+
+ // leaf node
+ if(node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ RdKNNLeafEntry p = (RdKNNLeafEntry) node.getEntry(i);
+ double dist_pq = distanceQuery.distance(p.getDBID(), ((LeafEntry) q).getDBID());
+
+ // p is nearer to q than the farthest kNN-candidate of q
+ // ==> p becomes a knn-candidate
+ if(dist_pq <= knnDist_q) {
+ knns_q.insert(dist_pq, p.getDBID());
+ if(knns_q.size() >= settings.k_max) {
+ knnDist_q = knns_q.getKNNDistance();
+ q.setKnnDistance(knnDist_q);
+ }
+
+ }
+ // p is nearer to q than to its farthest knn-candidate
+ // q becomes knn of p
+ if(dist_pq <= p.getKnnDistance()) {
+ O obj = relation.get(p.getDBID());
+ KNNList knns_without_q = knnQuery.getKNNForObject(obj, settings.k_max);
+
+ if(knns_without_q.size() + 1 < settings.k_max) {
+ p.setKnnDistance(Double.NaN);
+ }
+ else {
+ double knnDist_p = Math.min(knns_without_q.get(knns_without_q.size() - 1).doubleValue(), dist_pq);
+ p.setKnnDistance(knnDist_p);
+ }
+ }
+ knnDist_node = Math.max(knnDist_node, p.getKnnDistance());
+ }
+ }
+ // directory node
+ else {
+ O obj = relation.get(((LeafEntry) q).getDBID());
+ List<DoubleObjPair<RdKNNEntry>> entries = getSortedEntries(node, obj, settings.distanceFunction);
+ for(DoubleObjPair<RdKNNEntry> distEntry : entries) {
+ RdKNNEntry entry = distEntry.second;
+ double entry_knnDist = entry.getKnnDistance();
+
+ if(distEntry.first < entry_knnDist || distEntry.first < knnDist_q) {
+ preInsert(q, entry, knns_q);
+ knnDist_q = knns_q.getKNNDistance();
+ }
+ knnDist_node = Math.max(knnDist_node, entry.getKnnDistance());
+ }
+ }
+ nodeEntry.setKnnDistance(knnDist_node);
+ }
+
+ /**
+ * Performs a reverse knn query in the specified subtree.
+ *
+ * @param node the root node of the current subtree
+ * @param oid the id of the object for which the rknn query is performed
+ * @param result the list containing the query results
+ */
+ private void doReverseKNN(RdKNNNode node, DBID oid, ModifiableDoubleDBIDList result) {
+ if(node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ RdKNNLeafEntry entry = (RdKNNLeafEntry) node.getEntry(i);
+ double distance = distanceQuery.distance(entry.getDBID(), oid);
+ if(distance <= entry.getKnnDistance()) {
+ result.add(distance, entry.getDBID());
+ }
+ }
+ }
+ // node is a inner node
+ else {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ RdKNNDirectoryEntry entry = (RdKNNDirectoryEntry) node.getEntry(i);
+ double minDist = distanceQuery.minDist(entry, oid);
+ if(minDist <= entry.getKnnDistance()) {
+ doReverseKNN(getNode(entry), oid, result);
+ }
+ }
+ }
+ }
+
+ /**
+ * Performs a bulk reverse knn query in the specified subtree.
+ *
+ * @param node the root node of the current subtree
+ * @param ids the object ids for which the rknn query is performed
+ * @param result the map containing the query results for each object
+ */
+ private void doBulkReverseKNN(RdKNNNode node, DBIDs ids, Map<DBID, ModifiableDoubleDBIDList> result) {
+ if(node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ RdKNNLeafEntry entry = (RdKNNLeafEntry) node.getEntry(i);
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ DBID id = DBIDUtil.deref(iter);
+ double distance = distanceQuery.distance(entry.getDBID(), id);
+ if(distance <= entry.getKnnDistance()) {
+ result.get(id).add(distance, entry.getDBID());
+ }
+ }
+ }
+ }
+ // node is a inner node
+ else {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ RdKNNDirectoryEntry entry = (RdKNNDirectoryEntry) node.getEntry(i);
+ ModifiableDBIDs candidates = DBIDUtil.newArray();
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ DBID id = DBIDUtil.deref(iter);
+ double minDist = distanceQuery.minDist(entry, id);
+ if(minDist <= entry.getKnnDistance()) {
+ candidates.add(id);
+ }
+ if(!candidates.isEmpty()) {
+ doBulkReverseKNN(getNode(entry), candidates, result);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Adjusts the knn distance in the subtree of the specified root entry.
+ *
+ * @param entry the root entry of the current subtree
+ * @param ids <em>Sorted</em> list of IDs
+ * @param knnLists a map of knn lists for each leaf entry
+ */
+ private void adjustKNNDistance(RdKNNEntry entry, ArrayDBIDs ids, List<? extends KNNList> knnLists) {
+ RdKNNNode node = getNode(entry);
+ double knnDist_node = 0.;
+ if(node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ RdKNNEntry leafEntry = node.getEntry(i);
+ DBID id = ((LeafEntry) leafEntry).getDBID();
+ int pos = ids.binarySearch(id);
+ if(pos >= 0) {
+ leafEntry.setKnnDistance(knnLists.get(pos).getKNNDistance());
+ }
+ knnDist_node = Math.max(knnDist_node, leafEntry.getKnnDistance());
+ }
+ }
+ else {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ RdKNNEntry dirEntry = node.getEntry(i);
+ adjustKNNDistance(dirEntry, ids, knnLists);
+ knnDist_node = Math.max(knnDist_node, dirEntry.getKnnDistance());
+ }
+ }
+ entry.setKnnDistance(knnDist_node);
+ }
+
+ /**
+ * Creates a new leaf node with the specified capacity.
+ *
+ * @return a new leaf node
+ */
+ @Override
+ protected RdKNNNode createNewLeafNode() {
+ return new RdKNNNode(leafCapacity, true);
+ }
+
+ /**
+ * Creates a new directory node with the specified capacity.
+ *
+ * @return a new directory node
+ */
+ @Override
+ protected RdKNNNode createNewDirectoryNode() {
+ return new RdKNNNode(dirCapacity, false);
+ }
+
+ /**
+ * Creates a new directory entry representing the specified node.
+ *
+ * @param node the node to be represented by the new entry
+ */
+ @Override
+ protected RdKNNEntry createNewDirectoryEntry(RdKNNNode node) {
+ return new RdKNNDirectoryEntry(node.getPageID(), node.computeMBR(), node.kNNDistance());
+ }
+
+ /**
+ * Creates an entry representing the root node.
+ *
+ * @return an entry representing the root node
+ */
+ @Override
+ protected RdKNNEntry createRootEntry() {
+ return new RdKNNDirectoryEntry(0, null, Double.NaN);
+ }
+
+ /**
+ * Throws an IllegalArgumentException if the specified distance function is
+ * not an instance of the distance function used by this index.
+ *
+ * @throws IllegalArgumentException
+ * @param distanceFunction the distance function to be checked
+ */
+ private void checkDistanceFunction(SpatialPrimitiveDistanceFunction<? super O> distanceFunction) {
+ if(!settings.distanceFunction.equals(distanceFunction)) {
+ throw new IllegalArgumentException("Parameter distanceFunction must be an instance of " + this.distanceQuery.getClass() + ", but is " + distanceFunction.getClass());
+ }
+ }
+
+ protected RdKNNLeafEntry createNewLeafEntry(DBID id) {
+ return new RdKNNLeafEntry(id, relation.get(id), Double.NaN);
+ }
+
+ @Override
+ public void initialize() {
+ super.initialize();
+ insertAll(relation.getDBIDs());
+ }
+
+ /**
+ * Inserts the specified real vector object into this index.
+ *
+ * @param id the object id that was inserted
+ */
+ @Override
+ public final void insert(DBIDRef id) {
+ insertLeaf(createNewLeafEntry(DBIDUtil.deref(id)));
+ }
+
+ /**
+ * Inserts the specified objects into this index. If a bulk load mode is
+ * implemented, the objects are inserted in one bulk.
+ *
+ * @param ids the objects to be inserted
+ */
+ @Override
+ public final void insertAll(DBIDs ids) {
+ if(ids.isEmpty() || (ids.size() == 1)) {
+ return;
+ }
+
+ // Make an example leaf
+ if(canBulkLoad()) {
+ List<RdKNNEntry> leafs = new ArrayList<>(ids.size());
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ leafs.add(createNewLeafEntry(DBIDUtil.deref(iter)));
+ }
+ bulkLoad(leafs);
+ }
+ else {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ insert(iter);
+ }
+ }
+
+ doExtraIntegrityChecks();
+ }
+
+ /**
+ * Deletes the specified object from this index.
+ *
+ * @return true if this index did contain the object with the specified id,
+ * false otherwise
+ */
+ @Override
+ public final boolean delete(DBIDRef id) {
+ // find the leaf node containing o
+ O obj = relation.get(id);
+ IndexTreePath<RdKNNEntry> deletionPath = findPathToObject(getRootPath(), obj, id);
+ if(deletionPath == null) {
+ return false;
+ }
+ deletePath(deletionPath);
+ return true;
+ }
+
+ @Override
+ public void deleteAll(DBIDs ids) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ delete(DBIDUtil.deref(iter));
+ }
+ }
+
+ @Override
+ public RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ // Query on the relation we index
+ if(distanceQuery.getRelation() != relation) {
+ return null;
+ }
+ // Can we support this distance function - spatial distances only!
+ if(!(distanceQuery instanceof SpatialDistanceQuery)) {
+ return null;
+ }
+ return RStarTreeUtil.getRangeQuery(this, (SpatialDistanceQuery<O>) distanceQuery, hints);
+ }
+
+ @Override
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ // Query on the relation we index
+ if(distanceQuery.getRelation() != relation) {
+ return null;
+ }
+ // Can we support this distance function - spatial distances only!
+ if(!(distanceQuery instanceof SpatialDistanceQuery)) {
+ return null;
+ }
+ return RStarTreeUtil.getKNNQuery(this, (SpatialDistanceQuery<O>) distanceQuery, hints);
+ }
+
+ @Override
+ public RKNNQuery<O> getRKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
+ // FIXME: re-add
+ return null;
+ }
+
+ @Override
+ public String getLongName() {
+ return "RdKNNTree";
+ }
+
+ @Override
+ public String getShortName() {
+ return "rdknntree";
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return LOG;
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNTreeFactory.java
new file mode 100644
index 00000000..a2c9d110
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNTreeFactory.java
@@ -0,0 +1,120 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rdknn;
+
+/*
+ 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.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeFactory;
+import de.lmu.ifi.dbs.elki.persistent.PageFile;
+import de.lmu.ifi.dbs.elki.persistent.PageFileFactory;
+import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
+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;
+
+/**
+ * Factory for RdKNN R*-Trees.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.stereotype factory
+ * @apiviz.uses RdKNNTreeIndex oneway - - «create»
+ *
+ * @param <O> Object type
+ */
+public class RdKNNTreeFactory<O extends NumberVector> extends AbstractRStarTreeFactory<O, RdKNNNode, RdKNNEntry, RdKNNTree<O>, RdkNNSettings<O>> {
+ /**
+ * Parameter for k
+ */
+ public static final OptionID K_ID = new OptionID("rdknn.k", "positive integer specifying the maximal number k of reverse " + "k nearest neighbors to be supported.");
+
+ /**
+ * The default distance function.
+ */
+ public static final Class<?> DEFAULT_DISTANCE_FUNCTION = EuclideanDistanceFunction.class;
+
+ /**
+ * Parameter for distance function
+ */
+ public static final OptionID DISTANCE_FUNCTION_ID = new OptionID("rdknn.distancefunction", "Distance function to determine the distance between database objects.");
+
+ /**
+ * Constructor.
+ *
+ * @param pageFileFactory Data storage
+ * @param settings Settings class
+ */
+ public RdKNNTreeFactory(PageFileFactory<?> pageFileFactory, RdkNNSettings<O> settings) {
+ super(pageFileFactory, settings);
+ }
+
+ @Override
+ public RdKNNTree<O> instantiate(Relation<O> relation) {
+ PageFile<RdKNNNode> pagefile = makePageFile(getNodeClass());
+ RdKNNTree<O> index = new RdKNNTree<>(relation, pagefile, settings);
+ return index;
+ }
+
+ protected Class<RdKNNNode> getNodeClass() {
+ return ClassGenericsUtil.uglyCastIntoSubclass(RdKNNNode.class);
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer<O extends NumberVector> extends AbstractRStarTreeFactory.Parameterizer<O, RdkNNSettings<O>> {
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ IntParameter k_maxP = new IntParameter(K_ID);
+ k_maxP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(k_maxP)) {
+ settings.k_max = k_maxP.intValue();
+ }
+
+ ObjectParameter<SpatialPrimitiveDistanceFunction<O>> distanceFunctionP = new ObjectParameter<>(DISTANCE_FUNCTION_ID, SpatialPrimitiveDistanceFunction.class, DEFAULT_DISTANCE_FUNCTION);
+ if(config.grab(distanceFunctionP)) {
+ settings.distanceFunction = distanceFunctionP.instantiateClass(config);
+ }
+ }
+
+ @Override
+ protected RdKNNTreeFactory<O> makeInstance() {
+ return new RdKNNTreeFactory<>(pageFileFactory, settings);
+ }
+
+ @Override
+ protected RdkNNSettings<O> createSettings() {
+ return new RdkNNSettings<>();
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNTreeHeader.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNTreeHeader.java
new file mode 100644
index 00000000..fdcff104
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdKNNTreeHeader.java
@@ -0,0 +1,101 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rdknn;
+
+/*
+ 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.IOException;
+import java.io.RandomAccessFile;
+
+import de.lmu.ifi.dbs.elki.index.tree.TreeIndexHeader;
+
+/**
+ * Encapsulates the header information of a RDkNN-Tree. This information is
+ * needed for persistent storage.
+ *
+ * @author Elke Achtert
+ */
+class RdKNNTreeHeader extends TreeIndexHeader {
+ /**
+ * The size of this header in Bytes, which is 4 Bytes (for {@link #k_max}).
+ */
+ private static int SIZE = 4;
+
+ /**
+ * The maximum number k of reverse kNN queries to be supported.
+ */
+ int k_max;
+
+ /**
+ * Empty constructor for serialization.
+ */
+ public RdKNNTreeHeader() {
+ super();
+ }
+
+ /**
+ * Creates a new header with the specified parameters.
+ *
+ * @param pageSize the size of a page in bytes
+ * @param dirCapacity the maximum number of entries in a directory node
+ * @param leafCapacity the maximum number of entries in a leaf node
+ * @param dirMinimum the minimum number of entries in a directory node
+ * @param leafMinimum the minimum number of entries in a leaf node
+ * @param k_max the maximum number k of reverse kNN queries to be supported
+ */
+ public RdKNNTreeHeader(int pageSize, int dirCapacity, int leafCapacity, int dirMinimum, int leafMinimum, int k_max) {
+ super(pageSize, dirCapacity, leafCapacity, dirMinimum, leafMinimum);
+ this.k_max = k_max;
+ }
+
+ /**
+ * Initializes this header from the specified file. Calls
+ * {@link de.lmu.ifi.dbs.elki.index.tree.TreeIndexHeader#readHeader(java.io.RandomAccessFile)
+ * TreeIndexHeader#readHeader(file)} and reads additionally the integer value
+ * of {@link #k_max} from the file.
+ */
+ @Override
+ public void readHeader(RandomAccessFile file) throws IOException {
+ super.readHeader(file);
+ this.k_max = file.readInt();
+ }
+
+ /**
+ * Writes this header to the specified file. Calls
+ * {@link de.lmu.ifi.dbs.elki.index.tree.TreeIndexHeader#writeHeader(java.io.RandomAccessFile)}
+ * and writes additionally the integer value of {@link #k_max} to the file.
+ */
+ @Override
+ public void writeHeader(RandomAccessFile file) throws IOException {
+ super.writeHeader(file);
+ file.writeInt(this.k_max);
+ }
+
+ /**
+ * Returns {@link de.lmu.ifi.dbs.elki.index.tree.TreeIndexHeader#size()} plus
+ * the value of {@link #SIZE}).
+ */
+ @Override
+ public int size() {
+ return super.size() + SIZE;
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceKNNList.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdkNNSettings.java
index c54110ab..3f9997e2 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceKNNList.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdkNNSettings.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.database.ids.distance;
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rdknn;
/*
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,34 +22,25 @@ package de.lmu.ifi.dbs.elki.database.ids.distance;
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.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRTreeSettings;
/**
- * Double-valued KNN result.
+ * Settings for the RdKNN Tree.
*
* @author Erich Schubert
+ *
+ * @param <O> Object type
*/
-public interface DoubleDistanceKNNList extends KNNList<DoubleDistance> {
+public class RdkNNSettings<O extends NumberVector> extends AbstractRTreeSettings {
/**
- * {@inheritDoc}
- *
- * @deprecated use doubleKNNDistance()!
+ * Parameter k.
*/
- @Override
- @Deprecated
- DoubleDistance getKNNDistance();
+ int k_max;
/**
- * Get the kNN distance as double value.
- *
- * @return Distance
+ * The distance function.
*/
- double doubleKNNDistance();
-
- @Override
- DoubleDistanceDBIDListIter iter();
-
- @Override
- DoubleDistanceDBIDPair get(int off);
+ SpatialPrimitiveDistanceFunction<O> distanceFunction;
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/images/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/package-info.java
index 1a76913e..972376d6 100644
--- a/src/de/lmu/ifi/dbs/elki/data/images/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/package-info.java
@@ -1,13 +1,11 @@
/**
- * <p>Package for processing image data (e.g. compute color histograms)</p>
- *
- * @apiviz.exclude java.io.*
+ * <p>{@link de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rdknn.RdKNNTree}</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
@@ -25,4 +23,4 @@ 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.data.images;
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rdknn; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTree.java
index 1c2a7fe8..f7ee9bb5 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar;
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/index/tree/spatial/rstarvariants/rstar/RStarTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeFactory.java
index 72f7f7dd..74a6f54d 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar;
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
@@ -43,7 +43,7 @@ import de.lmu.ifi.dbs.elki.utilities.Alias;
* @param <O> Object type
*/
@Alias({"rstar", "r*"})
-public class RStarTreeFactory<O extends NumberVector<?>> extends AbstractRStarTreeFactory<O, RStarTreeNode, SpatialEntry, RStarTreeIndex<O>, AbstractRTreeSettings> {
+public class RStarTreeFactory<O extends NumberVector> extends AbstractRStarTreeFactory<O, RStarTreeNode, SpatialEntry, RStarTreeIndex<O>, AbstractRTreeSettings> {
/**
* Constructor.
*
@@ -73,7 +73,7 @@ public class RStarTreeFactory<O extends NumberVector<?>> extends AbstractRStarTr
*
* @param <O> Object type
*/
- public static class Parameterizer<O extends NumberVector<?>> extends AbstractRStarTreeFactory.Parameterizer<O, AbstractRTreeSettings> {
+ public static class Parameterizer<O extends NumberVector> extends AbstractRStarTreeFactory.Parameterizer<O, AbstractRTreeSettings> {
@Override
protected RStarTreeFactory<O> makeInstance() {
return new RStarTreeFactory<>(pageFileFactory, settings);
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeIndex.java
index 15b43e64..f94d20dd 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar;
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
@@ -36,7 +36,6 @@ import de.lmu.ifi.dbs.elki.database.query.distance.SpatialDistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
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.DynamicIndex;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
import de.lmu.ifi.dbs.elki.index.RangeIndex;
@@ -55,7 +54,7 @@ import de.lmu.ifi.dbs.elki.persistent.PageFile;
*
* @param <O> Object type
*/
-public class RStarTreeIndex<O extends NumberVector<?>> extends RStarTree implements RangeIndex<O>, KNNIndex<O>, DynamicIndex {
+public class RStarTreeIndex<O extends NumberVector> extends RStarTree implements RangeIndex<O>, KNNIndex<O>, DynamicIndex {
/**
* The appropriate logger for this index.
*/
@@ -93,7 +92,7 @@ public class RStarTreeIndex<O extends NumberVector<?>> extends RStarTree impleme
super.initialize();
insertAll(relation.getDBIDs()); // Will check for actual bulk load!
}
-
+
/**
* Inserts the specified reel vector object into this index.
*
@@ -119,13 +118,13 @@ public class RStarTreeIndex<O extends NumberVector<?>> extends RStarTree impleme
// Make an example leaf
if(canBulkLoad()) {
List<SpatialEntry> leafs = new ArrayList<>(ids.size());
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
leafs.add(createNewLeafEntry(iter));
}
bulkLoad(leafs);
}
else {
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
insert(DBIDUtil.deref(iter));
}
}
@@ -153,13 +152,13 @@ public class RStarTreeIndex<O extends NumberVector<?>> extends RStarTree impleme
@Override
public void deleteAll(DBIDs ids) {
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
delete(iter);
}
}
@Override
- public <D extends Distance<D>> RangeQuery<O, D> getRangeQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
+ public RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) {
// Query on the relation we index
if(distanceQuery.getRelation() != relation) {
return null;
@@ -168,12 +167,12 @@ public class RStarTreeIndex<O extends NumberVector<?>> extends RStarTree impleme
if(!(distanceQuery instanceof SpatialDistanceQuery)) {
return null;
}
- SpatialDistanceQuery<O, D> dq = (SpatialDistanceQuery<O, D>) distanceQuery;
+ SpatialDistanceQuery<O> dq = (SpatialDistanceQuery<O>) distanceQuery;
return RStarTreeUtil.getRangeQuery(this, dq, hints);
}
@Override
- public <D extends Distance<D>> KNNQuery<O, D> getKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints) {
+ public KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) {
// Query on the relation we index
if(distanceQuery.getRelation() != relation) {
return null;
@@ -182,7 +181,7 @@ public class RStarTreeIndex<O extends NumberVector<?>> extends RStarTree impleme
if(!(distanceQuery instanceof SpatialDistanceQuery)) {
return null;
}
- SpatialDistanceQuery<O, D> dq = (SpatialDistanceQuery<O, D>) distanceQuery;
+ SpatialDistanceQuery<O> dq = (SpatialDistanceQuery<O>) distanceQuery;
return RStarTreeUtil.getKNNQuery(this, dq, hints);
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeNode.java
index 7226fa1c..833b32d0 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar;
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/index/tree/spatial/rstarvariants/rstar/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/package-info.java
index 7897fae1..8d8b2355 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/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/index/tree/spatial/rstarvariants/strategies/bulk/AbstractBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/AbstractBulkSplit.java
index 7d463a03..6f656be6 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/AbstractBulkSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/AbstractBulkSplit.java
@@ -7,7 +7,7 @@ import java.util.List;
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/index/tree/spatial/rstarvariants/strategies/bulk/AdaptiveSortTileRecursiveBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/AdaptiveSortTileRecursiveBulkSplit.java
index fbbf7d8f..5794bc0d 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/AdaptiveSortTileRecursiveBulkSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/AdaptiveSortTileRecursiveBulkSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
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/index/tree/spatial/rstarvariants/strategies/bulk/BulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/BulkSplit.java
index c32a512c..d42f03e2 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/BulkSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/BulkSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
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,13 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
import java.util.List;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Interface for a bulk split strategy.
*
* @author Erich Schubert
*/
-public interface BulkSplit extends Parameterizable {
+public interface BulkSplit {
/**
* Partitions the specified feature vectors
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/FileOrderBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/FileOrderBulkSplit.java
index 8b0dfd77..77aaf071 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/FileOrderBulkSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/FileOrderBulkSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
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/index/tree/spatial/rstarvariants/strategies/bulk/MaxExtensionBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/MaxExtensionBulkSplit.java
index 5251e18b..edf11285 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/MaxExtensionBulkSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/MaxExtensionBulkSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
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/index/tree/spatial/rstarvariants/strategies/bulk/MaxExtensionSortTileRecursiveBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/MaxExtensionSortTileRecursiveBulkSplit.java
index 6bf37642..8852bffa 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/MaxExtensionSortTileRecursiveBulkSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/MaxExtensionSortTileRecursiveBulkSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
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/index/tree/spatial/rstarvariants/strategies/bulk/OneDimSortBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/OneDimSortBulkSplit.java
index 5d2083b3..f691789e 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/OneDimSortBulkSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/OneDimSortBulkSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
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/index/tree/spatial/rstarvariants/strategies/bulk/SortTileRecursiveBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SortTileRecursiveBulkSplit.java
index 6cd7a598..a5431819 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SortTileRecursiveBulkSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SortTileRecursiveBulkSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
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/index/tree/spatial/rstarvariants/strategies/bulk/SpatialSortBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SpatialSortBulkSplit.java
index 6e2b6369..b99764ab 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SpatialSortBulkSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SpatialSortBulkSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
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/index/tree/spatial/rstarvariants/strategies/bulk/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/package-info.java
index 5c52de3e..e2e2e593 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/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/index/tree/spatial/rstarvariants/strategies/insert/ApproximativeLeastOverlapInsertionStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/ApproximativeLeastOverlapInsertionStrategy.java
index 01dde189..fe9698ba 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/ApproximativeLeastOverlapInsertionStrategy.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/ApproximativeLeastOverlapInsertionStrategy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert;
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/index/tree/spatial/rstarvariants/strategies/insert/CombinedInsertionStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/CombinedInsertionStrategy.java
index 837f0312..ac055184 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/CombinedInsertionStrategy.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/CombinedInsertionStrategy.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert;
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/index/tree/spatial/rstarvariants/strategies/insert/InsertionStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/InsertionStrategy.java
index 477f0f48..964bce27 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/InsertionStrategy.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/InsertionStrategy.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert;
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,14 +24,13 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* RTree insertion strategy interface.
*
* @author Erich Schubert
*/
-public interface InsertionStrategy extends Parameterizable {
+public interface InsertionStrategy {
/**
* Choose insertion rectangle.
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementInsertionStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementInsertionStrategy.java
index 39348bf5..93d80436 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementInsertionStrategy.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementInsertionStrategy.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert;
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/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementWithAreaInsertionStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementWithAreaInsertionStrategy.java
index 627428e9..cf1267f7 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementWithAreaInsertionStrategy.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementWithAreaInsertionStrategy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert;
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/index/tree/spatial/rstarvariants/strategies/insert/LeastOverlapInsertionStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastOverlapInsertionStrategy.java
index 18855d90..8ed0b2b1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastOverlapInsertionStrategy.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastOverlapInsertionStrategy.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert;
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/index/tree/spatial/rstarvariants/strategies/insert/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/package-info.java
index d425c7bd..6c2f26b2 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/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/index/tree/spatial/rstarvariants/strategies/overflow/LimitedReinsertOverflowTreatment.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/LimitedReinsertOverflowTreatment.java
index 0af90d78..b7184f93 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/LimitedReinsertOverflowTreatment.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/LimitedReinsertOverflowTreatment.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.overflow
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/index/tree/spatial/rstarvariants/strategies/overflow/OverflowTreatment.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/OverflowTreatment.java
index 4b2f94b1..06dcd215 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/OverflowTreatment.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/OverflowTreatment.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.overflow
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/index/tree/spatial/rstarvariants/strategies/overflow/SplitOnlyOverflowTreatment.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/SplitOnlyOverflowTreatment.java
index 82ceb4ef..5aea9e5c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/SplitOnlyOverflowTreatment.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/SplitOnlyOverflowTreatment.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.overflow
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/index/tree/spatial/rstarvariants/strategies/overflow/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/package-info.java
index fc7f16f0..28cbc3eb 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/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/index/tree/spatial/rstarvariants/strategies/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/package-info.java
index 7d2dfc0a..d3b6de11 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/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/index/tree/spatial/rstarvariants/strategies/reinsert/AbstractPartialReinsert.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/AbstractPartialReinsert.java
index f73699ea..02b98e3b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/AbstractPartialReinsert.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/AbstractPartialReinsert.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert
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.index.tree.spatial.rstarvariants.strategies.reinsert
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-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.SquaredEuclideanDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -47,7 +47,7 @@ public abstract class AbstractPartialReinsert implements ReinsertStrategy {
/**
* Distance function to use for measuring
*/
- SpatialPrimitiveDoubleDistanceFunction<?> distanceFunction;
+ SpatialPrimitiveDistanceFunction<?> distanceFunction;
/**
* Constructor.
@@ -55,7 +55,7 @@ public abstract class AbstractPartialReinsert implements ReinsertStrategy {
* @param reinsertAmount Relative amount of objects to reinsert.
* @param distanceFunction Distance function to use
*/
- public AbstractPartialReinsert(double reinsertAmount, SpatialPrimitiveDoubleDistanceFunction<?> distanceFunction) {
+ public AbstractPartialReinsert(double reinsertAmount, SpatialPrimitiveDistanceFunction<?> distanceFunction) {
super();
this.reinsertAmount = reinsertAmount;
this.distanceFunction = distanceFunction;
@@ -87,7 +87,7 @@ public abstract class AbstractPartialReinsert implements ReinsertStrategy {
/**
* Distance function to use for measuring
*/
- SpatialPrimitiveDoubleDistanceFunction<?> distanceFunction;
+ SpatialPrimitiveDistanceFunction<?> distanceFunction;
@Override
protected void makeOptions(Parameterization config) {
@@ -98,7 +98,7 @@ public abstract class AbstractPartialReinsert implements ReinsertStrategy {
if(config.grab(reinsertAmountP)) {
reinsertAmount = reinsertAmountP.getValue();
}
- ObjectParameter<SpatialPrimitiveDoubleDistanceFunction<?>> distanceP = new ObjectParameter<>(REINSERT_DISTANCE_ID, SpatialPrimitiveDoubleDistanceFunction.class, SquaredEuclideanDistanceFunction.class);
+ ObjectParameter<SpatialPrimitiveDistanceFunction<?>> distanceP = new ObjectParameter<>(REINSERT_DISTANCE_ID, SpatialPrimitiveDistanceFunction.class, SquaredEuclideanDistanceFunction.class);
if(config.grab(distanceP)) {
distanceFunction = distanceP.instantiateClass(config);
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/CloseReinsert.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/CloseReinsert.java
index 3002f18b..05dcffb9 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/CloseReinsert.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/CloseReinsert.java
@@ -6,7 +6,7 @@ import java.util.Collections;
import de.lmu.ifi.dbs.elki.data.DoubleVector;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
@@ -15,7 +15,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
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
@@ -42,24 +42,27 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
*
* @author Erich Schubert
*/
-@Reference(authors = "N. Beckmann, H.-P. Kriegel, R. Schneider, B. Seeger", title = "The R*-tree: an efficient and robust access method for points and rectangles", booktitle = "Proceedings of the 1990 ACM SIGMOD International Conference on Management of Data, Atlantic City, NJ, May 23-25, 1990", url = "http://dx.doi.org/10.1145/93597.98741")
+@Reference(authors = "N. Beckmann, H.-P. Kriegel, R. Schneider, B. Seeger", //
+title = "The R*-tree: an efficient and robust access method for points and rectangles", //
+booktitle = "Proceedings of the 1990 ACM SIGMOD International Conference on Management of Data, Atlantic City, NJ, May 23-25, 1990", //
+url = "http://dx.doi.org/10.1145/93597.98741")
public class CloseReinsert extends AbstractPartialReinsert {
/**
* Constructor.
- *
+ *
* @param reinsertAmount Amount of objects to reinsert
* @param distanceFunction Distance function to use for reinsertion
*/
- public CloseReinsert(double reinsertAmount, SpatialPrimitiveDoubleDistanceFunction<?> distanceFunction) {
+ public CloseReinsert(double reinsertAmount, SpatialPrimitiveDistanceFunction<?> distanceFunction) {
super(reinsertAmount, distanceFunction);
}
@Override
public <A> int[] computeReinserts(A entries, ArrayAdapter<? extends SpatialComparable, ? super A> getter, SpatialComparable page) {
DoubleIntPair[] order = new DoubleIntPair[getter.size(entries)];
- DoubleVector centroid = new DoubleVector(SpatialUtil.centroid(page));
+ DoubleVector centroid = new DoubleVector(SpatialUtil.centroid(page));
for(int i = 0; i < order.length; i++) {
- double distance = distanceFunction.doubleMinDist(new DoubleVector(SpatialUtil.centroid(getter.get(entries, i))), centroid);
+ double distance = distanceFunction.minDist(new DoubleVector(SpatialUtil.centroid(getter.get(entries, i))), centroid);
order[i] = new DoubleIntPair(distance, i);
}
Arrays.sort(order, Collections.reverseOrder());
@@ -71,7 +74,7 @@ public class CloseReinsert extends AbstractPartialReinsert {
}
return re;
}
-
+
/**
* Parameterization class.
*
@@ -81,7 +84,7 @@ public class CloseReinsert extends AbstractPartialReinsert {
*/
public static class Parameterizer extends AbstractPartialReinsert.Parameterizer {
@Override
- protected Object makeInstance() {
+ protected CloseReinsert makeInstance() {
return new CloseReinsert(reinsertAmount, distanceFunction);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/FarReinsert.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/FarReinsert.java
index 02c1d4d7..bdb7790a 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/FarReinsert.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/FarReinsert.java
@@ -6,7 +6,7 @@ import java.util.Collections;
import de.lmu.ifi.dbs.elki.data.DoubleVector;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
@@ -15,7 +15,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
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
@@ -42,7 +42,10 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
*
* @author Erich Schubert
*/
-@Reference(authors = "N. Beckmann, H.-P. Kriegel, R. Schneider, B. Seeger", title = "The R*-tree: an efficient and robust access method for points and rectangles", booktitle = "Proceedings of the 1990 ACM SIGMOD International Conference on Management of Data, Atlantic City, NJ, May 23-25, 1990", url = "http://dx.doi.org/10.1145/93597.98741")
+@Reference(authors = "N. Beckmann, H.-P. Kriegel, R. Schneider, B. Seeger", //
+title = "The R*-tree: an efficient and robust access method for points and rectangles", //
+booktitle = "Proceedings of the 1990 ACM SIGMOD International Conference on Management of Data, Atlantic City, NJ, May 23-25, 1990", //
+url = "http://dx.doi.org/10.1145/93597.98741")
public class FarReinsert extends AbstractPartialReinsert {
/**
* Constructor.
@@ -50,7 +53,7 @@ public class FarReinsert extends AbstractPartialReinsert {
* @param reinsertAmount Amount to reinsert
* @param distanceFunction Distance function
*/
- public FarReinsert(double reinsertAmount, SpatialPrimitiveDoubleDistanceFunction<?> distanceFunction) {
+ public FarReinsert(double reinsertAmount, SpatialPrimitiveDistanceFunction<?> distanceFunction) {
super(reinsertAmount, distanceFunction);
}
@@ -59,7 +62,7 @@ public class FarReinsert extends AbstractPartialReinsert {
DoubleIntPair[] order = new DoubleIntPair[getter.size(entries)];
DoubleVector centroid = new DoubleVector(SpatialUtil.centroid(page));
for(int i = 0; i < order.length; i++) {
- double distance = distanceFunction.doubleMinDist(new DoubleVector(SpatialUtil.centroid(getter.get(entries, i))), centroid);
+ double distance = distanceFunction.minDist(new DoubleVector(SpatialUtil.centroid(getter.get(entries, i))), centroid);
order[i] = new DoubleIntPair(distance, i);
}
Arrays.sort(order, Collections.reverseOrder());
@@ -81,8 +84,8 @@ public class FarReinsert extends AbstractPartialReinsert {
*/
public static class Parameterizer extends AbstractPartialReinsert.Parameterizer {
@Override
- protected Object makeInstance() {
- return new CloseReinsert(reinsertAmount, distanceFunction);
+ protected FarReinsert makeInstance() {
+ return new FarReinsert(reinsertAmount, distanceFunction);
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/ReinsertStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/ReinsertStrategy.java
index 2a4f130f..4b350123 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/ReinsertStrategy.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/ReinsertStrategy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert
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/index/tree/spatial/rstarvariants/strategies/reinsert/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/package-info.java
index 2d2c6871..e96642f6 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/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/index/tree/spatial/rstarvariants/strategies/split/AngTanLinearSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/AngTanLinearSplit.java
index c31abc2d..60ba9457 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/AngTanLinearSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/AngTanLinearSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split;
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/index/tree/spatial/rstarvariants/strategies/split/GreeneSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/GreeneSplit.java
index d00479cf..5bee1302 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/GreeneSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/GreeneSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split;
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/index/tree/spatial/rstarvariants/strategies/split/RTreeLinearSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeLinearSplit.java
index 4dc9b15d..75f37a71 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeLinearSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeLinearSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split;
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/index/tree/spatial/rstarvariants/strategies/split/RTreeQuadraticSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeQuadraticSplit.java
index 91ef8f16..2ac7c176 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeQuadraticSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeQuadraticSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split;
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/index/tree/spatial/rstarvariants/strategies/split/SplitStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/SplitStrategy.java
index 0bc1ffcf..0bd4f39f 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/SplitStrategy.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/SplitStrategy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split;
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,14 +27,13 @@ import java.util.BitSet;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Generic interface for split strategies.
*
* @author Erich Schubert
*/
-public interface SplitStrategy extends Parameterizable {
+public interface SplitStrategy {
/**
* Split a page
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/TopologicalSplitter.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/TopologicalSplitter.java
index dc9092ad..259c83b1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/TopologicalSplitter.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/TopologicalSplitter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split;
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/index/tree/spatial/rstarvariants/strategies/split/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/package-info.java
index bb8cb1e2..78bffb0f 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/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/index/tree/spatial/rstarvariants/util/NodeArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/NodeArrayAdapter.java
index def824ba..86cb360a 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/NodeArrayAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/NodeArrayAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util;
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/index/tree/spatial/rstarvariants/util/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/package-info.java
index 22088417..6f2686f6 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/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/index/vafile/DAFile.java b/src/de/lmu/ifi/dbs/elki/index/vafile/DAFile.java
index 089397dd..dcc54e2a 100644
--- a/src/de/lmu/ifi/dbs/elki/index/vafile/DAFile.java
+++ b/src/de/lmu/ifi/dbs/elki/index/vafile/DAFile.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.vafile;
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
@@ -28,8 +28,8 @@ import java.util.Arrays;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
/**
* Dimension approximation file, a one-dimensional part of the
@@ -66,7 +66,7 @@ public class DAFile {
* @param dimension Dimension of this file
* @param partitions Number of partitions
*/
- public DAFile(Relation<? extends NumberVector<?>> relation, int dimension, int partitions) {
+ public DAFile(Relation<? extends NumberVector> relation, int dimension, int partitions) {
final int size = relation.size();
this.dimension = dimension;
this.splitPositions = new double[partitions + 1];
diff --git a/src/de/lmu/ifi/dbs/elki/index/vafile/PartialVAFile.java b/src/de/lmu/ifi/dbs/elki/index/vafile/PartialVAFile.java
index e66b4011..a7dd0a29 100644
--- a/src/de/lmu/ifi/dbs/elki/index/vafile/PartialVAFile.java
+++ b/src/de/lmu/ifi/dbs/elki/index/vafile/PartialVAFile.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.vafile;
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,6 @@ package de.lmu.ifi.dbs.elki.index.vafile;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.BitSet;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
@@ -38,9 +37,10 @@ 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.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPairList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
@@ -50,8 +50,6 @@ import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.SubspaceLPNormDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.index.AbstractRefiningIndex;
import de.lmu.ifi.dbs.elki.index.IndexFactory;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
@@ -61,9 +59,10 @@ import de.lmu.ifi.dbs.elki.logging.statistics.Counter;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.persistent.AbstractPageFileFactory;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.DoubleMaxHeap;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+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.constraints.CommonConstraints;
@@ -96,7 +95,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleObjPair;
* @param <V> Vector type
*/
@Reference(authors = "Hans-Peter Kriegel, Peer Kröger, Matthias Schubert, Ziyue Zhu", title = "Efficient Query Processing in Arbitrary Subspaces Using Vector Approximations", booktitle = "Proc. 18th Int. Conf. on Scientific and Statistical Database Management (SSDBM 06), Wien, Austria, 2006", url = "http://dx.doi.org/10.1109/SSDBM.2006.23")
-public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIndex<V> implements KNNIndex<V>, RangeIndex<V> {
+public class PartialVAFile<V extends NumberVector> extends AbstractRefiningIndex<V> implements KNNIndex<V>, RangeIndex<V> {
/**
* Class logger.
*/
@@ -152,7 +151,7 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
throw new IllegalStateException("Data already inserted.");
}
- if((Math.log(partitions) / MathUtil.LOG2) != (int) (Math.log(partitions) / MathUtil.LOG2)) {
+ if(MathUtil.log2(partitions) != (int) MathUtil.log2(partitions)) {
throw new IllegalArgumentException("Number of partitions must be a power of 2!");
}
@@ -196,21 +195,6 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
}
/**
- * Fake subspace (full-dimensional).
- *
- * @param relation Relation with full dimensionality
- * @return Bit set with all bits set.
- */
- protected static BitSet fakeSubspace(Relation<? extends NumberVector<?>> relation) {
- int dim = RelationUtil.dimensionality(relation);
- BitSet bits = new BitSet();
- for(int i = 0; i < dim; i++) {
- bits.set(i);
- }
- return bits;
- }
-
- /**
* Calculate the VA file position given the existing borders.
*
* @param id Object ID
@@ -247,51 +231,41 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
return new VectorApproximation(id, approximation);
}
- @SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> KNNQuery<V, D> getKNNQuery(DistanceQuery<V, D> distanceQuery, Object... hints) {
+ public KNNQuery<V> getKNNQuery(DistanceQuery<V> distanceQuery, Object... hints) {
for(Object hint : hints) {
if(hint == DatabaseQuery.HINT_BULK) {
// FIXME: support bulk?
return null;
}
}
- DistanceFunction<? super V, ?> df = distanceQuery.getDistanceFunction();
+ DistanceFunction<? super V> df = distanceQuery.getDistanceFunction();
if(df instanceof SubspaceLPNormDistanceFunction) {
double p = ((SubspaceLPNormDistanceFunction) df).getP();
- BitSet bits = ((SubspaceLPNormDistanceFunction) df).getSelectedDimensions();
- DistanceQuery<V, ?> ddq = (DistanceQuery<V, ?>) distanceQuery;
- KNNQuery<V, ?> dq = new PartialVAFileKNNQuery((DistanceQuery<V, DoubleDistance>) ddq, p, bits);
- return (KNNQuery<V, D>) dq;
+ long[] bits = ((SubspaceLPNormDistanceFunction) df).getSelectedDimensions();
+ return new PartialVAFileKNNQuery(distanceQuery, p, bits);
}
if(df instanceof LPNormDistanceFunction) {
double p = ((LPNormDistanceFunction) df).getP();
- BitSet bits = fakeSubspace(distanceQuery.getRelation());
- DistanceQuery<V, ?> ddq = (DistanceQuery<V, ?>) distanceQuery;
- KNNQuery<V, ?> dq = new PartialVAFileKNNQuery((DistanceQuery<V, DoubleDistance>) ddq, p, bits);
- return (KNNQuery<V, D>) dq;
+ long[] bits = BitsUtil.ones(RelationUtil.dimensionality(distanceQuery.getRelation()));
+ return new PartialVAFileKNNQuery(distanceQuery, p, bits);
}
// Not supported.
return null;
}
- @SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> RangeQuery<V, D> getRangeQuery(DistanceQuery<V, D> distanceQuery, Object... hints) {
- DistanceFunction<? super V, ?> df = distanceQuery.getDistanceFunction();
+ public RangeQuery<V> getRangeQuery(DistanceQuery<V> distanceQuery, Object... hints) {
+ DistanceFunction<? super V> df = distanceQuery.getDistanceFunction();
if(df instanceof SubspaceLPNormDistanceFunction) {
double p = ((SubspaceLPNormDistanceFunction) df).getP();
- BitSet bits = ((SubspaceLPNormDistanceFunction) df).getSelectedDimensions();
- DistanceQuery<V, ?> ddq = (DistanceQuery<V, ?>) distanceQuery;
- RangeQuery<V, ?> dq = new PartialVAFileRangeQuery((DistanceQuery<V, DoubleDistance>) ddq, p, bits);
- return (RangeQuery<V, D>) dq;
+ long[] bits = ((SubspaceLPNormDistanceFunction) df).getSelectedDimensions();
+ return new PartialVAFileRangeQuery(distanceQuery, p, bits);
}
if(df instanceof LPNormDistanceFunction) {
double p = ((LPNormDistanceFunction) df).getP();
- BitSet bits = fakeSubspace(distanceQuery.getRelation());
- DistanceQuery<V, ?> ddq = (DistanceQuery<V, ?>) distanceQuery;
- RangeQuery<V, ?> dq = new PartialVAFileRangeQuery((DistanceQuery<V, DoubleDistance>) ddq, p, bits);
- return (RangeQuery<V, D>) dq;
+ long[] bits = BitsUtil.ones(RelationUtil.dimensionality(distanceQuery.getRelation()));
+ return new PartialVAFileRangeQuery(distanceQuery, p, bits);
}
// Not supported.
return null;
@@ -304,7 +278,7 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
* @param query Query vector
* @param epsilon Epsilon radius
*/
- protected static void calculateSelectivityCoeffs(List<DoubleObjPair<DAFile>> daFiles, NumberVector<?> query, double epsilon) {
+ protected static void calculateSelectivityCoeffs(List<DoubleObjPair<DAFile>> daFiles, NumberVector query, double epsilon) {
final int dimensions = query.getDimensionality();
double[] lowerVals = new double[dimensions];
double[] upperVals = new double[dimensions];
@@ -337,7 +311,7 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
* @param daFiles List of approximations to use
* @return Vector approximation
*/
- protected static VectorApproximation calculatePartialApproximation(DBID id, NumberVector<?> dv, List<DoubleObjPair<DAFile>> daFiles) {
+ protected static VectorApproximation calculatePartialApproximation(DBID id, NumberVector dv, List<DoubleObjPair<DAFile>> daFiles) {
int[] approximation = new int[dv.getDimensionality()];
for(int i = 0; i < daFiles.size(); i++) {
double val = dv.doubleValue(i);
@@ -484,7 +458,7 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
* @author Erich Schubert
* @author Thomas Bernecker
*/
- public class PartialVAFileRangeQuery extends AbstractRefiningIndex<V>.AbstractRangeQuery<DoubleDistance> {
+ public class PartialVAFileRangeQuery extends AbstractRefiningIndex<V>.AbstractRangeQuery {
/**
* Lp-Norm p.
*/
@@ -493,7 +467,7 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
/**
* Subspace.
*/
- private BitSet subspace;
+ private long[] subspace;
/**
* Constructor.
@@ -502,18 +476,18 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
* @param p LP Norm p
* @param subspace Subspace
*/
- public PartialVAFileRangeQuery(DistanceQuery<V, DoubleDistance> ddq, double p, BitSet subspace) {
+ public PartialVAFileRangeQuery(DistanceQuery<V> ddq, double p, long[] subspace) {
super(ddq);
this.p = p;
this.subspace = subspace;
}
@Override
- public DoubleDistanceDBIDPairList getRangeForObject(V query, DoubleDistance range) {
+ public DoubleDBIDList getRangeForObject(V query, double range) {
stats.incrementIssuedQueries();
long t = System.nanoTime();
- final double epsilonP = Math.pow(range.doubleValue(), p);
+ final double epsilonP = Math.pow(range, p);
// generate query approximation and lookup table
final VectorApproximation queryApprox = calculateFullApproximation(null, query);
@@ -524,12 +498,12 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
// filter step
// calculate selectivity coefficients
- List<DoubleObjPair<DAFile>> subspaceDAFiles = new ArrayList<>(subspace.cardinality());
- for(int d = subspace.nextSetBit(0); d >= 0; d = subspace.nextSetBit(d + 1)) {
+ List<DoubleObjPair<DAFile>> subspaceDAFiles = new ArrayList<>(BitsUtil.cardinality(subspace));
+ for(int d = BitsUtil.nextSetBit(subspace, 0); d >= 0; d = BitsUtil.nextSetBit(subspace, d + 1)) {
DAFile daFile = daFiles.get(d);
subspaceDAFiles.add(new DoubleObjPair<>(-1, daFile));
}
- calculateSelectivityCoeffs(subspaceDAFiles, query, range.doubleValue());
+ calculateSelectivityCoeffs(subspaceDAFiles, query, range);
// sort DA files by selectivity
// TODO: validate that this is the correct order
Collections.sort(subspaceDAFiles, Collections.reverseOrder());
@@ -537,7 +511,7 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
// create candidate list (all objects) and prune candidates w.r.t.
// mindist (i.e. remove them from the list)
// important: this structure contains the maxDist values for refinement!
- DoubleDistanceDBIDPairList result = new DoubleDistanceDBIDPairList();
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
int candidates = 0;
for(VectorApproximation va : vectorApprox) {
DBID id = va.getId();
@@ -560,20 +534,20 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
// candidate cannot be dropped
// TODO: actually: no refinement needed - need API that allows
// reporting maxdists only.
- result.add(refine(id, query).doubleValue(), id);
+ result.add(refine(id, query), id);
}
else { // refine candidate - true refinement
- DoubleDistance dis = refine(id, query);
+ double dis = refine(id, query);
stats.incrementRefinements();
- if(dis.doubleValue() <= range.doubleValue()) {
- result.add(dis.doubleValue(), id);
+ if(dis <= range) {
+ result.add(dis, id);
}
}
}
}
result.sort();
- stats.incrementScannedBytes(relation.size() * VectorApproximation.byteOnDisk(subspace.cardinality(), partitions));
+ stats.incrementScannedBytes(relation.size() * VectorApproximation.byteOnDisk(BitsUtil.cardinality(subspace), partitions));
stats.incrementQueryTime(System.nanoTime() - t);
@@ -592,7 +566,7 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
* @author Erich Schubert
* @author Thomas Bernecker
*/
- public class PartialVAFileKNNQuery extends AbstractRefiningIndex<V>.AbstractKNNQuery<DoubleDistance> {
+ public class PartialVAFileKNNQuery extends AbstractRefiningIndex<V>.AbstractKNNQuery {
/**
* Lp-Norm p.
*/
@@ -601,7 +575,7 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
/**
* Subspace.
*/
- private BitSet subspace;
+ private long[] subspace;
/**
* Constructor.
@@ -610,14 +584,14 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
* @param p LP-norm p
* @param subspace Subspace to query
*/
- public PartialVAFileKNNQuery(DistanceQuery<V, DoubleDistance> ddq, double p, BitSet subspace) {
+ public PartialVAFileKNNQuery(DistanceQuery<V> ddq, double p, long[] subspace) {
super(ddq);
this.p = p;
this.subspace = subspace;
}
@Override
- public DoubleDistanceKNNList getKNNForObject(V query, int k) {
+ public KNNList getKNNForObject(V query, int k) {
stats.incrementIssuedQueries();
long t = System.nanoTime();
@@ -628,7 +602,7 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
// sort DA files by worst case distance
List<DAFile> daFiles = getWorstCaseDistOrder(dist, subspace);
- final int currentSubspaceDims = subspace.cardinality();
+ final int currentSubspaceDims = BitsUtil.cardinality(subspace);
int reducedDims = (2 * currentSubspaceDims) / 3;
reducedDims = Math.max(1, reducedDims);
if(LOG.isDebuggingFine()) {
@@ -690,7 +664,7 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
ArrayList<PartialVACandidate> sortedCandidates = new ArrayList<>(candidates2);
// sort candidates by lower bound (minDist)
Collections.sort(sortedCandidates);
- DoubleDistanceKNNList result = retrieveAccurateDistances(sortedCandidates, k, subspace, query);
+ KNNList result = retrieveAccurateDistances(sortedCandidates, k, subspace, query);
stats.incrementQueryTime(System.nanoTime() - t);
return result;
@@ -758,26 +732,26 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
* @param subspace Subspace
* @return Ordered list of dimension files
*/
- public List<DAFile> getWorstCaseDistOrder(VALPNormDistance dist, BitSet subspace) {
- int subspaceLength = subspace.cardinality();
+ public List<DAFile> getWorstCaseDistOrder(VALPNormDistance dist, long[] subspace) {
+ int subspaceLength = BitsUtil.cardinality(subspace);
List<DAFile> result = new ArrayList<>(subspaceLength);
- for(int i = subspace.nextSetBit(0); i >= 0; i = subspace.nextSetBit(i + 1)) {
+ for(int i = BitsUtil.nextSetBit(subspace, 0); i >= 0; i = BitsUtil.nextSetBit(subspace, i + 1)) {
result.add(daFiles.get(i));
}
Collections.sort(result, new WorstCaseDistComparator(dist));
return result;
}
- protected DoubleDistanceKNNList retrieveAccurateDistances(List<PartialVACandidate> sortedCandidates, int k, BitSet subspace, V query) {
- DoubleDistanceKNNHeap result = DBIDUtil.newDoubleDistanceHeap(k);
+ protected KNNList retrieveAccurateDistances(List<PartialVACandidate> sortedCandidates, int k, long[] subspace, V query) {
+ KNNHeap result = DBIDUtil.newHeap(k);
for(PartialVACandidate va : sortedCandidates) {
- double stopdist = result.doubleKNNDistance();
+ double stopdist = result.getKNNDistance();
DBID currentID = va.getId();
if(result.size() < k || va.minDistP < stopdist) {
- DoubleDistance dist = refine(currentID, query);
+ double dist = refine(currentID, query);
stats.incrementRefinements();
- if(dist.doubleValue() < stopdist) {
- result.insert(dist.doubleValue(), currentID);
+ if(dist < stopdist) {
+ result.insert(dist, currentID);
}
}
}
@@ -813,7 +787,7 @@ public class PartialVAFile<V extends NumberVector<?>> extends AbstractRefiningIn
*
* @param <V> Vector type
*/
- public static class Factory<V extends NumberVector<?>> implements IndexFactory<V, PartialVAFile<V>> {
+ public static class Factory<V extends NumberVector> implements IndexFactory<V, PartialVAFile<V>> {
/**
* Number of partitions to use in each dimension.
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/vafile/VAFile.java b/src/de/lmu/ifi/dbs/elki/index/vafile/VAFile.java
index 42651b15..bdf30d15 100644
--- a/src/de/lmu/ifi/dbs/elki/index/vafile/VAFile.java
+++ b/src/de/lmu/ifi/dbs/elki/index/vafile/VAFile.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.vafile;
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,6 @@ package de.lmu.ifi.dbs.elki.index.vafile;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import de.lmu.ifi.dbs.elki.data.NumberVector;
@@ -34,9 +33,11 @@ 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.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPairList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
@@ -45,8 +46,6 @@ 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.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.index.AbstractRefiningIndex;
import de.lmu.ifi.dbs.elki.index.IndexFactory;
import de.lmu.ifi.dbs.elki.index.KNNIndex;
@@ -61,7 +60,6 @@ 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.pairs.DoubleObjPair;
/**
* Vector-approximation file (VAFile)
@@ -87,7 +85,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleObjPair;
*/
@Title("An approximation based data structure for similarity search")
@Reference(authors = "Weber, R. and Blott, S.", title = "An approximation based data structure for similarity search", booktitle = "Report TR1997b, ETH Zentrum, Zurich, Switzerland", url = "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.40.480&rep=rep1&type=pdf")
-public class VAFile<V extends NumberVector<?>> extends AbstractRefiningIndex<V> implements KNNIndex<V>, RangeIndex<V> {
+public class VAFile<V extends NumberVector> extends AbstractRefiningIndex<V> implements KNNIndex<V>, RangeIndex<V> {
/**
* Logging class.
*/
@@ -244,35 +242,29 @@ public class VAFile<V extends NumberVector<?>> extends AbstractRefiningIndex<V>
return "va-file";
}
- @SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> KNNQuery<V, D> getKNNQuery(DistanceQuery<V, D> distanceQuery, Object... hints) {
+ public KNNQuery<V> getKNNQuery(DistanceQuery<V> distanceQuery, Object... hints) {
for(Object hint : hints) {
if(hint == DatabaseQuery.HINT_BULK) {
// FIXME: support bulk?
return null;
}
}
- DistanceFunction<? super V, ?> df = distanceQuery.getDistanceFunction();
+ DistanceFunction<? super V> df = distanceQuery.getDistanceFunction();
if(df instanceof LPNormDistanceFunction) {
double p = ((LPNormDistanceFunction) df).getP();
- DistanceQuery<V, ?> ddq = (DistanceQuery<V, ?>) distanceQuery;
- KNNQuery<V, ?> dq = new VAFileKNNQuery((DistanceQuery<V, DoubleDistance>) ddq, p);
- return (KNNQuery<V, D>) dq;
+ return new VAFileKNNQuery(distanceQuery, p);
}
// Not supported.
return null;
}
- @SuppressWarnings("unchecked")
@Override
- public <D extends Distance<D>> RangeQuery<V, D> getRangeQuery(DistanceQuery<V, D> distanceQuery, Object... hints) {
- DistanceFunction<? super V, ?> df = distanceQuery.getDistanceFunction();
+ public RangeQuery<V> getRangeQuery(DistanceQuery<V> distanceQuery, Object... hints) {
+ DistanceFunction<? super V> df = distanceQuery.getDistanceFunction();
if(df instanceof LPNormDistanceFunction) {
double p = ((LPNormDistanceFunction) df).getP();
- DistanceQuery<V, ?> ddq = (DistanceQuery<V, ?>) distanceQuery;
- RangeQuery<V, ?> dq = new VAFileRangeQuery((DistanceQuery<V, DoubleDistance>) ddq, p);
- return (RangeQuery<V, D>) dq;
+ return new VAFileRangeQuery(distanceQuery, p);
}
// Not supported.
return null;
@@ -283,7 +275,7 @@ public class VAFile<V extends NumberVector<?>> extends AbstractRefiningIndex<V>
*
* @author Erich Schubert
*/
- public class VAFileRangeQuery extends AbstractRefiningIndex<V>.AbstractRangeQuery<DoubleDistance> {
+ public class VAFileRangeQuery extends AbstractRefiningIndex<V>.AbstractRangeQuery {
/**
* LP Norm p parameter.
*/
@@ -296,14 +288,13 @@ public class VAFile<V extends NumberVector<?>> extends AbstractRefiningIndex<V>
* @param p LP norm p
*/
- public VAFileRangeQuery(DistanceQuery<V, DoubleDistance> distanceQuery, double p) {
+ public VAFileRangeQuery(DistanceQuery<V> distanceQuery, double p) {
super(distanceQuery);
this.p = p;
}
@Override
- public DoubleDistanceDBIDPairList getRangeForObject(V query, DoubleDistance range) {
- final double eps = range.doubleValue();
+ public DoubleDBIDList getRangeForObject(V query, double eps) {
// generate query approximation and lookup table
VectorApproximation queryApprox = calculateApproximation(null, query);
@@ -313,7 +304,7 @@ public class VAFile<V extends NumberVector<?>> extends AbstractRefiningIndex<V>
// Count a VA file scan
scans += 1;
- DoubleDistanceDBIDPairList result = new DoubleDistanceDBIDPairList();
+ ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
// Approximation step
for(int i = 0; i < vectorApprox.size(); i++) {
VectorApproximation va = vectorApprox.get(i);
@@ -327,7 +318,7 @@ public class VAFile<V extends NumberVector<?>> extends AbstractRefiningIndex<V>
// interested in the DBID only! But this needs an API change.
// refine the next element
- final double dist = refine(va.id, query).doubleValue();
+ final double dist = refine(va.id, query);
if(dist <= eps) {
result.add(dist, va.id);
}
@@ -342,7 +333,7 @@ public class VAFile<V extends NumberVector<?>> extends AbstractRefiningIndex<V>
*
* @author Erich Schubert
*/
- public class VAFileKNNQuery extends AbstractRefiningIndex<V>.AbstractKNNQuery<DoubleDistance> {
+ public class VAFileKNNQuery extends AbstractRefiningIndex<V>.AbstractKNNQuery {
/**
* LP Norm p parameter.
*/
@@ -354,13 +345,13 @@ public class VAFile<V extends NumberVector<?>> extends AbstractRefiningIndex<V>
* @param distanceQuery Distance query object
* @param p LP norm p
*/
- public VAFileKNNQuery(DistanceQuery<V, DoubleDistance> distanceQuery, double p) {
+ public VAFileKNNQuery(DistanceQuery<V> distanceQuery, double p) {
super(distanceQuery);
this.p = p;
}
@Override
- public DoubleDistanceKNNList getKNNForObject(V query, int k) {
+ public KNNList getKNNForObject(V query, int k) {
// generate query approximation and lookup table
VectorApproximation queryApprox = calculateApproximation(null, query);
@@ -371,7 +362,7 @@ public class VAFile<V extends NumberVector<?>> extends AbstractRefiningIndex<V>
DoubleMaxHeap minMaxHeap = new DoubleMaxHeap(k + 1);
double minMaxDist = Double.POSITIVE_INFINITY;
// Candidates with minDist <= kth maxDist
- ArrayList<DoubleObjPair<DBID>> candidates = new ArrayList<>(vectorApprox.size());
+ ModifiableDoubleDBIDList candidates = DBIDUtil.newDistanceDBIDList(vectorApprox.size());
// Count a VA file scan
scans += 1;
@@ -386,7 +377,7 @@ public class VAFile<V extends NumberVector<?>> extends AbstractRefiningIndex<V>
if(minDist > minMaxDist) {
continue;
}
- candidates.add(new DoubleObjPair<>(minDist, va.id));
+ candidates.add(minDist, va.id);
// Update candidate pruning heap
minMaxHeap.add(maxDist, k);
@@ -395,25 +386,25 @@ public class VAFile<V extends NumberVector<?>> extends AbstractRefiningIndex<V>
}
}
// sort candidates by lower bound (minDist)
- Collections.sort(candidates);
+ candidates.sort();
// refinement step
- DoubleDistanceKNNHeap result = DBIDUtil.newDoubleDistanceHeap(k);
+ KNNHeap result = DBIDUtil.newHeap(k);
// log.fine("candidates size " + candidates.size());
// retrieve accurate distances
- for(DoubleObjPair<DBID> va : candidates) {
+ for(DoubleDBIDListIter iter = candidates.iter(); iter.valid(); iter.advance()) {
// Stop when we are sure to have all elements
if(result.size() >= k) {
- double kDist = result.doubleKNNDistance();
- if(va.first > kDist) {
+ double kDist = result.getKNNDistance();
+ if(iter.doubleValue() > kDist) {
break;
}
}
// refine the next element
- final double dist = refine(va.second, query).doubleValue();
- result.insert(dist, va.second);
+ final double dist = refine(iter, query);
+ result.insert(dist, iter);
}
if(LOG.isDebuggingFinest()) {
LOG.finest("query = (" + query + ")");
@@ -434,7 +425,7 @@ public class VAFile<V extends NumberVector<?>> extends AbstractRefiningIndex<V>
*
* @param <V> Vector type
*/
- public static class Factory<V extends NumberVector<?>> implements IndexFactory<V, VAFile<V>> {
+ public static class Factory<V extends NumberVector> implements IndexFactory<V, VAFile<V>> {
/**
* Number of partitions to use in each dimension.
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/vafile/VALPNormDistance.java b/src/de/lmu/ifi/dbs/elki/index/vafile/VALPNormDistance.java
index d0b4a8e5..92ef5097 100644
--- a/src/de/lmu/ifi/dbs/elki/index/vafile/VALPNormDistance.java
+++ b/src/de/lmu/ifi/dbs/elki/index/vafile/VALPNormDistance.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.vafile;
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
@@ -54,7 +54,7 @@ public class VALPNormDistance {
* @param query Query vector
* @param queryApprox Query approximation
*/
- public VALPNormDistance(double p, double[][] splitPositions, NumberVector<?> query, VectorApproximation queryApprox) {
+ public VALPNormDistance(double p, double[][] splitPositions, NumberVector query, VectorApproximation queryApprox) {
super();
this.onebyp = 1.0 / p;
this.queryApprox = queryApprox;
@@ -155,7 +155,7 @@ public class VALPNormDistance {
* @param query Query vector
* @param p p
*/
- private void initializeLookupTable(double[][] splitPositions, NumberVector<?> query, double p) {
+ private void initializeLookupTable(double[][] splitPositions, NumberVector query, double p) {
final int dimensions = splitPositions.length;
final int bordercount = splitPositions[0].length;
lookup = new double[dimensions][bordercount];
diff --git a/src/de/lmu/ifi/dbs/elki/index/vafile/VectorApproximation.java b/src/de/lmu/ifi/dbs/elki/index/vafile/VectorApproximation.java
index f679cf16..464eee11 100644
--- a/src/de/lmu/ifi/dbs/elki/index/vafile/VectorApproximation.java
+++ b/src/de/lmu/ifi/dbs/elki/index/vafile/VectorApproximation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.vafile;
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
@@ -26,7 +26,7 @@ package de.lmu.ifi.dbs.elki.index.vafile;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
/**
* Object in a VA approximation.
diff --git a/src/de/lmu/ifi/dbs/elki/index/vafile/package-info.java b/src/de/lmu/ifi/dbs/elki/index/vafile/package-info.java
index 10aae35c..362d0b79 100644
--- a/src/de/lmu/ifi/dbs/elki/index/vafile/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/vafile/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/logging/CLISmartHandler.java b/src/de/lmu/ifi/dbs/elki/logging/CLISmartHandler.java
index 36ed3d64..81d6f96d 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/CLISmartHandler.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/CLISmartHandler.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging;
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/logging/ELKILogRecord.java b/src/de/lmu/ifi/dbs/elki/logging/ELKILogRecord.java
index 53540ec2..f18dceae 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/ELKILogRecord.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/ELKILogRecord.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging;
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/logging/ErrorFormatter.java b/src/de/lmu/ifi/dbs/elki/logging/ErrorFormatter.java
index b4530c25..8888bdd1 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/ErrorFormatter.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/ErrorFormatter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging;
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/logging/Logging.java b/src/de/lmu/ifi/dbs/elki/logging/Logging.java
index b9cbc16d..99b6152b 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/Logging.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/Logging.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging;
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,12 @@ import java.util.HashMap;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
+import de.lmu.ifi.dbs.elki.logging.progress.AbstractProgress;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.logging.progress.IndefiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.Progress;
import de.lmu.ifi.dbs.elki.logging.progress.ProgressLogRecord;
+import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
import de.lmu.ifi.dbs.elki.logging.statistics.Counter;
import de.lmu.ifi.dbs.elki.logging.statistics.Duration;
import de.lmu.ifi.dbs.elki.logging.statistics.MillisTimeDuration;
@@ -111,6 +115,19 @@ public class Logging {
public Level(String name, int value) {
super(name, value);
}
+
+ /**
+ * Parse a logging level.
+ *
+ * @param levelName Name of level to parse.
+ * @return {@link java.util.logging.Level} level
+ */
+ public static java.util.logging.Level parse(String levelName) {
+ // While this is a pass-through to the parent class,
+ // it ensures our own level have been added.
+ // Otherwise, levels such as "STATISTICS" might not work!
+ return java.util.logging.Level.parse(levelName);
+ }
}
/**
@@ -140,7 +157,7 @@ public class Logging {
*/
public synchronized static Logging getLogger(final String name) {
Logging logger = loggers.get(name);
- if (logger == null) {
+ if(logger == null) {
logger = new Logging(Logger.getLogger(name));
loggers.put(name, logger);
}
@@ -607,6 +624,67 @@ public class Logging {
}
/**
+ * Increment a progress (unless {@code null}).
+ *
+ * @param prog Progress to increment, may be {@code null}.
+ */
+ public void incrementProcessed(AbstractProgress prog) {
+ if(prog != null) {
+ prog.incrementProcessed(this);
+ }
+ }
+
+ /**
+ * Increment a progress (unless {@code null}).
+ *
+ * @param prog Progress to complete, may be {@code null}.
+ */
+ public void ensureCompleted(FiniteProgress prog) {
+ if(prog != null) {
+ prog.ensureCompleted(this);
+ }
+ }
+
+ /**
+ * Begin a new algorithm step (unless {@code null}).
+ *
+ * <b>Important:</b> Do not use this method when the parameter are not static.
+ * In these cases, check whether logging is enabled first, to avoid computing
+ * method parameters!
+ *
+ * @param prog Progress to increment, may be {@code null}.
+ * @param step Step number
+ * @param title Step title
+ */
+ public void beginStep(StepProgress prog, int step, String title) {
+ if(prog != null) {
+ prog.beginStep(step, title, this);
+ }
+ }
+
+ /**
+ * Finish a progress (unless {@code null}).
+ *
+ * @param prog Progress to complete, may be {@code null}.
+ */
+ public void setCompleted(StepProgress prog) {
+ if(prog != null) {
+ prog.setCompleted(this);
+ }
+ }
+
+ /**
+ * Finish a progress (unless {@code null}).
+ *
+ * @param prog Progress to complete, may be {@code null}.
+ */
+ public void setCompleted(IndefiniteProgress prog) {
+ if(prog != null) {
+ prog.setCompleted(this);
+ }
+ }
+
+ /**
* Log a statistics object.
*
* @param stats Statistics object to report.
diff --git a/src/de/lmu/ifi/dbs/elki/logging/LoggingConfiguration.java b/src/de/lmu/ifi/dbs/elki/logging/LoggingConfiguration.java
index 1c609b80..dfe5df9a 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/LoggingConfiguration.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/LoggingConfiguration.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging;
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/logging/LoggingUtil.java b/src/de/lmu/ifi/dbs/elki/logging/LoggingUtil.java
index ce62f419..a7980532 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/LoggingUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/LoggingUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging;
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/logging/MessageFormatter.java b/src/de/lmu/ifi/dbs/elki/logging/MessageFormatter.java
index 6df68224..7ec0320d 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/MessageFormatter.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/MessageFormatter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging;
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
@@ -36,8 +36,7 @@ import de.lmu.ifi.dbs.elki.logging.progress.ProgressLogRecord;
*/
public class MessageFormatter extends Formatter {
/**
- * Provides a message formatter to simply retrieve the message of an
- * LogRecord.
+ * Constructor.
*/
public MessageFormatter() {
super();
diff --git a/src/de/lmu/ifi/dbs/elki/logging/OutputStreamLogger.java b/src/de/lmu/ifi/dbs/elki/logging/OutputStreamLogger.java
index 7c618ec1..9dc26247 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/OutputStreamLogger.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/OutputStreamLogger.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging;
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/logging/package-info.java b/src/de/lmu/ifi/dbs/elki/logging/package-info.java
index 8e20cb09..8c9547f6 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/package-info.java
@@ -56,7 +56,7 @@ if (verbose) {
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/logging/progress/AbstractProgress.java b/src/de/lmu/ifi/dbs/elki/logging/progress/AbstractProgress.java
index ce97b84c..18612c87 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/progress/AbstractProgress.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/progress/AbstractProgress.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.progress;
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
@@ -75,7 +75,7 @@ public abstract class AbstractProgress implements Progress {
* @param processed the number of items already processed at a time being
* @throws IllegalArgumentException if an invalid value was passed.
*/
- public void setProcessed(int processed) throws IllegalArgumentException {
+ protected void setProcessed(int processed) throws IllegalArgumentException {
this.processed.set(processed);
}
@@ -119,16 +119,7 @@ public abstract class AbstractProgress implements Progress {
*/
@Override
public String toString() {
- StringBuilder message = new StringBuilder();
- appendToBuffer(message);
- return message.toString();
- }
-
- /**
- * Increment the processed counter.
- */
- public void incrementProcessed() {
- this.processed.incrementAndGet();
+ return appendToBuffer(new StringBuilder()).toString();
}
/**
@@ -137,7 +128,7 @@ public abstract class AbstractProgress implements Progress {
* @param logger Logger to report to.
*/
public void incrementProcessed(Logging logger) {
- incrementProcessed();
+ this.processed.incrementAndGet();
if(testLoggingRate()) {
logger.progress(this);
}
diff --git a/src/de/lmu/ifi/dbs/elki/logging/progress/FiniteProgress.java b/src/de/lmu/ifi/dbs/elki/logging/progress/FiniteProgress.java
index 83419ef4..c9cae77f 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/progress/FiniteProgress.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/progress/FiniteProgress.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.progress;
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
@@ -47,13 +47,12 @@ public class FiniteProgress extends AbstractProgress {
private final int totalLength;
/**
- * A progress object for a given overall number of items to process.
+ * Constructor.
*
* @param task the name of the task
* @param total the overall number of items to process
*/
- @Deprecated
- public FiniteProgress(String task, int total) {
+ protected FiniteProgress(String task, int total) {
super(task);
this.total = total;
this.totalLength = Integer.toString(total).length();
@@ -81,7 +80,7 @@ public class FiniteProgress extends AbstractProgress {
* the overall number of items to process
*/
@Override
- public void setProcessed(int processed) throws IllegalArgumentException {
+ protected void setProcessed(int processed) throws IllegalArgumentException {
if (processed > total) {
throw new IllegalArgumentException(processed + " exceeds total: " + total);
}
diff --git a/src/de/lmu/ifi/dbs/elki/logging/progress/IndefiniteProgress.java b/src/de/lmu/ifi/dbs/elki/logging/progress/IndefiniteProgress.java
index 673ceea7..bd00a328 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/progress/IndefiniteProgress.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/progress/IndefiniteProgress.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.progress;
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
@@ -37,16 +37,6 @@ public class IndefiniteProgress extends AbstractProgress {
private boolean completed = false;
/**
- * Constructor.
- *
- * @param task Task name.
- */
- @Deprecated
- public IndefiniteProgress(String task) {
- super(task);
- }
-
- /**
* Constructor with logging.
*
* @param task Task name.
@@ -79,14 +69,6 @@ public class IndefiniteProgress extends AbstractProgress {
}
/**
- * Set the completion flag.
- */
- @Deprecated
- public void setCompleted() {
- this.completed = true;
- }
-
- /**
* Set the completion flag and log it
*
* @param logger Logger to report to.
diff --git a/src/de/lmu/ifi/dbs/elki/logging/progress/MutableProgress.java b/src/de/lmu/ifi/dbs/elki/logging/progress/MutableProgress.java
index a89d7b43..8b653592 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/progress/MutableProgress.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/progress/MutableProgress.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.progress;
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/logging/progress/Progress.java b/src/de/lmu/ifi/dbs/elki/logging/progress/Progress.java
index bb2151ba..a1efc65b 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/progress/Progress.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/progress/Progress.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.progress;
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/logging/progress/ProgressLogRecord.java b/src/de/lmu/ifi/dbs/elki/logging/progress/ProgressLogRecord.java
index 8512ba9f..348b39f6 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/progress/ProgressLogRecord.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/progress/ProgressLogRecord.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.progress;
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/logging/progress/ProgressTracker.java b/src/de/lmu/ifi/dbs/elki/logging/progress/ProgressTracker.java
index c44fd1fd..dabb279e 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/progress/ProgressTracker.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/progress/ProgressTracker.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.progress;
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/logging/progress/StepProgress.java b/src/de/lmu/ifi/dbs/elki/logging/progress/StepProgress.java
index ee1225b6..26a5aaf4 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/progress/StepProgress.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/progress/StepProgress.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.progress;
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
@@ -42,7 +42,6 @@ public class StepProgress extends FiniteProgress {
*
* @param total Total number of steps.
*/
- @SuppressWarnings("deprecation")
public StepProgress(int total) {
super("Step", total);
}
@@ -54,7 +53,6 @@ public class StepProgress extends FiniteProgress {
* @param task Task title
* @param total Total number of steps.
*/
- @SuppressWarnings("deprecation")
public StepProgress(String task, int total) {
super(task, total);
}
@@ -75,18 +73,6 @@ public class StepProgress extends FiniteProgress {
}
/**
- * Do a new step.
- *
- * @param step Step number
- * @param stepTitle Step title
- */
- @Deprecated
- public void beginStep(int step, String stepTitle) {
- setProcessed(step - 1);
- this.stepTitle = stepTitle;
- }
-
- /**
* Do a new step and log it
*
* @param step Step number
@@ -100,14 +86,6 @@ public class StepProgress extends FiniteProgress {
}
/**
- * Mark the progress as completed.
- */
- @Deprecated
- public void setCompleted() {
- setProcessed(getTotal());
- }
-
- /**
* Mark the progress as completed and log it.
*
* @param logger Logger to report to.
diff --git a/src/de/lmu/ifi/dbs/elki/logging/progress/package-info.java b/src/de/lmu/ifi/dbs/elki/logging/progress/package-info.java
index 61c53d8d..ab1a44c9 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/progress/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/progress/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/logging/statistics/AbstractStatistic.java b/src/de/lmu/ifi/dbs/elki/logging/statistics/AbstractStatistic.java
index 8f0b7939..a88056fe 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/statistics/AbstractStatistic.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/statistics/AbstractStatistic.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.statistics;
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/logging/statistics/AtomicLongCounter.java b/src/de/lmu/ifi/dbs/elki/logging/statistics/AtomicLongCounter.java
index e200d93e..be898904 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/statistics/AtomicLongCounter.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/statistics/AtomicLongCounter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.statistics;
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/logging/statistics/Counter.java b/src/de/lmu/ifi/dbs/elki/logging/statistics/Counter.java
index 0a39f1bd..893ff120 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/statistics/Counter.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/statistics/Counter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.statistics;
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/logging/statistics/DoubleStatistic.java b/src/de/lmu/ifi/dbs/elki/logging/statistics/DoubleStatistic.java
index 7754ccf1..25383c12 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/statistics/DoubleStatistic.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/statistics/DoubleStatistic.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.statistics;
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,6 @@ package de.lmu.ifi.dbs.elki.logging.statistics;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-
/**
* Trivial double-valued statistic.
*
@@ -67,6 +65,6 @@ public class DoubleStatistic extends AbstractStatistic {
@Override
public String formatValue() {
- return FormatUtil.NF.format(value);
+ return Double.toString(value);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/logging/statistics/Duration.java b/src/de/lmu/ifi/dbs/elki/logging/statistics/Duration.java
index 24799408..279cd686 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/statistics/Duration.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/statistics/Duration.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.statistics;
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,12 +34,12 @@ public interface Duration extends Statistic {
/**
* Start the timer.
*/
- void begin();
+ Duration begin();
/**
* Finish the timer.
*/
- void end();
+ Duration end();
/**
* Get the begin of the interval.
diff --git a/src/de/lmu/ifi/dbs/elki/logging/statistics/LongStatistic.java b/src/de/lmu/ifi/dbs/elki/logging/statistics/LongStatistic.java
index 5ac805e8..15ce1ec0 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/statistics/LongStatistic.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/statistics/LongStatistic.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.statistics;
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/logging/statistics/MillisTimeDuration.java b/src/de/lmu/ifi/dbs/elki/logging/statistics/MillisTimeDuration.java
index 9f2cfd64..11e30724 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/statistics/MillisTimeDuration.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/statistics/MillisTimeDuration.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.statistics;
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
@@ -44,13 +44,15 @@ public class MillisTimeDuration extends AbstractStatistic implements Duration {
}
@Override
- public void begin() {
+ public MillisTimeDuration begin() {
begin = System.currentTimeMillis();
+ return this;
}
@Override
- public void end() {
+ public MillisTimeDuration end() {
end = System.currentTimeMillis();
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/logging/statistics/NanoDuration.java b/src/de/lmu/ifi/dbs/elki/logging/statistics/NanoDuration.java
index 77acbbdb..07c074f0 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/statistics/NanoDuration.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/statistics/NanoDuration.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.statistics;
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
@@ -44,13 +44,15 @@ public class NanoDuration extends AbstractStatistic implements Duration {
}
@Override
- public void begin() {
+ public NanoDuration begin() {
begin = System.nanoTime();
+ return this;
}
@Override
- public void end() {
+ public NanoDuration end() {
end = System.nanoTime();
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/logging/statistics/Statistic.java b/src/de/lmu/ifi/dbs/elki/logging/statistics/Statistic.java
index 0d1a191a..de7219c5 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/statistics/Statistic.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/statistics/Statistic.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.statistics;
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/logging/statistics/StringStatistic.java b/src/de/lmu/ifi/dbs/elki/logging/statistics/StringStatistic.java
index 2b7faed3..b8dff132 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/statistics/StringStatistic.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/statistics/StringStatistic.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.statistics;
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/logging/statistics/UnsynchronizedLongCounter.java b/src/de/lmu/ifi/dbs/elki/logging/statistics/UnsynchronizedLongCounter.java
index 6068b652..0942592f 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/statistics/UnsynchronizedLongCounter.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/statistics/UnsynchronizedLongCounter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.logging.statistics;
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/logging/statistics/package-info.java b/src/de/lmu/ifi/dbs/elki/logging/statistics/package-info.java
index ef9f5d98..1f664391 100644
--- a/src/de/lmu/ifi/dbs/elki/logging/statistics/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/logging/statistics/package-info.java
@@ -3,7 +3,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/math/DoubleMinMax.java b/src/de/lmu/ifi/dbs/elki/math/DoubleMinMax.java
index 1dfdc75d..18ff8979 100644
--- a/src/de/lmu/ifi/dbs/elki/math/DoubleMinMax.java
+++ b/src/de/lmu/ifi/dbs/elki/math/DoubleMinMax.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math;
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,8 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleDoublePair;
* Class to find the minimum and maximum double values in data.
*
* @author Erich Schubert
+ *
+ * @apiviz.exclude DoubleMinMaxProcessor
*/
public class DoubleMinMax extends DoubleDoublePair {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/math/IntegerMinMax.java b/src/de/lmu/ifi/dbs/elki/math/IntegerMinMax.java
index 5804f057..ff292e45 100644
--- a/src/de/lmu/ifi/dbs/elki/math/IntegerMinMax.java
+++ b/src/de/lmu/ifi/dbs/elki/math/IntegerMinMax.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math;
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/math/MathUtil.java b/src/de/lmu/ifi/dbs/elki/math/MathUtil.java
index 9a7d4770..16f2d096 100644
--- a/src/de/lmu/ifi/dbs/elki/math/MathUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/math/MathUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math;
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
@@ -106,6 +106,11 @@ public final class MathUtil {
public static final double ONE_BY_SQRTTWOPI = 1. / SQRTTWOPI;
/**
+ * 1. / log(2)
+ */
+ public static final double ONE_BY_LOG2 = 1. / Math.log(2.);
+
+ /**
* Logarithm of 2 to the basis e, for logarithm conversion.
*/
public static final double LOG2 = Math.log(2.);
@@ -131,6 +136,11 @@ public final class MathUtil {
public static final double LOGPIHALF = LOGPI / 2.;
/**
+ * Math.log(2*Math.PI).
+ */
+ public static final double LOGTWOPI = Math.log(TWOPI);
+
+ /**
* Math.log(Math.sqrt(2*Math.PI)).
*/
public static final double LOGSQRTTWOPI = Math.log(SQRTTWOPI);
@@ -158,6 +168,16 @@ public final class MathUtil {
}
/**
+ * Compute the base 2 logarithm.
+ *
+ * @param x X
+ * @return Logarithm base 2.
+ */
+ public static double log2(double x) {
+ return Math.log(x) * ONE_BY_LOG2;
+ }
+
+ /**
* Computes the square root of the sum of the squared arguments without under
* or overflow.
*
@@ -169,19 +189,21 @@ public final class MathUtil {
* @return {@code sqrt(a<sup>2</sup> + b<sup>2</sup>)}
*/
public static double fastHypot(double a, double b) {
- if (a < 0) {
+ if(a < 0) {
a = -a;
}
- if (b < 0) {
+ if(b < 0) {
b = -b;
}
- if (a > b) {
+ if(a > b) {
final double r = b / a;
return a * Math.sqrt(1 + r * r);
- } else if (b != 0) {
+ }
+ else if(b != 0) {
final double r = a / b;
return b * Math.sqrt(1 + r * r);
- } else {
+ }
+ else {
return 0.0;
}
}
@@ -199,17 +221,17 @@ public final class MathUtil {
* @return {@code sqrt(a<sup>2</sup> + b<sup>2</sup> + c<sup>2</sup>)}
*/
public static double fastHypot3(double a, double b, double c) {
- if (a < 0) {
+ if(a < 0) {
a = -a;
}
- if (b < 0) {
+ if(b < 0) {
b = -b;
}
- if (c < 0) {
+ if(c < 0) {
c = -c;
}
double m = (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c);
- if (m <= 0) {
+ if(m <= 0) {
return 0.0;
}
a = a / m;
@@ -227,7 +249,7 @@ public final class MathUtil {
*/
public static double mahalanobisDistance(Matrix weightMatrix, Vector o1_minus_o2) {
double sqrDist = o1_minus_o2.transposeTimesTimes(weightMatrix, o1_minus_o2);
- if (sqrDist < 0 && Math.abs(sqrDist) < 0.000000001) {
+ if(sqrDist < 0 && Math.abs(sqrDist) < 0.000000001) {
sqrDist = Math.abs(sqrDist);
}
return Math.sqrt(sqrDist);
@@ -242,97 +264,196 @@ public final class MathUtil {
*/
public static double mahalanobisDistance(double[][] weightMatrix, double[] o1_minus_o2) {
double sqrDist = VMath.transposeTimesTimes(o1_minus_o2, weightMatrix, o1_minus_o2);
- if (sqrDist < 0 && Math.abs(sqrDist) < 0.000000001) {
+ if(sqrDist < 0 && Math.abs(sqrDist) < 0.000000001) {
sqrDist = Math.abs(sqrDist);
}
return Math.sqrt(sqrDist);
}
/**
- * <p>
- * Provides the Pearson product-moment correlation coefficient for two
- * FeatureVectors.
- * </p>
+ * Compute the Mahalanobis distance using the given weight matrix.
*
- * @param x first FeatureVector
- * @param y second FeatureVector
+ * @param weightMatrix Weight Matrix
+ * @param o1 First vector
+ * @param o2 Center vector
+ * @return Mahalanobis distance
+ */
+ public static double mahalanobisDistance(Matrix weightMatrix, Vector o1, Vector o2) {
+ double sqrDist = VMath.mahalanobisDistance(weightMatrix.getArrayRef(), o1.getArrayRef(), o2.getArrayRef());
+ if(sqrDist < 0 && Math.abs(sqrDist) < 0.000000001) {
+ sqrDist = Math.abs(sqrDist);
+ }
+ return Math.sqrt(sqrDist);
+ }
+
+ /**
+ * Compute the Mahalanobis distance using the given weight matrix.
+ *
+ * @param weightMatrix Weight Matrix
+ * @param o1 First vector
+ * @param o2 Center vector
+ * @return Mahalanobis distance
+ */
+ public static double mahalanobisDistance(double[][] weightMatrix, double[] o1, double[] o2) {
+ double sqrDist = VMath.mahalanobisDistance(weightMatrix, o1, o2);
+ if(sqrDist < 0 && Math.abs(sqrDist) < 0.000000001) {
+ sqrDist = Math.abs(sqrDist);
+ }
+ return Math.sqrt(sqrDist);
+ }
+
+ /**
+ * Compute the Pearson product-moment correlation coefficient for two
+ * NumberVectors.
+ *
+ * @param x first NumberVector
+ * @param y second NumberVector
* @return the Pearson product-moment correlation coefficient for x and y
*/
- public static double pearsonCorrelationCoefficient(NumberVector<?> x, NumberVector<?> y) {
+ public static double pearsonCorrelationCoefficient(NumberVector x, NumberVector y) {
final int xdim = x.getDimensionality();
final int ydim = y.getDimensionality();
- if (xdim != ydim) {
- throw new IllegalArgumentException("Invalid arguments: feature vectors differ in dimensionality.");
+ if(xdim != ydim) {
+ throw new IllegalArgumentException("Invalid arguments: number vectors differ in dimensionality.");
}
- if (xdim <= 0) {
- throw new IllegalArgumentException("Invalid arguments: dimensionality not positive.");
+ // Old code, using an instance:
+ // PearsonCorrelation pc = new PearsonCorrelation();
+ // for(int i = 0; i < xdim; ++i) {
+ // final double xv = x.doubleValue(i), yv = y.doubleValue(i);
+ // pc.put(xv, yv, 1.);
+ // }
+ // return pc.getCorrelation();
+
+ // Inlined computation of Pearson correlation, to avoid allocating objects!
+ // This is a numerically stabilized version, avoiding sum-of-squares.
+ double sumXX = 0., sumYY = 0., sumXY = 0.;
+ double meanX = x.doubleValue(0), meanY = y.doubleValue(0);
+ int i = 1;
+ while(i < xdim) {
+ final double xv = x.doubleValue(i), yv = y.doubleValue(i);
+ // Delta to previous mean
+ final double deltaX = xv - meanX;
+ final double deltaY = yv - meanY;
+ // Increment count first
+ ++i;
+ // Update means
+ meanX += deltaX / i;
+ meanY += deltaY / i;
+ // Delta to new mean
+ final double neltaX = xv - meanX;
+ final double neltaY = yv - meanY;
+ // Update
+ sumXX += deltaX * neltaX;
+ sumYY += deltaY * neltaY;
+ // should equal deltaY * neltaX!
+ sumXY += deltaX * neltaY;
}
- PearsonCorrelation pc = new PearsonCorrelation();
- for (int i = 0; i < xdim; i++) {
- pc.put(x.doubleValue(i), y.doubleValue(i), 1.0);
+ // One or both series were constant:
+ if(!(sumXX > 0. && sumYY > 0.)) {
+ return (sumXX == sumYY) ? 1. : 0.;
}
- return pc.getCorrelation();
+ return sumXY / Math.sqrt(sumXX * sumYY);
}
/**
- * <p>
- * Provides the Pearson product-moment correlation coefficient for two
- * FeatureVectors.
- * </p>
+ * Compute the Pearson product-moment correlation coefficient for two
+ * NumberVectors.
*
- * @param x first FeatureVector
- * @param y second FeatureVector
+ * @param x first NumberVector
+ * @param y second NumberVector
* @param weights Weights
* @return the Pearson product-moment correlation coefficient for x and y
*/
- public static double weightedPearsonCorrelationCoefficient(NumberVector<?> x, NumberVector<?> y, double[] weights) {
+ public static double weightedPearsonCorrelationCoefficient(NumberVector x, NumberVector y, double[] weights) {
final int xdim = x.getDimensionality();
final int ydim = y.getDimensionality();
- if (xdim != ydim) {
- throw new IllegalArgumentException("Invalid arguments: feature vectors differ in dimensionality.");
+ if(xdim != ydim) {
+ throw new IllegalArgumentException("Invalid arguments: number vectors differ in dimensionality.");
}
- if (xdim != weights.length) {
+ if(xdim != weights.length) {
throw new IllegalArgumentException("Dimensionality doesn't agree to weights.");
}
- PearsonCorrelation pc = new PearsonCorrelation();
- for (int i = 0; i < xdim; i++) {
- pc.put(x.doubleValue(i), y.doubleValue(i), weights[i]);
+ // Inlined computation of Pearson correlation, to avoid allocating objects!
+ // This is a numerically stabilized version, avoiding sum-of-squares.
+ double sumXX = 0., sumYY = 0., sumXY = 0., sumWe = weights[0];
+ double meanX = x.doubleValue(0), meanY = y.doubleValue(0);
+ for(int i = 1; i < xdim; ++i) {
+ final double xv = x.doubleValue(i), yv = y.doubleValue(i), w = weights[i];
+ // Delta to previous mean
+ final double deltaX = xv - meanX;
+ final double deltaY = yv - meanY;
+ // Increment weight first
+ sumWe += w;
+ // Update means
+ meanX += deltaX * w / sumWe;
+ meanY += deltaY * w / sumWe;
+ // Delta to new mean
+ final double neltaX = xv - meanX;
+ final double neltaY = yv - meanY;
+ // Update
+ sumXX += w * deltaX * neltaX;
+ sumYY += w * deltaY * neltaY;
+ // should equal weight * deltaY * neltaX!
+ sumXY += w * deltaX * neltaY;
+ }
+ // One or both series were constant:
+ if(!(sumXX > 0. && sumYY > 0.)) {
+ return (sumXX == sumYY) ? 1. : 0.;
}
- return pc.getCorrelation();
+ return sumXY / Math.sqrt(sumXX * sumYY);
}
/**
- * <p>
- * Provides the Pearson product-moment correlation coefficient for two
+ * Compute the Pearson product-moment correlation coefficient for two
* FeatureVectors.
- * </p>
*
* @param x first FeatureVector
* @param y second FeatureVector
* @param weights Weights
* @return the Pearson product-moment correlation coefficient for x and y
*/
- public static double weightedPearsonCorrelationCoefficient(NumberVector<?> x, NumberVector<?> y, NumberVector<?> weights) {
+ public static double weightedPearsonCorrelationCoefficient(NumberVector x, NumberVector y, NumberVector weights) {
final int xdim = x.getDimensionality();
final int ydim = y.getDimensionality();
- if (xdim != ydim) {
+ if(xdim != ydim) {
throw new IllegalArgumentException("Invalid arguments: feature vectors differ in dimensionality.");
}
- if (xdim != weights.getDimensionality()) {
+ if(xdim != weights.getDimensionality()) {
throw new IllegalArgumentException("Dimensionality doesn't agree to weights.");
}
- PearsonCorrelation pc = new PearsonCorrelation();
- for (int i = 0; i < xdim; i++) {
- pc.put(x.doubleValue(i), y.doubleValue(i), weights.doubleValue(i));
+ // Inlined computation of Pearson correlation, to avoid allocating objects!
+ // This is a numerically stabilized version, avoiding sum-of-squares.
+ double sumXX = 0., sumYY = 0., sumXY = 0., sumWe = weights.doubleValue(0);
+ double meanX = x.doubleValue(0), meanY = y.doubleValue(0);
+ for(int i = 1; i < xdim; ++i) {
+ final double xv = x.doubleValue(i), yv = y.doubleValue(i), w = weights.doubleValue(i);
+ // Delta to previous mean
+ final double deltaX = xv - meanX;
+ final double deltaY = yv - meanY;
+ // Increment weight first
+ sumWe += w;
+ // Update means
+ meanX += deltaX * w / sumWe;
+ meanY += deltaY * w / sumWe;
+ // Delta to new mean
+ final double neltaX = xv - meanX;
+ final double neltaY = yv - meanY;
+ // Update
+ sumXX += w * deltaX * neltaX;
+ sumYY += w * deltaY * neltaY;
+ // should equal weight * deltaY * neltaX!
+ sumXY += w * deltaX * neltaY;
+ }
+ // One or both series were constant:
+ if(!(sumXX > 0. && sumYY > 0.)) {
+ return (sumXX == sumYY) ? 1. : 0.;
}
- return pc.getCorrelation();
+ return sumXY / Math.sqrt(sumXX * sumYY);
}
/**
- * <p>
- * Provides the Pearson product-moment correlation coefficient for two
+ * Compute the Pearson product-moment correlation coefficient for two
* FeatureVectors.
- * </p>
*
* @param x first FeatureVector
* @param y second FeatureVector
@@ -341,21 +462,43 @@ public final class MathUtil {
public static double pearsonCorrelationCoefficient(double[] x, double[] y) {
final int xdim = x.length;
final int ydim = y.length;
- if (xdim != ydim) {
- throw new IllegalArgumentException("Invalid arguments: feature vectors differ in dimensionality.");
+ if(xdim != ydim) {
+ throw new IllegalArgumentException("Invalid arguments: arrays differ in length.");
}
- PearsonCorrelation pc = new PearsonCorrelation();
- for (int i = 0; i < xdim; i++) {
- pc.put(x[i], y[i], 1.0);
+ // Inlined computation of Pearson correlation, to avoid allocating objects!
+ // This is a numerically stabilized version, avoiding sum-of-squares.
+ double sumXX = 0., sumYY = 0., sumXY = 0.;
+ double meanX = x[0], meanY = y[0];
+ int i = 1;
+ while(i < xdim) {
+ final double xv = x[i], yv = y[i];
+ // Delta to previous mean
+ final double deltaX = xv - meanX;
+ final double deltaY = yv - meanY;
+ // Increment count first
+ ++i;
+ // Update means
+ meanX += deltaX / i;
+ meanY += deltaY / i;
+ // Delta to new mean
+ final double neltaX = xv - meanX;
+ final double neltaY = yv - meanY;
+ // Update
+ sumXX += deltaX * neltaX;
+ sumYY += deltaY * neltaY;
+ // should equal deltaY * neltaX!
+ sumXY += deltaX * neltaY;
}
- return pc.getCorrelation();
+ // One or both series were constant:
+ if(!(sumXX > 0. && sumYY > 0.)) {
+ return (sumXX == sumYY) ? 1. : 0.;
+ }
+ return sumXY / Math.sqrt(sumXX * sumYY);
}
/**
- * <p>
- * Provides the Pearson product-moment correlation coefficient for two
+ * Compute the Pearson product-moment correlation coefficient for two
* FeatureVectors.
- * </p>
*
* @param x first FeatureVector
* @param y second FeatureVector
@@ -365,17 +508,40 @@ public final class MathUtil {
public static double weightedPearsonCorrelationCoefficient(double[] x, double[] y, double[] weights) {
final int xdim = x.length;
final int ydim = y.length;
- if (xdim != ydim) {
- throw new IllegalArgumentException("Invalid arguments: feature vectors differ in dimensionality.");
+ if(xdim != ydim) {
+ throw new IllegalArgumentException("Invalid arguments: arrays differ in length.");
}
- if (xdim != weights.length) {
+ if(xdim != weights.length) {
throw new IllegalArgumentException("Dimensionality doesn't agree to weights.");
}
- PearsonCorrelation pc = new PearsonCorrelation();
- for (int i = 0; i < xdim; i++) {
- pc.put(x[i], y[i], weights[i]);
+ // Inlined computation of Pearson correlation, to avoid allocating objects!
+ // This is a numerically stabilized version, avoiding sum-of-squares.
+ double sumXX = 0., sumYY = 0., sumXY = 0., sumWe = weights[0];
+ double meanX = x[0], meanY = y[0];
+ for(int i = 1; i < xdim; ++i) {
+ final double xv = x[i], yv = y[i], w = weights[i];
+ // Delta to previous mean
+ final double deltaX = xv - meanX;
+ final double deltaY = yv - meanY;
+ // Increment weight first
+ sumWe += w;
+ // Update means
+ meanX += deltaX * w / sumWe;
+ meanY += deltaY * w / sumWe;
+ // Delta to new mean
+ final double neltaX = xv - meanX;
+ final double neltaY = yv - meanY;
+ // Update
+ sumXX += w * deltaX * neltaX;
+ sumYY += w * deltaY * neltaY;
+ // should equal weight * deltaY * neltaX!
+ sumXY += w * deltaX * neltaY;
+ }
+ // One or both series were constant:
+ if(!(sumXX > 0. && sumYY > 0.)) {
+ return (sumXX == sumYY) ? 1. : 0.;
}
- return pc.getCorrelation();
+ return sumXY / Math.sqrt(sumXX * sumYY);
}
/**
@@ -390,10 +556,10 @@ public final class MathUtil {
* @return n * (n-1) * (n-2) * ... * 1
*/
public static BigInteger factorial(BigInteger n) {
- BigInteger nFac = BigInteger.valueOf(1);
- while (n.compareTo(BigInteger.valueOf(1)) > 0) {
+ BigInteger nFac = BigInteger.ONE;
+ while(n.compareTo(BigInteger.ONE) > 0) {
nFac = nFac.multiply(n);
- n = n.subtract(BigInteger.valueOf(1));
+ n = n.subtract(BigInteger.ONE);
}
return nFac;
}
@@ -407,7 +573,7 @@ public final class MathUtil {
*/
public static long factorial(int n) {
long nFac = 1;
- for (long i = n; i > 0; i--) {
+ for(long i = n; i > 0; i--) {
nFac *= i;
}
return nFac;
@@ -426,7 +592,7 @@ public final class MathUtil {
public static long binomialCoefficient(long n, long k) {
final long m = Math.max(k, n - k);
double temp = 1;
- for (long i = n, j = 1; i > m; i--, j++) {
+ for(long i = n, j = 1; i > m; i--, j++) {
temp = temp * i / j;
}
return (long) temp;
@@ -441,7 +607,7 @@ public final class MathUtil {
*/
public static double approximateFactorial(int n) {
double nFac = 1.0;
- for (int i = n; i > 0; i--) {
+ for(int i = n; i > 0; i--) {
nFac *= i;
}
return nFac;
@@ -458,7 +624,7 @@ public final class MathUtil {
public static double approximateBinomialCoefficient(int n, int k) {
final int m = Math.max(k, n - k);
long temp = 1;
- for (int i = n, j = 1; i > m; i--, j++) {
+ for(int i = n, j = 1; i > m; i--, j++) {
temp = temp * i / j;
}
return temp;
@@ -493,7 +659,7 @@ public final class MathUtil {
*/
public static double[] randomDoubleArray(int len, Random r) {
final double[] ret = new double[len];
- for (int i = 0; i < len; i++) {
+ for(int i = 0; i < len; i++) {
ret[i] = r.nextDouble();
}
return ret;
@@ -549,18 +715,18 @@ public final class MathUtil {
// v1.transposeTimes(v2) / (v1.euclideanLength() * v2.euclideanLength());
// We can just compute all three in parallel.
double s = 0, e1 = 0, e2 = 0;
- for (int k = 0; k < mindim; k++) {
+ for(int k = 0; k < mindim; k++) {
final double r1 = v1[k];
final double r2 = v2[k];
s += r1 * r2;
e1 += r1 * r1;
e2 += r2 * r2;
}
- for (int k = mindim; k < v1.length; k++) {
+ for(int k = mindim; k < v1.length; k++) {
final double r1 = v1[k];
e1 += r1 * r1;
}
- for (int k = mindim; k < v2.length; k++) {
+ for(int k = mindim; k < v2.length; k++) {
final double r2 = v2[k];
e2 += r2 * r2;
}
@@ -594,7 +760,7 @@ public final class MathUtil {
// v1'.transposeTimes(v2') / (v1'.euclideanLength()*v2'.euclideanLength());
// We can just compute all three in parallel.
double s = 0, e1 = 0, e2 = 0;
- for (int k = 0; k < mindim; k++) {
+ for(int k = 0; k < mindim; k++) {
final double ok = (k < o.length) ? o[k] : 0;
final double r1 = v1[k] - ok;
final double r2 = v2[k] - ok;
@@ -602,12 +768,12 @@ public final class MathUtil {
e1 += r1 * r1;
e2 += r2 * r2;
}
- for (int k = mindim; k < v1.length; k++) {
+ for(int k = mindim; k < v1.length; k++) {
final double ok = (k < o.length) ? o[k] : 0;
final double r1 = v1[k] - ok;
e1 += r1 * r1;
}
- for (int k = mindim; k < v2.length; k++) {
+ for(int k = mindim; k < v2.length; k++) {
final double ok = (k < o.length) ? o[k] : 0;
final double r2 = v2[k] - ok;
e2 += r2 * r2;
@@ -623,11 +789,7 @@ public final class MathUtil {
*/
public static double normAngle(double x) {
x %= TWOPI;
- if (x > 0) {
- return x;
- } else {
- return x + TWOPI;
- }
+ return (x > 0) ? x : x + TWOPI;
}
/**
@@ -639,15 +801,12 @@ public final class MathUtil {
*/
public static double sinToCos(double angle, double sin) {
// Numerics of the formula below aren't too good.
- if ((-1e-5 < sin && sin < 1e-5) || sin > 0.99999 || sin < -0.99999) {
+ if((-1e-5 < sin && sin < 1e-5) || sin > 0.99999 || sin < -0.99999) {
return Math.cos(angle);
}
angle = normAngle(angle);
- if (angle < HALFPI || angle > ONEHALFPI) {
- return Math.sqrt(1 - sin * sin);
- } else {
- return -Math.sqrt(1 - sin * sin);
- }
+ final double s = Math.sqrt(1 - sin * sin);
+ return (angle < HALFPI || angle > ONEHALFPI) ? s : -s;
}
/**
@@ -659,15 +818,12 @@ public final class MathUtil {
*/
public static double cosToSin(double angle, double cos) {
// Numerics of the formula below aren't too good.
- if ((-1e-5 < cos && cos < 1e-5) || cos > 0.99999 || cos < -0.99999) {
+ if((-1e-5 < cos && cos < 1e-5) || cos > 0.99999 || cos < -0.99999) {
return Math.sin(angle);
}
angle = normAngle(angle);
- if (angle < Math.PI) {
- return Math.sqrt(1 - cos * cos);
- } else {
- return -Math.sqrt(1 - cos * cos);
- }
+ final double s = Math.sqrt(1 - cos * cos);
+ return (angle < Math.PI) ? s : -s;
}
/**
@@ -754,48 +910,52 @@ public final class MathUtil {
* @return Double value
*/
public static double floatToDoubleUpper(float f) {
- if (Float.isNaN(f)) {
+ if(Float.isNaN(f)) {
return Double.NaN;
}
- if (Float.isInfinite(f)) {
- if (f > 0) {
+ if(Float.isInfinite(f)) {
+ if(f > 0) {
return Double.POSITIVE_INFINITY;
- } else {
+ }
+ else {
return Double.longBitsToDouble(0xc7efffffffffffffL);
}
}
long bits = Double.doubleToRawLongBits((double) f);
- if ((bits & 0x8000000000000000L) == 0) { // Positive
- if (bits == 0L) {
+ if((bits & 0x8000000000000000L) == 0) { // Positive
+ if(bits == 0L) {
return Double.longBitsToDouble(0x3690000000000000L);
}
- if (f == Float.MIN_VALUE) {
+ if(f == Float.MIN_VALUE) {
// bits += 0x7_ffff_ffff_ffffl;
return Double.longBitsToDouble(0x36a7ffffffffffffL);
}
- if (Float.MIN_NORMAL > f && f >= Double.MIN_NORMAL) {
+ if(Float.MIN_NORMAL > f && f >= Double.MIN_NORMAL) {
// The most tricky case:
// a denormalized float, but a normalized double
final long bits2 = Double.doubleToRawLongBits((double) Math.nextUp(f));
bits = (bits >>> 1) + (bits2 >>> 1) - 1L;
- } else {
+ }
+ else {
bits += 0xfffffffL; // 28 extra bits
}
return Double.longBitsToDouble(bits);
- } else {
- if (bits == 0x8000000000000000L) {
+ }
+ else {
+ if(bits == 0x8000000000000000L) {
return -0.0d;
}
- if (f == -Float.MIN_VALUE) {
+ if(f == -Float.MIN_VALUE) {
// bits -= 0xf_ffff_ffff_ffffl;
return Double.longBitsToDouble(0xb690000000000001L);
}
- if (-Float.MIN_NORMAL < f && f <= -Double.MIN_NORMAL) {
+ if(-Float.MIN_NORMAL < f && f <= -Double.MIN_NORMAL) {
// The most tricky case:
// a denormalized float, but a normalized double
final long bits2 = Double.doubleToRawLongBits((double) Math.nextUp(f));
bits = (bits >>> 1) + (bits2 >>> 1) + 1L;
- } else {
+ }
+ else {
bits -= 0xfffffffL; // 28 extra bits
}
return Double.longBitsToDouble(bits);
@@ -812,48 +972,52 @@ public final class MathUtil {
* @return Double value
*/
public static double floatToDoubleLower(float f) {
- if (Float.isNaN(f)) {
+ if(Float.isNaN(f)) {
return Double.NaN;
}
- if (Float.isInfinite(f)) {
- if (f < 0) {
+ if(Float.isInfinite(f)) {
+ if(f < 0) {
return Double.NEGATIVE_INFINITY;
- } else {
+ }
+ else {
return Double.longBitsToDouble(0x47efffffffffffffL);
}
}
long bits = Double.doubleToRawLongBits((double) f);
- if ((bits & 0x8000000000000000L) == 0) { // Positive
- if (bits == 0L) {
+ if((bits & 0x8000000000000000L) == 0) { // Positive
+ if(bits == 0L) {
return +0.0d;
}
- if (f == Float.MIN_VALUE) {
+ if(f == Float.MIN_VALUE) {
// bits -= 0xf_ffff_ffff_ffffl;
return Double.longBitsToDouble(0x3690000000000001L);
}
- if (Float.MIN_NORMAL > f /* && f >= Double.MIN_NORMAL */) {
+ if(Float.MIN_NORMAL > f /* && f >= Double.MIN_NORMAL */) {
// The most tricky case:
// a denormalized float, but a normalized double
final long bits2 = Double.doubleToRawLongBits((double) -Math.nextUp(-f));
bits = (bits >>> 1) + (bits2 >>> 1) + 1L; // + (0xfff_ffffL << 18);
- } else {
+ }
+ else {
bits -= 0xfffffffL; // 28 extra bits
}
return Double.longBitsToDouble(bits);
- } else {
- if (bits == 0x8000000000000000L) {
+ }
+ else {
+ if(bits == 0x8000000000000000L) {
return Double.longBitsToDouble(0xb690000000000000L);
}
- if (f == -Float.MIN_VALUE) {
+ if(f == -Float.MIN_VALUE) {
// bits += 0x7_ffff_ffff_ffffl;
return Double.longBitsToDouble(0xb6a7ffffffffffffL);
}
- if (-Float.MIN_NORMAL < f /* && f <= -Double.MIN_NORMAL */) {
+ if(-Float.MIN_NORMAL < f /* && f <= -Double.MIN_NORMAL */) {
// The most tricky case:
// a denormalized float, but a normalized double
final long bits2 = Double.doubleToRawLongBits((double) -Math.nextUp(-f));
bits = (bits >>> 1) + (bits2 >>> 1) - 1L;
- } else {
+ }
+ else {
bits += 0xfffffffL; // 28 extra bits
}
return Double.longBitsToDouble(bits);
@@ -878,12 +1042,12 @@ public final class MathUtil {
* @return {@code Math.pow(x, p)}
*/
public static double powi(double x, int p) {
- if (p < 0) { // Fallback for negative integers.
+ if(p < 0) { // Fallback for negative integers.
return Math.pow(x, p);
}
double ret = 1.;
- for (; p > 0; p >>= 1) {
- if ((p & 1) == 1) {
+ for(; p > 0; p >>= 1) {
+ if((p & 1) == 1) {
ret *= x;
}
x *= x;
@@ -900,16 +1064,39 @@ public final class MathUtil {
* @return {@code Math.pow(x, p)}
*/
public static int ipowi(int x, int p) {
- if (p < 0) { // Fallback for negative integers.
+ if(p < 0) { // Fallback for negative integers.
return (int) Math.pow(x, p);
}
int ret = 1;
- for (; p > 0; p >>= 1) {
- if ((p & 1) == 1) {
+ for(; p > 0; p >>= 1) {
+ if((p & 1) == 1) {
ret *= x;
}
x *= x;
}
return ret;
}
+
+ /**
+ * Empty integer array.
+ */
+ public static final int[] EMPTY_INTS = new int[0];
+
+ /**
+ * Generate an array of integers.
+ *
+ * @param start First integer
+ * @param end Last integer (exclusive!)
+ * @return Array of integers of length end-start
+ */
+ public static int[] sequence(int start, int end) {
+ if(start >= end) {
+ return EMPTY_INTS;
+ }
+ int[] ret = new int[end - start];
+ for(int j = 0; start < end; start++, j++) {
+ ret[j] = start;
+ }
+ return ret;
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/Mean.java b/src/de/lmu/ifi/dbs/elki/math/Mean.java
index 5e70938f..e6d89214 100644
--- a/src/de/lmu/ifi/dbs/elki/math/Mean.java
+++ b/src/de/lmu/ifi/dbs/elki/math/Mean.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math;
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/math/MeanVariance.java b/src/de/lmu/ifi/dbs/elki/math/MeanVariance.java
index b229d5d8..c9b8b15b 100644
--- a/src/de/lmu/ifi/dbs/elki/math/MeanVariance.java
+++ b/src/de/lmu/ifi/dbs/elki/math/MeanVariance.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math;
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/math/MeanVarianceMinMax.java b/src/de/lmu/ifi/dbs/elki/math/MeanVarianceMinMax.java
index 027a302d..22864c64 100644
--- a/src/de/lmu/ifi/dbs/elki/math/MeanVarianceMinMax.java
+++ b/src/de/lmu/ifi/dbs/elki/math/MeanVarianceMinMax.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math;
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/math/MinMax.java b/src/de/lmu/ifi/dbs/elki/math/MinMax.java
deleted file mode 100644
index d3ee45bd..00000000
--- a/src/de/lmu/ifi/dbs/elki/math/MinMax.java
+++ /dev/null
@@ -1,185 +0,0 @@
-package de.lmu.ifi.dbs.elki.math;
-
-/*
- 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.SortedSet;
-
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
-
-/**
- * Class to find the minimum and maximum double values in data.
- *
- * @author Erich Schubert
- *
- * Note: Unused, see {@link DoubleMinMax} specialization.
- *
- * @param <T> Data type
- */
-public class MinMax<T extends Comparable<? super T>> extends Pair<T, T> {
- /**
- * Constructor without starting values.
- *
- * The minimum will be initialized to {@code null}.
- *
- * The maximum will be initialized to {@code null}.
- */
- public MinMax() {
- super(null, null);
- }
-
- /**
- * Constructor with predefined minimum and maximum values.
- *
- * @param min Minimum value
- * @param max Maximum value
- */
- public MinMax(T min, T max) {
- super(min, max);
- }
-
- /**
- * Process a single value.
- *
- * If the new value is smaller than the current minimum, it will become the
- * new minimum.
- *
- * If the new value is larger than the current maximum, it will become the new
- * maximum.
- *
- * @param data New value
- */
- public void put(T data) {
- if(this.first == null || this.first.compareTo(data) > 0) {
- this.first = data;
- }
- if(this.second == null || this.second.compareTo(data) < 0) {
- this.second = data;
- }
- }
-
- /**
- * Process a whole array of values.
- *
- * If any of the values is smaller than the current minimum, it will become
- * the new minimum.
- *
- * If any of the values is larger than the current maximum, it will become the
- * new maximum.
- *
- * @param data Data to process
- */
- public void put(T[] data) {
- for(T value : data) {
- this.put(value);
- }
- }
-
- /**
- * Process a whole collection of values.
- *
- * If any of the values is smaller than the current minimum, it will become
- * the new minimum.
- *
- * If any of the values is larger than the current maximum, it will become the
- * new maximum.
- *
- * @param data Data to process
- */
- public void put(Iterable<T> data) {
- for(T value : data) {
- this.put(value);
- }
- }
-
- /**
- * Process a whole collection of values.
- *
- * If any of the values is smaller than the current minimum, it will become
- * the new minimum.
- *
- * If any of the values is larger than the current maximum, it will become the
- * new maximum.
- *
- * @param data Data to process
- */
- public void put(SortedSet<T> data) {
- if(!data.isEmpty()) {
- this.put(data.first());
- this.put(data.last());
- }
- }
-
- /**
- * Get the current minimum.
- *
- * @return current minimum.
- */
- public T getMin() {
- return this.getFirst();
- }
-
- /**
- * Get the current maximum.
- *
- * @return current maximum.
- */
- public T getMax() {
- return this.getSecond();
- }
-
- /**
- * Test if we have seen any data (and thus have a useful minimum and maximum).
- *
- * @return {@code true} iff min != null and max != null.
- */
- public boolean isValid() {
- return (this.getMin() != null) && (this.getMax() != null);
- }
-
- /**
- * Return minimum and maximum as array.
- *
- * @return Minimum, Maximum
- */
- public Object[] asArray() {
- return new Object[] { this.getMin(), this.getMax() };
- }
-
- /**
- * New array of MinMax objects for a given type.
- *
- * @param <N> Number type.
- * @param size Size.
- * @return Initialized array.
- */
- public static <N extends Comparable<N>> MinMax<N>[] newArray(int size) {
- Class<MinMax<N>> mmcls = ClassGenericsUtil.uglyCastIntoSubclass(MinMax.class);
- MinMax<N>[] mms = ClassGenericsUtil.newArrayOfNull(size, mmcls);
- for(int i = 0; i < size; i++) {
- mms[i] = new MinMax<>();
- }
- return mms;
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/PearsonCorrelation.java b/src/de/lmu/ifi/dbs/elki/math/PearsonCorrelation.java
index 4cd9c732..710ec0ae 100644
--- a/src/de/lmu/ifi/dbs/elki/math/PearsonCorrelation.java
+++ b/src/de/lmu/ifi/dbs/elki/math/PearsonCorrelation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math;
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,34 +34,19 @@ package de.lmu.ifi.dbs.elki.math;
*/
public class PearsonCorrelation {
/**
- * Sum for XX
+ * Aggregation for squared residuals - we are not using sum-of-squares!
*/
- private double sumXX = 0;
+ private double sumXX = 0., sumYY = 0., sumXY = 0.;
/**
- * Sum for YY
+ * Current mean for X and Y.
*/
- private double sumYY = 0;
+ private double meanX = 0., meanY = 0.;
/**
- * Sum for XY
+ * Weight sum.
*/
- private double sumXY = 0;
-
- /**
- * Current mean for X
- */
- private double meanX = 0;
-
- /**
- * Current mean for Y
- */
- private double meanY = 0;
-
- /**
- * Weight sum
- */
- private double sumWe = 0;
+ private double sumWe = 0.;
/**
* Constructor.
@@ -78,7 +63,7 @@ public class PearsonCorrelation {
* @param w Weight
*/
public void put(double x, double y, double w) {
- if(sumWe <= 0.0) {
+ if(sumWe <= 0.) {
meanX = x;
meanY = y;
sumWe = w;
@@ -109,22 +94,19 @@ public class PearsonCorrelation {
* @param y Value in Y
*/
public void put(double x, double y) {
- put(x, y, 1.0);
+ put(x, y, 1.);
}
/**
- * Get the pearson correlation value.
+ * Get the Pearson correlation value.
*
* @return Correlation value
*/
public double getCorrelation() {
- final double popSdX = getNaiveStddevX();
- final double popSdY = getNaiveStddevY();
- final double covXY = getNaiveCovariance();
- if(popSdX == 0 || popSdY == 0) {
- return 0;
+ if(!(sumXX > 0. && sumYY > 0.)) {
+ return (sumXX == sumYY) ? 1. : 0.;
}
- return covXY / (popSdX * popSdY);
+ return sumXY / Math.sqrt(sumXX * sumYY);
}
/**
@@ -144,7 +126,7 @@ public class PearsonCorrelation {
public double getMeanX() {
return meanX;
}
-
+
/**
* Return mean of Y
*
@@ -153,7 +135,7 @@ public class PearsonCorrelation {
public double getMeanY() {
return meanY;
}
-
+
/**
* Get the covariance of X and Y (not taking sampling into account)
*
@@ -169,8 +151,8 @@ public class PearsonCorrelation {
* @return Covariance
*/
public double getSampleCovariance() {
- assert (sumWe > 1);
- return sumXY / (sumWe - 1);
+ assert (sumWe > 1.);
+ return sumXY / (sumWe - 1.);
}
/**
@@ -190,8 +172,8 @@ public class PearsonCorrelation {
* @return sample variance
*/
public double getSampleVarianceX() {
- assert (sumWe > 1);
- return sumXX / (sumWe - 1);
+ assert (sumWe > 1.);
+ return sumXX / (sumWe - 1.);
}
/**
@@ -199,7 +181,7 @@ public class PearsonCorrelation {
*
* Note: usually, you should be using {@link #getSampleStddevX} instead!
*
- * @return stddev
+ * @return standard deviation
*/
public double getNaiveStddevX() {
return Math.sqrt(getNaiveVarianceX());
@@ -208,7 +190,7 @@ public class PearsonCorrelation {
/**
* Return standard deviation
*
- * @return stddev
+ * @return standard deviation
*/
public double getSampleStddevX() {
return Math.sqrt(getSampleVarianceX());
@@ -231,8 +213,8 @@ public class PearsonCorrelation {
* @return sample variance
*/
public double getSampleVarianceY() {
- assert (sumWe > 1);
- return sumYY / (sumWe - 1);
+ assert (sumWe > 1.);
+ return sumYY / (sumWe - 1.);
}
/**
@@ -259,11 +241,11 @@ public class PearsonCorrelation {
* Reset the value.
*/
public void reset() {
- sumXX = 0;
- sumXY = 0;
- sumYY = 0;
- meanX = 0;
- meanY = 0;
- sumWe = 0;
+ sumXX = 0.;
+ sumXY = 0.;
+ sumYY = 0.;
+ meanX = 0.;
+ meanY = 0.;
+ sumWe = 0.;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/Primes.java b/src/de/lmu/ifi/dbs/elki/math/Primes.java
index 5755df1a..71167c94 100644
--- a/src/de/lmu/ifi/dbs/elki/math/Primes.java
+++ b/src/de/lmu/ifi/dbs/elki/math/Primes.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math;
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/math/SinCosTable.java b/src/de/lmu/ifi/dbs/elki/math/SinCosTable.java
index 6cabb172..9d591651 100644
--- a/src/de/lmu/ifi/dbs/elki/math/SinCosTable.java
+++ b/src/de/lmu/ifi/dbs/elki/math/SinCosTable.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math;
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/math/StatisticalMoments.java b/src/de/lmu/ifi/dbs/elki/math/StatisticalMoments.java
index af42c2e5..76542a6e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/StatisticalMoments.java
+++ b/src/de/lmu/ifi/dbs/elki/math/StatisticalMoments.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math;
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/result/optics/package-info.java b/src/de/lmu/ifi/dbs/elki/math/analysis/package-info.java
index e74b3c7b..dc4ab3ee 100644
--- a/src/de/lmu/ifi/dbs/elki/result/optics/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/analysis/package-info.java
@@ -1,11 +1,11 @@
/**
- * <p>Result classes for OPTICS.</p>
- */
+<p>Analysis package</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
@@ -23,4 +23,4 @@ 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.result.optics; \ No newline at end of file
+package de.lmu.ifi.dbs.elki.math.analysis; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/CovarianceDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/CovarianceDimensionSimilarity.java
index 59380a74..1dbf03dd 100644
--- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/CovarianceDimensionSimilarity.java
+++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/CovarianceDimensionSimilarity.java
@@ -4,7 +4,7 @@ package 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
@@ -34,7 +34,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Erich Schubert
*/
-public class CovarianceDimensionSimilarity implements DimensionSimilarity<NumberVector<?>> {
+public class CovarianceDimensionSimilarity implements DimensionSimilarity<NumberVector> {
/**
* Static instance
*/
@@ -48,7 +48,7 @@ public class CovarianceDimensionSimilarity implements DimensionSimilarity<Number
}
@Override
- public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
+ public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
// FIXME: Use only necessary dimensions!
CovarianceMatrix covmat = CovarianceMatrix.make(relation, subset);
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarity.java
index d0c1a0bc..253bdb85 100644
--- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarity.java
+++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarity.java
@@ -4,7 +4,7 @@ package 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
@@ -25,7 +25,6 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Interface for computing pairwise dimension similarities, used for arranging
@@ -37,7 +36,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
*
* @param <V> Object type
*/
-public interface DimensionSimilarity<V> extends Parameterizable {
+public interface DimensionSimilarity<V> {
/**
* Compute the dimension similarity matrix
*
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarityMatrix.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarityMatrix.java
index 70429de4..7972938e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarityMatrix.java
+++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/DimensionSimilarityMatrix.java
@@ -7,7 +7,7 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
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/math/dimensionsimilarity/HSMDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HSMDimensionSimilarity.java
index e73d02af..02511047 100644
--- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HSMDimensionSimilarity.java
+++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HSMDimensionSimilarity.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -28,11 +28,10 @@ import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.math.SinCosTable;
-import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Compute the similarity of dimensions by using a hough transformation.
@@ -52,8 +51,11 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
* @author Erich Schubert
* @author Robert Rödler
*/
-@Reference(authors = "A. Tatu, G. Albuquerque, M. Eisemann, P. Bak, H. Theisel, M. A. Magnor, and D. A. Keim.", title = "Automated Analytical Methods to Support Visual Exploration of High-Dimensional Data", booktitle = "IEEE Trans. Visualization and Computer Graphics, 2011", url = "http://dx.doi.org/10.1109/TVCG.2010.242")
-public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector<?>> {
+@Reference(authors = "A. Tatu, G. Albuquerque, M. Eisemann, P. Bak, H. Theisel, M. A. Magnor, and D. A. Keim", //
+title = "Automated Analytical Methods to Support Visual Exploration of High-Dimensional Data", //
+booktitle = "IEEE Trans. Visualization and Computer Graphics, 2011", //
+url = "http://dx.doi.org/10.1109/TVCG.2010.242")
+public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector> {
/**
* Static instance.
*/
@@ -79,36 +81,35 @@ public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector<
}
@Override
- public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
+ public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
final int resolution = 512;
boolean[][][][] pics = new boolean[dim][dim][][]; // [resolution][resolution];
// Initialize / allocate "pictures":
- for (int i = 0; i < dim - 1; i++) {
- for (int j = i + 1; j < dim; j++) {
+ for(int i = 0; i < dim - 1; i++) {
+ for(int j = i + 1; j < dim; j++) {
pics[i][j] = new boolean[resolution][resolution];
}
}
// FIXME: Get/keep these statistics in the relation, or compute for the
// sample only.
- double[] off = new double[dim], scale = new double[dim];
+ double[] off, scale;
{
- Pair<? extends NumberVector<?>, ? extends NumberVector<?>> mm = DatabaseUtil.computeMinMax(relation);
- NumberVector<?> min = mm.first;
- NumberVector<?> max = mm.second;
- for (int d = 0; d < dim; d++) {
- off[d] = min.doubleValue(matrix.dim(d));
- final double m = max.doubleValue(matrix.dim(d));
- scale[d] = (m > off[d]) ? 1. / (m - off[d]) : 1;
+ double[][] mm = RelationUtil.computeMinMax(relation);
+ off = mm[0];
+ scale = mm[1];
+ for(int d = 0; d < dim; d++) {
+ scale[d] -= off[d];
+ scale[d] = (scale[d] > 0.) ? 1. / scale[d] : 1.;
}
}
// Iterate dataset
- for (DBIDIter id = subset.iter(); id.valid(); id.advance()) {
- NumberVector<?> pvec = relation.get(id);
- for (int i = 0; i < dim - 1; i++) {
+ for(DBIDIter id = subset.iter(); id.valid(); id.advance()) {
+ NumberVector pvec = relation.get(id);
+ for(int i = 0; i < dim - 1; i++) {
double xi = (pvec.doubleValue(matrix.dim(i)) - off[i]) * scale[i];
- for (int j = i + 1; j < dim; j++) {
+ for(int j = i + 1; j < dim; j++) {
double xj = (pvec.doubleValue(matrix.dim(j)) - off[j]) * scale[j];
drawLine(0, (int) (resolution * xi), resolution - 1, (int) (resolution * xj), pics[i][j]);
}
@@ -116,8 +117,8 @@ public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector<
}
final double stepsq = (double) STEPS * (double) STEPS;
- for (int x = 0; x < dim; x++) {
- for (int y = x + 1; y < dim; y++) {
+ for(int x = 0; x < dim; x++) {
+ for(int y = x + 1; y < dim; y++) {
int[][] hough = houghTransformation(pics[x][y]);
pics[x][y] = null; // Release picture
// The original publication said "median", but judging from the text,
@@ -139,9 +140,9 @@ public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector<
*/
private long sumMatrix(int[][] mat) {
long ret = 0;
- for (int i = 0; i < mat.length; i++) {
+ for(int i = 0; i < mat.length; i++) {
final int[] row = mat[i];
- for (int j = 0; j < row.length; j++) {
+ for(int j = 0; j < row.length; j++) {
ret += row[j];
}
}
@@ -157,10 +158,10 @@ public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector<
*/
private int countAboveThreshold(int[][] mat, double threshold) {
int ret = 0;
- for (int i = 0; i < mat.length; i++) {
+ for(int i = 0; i < mat.length; i++) {
int[] row = mat[i];
- for (int j = 0; j < row.length; j++) {
- if (row[j] >= threshold) {
+ for(int j = 0; j < row.length; j++) {
+ if(row[j] >= threshold) {
ret++;
}
}
@@ -179,12 +180,12 @@ public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector<
final double tscale = STEPS * .5 / (xres + yres);
final int[][] ret = new int[STEPS][STEPS];
- for (int x = 0; x < mat.length; x++) {
- for (int y = 0; y < mat[0].length; y++) {
- if (mat[x][y]) {
- for (int i = 0; i < STEPS; i++) {
+ for(int x = 0; x < mat.length; x++) {
+ for(int y = 0; y < mat[0].length; y++) {
+ if(mat[x][y]) {
+ for(int i = 0; i < STEPS; i++) {
final int d = (STEPS >> 1) + (int) (tscale * (x * table.cos(i) + y * table.sin(i)));
- if (d > 0 && d < STEPS) {
+ if(d > 0 && d < STEPS) {
ret[d][i]++;
}
}
@@ -217,18 +218,18 @@ public class HSMDimensionSimilarity implements DimensionSimilarity<NumberVector<
// Error counter
int err = dx + dy;
- for (;;) {
+ for(;;) {
pic[x0][y0] = true;
- if (x0 == x1 && y0 == y1) {
+ if(x0 == x1 && y0 == y1) {
break;
}
final int e2 = err << 1;
- if (e2 > dy) {
+ if(e2 > dy) {
err += dy;
x0 += sx;
}
- if (e2 < dx) {
+ if(e2 < dx) {
err += dx;
y0 += sy;
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HiCSDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HiCSDimensionSimilarity.java
index 9168fe7e..0ef532dd 100644
--- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HiCSDimensionSimilarity.java
+++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HiCSDimensionSimilarity.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -39,9 +39,9 @@ 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.HashSetModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.math.statistics.tests.GoodnessOfFitTest;
import de.lmu.ifi.dbs.elki.math.statistics.tests.KolmogorovSmirnovTest;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
@@ -72,8 +72,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
* @author Erich Schubert
* @author Robert Rödler
*/
-@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", url = "http://dx.doi.org/10.1145/2463676.2463696")
-public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector<?>> {
+@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", //
+title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", //
+booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", //
+url = "http://dx.doi.org/10.1145/2463676.2463696")
+public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector> {
/**
* Monte-Carlo iterations
*/
@@ -111,7 +114,7 @@ public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector
}
@Override
- public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
+ public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
final Random random = rnd.getSingleThreadedRandom();
final int dim = matrix.size();
@@ -138,7 +141,7 @@ public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector
* @param matrix Matrix (for dimension subset)
* @return List of sorted objects
*/
- private ArrayList<ArrayDBIDs> buildOneDimIndexes(Relation<? extends NumberVector<?>> relation, DBIDs ids, DimensionSimilarityMatrix matrix) {
+ private ArrayList<ArrayDBIDs> buildOneDimIndexes(Relation<? extends NumberVector> relation, DBIDs ids, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
ArrayList<ArrayDBIDs> subspaceIndex = new ArrayList<>(dim);
@@ -165,7 +168,7 @@ public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector
* @param random Random generator
* @return Contrast
*/
- private double calculateContrast(Relation<? extends NumberVector<?>> relation, DBIDs subset, ArrayDBIDs subspaceIndex1, ArrayDBIDs subspaceIndex2, int dim1, int dim2, Random random) {
+ private double calculateContrast(Relation<? extends NumberVector> relation, DBIDs subset, ArrayDBIDs subspaceIndex1, ArrayDBIDs subspaceIndex2, int dim1, int dim2, Random random) {
final double alpha1 = Math.sqrt(alpha);
final int windowsize = (int) (relation.size() * alpha1);
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/MCEDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/MCEDimensionSimilarity.java
index b3e6bb76..b5e9be6b 100644
--- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/MCEDimensionSimilarity.java
+++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/MCEDimensionSimilarity.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -54,8 +54,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Erich Schubert
*/
-@Reference(authors = "D. Guo", title = "Coordinating computational and visual approaches for interactive feature selection and multivariate clustering", booktitle = "Information Visualization, 2(4)", url = "http://dx.doi.org/10.1057/palgrave.ivs.9500053")
-public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector<?>> {
+@Reference(authors = "D. Guo", //
+title = "Coordinating computational and visual approaches for interactive feature selection and multivariate clustering", //
+booktitle = "Information Visualization, 2(4)", //
+url = "http://dx.doi.org/10.1057/palgrave.ivs.9500053")
+public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector> {
/**
* Static instance.
*/
@@ -77,11 +80,11 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector<
}
@Override
- public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
+ public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
// Find a number of bins as recommended by Cheng et al.
- double p = Math.log(subset.size() / (double) TARGET) / MathUtil.LOG2;
+ double p = MathUtil.log2(subset.size() / (double) TARGET);
// As we are in 2d, take the root (*.5) But let's use at least 1, too.
// Check: for 10000 this should give 4, for 150 it gives 1.
int power = Math.max(1, (int) Math.floor(p * .5));
@@ -92,18 +95,18 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector<
// Partition sizes
int[][] psizes = new int[dim][gridsize];
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
final ArrayList<DBIDs> partsd = parts.get(d);
final int[] sizesp = psizes[d];
- for (int i = 0; i < gridsize; i++) {
+ for(int i = 0; i < gridsize; i++) {
sizesp[i] = partsd.get(i).size();
}
}
int[][] res = new int[gridsize][gridsize];
- for (int x = 0; x < dim; x++) {
+ for(int x = 0; x < dim; x++) {
ArrayList<DBIDs> partsi = parts.get(x);
- for (int y = x + 1; y < dim; y++) {
+ for(int y = x + 1; y < dim; y++) {
ArrayList<DBIDs> partsj = parts.get(y);
// Fill the intersection matrix
intersectionMatrix(res, partsi, partsj, gridsize);
@@ -113,69 +116,6 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector<
}
/**
- * Intersect the two 1d grid decompositions, to obtain a 2d matrix.
- *
- * @param res Output matrix to fill
- * @param partsx Partitions in first component
- * @param partsy Partitions in second component.
- * @param gridsize Size of partition decomposition
- */
- private void intersectionMatrix(int[][] res, ArrayList<? extends DBIDs> partsx, ArrayList<? extends DBIDs> partsy, int gridsize) {
- for (int x = 0; x < gridsize; x++) {
- final DBIDs px = partsx.get(x);
- final int[] rowx = res[x];
- for (int y = 0; y < gridsize; y++) {
- rowx[y] = DBIDUtil.intersectionSize(px, partsy.get(y));
- }
- }
- }
-
- /**
- * Compute the MCE entropy value.
- *
- * @param mat Partition size matrix
- * @param psizesx Partition sizes on X
- * @param psizesy Partition sizes on Y
- * @param size Data set size
- * @param gridsize Size of grids
- * @param loggrid Logarithm of grid sizes, for normalization
- * @return MCE score.
- */
- private double getMCEntropy(int[][] mat, int[] psizesx, int[] psizesy, int size, int gridsize, double loggrid) {
- // Margin entropies:
- double[] mx = new double[gridsize];
- double[] my = new double[gridsize];
-
- for (int i = 0; i < gridsize; i++) {
- // Note: indexes are a bit tricky here, because we compute both margin
- // entropies at the same time!
- final double sumx = (double) psizesx[i];
- final double sumy = (double) psizesy[i];
- for (int j = 0; j < gridsize; j++) {
- double px = mat[i][j] / sumx;
- double py = mat[j][i] / sumy;
-
- if (px > 0.) {
- mx[i] -= px * Math.log(px);
- }
- if (py > 0.) {
- my[i] -= py * Math.log(py);
- }
- }
- }
-
- // Weighted sums of margin entropies.
- double sumx = 0., sumy = 0.;
- for (int i = 0; i < gridsize; i++) {
- sumx += mx[i] * psizesx[i];
- sumy += my[i] * psizesy[i];
- }
-
- double max = ((sumx > sumy) ? sumx : sumy);
- return max / (size * loggrid);
- }
-
- /**
* Calculates "index structures" for every attribute, i.e. sorts a
* ModifiableArray of every DBID in the database for every dimension and
* stores them in a list.
@@ -185,14 +125,14 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector<
* @param matrix Matrix for dimension information
* @return List of sorted objects
*/
- private ArrayList<ArrayList<DBIDs>> buildPartitions(Relation<? extends NumberVector<?>> relation, DBIDs ids, int depth, DimensionSimilarityMatrix matrix) {
+ private ArrayList<ArrayList<DBIDs>> buildPartitions(Relation<? extends NumberVector> relation, DBIDs ids, int depth, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
ArrayList<ArrayList<DBIDs>> subspaceIndex = new ArrayList<>(dim);
SortDBIDsBySingleDimension comp = new VectorUtil.SortDBIDsBySingleDimension(relation);
double[] tmp = new double[ids.size()];
Mean mean = new Mean();
-
- for (int i = 0; i < dim; i++) {
+
+ for(int i = 0; i < dim; i++) {
final int d = matrix.dim(i);
// Index for a single dimension:
ArrayList<DBIDs> idx = new ArrayList<>(1 << depth);
@@ -202,7 +142,7 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector<
sids.sort(comp);
// Now we build the temp array, and compute the first mean.
DBIDArrayIter it = sids.iter();
- for (int j = 0; j < tmp.length; j++, it.advance()) {
+ for(int j = 0; j < tmp.length; j++, it.advance()) {
assert (it.valid());
tmp[j] = relation.get(it).doubleValue(d);
}
@@ -210,7 +150,7 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector<
assert (idx.size() == (1 << depth));
subspaceIndex.add(idx);
}
-
+
return subspaceIndex;
}
@@ -227,44 +167,50 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector<
*/
private void divide(DBIDArrayIter it, double[] data, ArrayList<DBIDs> idx, int start, int end, int depth, Mean mean) {
final int count = end - start;
- if (depth == 0) {
- if (count > 0) {
+ if(depth == 0) {
+ if(count > 0) {
ModifiableDBIDs out = DBIDUtil.newHashSet(count);
it.seek(start);
- for (int i = count; i > 0; i--, it.advance()) {
+ for(int i = count; i > 0; i--, it.advance()) {
out.add(it);
}
idx.add(out);
- } else {
+ }
+ else {
idx.add(DBIDUtil.EMPTYDBIDS);
}
return;
- } else {
- if (count > 0) {
+ }
+ else {
+ if(count > 0) {
mean.reset();
- for (int i = start; i < end; i++) {
+ for(int i = start; i < end; i++) {
mean.put(data[i]);
}
final double m = mean.getMean();
int pos = Arrays.binarySearch(data, start, end, m);
- if (pos >= 0) {
+ if(pos >= 0) {
// Ties: try to choose the most central element.
int opt = (start + end) >> 1;
- while (Double.compare(data[pos], m) == 0) {
- if (pos < opt) {
+ while(Double.compare(data[pos], m) == 0) {
+ if(pos < opt) {
pos++;
- } else if (pos > opt) {
+ }
+ else if(pos > opt) {
pos--;
- } else {
+ }
+ else {
break;
}
}
- } else {
+ }
+ else {
pos = (-pos - 1);
}
divide(it, data, idx, start, pos, depth - 1, mean);
divide(it, data, idx, pos, end, depth - 1, mean);
- } else {
+ }
+ else {
// Corner case, that should barely happen. But for ties, we currently
// Do not yet assure that it doesn't happen!
divide(it, data, idx, start, end, depth - 1, mean);
@@ -274,6 +220,69 @@ public class MCEDimensionSimilarity implements DimensionSimilarity<NumberVector<
}
/**
+ * Intersect the two 1d grid decompositions, to obtain a 2d matrix.
+ *
+ * @param res Output matrix to fill
+ * @param partsx Partitions in first component
+ * @param partsy Partitions in second component.
+ * @param gridsize Size of partition decomposition
+ */
+ private void intersectionMatrix(int[][] res, ArrayList<? extends DBIDs> partsx, ArrayList<? extends DBIDs> partsy, int gridsize) {
+ for(int x = 0; x < gridsize; x++) {
+ final DBIDs px = partsx.get(x);
+ final int[] rowx = res[x];
+ for(int y = 0; y < gridsize; y++) {
+ rowx[y] = DBIDUtil.intersectionSize(px, partsy.get(y));
+ }
+ }
+ }
+
+ /**
+ * Compute the MCE entropy value.
+ *
+ * @param mat Partition size matrix
+ * @param psizesx Partition sizes on X
+ * @param psizesy Partition sizes on Y
+ * @param size Data set size
+ * @param gridsize Size of grids
+ * @param loggrid Logarithm of grid sizes, for normalization
+ * @return MCE score.
+ */
+ private double getMCEntropy(int[][] mat, int[] psizesx, int[] psizesy, int size, int gridsize, double loggrid) {
+ // Margin entropies:
+ double[] mx = new double[gridsize];
+ double[] my = new double[gridsize];
+
+ for(int i = 0; i < gridsize; i++) {
+ // Note: indexes are a bit tricky here, because we compute both margin
+ // entropies at the same time!
+ final double sumx = (double) psizesx[i];
+ final double sumy = (double) psizesy[i];
+ for(int j = 0; j < gridsize; j++) {
+ double px = mat[i][j] / sumx;
+ double py = mat[j][i] / sumy;
+
+ if(px > 0.) {
+ mx[i] -= px * Math.log(px);
+ }
+ if(py > 0.) {
+ my[i] -= py * Math.log(py);
+ }
+ }
+ }
+
+ // Weighted sums of margin entropies.
+ double sumx = 0., sumy = 0.;
+ for(int i = 0; i < gridsize; i++) {
+ sumx += mx[i] * psizesx[i];
+ sumy += my[i] * psizesy[i];
+ }
+
+ double max = ((sumx > sumy) ? sumx : sumy);
+ return max / (size * loggrid);
+ }
+
+ /**
* Parameterization class.
*
* @author Erich Schubert
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SURFINGDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SURFINGDimensionSimilarity.java
index fd83d44b..70831a02 100644
--- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SURFINGDimensionSimilarity.java
+++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SURFINGDimensionSimilarity.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,8 +23,6 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity;
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.Database;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
@@ -33,8 +31,8 @@ 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.distancefunction.subspace.SubspaceEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.math.Mean;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -70,7 +68,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
* @apiviz.uses SubspaceEuclideanDistanceFunction
*/
@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", url = "http://dx.doi.org/10.1145/2463676.2463696")
-public class SURFINGDimensionSimilarity implements DimensionSimilarity<NumberVector<?>> {
+public class SURFINGDimensionSimilarity implements DimensionSimilarity<NumberVector> {
/**
* Static instance.
*/
@@ -83,9 +81,12 @@ public class SURFINGDimensionSimilarity implements DimensionSimilarity<NumberVec
super();
}
- @Reference(authors = "Christian Baumgartner, Claudia Plant, Karin Kailing, Hans-Peter Kriegel, and Peer Kröger", title = "Subspace Selection for Clustering High-Dimensional Data", booktitle = "IEEE International Conference on Data Mining, 2004", url = "http://dx.doi.org/10.1109/ICDM.2004.10112")
+ @Reference(authors = "Christian Baumgartner, Claudia Plant, Karin Kailing, Hans-Peter Kriegel, and Peer Kröger", //
+ title = "Subspace Selection for Clustering High-Dimensional Data", //
+ booktitle = "IEEE International Conference on Data Mining, 2004", //
+ url = "http://dx.doi.org/10.1109/ICDM.2004.10112")
@Override
- public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
+ public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
Mean kdistmean = new Mean();
final int k = Math.max(1, subset.size() / 10);
@@ -93,20 +94,20 @@ public class SURFINGDimensionSimilarity implements DimensionSimilarity<NumberVec
double[] knns = new double[subset.size()];
// TODO: optimize by using 1d indexes?
- for (int x = 0; x < dim; x++) {
+ for(int x = 0; x < dim; x++) {
final int i = matrix.dim(x);
- for (int y = x + 1; y < dim; y++) {
+ for(int y = x + 1; y < dim; y++) {
final int j = matrix.dim(y);
- BitSet dims = new BitSet(dim);
- dims.set(i);
- dims.set(j);
- DistanceQuery<? extends NumberVector<?>, DoubleDistance> dq = database.getDistanceQuery(relation, new SubspaceEuclideanDistanceFunction(dims));
- KNNQuery<? extends NumberVector<?>, DoubleDistance> knnq = database.getKNNQuery(dq, k);
+ long[] dims = BitsUtil.zero(dim);
+ BitsUtil.setI(dims, i);
+ BitsUtil.setI(dims, j);
+ DistanceQuery<? extends NumberVector> dq = database.getDistanceQuery(relation, new SubspaceEuclideanDistanceFunction(dims));
+ KNNQuery<? extends NumberVector> knnq = database.getKNNQuery(dq, k);
kdistmean.reset();
int knn = 0;
- for (DBIDIter id1 = subset.iter(); id1.valid(); id1.advance(), knn++) {
- final double kdist = knnq.getKNNForDBID(id1, k).getKNNDistance().doubleValue();
+ for(DBIDIter id1 = subset.iter(); id1.valid(); id1.advance(), knn++) {
+ final double kdist = knnq.getKNNForDBID(id1, k).getKNNDistance();
kdistmean.put(kdist);
knns[knn] = kdist;
}
@@ -114,9 +115,9 @@ public class SURFINGDimensionSimilarity implements DimensionSimilarity<NumberVec
// Deviation from mean:
double diff = 0.;
int below = 0;
- for (int l = 0; l < knns.length; l++) {
+ for(int l = 0; l < knns.length; l++) {
diff += Math.abs(mean - knns[l]);
- if (knns[l] < mean) {
+ if(knns[l] < mean) {
below++;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeDimensionSimilarity.java
index 1eb62189..b48a2410 100644
--- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeDimensionSimilarity.java
+++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeDimensionSimilarity.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -28,10 +28,9 @@ import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
+import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Arrange dimensions based on the entropy of the slope spectrum.
@@ -43,12 +42,17 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
* Proceedings of the 2013 ACM International Conference on Management of Data
* (SIGMOD), New York City, NY, 2013.
* </p>
- *
+ *
+ * TODO: shouldn't this be normalized by the single-dimension entropies or so?
+ *
* @author Erich Schubert
* @author Robert Rödler
*/
-@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", url = "http://dx.doi.org/10.1145/2463676.2463696")
-public class SlopeDimensionSimilarity implements DimensionSimilarity<NumberVector<?>> {
+@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", //
+title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", //
+booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", //
+url = "http://dx.doi.org/10.1145/2463676.2463696")
+public class SlopeDimensionSimilarity implements DimensionSimilarity<NumberVector> {
/**
* Static instance.
*/
@@ -77,21 +81,19 @@ public class SlopeDimensionSimilarity implements DimensionSimilarity<NumberVecto
}
@Override
- public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
+ public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
final int size = subset.size();
// FIXME: Get/keep these statistics in the relation, or compute for the
// sample only.
- double[] off = new double[dim], scale = new double[dim];
+ double[] off, scale;
{
- Pair<? extends NumberVector<?>, ? extends NumberVector<?>> mm = DatabaseUtil.computeMinMax(relation);
- NumberVector<?> min = mm.first;
- NumberVector<?> max = mm.second;
+ double[][] mm = RelationUtil.computeMinMax(relation);
+ off = mm[0]; scale = mm[1];
for (int d = 0; d < dim; d++) {
- off[d] = min.doubleValue(matrix.dim(d));
- final double m = max.doubleValue(matrix.dim(d));
- scale[d] = (m > off[d]) ? 1. / (m - off[d]) : 1;
+ scale[d] -= off[d];
+ scale[d] = (scale[d] > 0.) ? 1. / scale[d] : 1.;
}
}
@@ -102,7 +104,7 @@ public class SlopeDimensionSimilarity implements DimensionSimilarity<NumberVecto
// Scratch buffer
double[] vec = new double[dim];
for (DBIDIter id = subset.iter(); id.valid(); id.advance()) {
- final NumberVector<?> obj = relation.get(id);
+ final NumberVector obj = relation.get(id);
// Map values to 0..1
for (int d = 0; d < dim; d++) {
vec[d] = (obj.doubleValue(matrix.dim(d)) - off[d]) * scale[d];
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeInversionDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeInversionDimensionSimilarity.java
index 77408914..8ccb3597 100644
--- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeInversionDimensionSimilarity.java
+++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/SlopeInversionDimensionSimilarity.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.dimensionsimilarity;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -28,10 +28,9 @@ import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
+import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Arrange dimensions based on the entropy of the slope spectrum. In contrast to
@@ -51,7 +50,10 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
* @author Erich Schubert
* @author Robert Rödler
*/
-@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", url = "http://dx.doi.org/10.1145/2463676.2463696")
+@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", //
+title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", //
+booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", //
+url = "http://dx.doi.org/10.1145/2463676.2463696")
public class SlopeInversionDimensionSimilarity extends SlopeDimensionSimilarity {
/**
* Static instance.
@@ -66,7 +68,7 @@ public class SlopeInversionDimensionSimilarity extends SlopeDimensionSimilarity
}
@Override
- public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
+ public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
final int dim = matrix.size();
final int size = subset.size();
@@ -77,28 +79,27 @@ public class SlopeInversionDimensionSimilarity extends SlopeDimensionSimilarity
// FIXME: Get/keep these statistics in the relation, or compute for the
// sample only.
- double[] off = new double[dim], scale = new double[dim];
+ double[] off, scale;
{
- Pair<? extends NumberVector<?>, ? extends NumberVector<?>> mm = DatabaseUtil.computeMinMax(relation);
- NumberVector<?> min = mm.first;
- NumberVector<?> max = mm.second;
- for (int d = 0; d < dim; d++) {
- off[d] = min.doubleValue(matrix.dim(d));
- final double m = max.doubleValue(matrix.dim(d));
- scale[d] = (m > off[d]) ? 1. / (m - off[d]) : 1;
+ double[][] mm = RelationUtil.computeMinMax(relation);
+ off = mm[0];
+ scale = mm[1];
+ for(int d = 0; d < dim; d++) {
+ scale[d] -= off[d];
+ scale[d] = (scale[d] > 0.) ? 1. / scale[d] : 1.;
}
}
// Scratch buffer
double[] vec = new double[dim];
- for (DBIDIter id = subset.iter(); id.valid(); id.advance()) {
- final NumberVector<?> obj = relation.get(id);
+ for(DBIDIter id = subset.iter(); id.valid(); id.advance()) {
+ final NumberVector obj = relation.get(id);
// Map values to 0..1
- for (int d = 0; d < dim; d++) {
+ for(int d = 0; d < dim; d++) {
vec[d] = (obj.doubleValue(matrix.dim(d)) - off[d]) * scale[d];
}
- for (int i = 0; i < dim - 1; i++) {
- for (int j = i + 1; j < dim; j++) {
+ for(int i = 0; i < dim - 1; i++) {
+ for(int j = i + 1; j < dim; j++) {
{
// This will be on a scale of 0 .. 2:
final double delta = vec[j] - vec[i] + 1;
@@ -120,13 +121,13 @@ public class SlopeInversionDimensionSimilarity extends SlopeDimensionSimilarity
}
// Compute entropy in each combination:
- for (int x = 0; x < dim; x++) {
- for (int y = x + 1; y < dim; y++) {
+ for(int x = 0; x < dim; x++) {
+ for(int y = x + 1; y < dim; y++) {
double entropy = 0., entropyI = 0;
{
int[] as = angles[x][y];
- for (int l = 0; l < PRECISION; l++) {
- if (as[l] > 0) {
+ for(int l = 0; l < PRECISION; l++) {
+ if(as[l] > 0) {
final double p = as[l] / (double) size;
entropy += p * Math.log(p);
}
@@ -134,17 +135,18 @@ public class SlopeInversionDimensionSimilarity extends SlopeDimensionSimilarity
}
{
int[] as = angleI[x][y];
- for (int l = 0; l < PRECISION; l++) {
- if (as[l] > 0) {
+ for(int l = 0; l < PRECISION; l++) {
+ if(as[l] > 0) {
final double p = as[l] / (double) size;
entropyI += p * Math.log(p);
}
}
}
- if (entropy >= entropyI) {
+ if(entropy >= entropyI) {
entropy = 1 + entropy / LOG_PRECISION;
matrix.set(x, y, entropy);
- } else {
+ }
+ else {
entropyI = 1 + entropyI / LOG_PRECISION;
// Negative sign to indicate the axes might be inversely related
matrix.set(x, y, -entropyI);
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/package-info.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/package-info.java
index bcbd47d5..606a43ce 100644
--- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/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/math/geodesy/AbstractEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/AbstractEarthModel.java
index d8eaa43f..9426f84e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geodesy/AbstractEarthModel.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/AbstractEarthModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy;
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/math/geodesy/Clarke1858SpheroidEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1858SpheroidEarthModel.java
index c1d8a9af..d8842b30 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1858SpheroidEarthModel.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1858SpheroidEarthModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy;
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/math/geodesy/Clarke1880SpheroidEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1880SpheroidEarthModel.java
index 731cf9eb..e23f15fb 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1880SpheroidEarthModel.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/Clarke1880SpheroidEarthModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy;
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/math/geodesy/EarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/EarthModel.java
index b27f2e3b..9cf76ac3 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geodesy/EarthModel.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/EarthModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy;
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/math/geodesy/GRS67SpheroidEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/GRS67SpheroidEarthModel.java
index 81dc7565..33c7f243 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geodesy/GRS67SpheroidEarthModel.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/GRS67SpheroidEarthModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy;
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/math/geodesy/GRS80SpheroidEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/GRS80SpheroidEarthModel.java
index 2499da0c..78bb396b 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geodesy/GRS80SpheroidEarthModel.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/GRS80SpheroidEarthModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy;
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/math/geodesy/SphereUtil.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphereUtil.java
index b8e57cc3..d53f9a62 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geodesy/SphereUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphereUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy;
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/math/geodesy/SphericalCosineEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalCosineEarthModel.java
index f81757ac..9e66bd25 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalCosineEarthModel.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalCosineEarthModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy;
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/math/geodesy/SphericalHaversineEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalHaversineEarthModel.java
index 5ed8c4ca..b4823341 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalHaversineEarthModel.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalHaversineEarthModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy;
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/math/geodesy/SphericalVincentyEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalVincentyEarthModel.java
index e9a780cc..507218e7 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalVincentyEarthModel.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/SphericalVincentyEarthModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy;
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/math/geodesy/WGS72SpheroidEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/WGS72SpheroidEarthModel.java
index 44d4f9d0..488006ae 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geodesy/WGS72SpheroidEarthModel.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/WGS72SpheroidEarthModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy;
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/math/geodesy/WGS84SpheroidEarthModel.java b/src/de/lmu/ifi/dbs/elki/math/geodesy/WGS84SpheroidEarthModel.java
index 30ba02aa..07b8dab5 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geodesy/WGS84SpheroidEarthModel.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geodesy/WGS84SpheroidEarthModel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geodesy;
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/math/geometry/AlphaShape.java b/src/de/lmu/ifi/dbs/elki/math/geometry/AlphaShape.java
index 11f24cb2..a2349b32 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geometry/AlphaShape.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geometry/AlphaShape.java
@@ -12,7 +12,7 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
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/math/geometry/GrahamScanConvexHull2D.java b/src/de/lmu/ifi/dbs/elki/math/geometry/GrahamScanConvexHull2D.java
index c2945fde..27b8444f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geometry/GrahamScanConvexHull2D.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geometry/GrahamScanConvexHull2D.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geometry;
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
@@ -43,7 +43,9 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
*
* @apiviz.has Polygon
*/
-@Reference(authors = "Paul Graham", title = "An Efficient Algorithm for Determining the Convex Hull of a Finite Planar Set", booktitle = "Information Processing Letters 1")
+@Reference(authors = "Paul Graham", //
+title = "An Efficient Algorithm for Determining the Convex Hull of a Finite Planar Set", //
+booktitle = "Information Processing Letters 1")
public class GrahamScanConvexHull2D {
/**
* The current set of points
diff --git a/src/de/lmu/ifi/dbs/elki/math/geometry/PrimsMinimumSpanningTree.java b/src/de/lmu/ifi/dbs/elki/math/geometry/PrimsMinimumSpanningTree.java
index 887b5012..bc7380cd 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geometry/PrimsMinimumSpanningTree.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geometry/PrimsMinimumSpanningTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geometry;
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
@@ -45,7 +45,9 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
*
* @apiviz.composedOf Adapter
*/
-@Reference(authors = "R. C. Prim", title = "Shortest connection networks and some generalizations", booktitle = "Bell System Technical Journal, 36 (1957)")
+@Reference(authors = "R. C. Prim", //
+title = "Shortest connection networks and some generalizations", //
+booktitle = "Bell System Technical Journal, 36 (1957)")
public class PrimsMinimumSpanningTree {
/**
* Adapter class for double[][] matrixes.
@@ -99,18 +101,18 @@ public class PrimsMinimumSpanningTree {
best[current] = 0;
// Search
- for (int i = n - 2; i >= 0; i--) {
+ for(int i = n - 2; i >= 0; i--) {
// Update best and src from current:
int newbesti = -1;
double newbestd = Double.POSITIVE_INFINITY;
// Note: we assume we started with 0, and can thus skip it
- for (int j = in.nextClearBit(1); j < n && j > 0; j = in.nextClearBit(j + 1)) {
+ for(int j = in.nextClearBit(1); j < n && j > 0; j = in.nextClearBit(j + 1)) {
final double dist = adapter.distance(data, current, j);
- if (dist < best[j]) {
+ if(dist < best[j]) {
best[j] = dist;
src[j] = current;
}
- if (best[j] < newbestd) {
+ if(best[j] < newbestd) {
newbestd = best[j];
newbesti = j;
}
@@ -128,6 +130,42 @@ public class PrimsMinimumSpanningTree {
}
/**
+ * Prune the minimum spanning tree, removing all edges to nodes that have a
+ * degree below {@code minDegree}.
+ *
+ * @param numnodes Number of nodes (MUST use numbers 0 to {@code numnodes-1})
+ * @param tree Original spanning tree
+ * @param minDegree Minimum node degree
+ * @return Pruned spanning tree
+ */
+ public static int[] pruneTree(int numnodes, int[] tree, int minDegree) {
+ // Compute node degrees
+ int[] deg = new int[numnodes];
+ for(int i = 0; i < tree.length; i++) {
+ deg[tree[i]]++;
+ }
+ // Count nodes to be retained:
+ int keep = 0;
+ for(int i = 0; i < tree.length; i += 2) {
+ if(deg[tree[i]] >= minDegree && deg[tree[i + 1]] >= minDegree) {
+ keep++;
+ }
+ }
+ // Build reduced tree
+ int j = 0;
+ int[] ret = new int[keep];
+ for(int i = 0; i < tree.length; i += 2) {
+ if(deg[tree[i]] >= minDegree && deg[tree[i + 1]] >= minDegree) {
+ ret[j] = tree[i];
+ ret[j + 1] = tree[i + 1];
+ j += 2;
+ }
+ }
+ assert (j == ret.length);
+ return ret;
+ }
+
+ /**
* Adapter interface to allow use with different data representations.
*
* @author Erich Schubert
diff --git a/src/de/lmu/ifi/dbs/elki/math/geometry/SweepHullDelaunay2D.java b/src/de/lmu/ifi/dbs/elki/math/geometry/SweepHullDelaunay2D.java
index ca6d0e5e..c45d8297 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geometry/SweepHullDelaunay2D.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geometry/SweepHullDelaunay2D.java
@@ -21,7 +21,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.IntIntPair;
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
@@ -49,7 +49,9 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.IntIntPair;
*
* @apiviz.has Polygon
*/
-@Reference(authors = "David Sinclair", title = "S-hull: a fast sweep-hull routine for Delaunay triangulation", booktitle = "Online: http://s-hull.org/")
+@Reference(authors = "David Sinclair", //
+title = "S-hull: a fast sweep-hull routine for Delaunay triangulation", //
+booktitle = "Online: http://s-hull.org/")
public class SweepHullDelaunay2D {
/**
* Class logger
@@ -655,7 +657,7 @@ public class SweepHullDelaunay2D {
* @param a Starting point
* @param b Reference point
* @param d Test point
- * @return true when on the left side
+ * @return true when on the left side
*/
boolean leftOf(Vector a, Vector b, Vector d) {
final double bax = b.get(0) - a.get(0);
@@ -700,7 +702,7 @@ public class SweepHullDelaunay2D {
* Circumcircle parameters
*/
public double r2 = -1;
-
+
/**
* Center vector
*/
@@ -890,7 +892,7 @@ public class SweepHullDelaunay2D {
// Compute D
final double D = 2 * (abx * acy - aby * acx);
-
+
// No circumcircle:
if(D == 0) {
return false;
@@ -900,7 +902,6 @@ public class SweepHullDelaunay2D {
final double offx = (acy * ablen - aby * aclen) / D;
final double offy = (abx * aclen - acx * ablen) / D;
-
// Avoid degeneration:
r2 = offx * offx + offy * offy;
if((r2 > 1e10 * ablen || r2 > 1e10 * aclen)) {
diff --git a/src/de/lmu/ifi/dbs/elki/math/geometry/XYCurve.java b/src/de/lmu/ifi/dbs/elki/math/geometry/XYCurve.java
index 36ee7f23..35edd0cc 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geometry/XYCurve.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geometry/XYCurve.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.geometry;
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/math/geometry/package-info.java b/src/de/lmu/ifi/dbs/elki/math/geometry/package-info.java
index d94ac05a..c4e932a8 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geometry/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geometry/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/math/linearalgebra/AffineTransformation.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/AffineTransformation.java
index a4df5e80..745fbf4d 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/AffineTransformation.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/AffineTransformation.java
@@ -8,7 +8,7 @@ import de.lmu.ifi.dbs.elki.math.MathUtil;
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
@@ -270,7 +270,7 @@ public class AffineTransformation {
* @return copy of the transformation matrix
*/
public Matrix getTransformation() {
- return trans.copy();
+ return trans;
}
/**
@@ -282,7 +282,7 @@ public class AffineTransformation {
if(inv == null) {
updateInverse();
}
- return inv.copy();
+ return inv;
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Centroid.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Centroid.java
index 7650ecd2..4b38f556 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Centroid.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Centroid.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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
@@ -114,7 +114,7 @@ public class Centroid extends Vector {
*
* @param val Value
*/
- public void put(NumberVector<?> val) {
+ public void put(NumberVector val) {
assert (val.getDimensionality() == elements.length);
wsum += 1.0;
for (int i = 0; i < elements.length; i++) {
@@ -129,7 +129,7 @@ public class Centroid extends Vector {
* @param val data
* @param weight weight
*/
- public void put(NumberVector<?> val, double weight) {
+ public void put(NumberVector val, double weight) {
assert (val.getDimensionality() == elements.length);
if (weight == 0) {
return; // Skip zero weights.
@@ -150,7 +150,7 @@ public class Centroid extends Vector {
* @param <F> vector type
* @return the data
*/
- public <F extends NumberVector<?>> F toVector(Relation<? extends F> relation) {
+ public <F extends NumberVector> F toVector(Relation<? extends F> relation) {
return RelationUtil.getNumberVectorFactory(relation).newNumberVector(elements);
}
@@ -176,7 +176,7 @@ public class Centroid extends Vector {
* @param relation Relation to use
* @return Centroid of relation
*/
- public static Centroid make(Relation<? extends NumberVector<?>> relation) {
+ public static Centroid make(Relation<? extends NumberVector> relation) {
Centroid c = new Centroid(RelationUtil.dimensionality(relation));
for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
c.put(relation.get(iditer));
@@ -191,7 +191,7 @@ public class Centroid extends Vector {
* @param ids IDs to use
* @return Centroid
*/
- public static Centroid make(Relation<? extends NumberVector<?>> relation, DBIDs ids) {
+ public static Centroid make(Relation<? extends NumberVector> relation, DBIDs ids) {
Centroid c = new Centroid(RelationUtil.dimensionality(relation));
for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
c.put(relation.get(iter));
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CholeskyDecomposition.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CholeskyDecomposition.java
index 6fa455ca..eb8bc0f9 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CholeskyDecomposition.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CholeskyDecomposition.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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/math/linearalgebra/CovarianceMatrix.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CovarianceMatrix.java
index 345f2a42..38a98b3c 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CovarianceMatrix.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CovarianceMatrix.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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,6 +23,8 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
@@ -85,7 +87,16 @@ public class CovarianceMatrix {
this.mean = new double[dim];
this.nmea = new double[dim];
this.elements = new double[dim][dim];
- this.wsum = 0.0;
+ this.wsum = 0.;
+ }
+
+ /**
+ * Get the matrix dimensionality.
+ *
+ * @return Mean length.
+ */
+ public int getDimensionality() {
+ return mean.length;
}
/**
@@ -95,21 +106,21 @@ public class CovarianceMatrix {
*/
public void put(double[] val) {
assert (val.length == mean.length);
- final double nwsum = wsum + 1.0;
+ final double nwsum = wsum + 1.;
// Compute new means
- for (int i = 0; i < mean.length; i++) {
+ for(int i = 0; i < mean.length; i++) {
final double delta = val[i] - mean[i];
nmea[i] = mean[i] + delta / nwsum;
}
// Update covariance matrix
- for (int i = 0; i < mean.length; i++) {
- for (int j = i; j < mean.length; j++) {
+ for(int i = 0; i < mean.length; i++) {
+ for(int j = i; j < mean.length; j++) {
// We DO want to use the new mean once and the old mean once!
// It does not matter which one is which.
double delta = (val[i] - nmea[i]) * (val[j] - mean[j]);
elements[i][j] = elements[i][j] + delta;
// Optimize via symmetry
- if (i != j) {
+ if(i != j) {
elements[j][i] = elements[j][i] + delta;
}
}
@@ -130,20 +141,20 @@ public class CovarianceMatrix {
assert (val.length == mean.length);
final double nwsum = wsum + weight;
// Compute new means
- for (int i = 0; i < mean.length; i++) {
+ for(int i = 0; i < mean.length; i++) {
final double delta = val[i] - mean[i];
final double rval = delta * weight / nwsum;
nmea[i] = mean[i] + rval;
}
// Update covariance matrix
- for (int i = 0; i < mean.length; i++) {
- for (int j = i; j < mean.length; j++) {
+ for(int i = 0; i < mean.length; i++) {
+ for(int j = i; j < mean.length; j++) {
// We DO want to use the new mean once and the old mean once!
// It does not matter which one is which.
double delta = (val[i] - nmea[i]) * (val[j] - mean[j]) * weight;
elements[i][j] = elements[i][j] + delta;
// Optimize via symmetry
- if (i != j) {
+ if(i != j) {
elements[j][i] = elements[j][i] + delta;
}
}
@@ -178,23 +189,23 @@ public class CovarianceMatrix {
*
* @param val Value
*/
- public void put(NumberVector<?> val) {
+ public void put(NumberVector val) {
assert (val.getDimensionality() == mean.length);
- final double nwsum = wsum + 1.0;
+ final double nwsum = wsum + 1.;
// Compute new means
- for (int i = 0; i < mean.length; i++) {
+ for(int i = 0; i < mean.length; i++) {
final double delta = val.doubleValue(i) - mean[i];
nmea[i] = mean[i] + delta / nwsum;
}
// Update covariance matrix
- for (int i = 0; i < mean.length; i++) {
- for (int j = i; j < mean.length; j++) {
+ for(int i = 0; i < mean.length; i++) {
+ for(int j = i; j < mean.length; j++) {
// We DO want to use the new mean once and the old mean once!
// It does not matter which one is which.
double delta = (val.doubleValue(i) - nmea[i]) * (val.doubleValue(j) - mean[j]);
elements[i][j] = elements[i][j] + delta;
// Optimize via symmetry
- if (i != j) {
+ if(i != j) {
elements[j][i] = elements[j][i] + delta;
}
}
@@ -205,39 +216,29 @@ public class CovarianceMatrix {
}
/**
- * Get the weight sum, to test whether the covariance matrix can be
- * materialized.
- *
- * @return Weight sum.
- */
- public double getWeight() {
- return wsum;
- }
-
- /**
* Add data with a given weight.
*
* @param val data
* @param weight weight
*/
- public void put(NumberVector<?> val, double weight) {
+ public void put(NumberVector val, double weight) {
assert (val.getDimensionality() == mean.length);
final double nwsum = wsum + weight;
// Compute new means
- for (int i = 0; i < mean.length; i++) {
+ for(int i = 0; i < mean.length; i++) {
final double delta = val.doubleValue(i) - mean[i];
final double rval = delta * weight / nwsum;
nmea[i] = mean[i] + rval;
}
// Update covariance matrix
- for (int i = 0; i < mean.length; i++) {
- for (int j = i; j < mean.length; j++) {
+ for(int i = 0; i < mean.length; i++) {
+ for(int j = i; j < mean.length; j++) {
// We DO want to use the new mean once and the old mean once!
// It does not matter which one is which.
double delta = (val.doubleValue(i) - nmea[i]) * (val.doubleValue(j) - mean[j]) * weight;
elements[i][j] = elements[i][j] + delta;
// Optimize via symmetry
- if (i != j) {
+ if(i != j) {
elements[j][i] = elements[j][i] + delta;
}
}
@@ -248,6 +249,16 @@ public class CovarianceMatrix {
}
/**
+ * Get the weight sum, to test whether the covariance matrix can be
+ * materialized.
+ *
+ * @return Weight sum.
+ */
+ public double getWeight() {
+ return wsum;
+ }
+
+ /**
* Get the mean as vector.
*
* @return Mean vector
@@ -263,7 +274,7 @@ public class CovarianceMatrix {
* @param <F> vector type
* @return Mean vector
*/
- public <F extends NumberVector<?>> F getMeanVector(Relation<? extends F> relation) {
+ public <F extends NumberVector> F getMeanVector(Relation<? extends F> relation) {
return RelationUtil.getNumberVectorFactory(relation).newNumberVector(mean);
}
@@ -278,7 +289,7 @@ public class CovarianceMatrix {
* @return New matrix
*/
public Matrix makeSampleMatrix() {
- if (wsum <= 1.0) {
+ if(wsum <= 1.0) {
throw new IllegalStateException(ERR_TOO_LITTLE_WEIGHT);
}
Matrix mat = new Matrix(elements);
@@ -296,11 +307,11 @@ public class CovarianceMatrix {
* @return New matrix
*/
public Matrix makeNaiveMatrix() {
- if (wsum <= 0.0) {
+ if(wsum <= 0.) {
throw new IllegalStateException(ERR_TOO_LITTLE_WEIGHT);
}
Matrix mat = new Matrix(elements);
- return mat.times(1.0 / wsum);
+ return mat.times(1. / wsum);
}
/**
@@ -314,10 +325,10 @@ public class CovarianceMatrix {
* @return New matrix
*/
public Matrix destroyToSampleMatrix() {
- if (wsum <= 1.0) {
+ if(wsum <= 1.) {
throw new IllegalStateException(ERR_TOO_LITTLE_WEIGHT);
}
- Matrix mat = new Matrix(elements).timesEquals(1.0 / (wsum - 1));
+ Matrix mat = new Matrix(elements).timesEquals(1. / (wsum - 1.));
this.elements = null;
return mat;
}
@@ -333,15 +344,34 @@ public class CovarianceMatrix {
* @return New matrix
*/
public Matrix destroyToNaiveMatrix() {
- if (wsum <= 0.0) {
+ if(wsum <= 0.) {
throw new IllegalStateException(ERR_TOO_LITTLE_WEIGHT);
}
- Matrix mat = new Matrix(elements).timesEquals(1.0 / wsum);
+ Matrix mat = new Matrix(elements).timesEquals(1. / wsum);
this.elements = null;
return mat;
}
/**
+ * Reset the covariance matrix.
+ *
+ * This function <em>may</em> be called after a "destroy".
+ */
+ public void reset() {
+ Arrays.fill(mean, 0.);
+ Arrays.fill(nmea, 0.);
+ if(elements != null) {
+ for(int i = 0; i < elements.length; i++) {
+ Arrays.fill(elements[i], 0.);
+ }
+ }
+ else {
+ elements = new double[mean.length][mean.length];
+ }
+ wsum = 0.;
+ }
+
+ /**
* Static Constructor.
*
* @param mat Matrix to use the columns of
@@ -350,7 +380,7 @@ public class CovarianceMatrix {
public static CovarianceMatrix make(Matrix mat) {
CovarianceMatrix c = new CovarianceMatrix(mat.getRowDimensionality());
int n = mat.getColumnDimensionality();
- for (int i = 0; i < n; i++) {
+ for(int i = 0; i < n; i++) {
// TODO: avoid constructing the vector objects?
c.put(mat.getCol(i));
}
@@ -363,9 +393,9 @@ public class CovarianceMatrix {
* @param relation Relation to use.
* @return Covariance matrix
*/
- public static CovarianceMatrix make(Relation<? extends NumberVector<?>> relation) {
+ public static CovarianceMatrix make(Relation<? extends NumberVector> relation) {
CovarianceMatrix c = new CovarianceMatrix(RelationUtil.dimensionality(relation));
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
c.put(relation.get(iditer));
}
return c;
@@ -378,9 +408,9 @@ public class CovarianceMatrix {
* @param ids IDs to add
* @return Covariance matrix
*/
- public static CovarianceMatrix make(Relation<? extends NumberVector<?>> relation, DBIDs ids) {
+ public static CovarianceMatrix make(Relation<? extends NumberVector> relation, DBIDs ids) {
CovarianceMatrix c = new CovarianceMatrix(RelationUtil.dimensionality(relation));
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
c.put(relation.get(iter));
}
return c;
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenPair.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenPair.java
index 3b65d99a..1ca999cc 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenPair.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenPair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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
@@ -101,6 +101,6 @@ public class EigenPair implements Comparable<EigenPair> {
*/
@Override
public String toString() {
- return "(ew = " + FormatUtil.format(eigenvalue) + ", ev = [" + FormatUtil.format(eigenvector) + "])";
+ return "(ew = " + eigenvalue + ", ev = [" + FormatUtil.format(eigenvector) + "])";
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenvalueDecomposition.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenvalueDecomposition.java
index 61401b18..cf5dc8e9 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenvalueDecomposition.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenvalueDecomposition.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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/math/linearalgebra/LUDecomposition.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/LUDecomposition.java
index 16fcf21c..9b76c489 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/LUDecomposition.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/LUDecomposition.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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/math/linearalgebra/LinearEquationSystem.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/LinearEquationSystem.java
index f32ce410..0a837f0e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/LinearEquationSystem.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/LinearEquationSystem.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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
@@ -623,7 +623,7 @@ public class LinearEquationSystem {
StringBuilder msg = new StringBuilder();
if (LOG.isDebugging()) {
- msg.append("\nSpecial solution x_0 = [").append(FormatUtil.format(x_0, ",", 4)).append(']');
+ msg.append("\nSpecial solution x_0 = [").append(FormatUtil.format(x_0, ",", FormatUtil.NF4)).append(']');
msg.append("\nbound Indices ").append(boundIndices);
msg.append("\nfree Indices ").append(freeIndices);
}
@@ -651,7 +651,7 @@ public class LinearEquationSystem {
if (LOG.isDebugging()) {
msg.append("\nU");
for (double[] anU : u) {
- msg.append('\n').append(FormatUtil.format(anU, ",", 4));
+ msg.append('\n').append(FormatUtil.format(anU, ",", FormatUtil.NF4));
}
LOG.debugFine(msg.toString());
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Matrix.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Matrix.java
index 3f513720..6826f67d 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Matrix.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Matrix.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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,7 +31,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Logger;
-import de.lmu.ifi.dbs.elki.data.RationalNumber;
import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
@@ -58,9 +57,15 @@ public class Matrix {
public static final double DELTA = 1E-3;
/**
- * Error: matrix not square.
+ * Small value to increment diagonally of a matrix in order to avoid
+ * singularity before building the inverse.
*/
- public static final String ERR_NOTSQUARE = "All rows must have the same length.";
+ public static final double SINGULARITY_CHEAT = 1E-9;
+
+ /**
+ * Error: matrix not rectangular.
+ */
+ public static final String ERR_NOTRECTANGULAR = "All rows must have the same length.";
/**
* Error: matrix indexes incorrect
@@ -112,8 +117,8 @@ public class Matrix {
public Matrix(final int m, final int n, final double s) {
this.columndimension = n;
elements = new double[m][n];
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < n; j++) {
+ for(int i = 0; i < m; i++) {
+ for(int j = 0; j < n; j++) {
elements[i][j] = s;
}
}
@@ -128,31 +133,15 @@ public class Matrix {
*/
public Matrix(final double[][] elements) {
columndimension = elements[0].length;
- for (int i = 0; i < elements.length; i++) {
- if (elements[i].length != columndimension) {
- throw new IllegalArgumentException(ERR_NOTSQUARE);
+ for(int i = 0; i < elements.length; i++) {
+ if(elements[i].length != columndimension) {
+ throw new IllegalArgumentException(ERR_NOTRECTANGULAR);
}
}
this.elements = elements;
}
/**
- * Constructs a Matrix for a given array of arrays of {@link RationalNumber}s.
- *
- * @param q an array of arrays of RationalNumbers. q is not checked for
- * consistency (i.e. whether all rows are of equal length)
- */
- public Matrix(final RationalNumber[][] q) {
- columndimension = q[0].length;
- elements = new double[q.length][columndimension];
- for (int row = 0; row < q.length; row++) {
- for (int col = 0; col < q[row].length; col++) {
- elements[row][col] = q[row][col].doubleValue();
- }
- }
- }
-
- /**
* Construct a matrix from a one-dimensional packed array
*
* @param values One-dimensional array of doubles, packed by columns (ala
@@ -162,12 +151,12 @@ public class Matrix {
*/
public Matrix(final double values[], final int m) {
columndimension = (m != 0 ? values.length / m : 0);
- if (m * columndimension != values.length) {
+ if(m * columndimension != values.length) {
throw new IllegalArgumentException("Array length must be a multiple of m.");
}
elements = new double[m][columndimension];
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < m; i++) {
+ for(int j = 0; j < columndimension; j++) {
elements[i][j] = values[i + j * m];
}
}
@@ -193,9 +182,9 @@ public class Matrix {
final int m = A.length;
final int n = A[0].length;
final Matrix X = new Matrix(m, n);
- for (int i = 0; i < m; i++) {
- if (A[i].length != n) {
- throw new IllegalArgumentException(ERR_NOTSQUARE);
+ for(int i = 0; i < m; i++) {
+ if(A[i].length != n) {
+ throw new IllegalArgumentException(ERR_NOTRECTANGULAR);
}
System.arraycopy(A[i], 0, X.elements[i], 0, n);
}
@@ -210,7 +199,7 @@ public class Matrix {
*/
public static final Matrix unitMatrix(final int dim) {
final double[][] e = new double[dim][dim];
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
e[i][i] = 1;
}
return new Matrix(e);
@@ -236,8 +225,8 @@ public class Matrix {
*/
public static final Matrix random(final int m, final int n) {
final Matrix A = new Matrix(m, n);
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < n; j++) {
+ for(int i = 0; i < m; i++) {
+ for(int j = 0; j < n; j++) {
A.elements[i][j] = Math.random();
}
}
@@ -253,7 +242,7 @@ public class Matrix {
*/
public static final Matrix identity(final int m, final int n) {
final Matrix A = new Matrix(m, n);
- for (int i = 0; i < Math.min(m, n); i++) {
+ for(int i = 0; i < Math.min(m, n); i++) {
A.elements[i][i] = 1.0;
}
return A;
@@ -268,7 +257,7 @@ public class Matrix {
*/
public static final Matrix diagonal(final double[] diagonal) {
final Matrix result = new Matrix(diagonal.length, diagonal.length);
- for (int i = 0; i < diagonal.length; i++) {
+ for(int i = 0; i < diagonal.length; i++) {
result.elements[i][i] = diagonal[i];
}
return result;
@@ -283,7 +272,7 @@ public class Matrix {
*/
public static final Matrix diagonal(final Vector diagonal) {
final Matrix result = new Matrix(diagonal.elements.length, diagonal.elements.length);
- for (int i = 0; i < diagonal.elements.length; i++) {
+ for(int i = 0; i < diagonal.elements.length; i++) {
result.elements[i][i] = diagonal.elements[i];
}
return result;
@@ -296,7 +285,7 @@ public class Matrix {
*/
public final Matrix copy() {
final Matrix X = new Matrix(elements.length, columndimension);
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
System.arraycopy(elements[i], 0, X.elements[i], 0, columndimension);
}
return X;
@@ -326,7 +315,7 @@ public class Matrix {
*/
public final double[][] getArrayCopy() {
final double[][] C = new double[elements.length][];
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
C[i] = elements[i].clone();
}
return C;
@@ -397,7 +386,7 @@ public class Matrix {
*/
public final double[] getRowPackedCopy() {
double[] vals = new double[elements.length * columndimension];
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
System.arraycopy(elements[i], 0, vals, i * columndimension, columndimension);
}
return vals;
@@ -410,8 +399,8 @@ public class Matrix {
*/
public final double[] getColumnPackedCopy() {
final double[] vals = new double[elements.length * columndimension];
- for (int i = 0; i < elements.length; i++) {
- for (int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < elements.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
vals[i + j * elements.length] = elements[i][j];
}
}
@@ -431,10 +420,11 @@ public class Matrix {
public final Matrix getMatrix(final int i0, final int i1, final int j0, final int j1) {
final Matrix X = new Matrix(i1 - i0 + 1, j1 - j0 + 1);
try {
- for (int i = i0; i <= i1; i++) {
+ for(int i = i0; i <= i1; i++) {
System.arraycopy(elements[i], j0, X.elements[i - i0], 0, j1 - j0 + 1);
}
- } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ catch(ArrayIndexOutOfBoundsException e) {
throw new ArrayIndexOutOfBoundsException(ERR_REINDEX);
}
return X;
@@ -451,12 +441,13 @@ public class Matrix {
public final Matrix getMatrix(final int[] r, final int[] c) {
final Matrix X = new Matrix(r.length, c.length);
try {
- for (int i = 0; i < r.length; i++) {
- for (int j = 0; j < c.length; j++) {
+ for(int i = 0; i < r.length; i++) {
+ for(int j = 0; j < c.length; j++) {
X.elements[i][j] = elements[r[i]][c[j]];
}
}
- } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ catch(ArrayIndexOutOfBoundsException e) {
throw new ArrayIndexOutOfBoundsException(ERR_REINDEX);
}
return X;
@@ -474,10 +465,11 @@ public class Matrix {
public final Matrix getMatrix(final int[] r, final int j0, final int j1) {
final Matrix X = new Matrix(r.length, j1 - j0 + 1);
try {
- for (int i = 0; i < r.length; i++) {
+ for(int i = 0; i < r.length; i++) {
System.arraycopy(elements[r[i]], j0, X.elements[i], 0, j1 - j0 + 1);
}
- } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ catch(ArrayIndexOutOfBoundsException e) {
throw new ArrayIndexOutOfBoundsException(ERR_REINDEX);
}
return X;
@@ -495,12 +487,13 @@ public class Matrix {
public final Matrix getMatrix(final int i0, final int i1, final int[] c) {
final Matrix X = new Matrix(i1 - i0 + 1, c.length);
try {
- for (int i = i0; i <= i1; i++) {
- for (int j = 0; j < c.length; j++) {
+ for(int i = i0; i <= i1; i++) {
+ for(int j = 0; j < c.length; j++) {
X.elements[i - i0][j] = elements[i][c[j]];
}
}
- } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ catch(ArrayIndexOutOfBoundsException e) {
throw new ArrayIndexOutOfBoundsException(ERR_REINDEX);
}
return X;
@@ -518,10 +511,11 @@ public class Matrix {
*/
public final void setMatrix(final int i0, final int i1, final int j0, final int j1, final Matrix X) {
try {
- for (int i = i0; i <= i1; i++) {
+ for(int i = i0; i <= i1; i++) {
System.arraycopy(X.elements[i - i0], 0, elements[i], j0, j1 - j0 + 1);
}
- } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ catch(ArrayIndexOutOfBoundsException e) {
throw new ArrayIndexOutOfBoundsException(ERR_REINDEX);
}
}
@@ -536,12 +530,13 @@ public class Matrix {
*/
public final void setMatrix(final int[] r, final int[] c, final Matrix X) {
try {
- for (int i = 0; i < r.length; i++) {
- for (int j = 0; j < c.length; j++) {
+ for(int i = 0; i < r.length; i++) {
+ for(int j = 0; j < c.length; j++) {
elements[r[i]][c[j]] = X.elements[i][j];
}
}
- } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ catch(ArrayIndexOutOfBoundsException e) {
throw new ArrayIndexOutOfBoundsException(ERR_REINDEX);
}
}
@@ -557,10 +552,11 @@ public class Matrix {
*/
public final void setMatrix(final int[] r, final int j0, final int j1, final Matrix X) {
try {
- for (int i = 0; i < r.length; i++) {
+ for(int i = 0; i < r.length; i++) {
System.arraycopy(X.elements[i], 0, elements[r[i]], j0, j1 - j0 + 1);
}
- } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ catch(ArrayIndexOutOfBoundsException e) {
throw new ArrayIndexOutOfBoundsException(ERR_REINDEX);
}
}
@@ -576,12 +572,13 @@ public class Matrix {
*/
public final void setMatrix(final int i0, final int i1, final int[] c, final Matrix X) {
try {
- for (int i = i0; i <= i1; i++) {
- for (int j = 0; j < c.length; j++) {
+ for(int i = i0; i <= i1; i++) {
+ for(int j = 0; j < c.length; j++) {
elements[i][c[j]] = X.elements[i - i0][j];
}
}
- } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ catch(ArrayIndexOutOfBoundsException e) {
throw new ArrayIndexOutOfBoundsException(ERR_REINDEX);
}
}
@@ -604,7 +601,7 @@ public class Matrix {
* @param row the value of the column to be set
*/
public final void setRow(final int j, final Vector row) {
- if (row.elements.length != columndimension) {
+ if(row.elements.length != columndimension) {
throw new IllegalArgumentException(ERR_MATRIX_DIMENSIONS);
}
System.arraycopy(row.elements, 0, elements[j], 0, columndimension);
@@ -618,7 +615,7 @@ public class Matrix {
*/
public final Vector getCol(final int j) {
final Vector v = new Vector(elements.length);
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
v.elements[i] = elements[i][j];
}
return v;
@@ -631,10 +628,10 @@ public class Matrix {
* @param column the value of the column to be set
*/
public final void setCol(final int j, final Vector column) {
- if (column.elements.length != elements.length) {
+ if(column.elements.length != elements.length) {
throw new IllegalArgumentException(ERR_MATRIX_DIMENSIONS);
}
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
elements[i][j] = column.elements[i];
}
}
@@ -646,8 +643,8 @@ public class Matrix {
*/
public final Matrix transpose() {
final Matrix X = new Matrix(columndimension, elements.length);
- for (int i = 0; i < elements.length; i++) {
- for (int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < elements.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
X.elements[j][i] = elements[i][j];
}
}
@@ -665,6 +662,26 @@ public class Matrix {
}
/**
+ * C = A + s
+ *
+ * @param s scalar value
+ * @return A + s in a new Matrix
+ */
+ public final Matrix plus(final double s) {
+ return copy().plusEquals(s);
+ }
+
+ /**
+ * C = A + s
+ *
+ * @param s scalar value
+ * @return A + s * E in a new Matrix
+ */
+ public final Matrix plusDiagonal(final double s) {
+ return copy().plusDiagonalEquals(s);
+ }
+
+ /**
* C = A + s * B
*
* @param B another matrix
@@ -683,8 +700,8 @@ public class Matrix {
*/
public final Matrix plusEquals(final Matrix B) {
checkMatrixDimensions(B);
- for (int i = 0; i < elements.length; i++) {
- for (int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < elements.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
elements[i][j] += B.elements[i][j];
}
}
@@ -692,6 +709,34 @@ public class Matrix {
}
/**
+ * A = A + s
+ *
+ * @param s constant to add to every cell
+ * @return A + s in this Matrix
+ */
+ public final Matrix plusEquals(final double s) {
+ for(int i = 0; i < elements.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
+ elements[i][j] += s;
+ }
+ }
+ return this;
+ }
+
+ /**
+ * A = A + s
+ *
+ * @param s constant to add to the diagonal
+ * @return A + s in this Matrix
+ */
+ public final Matrix plusDiagonalEquals(final double s) {
+ for(int i = 0; i < elements.length && i < columndimension; i++) {
+ elements[i][i] += s;
+ }
+ return this;
+ }
+
+ /**
* A = A + s * B
*
* @param B another matrix
@@ -700,8 +745,8 @@ public class Matrix {
*/
public final Matrix plusTimesEquals(final Matrix B, final double s) {
checkMatrixDimensions(B);
- for (int i = 0; i < elements.length; i++) {
- for (int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < elements.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
elements[i][j] += s * B.elements[i][j];
}
}
@@ -737,8 +782,8 @@ public class Matrix {
*/
public final Matrix minusEquals(final Matrix B) {
checkMatrixDimensions(B);
- for (int i = 0; i < elements.length; i++) {
- for (int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < elements.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
elements[i][j] -= B.elements[i][j];
}
}
@@ -754,8 +799,8 @@ public class Matrix {
*/
public final Matrix minusTimesEquals(final Matrix B, final double s) {
checkMatrixDimensions(B);
- for (int i = 0; i < elements.length; i++) {
- for (int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < elements.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
elements[i][j] -= s * B.elements[i][j];
}
}
@@ -779,8 +824,8 @@ public class Matrix {
* @return replace A by s*A
*/
public final Matrix timesEquals(final double s) {
- for (int i = 0; i < elements.length; i++) {
- for (int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < elements.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
elements[i][j] *= s;
}
}
@@ -796,22 +841,22 @@ public class Matrix {
*/
public final Matrix times(final Matrix B) {
// Optimized implementation, exploiting the storage layout
- if (B.elements.length != this.columndimension) {
+ if(B.elements.length != this.columndimension) {
throw new IllegalArgumentException(ERR_MATRIX_INNERDIM);
}
final Matrix X = new Matrix(this.elements.length, B.columndimension);
// Optimized ala Jama. jik order.
final double[] Bcolj = new double[this.columndimension];
- for (int j = 0; j < X.columndimension; j++) {
+ for(int j = 0; j < X.columndimension; j++) {
// Make a linear copy of column j from B
- for (int k = 0; k < this.columndimension; k++) {
+ for(int k = 0; k < this.columndimension; k++) {
Bcolj[k] = B.elements[k][j];
}
// multiply it with each row from A
- for (int i = 0; i < this.elements.length; i++) {
+ for(int i = 0; i < this.elements.length; i++) {
final double[] Arowi = this.elements[i];
double s = 0;
- for (int k = 0; k < this.columndimension; k++) {
+ for(int k = 0; k < this.columndimension; k++) {
s += Arowi[k] * Bcolj[k];
}
X.elements[i][j] = s;
@@ -828,15 +873,15 @@ public class Matrix {
* @throws IllegalArgumentException Matrix inner dimensions must agree.
*/
public final Vector times(final Vector B) {
- if (B.elements.length != this.columndimension) {
+ if(B.elements.length != this.columndimension) {
throw new IllegalArgumentException(ERR_MATRIX_INNERDIM);
}
final Vector X = new Vector(this.elements.length);
// multiply it with each row from A
- for (int i = 0; i < this.elements.length; i++) {
+ for(int i = 0; i < this.elements.length; i++) {
final double[] Arowi = this.elements[i];
double s = 0;
- for (int k = 0; k < this.columndimension; k++) {
+ for(int k = 0; k < this.columndimension; k++) {
s += Arowi[k] * B.elements[k];
}
X.elements[i] = s;
@@ -852,14 +897,14 @@ public class Matrix {
* @throws IllegalArgumentException Matrix inner dimensions must agree.
*/
public final Vector transposeTimes(final Vector B) {
- if (B.elements.length != elements.length) {
+ if(B.elements.length != elements.length) {
throw new IllegalArgumentException(ERR_MATRIX_INNERDIM);
}
final Vector X = new Vector(this.columndimension);
// multiply it with each row from A
- for (int i = 0; i < this.columndimension; i++) {
+ for(int i = 0; i < this.columndimension; i++) {
double s = 0;
- for (int k = 0; k < elements.length; k++) {
+ for(int k = 0; k < elements.length; k++) {
s += elements[k][i] * B.elements[k];
}
X.elements[i] = s;
@@ -875,20 +920,20 @@ public class Matrix {
* @throws IllegalArgumentException Matrix inner dimensions must agree.
*/
public final Matrix transposeTimes(final Matrix B) {
- if (B.elements.length != elements.length) {
+ if(B.elements.length != elements.length) {
throw new IllegalArgumentException(ERR_MATRIX_INNERDIM);
}
final Matrix X = new Matrix(this.columndimension, B.columndimension);
final double[] Bcolj = new double[elements.length];
- for (int j = 0; j < X.columndimension; j++) {
+ for(int j = 0; j < X.columndimension; j++) {
// Make a linear copy of column j from B
- for (int k = 0; k < elements.length; k++) {
+ for(int k = 0; k < elements.length; k++) {
Bcolj[k] = B.elements[k][j];
}
// multiply it with each row from A
- for (int i = 0; i < this.columndimension; i++) {
+ for(int i = 0; i < this.columndimension; i++) {
double s = 0;
- for (int k = 0; k < elements.length; k++) {
+ for(int k = 0; k < elements.length; k++) {
s += elements[k][i] * Bcolj[k];
}
X.elements[i][j] = s;
@@ -905,17 +950,17 @@ public class Matrix {
* @throws IllegalArgumentException Matrix inner dimensions must agree.
*/
public final Matrix timesTranspose(final Matrix B) {
- if (B.columndimension != this.columndimension) {
+ if(B.columndimension != this.columndimension) {
throw new IllegalArgumentException(ERR_MATRIX_INNERDIM);
}
final Matrix X = new Matrix(this.elements.length, B.elements.length);
- for (int j = 0; j < X.elements.length; j++) {
+ for(int j = 0; j < X.elements.length; j++) {
final double[] Browj = B.elements[j];
// multiply it with each row from A
- for (int i = 0; i < this.elements.length; i++) {
+ for(int i = 0; i < this.elements.length; i++) {
final double[] Arowi = this.elements[i];
double s = 0;
- for (int k = 0; k < this.columndimension; k++) {
+ for(int k = 0; k < this.columndimension; k++) {
s += Arowi[k] * Browj[k];
}
X.elements[i][j] = s;
@@ -933,23 +978,23 @@ public class Matrix {
*/
public final Matrix transposeTimesTranspose(Matrix B) {
// Optimized implementation, exploiting the storage layout
- if (this.elements.length != B.columndimension) {
+ if(this.elements.length != B.columndimension) {
throw new IllegalArgumentException("Matrix inner dimensions must agree: " + getRowDimensionality() + "," + getColumnDimensionality() + " * " + B.getRowDimensionality() + "," + B.getColumnDimensionality());
}
final Matrix X = new Matrix(this.columndimension, B.elements.length);
// Optimized ala Jama. jik order.
final double[] Acolj = new double[this.elements.length];
- for (int j = 0; j < X.elements.length; j++) {
+ for(int j = 0; j < X.elements.length; j++) {
// Make a linear copy of column j from B
- for (int k = 0; k < this.elements.length; k++) {
+ for(int k = 0; k < this.elements.length; k++) {
Acolj[k] = this.elements[k][j];
}
final double[] Xrow = X.elements[j];
// multiply it with each row from A
- for (int i = 0; i < B.elements.length; i++) {
+ for(int i = 0; i < B.elements.length; i++) {
final double[] Browi = B.elements[i];
double s = 0;
- for (int k = 0; k < B.columndimension; k++) {
+ for(int k = 0; k < B.columndimension; k++) {
s += Browi[k] * Acolj[k];
}
Xrow[i] = s;
@@ -978,6 +1023,19 @@ public class Matrix {
}
/**
+ * Matrix inverse for square matrixes.
+ *
+ * @return inverse(A), or inverse(A + epsilon E) if singular.
+ */
+ public final Matrix robustInverse() {
+ LUDecomposition d = new LUDecomposition(this);
+ if(!d.isNonsingular()) {
+ d = new LUDecomposition(plusDiagonal(SINGULARITY_CHEAT).getArrayRef(), elements.length, columndimension);
+ }
+ return d.solve(identity(elements.length, elements.length));
+ }
+
+ /**
* Matrix determinant
*
* @return determinant
@@ -1011,7 +1069,7 @@ public class Matrix {
*/
public final double trace() {
double t = 0;
- for (int i = 0; i < Math.min(elements.length, columndimension); i++) {
+ for(int i = 0; i < Math.min(elements.length, columndimension); i++) {
t += elements[i][i];
}
return t;
@@ -1024,9 +1082,9 @@ public class Matrix {
*/
public final double norm1() {
double f = 0;
- for (int j = 0; j < columndimension; j++) {
+ for(int j = 0; j < columndimension; j++) {
double s = 0;
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
s += Math.abs(elements[i][j]);
}
f = Math.max(f, s);
@@ -1050,9 +1108,9 @@ public class Matrix {
*/
public final double normInf() {
double f = 0;
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
double s = 0;
- for (int j = 0; j < columndimension; j++) {
+ for(int j = 0; j < columndimension; j++) {
s += Math.abs(elements[i][j]);
}
f = Math.max(f, s);
@@ -1067,8 +1125,8 @@ public class Matrix {
*/
public final double normF() {
double f = 0;
- for (int i = 0; i < elements.length; i++) {
- for (int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < elements.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
f = MathUtil.fastHypot(f, elements[i][j]);
}
}
@@ -1079,14 +1137,14 @@ public class Matrix {
* Normalizes the columns of this matrix to length of 1.0.
*/
public final void normalizeColumns() {
- for (int col = 0; col < columndimension; col++) {
+ for(int col = 0; col < columndimension; col++) {
double norm = 0.0;
- for (int row = 0; row < elements.length; row++) {
+ for(int row = 0; row < elements.length; row++) {
norm = norm + (elements[row][col] * elements[row][col]);
}
norm = Math.sqrt(norm);
- if (norm != 0) {
- for (int row = 0; row < elements.length; row++) {
+ if(norm != 0) {
+ for(int row = 0; row < elements.length; row++) {
elements[row][col] /= norm;
}
}
@@ -1105,13 +1163,13 @@ public class Matrix {
* columns of this matrix
*/
public final boolean linearlyIndependent(final Matrix columnMatrix) {
- if (columnMatrix.columndimension != 1) {
+ if(columnMatrix.columndimension != 1) {
throw new IllegalArgumentException("a.getColumnDimension() != 1");
}
- if (this.elements.length != columnMatrix.elements.length) {
+ if(this.elements.length != columnMatrix.elements.length) {
throw new IllegalArgumentException(ERR_MATRIX_DIMENSIONS);
}
- if (this.columndimension + columnMatrix.columndimension > this.elements.length) {
+ if(this.columndimension + columnMatrix.columndimension > this.elements.length) {
return false;
}
final StringBuilder msg = LoggingConfiguration.DEBUG ? new StringBuilder() : null;
@@ -1119,20 +1177,22 @@ public class Matrix {
final double[][] a = new double[columndimension + 1][elements.length - 1];
final double[] b = new double[columndimension + 1];
- for (int i = 0; i < a.length; i++) {
- for (int j = 0; j < a[i].length; j++) {
- if (i < columndimension) {
+ for(int i = 0; i < a.length; i++) {
+ for(int j = 0; j < a[i].length; j++) {
+ if(i < columndimension) {
a[i][j] = elements[j][i];
- } else {
+ }
+ else {
a[i][j] = columnMatrix.elements[j][0];
}
}
}
- for (int i = 0; i < b.length; i++) {
- if (i < columndimension) {
+ for(int i = 0; i < b.length; i++) {
+ if(i < columndimension) {
b[i] = elements[elements.length - 1][i];
- } else {
+ }
+ else {
b[i] = columnMatrix.elements[i][0];
}
}
@@ -1143,7 +1203,7 @@ public class Matrix {
final double[][] coefficients = les.getCoefficents();
final double[] rhs = les.getRHS();
- if (msg != null) {
+ if(msg != null) {
msg.append("\na' ").append(FormatUtil.format(this.getArrayRef()));
msg.append("\nb' ").append(FormatUtil.format(columnMatrix.getColumnPackedCopy()));
@@ -1152,20 +1212,20 @@ public class Matrix {
msg.append("\nleq ").append(les.equationsToString(4));
}
- for (int i = 0; i < coefficients.length; i++) {
+ for(int i = 0; i < coefficients.length; i++) {
boolean allCoefficientsZero = true;
- for (int j = 0; j < coefficients[i].length; j++) {
+ for(int j = 0; j < coefficients[i].length; j++) {
final double value = coefficients[i][j];
- if (Math.abs(value) > DELTA) {
+ if(Math.abs(value) > DELTA) {
allCoefficientsZero = false;
break;
}
}
// allCoefficients=0 && rhs=0 -> linearly dependent
- if (allCoefficientsZero) {
+ if(allCoefficientsZero) {
final double value = rhs[i];
- if (Math.abs(value) < DELTA) {
- if (msg != null) {
+ if(Math.abs(value) < DELTA) {
+ if(msg != null) {
msg.append("\nvalue ").append(value).append('[').append(i).append(']');
msg.append("\nlinearly independent ").append(false);
Logger.getLogger(this.getClass().getName()).fine(msg.toString());
@@ -1175,7 +1235,7 @@ public class Matrix {
}
}
- if (msg != null) {
+ if(msg != null) {
msg.append("\nlinearly independent ").append(true);
Logger.getLogger(this.getClass().getName()).fine(msg.toString());
}
@@ -1183,128 +1243,17 @@ public class Matrix {
}
/**
- * Returns a matrix derived by Gauss-Jordan-elimination using RationalNumbers
- * for the transformations.
- *
- * @return a matrix derived by Gauss-Jordan-elimination using RationalNumbers
- * for the transformations
- */
- public final Matrix exactGaussJordanElimination() {
- final RationalNumber[][] gauss = exactGaussElimination();
-
- // reduced form
- for (int row = gauss.length - 1; row > 0; row--) {
- int firstCol = -1;
- for (int col = 0; col < gauss[row].length && firstCol == -1; col++) {
- // if(gauss.get(row, col) != 0.0) // i.e. == 1
- if (gauss[row][col].equals(RationalNumber.ONE)) {
- firstCol = col;
- }
- }
- if (firstCol > -1) {
- for (int currentRow = row - 1; currentRow >= 0; currentRow--) {
- RationalNumber multiplier = gauss[currentRow][firstCol].copy();
- for (int col = firstCol; col < gauss[currentRow].length; col++) {
- RationalNumber subtrahent = gauss[row][col].times(multiplier);
- gauss[currentRow][col] = gauss[currentRow][col].minus(subtrahent);
- }
- }
- }
- }
- return new Matrix(gauss);
- }
-
- /**
- * Perform an exact Gauss-elimination of this Matrix using RationalNumbers to
- * yield highest possible accuracy.
- *
- * @return an array of arrays of RationalNumbers representing the
- * Gauss-eliminated form of this Matrix
- */
- private final RationalNumber[][] exactGaussElimination() {
- final RationalNumber[][] gauss = new RationalNumber[elements.length][this.columndimension];
- for (int row = 0; row < elements.length; row++) {
- for (int col = 0; col < this.columndimension; col++) {
- gauss[row][col] = new RationalNumber(elements[row][col]);
- }
- }
- return exactGaussElimination(gauss);
- }
-
- /**
- * Perform recursive Gauss-elimination on the given matrix of RationalNumbers.
- *
- * @param gauss an array of arrays of RationalNumber
- * @return recursive derived Gauss-elimination-form of the given matrix of
- * RationalNumbers
- */
- private static final RationalNumber[][] exactGaussElimination(final RationalNumber[][] gauss) {
- int firstCol = -1;
- int firstRow = -1;
-
- // 1. find first column unequal to zero
- for (int col = 0; col < gauss[0].length && firstCol == -1; col++) {
- for (int row = 0; row < gauss.length && firstCol == -1; row++) {
- // if(gauss.get(row, col) != 0.0)
- if (!gauss[row][col].equals(RationalNumber.ZERO)) {
- firstCol = col;
- firstRow = row;
- }
- }
- }
-
- // 2. set row as first row
- if (firstCol != -1) {
- if (firstRow != 0) {
- final RationalNumber[] row = new RationalNumber[gauss[firstRow].length];
- System.arraycopy(gauss[firstRow], 0, row, 0, gauss[firstRow].length);
- System.arraycopy(gauss[0], 0, gauss[firstRow], 0, gauss[firstRow].length);
- System.arraycopy(row, 0, gauss[0], 0, row.length);
- }
-
- // 3. create leading 1
- if (!gauss[0][firstCol].equals(RationalNumber.ONE)) {
- final RationalNumber inverse = gauss[0][firstCol].multiplicativeInverse();
- for (int col = 0; col < gauss[0].length; col++) {
- gauss[0][col] = gauss[0][col].times(inverse);
- }
- }
-
- // 4. eliminate values unequal to zero below leading 1
- for (int row = 1; row < gauss.length; row++) {
- final RationalNumber multiplier = gauss[row][firstCol].copy();
- // if(multiplier != 0.0)
- if (!multiplier.equals(RationalNumber.ZERO)) {
- for (int col = firstCol; col < gauss[row].length; col++) {
- final RationalNumber subtrahent = gauss[0][col].times(multiplier);
- gauss[row][col] = gauss[row][col].minus(subtrahent);
- }
- }
- }
-
- // 5. recursion
- if (gauss.length > 1) {
- final RationalNumber[][] subMatrix = new RationalNumber[gauss.length - 1][gauss[1].length];
- System.arraycopy(gauss, 1, subMatrix, 0, gauss.length - 1);
- final RationalNumber[][] eliminatedSubMatrix = exactGaussElimination(subMatrix);
- System.arraycopy(eliminatedSubMatrix, 0, gauss, 1, eliminatedSubMatrix.length);
- }
- }
- return gauss;
- }
-
- /**
* Returns true, if this matrix is symmetric, false otherwise.
*
* @return true, if this matrix is symmetric, false otherwise
*/
public final boolean isSymmetric() {
- if (elements.length != columndimension) {
+ if(elements.length != columndimension) {
return false;
}
- for (int i = 0; i < elements.length; i++) {
- for (int j = i + 1; j < columndimension; j++) {
- if (elements[i][j] != elements[j][i]) {
+ for(int i = 0; i < elements.length; i++) {
+ for(int j = i + 1; j < columndimension; j++) {
+ if(elements[i][j] != elements[j][i]) {
return false;
}
}
@@ -1321,16 +1270,17 @@ public class Matrix {
public final Matrix completeBasis() {
Matrix basis = copy();
Matrix result = null;
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
final Matrix e_i = new Matrix(elements.length, 1);
e_i.elements[0][i] = 1.0;
final boolean li = basis.linearlyIndependent(e_i);
// TODO: efficiency - appendColumns is expensive.
- if (li) {
- if (result == null) {
+ if(li) {
+ if(result == null) {
result = e_i.copy();
- } else {
+ }
+ else {
result = result.appendColumns(e_i);
}
basis = basis.appendColumns(e_i);
@@ -1348,16 +1298,17 @@ public class Matrix {
public final Matrix completeToOrthonormalBasis() {
Matrix basis = copy();
Matrix result = null;
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
final Matrix e_i = new Matrix(elements.length, 1);
e_i.elements[i][0] = 1.0;
final boolean li = basis.linearlyIndependent(e_i);
// TODO: efficiency - appendColumns is expensive.
- if (li) {
- if (result == null) {
+ if(li) {
+ if(result == null) {
result = e_i.copy();
- } else {
+ }
+ else {
result = result.appendColumns(e_i);
}
basis = basis.appendColumns(e_i);
@@ -1374,16 +1325,17 @@ public class Matrix {
* @return the new matrix with the appended columns
*/
public final Matrix appendColumns(final Matrix columns) {
- if (elements.length != columns.elements.length) {
+ if(elements.length != columns.elements.length) {
throw new IllegalArgumentException(ERR_MATRIX_DIMENSIONS);
}
final Matrix result = new Matrix(elements.length, columndimension + columns.columndimension);
- for (int i = 0; i < result.columndimension; i++) {
+ for(int i = 0; i < result.columndimension; i++) {
// FIXME: optimize - excess copying!
- if (i < columndimension) {
+ if(i < columndimension) {
result.setCol(i, getCol(i));
- } else {
+ }
+ else {
result.setCol(i, columns.getCol(i - columndimension));
}
}
@@ -1399,10 +1351,10 @@ public class Matrix {
Matrix v = copy();
// FIXME: optimize - excess copying!
- for (int i = 1; i < columndimension; i++) {
+ for(int i = 1; i < columndimension; i++) {
final Vector u_i = getCol(i);
final Vector sum = new Vector(elements.length);
- for (int j = 0; j < i; j++) {
+ for(int j = 0; j < i; j++) {
final Vector v_j = v.getCol(j);
double scalar = u_i.transposeTimes(v_j) / v_j.transposeTimes(v_j);
sum.plusTimesEquals(v_j, scalar);
@@ -1425,7 +1377,7 @@ public class Matrix {
*/
public final Matrix cheatToAvoidSingularity(final double constant) {
final Matrix a = this.copy();
- for (int i = 0; i < a.columndimension && i < a.elements.length; i++) {
+ for(int i = 0; i < a.columndimension && i < a.elements.length; i++) {
// if(a.get(i, i) < constant)
{
a.elements[i][i] += constant;
@@ -1460,40 +1412,40 @@ public class Matrix {
TDoubleArrayList v = new TDoubleArrayList();
// Ignore initial empty lines
- while (tokenizer.nextToken() == StreamTokenizer.TT_EOL) {
+ while(tokenizer.nextToken() == StreamTokenizer.TT_EOL) {
// ignore initial empty lines
}
- if (tokenizer.ttype == StreamTokenizer.TT_EOF) {
+ if(tokenizer.ttype == StreamTokenizer.TT_EOF) {
throw new java.io.IOException("Unexpected EOF on matrix read.");
}
do {
v.add(FormatUtil.parseDouble(tokenizer.sval)); // Read & store 1st
// row.
}
- while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);
+ while(tokenizer.nextToken() == StreamTokenizer.TT_WORD);
int n = v.size(); // Now we've got the number of columns!
double row[] = v.toArray();
ArrayList<double[]> rowV = new ArrayList<>();
rowV.add(row); // Start storing rows instead of columns.
- while (tokenizer.nextToken() == StreamTokenizer.TT_WORD) {
+ while(tokenizer.nextToken() == StreamTokenizer.TT_WORD) {
// While non-empty lines
rowV.add(row = new double[n]);
int j = 0;
do {
- if (j >= n) {
+ if(j >= n) {
throw new java.io.IOException("Row " + v.size() + " is too long.");
}
row[j++] = FormatUtil.parseDouble(tokenizer.sval);
}
- while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);
- if (j < n) {
+ while(tokenizer.nextToken() == StreamTokenizer.TT_WORD);
+ if(j < n) {
throw new java.io.IOException("Row " + v.size() + " is too short.");
}
}
int m = rowV.size(); // Now we've got the number of rows.
double[][] A = new double[m][];
- for (int i = 0; i < m; i++) {
+ for(int i = 0; i < m; i++) {
A[i] = rowV.get(i);
}
return new Matrix(A);
@@ -1503,7 +1455,7 @@ public class Matrix {
* Check if size(A) == size(B)
*/
protected void checkMatrixDimensions(Matrix B) {
- if (B.getRowDimensionality() != getRowDimensionality() || B.getColumnDimensionality() != getColumnDimensionality()) {
+ if(B.getRowDimensionality() != getRowDimensionality() || B.getColumnDimensionality() != getColumnDimensionality()) {
throw new IllegalArgumentException("Matrix dimensions must agree.");
}
}
@@ -1520,25 +1472,25 @@ public class Matrix {
@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;
}
final Matrix other = (Matrix) obj;
- if (this.elements.length != other.elements.length) {
+ if(this.elements.length != other.elements.length) {
return false;
}
- if (this.columndimension != other.columndimension) {
+ if(this.columndimension != other.columndimension) {
return false;
}
- for (int i = 0; i < this.elements.length; i++) {
- for (int j = 0; j < this.columndimension; j++) {
- if (this.elements[i][j] != other.elements[i][j]) {
+ for(int i = 0; i < this.elements.length; i++) {
+ for(int j = 0; j < this.columndimension; j++) {
+ if(this.elements[i][j] != other.elements[i][j]) {
return false;
}
}
@@ -1555,25 +1507,25 @@ public class Matrix {
* @return true if delta smaller than maximum
*/
public boolean almostEquals(Object obj, double maxdelta) {
- 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;
}
final Matrix other = (Matrix) obj;
- if (this.elements.length != other.elements.length) {
+ if(this.elements.length != other.elements.length) {
return false;
}
- if (this.columndimension != other.columndimension) {
+ if(this.columndimension != other.columndimension) {
return false;
}
- for (int i = 0; i < this.elements.length; i++) {
- for (int j = 0; j < this.columndimension; j++) {
- if (Math.abs(this.elements[i][j] - other.elements[i][j]) > maxdelta) {
+ for(int i = 0; i < this.elements.length; i++) {
+ for(int j = 0; j < this.columndimension; j++) {
+ if(Math.abs(this.elements[i][j] - other.elements[i][j]) > maxdelta) {
return false;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectedCentroid.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectedCentroid.java
index a0a1e011..5622daf3 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectedCentroid.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectedCentroid.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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,12 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
+import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
/**
* Centroid only using a subset of dimensions.
@@ -46,7 +45,7 @@ public class ProjectedCentroid extends Centroid {
/**
* The selected dimensions.
*/
- private BitSet dims;
+ private long[] dims;
/**
* Constructor for updating use.
@@ -54,10 +53,9 @@ public class ProjectedCentroid extends Centroid {
* @param dims Dimensions to use (indexed with 0)
* @param dim Full dimensionality
*/
- public ProjectedCentroid(BitSet dims, int dim) {
+ public ProjectedCentroid(long[] dims, int dim) {
super(dim);
this.dims = dims;
- assert (dims.length() <= dim) : (dims.length() + " > " + dim + " ?!?");
}
/**
@@ -69,7 +67,7 @@ public class ProjectedCentroid extends Centroid {
public void put(double[] val) {
assert (val.length == elements.length);
wsum += 1.0;
- for(int i = dims.nextSetBit(0); i >= 0; i = dims.nextSetBit(i + 1)) {
+ for(int i = BitsUtil.nextSetBit(dims, 0); i >= 0; i = BitsUtil.nextSetBit(dims, i + 1)) {
final double delta = val[i] - elements[i];
elements[i] += delta / wsum;
}
@@ -84,11 +82,11 @@ public class ProjectedCentroid extends Centroid {
@Override
public void put(double[] val, double weight) {
assert (val.length == elements.length);
- if (weight == 0) {
+ if(weight == 0) {
return; // Skip zero weights.
}
final double nwsum = weight + wsum;
- for(int i = dims.nextSetBit(0); i >= 0; i = dims.nextSetBit(i + 1)) {
+ for(int i = BitsUtil.nextSetBit(dims, 0); i >= 0; i = BitsUtil.nextSetBit(dims, i + 1)) {
final double delta = val[i] - elements[i];
final double rval = delta * weight / nwsum;
elements[i] += rval;
@@ -102,10 +100,10 @@ public class ProjectedCentroid extends Centroid {
* @param val Value
*/
@Override
- public void put(NumberVector<?> val) {
+ public void put(NumberVector val) {
assert (val.getDimensionality() == elements.length);
wsum += 1.0;
- for(int i = dims.nextSetBit(0); i >= 0; i = dims.nextSetBit(i + 1)) {
+ for(int i = BitsUtil.nextSetBit(dims, 0); i >= 0; i = BitsUtil.nextSetBit(dims, i + 1)) {
final double delta = val.doubleValue(i) - elements[i];
elements[i] += delta / wsum;
}
@@ -118,13 +116,13 @@ public class ProjectedCentroid extends Centroid {
* @param weight weight
*/
@Override
- public void put(NumberVector<?> val, double weight) {
+ public void put(NumberVector val, double weight) {
assert (val.getDimensionality() == elements.length);
- if (weight == 0) {
+ if(weight == 0) {
return; // Skip zero weights.
}
final double nwsum = weight + wsum;
- for(int i = dims.nextSetBit(0); i >= 0; i = dims.nextSetBit(i + 1)) {
+ for(int i = BitsUtil.nextSetBit(dims, 0); i >= 0; i = BitsUtil.nextSetBit(dims, i + 1)) {
final double delta = val.doubleValue(i) - elements[i];
final double rval = delta * weight / nwsum;
elements[i] += rval;
@@ -139,9 +137,8 @@ public class ProjectedCentroid extends Centroid {
* @param relation Relation to process
* @return Centroid
*/
- public static ProjectedCentroid make(BitSet dims, Relation<? extends NumberVector<?>> relation) {
+ public static ProjectedCentroid make(long[] dims, Relation<? extends NumberVector> relation) {
ProjectedCentroid c = new ProjectedCentroid(dims, RelationUtil.dimensionality(relation));
- assert (dims.size() <= RelationUtil.dimensionality(relation));
for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
c.put(relation.get(iditer));
}
@@ -156,9 +153,8 @@ public class ProjectedCentroid extends Centroid {
* @param ids IDs to process
* @return Centroid
*/
- public static ProjectedCentroid make(BitSet dims, Relation<? extends NumberVector<?>> relation, DBIDs ids) {
+ public static ProjectedCentroid make(long[] dims, Relation<? extends NumberVector> relation, DBIDs ids) {
ProjectedCentroid c = new ProjectedCentroid(dims, RelationUtil.dimensionality(relation));
- assert (dims.length() <= RelationUtil.dimensionality(relation));
for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
c.put(relation.get(iter));
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectionResult.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectionResult.java
index 901450c3..523908f3 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectionResult.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/ProjectionResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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/math/linearalgebra/QRDecomposition.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/QRDecomposition.java
index 4b30bf5d..6732f8f8 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/QRDecomposition.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/QRDecomposition.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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/math/linearalgebra/SingularValueDecomposition.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SingularValueDecomposition.java
index dc94754a..0697acaa 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SingularValueDecomposition.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SingularValueDecomposition.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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/math/linearalgebra/SortedEigenPairs.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SortedEigenPairs.java
index 185ae612..61340433 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SortedEigenPairs.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SortedEigenPairs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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/math/linearalgebra/VMath.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/VMath.java
index 6b8cdc31..fc514a65 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/VMath.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/VMath.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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
@@ -75,16 +75,17 @@ public final class VMath {
*/
public static final double[] randomNormalizedVector(final int dimensionality) {
final double[] v = new double[dimensionality];
- for (int i = 0; i < dimensionality; i++) {
+ for(int i = 0; i < dimensionality; i++) {
v[i] = Math.random();
}
double norm = euclideanLength(v);
- if (norm != 0) {
- for (int row = 0; row < v.length; row++) {
+ if(norm != 0) {
+ for(int row = 0; row < v.length; row++) {
v[row] /= norm;
}
return v;
- } else {
+ }
+ else {
return randomNormalizedVector(dimensionality);
}
}
@@ -120,7 +121,7 @@ public final class VMath {
*/
public static final double[][] transpose(final double[] v) {
double[][] re = new double[v.length][1];
- for (int i = 0; i < v.length; i++) {
+ for(int i = 0; i < v.length; i++) {
re[i][0] = v[i];
}
return re;
@@ -136,7 +137,7 @@ public final class VMath {
public static final double[] plus(final double[] v1, final double[] v2) {
assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS;
final double[] result = new double[v1.length];
- for (int i = 0; i < result.length; i++) {
+ for(int i = 0; i < result.length; i++) {
result[i] = v1[i] + v2[i];
}
return result;
@@ -153,7 +154,7 @@ public final class VMath {
public static final double[] plusTimes(final double[] v1, final double[] v2, final double s2) {
assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS;
final double[] result = new double[v1.length];
- for (int i = 0; i < result.length; i++) {
+ for(int i = 0; i < result.length; i++) {
result[i] = v1[i] + v2[i] * s2;
}
return result;
@@ -170,7 +171,7 @@ public final class VMath {
public static final double[] timesPlus(final double[] v1, final double s1, final double[] v2) {
assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS;
final double[] result = new double[v1.length];
- for (int i = 0; i < result.length; i++) {
+ for(int i = 0; i < result.length; i++) {
result[i] = v1[i] * s1 + v2[i];
}
return result;
@@ -188,7 +189,7 @@ public final class VMath {
public static final double[] timesPlusTimes(final double[] v1, final double s1, final double[] v2, final double s2) {
assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS;
final double[] result = new double[v1.length];
- for (int i = 0; i < result.length; i++) {
+ for(int i = 0; i < result.length; i++) {
result[i] = v1[i] * s1 + v2[i] * s2;
}
return result;
@@ -203,7 +204,7 @@ public final class VMath {
*/
public static final double[] plusEquals(final double[] v1, final double[] v2) {
assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS;
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
v1[i] += v2[i];
}
return v1;
@@ -219,7 +220,7 @@ public final class VMath {
*/
public static final double[] plusTimesEquals(final double[] v1, final double[] v2, final double s2) {
assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS;
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
v1[i] += s2 * v2[i];
}
return v1;
@@ -235,7 +236,7 @@ public final class VMath {
*/
public static final double[] timesPlusEquals(final double[] v1, final double s1, final double[] v2) {
assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS;
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
v1[i] = v1[i] * s1 + v2[i];
}
return v1;
@@ -252,7 +253,7 @@ public final class VMath {
*/
public static final double[] timesPlusTimesEquals(final double[] v1, final double s1, final double[] v2, final double s2) {
assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS;
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
v1[i] = v1[i] * s1 + v2[i] * s2;
}
return v1;
@@ -267,7 +268,7 @@ public final class VMath {
*/
public static final double[] plus(final double[] v1, final double d) {
final double[] result = new double[v1.length];
- for (int i = 0; i < result.length; i++) {
+ for(int i = 0; i < result.length; i++) {
result[i] = v1[i] + d;
}
return result;
@@ -281,7 +282,7 @@ public final class VMath {
* @return Modified vector
*/
public static final double[] plusEquals(final double[] v1, final double d) {
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
v1[i] += d;
}
return v1;
@@ -296,7 +297,7 @@ public final class VMath {
*/
public static final double[] minus(final double[] v1, final double[] v2) {
final double[] sub = new double[v1.length];
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
sub[i] = v1[i] - v2[i];
}
return sub;
@@ -312,7 +313,7 @@ public final class VMath {
*/
public static final double[] minusTimes(final double[] v1, final double[] v2, final double s2) {
final double[] sub = new double[v1.length];
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
sub[i] = v1[i] - v2[i] * s2;
}
return sub;
@@ -328,7 +329,7 @@ public final class VMath {
*/
public static final double[] timesMinus(final double[] v1, final double s1, final double[] v2) {
final double[] sub = new double[v1.length];
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
sub[i] = v1[i] * s1 - v2[i];
}
return sub;
@@ -345,7 +346,7 @@ public final class VMath {
*/
public static final double[] timesMinusTimes(final double[] v1, final double s1, final double[] v2, final double s2) {
final double[] sub = new double[v1.length];
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
sub[i] = v1[i] * s1 - v2[i] * s2;
}
return sub;
@@ -360,7 +361,7 @@ public final class VMath {
*/
public static final double[] minusEquals(final double[] v1, final double[] v2) {
assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS;
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
v1[i] -= v2[i];
}
return v1;
@@ -376,7 +377,7 @@ public final class VMath {
*/
public static final double[] minusTimesEquals(final double[] v1, final double[] v2, final double s2) {
assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS;
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
v1[i] -= v2[i] * s2;
}
return v1;
@@ -392,7 +393,7 @@ public final class VMath {
*/
public static final double[] timesMinusEquals(final double[] v1, final double s1, final double[] v2) {
assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS;
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
v1[i] = v1[i] * s1 - v2[i];
}
return v1;
@@ -409,7 +410,7 @@ public final class VMath {
*/
public static final double[] timesMinusTimesEquals(final double[] v1, final double s1, final double[] v2, final double s2) {
assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS;
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
v1[i] = v1[i] * s1 - v2[i] * s2;
}
return v1;
@@ -424,7 +425,7 @@ public final class VMath {
*/
public static final double[] minus(final double[] v1, final double d) {
final double[] result = new double[v1.length];
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
result[i] = v1[i] - d;
}
return result;
@@ -438,7 +439,7 @@ public final class VMath {
* @return v1 = v1 - d
*/
public static final double[] minusEquals(final double[] v1, final double d) {
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
v1[i] -= d;
}
return v1;
@@ -453,7 +454,7 @@ public final class VMath {
*/
public static final double[] times(final double[] v1, final double s1) {
final double[] v = new double[v1.length];
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
v[i] = v1[i] * s1;
}
return v;
@@ -467,7 +468,7 @@ public final class VMath {
* @return v1 = v1 * s1
*/
public static final double[] timesEquals(final double[] v1, final double s) {
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
v1[i] *= s;
}
return v1;
@@ -484,8 +485,8 @@ public final class VMath {
assert (m2.length == 1) : ERR_MATRIX_INNERDIM;
final int columndimension = m2[0].length;
final double[][] re = new double[v1.length][columndimension];
- for (int j = 0; j < columndimension; j++) {
- for (int i = 0; i < v1.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < v1.length; i++) {
re[i][j] = v1[i] * m2[0][j];
}
}
@@ -503,9 +504,9 @@ public final class VMath {
assert (m2.length == v1.length) : ERR_MATRIX_INNERDIM;
final int columndimension = m2[0].length;
final double[][] re = new double[1][columndimension];
- for (int j = 0; j < columndimension; j++) {
+ for(int j = 0; j < columndimension; j++) {
double s = 0;
- for (int k = 0; k < v1.length; k++) {
+ for(int k = 0; k < v1.length; k++) {
s += v1[k] * m2[k][j];
}
re[0][j] = s;
@@ -523,7 +524,7 @@ public final class VMath {
public static final double transposeTimes(final double[] v1, final double[] v2) {
assert (v2.length == v1.length) : ERR_MATRIX_INNERDIM;
double s = 0;
- for (int k = 0; k < v1.length; k++) {
+ for(int k = 0; k < v1.length; k++) {
s += v1[k] * v2[k];
}
return s;
@@ -540,8 +541,8 @@ public final class VMath {
assert (m2[0].length == 1) : ERR_MATRIX_INNERDIM;
final double[][] re = new double[v1.length][m2.length];
- for (int j = 0; j < m2.length; j++) {
- for (int i = 0; i < v1.length; i++) {
+ for(int j = 0; j < m2.length; j++) {
+ for(int i = 0; i < v1.length; i++) {
re[i][j] = v1[i] * m2[j][0];
}
}
@@ -557,8 +558,8 @@ public final class VMath {
*/
public static final double[][] timesTranspose(final double[] v1, final double[] v2) {
final double[][] re = new double[v1.length][v2.length];
- for (int j = 0; j < v2.length; j++) {
- for (int i = 0; i < v1.length; i++) {
+ for(int j = 0; j < v2.length; j++) {
+ for(int i = 0; i < v1.length; i++) {
re[i][j] = v1[i] * v2[j];
}
}
@@ -566,7 +567,8 @@ public final class VMath {
}
/**
- * Returns the scalar product (dot product) of this vector and the specified vector v.
+ * Returns the scalar product (dot product) of this vector and the specified
+ * vector v.
*
* This is the same as transposeTimes.
*
@@ -577,21 +579,36 @@ public final class VMath {
public static final double scalarProduct(final double[] v1, final double[] v2) {
assert (v1.length == v2.length) : ERR_VEC_DIMENSIONS;
double scalarProduct = 0.0;
- for (int row = 0; row < v1.length; row++) {
+ for(int row = 0; row < v1.length; row++) {
scalarProduct += v1[row] * v2[row];
}
return scalarProduct;
}
/**
+ * Squared Euclidean length of the vector
+ *
+ * @param v1 vector
+ * @return squared Euclidean length of this vector
+ */
+ public static final double squareSum(final double[] v1) {
+ double acc = 0.0;
+ for(int row = 0; row < v1.length; row++) {
+ final double v = v1[row];
+ acc += v * v;
+ }
+ return acc;
+ }
+
+ /**
* Euclidean length of the vector
*
* @param v1 vector
- * @return euclidean length of this vector
+ * @return Euclidean length of this vector
*/
public static final double euclideanLength(final double[] v1) {
double acc = 0.0;
- for (int row = 0; row < v1.length; row++) {
+ for(int row = 0; row < v1.length; row++) {
final double v = v1[row];
acc += v * v;
}
@@ -607,8 +624,8 @@ public final class VMath {
public static final double[] normalize(final double[] v1) {
double norm = euclideanLength(v1);
double[] re = new double[v1.length];
- if (norm != 0) {
- for (int row = 0; row < v1.length; row++) {
+ if(norm != 0) {
+ for(int row = 0; row < v1.length; row++) {
re[row] = v1[row] / norm;
}
}
@@ -623,8 +640,8 @@ public final class VMath {
*/
public static final double[] normalizeEquals(final double[] v1) {
double norm = euclideanLength(v1);
- if (norm != 0) {
- for (int row = 0; row < v1.length; row++) {
+ if(norm != 0) {
+ for(int row = 0; row < v1.length; row++) {
v1[row] /= norm;
}
}
@@ -643,7 +660,7 @@ public final class VMath {
final int columndimension = m2[0].length;
double[] sum = new double[v1.length];
- for (int i = 0; i < columndimension; i++) {
+ for(int i = 0; i < columndimension; i++) {
// TODO: optimize - copy less.
double[] v_i = getCol(m2, i);
plusTimesEquals(sum, v_i, scalarProduct(v1, v_i));
@@ -705,7 +722,7 @@ public final class VMath {
*/
public static final double[][] unitMatrix(final int dim) {
final double[][] e = new double[dim][dim];
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
e[i][i] = 1;
}
return e;
@@ -731,8 +748,8 @@ public final class VMath {
*/
public static final double[][] random(final int m, final int n) {
final double[][] A = new double[m][n];
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < n; j++) {
+ for(int i = 0; i < m; i++) {
+ for(int j = 0; j < n; j++) {
A[i][j] = Math.random();
}
}
@@ -748,7 +765,7 @@ public final class VMath {
*/
public static final double[][] identity(final int m, final int n) {
final double[][] A = new double[m][n];
- for (int i = 0; i < Math.min(m, n); i++) {
+ for(int i = 0; i < Math.min(m, n); i++) {
A[i][i] = 1.0;
}
return A;
@@ -763,7 +780,7 @@ public final class VMath {
*/
public static final double[][] diagonal(final double[] v1) {
final double[][] result = new double[v1.length][v1.length];
- for (int i = 0; i < v1.length; i++) {
+ for(int i = 0; i < v1.length; i++) {
result[i][i] = v1[i];
}
return result;
@@ -778,7 +795,7 @@ public final class VMath {
public static final double[][] copy(final double[][] m1) {
final int columndimension = m1[0].length;
final double[][] X = new double[m1.length][columndimension];
- for (int i = 0; i < m1.length; i++) {
+ for(int i = 0; i < m1.length; i++) {
System.arraycopy(m1[i], 0, X[i], 0, columndimension);
}
return X;
@@ -793,7 +810,7 @@ public final class VMath {
public static final double[] rowPackedCopy(final double[][] m1) {
final int columndimension = m1[0].length;
double[] vals = new double[m1.length * columndimension];
- for (int i = 0; i < m1.length; i++) {
+ for(int i = 0; i < m1.length; i++) {
System.arraycopy(m1[i], 0, vals, i * columndimension, columndimension);
}
return vals;
@@ -808,8 +825,8 @@ public final class VMath {
public static final double[] columnPackedCopy(final double[][] m1) {
final int columndimension = m1[0].length;
final double[] vals = new double[m1.length * columndimension];
- for (int i = 0; i < m1.length; i++) {
- for (int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < m1.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
vals[i + j * m1.length] = m1[i][j];
}
}
@@ -828,7 +845,7 @@ public final class VMath {
*/
public static final double[][] getMatrix(final double[][] m1, final int r0, final int r1, final int c0, final int c1) {
final double[][] X = new double[r1 - r0 + 1][c1 - c0 + 1];
- for (int i = r0; i <= r1; i++) {
+ for(int i = r0; i <= r1; i++) {
System.arraycopy(m1[i], c0, X[i - r0], 0, c1 - c0 + 1);
}
return X;
@@ -844,8 +861,8 @@ public final class VMath {
*/
public static final double[][] getMatrix(final double[][] m1, final int[] r, final int[] c) {
final double[][] X = new double[r.length][c.length];
- for (int i = 0; i < r.length; i++) {
- for (int j = 0; j < c.length; j++) {
+ for(int i = 0; i < r.length; i++) {
+ for(int j = 0; j < c.length; j++) {
X[i][j] = m1[r[i]][c[j]];
}
}
@@ -863,7 +880,7 @@ public final class VMath {
*/
public static final double[][] getMatrix(final double[][] m1, final int[] r, final int c0, final int c1) {
final double[][] X = new double[r.length][c1 - c0 + 1];
- for (int i = 0; i < r.length; i++) {
+ for(int i = 0; i < r.length; i++) {
System.arraycopy(m1[r[i]], c0, X[i], 0, c1 - c0 + 1);
}
return X;
@@ -880,8 +897,8 @@ public final class VMath {
*/
public static final double[][] getMatrix(final double[][] m1, final int r0, final int r1, final int[] c) {
final double[][] X = new double[r1 - r0 + 1][c.length];
- for (int i = r0; i <= r1; i++) {
- for (int j = 0; j < c.length; j++) {
+ for(int i = r0; i <= r1; i++) {
+ for(int j = 0; j < c.length; j++) {
X[i - r0][j] = m1[i][c[j]];
}
}
@@ -899,7 +916,7 @@ public final class VMath {
* @param m2 New values for m1(r0:r1,c0:c1)
*/
public static final void setMatrix(final double[][] m1, final int r0, final int r1, final int c0, final int c1, final double[][] m2) {
- for (int i = r0; i <= r1; i++) {
+ for(int i = r0; i <= r1; i++) {
System.arraycopy(m2[i - r0], 0, m1[i], c0, c1 - c0 + 1);
}
}
@@ -913,8 +930,8 @@ public final class VMath {
* @param m2 New values for m1(r(:),c(:))
*/
public static final void setMatrix(final double[][] m1, final int[] r, final int[] c, final double[][] m2) {
- for (int i = 0; i < r.length; i++) {
- for (int j = 0; j < c.length; j++) {
+ for(int i = 0; i < r.length; i++) {
+ for(int j = 0; j < c.length; j++) {
m1[r[i]][c[j]] = m2[i][j];
}
}
@@ -930,7 +947,7 @@ public final class VMath {
* @param m2 New values for m1(r(:),c0:c1)
*/
public static final void setMatrix(final double[][] m1, final int[] r, final int c0, final int c1, final double[][] m2) {
- for (int i = 0; i < r.length; i++) {
+ for(int i = 0; i < r.length; i++) {
System.arraycopy(m2[i], 0, m1[r[i]], c0, c1 - c0 + 1);
}
}
@@ -945,8 +962,8 @@ public final class VMath {
* @param m2 New values for m1(r0:r1,c(:))
*/
public static final void setMatrix(final double[][] m1, final int r0, final int r1, final int[] c, final double[][] m2) {
- for (int i = r0; i <= r1; i++) {
- for (int j = 0; j < c.length; j++) {
+ for(int i = r0; i <= r1; i++) {
+ for(int j = 0; j < c.length; j++) {
m1[i][c[j]] = m2[i - r0][j];
}
}
@@ -985,7 +1002,7 @@ public final class VMath {
*/
public static final double[] getCol(double[][] m1, int col) {
double[] ret = new double[m1.length];
- for (int i = 0; i < ret.length; i++) {
+ for(int i = 0; i < ret.length; i++) {
ret[i] = m1[i][col];
}
return ret;
@@ -1000,7 +1017,7 @@ public final class VMath {
*/
public static final void setCol(final double[][] m1, final int c, final double[] column) {
assert (column.length == m1.length) : ERR_DIMENSIONS;
- for (int i = 0; i < m1.length; i++) {
+ for(int i = 0; i < m1.length; i++) {
m1[i][c] = column[i];
}
}
@@ -1014,8 +1031,8 @@ public final class VMath {
public static final double[][] transpose(final double[][] m1) {
final int columndimension = getColumnDimensionality(m1);
final double[][] re = new double[columndimension][m1.length];
- for (int i = 0; i < m1.length; i++) {
- for (int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < m1.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
re[j][i] = m1[i][j];
}
}
@@ -1055,8 +1072,8 @@ public final class VMath {
public static final double[][] plusEquals(final double[][] m1, final double[][] m2) {
final int columndimension = getColumnDimensionality(m1);
assert (getRowDimensionality(m1) == getRowDimensionality(m2) && columndimension == getColumnDimensionality(m2)) : ERR_MATRIX_DIMENSIONS;
- for (int i = 0; i < m1.length; i++) {
- for (int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < m1.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
m1[i][j] += m2[i][j];
}
}
@@ -1074,8 +1091,8 @@ public final class VMath {
public static final double[][] plusTimesEquals(final double[][] m1, final double[][] m2, final double s2) {
final int columndimension = getColumnDimensionality(m1);
assert (getRowDimensionality(m1) == getRowDimensionality(m2) && columndimension == getColumnDimensionality(m2)) : ERR_MATRIX_DIMENSIONS;
- for (int i = 0; i < m1.length; i++) {
- for (int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < m1.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
m1[i][j] += s2 * m2[i][j];
}
}
@@ -1115,8 +1132,8 @@ public final class VMath {
public static final double[][] minusEquals(final double[][] m1, final double[][] m2) {
final int columndimension = getColumnDimensionality(m1);
assert (getRowDimensionality(m1) == getRowDimensionality(m2) && columndimension == getColumnDimensionality(m2)) : ERR_MATRIX_DIMENSIONS;
- for (int i = 0; i < m1.length; i++) {
- for (int j = 0; j < columndimension; j++) {
+ for(int i = 0; i < m1.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
m1[i][j] -= m2[i][j];
}
}
@@ -1133,10 +1150,10 @@ public final class VMath {
*/
public static final double[][] minusTimesEquals(final double[][] m1, final double[][] m2, final double s2) {
assert (getRowDimensionality(m1) == getRowDimensionality(m2) && getColumnDimensionality(m1) == getColumnDimensionality(m2)) : ERR_MATRIX_DIMENSIONS;
- for (int i = 0; i < m1.length; i++) {
+ for(int i = 0; i < m1.length; i++) {
final double[] row1 = m1[i];
final double[] row2 = m2[i];
- for (int j = 0; j < row1.length; j++) {
+ for(int j = 0; j < row1.length; j++) {
row1[j] -= s2 * row2[j];
}
}
@@ -1162,9 +1179,9 @@ public final class VMath {
* @return m1 = s1 * m1, overwriting m1
*/
public static final double[][] timesEquals(final double[][] m1, final double s1) {
- for (int i = 0; i < m1.length; i++) {
+ for(int i = 0; i < m1.length; i++) {
final double[] row = m1[i];
- for (int j = 0; j < row.length; j++) {
+ for(int j = 0; j < row.length; j++) {
row[j] *= s1;
}
}
@@ -1186,17 +1203,17 @@ public final class VMath {
final double[][] r2 = new double[m1.length][bcolumndimension];
// Optimized ala Jama. jik order.
final double[] Bcolj = new double[columndimension];
- for (int j = 0; j < bcolumndimension; j++) {
+ for(int j = 0; j < bcolumndimension; j++) {
// Make a linear copy of column j from B
// TODO: use column getter from B?
- for (int k = 0; k < columndimension; k++) {
+ for(int k = 0; k < columndimension; k++) {
Bcolj[k] = m2[k][j];
}
// multiply it with each row from A
- for (int i = 0; i < m1.length; i++) {
+ for(int i = 0; i < m1.length; i++) {
final double[] Arowi = m1[i];
double s = 0;
- for (int k = 0; k < columndimension; k++) {
+ for(int k = 0; k < columndimension; k++) {
s += Arowi[k] * Bcolj[k];
}
r2[i][j] = s;
@@ -1216,10 +1233,10 @@ public final class VMath {
assert (v2.length == getColumnDimensionality(m1)) : ERR_MATRIX_INNERDIM;
final double[] re = new double[m1.length];
// multiply it with each row from A
- for (int i = 0; i < m1.length; i++) {
+ for(int i = 0; i < m1.length; i++) {
final double[] Arowi = m1[i];
double s = 0;
- for (int k = 0; k < Arowi.length; k++) {
+ for(int k = 0; k < Arowi.length; k++) {
s += Arowi[k] * v2[k];
}
re[i] = s;
@@ -1239,9 +1256,9 @@ public final class VMath {
assert (v2.length == m1.length) : ERR_MATRIX_INNERDIM;
final double[] re = new double[columndimension];
// multiply it with each row from A
- for (int i = 0; i < columndimension; i++) {
+ for(int i = 0; i < columndimension; i++) {
double s = 0;
- for (int k = 0; k < m1.length; k++) {
+ for(int k = 0; k < m1.length; k++) {
s += m1[k][i] * v2[k];
}
re[i] = s;
@@ -1262,15 +1279,15 @@ public final class VMath {
assert (m2.length == m1.length) : ERR_MATRIX_INNERDIM;
final double[][] re = new double[coldim1][coldim2];
final double[] Bcolj = new double[m1.length];
- for (int j = 0; j < coldim2; j++) {
+ for(int j = 0; j < coldim2; j++) {
// Make a linear copy of column j from B
- for (int k = 0; k < m1.length; k++) {
+ for(int k = 0; k < m1.length; k++) {
Bcolj[k] = m2[k][j];
}
// multiply it with each row from A
- for (int i = 0; i < coldim1; i++) {
+ for(int i = 0; i < coldim1; i++) {
double s = 0;
- for (int k = 0; k < m1.length; k++) {
+ for(int k = 0; k < m1.length; k++) {
s += m1[k][i] * Bcolj[k];
}
re[i][j] = s;
@@ -1282,6 +1299,7 @@ public final class VMath {
/**
* Linear algebraic matrix multiplication, a<sup>T</sup> * B * c
*
+ * @param a vector on the left
* @param B matrix
* @param c vector on the right
* @return Matrix product, a<sup>T</sup> * B * c
@@ -1289,10 +1307,10 @@ public final class VMath {
public static double transposeTimesTimes(final double[] a, final double[][] B, final double[] c) {
assert (B.length == a.length) : ERR_MATRIX_INNERDIM;
double sum = 0.0;
- for (int j = 0; j < B[0].length; j++) {
+ for(int j = 0; j < B[0].length; j++) {
// multiply it with each row from A
double s = 0;
- for (int k = 0; k < a.length; k++) {
+ for(int k = 0; k < a.length; k++) {
s += a[k] * B[k][j];
}
sum += s * c[j];
@@ -1310,13 +1328,13 @@ public final class VMath {
public static final double[][] timesTranspose(final double[][] m1, final double[][] m2) {
assert (getColumnDimensionality(m2) == getColumnDimensionality(m1)) : ERR_MATRIX_INNERDIM;
final double[][] re = new double[m1.length][m2.length];
- for (int j = 0; j < re.length; j++) {
+ for(int j = 0; j < re.length; j++) {
final double[] Browj = m2[j];
// multiply it with each row from A
- for (int i = 0; i < m1.length; i++) {
+ for(int i = 0; i < m1.length; i++) {
final double[] Arowi = m1[i];
double s = 0;
- for (int k = 0; k < Browj.length; k++) {
+ for(int k = 0; k < Browj.length; k++) {
s += Arowi[k] * Browj[k];
}
re[i][j] = s;
@@ -1338,17 +1356,17 @@ public final class VMath {
final double[][] re = new double[getColumnDimensionality(m1)][m2.length];
// Optimized ala Jama. jik order.
final double[] Acolj = new double[m1.length];
- for (int j = 0; j < re.length; j++) {
+ for(int j = 0; j < re.length; j++) {
// Make a linear copy of column j from B
- for (int k = 0; k < m1.length; k++) {
+ for(int k = 0; k < m1.length; k++) {
Acolj[k] = m1[k][j];
}
final double[] Xrow = re[j];
// multiply it with each row from A
- for (int i = 0; i < m2.length; i++) {
+ for(int i = 0; i < m2.length; i++) {
final double[] Browi = m2[i];
double s = 0;
- for (int k = 0; k < m1.length; k++) {
+ for(int k = 0; k < m1.length; k++) {
s += Browi[k] * Acolj[k];
}
Xrow[i] = s;
@@ -1358,6 +1376,28 @@ public final class VMath {
}
/**
+ * Linear algebraic matrix multiplication, (a-c)<sup>T</sup> * B * (a-c)
+ *
+ * @param B matrix
+ * @param a First vector
+ * @param c Center vector
+ * @return Matrix product, (a-c)<sup>T</sup> * B * (a-c)
+ */
+ public static double mahalanobisDistance(final double[][] B, final double[] a, final double[] c) {
+ assert (B.length == a.length && a.length == c.length) : ERR_MATRIX_INNERDIM;
+ double sum = 0.0;
+ for(int j = 0; j < B[0].length; j++) {
+ // multiply it with each row from A
+ double s = 0;
+ for(int k = 0; k < a.length; k++) {
+ s += (a[k] - c[k]) * B[k][j];
+ }
+ sum += s * (a[j] - c[j]);
+ }
+ return sum;
+ }
+
+ /**
* getDiagonal returns array of diagonal-elements.
*
* @param m1 Input matrix
@@ -1366,7 +1406,7 @@ public final class VMath {
public static final double[] getDiagonal(final double[][] m1) {
final int dim = Math.min(getColumnDimensionality(m1), m1.length);
final double[] diagonal = new double[dim];
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
diagonal[i] = m1[i][i];
}
return diagonal;
@@ -1379,17 +1419,18 @@ public final class VMath {
*/
public static final void normalizeColumns(final double[][] m1) {
final int columndimension = getColumnDimensionality(m1);
- for (int col = 0; col < columndimension; col++) {
+ for(int col = 0; col < columndimension; col++) {
double norm = 0.0;
- for (int row = 0; row < m1.length; row++) {
+ for(int row = 0; row < m1.length; row++) {
norm = norm + (m1[row][col] * m1[row][col]);
}
norm = Math.sqrt(norm);
- if (norm != 0) {
- for (int row = 0; row < m1.length; row++) {
+ if(norm != 0) {
+ for(int row = 0; row < m1.length; row++) {
m1[row][col] /= norm;
}
- } else {
+ }
+ else {
// TODO: else: throw an exception?
}
}
@@ -1409,11 +1450,12 @@ public final class VMath {
final int rcolumndimension = columndimension + ccolumndimension;
final double[][] result = new double[m1.length][rcolumndimension];
- for (int i = 0; i < rcolumndimension; i++) {
+ for(int i = 0; i < rcolumndimension; i++) {
// FIXME: optimize - excess copying!
- if (i < columndimension) {
+ if(i < columndimension) {
setCol(result, i, getCol(m1, i));
- } else {
+ }
+ else {
setCol(result, i, getCol(m2, i - columndimension));
}
}
@@ -1431,10 +1473,10 @@ public final class VMath {
double[][] v = copy(m1);
// FIXME: optimize - excess copying!
- for (int i = 1; i < columndimension; i++) {
+ for(int i = 1; i < columndimension; i++) {
final double[] u_i = getCol(m1, i);
final double[] sum = new double[m1.length];
- for (int j = 0; j < i; j++) {
+ for(int j = 0; j < i; j++) {
final double[] v_j = getCol(v, j);
double scalar = scalarProduct(u_i, v_j) / scalarProduct(v_j, v_j);
plusEquals(sum, times(v_j, scalar));
@@ -1478,25 +1520,25 @@ public final class VMath {
* @return true if delta smaller than maximum
*/
public static final boolean almostEquals(final double[][] m1, final double[][] m2, final double maxdelta) {
- if (m1 == m2) {
+ if(m1 == m2) {
return true;
}
- if (m2 == null) {
+ if(m2 == null) {
return false;
}
- if (m1.getClass() != m2.getClass()) {
+ if(m1.getClass() != m2.getClass()) {
return false;
}
- if (m1.length != m2.length) {
+ if(m1.length != m2.length) {
return false;
}
final int columndimension = getColumnDimensionality(m1);
- if (columndimension != getColumnDimensionality(m2)) {
+ if(columndimension != getColumnDimensionality(m2)) {
return false;
}
- for (int i = 0; i < m1.length; i++) {
- for (int j = 0; j < columndimension; j++) {
- if (Math.abs(m1[i][j] - m2[i][j]) > maxdelta) {
+ for(int i = 0; i < m1.length; i++) {
+ for(int j = 0; j < columndimension; j++) {
+ if(Math.abs(m1[i][j] - m2[i][j]) > maxdelta) {
return false;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Vector.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Vector.java
index eca1dbea..36ab94dc 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Vector.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Vector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
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,19 +23,46 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.io.IOException;
+import java.nio.ByteBuffer;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
/**
- * Provides a vector object that encapsulates an m x 1 - matrix object.
+ * A mathematical vector object, along with mathematical operations.
*
* @author Elke Achtert
*
* @apiviz.landmark
*/
-public class Vector implements NumberVector<Double> {
+public class Vector implements NumberVector {
+ /**
+ * Static vector factory.
+ */
+ public static final Factory FACTORY = new Factory();
+
+ /**
+ * Serializer for up to 127 dimensions.
+ */
+ public static final ByteBufferSerializer<Vector> BYTE_SERIALIZER = new SmallSerializer();
+
+ /**
+ * Serializer for up to 2^15-1 dimensions.
+ */
+ public static final ByteBufferSerializer<Vector> SHORT_SERIALIZER = new ShortSerializer();
+
+ /**
+ * Serializer using varint encoding.
+ */
+ public static final ByteBufferSerializer<Vector> VARIABLE_SERIALIZER = new VariableSerializer();
+
/**
* Array for internal storage of elements.
*
@@ -68,7 +95,7 @@ public class Vector implements NumberVector<Double> {
}
/**
- * Provides an m x 1 vector.
+ * Constructor
*
* @param m the number of rows
*/
@@ -85,13 +112,13 @@ public class Vector implements NumberVector<Double> {
public static final Vector randomNormalizedVector(final int dimensionality) {
final Vector v = new Vector(dimensionality);
double norm = 0;
- while (norm <= 0) {
- for (int i = 0; i < dimensionality; i++) {
+ while(norm <= 0) {
+ for(int i = 0; i < dimensionality; i++) {
v.elements[i] = Math.random();
}
norm = v.euclideanLength();
}
- for (int row = 0; row < dimensionality; row++) {
+ for(int row = 0; row < dimensionality; row++) {
v.elements[row] /= norm;
}
return v;
@@ -185,7 +212,7 @@ public class Vector implements NumberVector<Double> {
public final Vector plus(final Vector v) {
assert (this.elements.length == v.elements.length) : ERR_VEC_DIMENSIONS;
final Vector result = new Vector(elements.length);
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
result.elements[i] = elements[i] + v.elements[i];
}
return result;
@@ -202,7 +229,7 @@ public class Vector implements NumberVector<Double> {
public final Vector plusTimes(final Vector v, final double s) {
assert (this.elements.length == v.elements.length) : ERR_VEC_DIMENSIONS;
final Vector result = new Vector(elements.length);
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
result.elements[i] = elements[i] + v.elements[i] * s;
}
return result;
@@ -216,7 +243,7 @@ public class Vector implements NumberVector<Double> {
*/
public final Vector plusEquals(final Vector b) {
assert (this.elements.length == b.elements.length) : ERR_VEC_DIMENSIONS;
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
elements[i] += b.elements[i];
}
return this;
@@ -231,7 +258,7 @@ public class Vector implements NumberVector<Double> {
*/
public final Vector plusTimesEquals(final Vector b, final double s) {
assert (this.elements.length == b.elements.length) : ERR_VEC_DIMENSIONS;
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
elements[i] += s * b.elements[i];
}
return this;
@@ -244,7 +271,7 @@ public class Vector implements NumberVector<Double> {
* @return Modified vector
*/
public final Vector plusEquals(final double d) {
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
elements[i] += d;
}
return this;
@@ -258,7 +285,7 @@ public class Vector implements NumberVector<Double> {
*/
public final Vector minus(final Vector v) {
final Vector sub = new Vector(elements.length);
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
sub.elements[i] = elements[i] - v.elements[i];
}
return sub;
@@ -273,7 +300,7 @@ public class Vector implements NumberVector<Double> {
*/
public final Vector minusTimes(final Vector v, final double s) {
final Vector sub = new Vector(elements.length);
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
sub.elements[i] = elements[i] - v.elements[i] * s;
}
return sub;
@@ -287,7 +314,7 @@ public class Vector implements NumberVector<Double> {
*/
public final Vector minusEquals(final Vector b) {
assert (this.elements.length == b.elements.length) : ERR_VEC_DIMENSIONS;
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
elements[i] -= b.elements[i];
}
return this;
@@ -302,7 +329,7 @@ public class Vector implements NumberVector<Double> {
*/
public final Vector minusTimesEquals(final Vector b, final double s) {
assert (this.elements.length == b.elements.length) : ERR_VEC_DIMENSIONS;
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
elements[i] -= s * b.elements[i];
}
return this;
@@ -315,7 +342,7 @@ public class Vector implements NumberVector<Double> {
* @return Modified vector
*/
public final Vector minusEquals(final double d) {
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
elements[i] -= d;
}
return this;
@@ -330,7 +357,7 @@ public class Vector implements NumberVector<Double> {
*/
public final Vector times(final double s) {
final Vector v = new Vector(elements.length);
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
v.elements[i] = elements[i] * s;
}
return v;
@@ -343,7 +370,7 @@ public class Vector implements NumberVector<Double> {
* @return replace A by s*A
*/
public final Vector timesEquals(final double s) {
- for (int i = 0; i < elements.length; i++) {
+ for(int i = 0; i < elements.length; i++) {
elements[i] *= s;
}
return this;
@@ -358,8 +385,8 @@ public class Vector implements NumberVector<Double> {
public final Matrix times(final Matrix B) {
assert (B.elements.length == 1) : ERR_MATRIX_INNERDIM;
final Matrix X = new Matrix(this.elements.length, B.columndimension);
- for (int j = 0; j < B.columndimension; j++) {
- for (int i = 0; i < this.elements.length; i++) {
+ for(int j = 0; j < B.columndimension; j++) {
+ for(int i = 0; i < this.elements.length; i++) {
X.elements[i][j] = elements[i] * B.elements[0][j];
}
}
@@ -375,10 +402,10 @@ public class Vector implements NumberVector<Double> {
public final Matrix transposeTimes(final Matrix B) {
assert (B.elements.length == this.elements.length) : ERR_MATRIX_INNERDIM;
final Matrix X = new Matrix(1, B.columndimension);
- for (int j = 0; j < B.columndimension; j++) {
+ for(int j = 0; j < B.columndimension; j++) {
// multiply it with each row from A
double s = 0;
- for (int k = 0; k < this.elements.length; k++) {
+ for(int k = 0; k < this.elements.length; k++) {
s += this.elements[k] * B.elements[k][j];
}
X.elements[0][j] = s;
@@ -396,10 +423,10 @@ public class Vector implements NumberVector<Double> {
public final double transposeTimesTimes(final Matrix B, final Vector c) {
assert (B.elements.length == this.elements.length) : ERR_MATRIX_INNERDIM;
double sum = 0.0;
- for (int j = 0; j < B.columndimension; j++) {
+ for(int j = 0; j < B.columndimension; j++) {
// multiply it with each row from A
double s = 0;
- for (int k = 0; k < this.elements.length; k++) {
+ for(int k = 0; k < this.elements.length; k++) {
s += this.elements[k] * B.elements[k][j];
}
sum += s * c.elements[j];
@@ -416,7 +443,7 @@ public class Vector implements NumberVector<Double> {
public final double transposeTimes(final Vector B) {
assert (B.elements.length == this.elements.length) : ERR_MATRIX_INNERDIM;
double s = 0;
- for (int k = 0; k < this.elements.length; k++) {
+ for(int k = 0; k < this.elements.length; k++) {
s += this.elements[k] * B.elements[k];
}
return s;
@@ -431,8 +458,8 @@ public class Vector implements NumberVector<Double> {
public final Matrix timesTranspose(final Matrix B) {
assert (B.columndimension == 1) : ERR_MATRIX_INNERDIM;
final Matrix X = new Matrix(this.elements.length, B.elements.length);
- for (int j = 0; j < B.elements.length; j++) {
- for (int i = 0; i < this.elements.length; i++) {
+ for(int j = 0; j < B.elements.length; j++) {
+ for(int i = 0; i < this.elements.length; i++) {
X.elements[i][j] = elements[i] * B.elements[j][0];
}
}
@@ -447,8 +474,8 @@ public class Vector implements NumberVector<Double> {
*/
public final Matrix timesTranspose(final Vector B) {
final Matrix X = new Matrix(this.elements.length, B.elements.length);
- for (int j = 0; j < B.elements.length; j++) {
- for (int i = 0; i < this.elements.length; i++) {
+ for(int j = 0; j < B.elements.length; j++) {
+ for(int i = 0; i < this.elements.length; i++) {
X.elements[i][j] = elements[i] * B.elements[j];
}
}
@@ -462,7 +489,7 @@ public class Vector implements NumberVector<Double> {
*/
public final double euclideanLength() {
double acc = 0.0;
- for (int row = 0; row < elements.length; row++) {
+ for(int row = 0; row < elements.length; row++) {
final double v = elements[row];
acc += v * v;
}
@@ -476,8 +503,8 @@ public class Vector implements NumberVector<Double> {
*/
public final Vector normalize() {
double norm = euclideanLength();
- if (norm != 0) {
- for (int row = 0; row < elements.length; row++) {
+ if(norm != 0) {
+ for(int row = 0; row < elements.length; row++) {
elements[row] /= norm;
}
}
@@ -494,7 +521,7 @@ public class Vector implements NumberVector<Double> {
public final Vector projection(final Matrix v) {
assert (elements.length == v.elements.length) : ERR_DIMENSIONS;
Vector sum = new Vector(elements.length);
- for (int i = 0; i < v.columndimension; i++) {
+ for(int i = 0; i < v.columndimension; i++) {
// TODO: optimize - copy less?
Vector v_i = v.getCol(i);
sum.plusTimesEquals(v_i, this.transposeTimes(v_i));
@@ -509,17 +536,17 @@ public class Vector implements NumberVector<Double> {
@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;
}
final Vector other = (Vector) obj;
- if (this.elements.length != other.elements.length) {
+ if(this.elements.length != other.elements.length) {
return false;
}
return Arrays.equals(this.elements, other.elements);
@@ -632,4 +659,159 @@ public class Vector implements NumberVector<Double> {
public Vector getColumnVector() {
return copy();
}
+
+ /**
+ * Vector factory for Vectors.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ private static class Factory implements NumberVector.Factory<Vector> {
+ @Override
+ public <A> Vector newFeatureVector(A array, ArrayAdapter<? extends Number, A> adapter) {
+ if(adapter instanceof NumberArrayAdapter) {
+ return new Vector(ArrayLikeUtil.toPrimitiveDoubleArray(array, (NumberArrayAdapter<?, ? super A>) adapter));
+ }
+ double[] data = new double[adapter.size(array)];
+ for(int i = 0; i < data.length; i++) {
+ data[i] = adapter.get(array, i).doubleValue();
+ }
+ return new Vector(data);
+ }
+
+ @Override
+ public ByteBufferSerializer<Vector> getDefaultSerializer() {
+ return VARIABLE_SERIALIZER;
+ }
+
+ @Override
+ public Class<? super Vector> getRestrictionClass() {
+ return Vector.class;
+ }
+
+ @Override
+ public Vector newNumberVector(double[] values) {
+ return new Vector(values.clone());
+ }
+
+ @Override
+ public <A> Vector newNumberVector(A array, NumberArrayAdapter<?, ? super A> adapter) {
+ return new Vector(ArrayLikeUtil.toPrimitiveDoubleArray(array, adapter));
+ }
+
+ @Override
+ public Vector newNumberVector(NumberVector values) {
+ return new Vector(ArrayLikeUtil.toPrimitiveDoubleArray(values));
+ }
+ }
+
+ /**
+ * Serialization class for dense double vectors with up to 127 dimensions, by
+ * using a byte for storing the dimensionality.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class SmallSerializer implements ByteBufferSerializer<Vector> {
+ @Override
+ public Vector fromByteBuffer(ByteBuffer buffer) throws IOException {
+ final byte dimensionality = buffer.get();
+ assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * dimensionality);
+ final double[] values = new double[dimensionality];
+ for(int i = 0; i < dimensionality; i++) {
+ values[i] = buffer.getDouble();
+ }
+ return new Vector(values);
+ }
+
+ @Override
+ public void toByteBuffer(ByteBuffer buffer, Vector vec) throws IOException {
+ assert (vec.elements.length < Byte.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Byte.MAX_VALUE + "!";
+ assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * vec.elements.length);
+ buffer.put((byte) vec.elements.length);
+ for(int i = 0; i < vec.elements.length; i++) {
+ buffer.putDouble(vec.elements[i]);
+ }
+ }
+
+ @Override
+ public int getByteSize(Vector vec) {
+ assert (vec.elements.length < Byte.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Byte.MAX_VALUE + "!";
+ return ByteArrayUtil.SIZE_BYTE + ByteArrayUtil.SIZE_DOUBLE * vec.getDimensionality();
+ }
+ }
+
+ /**
+ * Serialization class for dense double vectors with up to
+ * {@link Short#MAX_VALUE} dimensions, by using a short for storing the
+ * dimensionality.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class ShortSerializer implements ByteBufferSerializer<Vector> {
+ @Override
+ public Vector fromByteBuffer(ByteBuffer buffer) throws IOException {
+ final short dimensionality = buffer.getShort();
+ assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * dimensionality);
+ final double[] values = new double[dimensionality];
+ for(int i = 0; i < dimensionality; i++) {
+ values[i] = buffer.getDouble();
+ }
+ return new Vector(values);
+ }
+
+ @Override
+ public void toByteBuffer(ByteBuffer buffer, Vector vec) throws IOException {
+ assert (vec.elements.length < Short.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Short.MAX_VALUE + "!";
+ assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * vec.elements.length);
+ buffer.putShort((short) vec.elements.length);
+ for(int i = 0; i < vec.elements.length; i++) {
+ buffer.putDouble(vec.elements[i]);
+ }
+ }
+
+ @Override
+ public int getByteSize(Vector vec) {
+ assert (vec.elements.length < Short.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Short.MAX_VALUE + "!";
+ return ByteArrayUtil.SIZE_SHORT + ByteArrayUtil.SIZE_DOUBLE * vec.getDimensionality();
+ }
+ }
+
+ /**
+ * Serialization class for variable dimensionality by using VarInt encoding.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ protected static class VariableSerializer implements ByteBufferSerializer<Vector> {
+ @Override
+ public Vector fromByteBuffer(ByteBuffer buffer) throws IOException {
+ final int dimensionality = ByteArrayUtil.readUnsignedVarint(buffer);
+ assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * dimensionality);
+ final double[] values = new double[dimensionality];
+ for(int i = 0; i < dimensionality; i++) {
+ values[i] = buffer.getDouble();
+ }
+ return new Vector(values);
+ }
+
+ @Override
+ public void toByteBuffer(ByteBuffer buffer, Vector vec) throws IOException {
+ assert (buffer.remaining() >= ByteArrayUtil.SIZE_DOUBLE * vec.elements.length);
+ ByteArrayUtil.writeUnsignedVarint(buffer, vec.elements.length);
+ for(int i = 0; i < vec.elements.length; i++) {
+ buffer.putDouble(vec.elements[i]);
+ }
+ }
+
+ @Override
+ public int getByteSize(Vector vec) {
+ return ByteArrayUtil.getUnsignedVarintSize(vec.elements.length) + ByteArrayUtil.SIZE_DOUBLE * vec.elements.length;
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunction.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunction.java
index 48e90c00..6128bd8d 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.fitting;
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/math/linearalgebra/fitting/FittingFunctionResult.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunctionResult.java
index 96d5381b..6a104ea5 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunctionResult.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/FittingFunctionResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.fitting;
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/math/linearalgebra/fitting/GaussianFittingFunction.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/GaussianFittingFunction.java
index 239d51c6..75eea676 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/GaussianFittingFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/GaussianFittingFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.fitting;
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/math/linearalgebra/fitting/LevenbergMarquardtMethod.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/LevenbergMarquardtMethod.java
index 1f2aa913..b855ffe2 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/LevenbergMarquardtMethod.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/LevenbergMarquardtMethod.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.fitting;
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/math/linearalgebra/fitting/package-info.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/package-info.java
index 100f36e2..5264b1ec 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/fitting/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/math/linearalgebra/package-info.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/package-info.java
index 4806b2d6..004575e5 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/package-info.java
@@ -38,27 +38,29 @@ can be found at <a href="http://math.nist.gov/javanumerics/jama/">http://math.ni
Here, for the adaption some classes and methods convenient for data mining applications within ELKI were added.
Furthermore some erroneous comments were corrected and the coding-style was subtly changed to a more Java-typical style.
-*/
+
+ * @apiviz.exclude ^java\.(io|lang)\..*
+ */
/*
-This file is part of ELKI:
-Environment for Developing KDD-Applications Supported by Index-Structures
+ 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
+ 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 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.
+ 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/>.
-*/
+ 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.math.linearalgebra; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/AbstractCovarianceMatrixBuilder.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/AbstractCovarianceMatrixBuilder.java
index 7079f5e1..42c0f493 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/AbstractCovarianceMatrixBuilder.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/AbstractCovarianceMatrixBuilder.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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,32 +27,28 @@ import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.DoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Abstract class with the task of computing a Covariance matrix to be used in PCA.
* Mostly the specification of an interface.
*
* @author Erich Schubert
- *
- * @param <V> Vector class in use
*/
-public abstract class AbstractCovarianceMatrixBuilder<V extends NumberVector<?>> implements Parameterizable, CovarianceMatrixBuilder<V> {
+public abstract class AbstractCovarianceMatrixBuilder implements CovarianceMatrixBuilder {
@Override
- public Matrix processDatabase(Relation<? extends V> database) {
+ public Matrix processDatabase(Relation<? extends NumberVector> database) {
return processIds(database.getDBIDs(), database);
}
@Override
- public abstract Matrix processIds(DBIDs ids, Relation<? extends V> database);
+ public abstract Matrix processIds(DBIDs ids, Relation<? extends NumberVector> database);
@Override
- public <D extends NumberDistance<D, ?>> Matrix processQueryResults(DistanceDBIDList<D> results, Relation<? extends V> database, int k) {
+ public Matrix processQueryResults(DoubleDBIDList results, Relation<? extends NumberVector> database, int k) {
ModifiableDBIDs ids = DBIDUtil.newArray(k);
int have = 0;
for(DBIDIter it = results.iter(); it.valid() && have < k; it.advance(), have++) {
@@ -62,7 +58,7 @@ public abstract class AbstractCovarianceMatrixBuilder<V extends NumberVector<?>>
}
@Override
- public final <D extends NumberDistance<D, ?>> Matrix processQueryResults(DistanceDBIDList<D> results, Relation<? extends V> database) {
+ public final Matrix processQueryResults(DoubleDBIDList results, Relation<? extends NumberVector> database) {
return processQueryResults(results, database, results.size());
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CompositeEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CompositeEigenPairFilter.java
index eb725400..d177c73c 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CompositeEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CompositeEigenPairFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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/math/linearalgebra/pca/CovarianceMatrixBuilder.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CovarianceMatrixBuilder.java
index d819c839..7bcf487d 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CovarianceMatrixBuilder.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/CovarianceMatrixBuilder.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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,23 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
/**
* Interface for computing covariance matrixes on a data set.
*
* @author Erich Schubert
- *
- * @param <V> Vector base type
*/
-public interface CovarianceMatrixBuilder<V extends NumberVector<?>> {
+public interface CovarianceMatrixBuilder {
/**
* Compute Covariance Matrix for a complete database.
*
* @param database the database used
* @return Covariance Matrix
*/
- Matrix processDatabase(Relation<? extends V> database);
+ Matrix processDatabase(Relation<? extends NumberVector> database);
/**
* Compute Covariance Matrix for a collection of database IDs.
@@ -53,7 +50,7 @@ public interface CovarianceMatrixBuilder<V extends NumberVector<?>> {
* @param database the database used
* @return Covariance Matrix
*/
- Matrix processIds(DBIDs ids, Relation<? extends V> database);
+ Matrix processIds(DBIDs ids, Relation<? extends NumberVector> database);
/**
* Compute Covariance Matrix for a QueryResult Collection.
@@ -63,10 +60,9 @@ public interface CovarianceMatrixBuilder<V extends NumberVector<?>> {
* @param results a collection of QueryResults
* @param database the database used
* @param k the number of entries to process
- * @param <D> distance type
* @return Covariance Matrix
*/
- <D extends NumberDistance<D, ?>> Matrix processQueryResults(DistanceDBIDList<D> results, Relation<? extends V> database, int k);
+ Matrix processQueryResults(DoubleDBIDList results, Relation<? extends NumberVector> database, int k);
/**
* Compute Covariance Matrix for a QueryResult Collection.
@@ -75,8 +71,7 @@ public interface CovarianceMatrixBuilder<V extends NumberVector<?>> {
*
* @param results a collection of QueryResults
* @param database the database used
- * @param <D> distance type
* @return Covariance Matrix
*/
- <D extends NumberDistance<D, ?>> Matrix processQueryResults(DistanceDBIDList<D> results, Relation<? extends V> database);
+ Matrix processQueryResults(DoubleDBIDList results, Relation<? extends NumberVector> database);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/DropEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/DropEigenPairFilter.java
index 7a2917c5..e30be31f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/DropEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/DropEigenPairFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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/math/linearalgebra/pca/EigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/EigenPairFilter.java
index a3f506e1..9ce56274 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/EigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/EigenPairFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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.math.linearalgebra.pca;
*/
import de.lmu.ifi.dbs.elki.math.linearalgebra.SortedEigenPairs;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* The eigenpair filter is used to filter eigenpairs (i.e. eigenvectors
@@ -39,7 +38,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
* @apiviz.uses SortedEigenPairs oneway - - reads
* @apiviz.uses FilteredEigenPairs oneway - - «create»
*/
-public interface EigenPairFilter extends Parameterizable {
+public interface EigenPairFilter {
/**
* Filters the specified eigenpairs into strong and weak eigenpairs,
* where strong eigenpairs having high variances
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FilteredEigenPairs.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FilteredEigenPairs.java
index 6cb6f07c..cad1a7b2 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FilteredEigenPairs.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FilteredEigenPairs.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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/math/linearalgebra/pca/FirstNEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FirstNEigenPairFilter.java
index 79ee4ea6..e8bb6b7f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FirstNEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FirstNEigenPairFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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/math/linearalgebra/pca/LimitEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/LimitEigenPairFilter.java
index 4d9e7331..a63a89ce 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/LimitEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/LimitEigenPairFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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/math/linearalgebra/pca/NormalizingEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/NormalizingEigenPairFilter.java
index 1d74d307..3b9865db 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/NormalizingEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/NormalizingEigenPairFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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
@@ -48,9 +48,7 @@ public class NormalizingEigenPairFilter implements EigenPairFilter {
private static final Logging LOG = Logging.getLogger(NormalizingEigenPairFilter.class);
/**
- * Provides a new EigenPairFilter that normalizes all eigenvectors s.t.
- * eigenvalue * <eigenvector, eigenvector> = 1, where <,> is the standard dot
- * product
+ * Constructor.
*/
public NormalizingEigenPairFilter() {
super();
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredAutotuningRunner.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredAutotuningRunner.java
index 4a36036a..8537ff65 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredAutotuningRunner.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredAutotuningRunner.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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,21 +29,21 @@ import java.util.List;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+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.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPairList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList;
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.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Centroid;
import de.lmu.ifi.dbs.elki.math.linearalgebra.EigenPair;
import de.lmu.ifi.dbs.elki.math.linearalgebra.EigenvalueDecomposition;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
import de.lmu.ifi.dbs.elki.math.linearalgebra.SortedEigenPairs;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
/**
@@ -55,10 +55,12 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* exhibit the clearest correlation.
*
* @author Erich Schubert
- * @param <V> vector type
*/
-@Reference(authors = "H.-P. Kriegel, P. Kröger, E. Schubert, A. Zimek", title = "A General Framework for Increasing the Robustness of PCA-based Correlation Clustering Algorithms", booktitle = "Proceedings of the 20th International Conference on Scientific and Statistical Database Management (SSDBM), Hong Kong, China, 2008", url = "http://dx.doi.org/10.1007/978-3-540-69497-7_27")
-public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAFilteredRunner<V> {
+@Reference(authors = "Hans-Peter Kriegel, Peer Kröger, Erich Schubert, Arthur Zimek", //
+title = "A General Framework for Increasing the Robustness of PCA-based Correlation Clustering Algorithms",//
+booktitle = "Proceedings of the 20th International Conference on Scientific and Statistical Database Management (SSDBM), Hong Kong, China, 2008",//
+url = "http://dx.doi.org/10.1007/978-3-540-69497-7_27")
+public class PCAFilteredAutotuningRunner extends PCAFilteredRunner {
/**
* Constructor.
*
@@ -67,18 +69,18 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF
* @param big Replacement for large values
* @param small Replacement for small values
*/
- public PCAFilteredAutotuningRunner(CovarianceMatrixBuilder<V> covarianceMatrixBuilder, EigenPairFilter eigenPairFilter, double big, double small) {
+ public PCAFilteredAutotuningRunner(CovarianceMatrixBuilder covarianceMatrixBuilder, EigenPairFilter eigenPairFilter, double big, double small) {
super(covarianceMatrixBuilder, eigenPairFilter, big, small);
}
@Override
- public PCAFilteredResult processIds(DBIDs ids, Relation<? extends V> database) {
+ public PCAFilteredResult processIds(DBIDs ids, Relation<? extends NumberVector> database) {
// Assume Euclidean distance. In the context of PCA, the neighborhood should
// be L2-spherical to be unbiased.
- V center = Centroid.make(database, ids).toVector(database);
- DoubleDistanceDBIDPairList dres = new DoubleDistanceDBIDPairList(ids.size());
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- final double dist = EuclideanDistanceFunction.STATIC.doubleDistance(center, database.get(iter));
+ Vector center = Centroid.make(database, ids);
+ ModifiableDoubleDBIDList dres = DBIDUtil.newDistanceDBIDList(ids.size());
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ final double dist = EuclideanDistanceFunction.STATIC.distance(center, database.get(iter));
dres.add(dist, iter);
}
dres.sort();
@@ -117,16 +119,16 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF
}
@Override
- public <D extends NumberDistance<D, ?>> PCAFilteredResult processQueryResult(DistanceDBIDList<D> results, Relation<? extends V> database) {
+ public PCAFilteredResult processQueryResult(DoubleDBIDList results, Relation<? extends NumberVector> database) {
assertSortedByDistance(results);
final int dim = RelationUtil.dimensionality(database);
List<Matrix> best = new LinkedList<>();
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
best.add(null);
}
double[] beststrength = new double[dim];
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
beststrength[i] = -1;
}
int[] bestk = new int[dim];
@@ -135,11 +137,11 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF
// TODO: starting parameter shouldn't be hardcoded...
int smooth = 3;
int startk = 4;
- if (startk > results.size() - 1) {
+ if(startk > results.size() - 1) {
startk = results.size() - 1;
}
// TODO: add smoothing options, handle border cases better.
- for (int k = startk; k < results.size(); k++) {
+ for(int k = startk; k < results.size(); k++) {
// sorted eigenpairs, eigenvectors, eigenvalues
Matrix covMat = covarianceMatrixBuilder.processQueryResults(results, database);
EigenvalueDecomposition evd = new EigenvalueDecomposition(covMat);
@@ -155,23 +157,23 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF
prev.add(new Cand(covMat, thisexplain, thisdim));
- if (prev.size() >= 2 * smooth + 1) {
+ if(prev.size() >= 2 * smooth + 1) {
// all the same dimension?
boolean samedim = true;
- for (Iterator<Cand> it = prev.iterator(); it.hasNext();) {
- if (it.next().dim != thisdim) {
+ for(Iterator<Cand> it = prev.iterator(); it.hasNext();) {
+ if(it.next().dim != thisdim) {
samedim = false;
}
}
- if (samedim) {
+ if(samedim) {
// average their explain values
double avgexplain = 0.0;
- for (Iterator<Cand> it = prev.iterator(); it.hasNext();) {
+ for(Iterator<Cand> it = prev.iterator(); it.hasNext();) {
avgexplain += it.next().explain;
}
avgexplain /= prev.size();
- if (avgexplain > beststrength[thisdim - 1]) {
+ if(avgexplain > beststrength[thisdim - 1]) {
beststrength[thisdim - 1] = avgexplain;
best.set(thisdim - 1, prev.get(smooth).m);
bestk[thisdim - 1] = k - smooth;
@@ -181,13 +183,13 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF
}
}
// Try all dimensions, lowest first.
- for (int i = 0; i < dim; i++) {
- if (beststrength[i] > 0.0) {
+ for(int i = 0; i < dim; i++) {
+ if(beststrength[i] > 0.0) {
// If the best was the lowest or the biggest k, skip it!
- if (bestk[i] == startk + smooth) {
+ if(bestk[i] == startk + smooth) {
continue;
}
- if (bestk[i] == results.size() - smooth - 1) {
+ if(bestk[i] == results.size() - smooth - 1) {
continue;
}
Matrix covMat = best.get(i);
@@ -212,10 +214,10 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF
private double computeExplainedVariance(FilteredEigenPairs filteredEigenPairs) {
double strongsum = 0.0;
double weaksum = 0.0;
- for (EigenPair ep : filteredEigenPairs.getStrongEigenPairs()) {
+ for(EigenPair ep : filteredEigenPairs.getStrongEigenPairs()) {
strongsum += ep.getEigenvalue();
}
- for (EigenPair ep : filteredEigenPairs.getWeakEigenPairs()) {
+ for(EigenPair ep : filteredEigenPairs.getWeakEigenPairs()) {
weaksum += ep.getEigenvalue();
}
return strongsum / (strongsum / weaksum);
@@ -225,25 +227,26 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF
* Ensure that the results are sorted by distance.
*
* @param results Results to process
- * @param <D> distance type
*/
- private <D extends NumberDistance<D, ?>> void assertSortedByDistance(DistanceDBIDList<D> results) {
+ private void assertSortedByDistance(DoubleDBIDList results) {
// TODO: sort results instead?
double dist = -1.0;
boolean sorted = true;
- for (DistanceDBIDListIter<D> it = results.iter(); it.valid(); it.advance()) {
- double qr = it.getDistance().doubleValue();
- if (qr < dist) {
+ for(DoubleDBIDListIter it = results.iter(); it.valid(); it.advance()) {
+ double qr = it.doubleValue();
+ if(qr < dist) {
sorted = false;
}
dist = qr;
}
- if (!sorted) {
+ if(!sorted) {
try {
- ModifiableDistanceDBIDList.class.cast(results).sort();
- } catch (ClassCastException e) {
+ ModifiableDoubleDBIDList.class.cast(results).sort();
+ }
+ catch(ClassCastException e) {
LoggingUtil.warning("WARNING: results not sorted by distance!", e);
- } catch (UnsupportedOperationException e) {
+ }
+ catch(UnsupportedOperationException e) {
LoggingUtil.warning("WARNING: results not sorted by distance!", e);
}
}
@@ -256,10 +259,10 @@ public class PCAFilteredAutotuningRunner<V extends NumberVector<?>> extends PCAF
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends PCAFilteredRunner.Parameterizer<V> {
+ public static class Parameterizer extends PCAFilteredRunner.Parameterizer {
@Override
- protected PCAFilteredAutotuningRunner<V> makeInstance() {
- return new PCAFilteredAutotuningRunner<>(covarianceMatrixBuilder, eigenPairFilter, big, small);
+ protected PCAFilteredAutotuningRunner makeInstance() {
+ return new PCAFilteredAutotuningRunner(covarianceMatrixBuilder, eigenPairFilter, big, small);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredResult.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredResult.java
index 7303f530..47a8bef0 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredResult.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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/math/linearalgebra/pca/PCAFilteredRunner.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredRunner.java
index 670b4559..6c0a417d 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredRunner.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredRunner.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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,8 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.math.linearalgebra.EigenvalueDecomposition;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
import de.lmu.ifi.dbs.elki.math.linearalgebra.SortedEigenPairs;
@@ -47,59 +46,21 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.landmark
* @apiviz.has PCAFilteredResult oneway - - «create»
* @apiviz.composedOf EigenPairFilter
- *
- * @param <V> Vector class to use
*/
-public class PCAFilteredRunner<V extends NumberVector<?>> extends PCARunner<V> {
- /**
- * Parameter to specify the filter for determination of the strong and weak
- * eigenvectors, must be a subclass of {@link EigenPairFilter}.
- * <p>
- * Default value: {@link PercentageEigenPairFilter}
- * </p>
- * <p>
- * Key: {@code -pca.filter}
- * </p>
- */
- public static final OptionID PCA_EIGENPAIR_FILTER = new OptionID("pca.filter", "Filter class to determine the strong and weak eigenvectors.");
-
- /**
- * Parameter to specify a constant big value to reset high eigenvalues, must
- * be a double greater than 0.
- * <p>
- * Default value: {@code 1.0}
- * </p>
- * <p>
- * Key: {@code -pca.big}
- * </p>
- */
- public static final OptionID BIG_ID = new OptionID("pca.big", "A constant big value to reset high eigenvalues.");
-
- /**
- * Parameter to specify a constant small value to reset low eigenvalues, must
- * be a double greater than 0.
- * <p>
- * Default value: {@code 0.0}
- * </p>
- * <p>
- * Key: {@code -pca.small}
- * </p>
- */
- public static final OptionID SMALL_ID = new OptionID("pca.small", "A constant small value to reset low eigenvalues.");
-
+public class PCAFilteredRunner extends PCARunner {
/**
* Holds the instance of the EigenPairFilter specified by
- * {@link #PCA_EIGENPAIR_FILTER}.
+ * {@link Parameterizer#PCA_EIGENPAIR_FILTER}.
*/
private EigenPairFilter eigenPairFilter;
/**
- * Holds the value of {@link #BIG_ID}.
+ * Holds the value of {@link Parameterizer#BIG_ID}.
*/
private double big;
/**
- * Holds the value of {@link #SMALL_ID}.
+ * Holds the value of {@link Parameterizer#SMALL_ID}.
*/
private double small;
@@ -111,7 +72,7 @@ public class PCAFilteredRunner<V extends NumberVector<?>> extends PCARunner<V> {
* @param big Replacement for large eigenvalues
* @param small Replacement for small eigenvalues
*/
- public PCAFilteredRunner(CovarianceMatrixBuilder<V> covarianceMatrixBuilder, EigenPairFilter eigenPairFilter, double big, double small) {
+ public PCAFilteredRunner(CovarianceMatrixBuilder covarianceMatrixBuilder, EigenPairFilter eigenPairFilter, double big, double small) {
super(covarianceMatrixBuilder);
this.eigenPairFilter = eigenPairFilter;
this.big = big;
@@ -126,7 +87,7 @@ public class PCAFilteredRunner<V extends NumberVector<?>> extends PCARunner<V> {
* @return PCA result
*/
@Override
- public PCAFilteredResult processIds(DBIDs ids, Relation<? extends V> database) {
+ public PCAFilteredResult processIds(DBIDs ids, Relation<? extends NumberVector> database) {
return processCovarMatrix(covarianceMatrixBuilder.processIds(ids, database));
}
@@ -135,11 +96,10 @@ public class PCAFilteredRunner<V extends NumberVector<?>> extends PCARunner<V> {
*
* @param results a collection of QueryResults
* @param database the database used
- * @param <D> distance type
* @return PCA result
*/
@Override
- public <D extends NumberDistance<D, ?>> PCAFilteredResult processQueryResult(DistanceDBIDList<D> results, Relation<? extends V> database) {
+ public PCAFilteredResult processQueryResult(DoubleDBIDList results, Relation<? extends NumberVector> database) {
return processCovarMatrix(covarianceMatrixBuilder.processQueryResults(results, database));
}
@@ -185,7 +145,43 @@ public class PCAFilteredRunner<V extends NumberVector<?>> extends PCARunner<V> {
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends PCARunner.Parameterizer<V> {
+ public static class Parameterizer extends PCARunner.Parameterizer {
+ /**
+ * Parameter to specify the filter for determination of the strong and weak
+ * eigenvectors, must be a subclass of {@link EigenPairFilter}.
+ * <p>
+ * Default value: {@link PercentageEigenPairFilter}
+ * </p>
+ * <p>
+ * Key: {@code -pca.filter}
+ * </p>
+ */
+ public static final OptionID PCA_EIGENPAIR_FILTER = new OptionID("pca.filter", "Filter class to determine the strong and weak eigenvectors.");
+
+ /**
+ * Parameter to specify a constant big value to reset high eigenvalues, must
+ * be a double greater than 0.
+ * <p>
+ * Default value: {@code 1.0}
+ * </p>
+ * <p>
+ * Key: {@code -pca.big}
+ * </p>
+ */
+ public static final OptionID BIG_ID = new OptionID("pca.big", "A constant big value to reset high eigenvalues.");
+
+ /**
+ * Parameter to specify a constant small value to reset low eigenvalues, must
+ * be a double greater than 0.
+ * <p>
+ * Default value: {@code 0.0}
+ * </p>
+ * <p>
+ * Key: {@code -pca.small}
+ * </p>
+ */
+ public static final OptionID SMALL_ID = new OptionID("pca.small", "A constant small value to reset low eigenvalues.");
+
/**
* Holds the instance of the EigenPairFilter specified by
* {@link #PCA_EIGENPAIR_FILTER}.
@@ -228,8 +224,8 @@ public class PCAFilteredRunner<V extends NumberVector<?>> extends PCARunner<V> {
}
@Override
- protected PCAFilteredRunner<V> makeInstance() {
- return new PCAFilteredRunner<>(covarianceMatrixBuilder, eigenPairFilter, big, small);
+ protected PCAFilteredRunner makeInstance() {
+ return new PCAFilteredRunner(covarianceMatrixBuilder, eigenPairFilter, big, small);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAResult.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAResult.java
index 1634cbf0..b75600d6 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAResult.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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/math/linearalgebra/pca/PCARunner.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCARunner.java
index 91447024..2bfbaa8d 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCARunner.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCARunner.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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,18 +23,15 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.math.linearalgebra.EigenvalueDecomposition;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
import de.lmu.ifi.dbs.elki.math.linearalgebra.SortedEigenPairs;
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.Parameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
@@ -53,10 +50,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.landmark
* @apiviz.uses PCAResult oneway - - «create»
* @apiviz.composedOf CovarianceMatrixBuilder
- *
- * @param <V> Vector type
*/
-public class PCARunner<V extends NumberVector<?>> implements Parameterizable {
+public class PCARunner {
/**
* Parameter to specify the class to compute the covariance matrix, must be a
* subclass of {@link CovarianceMatrixBuilder}.
@@ -72,14 +67,14 @@ public class PCARunner<V extends NumberVector<?>> implements Parameterizable {
/**
* The covariance computation class.
*/
- protected CovarianceMatrixBuilder<V> covarianceMatrixBuilder;
+ protected CovarianceMatrixBuilder covarianceMatrixBuilder;
/**
* Constructor.
*
* @param covarianceMatrixBuilder Class for computing the covariance matrix
*/
- public PCARunner(CovarianceMatrixBuilder<V> covarianceMatrixBuilder) {
+ public PCARunner(CovarianceMatrixBuilder covarianceMatrixBuilder) {
super();
this.covarianceMatrixBuilder = covarianceMatrixBuilder;
}
@@ -90,7 +85,7 @@ public class PCARunner<V extends NumberVector<?>> implements Parameterizable {
* @param database the database used
* @return PCA result
*/
- public PCAResult processDatabase(Relation<? extends V> database) {
+ public PCAResult processDatabase(Relation<? extends NumberVector> database) {
return processCovarMatrix(covarianceMatrixBuilder.processDatabase(database));
}
@@ -101,7 +96,7 @@ public class PCARunner<V extends NumberVector<?>> implements Parameterizable {
* @param database the database used
* @return PCA result
*/
- public PCAResult processIds(DBIDs ids, Relation<? extends V> database) {
+ public PCAResult processIds(DBIDs ids, Relation<? extends NumberVector> database) {
return processCovarMatrix(covarianceMatrixBuilder.processIds(ids, database));
}
@@ -110,10 +105,9 @@ public class PCARunner<V extends NumberVector<?>> implements Parameterizable {
*
* @param results a collection of QueryResults
* @param database the database used
- * @param <D> distance type
* @return PCA result
*/
- public <D extends NumberDistance<D, ?>> PCAResult processQueryResult(DistanceDBIDList<D> results, Relation<? extends V> database) {
+ public PCAResult processQueryResult(DoubleDBIDList results, Relation<? extends NumberVector> database) {
return processCovarMatrix(covarianceMatrixBuilder.processQueryResults(results, database));
}
@@ -145,7 +139,7 @@ public class PCARunner<V extends NumberVector<?>> implements Parameterizable {
*
* @return covariance matrix builder in use
*/
- public CovarianceMatrixBuilder<V> getCovarianceMatrixBuilder() {
+ public CovarianceMatrixBuilder getCovarianceMatrixBuilder() {
return covarianceMatrixBuilder;
}
@@ -154,7 +148,7 @@ public class PCARunner<V extends NumberVector<?>> implements Parameterizable {
*
* @param covarianceBuilder New covariance matrix builder.
*/
- public void setCovarianceMatrixBuilder(CovarianceMatrixBuilder<V> covarianceBuilder) {
+ public void setCovarianceMatrixBuilder(CovarianceMatrixBuilder covarianceBuilder) {
this.covarianceMatrixBuilder = covarianceBuilder;
}
@@ -165,24 +159,24 @@ public class PCARunner<V extends NumberVector<?>> implements Parameterizable {
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer extends AbstractParameterizer {
/**
* The covariance computation class.
*/
- protected CovarianceMatrixBuilder<V> covarianceMatrixBuilder;
+ protected CovarianceMatrixBuilder covarianceMatrixBuilder;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- ObjectParameter<CovarianceMatrixBuilder<V>> covarianceP = new ObjectParameter<>(PCA_COVARIANCE_MATRIX, CovarianceMatrixBuilder.class, StandardCovarianceMatrixBuilder.class);
+ ObjectParameter<CovarianceMatrixBuilder> covarianceP = new ObjectParameter<>(PCA_COVARIANCE_MATRIX, CovarianceMatrixBuilder.class, StandardCovarianceMatrixBuilder.class);
if(config.grab(covarianceP)) {
covarianceMatrixBuilder = covarianceP.instantiateClass(config);
}
}
@Override
- protected PCARunner<V> makeInstance() {
- return new PCARunner<>(covarianceMatrixBuilder);
+ protected PCARunner makeInstance() {
+ return new PCARunner(covarianceMatrixBuilder);
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PercentageEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PercentageEigenPairFilter.java
index 5602228e..02814d74 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PercentageEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PercentageEigenPairFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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/math/linearalgebra/pca/ProgressiveEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/ProgressiveEigenPairFilter.java
index 4f412257..9ea532f9 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/ProgressiveEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/ProgressiveEigenPairFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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/math/linearalgebra/pca/RANSACCovarianceMatrixBuilder.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RANSACCovarianceMatrixBuilder.java
index 2b369a32..f5bff525 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RANSACCovarianceMatrixBuilder.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RANSACCovarianceMatrixBuilder.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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
@@ -33,8 +33,8 @@ import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.math.linearalgebra.CovarianceMatrix;
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.random.RandomFactory;
import de.lmu.ifi.dbs.elki.math.statistics.distribution.ChiSquaredDistribution;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -72,11 +72,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
* </p>
*
* @author Erich Schubert
- *
- * @param <V> Vector type
*/
-@Reference(authors = "Hans-Peter Kriegel, Peer Kröger, Erich Schubert, Arthur Zimek", title = "Outlier Detection in Arbitrarily Oriented Subspaces", booktitle = "Proc. IEEE International Conference on Data Mining (ICDM 2012)")
-public class RANSACCovarianceMatrixBuilder<V extends NumberVector<?>> extends AbstractCovarianceMatrixBuilder<V> {
+@Reference(authors = "Hans-Peter Kriegel, Peer Kröger, Erich Schubert, Arthur Zimek", //
+title = "Outlier Detection in Arbitrarily Oriented Subspaces", //
+booktitle = "Proc. IEEE International Conference on Data Mining (ICDM 2012)")
+public class RANSACCovarianceMatrixBuilder extends AbstractCovarianceMatrixBuilder {
/**
* Number of iterations to perform
*/
@@ -101,7 +101,7 @@ public class RANSACCovarianceMatrixBuilder<V extends NumberVector<?>> extends Ab
@Reference(title = "Random sample consensus: a paradigm for model fitting with applications to image analysis and automated cartography", authors = "M.A. Fischler, R.C. Bolles", booktitle = "Communications of the ACM, Vol. 24 Issue 6", url = "http://dx.doi.org/10.1145/358669.358692")
@Override
- public Matrix processIds(DBIDs ids, Relation<? extends V> relation) {
+ public Matrix processIds(DBIDs ids, Relation<? extends NumberVector> relation) {
final int dim = RelationUtil.dimensionality(relation);
DBIDs best = DBIDUtil.EMPTYDBIDS;
@@ -144,10 +144,8 @@ public class RANSACCovarianceMatrixBuilder<V extends NumberVector<?>> extends Ab
* @author Erich Schubert
*
* @apiviz.exclude
- *
- * @param <V> Vector type
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer extends AbstractParameterizer {
/**
* Number of iterations.
*/
@@ -183,8 +181,8 @@ public class RANSACCovarianceMatrixBuilder<V extends NumberVector<?>> extends Ab
}
@Override
- protected RANSACCovarianceMatrixBuilder<V> makeInstance() {
- return new RANSACCovarianceMatrixBuilder<>(iterations, rnd);
+ protected RANSACCovarianceMatrixBuilder makeInstance() {
+ return new RANSACCovarianceMatrixBuilder(iterations, rnd);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RelativeEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RelativeEigenPairFilter.java
index 32092ce9..fd80c93f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RelativeEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RelativeEigenPairFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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/math/linearalgebra/pca/SignificantEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/SignificantEigenPairFilter.java
index 6219f77f..9daaefa0 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/SignificantEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/SignificantEigenPairFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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/math/linearalgebra/pca/StandardCovarianceMatrixBuilder.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/StandardCovarianceMatrixBuilder.java
index 90dd59c1..ec889bcb 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/StandardCovarianceMatrixBuilder.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/StandardCovarianceMatrixBuilder.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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
@@ -36,10 +36,8 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
* @author Erich Schubert
*
* @apiviz.uses CovarianceMatrix
- *
- * @param <V> Vector class to use.
*/
-public class StandardCovarianceMatrixBuilder<V extends NumberVector<?>> extends AbstractCovarianceMatrixBuilder<V> {
+public class StandardCovarianceMatrixBuilder extends AbstractCovarianceMatrixBuilder {
/**
* Compute Covariance Matrix for a complete database.
*
@@ -47,7 +45,7 @@ public class StandardCovarianceMatrixBuilder<V extends NumberVector<?>> extends
* @return Covariance Matrix
*/
@Override
- public Matrix processDatabase(Relation<? extends V> database) {
+ public Matrix processDatabase(Relation<? extends NumberVector> database) {
return CovarianceMatrix.make(database).destroyToNaiveMatrix();
}
@@ -59,7 +57,7 @@ public class StandardCovarianceMatrixBuilder<V extends NumberVector<?>> extends
* @return Covariance Matrix
*/
@Override
- public Matrix processIds(DBIDs ids, Relation<? extends V> database) {
+ public Matrix processIds(DBIDs ids, Relation<? extends NumberVector> database) {
return CovarianceMatrix.make(database, ids).destroyToNaiveMatrix();
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeakEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeakEigenPairFilter.java
index 92e1e32e..2315bd8b 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeakEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeakEigenPairFilter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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/math/linearalgebra/pca/WeightedCovarianceMatrixBuilder.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeightedCovarianceMatrixBuilder.java
index 236a24bc..801decd7 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeightedCovarianceMatrixBuilder.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeightedCovarianceMatrixBuilder.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
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,19 +26,16 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-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.database.ids.distance.DoubleDistanceDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
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.distancefunction.PrimitiveDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Centroid;
import de.lmu.ifi.dbs.elki.math.linearalgebra.CovarianceMatrix;
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.weightfunctions.ConstantWeight;
import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions.WeightFunction;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
@@ -67,13 +64,14 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @apiviz.has WeightFunction
* @apiviz.has PrimitiveDistanceFunction
* @apiviz.uses CovarianceMatrix
- *
- * @param <V> Vector class to use
*/
@Title("Weighted Covariance Matrix / PCA")
@Description("A PCA modification by using weights while building the covariance matrix, to obtain more stable results")
-@Reference(authors = "H.-P. Kriegel, P. Kröger, E. Schubert, A. Zimek", title = "A General Framework for Increasing the Robustness of PCA-based Correlation Clustering Algorithms", booktitle = "Proceedings of the 20th International Conference on Scientific and Statistical Database Management (SSDBM), Hong Kong, China, 2008", url = "http://dx.doi.org/10.1007/978-3-540-69497-7_27")
-public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends AbstractCovarianceMatrixBuilder<V> {
+@Reference(authors = "Hans-Peter Kriegel, Peer Kröger, Erich Schubert, Arthur Zimek", //
+title = "A General Framework for Increasing the Robustness of PCA-based Correlation Clustering Algorithms",//
+booktitle = "Proceedings of the 20th International Conference on Scientific and Statistical Database Management (SSDBM), Hong Kong, China, 2008",//
+url = "http://dx.doi.org/10.1007/978-3-540-69497-7_27")
+public class WeightedCovarianceMatrixBuilder extends AbstractCovarianceMatrixBuilder {
/**
* Parameter to specify the weight function to use in weighted PCA, must
* implement
@@ -93,8 +91,7 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends
/**
* Holds the distance function used for weight calculation.
*/
- // TODO: make configurable?
- private PrimitiveDistanceFunction<? super V, DoubleDistance> weightDistance = EuclideanDistanceFunction.STATIC;
+ private PrimitiveDistanceFunction<? super NumberVector> weightDistance = EuclideanDistanceFunction.STATIC;
/**
* Constructor.
@@ -117,18 +114,18 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends
* @return Covariance matrix
*/
@Override
- public Matrix processIds(DBIDs ids, Relation<? extends V> relation) {
+ public Matrix processIds(DBIDs ids, Relation<? extends NumberVector> relation) {
final int dim = RelationUtil.dimensionality(relation);
final CovarianceMatrix cmat = new CovarianceMatrix(dim);
- final V centroid = Centroid.make(relation, ids).toVector(relation);
+ final Vector centroid = Centroid.make(relation, ids);
// find maximum distance
double maxdist = 0.0;
double stddev = 0.0;
{
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- V obj = relation.get(iter);
- double distance = weightDistance.distance(centroid, obj).doubleValue();
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ NumberVector obj = relation.get(iter);
+ double distance = weightDistance.distance(centroid, obj);
stddev += distance * distance;
if(distance > maxdist) {
maxdist = distance;
@@ -141,9 +138,9 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends
stddev = Math.sqrt(stddev / ids.size());
}
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- V obj = relation.get(iter);
- double distance = weightDistance.distance(centroid, obj).doubleValue();
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ NumberVector obj = relation.get(iter);
+ double distance = weightDistance.distance(centroid, obj);
double weight = weightfunction.getWeight(distance, maxdist, stddev);
cmat.put(obj, weight);
}
@@ -158,11 +155,10 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends
* @param results a collection of QueryResults
* @param database the database used
* @param k number of elements to process
- * @param <D> distance type
* @return Covariance Matrix
*/
@Override
- public <D extends NumberDistance<D, ?>> Matrix processQueryResults(DistanceDBIDList<D> results, Relation<? extends V> database, int k) {
+ public Matrix processQueryResults(DoubleDBIDList results, Relation<? extends NumberVector> database, int k) {
final int dim = RelationUtil.dimensionality(database);
final CovarianceMatrix cmat = new CovarianceMatrix(dim);
@@ -176,15 +172,8 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends
double stddev = 0.0;
{
int i = 0;
- for (DistanceDBIDListIter<D> it = results.iter(); it.valid() && i < k; it.advance(), k++) {
- DistanceDBIDPair<D> res = it.getDistancePair();
- final double dist;
- if(res instanceof DoubleDistanceDBIDPair) {
- dist = ((DoubleDistanceDBIDPair) res).doubleDistance();
- }
- else {
- dist = res.getDistance().doubleValue();
- }
+ for(DoubleDBIDListIter it = results.iter(); it.valid() && i < k; it.advance(), k++) {
+ final double dist = it.doubleValue();
stddev += dist * dist;
if(dist > maxdist) {
maxdist = dist;
@@ -198,17 +187,9 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends
// calculate weighted PCA
int i = 0;
- for (DistanceDBIDListIter<D> it = results.iter(); it.valid() && i < k; it.advance(), k++) {
- DistanceDBIDPair<D> res = it.getDistancePair();
- final double dist;
- if(res instanceof DoubleDistanceDBIDPair) {
- dist = ((DoubleDistanceDBIDPair) res).doubleDistance();
- }
- else {
- dist = res.getDistance().doubleValue();
- }
-
- V obj = database.get(res);
+ for(DoubleDBIDListIter it = results.iter(); it.valid() && i < k; it.advance(), k++) {
+ final double dist = it.doubleValue();
+ NumberVector obj = database.get(it);
double weight = weightfunction.getWeight(dist, maxdist, stddev);
cmat.put(obj, weight);
}
@@ -222,7 +203,7 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer extends AbstractParameterizer {
/**
* Weight function.
*/
@@ -238,8 +219,8 @@ public class WeightedCovarianceMatrixBuilder<V extends NumberVector<?>> extends
}
@Override
- protected WeightedCovarianceMatrixBuilder<V> makeInstance() {
- return new WeightedCovarianceMatrixBuilder<>(weightfunction);
+ protected WeightedCovarianceMatrixBuilder makeInstance() {
+ return new WeightedCovarianceMatrixBuilder(weightfunction);
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/package-info.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/package-info.java
index 2606234b..8ca349d0 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/package-info.java
@@ -1,11 +1,15 @@
/**
- * <p>Principal Component Analysis (PCA) and Eigenvector processing.</p>
+ * <p>Principal Component Analysis (PCA) and Eigenvector processing.</p>
+ *
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.datasource.filter.transform
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.index
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.algorithm
*/
/*
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/math/linearalgebra/pca/weightfunctions/ConstantWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ConstantWeight.java
index 2252b512..f326e60b 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ConstantWeight.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ConstantWeight.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions;
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/math/linearalgebra/pca/weightfunctions/ErfcStddevWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcStddevWeight.java
index 645eff29..08e2fb8a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcStddevWeight.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcStddevWeight.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions;
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/math/linearalgebra/pca/weightfunctions/ErfcWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcWeight.java
index be7626a3..3cd6096a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcWeight.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ErfcWeight.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions;
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/math/linearalgebra/pca/weightfunctions/ExponentialStddevWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialStddevWeight.java
index 7495805d..c99c4e9b 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialStddevWeight.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialStddevWeight.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions;
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/math/linearalgebra/pca/weightfunctions/ExponentialWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialWeight.java
index 13653ac8..eadb2c21 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialWeight.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/ExponentialWeight.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions;
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/math/linearalgebra/pca/weightfunctions/GaussStddevWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussStddevWeight.java
index 698cd50d..1bc57b21 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussStddevWeight.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussStddevWeight.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions;
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/math/linearalgebra/pca/weightfunctions/GaussWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussWeight.java
index bdb1d9d9..cd14ae3a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussWeight.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/GaussWeight.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions;
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/math/linearalgebra/pca/weightfunctions/InverseLinearWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseLinearWeight.java
index e82b51c9..6bcbee2e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseLinearWeight.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseLinearWeight.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions;
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/math/linearalgebra/pca/weightfunctions/InverseProportionalStddevWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalStddevWeight.java
index b8577617..7f17c063 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalStddevWeight.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalStddevWeight.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions;
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/math/linearalgebra/pca/weightfunctions/InverseProportionalWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalWeight.java
index b51c85fa..21e673b3 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalWeight.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/InverseProportionalWeight.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions;
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/math/linearalgebra/pca/weightfunctions/LinearWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/LinearWeight.java
index 68448433..45657631 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/LinearWeight.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/LinearWeight.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions;
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/math/linearalgebra/pca/weightfunctions/QuadraticStddevWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticStddevWeight.java
index 1279b22d..52188952 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticStddevWeight.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticStddevWeight.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions;
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/math/linearalgebra/pca/weightfunctions/QuadraticWeight.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticWeight.java
index b23713a6..0b4577e4 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticWeight.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/QuadraticWeight.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions;
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/math/linearalgebra/pca/weightfunctions/WeightFunction.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/WeightFunction.java
index 0c9f8ae0..e67f6b73 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/WeightFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/WeightFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions;
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/math/linearalgebra/pca/weightfunctions/package-info.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/package-info.java
index 7869427b..19bfd4dc 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/weightfunctions/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/math/linearalgebra/randomprojections/AbstractRandomProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AbstractRandomProjectionFamily.java
index e7f8198a..b20a9aed 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AbstractRandomProjectionFamily.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AbstractRandomProjectionFamily.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections;
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.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.VectorUtil;
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.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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;
@@ -116,7 +116,7 @@ public abstract class AbstractRandomProjectionFamily implements RandomProjection
}
@Override
- public double[] project(NumberVector<?> in) {
+ public double[] project(NumberVector in) {
for (int d = 0; d < vals.length; d++) {
vals[d] = in.doubleValue(d);
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AchlioptasRandomProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AchlioptasRandomProjectionFamily.java
index c07a9590..69e68e19 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AchlioptasRandomProjectionFamily.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AchlioptasRandomProjectionFamily.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections;
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.math.linearalgebra.randomprojections;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/CauchyRandomProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/CauchyRandomProjectionFamily.java
index 0e7aa7e1..20892ff4 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/CauchyRandomProjectionFamily.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/CauchyRandomProjectionFamily.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections;
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.math.linearalgebra.randomprojections;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
/**
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/GaussianRandomProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/GaussianRandomProjectionFamily.java
index 722c8454..7fa8863a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/GaussianRandomProjectionFamily.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/GaussianRandomProjectionFamily.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections;
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.math.linearalgebra.randomprojections;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
/**
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomProjectionFamily.java
index aa796383..267770d5 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomProjectionFamily.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomProjectionFamily.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections;
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
@@ -54,7 +54,7 @@ public interface RandomProjectionFamily {
* @param in Input vector
* @return Projected vector
*/
- double[] project(NumberVector<?> in);
+ double[] project(NumberVector in);
/**
* Get the output dimensionality.
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomSubsetProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomSubsetProjectionFamily.java
index 94a4a29c..b5f282dd 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomSubsetProjectionFamily.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomSubsetProjectionFamily.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.linearalgebra.randomprojections;
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 java.util.Arrays;
import java.util.Random;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
/**
@@ -137,7 +137,7 @@ public class RandomSubsetProjectionFamily extends AbstractRandomProjectionFamily
}
@Override
- public double[] project(NumberVector<?> in) {
+ public double[] project(NumberVector in) {
double[] buf = new double[dims.length];
for (int i = 0; i < dims.length; i++) {
buf[i] = in.doubleValue(dims[i]);
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/package-info.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/package-info.java
index 3ddd4a5c..ea22ccef 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/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/math/package-info.java b/src/de/lmu/ifi/dbs/elki/math/package-info.java
index 5a5f168f..33468cae 100644
--- a/src/de/lmu/ifi/dbs/elki/math/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/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/utilities/UnsafeRandom.java b/src/de/lmu/ifi/dbs/elki/math/random/FastNonThreadsafeRandom.java
index 898b685a..da1c01fa 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/UnsafeRandom.java
+++ b/src/de/lmu/ifi/dbs/elki/math/random/FastNonThreadsafeRandom.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.utilities;
+package de.lmu.ifi.dbs.elki.math.random;
/*
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,7 +30,7 @@ import java.util.Random;
*
* @author Erich Schubert
*/
-public class UnsafeRandom extends Random {
+public class FastNonThreadsafeRandom extends Random {
/**
* Serial version number.
*/
@@ -49,7 +49,7 @@ public class UnsafeRandom extends Random {
/**
* Constructor called only by localRandom.initialValue.
*/
- public UnsafeRandom() {
+ public FastNonThreadsafeRandom() {
super();
}
@@ -58,16 +58,10 @@ public class UnsafeRandom extends Random {
*
* @param seed Random generator seed.
*/
- public UnsafeRandom(long seed) {
+ public FastNonThreadsafeRandom(long seed) {
this.seed = (seed ^ multiplier) & mask;
}
- /**
- * Throws {@code UnsupportedOperationException}. Setting seeds in this
- * generator is not supported.
- *
- * @throws UnsupportedOperationException always
- */
@Override
public void setSeed(long seed) {
this.seed = (seed ^ multiplier) & mask;
@@ -75,6 +69,7 @@ public class UnsafeRandom extends Random {
@Override
protected int next(int bits) {
+ // Linear Congruential Generator:
seed = (seed * multiplier + addend) & mask;
return (int) (seed >>> (48 - bits));
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/RandomFactory.java b/src/de/lmu/ifi/dbs/elki/math/random/RandomFactory.java
index 229afe5f..09e7202f 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/RandomFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/math/random/RandomFactory.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.utilities;
+package de.lmu.ifi.dbs.elki.math.random;
/*
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
@@ -94,10 +94,10 @@ public class RandomFactory {
*/
public Random getSingleThreadedRandom() {
if(seed != null) {
- return new UnsafeRandom(seed.longValue());
+ return new FastNonThreadsafeRandom(seed.longValue());
}
else {
- return new UnsafeRandom();
+ return new FastNonThreadsafeRandom();
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/random/XorShift1024NonThreadsafeRandom.java b/src/de/lmu/ifi/dbs/elki/math/random/XorShift1024NonThreadsafeRandom.java
new file mode 100644
index 00000000..df07d9aa
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/random/XorShift1024NonThreadsafeRandom.java
@@ -0,0 +1,110 @@
+package de.lmu.ifi.dbs.elki.math.random;
+
+/*
+ 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.Random;
+
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+
+/**
+ * Replacement for Java's {@link java.util.Random} class, using a different
+ * random number generation strategy. Java's random generator is optimized for
+ * speed, but may lack the randomness needed for more complex experiments.
+ *
+ * This approach is based on the work on XorShift1024* by Sebastiano Vigna, with
+ * the original copyright statement:
+ * <p>
+ * Written in 2014 by Sebastiano Vigna (vigna@acm.org)
+ *
+ * To the extent possible under law, the author has dedicated all copyright and
+ * related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * See http://creativecommons.org/publicdomain/zero/1.0/
+ * </p>
+ *
+ * @author Erich Schubert
+ */
+@Reference(authors = "S. Vigna", //
+title = "An experimental exploration of Marsaglia's xorshift generators, scrambled", //
+booktitle = "", url = "http://vigna.di.unimi.it/ftp/papers/xorshift.pdf")
+public class XorShift1024NonThreadsafeRandom extends Random {
+ /**
+ * Serial version number.
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * State of random number generator.
+ */
+ private long[] x;
+
+ /**
+ * For rotating amongst states
+ */
+ int p = 0;
+
+ /**
+ * Constructor called only by localRandom.initialValue.
+ */
+ public XorShift1024NonThreadsafeRandom() {
+ super();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param seed Random generator seed.
+ */
+ public XorShift1024NonThreadsafeRandom(long seed) {
+ super(seed);
+ }
+
+ @Override
+ public void setSeed(long seed) {
+ this.x = new long[16];
+ long xor64 = seed != 0 ? seed : 4101842887655102017L;
+ // XorShift64* generator to seed:
+ for(int i = 0; i < 16; i++) {
+ xor64 ^= xor64 >>> 12; // a
+ xor64 ^= xor64 << 25; // b
+ xor64 ^= xor64 >>> 27; // c
+ x[i] = xor64 * 2685821657736338717L;
+ }
+ }
+
+ @Override
+ public long nextLong() {
+ long s0 = x[p];
+ long s1 = x[p = (p + 1) & 15];
+ s1 ^= s1 << 31; // a
+ s1 ^= s1 >>> 11; // b
+ s0 ^= s0 >>> 30; // c
+ return (x[p] = s0 ^ s1) * 1181783497276652981L;
+ }
+
+ @Override
+ protected int next(int bits) {
+ return (int) (nextLong() >>> (64 - bits));
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/random/XorShift64NonThreadsafeRandom.java b/src/de/lmu/ifi/dbs/elki/math/random/XorShift64NonThreadsafeRandom.java
new file mode 100644
index 00000000..15d9cbff
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/random/XorShift64NonThreadsafeRandom.java
@@ -0,0 +1,95 @@
+package de.lmu.ifi.dbs.elki.math.random;
+
+/*
+ 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.Random;
+
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+
+/**
+ * Replacement for Java's {@link java.util.Random} class, using a different
+ * random number generation strategy. Java's random generator is optimized for
+ * speed, but may lack the randomness needed for more complex experiments.
+ *
+ * This approach is based on the work on XorShift64* by Sebastiano Vigna, with
+ * the original copyright statement:
+ * <p>
+ * Written in 2014 by Sebastiano Vigna (vigna@acm.org)
+ *
+ * To the extent possible under law, the author has dedicated all copyright and
+ * related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * See http://creativecommons.org/publicdomain/zero/1.0/
+ * </p>
+ *
+ * @author Erich Schubert
+ */
+@Reference(authors = "S. Vigna", //
+title = "An experimental exploration of Marsaglia's xorshift generators, scrambled", //
+booktitle = "", url = "http://vigna.di.unimi.it/ftp/papers/xorshift.pdf")
+public class XorShift64NonThreadsafeRandom extends Random {
+ /**
+ * Serial version number.
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * State of random number generator.
+ */
+ private long x = 4101842887655102017L;
+
+ /**
+ * Constructor called only by localRandom.initialValue.
+ */
+ public XorShift64NonThreadsafeRandom() {
+ super();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param seed Random generator seed.
+ */
+ public XorShift64NonThreadsafeRandom(long seed) {
+ super(seed);
+ }
+
+ @Override
+ public void setSeed(long seed) {
+ x = seed != 0 ? seed : 4101842887655102017L;
+ }
+
+ @Override
+ public long nextLong() {
+ x ^= x >>> 12; // a
+ x ^= x << 25; // b
+ x ^= x >>> 27; // c
+ return x * 2685821657736338717L;
+ }
+
+ @Override
+ protected int next(int bits) {
+ return (int) (nextLong() >>> (64 - bits));
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/random/package-info.java b/src/de/lmu/ifi/dbs/elki/math/random/package-info.java
new file mode 100644
index 00000000..7026a516
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/random/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Random number generation.
+ */
+package de.lmu.ifi.dbs.elki.math.random;
+
+/*
+ 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/>.
+ */
diff --git a/src/de/lmu/ifi/dbs/elki/math/scales/LinearScale.java b/src/de/lmu/ifi/dbs/elki/math/scales/LinearScale.java
index 07191d61..899095d1 100644
--- a/src/de/lmu/ifi/dbs/elki/math/scales/LinearScale.java
+++ b/src/de/lmu/ifi/dbs/elki/math/scales/LinearScale.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.scales;
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/math/scales/Scales.java b/src/de/lmu/ifi/dbs/elki/math/scales/Scales.java
index bf258d99..4c3a27d1 100644
--- a/src/de/lmu/ifi/dbs/elki/math/scales/Scales.java
+++ b/src/de/lmu/ifi/dbs/elki/math/scales/Scales.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.scales;
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
@@ -50,12 +50,11 @@ public final class Scales {
/**
* Compute a linear scale for each dimension.
*
- * @param <O> vector type
* @param db Database
* @return Scales, indexed starting with 0 (like Vector, not database
* objects!)
*/
- public static <O extends NumberVector<? extends Number>> LinearScale[] calcScales(Relation<O> db) {
+ public static LinearScale[] calcScales(Relation<? extends NumberVector> db) {
if (db == null) {
throw new AbortException("No database was given to Scales.calcScales.");
}
@@ -65,7 +64,7 @@ public final class Scales {
// analyze data
for (DBIDIter iditer = db.iterDBIDs(); iditer.valid(); iditer.advance()) {
- O v = db.get(iditer);
+ NumberVector v = db.get(iditer);
for (int d = 0; d < dim; d++) {
final double val = v.doubleValue(d);
if(val != val) {
diff --git a/src/de/lmu/ifi/dbs/elki/math/scales/package-info.java b/src/de/lmu/ifi/dbs/elki/math/scales/package-info.java
index 17465485..120eac84 100644
--- a/src/de/lmu/ifi/dbs/elki/math/scales/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/scales/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/math/spacefillingcurves/AbstractSpatialSorter.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/AbstractSpatialSorter.java
index 347af4a7..99381206 100644
--- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/AbstractSpatialSorter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/AbstractSpatialSorter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves;
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/math/spacefillingcurves/BinarySplitSpatialSorter.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/BinarySplitSpatialSorter.java
index 742fae07..914c4390 100644
--- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/BinarySplitSpatialSorter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/BinarySplitSpatialSorter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves;
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/math/spacefillingcurves/HilbertSpatialSorter.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/HilbertSpatialSorter.java
index 231e8637..dd0e729c 100644
--- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/HilbertSpatialSorter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/HilbertSpatialSorter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves;
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/math/spacefillingcurves/PeanoSpatialSorter.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/PeanoSpatialSorter.java
index 3519e75d..ae2e3fa7 100644
--- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/PeanoSpatialSorter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/PeanoSpatialSorter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves;
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/math/spacefillingcurves/SpatialSorter.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/SpatialSorter.java
index 30e6e019..a8c6166e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/SpatialSorter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/SpatialSorter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves;
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/math/spacefillingcurves/ZCurveSpatialSorter.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveSpatialSorter.java
index d30f88d6..66a94c90 100644
--- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveSpatialSorter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveSpatialSorter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves;
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/math/spacefillingcurves/ZCurveTransformer.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveTransformer.java
index 7474a00d..3f51c45d 100644
--- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveTransformer.java
+++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/ZCurveTransformer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.spacefillingcurves;
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.math.spacefillingcurves;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.math.BigInteger;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.data.NumberVector;
@@ -59,7 +58,7 @@ public class ZCurveTransformer {
* @param relation Relation to transform
* @param ids IDs subset to process
*/
- public ZCurveTransformer(Relation<? extends NumberVector<?>> relation, DBIDs ids) {
+ public ZCurveTransformer(Relation<? extends NumberVector> relation, DBIDs ids) {
this.dimensionality = RelationUtil.dimensionality(relation);
this.minValues = new double[dimensionality];
this.maxValues = new double[dimensionality];
@@ -68,7 +67,7 @@ public class ZCurveTransformer {
Arrays.fill(minValues, Double.POSITIVE_INFINITY);
Arrays.fill(maxValues, Double.NEGATIVE_INFINITY);
for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- NumberVector<?> vector = relation.get(iter);
+ NumberVector vector = relation.get(iter);
for(int dim = 0; dim < dimensionality; ++dim) {
double dimValue = vector.doubleValue(dim);
minValues[dim] = Math.min(minValues[dim], dimValue);
@@ -81,20 +80,9 @@ public class ZCurveTransformer {
* Transform a single vector.
*
* @param vector Vector to transform
- * @return Z curve value as bigint
- */
- @Deprecated
- public BigInteger asBigInteger(NumberVector<?> vector) {
- return new BigInteger(asByteArray(vector));
- }
-
- /**
- * Transform a single vector.
- *
- * @param vector Vector to transform
* @return Z curve value as byte array
*/
- public byte[] asByteArray(NumberVector<?> vector) {
+ public byte[] asByteArray(NumberVector vector) {
final long[] longValueList = new long[dimensionality];
for(int dim = 0; dim < dimensionality; ++dim) {
diff --git a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/package-info.java b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/package-info.java
index a658d747..5e13c6b1 100644
--- a/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/spacefillingcurves/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/math/statistics/KernelDensityEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/KernelDensityEstimator.java
index de756520..6bb162b0 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/KernelDensityEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/KernelDensityEstimator.java
@@ -8,7 +8,7 @@ import de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions.KernelDensityFunction
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/math/statistics/LinearRegression.java b/src/de/lmu/ifi/dbs/elki/math/statistics/LinearRegression.java
index 00999245..3f55373f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/LinearRegression.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/LinearRegression.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics;
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/math/statistics/MultipleLinearRegression.java b/src/de/lmu/ifi/dbs/elki/math/statistics/MultipleLinearRegression.java
index 37718358..4d786d8d 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/MultipleLinearRegression.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/MultipleLinearRegression.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics;
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
@@ -86,8 +86,7 @@ public class MultipleLinearRegression {
private final double sst;
/**
- * Provides a new multiple linear regression model with the specified
- * parameters.
+ * Constructor.
*
* @param y the (n x 1) - vector holding the response values (y1, ..., yn)^T.
* @param x the (n x p+1)-matrix holding the explanatory values, where the
@@ -144,7 +143,7 @@ public class MultipleLinearRegression {
msg.append("\ny = ").append(FormatUtil.format(y, 9, 4));
msg.append("\nb = ").append(FormatUtil.format(b, 9, 4));
msg.append("\ne = ").append(FormatUtil.format(e, 9, 4));
- msg.append("error variance = ").append(FormatUtil.format(variance, 4));
+ msg.append("error variance = ").append(FormatUtil.NF4.format(variance));
return msg.toString();
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/PolynomialRegression.java b/src/de/lmu/ifi/dbs/elki/math/statistics/PolynomialRegression.java
index c478142a..6c68ffeb 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/PolynomialRegression.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/PolynomialRegression.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics;
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
@@ -51,7 +51,7 @@ public class PolynomialRegression extends MultipleLinearRegression {
public final int p;
/**
- * Provides a new polynomial regression model with the specified parameters.
+ * Constructor.
*
* @param y the (n x 1) - vector holding the response values (y1, ..., yn)^T.
* @param x the (n x 1)-vector holding the x-values (x1, ..., xn)^T.
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/ProbabilityWeightedMoments.java b/src/de/lmu/ifi/dbs/elki/math/statistics/ProbabilityWeightedMoments.java
index b74ba06a..6eb72322 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/ProbabilityWeightedMoments.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/ProbabilityWeightedMoments.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics;
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/math/statistics/dependence/AbstractDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/AbstractDependenceMeasure.java
new file mode 100644
index 00000000..ba23588e
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/AbstractDependenceMeasure.java
@@ -0,0 +1,262 @@
+package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ 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.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+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.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerArrayQuickSort;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerComparator;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+
+/**
+ * Abstract base class for dependence measures.
+ *
+ * @author Erich Schubert
+ */
+public abstract class AbstractDependenceMeasure implements DependenceMeasure {
+ // In your subclass, you will need to implement at least this method:
+ // Sorry for the complex use of generics, but this way we can use it with any
+ // type of array, including vectors in rows or columns etc.
+ @Override
+ abstract public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2);
+
+ @Override
+ public double dependence(double[] data1, double[] data2) {
+ return dependence(ArrayLikeUtil.DOUBLEARRAYADAPTER, data1, ArrayLikeUtil.DOUBLEARRAYADAPTER, data2);
+ }
+
+ @Override
+ public <A> double dependence(NumberArrayAdapter<?, A> adapter, A data1, A data2) {
+ return dependence(adapter, data1, adapter, data2);
+ }
+
+ @Override
+ public <A> double[] dependence(NumberArrayAdapter<?, A> adapter, List<? extends A> data) {
+ final int dims = data.size();
+ double[] out = new double[(dims * (dims - 1)) >> 1];
+ int o = 0;
+ for(int y = 1; y < dims; y++) {
+ A dy = data.get(y);
+ for(int x = 0; x < y; x++) {
+ out[o++] = dependence(adapter, data.get(x), adapter, dy);
+ }
+ }
+ return out;
+ }
+
+ /**
+ * Clamp values to a given minimum and maximum.
+ *
+ * @param value True value
+ * @param min Minimum
+ * @param max Maximum
+ * @return {@code value}, unless smaller than {@code min} or larger than
+ * {@code max}.
+ */
+ protected static double clamp(double value, double min, double max) {
+ return value < min ? min : value > max ? max : value;
+ }
+
+ /**
+ * Compute ranks of all objects, normalized to [0;1] (where 0 is the smallest
+ * value, 1 is the largest).
+ *
+ * @param adapter Data adapter
+ * @param data Data array
+ * @param len Length of data
+ * @return Array of scores
+ */
+ protected static <A> double[] computeNormalizedRanks(final NumberArrayAdapter<?, A> adapter, final A data, int len) {
+ // Sort the objects:
+ int[] s1 = sortedIndex(adapter, data, len);
+ final double norm = .5 / (len - 1);
+ double[] ret = new double[len];
+ for(int i = 0; i < len;) {
+ final int start = i++;
+ final double val = adapter.getDouble(data, s1[start]);
+ while(i < len && adapter.getDouble(data, s1[i]) <= val) {
+ i++;
+ }
+ final double score = (start + i - 1) * norm;
+ for(int j = start; j < i; j++) {
+ ret[s1[j]] = score;
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Compute ranks of all objects, ranging from 1 to len.
+ *
+ * Ties are given the average rank.
+ *
+ * @param adapter Data adapter
+ * @param data Data array
+ * @param len Length of data
+ * @return Array of scores
+ */
+ protected static <A> double[] ranks(final NumberArrayAdapter<?, A> adapter, final A data, int len) {
+ // Sort the objects:
+ int[] s1 = sortedIndex(adapter, data, len);
+ return ranks(adapter, data, s1);
+ }
+
+ /**
+ * Compute ranks of all objects, ranging from 1 to len.
+ *
+ * Ties are given the average rank.
+ *
+ * @param adapter Data adapter
+ * @param data Data array
+ * @param idx Data index
+ * @return Array of scores
+ */
+ protected static <A> double[] ranks(final NumberArrayAdapter<?, A> adapter, final A data, int[] idx) {
+ final int len = idx.length;
+ double[] ret = new double[len];
+ for(int i = 0; i < len;) {
+ final int start = i++;
+ final double val = adapter.getDouble(data, idx[start]);
+ // Include ties:
+ while(i < len && adapter.getDouble(data, idx[i]) <= val) {
+ i++;
+ }
+ final double score = (start + i - 1) * .5 + 1;
+ for(int j = start; j < i; j++) {
+ ret[idx[j]] = score;
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Build a sorted index of objects.
+ *
+ * @param adapter Data adapter
+ * @param data Data array
+ * @param len Length of data
+ * @return Sorted index
+ */
+ protected static <A> int[] sortedIndex(final NumberArrayAdapter<?, A> adapter, final A data, int len) {
+ int[] s1 = MathUtil.sequence(0, len);
+ IntegerArrayQuickSort.sort(s1, new IntegerComparator() {
+ @Override
+ public int compare(int x, int y) {
+ return Double.compare(adapter.getDouble(data, x), adapter.getDouble(data, y));
+ }
+ });
+ return s1;
+ }
+
+ /**
+ * Discretize a data set into equi-width bin numbers.
+ *
+ * @param adapter Data adapter
+ * @param data Data array
+ * @param len Length of data
+ * @param bins Number of bins
+ * @return Array of bin numbers [0;bin[
+ */
+ protected static <A> int[] discretize(NumberArrayAdapter<?, A> adapter, A data, final int len, final int bins) {
+ double min = adapter.getDouble(data, 0), max = min;
+ for(int i = 1; i < len; i++) {
+ double v = adapter.getDouble(data, i);
+ if(v < min) {
+ min = v;
+ }
+ else if(v > max) {
+ max = v;
+ }
+ }
+ final double scale = (max > min) ? bins / (max - min) : 1;
+ int[] discData = new int[len];
+ for(int i = 0; i < len; i++) {
+ int bin = (int) Math.floor((adapter.getDouble(data, i) - min) * scale);
+ discData[i] = bin < 0 ? 0 : bin >= bins ? bins - 1 : bin;
+ }
+ return discData;
+ }
+
+ /**
+ * Index into the serialized array.
+ *
+ * @param x Column
+ * @param y Row
+ * @return Index in serialized array
+ */
+ protected static int index(int x, int y) {
+ assert (x < y) : "Only lower triangle is allowed.";
+ return ((y * (y - 1)) >> 1) + x;
+ }
+
+ /**
+ * Validate the length of the two data sets (must be the same, and non-zero)
+ *
+ * @param adapter1 First data adapter
+ * @param data1 First data set
+ * @param adapter2 Second data adapter
+ * @param data2 Second data set
+ * @param <A> First array type
+ * @param <B> Second array type
+ */
+ public static <A, B> int size(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = adapter1.size(data1);
+ if(len != adapter2.size(data2)) {
+ throw new AbortException("Array sizes do not match!");
+ }
+ if(len == 0) {
+ throw new AbortException("Empty array!");
+ }
+ return len;
+ }
+
+ /**
+ * Validate the length of the two data sets (must be the same, and non-zero)
+ *
+ * @param adapter Data adapter
+ * @param data Data sets
+ * @param <A> First array type
+ */
+ public static <A> int size(NumberArrayAdapter<?, A> adapter, Collection<? extends A> data) {
+ if(data.size() < 2) {
+ throw new AbortException("Need at least two axes to compute dependence measures.");
+ }
+ Iterator<? extends A> iter = data.iterator();
+ final int len = adapter.size(iter.next());
+ while(iter.hasNext()) {
+ if(len != adapter.size(iter.next())) {
+ throw new AbortException("Array sizes do not match!");
+ }
+ }
+ if(len == 0) {
+ throw new AbortException("Empty array!");
+ }
+ return len;
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/CorrelationDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/CorrelationDependenceMeasure.java
new file mode 100644
index 00000000..e03601f7
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/CorrelationDependenceMeasure.java
@@ -0,0 +1,141 @@
+package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ 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.List;
+
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Pearson product-moment correlation coefficient.
+ *
+ * @author Erich Schubert
+ */
+public class CorrelationDependenceMeasure extends AbstractDependenceMeasure {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(CorrelationDependenceMeasure.class);
+
+ /**
+ * Static instance.
+ */
+ public static final CorrelationDependenceMeasure STATIC = new CorrelationDependenceMeasure();
+
+ /**
+ * Constructor - use {@link #STATIC} instance.
+ */
+ protected CorrelationDependenceMeasure() {
+ super();
+ }
+
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+ // Perform two-pass estimation, which is numerically stable and often faster
+ // than the Knuth-Welford approach (see PearsonCorrelation class)
+ double m1 = 0., m2 = 0;
+ for(int i = 0; i < len; i++) {
+ m1 += adapter1.getDouble(data1, i);
+ m2 += adapter2.getDouble(data2, i);
+ }
+ m1 /= len;
+ m2 /= len;
+ // Second pass: variances and covariance
+ double v1 = 0., v2 = 0., cov = 0.;
+ for(int i = 0; i < len; i++) {
+ double d1 = adapter1.getDouble(data1, i) - m1;
+ double d2 = adapter2.getDouble(data2, i) - m2;
+ v1 += d1 * d1;
+ v2 += d2 * d2;
+ cov += d1 * d2;
+ }
+ // Note: we did not normalize by len, as this cancels out.
+ return cov / Math.sqrt(v1 * v2);
+ }
+
+ @Override
+ public <A> double[] dependence(NumberArrayAdapter<?, A> adapter, List<? extends A> data) {
+ final int dims = data.size();
+ final int len = size(adapter, data);
+ double[] means = new double[dims];
+ // Two passes - often faster due to the lower numerical cost
+ // And accurate, don't use sum-of-squares.
+ for(int j = 0; j < dims; j++) {
+ double m = 0.;
+ A da = data.get(j);
+ for(int i = 0; i < len; i++) {
+ m += adapter.getDouble(da, i);
+ }
+ means[j] = m / len;
+ }
+ // Build the covariance matrix, lower triangular half
+ double[] vst = new double[dims];
+ double[] cov = new double[(dims * (dims - 1)) >> 1];
+ double[] buf = new double[dims];
+ for(int i = 0; i < len; i++) {
+ for(int j = 0; j < dims; j++) {
+ buf[j] = adapter.getDouble(data.get(j), i) - means[j];
+ }
+ for(int y = 0, c = 0; y < dims; y++) {
+ for(int x = 0; x < y; x++) {
+ cov[c++] += buf[x] * buf[y];
+ }
+ vst[y] += buf[y] * buf[y];
+ }
+ }
+ // Compute standard deviations (times sqrt(len)!):
+ for(int y = 0; y < dims; y++) {
+ if(vst[y] == 0.) {
+ LOG.warning("Correlation is not well defined for constant attributes.");
+ }
+ vst[y] = Math.sqrt(vst[y]);
+ }
+ for(int y = 1, c = 0; y < dims; y++) {
+ for(int x = 0; x < y; x++) {
+ // We don't need to divide by sqrt(len), because it will cancel out with
+ // the division we skipped just above.
+ cov[c] = cov[c] / (vst[x] * vst[y]);
+ c++;
+ }
+ }
+ return cov;
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected CorrelationDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/DependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/DependenceMeasure.java
new file mode 100644
index 00000000..0e9e02c0
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/DependenceMeasure.java
@@ -0,0 +1,98 @@
+package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ 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.List;
+
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+
+/**
+ * Measure the dependence of two variables.
+ *
+ * @author Erich Schubert
+ */
+public interface DependenceMeasure {
+ /**
+ * Measure the dependence of two variables.
+ *
+ * This is the more flexible API, which allows using different internal data
+ * representations.
+ *
+ * @param adapter1 First data adapter
+ * @param data1 First data set
+ * @param adapter2 Second data adapter
+ * @param data2 Second data set
+ * @param <A> First array type
+ * @param <B> Second array type
+ * @return Dependence measure
+ */
+ <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2);
+
+ /**
+ * Measure the dependence of two variables.
+ *
+ * This is the more flexible API, which allows using different internal data
+ * representations.
+ *
+ * @param adapter Array type adapter
+ * @param data1 First data set
+ * @param data2 Second data set
+ * @param <A> Array type
+ * @return Dependence measure
+ */
+ <A> double dependence(NumberArrayAdapter<?, A> adapter, A data1, A data2);
+
+ /**
+ * Measure the dependence of two variables.
+ *
+ * This is the more flexible API, which allows using different internal data
+ * representations.
+ *
+ * The resulting data is a serialized lower triangular matrix:
+ *
+ * <pre>
+ * X S S S S S
+ * 0 X S S S S
+ * 1 2 X S S S
+ * 3 4 5 X S S
+ * 6 7 8 9 X S
+ * 10 11 12 13 14 X
+ * </pre>
+ *
+ * @param adapter Data adapter
+ * @param data Data sets. Must have fast random access!
+ * @param <A> Array type
+ * @return Lower triangular serialized matrix
+ */
+ <A> double[] dependence(NumberArrayAdapter<?, A> adapter, List<? extends A> data);
+
+ /**
+ * Measure the dependence of two variables.
+ *
+ * @param data1 First data set
+ * @param data2 Second data set
+ * @return Dependence measure
+ */
+ double dependence(double[] data1, double[] data2);
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/DistanceCorrelationDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/DistanceCorrelationDependenceMeasure.java
new file mode 100644
index 00000000..1ae8d6b5
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/DistanceCorrelationDependenceMeasure.java
@@ -0,0 +1,206 @@
+package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ 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.List;
+
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Distance correlation.
+ *
+ * The value returned is the square root of the dCor² value. This matches the R
+ * implementation by the original authors.
+ *
+ * Reference:
+ * <p>
+ * Székely, G. J., Rizzo, M. L., & Bakirov, N. K.<br />
+ * Measuring and testing dependence by correlation of distances<br />
+ * The Annals of Statistics, 35(6), 2769-2794
+ * </p>
+ *
+ * Implementation notice: we exploit symmetry, and thus use diagonal matrixes.
+ * While initially the diagonal is zero, after double-centering the matrix these
+ * values can become non-zero!
+ *
+ * @author Marie Kiermeier
+ * @author Erich Schubert
+ */
+@Reference(authors = "Székely, G. J., Rizzo, M. L., & Bakirov, N. K.", //
+title = "Measuring and testing dependence by correlation of distances", //
+booktitle = "The Annals of Statistics, 35(6), 2769-2794", //
+url = "http://dx.doi.org/10.1214/009053607000000505")
+public class DistanceCorrelationDependenceMeasure extends AbstractDependenceMeasure {
+ /**
+ * Static instance.
+ */
+ public static final DistanceCorrelationDependenceMeasure STATIC = new DistanceCorrelationDependenceMeasure();
+
+ /**
+ * Constructor - use {@link #STATIC} instance instead!
+ */
+ protected DistanceCorrelationDependenceMeasure() {
+ super();
+ }
+
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+ double[] dMatrixA = computeDistances(adapter1, data1);
+ double[] dMatrixB = computeDistances(adapter2, data2);
+
+ // distance variance
+ double dVarA = computeDCovar(dMatrixA, dMatrixA, len);
+ if(!(dVarA > 0.)) {
+ return 0.;
+ }
+ double dVarB = computeDCovar(dMatrixB, dMatrixB, len);
+ if(!(dVarB > 0.)) {
+ return 0.;
+ }
+ double dCovar = computeDCovar(dMatrixA, dMatrixB, len);
+ // distance correlation
+ return Math.sqrt(dCovar / Math.sqrt(dVarA * dVarB));
+ }
+
+ @Override
+ public <A> double[] dependence(NumberArrayAdapter<?, A> adapter, List<? extends A> data) {
+ final int dims = data.size();
+ final int len = size(adapter, data);
+ double[][] dMatrix = new double[dims][];
+ for(int i = 0; i < dims; i++) {
+ dMatrix[i] = computeDistances(adapter, data.get(i));
+ }
+ double[] dVar = new double[dims];
+ for(int i = 0; i < dims; i++) {
+ dVar[i] = computeDCovar(dMatrix[i], dMatrix[i], len);
+ }
+ double[] dCor = new double[(dims * (dims - 1)) >> 1];
+ for(int y = 1, c = 0; y < dims; y++) {
+ for(int x = 0; x < y; x++) {
+ if(!(dVar[x] * dVar[y] > 0.)) {
+ dCor[c++] = 0.;
+ continue;
+ }
+ double dCovar = computeDCovar(dMatrix[x], dMatrix[y], len);
+ dCor[c++] = Math.sqrt(dCovar / Math.sqrt(dVar[x] * dVar[y]));
+ }
+ }
+ return dCor;
+ }
+
+ /**
+ * Compute the double-centered delta matrix.
+ *
+ * @param adapter Data adapter
+ * @param data Input data
+ * @return Double-centered delta matrix.
+ */
+ protected static <A> double[] computeDistances(NumberArrayAdapter<?, A> adapter, A data) {
+ final int size = adapter.size(data);
+ double[] dMatrix = new double[(size * (size + 1)) >> 1];
+ for(int i = 0, c = 0; i < size; i++) {
+ for(int j = 0; j < i; j++) {
+ double dx = adapter.getDouble(data, i) - adapter.getDouble(data, j);
+ dMatrix[c++] = (dx < 0) ? -dx : dx; // Absolute difference.
+ }
+ c++; // Diagonal entry: zero
+ }
+ doubleCenterMatrix(dMatrix, size);
+ return dMatrix;
+ }
+
+ /**
+ * Computes the distance variance matrix of one axis.
+ *
+ * @param dMatrix distance matrix of the axis
+ * @param size Dimensionality
+ */
+ public static void doubleCenterMatrix(double[] dMatrix, int size) {
+ double[] rowMean = new double[size];
+ // row sum
+ for(int i = 0, c = 0; i < size; i++) {
+ for(int j = 0; j < i; j++) {
+ double v = dMatrix[c++];
+ rowMean[i] += v;
+ rowMean[j] += v;
+ }
+ assert (dMatrix[c] == 0.);
+ c++; // Diagonal entry. Must be zero!
+ }
+ // Normalize averages:
+ double matrixMean = 0.;
+ for(int i = 0; i < size; i++) {
+ matrixMean += rowMean[i];
+ rowMean[i] /= size;
+ }
+ matrixMean /= size * size;
+
+ for(int o = 0, c = 0; o < size; o++) {
+ // Including row mean!
+ for(int p = 0; p <= o; p++) {
+ dMatrix[c++] -= rowMean[o] + rowMean[p] - matrixMean;
+ }
+ }
+ }
+
+ /**
+ * Computes the distance covariance for two axis. Can also be used to compute
+ * the distance variance of one axis (dVarMatrixA = dVarMatrixB).
+ *
+ * @param dVarMatrixA distance variance matrix of the first axis
+ * @param dVarMatrixB distance variance matrix of the second axis
+ * @param n number of points
+ * @return distance covariance
+ */
+ protected double computeDCovar(double[] dVarMatrixA, double[] dVarMatrixB, int n) {
+ double result = 0.;
+ for(int i = 0, c = 0; i < n; i++) {
+ for(int j = 0; j < i; j++) {
+ result += 2. * dVarMatrixA[c] * dVarMatrixB[c];
+ c++;
+ }
+ // Diagonal entry.
+ result += dVarMatrixA[c] * dVarMatrixB[c];
+ c++;
+ }
+ return result / (n * n);
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Marie Kiermeier
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected DistanceCorrelationDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HSMDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HSMDependenceMeasure.java
new file mode 100644
index 00000000..aaacb888
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HSMDependenceMeasure.java
@@ -0,0 +1,245 @@
+package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ 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.math.SinCosTable;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Compute the similarity of dimensions by using a hough transformation.
+ *
+ * Reference: <br>
+ * <p>
+ * A. Tatu, G. Albuquerque, M. Eisemann, P. Bak, H. Theisel, M. A. Magnor, and
+ * D. A. Keim.<br />
+ * Automated Analytical Methods to Support Visual Exploration of High-
+ * Dimensional Data. <br/>
+ * IEEEVisualization and Computer Graphics, 2011.
+ * </p>
+ *
+ * FIXME: This needs serious TESTING before release. Large parts have been
+ * rewritten, but could not be tested at the time of rewriting.
+ *
+ * @author Erich Schubert
+ * @author Robert Rödler
+ */
+@Reference(authors = "A. Tatu, G. Albuquerque, M. Eisemann, P. Bak, H. Theisel, M. A. Magnor, and D. A. Keim", //
+title = "Automated Analytical Methods to Support Visual Exploration of High-Dimensional Data", //
+booktitle = "IEEE Trans. Visualization and Computer Graphics, 2011", //
+url = "http://dx.doi.org/10.1109/TVCG.2010.242")
+public class HSMDependenceMeasure extends AbstractDependenceMeasure {
+ /**
+ * Static instance.
+ */
+ public static final HSMDependenceMeasure STATIC = new HSMDependenceMeasure();
+
+ /**
+ * Angular resolution. Best if divisible by 4: smaller tables.
+ *
+ * The original publication used 50.
+ */
+ private final static int STEPS = 48; // 64;
+
+ /**
+ * Resolution of image.
+ */
+ private final int resolution = 512;
+
+ /**
+ * Precompute sinus and cosinus
+ */
+ private final static SinCosTable table = SinCosTable.make(STEPS);
+
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+ boolean[][] pic = new boolean[resolution][resolution];
+
+ // Get attribute value range:
+ final double off1, scale1, off2, scale2;
+ {
+ double mi = adapter1.getDouble(data1, 0), ma = mi;
+ for(int i = 1; i < len; ++i) {
+ double v = adapter1.getDouble(data1, i);
+ if(v < mi) {
+ mi = v;
+ }
+ else if(v > ma) {
+ ma = v;
+ }
+ }
+ off1 = mi;
+ scale1 = (ma > mi) ? (1. / (ma - mi)) : 1.;
+ // Second data
+ mi = adapter2.getDouble(data2, 0);
+ ma = mi;
+ for(int i = 1; i < len; ++i) {
+ double v = adapter2.getDouble(data2, i);
+ if(v < mi) {
+ mi = v;
+ }
+ else if(v > ma) {
+ ma = v;
+ }
+ }
+ off2 = mi;
+ scale2 = (ma > mi) ? (1. / (ma - mi)) : 1.;
+ }
+ // Iterate dataset
+ for(int i = 0; i < len; ++i) {
+ double xi = (adapter1.getDouble(data1, i) - off1) * scale1;
+ double xj = (adapter2.getDouble(data2, i) - off2) * scale2;
+ drawLine(0, (int) (resolution * xi), resolution - 1, (int) (resolution * xj), pic);
+ }
+
+ final double stepsq = (double) STEPS * (double) STEPS;
+ int[][] hough = houghTransformation(pic);
+ // The original publication said "median", but judging from the text,
+ // meant "mean". Otherwise, always half of the cells are above the
+ // threshold, which doesn't match the explanation there.
+ double mean = sumMatrix(hough) / stepsq;
+ int abovemean = countAboveThreshold(hough, mean);
+
+ return 1. - (abovemean / stepsq);
+ }
+
+ /**
+ * Compute the sum of a matrix.
+ *
+ * @param mat Matrix
+ * @return Sum of all elements
+ */
+ private long sumMatrix(int[][] mat) {
+ long ret = 0;
+ for(int i = 0; i < mat.length; i++) {
+ final int[] row = mat[i];
+ for(int j = 0; j < row.length; j++) {
+ ret += row[j];
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Count the number of cells above the threshold.
+ *
+ * @param mat Matrix
+ * @param threshold Threshold
+ * @return Number of elements above the threshold.
+ */
+ private int countAboveThreshold(int[][] mat, double threshold) {
+ int ret = 0;
+ for(int i = 0; i < mat.length; i++) {
+ int[] row = mat[i];
+ for(int j = 0; j < row.length; j++) {
+ if(row[j] >= threshold) {
+ ret++;
+ }
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Perform a hough transformation on the binary image in "mat".
+ *
+ * @param mat Binary image
+ * @return Hough transformation of image.
+ */
+ private int[][] houghTransformation(boolean[][] mat) {
+ final int xres = mat.length, yres = mat[0].length;
+ final double tscale = STEPS * .5 / (xres + yres);
+ final int[][] ret = new int[STEPS][STEPS];
+
+ for(int x = 0; x < mat.length; x++) {
+ for(int y = 0; y < mat[0].length; y++) {
+ if(mat[x][y]) {
+ for(int i = 0; i < STEPS; i++) {
+ final int d = (STEPS >> 1) + (int) (tscale * (x * table.cos(i) + y * table.sin(i)));
+ if(d > 0 && d < STEPS) {
+ ret[d][i]++;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+ }
+
+ /**
+ * Draw a line onto the array, using the classic Bresenham algorithm.
+ *
+ * @param x0 Start X
+ * @param y0 Start Y
+ * @param x1 End X
+ * @param y1 End Y
+ * @param pic Picture array
+ */
+ private static void drawLine(int x0, int y0, int x1, int y1, boolean[][] pic) {
+ final int xres = pic.length, yres = pic[0].length;
+ // Ensure bounds
+ y0 = (y0 < 0) ? 0 : (y0 >= yres) ? (yres - 1) : y0;
+ y1 = (y1 < 0) ? 0 : (y1 >= yres) ? (yres - 1) : y1;
+ x0 = (x0 < 0) ? 0 : (x0 >= xres) ? (xres - 1) : x0;
+ x1 = (x1 < 0) ? 0 : (x1 >= xres) ? (xres - 1) : x1;
+ // Default slope
+ final int dx = +Math.abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
+ final int dy = -Math.abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
+ // Error counter
+ int err = dx + dy;
+
+ for(;;) {
+ pic[x0][y0] = true;
+ if(x0 == x1 && y0 == y1) {
+ break;
+ }
+
+ final int e2 = err << 1;
+ if(e2 > dy) {
+ err += dy;
+ x0 += sx;
+ }
+ if(e2 < dx) {
+ err += dx;
+ y0 += sy;
+ }
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected HSMDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HiCSDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HiCSDependenceMeasure.java
new file mode 100644
index 00000000..e760ef83
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HiCSDependenceMeasure.java
@@ -0,0 +1,243 @@
+package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ 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.Random;
+
+import de.lmu.ifi.dbs.elki.algorithm.outlier.meta.HiCS;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.statistics.tests.GoodnessOfFitTest;
+import de.lmu.ifi.dbs.elki.math.statistics.tests.KolmogorovSmirnovTest;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerArrayQuickSort;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerComparator;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+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.constraints.CommonConstraints;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
+
+/**
+ * Use the statistical tests as used by HiCS to measure dependence of variables.
+ *
+ * Reference:
+ * <p>
+ * Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek:<br />
+ * Interactive Data Mining with 3D-Parallel-Coordinate-Trees.<br />
+ * Proceedings of the 2013 ACM International Conference on Management of Data
+ * (SIGMOD), New York City, NY, 2013.
+ * </p>
+ *
+ * Based on:
+ * <p>
+ * F. Keller, E. Müller, and K. Böhm.<br />
+ * HiCS: High Contrast Subspaces for Density-Based Outlier Ranking. <br />
+ * In ICDE, pages 1037–1048, 2012.
+ * </p>
+ *
+ * @author Erich Schubert
+ * @author Robert Rödler
+ */
+@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", //
+title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", //
+booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", //
+url = "http://dx.doi.org/10.1145/2463676.2463696")
+public class HiCSDependenceMeasure extends AbstractDependenceMeasure {
+ /**
+ * Monte-Carlo iterations
+ */
+ private int m = 50;
+
+ /**
+ * Alpha threshold
+ */
+ private double alphasqrt = Math.sqrt(0.1);
+
+ /**
+ * Statistical test to use
+ */
+ private GoodnessOfFitTest statTest;
+
+ /**
+ * Random generator
+ */
+ private RandomFactory rnd;
+
+ /**
+ * Constructor.
+ *
+ * @param statTest Test function
+ * @param m Number of monte-carlo iterations
+ * @param alpha Alpha threshold
+ * @param rnd Random source
+ */
+ public HiCSDependenceMeasure(GoodnessOfFitTest statTest, int m, double alpha, RandomFactory rnd) {
+ super();
+ this.statTest = statTest;
+ this.m = m;
+ this.alphasqrt = Math.sqrt(alpha);
+ this.rnd = rnd;
+ }
+
+ @Override
+ public <A, B> double dependence(final NumberArrayAdapter<?, A> adapter1, final A data1, final NumberArrayAdapter<?, B> adapter2, final B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+ final int windowsize = (int) (len * alphasqrt);
+ final Random random = rnd.getSingleThreadedRandom();
+
+ // Sorted copies for slicing.
+ int[] s1 = MathUtil.sequence(0, len), s2 = MathUtil.sequence(0, len);
+ IntegerArrayQuickSort.sort(s1, new IntegerComparator() {
+ @Override
+ public int compare(int x, int y) {
+ return Double.compare(adapter1.getDouble(data1, x), adapter1.getDouble(data1, y));
+ }
+ });
+ IntegerArrayQuickSort.sort(s2, new IntegerComparator() {
+ @Override
+ public int compare(int x, int y) {
+ return Double.compare(adapter2.getDouble(data2, x), adapter2.getDouble(data2, y));
+ }
+ });
+
+ // Distributions for testing
+ double[] fullValues = new double[len];
+ double[] sampleValues = new double[windowsize];
+ double deviationSum = 0.;
+
+ // For the first half, we use the first dimension as reference
+ for(int i = 0; i < len; i++) {
+ fullValues[i] = adapter1.getDouble(data1, i);
+ if(fullValues[i] != fullValues[i]) {
+ throw new AbortException("NaN values are not allowed by this implementation!");
+ }
+ }
+
+ int half = m >> 1; // TODO: remove bias?
+ for(int i = 0; i < half; ++i) {
+ // Build the sample
+ for(int j = random.nextInt(len - windowsize), k = 0; k < windowsize; ++k, ++j) {
+ sampleValues[k] = adapter2.getDouble(data2, j);
+ }
+ double contrast = statTest.deviation(fullValues, sampleValues);
+ if(Double.isNaN(contrast)) {
+ --i; // Retry.
+ continue;
+ }
+ deviationSum += contrast;
+ }
+
+ // For the second half, we use the second dimension as reference
+ for(int i = 0; i < len; i++) {
+ fullValues[i] = adapter2.getDouble(data2, i);
+ if(fullValues[i] != fullValues[i]) {
+ throw new AbortException("NaN values are not allowed by this implementation!");
+ }
+ }
+
+ for(int i = half; i < m; ++i) {
+ // Build the sample
+ for(int j = random.nextInt(len - windowsize), k = 0; k < windowsize; ++k, ++j) {
+ sampleValues[k] = adapter1.getDouble(data1, j);
+ }
+ double contrast = statTest.deviation(fullValues, sampleValues);
+ if(Double.isNaN(contrast)) {
+ --i; // Retry.
+ continue;
+ }
+ deviationSum += contrast;
+ }
+
+ return deviationSum / m;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Statistical test to use
+ */
+ private GoodnessOfFitTest statTest;
+
+ /**
+ * Holds the value of
+ * {@link de.lmu.ifi.dbs.elki.algorithm.outlier.meta.HiCS.Parameterizer#M_ID}
+ * .
+ */
+ private int m = 50;
+
+ /**
+ * Holds the value of
+ * {@link de.lmu.ifi.dbs.elki.algorithm.outlier.meta.HiCS.Parameterizer#ALPHA_ID}
+ * .
+ */
+ private double alpha = 0.1;
+
+ /**
+ * Random generator.
+ */
+ private RandomFactory rnd;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ final IntParameter mP = new IntParameter(HiCS.Parameterizer.M_ID, 50);
+ mP.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
+ if(config.grab(mP)) {
+ m = mP.intValue();
+ }
+
+ final DoubleParameter alphaP = new DoubleParameter(HiCS.Parameterizer.ALPHA_ID, 0.1);
+ alphaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ if(config.grab(alphaP)) {
+ alpha = alphaP.doubleValue();
+ }
+
+ final ObjectParameter<GoodnessOfFitTest> testP = new ObjectParameter<>(HiCS.Parameterizer.TEST_ID, GoodnessOfFitTest.class, KolmogorovSmirnovTest.class);
+ if(config.grab(testP)) {
+ statTest = testP.instantiateClass(config);
+ }
+
+ final RandomParameter rndP = new RandomParameter(HiCS.Parameterizer.SEED_ID);
+ if(config.grab(rndP)) {
+ rnd = rndP.getValue();
+ }
+ }
+
+ @Override
+ protected HiCSDependenceMeasure makeInstance() {
+ return new HiCSDependenceMeasure(statTest, m, alpha, rnd);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HoeffdingsDDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HoeffdingsDDependenceMeasure.java
new file mode 100644
index 00000000..7f1f9fc4
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/HoeffdingsDDependenceMeasure.java
@@ -0,0 +1,207 @@
+package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ 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.math.MathUtil;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Calculate Hoeffding's D as a measure of dependence.
+ *
+ * References:
+ * <p>
+ * W. Hoeffding:<br />
+ * A non-parametric test of independence<br />
+ * The Annals of Mathematical Statistics 19:546–57
+ * </p>
+ *
+ * The resulting value is scaled by 30, so it is in the range {@code [-.5;1]}.
+ *
+ * @author Yinchong Yang
+ * @author Erich Schubert
+ */
+@Reference(authors = "W. Hoeffding", //
+title = "A non-parametric test of independence", //
+booktitle = "The Annals of Mathematical Statistics 19", //
+url = "http://www.jstor.org/stable/2236021")
+public class HoeffdingsDDependenceMeasure extends AbstractDependenceMeasure {
+ /**
+ * Static instance.
+ */
+ public static final HoeffdingsDDependenceMeasure STATIC = new HoeffdingsDDependenceMeasure();
+
+ /**
+ * Constructor - use {@link #STATIC} instance.
+ */
+ protected HoeffdingsDDependenceMeasure() {
+ super();
+ }
+
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int n = size(adapter1, data1, adapter2, data2);
+ assert (n > 4) : "Hoeffdings D needs at least 5 elements!";
+ if(n <= 4) {
+ return Double.NaN;
+ }
+ double[] r = ranks(adapter1, data1, n);
+ double[] s = ranks(adapter2, data2, n);
+ // TODO: is it possible to exploit sorting to accelerate computing q?
+ double[] q = computeBivariateRanks(adapter1, data1, adapter2, data2, n);
+
+ double d1 = 0, d2 = 0, d3 = 0;
+ for(int i = 0; i < n; i++) {
+ d1 += q[i] * (q[i] - 1); // Note: our q is 0-indexed.
+ d2 += (r[i] - 1) * (r[i] - 2) * (s[i] - 1) * (s[i] - 2);
+ d3 += (r[i] - 2) * (s[i] - 2) * q[i];
+ }
+
+ // Factor n-2 was moved for better numerical behavior.
+ double nom = (n - 3.) * d1 + d2 / (n - 2) - 2. * d3;
+ double div = n * (n - 1.) * (n - 3.) * (n - 4.);
+ double d = 30 * nom / div;
+ return d < 1. ? d : 1.;
+ }
+
+ /**
+ * Compute bivariate ranks.
+ *
+ * q[i] is the number of objects such that x[j] < x[i] and y[j] < y[i]
+ *
+ * @param adapter1 First adapter
+ * @param data1 First data set
+ * @param adapter2 Second adapter
+ * @param data2 Second data set
+ * @param len Length
+ * @return Bivariate rank statistics.
+ */
+ protected static <A, B> double[] computeBivariateRanks(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2, int len) {
+ double[] ret = new double[len];
+ for(int i = 0; i < len; i++) {
+ for(int j = i + 1; j < len; j++) {
+ double xi = adapter1.getDouble(data1, i), xj = adapter1.getDouble(data1, j);
+ double yi = adapter2.getDouble(data2, i), yj = adapter2.getDouble(data2, j);
+ if(xi < xj) {
+ ret[j] += (yi < yj) ? 1 : (yi == yj) ? .5 : 0;
+ }
+ else if(xj < xi) {
+ ret[i] += (yj < yi) ? 1 : (yj == yi) ? .5 : 0;
+ }
+ else { // tied on x
+ if(yi < yj) {
+ ret[j] += .5;
+ }
+ else if(yj < yi) {
+ ret[i] += .5;
+ }
+ else { // Double tied
+ ret[i] += .25;
+ ret[j] += .25;
+ }
+ }
+ }
+ }
+ return ret;
+ }
+
+ // Tabular approximation
+ private final static double[] TABVAL = { //
+ 0.5297, 0.4918, 0.4565, 0.4236, 0.393, //
+ 0.3648, 0.3387, 0.3146, 0.2924, 0.2719, // 10
+ 0.253, 0.2355, 0.2194, 0.2045, 0.1908, //
+ 0.1781, 0.1663, 0.1554, 0.1453, 0.1359, // 20
+ 0.1273, 0.1192, 0.1117, 0.1047, 0.0982, //
+ 0.0921, 0.0864, 0.0812, 0.0762, 0.0716, // 30
+ 0.0673, 0.0633, 0.0595, 0.056, 0.0527, //
+ 0.0496, 0.0467, 0.044, 0.0414, 0.039, // 40
+ 0.0368, 0.0347, 0.0327, 0.0308, 0.0291, //
+ 0.0274, 0.0259, 0.0244, 0.023, 0.0217, // 50
+ 0.0205, 0.0194, 0.0183, 0.0173, 0.0163, //
+ 0.0154, 0.0145, 0.0137, 0.013, 0.0123, // 60
+ 0.0116, 0.011, 0.0104, 0.0098, 0.0093, //
+ 0.0087, 0.0083, 0.0078, 0.0074, 0.007, // 70
+ 0.0066, 0.0063, 0.0059, 0.0056, 0.0053, //
+ 0.005, 0.0047, 0.0045, 0.0042, 0.0025, // 80
+ 0.0014, 0.0008, 0.0005, 0.0003, 0.0002, 0.0001 };
+
+ // Table positions
+ private final static double[] TABPOS = new double[] { //
+ 1.10, 1.15, 1.20, 1.25, 1.30, 1.35, 1.40, 1.45, 1.50, 1.55, //
+ 1.60, 1.65, 1.70, 1.75, 1.80, 1.85, 1.90, 1.95, 2.00, 2.05, //
+ 2.10, 2.15, 2.20, 2.25, 2.30, 2.35, 2.40, 2.45, 2.50, 2.55, //
+ 2.60, 2.65, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, //
+ 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, //
+ 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00, 4.05, //
+ 4.10, 4.15, 4.20, 4.25, 4.30, 4.35, 4.40, 4.45, 4.50, 4.55, //
+ 4.60, 4.65, 4.70, 4.75, 4.80, 4.85, 4.90, 4.95, 5.00, //
+ 5.50, 6.00, 6.50, 7.00, 7.50, 8.00, 8.50 };
+
+ /**
+ * Convert Hoeffding D value to a p-value.
+ *
+ * @param d D value
+ * @param n Data set size
+ * @return p-value
+ */
+ public double toPValue(double d, int n) {
+ double b = d / 30 + 1. / (36 * n);
+ double z = .5 * MathUtil.PISQUARE * MathUtil.PISQUARE * n * b;
+
+ // Exponential approximation
+ if(z < 1.1 || z > 8.5) {
+ double e = Math.exp(0.3885037 - 1.164879 * z);
+ return (e > 1) ? 1 : (e < 0) ? 0 : e;
+ }
+ // Tabular approximation
+ for(int i = 0; i < 86; i++) {
+ if(TABPOS[i] >= z) {
+ // Exact table value
+ if(TABPOS[i] == z) {
+ return TABVAL[i];
+ }
+ // Linear interpolation
+ double x1 = TABPOS[i], x0 = TABPOS[i - 1];
+ double y1 = TABVAL[i], y0 = TABVAL[i - 1];
+ return y0 + (y1 - y0) * (z - x0) / (x1 - x0);
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected HoeffdingsDDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/JensenShannonEquiwidthDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/JensenShannonEquiwidthDependenceMeasure.java
new file mode 100644
index 00000000..7b0000a3
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/JensenShannonEquiwidthDependenceMeasure.java
@@ -0,0 +1,143 @@
+package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ 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.math.MathUtil;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Jensen-Shannon Divergence is closely related to mutual information.
+ *
+ * The output value is normalized, such that an evenly distributed and identical
+ * distribution will yield a value of 1. Independent distributions may still
+ * yield values close to .25, though.
+ *
+ * TODO: Offer normalized and non-normalized variants?
+ *
+ * @author Erich Schubert
+ */
+public class JensenShannonEquiwidthDependenceMeasure extends AbstractDependenceMeasure {
+ /**
+ * Static instance.
+ */
+ public static final JensenShannonEquiwidthDependenceMeasure STATIC = new JensenShannonEquiwidthDependenceMeasure();
+
+ /**
+ * Constructor - use {@link #STATIC} instance.
+ */
+ protected JensenShannonEquiwidthDependenceMeasure() {
+ super();
+ }
+
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+ final int bins = (int) Math.round(Math.sqrt(len));
+ final int maxbin = bins - 1;
+
+ double min1 = adapter1.getDouble(data1, 0), max1 = min1;
+ double min2 = adapter2.getDouble(data2, 0), max2 = min2;
+ for(int i = 1; i < len; i++) {
+ final double vx = adapter1.getDouble(data1, i);
+ final double vy = adapter2.getDouble(data2, i);
+ if(vx < min1) {
+ min1 = vx;
+ }
+ else if(vx > max1) {
+ max1 = vx;
+ }
+ if(vy < min2) {
+ min2 = vy;
+ }
+ else if(vy > max2) {
+ max2 = vy;
+ }
+ }
+ final double scale1 = (max1 > min1) ? bins / (max1 - min1) : 1;
+ final double scale2 = (max2 > min2) ? bins / (max2 - min2) : 1;
+
+ int[] margin1 = new int[bins], margin2 = new int[bins];
+ int[][] counts = new int[bins][bins];
+ for(int i = 0; i < len; i++) {
+ int bin1 = (int) Math.floor((adapter1.getDouble(data1, i) - min1) * scale1);
+ int bin2 = (int) Math.floor((adapter2.getDouble(data2, i) - min2) * scale2);
+ bin1 = bin1 < bins ? bin1 : maxbin;
+ bin2 = bin2 < bins ? bin2 : maxbin;
+ margin1[bin1]++;
+ margin2[bin2]++;
+ counts[bin1][bin2]++;
+ }
+
+ // calculating relative frequencies
+ double e = 0;
+ for(int bin1 = 0; bin1 < counts.length; bin1++) {
+ // Margin value for row i.
+ final int sum1 = margin1[bin1];
+ // Skip empty rows early.
+ if(sum1 == 0) {
+ continue;
+ }
+ // Inverse pX
+ final double pX = sum1 / (double) len;
+ final int[] row = counts[bin1];
+ for(int bin2 = 0; bin2 < row.length; bin2++) {
+ final int sum2 = margin2[bin2];
+ if(sum2 > 0) {
+ final int cell = row[bin2];
+ // JS divergence of pXY and (pX * pY)
+ double pXY = cell / (double) len;
+ final double pXpY = pX * sum2 / len;
+ final double iavg = 2. / (pXY + pXpY);
+ e += pXY > 0. ? pXY * Math.log(pXY * iavg) : 0.;
+ e += pXpY * Math.log(pXpY * iavg);
+ }
+ }
+ }
+ // Expected value for evenly distributed and identical:
+ // pX = pY = 1/b and thus pXpY = 1/b^2.
+ // for i==j, pXY=1/b and thus iavg = 2*b*b/(b+1)
+ // otherwise, pXY=0 and thus iavg = 2*b*b
+ // pXY: e += log(b*2/(b+1)) = log(b) + log(2/(b+1))
+ // pXpY1: e += 1/b*log(2/(b+1)) = 1/b*log(2/(b+1))
+ // pXpY2: e += (b-1)/b*log(2) = (b-1)/b*log(2)
+ final double exp = Math.log(bins) + (1. + 1. / bins) * Math.log(2. / (bins + 1)) + (bins - 1.) / bins * MathUtil.LOG2;
+ // e *= .5; // Average, but we need to adjust exp then, too!
+ return e / exp;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected JensenShannonEquiwidthDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/MCEDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/MCEDependenceMeasure.java
new file mode 100644
index 00000000..899aff9a
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/MCEDependenceMeasure.java
@@ -0,0 +1,274 @@
+package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ 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.ArrayList;
+import java.util.Arrays;
+
+import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerArrayQuickSort;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerComparator;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Compute a mutual information based dependence measure using a nested means
+ * discretization, originally proposed for ordering axes in parallel coordinate
+ * plots.
+ *
+ * Reference:
+ * <p>
+ * D. Guo<br />
+ * Coordinating computational and visual approaches for interactive feature
+ * selection and multivariate clustering<br />
+ * Information Visualization, 2(4), 2003.
+ * </p>
+ *
+ * @author Erich Schubert
+ */
+@Reference(authors = "D. Guo", //
+title = "Coordinating computational and visual approaches for interactive feature selection and multivariate clustering", //
+booktitle = "Information Visualization, 2(4)", //
+url = "http://dx.doi.org/10.1057/palgrave.ivs.9500053")
+public class MCEDependenceMeasure extends AbstractDependenceMeasure {
+ /**
+ * Static instance.
+ */
+ public static final MCEDependenceMeasure STATIC = new MCEDependenceMeasure();
+
+ /**
+ * Desired size: 35 observations.
+ *
+ * While this could trivially be made parameterizable, it is a reasonable rule
+ * of thumb and not expected to have a major effect.
+ */
+ public static final int TARGET = 35;
+
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+ // Find a number of bins as recommended by Cheng et al.
+ double p = MathUtil.log2(len / (double) TARGET);
+ // As we are in 2d, take the root (*.5) But let's use at least 1, too.
+ // Check: for 10000 this should give 4, for 150 it gives 1.
+ int power = Math.max(1, (int) Math.floor(p * .5));
+ int gridsize = 1 << power;
+ double loggrid = Math.log((double) gridsize);
+
+ ArrayList<int[]> parts1 = buildPartitions(adapter1, data1, len, power);
+ ArrayList<int[]> parts2 = buildPartitions(adapter2, data2, len, power);
+
+ int[][] res = new int[gridsize][gridsize];
+ intersectionMatrix(res, parts1, parts2, gridsize);
+ return 1. - getMCEntropy(res, parts1, parts2, len, gridsize, loggrid);
+ }
+
+ /**
+ * Partitions an attribute.
+ *
+ * @param adapter1 Data adapter
+ * @param data1 Data set
+ * @param len Length of data
+ * @param depth Splitting depth
+ * @return List of sorted objects
+ */
+ private <A> ArrayList<int[]> buildPartitions(NumberArrayAdapter<?, A> adapter1, A data1, int len, int depth) {
+ final int[] idx = new int[len];
+ final double[] tmp = new double[len];
+ for(int i = 0; i < len; ++i) {
+ idx[i] = i;
+ tmp[i] = adapter1.getDouble(data1, i);
+ }
+ // Sort indexes:
+ IntegerArrayQuickSort.sort(idx, new IntegerComparator() {
+ @Override
+ public int compare(int x, int y) {
+ return Double.compare(tmp[x], tmp[y]);
+ }
+ });
+ Arrays.sort(tmp); // Should yield the same ordering
+
+ ArrayList<int[]> ret = new ArrayList<>(1 << depth);
+ divide(idx, tmp, ret, 0, tmp.length, depth);
+ return ret;
+ }
+
+ /**
+ * Recursive call to further subdivide the array.
+ *
+ * @param idx Object indexes.
+ * @param data 1D data, sorted
+ * @param ret Output index
+ * @param start Interval start
+ * @param end Interval end
+ * @param depth Depth
+ */
+ private void divide(int[] idx, double[] data, ArrayList<int[]> ret, int start, int end, int depth) {
+ if(depth == 0) {
+ int[] a = Arrays.copyOfRange(idx, start, end);
+ Arrays.sort(a);
+ ret.add(a);
+ return;
+ }
+ final int count = end - start;
+ if(count == 0) {
+ // Corner case, that should barely happen. But for ties, we currently
+ // Do not yet assure that it doesn't happen!
+ for(int j = 1 << depth; j > 0; --j) {
+ ret.add(new int[0]);
+ }
+ return;
+ }
+ double m = 0.;
+ for(int i = start; i < end; i++) {
+ m += data[i];
+ }
+ m /= count;
+ int pos = Arrays.binarySearch(data, start, end, m);
+ if(pos >= 0) {
+ // Ties: try to choose the most central element.
+ final int opt = (start + end) >> 1;
+ while(data[pos] == m) {
+ if(pos < opt) {
+ pos++;
+ }
+ else if(pos > opt) {
+ pos--;
+ }
+ else {
+ break;
+ }
+ }
+ }
+ else {
+ pos = (-pos - 1);
+ }
+ divide(idx, data, ret, start, pos, depth - 1);
+ divide(idx, data, ret, pos, end, depth - 1);
+ }
+
+ /**
+ * Intersect the two 1d grid decompositions, to obtain a 2d matrix.
+ *
+ * @param res Output matrix to fill
+ * @param partsx Partitions in first component
+ * @param partsy Partitions in second component.
+ * @param gridsize Size of partition decomposition
+ */
+ private void intersectionMatrix(int[][] res, ArrayList<int[]> partsx, ArrayList<int[]> partsy, int gridsize) {
+ for(int x = 0; x < gridsize; x++) {
+ final int[] px = partsx.get(x);
+ final int[] rowx = res[x];
+ for(int y = 0; y < gridsize; y++) {
+ int[] py = partsy.get(y);
+ rowx[y] = intersectionSize(px, py);
+ }
+ }
+ }
+
+ /**
+ * Compute the intersection of two sorted integer lists.
+ *
+ * @param px First list
+ * @param py Second list
+ * @return Intersection size.
+ */
+ private int intersectionSize(int[] px, int[] py) {
+ int i = 0, j = 0, c = 0;
+ while(i < px.length && j < py.length) {
+ final int vx = px[i], vy = py[i];
+ if(vx < vy) {
+ ++i;
+ }
+ else if(vx > vy) {
+ ++j;
+ }
+ else {
+ ++c;
+ ++i;
+ ++j;
+ }
+ }
+ return c;
+ }
+
+ /**
+ * Compute the MCE entropy value.
+ *
+ * @param mat Partition size matrix
+ * @param partsx Partitions on X
+ * @param partsy Partitions on Y
+ * @param size Data set size
+ * @param gridsize Size of grids
+ * @param loggrid Logarithm of grid sizes, for normalization
+ * @return MCE score.
+ */
+ private double getMCEntropy(int[][] mat, ArrayList<int[]> partsx, ArrayList<int[]> partsy, int size, int gridsize, double loggrid) {
+ // Margin entropies:
+ double[] mx = new double[gridsize];
+ double[] my = new double[gridsize];
+
+ for(int i = 0; i < gridsize; i++) {
+ // Note: indexes are a bit tricky here, because we compute both margin
+ // entropies at the same time!
+ final double sumx = (double) partsx.get(i).length;
+ final double sumy = (double) partsy.get(i).length;
+ for(int j = 0; j < gridsize; j++) {
+ double px = mat[i][j] / sumx;
+ double py = mat[j][i] / sumy;
+
+ if(px > 0.) {
+ mx[i] -= px * Math.log(px);
+ }
+ if(py > 0.) {
+ my[i] -= py * Math.log(py);
+ }
+ }
+ }
+
+ // Weighted sums of margin entropies.
+ double sumx = 0., sumy = 0.;
+ for(int i = 0; i < gridsize; i++) {
+ sumx += mx[i] * partsx.get(i).length;
+ sumy += my[i] * partsy.get(i).length;
+ }
+
+ double max = ((sumx > sumy) ? sumx : sumy);
+ return max / (size * loggrid);
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected MCEDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/MutualInformationEquiwidthDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/MutualInformationEquiwidthDependenceMeasure.java
new file mode 100644
index 00000000..26a1759a
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/MutualInformationEquiwidthDependenceMeasure.java
@@ -0,0 +1,137 @@
+package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ 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.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Mutual Information (MI) dependence measure by dividing each attribute into
+ * equal-width bins. MI can be seen as Kullback–Leibler divergence of the joint
+ * distribution and the product of the marginal distributions.
+ *
+ * For normalization, the resulting values are scaled by {@code mi/log(nbins)}.
+ * This both cancels out the logarithm base, and normalizes for the number of
+ * bins (a uniform distribution will yield a MI with itself of 1).
+ *
+ * TODO: Offer normalized and non-normalized variants?
+ *
+ * For a median-based discretization, see {@link MCEDependenceMeasure}.
+ *
+ * @author Erich Schubert
+ */
+public class MutualInformationEquiwidthDependenceMeasure extends AbstractDependenceMeasure {
+ /**
+ * Static instance.
+ */
+ public static final MutualInformationEquiwidthDependenceMeasure STATIC = new MutualInformationEquiwidthDependenceMeasure();
+
+ /**
+ * Constructor - use {@link #STATIC} instance.
+ */
+ protected MutualInformationEquiwidthDependenceMeasure() {
+ super();
+ }
+
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+ final int bins = (int) Math.round(Math.sqrt(len));
+ final int maxbin = bins - 1;
+
+ double min1 = adapter1.getDouble(data1, 0), max1 = min1;
+ double min2 = adapter2.getDouble(data2, 0), max2 = min2;
+ for(int i = 1; i < len; i++) {
+ final double vx = adapter1.getDouble(data1, i);
+ final double vy = adapter2.getDouble(data2, i);
+ if(vx < min1) {
+ min1 = vx;
+ }
+ else if(vx > max1) {
+ max1 = vx;
+ }
+ if(vy < min2) {
+ min2 = vy;
+ }
+ else if(vy > max2) {
+ max2 = vy;
+ }
+ }
+ final double scale1 = (max1 > min1) ? bins / (max1 - min1) : 1;
+ final double scale2 = (max2 > min2) ? bins / (max2 - min2) : 1;
+
+ int[] margin1 = new int[bins], margin2 = new int[bins];
+ int[][] counts = new int[bins][bins];
+ for(int i = 0; i < len; i++) {
+ int bin1 = (int) Math.floor((adapter1.getDouble(data1, i) - min1) * scale1);
+ int bin2 = (int) Math.floor((adapter2.getDouble(data2, i) - min2) * scale2);
+ bin1 = bin1 < bins ? bin1 : maxbin;
+ bin2 = bin2 < bins ? bin2 : maxbin;
+ margin1[bin1]++;
+ margin2[bin2]++;
+ counts[bin1][bin2]++;
+ }
+
+ // calculating relative frequencies
+ double e = 0;
+ for(int bin1 = 0; bin1 < counts.length; bin1++) {
+ // Margin value for row i.
+ final int sum1 = margin1[bin1];
+ // Skip empty rows early.
+ if(sum1 == 0) {
+ continue;
+ }
+ // Inverse pX
+ final double ipX = len / (double) sum1;
+ final int[] row = counts[bin1];
+ for(int bin2 = 0; bin2 < row.length; bin2++) {
+ final int cell = row[bin2];
+ // Skip empty cells.
+ if(cell != 0) {
+ // Mutual information pXY / (pX * pY)
+ double pXY = cell / (double) len;
+ // Inverse pXpY: 1 / (pX*pY)
+ final double ipXpY = ipX * len / margin2[bin2];
+ e += pXY * Math.log(pXY * ipXpY);
+ }
+ }
+ }
+ // Expected value for uniform identical: log(bins)!
+ return e / Math.log(bins);
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected MutualInformationEquiwidthDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SURFINGDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SURFINGDependenceMeasure.java
new file mode 100644
index 00000000..ce866c16
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SURFINGDependenceMeasure.java
@@ -0,0 +1,133 @@
+package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ 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.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.DoubleMinHeap;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Compute the similarity of dimensions using the SURFING score. The parameter k
+ * for the k nearest neighbors is currently hard-coded to 10% of the set size.
+ *
+ * Note that the complexity is roughly O(n n k), so this is a rather slow
+ * method, and with k at 10% of n, is actually cubic: O(0.1 * n^3).
+ *
+ * This version cannot use index support, as the API operates without database
+ * attachment. However, it should be possible to implement some trivial
+ * sorted-list indexes to get a reasonable speedup!
+ *
+ * Reference:
+ * <p>
+ * Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek:<br />
+ * Interactive Data Mining with 3D-Parallel-Coordinate-Trees.<br />
+ * Proceedings of the 2013 ACM International Conference on Management of Data
+ * (SIGMOD), New York City, NY, 2013.
+ * </p>
+ *
+ * Based on:
+ * <p>
+ * Christian Baumgartner, Claudia Plant, Karin Kailing, Hans-Peter Kriegel, and
+ * Peer Kröger<br />
+ * Subspace Selection for Clustering High-Dimensional Data<br />
+ * In IEEE International Conference on Data Mining, 2004.
+ * </p>
+ *
+ * TODO: make the subspace distance function and k parameterizable.
+ *
+ * @author Robert Rödler
+ * @author Erich Schubert
+ *
+ * @apiviz.uses SubspaceEuclideanDistanceFunction
+ */
+@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", //
+title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", //
+booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", //
+url = "http://dx.doi.org/10.1145/2463676.2463696")
+public class SURFINGDependenceMeasure extends AbstractDependenceMeasure {
+ /**
+ * Static instance.
+ */
+ public static final SURFINGDependenceMeasure STATIC = new SURFINGDependenceMeasure();
+
+ /**
+ * Constructor. Use static instance instead!
+ */
+ protected SURFINGDependenceMeasure() {
+ super();
+ }
+
+ @Reference(authors = "Christian Baumgartner, Claudia Plant, Karin Kailing, Hans-Peter Kriegel, and Peer Kröger", //
+ title = "Subspace Selection for Clustering High-Dimensional Data", //
+ booktitle = "IEEE International Conference on Data Mining, 2004", //
+ url = "http://dx.doi.org/10.1109/ICDM.2004.10112")
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+ final int k = Math.max(1, len / 10);
+
+ double[] knns = new double[len];
+
+ DoubleMinHeap heap = new DoubleMinHeap(k);
+ double kdistmean = 0.;
+ for(int i = 0; i < len; ++i) {
+ double ix = adapter1.getDouble(data1, i), iy = adapter2.getDouble(data2, i);
+ heap.clear();
+ for(int j = 0; j < len; ++j) {
+ double jx = adapter1.getDouble(data1, j), jy = adapter2.getDouble(data2, j);
+ double dx = ix - jx, dy = iy - jy;
+ heap.add(dx * dx + dy * dy); // Squared Euclidean.
+ }
+ double kdist = Math.sqrt(heap.peek()); // Euclidean
+ knns[i] = kdist;
+ kdistmean += kdist;
+ }
+ kdistmean /= len;
+ // Deviation from mean:
+ double diff = 0.;
+ int below = 0;
+ for(int l = 0; l < knns.length; l++) {
+ diff += Math.abs(kdistmean - knns[l]);
+ if(knns[l] < kdistmean) {
+ below++;
+ }
+ }
+ return (below > 0) ? diff / (2. * kdistmean * below) : 0;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected SURFINGDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SlopeDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SlopeDependenceMeasure.java
new file mode 100644
index 00000000..3dd4fcaa
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SlopeDependenceMeasure.java
@@ -0,0 +1,153 @@
+package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ 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.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Arrange dimensions based on the entropy of the slope spectrum.
+ *
+ * Reference:
+ * <p>
+ * Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek:<br />
+ * Interactive Data Mining with 3D-Parallel-Coordinate-Trees.<br />
+ * Proceedings of the 2013 ACM International Conference on Management of Data
+ * (SIGMOD), New York City, NY, 2013.
+ * </p>
+ *
+ * TODO: shouldn't this be normalized by the single-dimension entropies or so?
+ *
+ * @author Erich Schubert
+ * @author Robert Rödler
+ */
+@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", //
+title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", //
+booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", //
+url = "http://dx.doi.org/10.1145/2463676.2463696")
+public class SlopeDependenceMeasure extends AbstractDependenceMeasure {
+ /**
+ * Static instance.
+ */
+ public static final SlopeDependenceMeasure STATIC = new SlopeDependenceMeasure();
+
+ /**
+ * Full precision.
+ */
+ protected final static int PRECISION = 40;
+
+ /**
+ * Precision for entropy normalization.
+ */
+ protected final static double LOG_PRECISION = Math.log(PRECISION);
+
+ /**
+ * Scaling factor.
+ */
+ protected final static double RESCALE = PRECISION * .5;
+
+ /**
+ * Constructor. Use static instance instead!
+ */
+ protected SlopeDependenceMeasure() {
+ super();
+ }
+
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+
+ // Get attribute value range:
+ final double off1, scale1, off2, scale2;
+ {
+ double mi = adapter1.getDouble(data1, 0), ma = mi;
+ for(int i = 1; i < len; ++i) {
+ double v = adapter1.getDouble(data1, i);
+ if(v < mi) {
+ mi = v;
+ }
+ else if(v > ma) {
+ ma = v;
+ }
+ }
+ off1 = mi;
+ scale1 = (ma > mi) ? (1. / (ma - mi)) : 1.;
+ // Second data
+ mi = adapter2.getDouble(data2, 0);
+ ma = mi;
+ for(int i = 1; i < len; ++i) {
+ double v = adapter2.getDouble(data2, i);
+ if(v < mi) {
+ mi = v;
+ }
+ else if(v > ma) {
+ ma = v;
+ }
+ }
+ off2 = mi;
+ scale2 = (ma > mi) ? (1. / (ma - mi)) : 1.;
+ }
+
+ // Collect angular histograms.
+ // Note, we only fill half of the matrix
+ int[] angles = new int[PRECISION];
+
+ // Scratch buffer
+ for(int i = 0; i < len; i++) {
+ double x = adapter1.getDouble(data1, i), y = adapter2.getDouble(data2, i);
+ x = (x - off1) * scale1;
+ y = (y - off2) * scale2;
+ final double delta = x - y + 1;
+ int div = (int) Math.round(delta * RESCALE);
+ // TODO: do we really need this check?
+ div = (div < 0) ? 0 : (div >= PRECISION) ? PRECISION - 1 : div;
+ angles[div] += 1;
+ }
+
+ // Compute entropy:
+ double entropy = 0.;
+ for(int l = 0; l < PRECISION; l++) {
+ if(angles[l] > 0) {
+ final double p = angles[l] / (double) len;
+ entropy += p * Math.log(p);
+ }
+ }
+ return 1 + entropy / LOG_PRECISION;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected SlopeDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SlopeInversionDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SlopeInversionDependenceMeasure.java
new file mode 100644
index 00000000..01ad78bc
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SlopeInversionDependenceMeasure.java
@@ -0,0 +1,157 @@
+package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ 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.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Arrange dimensions based on the entropy of the slope spectrum.
+ *
+ * Reference:
+ * <p>
+ * Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek:<br />
+ * Interactive Data Mining with 3D-Parallel-Coordinate-Trees.<br />
+ * Proceedings of the 2013 ACM International Conference on Management of Data
+ * (SIGMOD), New York City, NY, 2013.
+ * </p>
+ *
+ * TODO: shouldn't this be normalized by the single-dimension entropies or so?
+ *
+ * @author Erich Schubert
+ * @author Robert Rödler
+ */
+@Reference(authors = "Elke Achtert, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", //
+title = "Interactive Data Mining with 3D-Parallel-Coordinate-Trees", //
+booktitle = "Proc. of the 2013 ACM International Conference on Management of Data (SIGMOD)", //
+url = "http://dx.doi.org/10.1145/2463676.2463696")
+public class SlopeInversionDependenceMeasure extends SlopeDependenceMeasure {
+ /**
+ * Static instance.
+ */
+ public static final SlopeInversionDependenceMeasure STATIC = new SlopeInversionDependenceMeasure();
+
+ /**
+ * Constructor. Use static instance instead!
+ */
+ protected SlopeInversionDependenceMeasure() {
+ super();
+ }
+
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+
+ // Get attribute value range:
+ final double off1, scale1, off2, scale2;
+ {
+ double mi = adapter1.getDouble(data1, 0), ma = mi;
+ for(int i = 1; i < len; ++i) {
+ double v = adapter1.getDouble(data1, i);
+ if(v < mi) {
+ mi = v;
+ }
+ else if(v > ma) {
+ ma = v;
+ }
+ }
+ off1 = mi;
+ scale1 = (ma > mi) ? (1. / (ma - mi)) : 1.;
+ // Second data
+ mi = adapter2.getDouble(data2, 0);
+ ma = mi;
+ for(int i = 1; i < len; ++i) {
+ double v = adapter2.getDouble(data2, i);
+ if(v < mi) {
+ mi = v;
+ }
+ else if(v > ma) {
+ ma = v;
+ }
+ }
+ off2 = mi;
+ scale2 = (ma > mi) ? (1. / (ma - mi)) : 1.;
+ }
+
+ // Collect angular histograms.
+ // Note, we only fill half of the matrix
+ int[] angles = new int[PRECISION];
+ int[] angleI = new int[PRECISION];
+
+ // Scratch buffer
+ for(int i = 0; i < len; i++) {
+ double x = adapter1.getDouble(data1, i), y = adapter2.getDouble(data2, i);
+ x = (x - off1) * scale1;
+ y = (y - off2) * scale2;
+ {
+ final double delta = x - y + 1;
+ int div = (int) Math.round(delta * RESCALE);
+ // TODO: do we really need this check?
+ div = (div < 0) ? 0 : (div >= PRECISION) ? PRECISION - 1 : div;
+ angles[div] += 1;
+ }
+ {
+ final double delta = x + y;
+ int div = (int) Math.round(delta * RESCALE);
+ // TODO: do we really need this check?
+ div = (div < 0) ? 0 : (div >= PRECISION) ? PRECISION - 1 : div;
+ angleI[div] += 1;
+ }
+ }
+
+ // Compute entropy:
+ double entropy = 0., entropyI = 0.;
+ for(int l = 0; l < PRECISION; l++) {
+ if(angles[l] > 0) {
+ final double p = angles[l] / (double) len;
+ entropy += p * Math.log(p);
+ }
+ if(angleI[l] > 0) {
+ final double p = angleI[l] / (double) len;
+ entropyI += p * Math.log(p);
+ }
+ }
+ if(entropy >= entropyI) {
+ return 1 + entropy / LOG_PRECISION;
+ }
+ else {
+ return 1 + entropyI / LOG_PRECISION;
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected SlopeInversionDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SpearmanCorrelationDependenceMeasure.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SpearmanCorrelationDependenceMeasure.java
new file mode 100644
index 00000000..24202dce
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/SpearmanCorrelationDependenceMeasure.java
@@ -0,0 +1,78 @@
+package de.lmu.ifi.dbs.elki.math.statistics.dependence;
+
+/*
+ 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.utilities.datastructures.arraylike.NumberArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Spearman rank-correlation coefficient, also known as Spearmans Rho.
+ *
+ * @author Erich Schubert
+ */
+public class SpearmanCorrelationDependenceMeasure extends AbstractDependenceMeasure {
+ /**
+ * Static instance.
+ */
+ public static final SpearmanCorrelationDependenceMeasure STATIC = new SpearmanCorrelationDependenceMeasure();
+
+ /**
+ * Constructor - use {@link #STATIC} instance.
+ */
+ protected SpearmanCorrelationDependenceMeasure() {
+ super();
+ }
+
+ @Override
+ public <A, B> double dependence(NumberArrayAdapter<?, A> adapter1, A data1, NumberArrayAdapter<?, B> adapter2, B data2) {
+ final int len = size(adapter1, data1, adapter2, data2);
+ double[] ranks1 = computeNormalizedRanks(adapter1, data1, len);
+ double[] ranks2 = computeNormalizedRanks(adapter2, data2, len);
+
+ // Second pass: variances and covariance
+ double v1 = 0., v2 = 0., cov = 0.;
+ for(int i = 0; i < len; i++) {
+ double d1 = ranks1[i] - .5, d2 = ranks2[i] - .5;
+ v1 += d1 * d1;
+ v2 += d2 * d2;
+ cov += d1 * d2;
+ }
+ // Note: we did not normalize by len, as this cancels out.
+ return cov / Math.sqrt(v1 * v2);
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected SpearmanCorrelationDependenceMeasure makeInstance() {
+ return STATIC;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/package-info.java
new file mode 100644
index 00000000..a1f0bd55
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/dependence/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * <p>Statistical measures of dependence, such as correlation.</p>
+ */
+/*
+ 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.math.statistics.dependence; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistribution.java
index 30481d00..1a05daed 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/BetaDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/BetaDistribution.java
index 04d55262..f01ac528 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/BetaDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/BetaDistribution.java
@@ -2,7 +2,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -12,7 +12,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ 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/math/statistics/distribution/CauchyDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/CauchyDistribution.java
index 2b5d4949..dddfdcc0 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/CauchyDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/CauchyDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiDistribution.java
index 5f144946..b7de1606 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiSquaredDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiSquaredDistribution.java
index 6fd432b2..5bea555d 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiSquaredDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiSquaredDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
*/
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ConstantDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ConstantDistribution.java
index b31eaa3d..3d70d0d3 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ConstantDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ConstantDistribution.java
@@ -9,7 +9,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
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/math/statistics/distribution/Distribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/Distribution.java
index 0c60e02f..68ac1b60 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/Distribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/Distribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Statistical distributions, with their common functions.
*
* @author Erich Schubert
*/
-public interface Distribution extends Parameterizable {
+public interface Distribution {
/**
* Return the density of an existing value
*
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentialDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentialDistribution.java
index 33d8e853..db6ea61d 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentialDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentialDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentiallyModifiedGaussianDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentiallyModifiedGaussianDistribution.java
index 22e75e3d..4905309f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentiallyModifiedGaussianDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentiallyModifiedGaussianDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.Alias;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GammaDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GammaDistribution.java
index 850b0e3a..b2a79d81 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GammaDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GammaDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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 java.util.Random;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.math.MathUtil;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedExtremeValueDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedExtremeValueDistribution.java
index 0d3fd4f8..4c0e267a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedExtremeValueDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedExtremeValueDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticAlternateDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticAlternateDistribution.java
index eb5e1b1a..6e41be51 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticAlternateDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticAlternateDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
*/
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticDistribution.java
index 467ad4f9..f86b3b04 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
*/
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GumbelDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GumbelDistribution.java
index 9f42b7e2..34683b97 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GumbelDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GumbelDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/HaltonUniformDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/HaltonUniformDistribution.java
index c16bb498..7724f237 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/HaltonUniformDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/HaltonUniformDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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 java.util.Random;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.Primes;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/KappaDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/KappaDistribution.java
index 156bf325..02940907 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/KappaDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/KappaDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
*/
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LaplaceDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LaplaceDistribution.java
index 18a6ffbe..ad14c001 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LaplaceDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LaplaceDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.Alias;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
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.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaAlternateDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaAlternateDistribution.java
index 90902ae0..afe12db1 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaAlternateDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaAlternateDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaDistribution.java
index 76b10dde..252794b7 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogLogisticDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogLogisticDistribution.java
index fe8557b3..50b4f762 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogLogisticDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogLogisticDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
*/
import java.util.Random;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.Alias;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogNormalDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogNormalDistribution.java
index ca2fbbab..cba41e9f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogNormalDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogNormalDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.Alias;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
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;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogisticDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogisticDistribution.java
index 12307a36..868d92bd 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogisticDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogisticDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.Alias;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/NormalDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/NormalDistribution.java
index 0a0d3d4e..4ce0e912 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/NormalDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/NormalDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.Alias;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
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;
@@ -112,6 +112,11 @@ public class NormalDistribution extends AbstractDistribution {
static final double ERFINV_D[] = { 7.784695709041462e-03, 3.224671290700398e-01, 2.445134137142996e+00, 3.754408661907416e+00 };
/**
+ * CDFINV(0.75)
+ */
+ public static final double PHIINV075 = 0.67448975019608171;
+
+ /**
* 1 / CDFINV(0.75)
*/
public static final double ONEBYPHIINV075 = 1.48260221850560186054;
@@ -212,28 +217,28 @@ public class NormalDistribution extends AbstractDistribution {
* @return erfc(x)
*/
public static double erfc(double x) {
- if (Double.isNaN(x)) {
+ if(Double.isNaN(x)) {
return Double.NaN;
}
- if (Double.isInfinite(x)) {
+ if(Double.isInfinite(x)) {
return (x < 0.0) ? 2 : 0;
}
double result = Double.NaN;
double absx = Math.abs(x);
// First approximation interval
- if (absx < 0.46875) {
+ if(absx < 0.46875) {
double z = x * x;
result = 1 - x * ((((ERFAPP_A[0] * z + ERFAPP_A[1]) * z + ERFAPP_A[2]) * z + ERFAPP_A[3]) * z + ERFAPP_A[4]) / ((((ERFAPP_B[0] * z + ERFAPP_B[1]) * z + ERFAPP_B[2]) * z + ERFAPP_B[3]) * z + ERFAPP_B[4]);
}
// Second approximation interval
- else if (absx < 4.0) {
+ else if(absx < 4.0) {
double z = absx;
result = ((((((((ERFAPP_C[0] * z + ERFAPP_C[1]) * z + ERFAPP_C[2]) * z + ERFAPP_C[3]) * z + ERFAPP_C[4]) * z + ERFAPP_C[5]) * z + ERFAPP_C[6]) * z + ERFAPP_C[7]) * z + ERFAPP_C[8]) / ((((((((ERFAPP_D[0] * z + ERFAPP_D[1]) * z + ERFAPP_D[2]) * z + ERFAPP_D[3]) * z + ERFAPP_D[4]) * z + ERFAPP_D[5]) * z + ERFAPP_D[6]) * z + ERFAPP_D[7]) * z + ERFAPP_D[8]);
double rounded = Math.round(result * 16.0) / 16.0;
double del = (absx - rounded) * (absx + rounded);
result = Math.exp(-rounded * rounded) * Math.exp(-del) * result;
- if (x < 0.0) {
+ if(x < 0.0) {
result = 2.0 - result;
}
}
@@ -245,7 +250,7 @@ public class NormalDistribution extends AbstractDistribution {
double rounded = Math.round(result * 16.0) / 16.0;
double del = (absx - rounded) * (absx + rounded);
result = Math.exp(-rounded * rounded) * Math.exp(-del) * result;
- if (x < 0.0) {
+ if(x < 0.0) {
result = 2.0 - result;
}
}
@@ -303,7 +308,7 @@ public class NormalDistribution extends AbstractDistribution {
* @return PDF of the given normal distribution at x.
*/
public static double standardNormalPDF(double x) {
- return Math.exp(-.5 * x * x) * MathUtil.SQRTHALF;
+ return Math.exp(-.5 * x * x) * MathUtil.ONE_BY_SQRTTWOPI;
}
/**
@@ -358,21 +363,26 @@ public class NormalDistribution extends AbstractDistribution {
* @return Inverse erf.
*/
public static double standardNormalQuantile(double d) {
- if (d == 0) {
+ if(d == 0) {
return Double.NEGATIVE_INFINITY;
- } else if (d == 1) {
+ }
+ else if(d == 1) {
return Double.POSITIVE_INFINITY;
- } else if (Double.isNaN(d) || d < 0 || d > 1) {
+ }
+ else if(Double.isNaN(d) || d < 0 || d > 1) {
return Double.NaN;
- } else if (d < P_LOW) {
+ }
+ else if(d < P_LOW) {
// Rational approximation for lower region:
double q = Math.sqrt(-2 * Math.log(d));
return (((((ERFINV_C[0] * q + ERFINV_C[1]) * q + ERFINV_C[2]) * q + ERFINV_C[3]) * q + ERFINV_C[4]) * q + ERFINV_C[5]) / ((((ERFINV_D[0] * q + ERFINV_D[1]) * q + ERFINV_D[2]) * q + ERFINV_D[3]) * q + 1);
- } else if (P_HIGH < d) {
+ }
+ else if(P_HIGH < d) {
// Rational approximation for upper region:
double q = Math.sqrt(-2 * Math.log(1 - d));
return -(((((ERFINV_C[0] * q + ERFINV_C[1]) * q + ERFINV_C[2]) * q + ERFINV_C[3]) * q + ERFINV_C[4]) * q + ERFINV_C[5]) / ((((ERFINV_D[0] * q + ERFINV_D[1]) * q + ERFINV_D[2]) * q + ERFINV_D[3]) * q + 1);
- } else {
+ }
+ else {
// Rational approximation for central region:
double q = d - 0.5D;
double r = q * q;
@@ -396,13 +406,13 @@ public class NormalDistribution extends AbstractDistribution {
super.makeOptions(config);
DoubleParameter muP = new DoubleParameter(LOCATION_ID);
- if (config.grab(muP)) {
+ if(config.grab(muP)) {
mu = muP.doubleValue();
}
DoubleParameter sigmaP = new DoubleParameter(SCALE_ID);
sigmaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
- if (config.grab(sigmaP)) {
+ if(config.grab(sigmaP)) {
sigma = sigmaP.doubleValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/PoissonDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/PoissonDistribution.java
index b6b70b34..3321ee69 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/PoissonDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/PoissonDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
import de.lmu.ifi.dbs.elki.math.MathUtil;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/RayleighDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/RayleighDistribution.java
index 68870f1a..9f3b718f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/RayleighDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/RayleighDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/SkewGeneralizedNormalDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/SkewGeneralizedNormalDistribution.java
index 76931029..ed3eda95 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/SkewGeneralizedNormalDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/SkewGeneralizedNormalDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
import de.lmu.ifi.dbs.elki.math.MathUtil;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/StudentsTDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/StudentsTDistribution.java
index ef9f06d4..56cf855f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/StudentsTDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/StudentsTDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ 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.math.statistics.distribution;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/UniformDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/UniformDistribution.java
index db2e2fb2..5dc33e5a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/UniformDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/UniformDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WaldDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WaldDistribution.java
index 123ece95..332c5ed0 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WaldDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WaldDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.Alias;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WeibullDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WeibullDistribution.java
index 9b7af6d8..4f261840 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WeibullDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WeibullDistribution.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
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.math.statistics.distribution;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractExpMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractExpMADEstimator.java
index 6f9dc541..68ea51e6 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractExpMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractExpMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/AbstractLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLMMEstimator.java
index 3d77a1e6..969f1c2e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/AbstractLogMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMADEstimator.java
index b4e4e095..d1b96526 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/AbstractLogMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMOMEstimator.java
index 8ae86d4a..f19f0f4f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMOMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMOMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/AbstractLogMeanVarianceEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMeanVarianceEstimator.java
index a21186db..b149fedc 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMeanVarianceEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractLogMeanVarianceEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/AbstractMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMADEstimator.java
index 54009592..a451d088 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/AbstractMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMOMEstimator.java
index 30bd0802..cc3c7460 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMOMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMOMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/AbstractMeanVarianceEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMeanVarianceEstimator.java
index 73a2e6d2..ccf522a0 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMeanVarianceEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/AbstractMeanVarianceEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/CauchyMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/CauchyMADEstimator.java
index e1cfb20c..77a21b11 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/CauchyMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/CauchyMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/DistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/DistributionEstimator.java
index 953fcff8..74ce583b 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/DistributionEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/DistributionEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/EMGOlivierNorbergEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/EMGOlivierNorbergEstimator.java
index 65c89c83..0319504a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/EMGOlivierNorbergEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/EMGOlivierNorbergEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/ExpMADDistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExpMADDistributionEstimator.java
index 70a16f3e..d185c36e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExpMADDistributionEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExpMADDistributionEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/ExponentialLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialLMMEstimator.java
index 66176545..b9367d11 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/ExponentialMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMADEstimator.java
index 208fc72b..fa654738 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/ExponentialMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMOMEstimator.java
index 4c3f93aa..cd05baad 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMOMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMOMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/ExponentialMedianEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMedianEstimator.java
index 19ce63c7..6480f6bb 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMedianEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/ExponentialMedianEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/GammaChoiWetteEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaChoiWetteEstimator.java
index 9e47e81d..db4a6fb9 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaChoiWetteEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaChoiWetteEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/GammaLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaLMMEstimator.java
index edfc3f51..1f30b58b 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/GammaMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMADEstimator.java
index 54b0d38b..0007c225 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/GammaMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMOMEstimator.java
index 0ff0cf47..5f381447 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMOMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaMOMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/GeneralizedExtremeValueLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedExtremeValueLMMEstimator.java
index cdadf47d..a2802c24 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedExtremeValueLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedExtremeValueLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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
@@ -103,7 +103,7 @@ public class GeneralizedExtremeValueLMMEstimator extends AbstractLMMEstimator<Ge
// g: Almost zero?
if (Math.abs(g) < 1e-50) {
double k = 0;
- double sigma = xmom[1] / MathUtil.LOG2;
+ double sigma = xmom[1] * MathUtil.ONE_BY_LOG2;
double mu = xmom[0] - Math.E * sigma;
return new GeneralizedExtremeValueDistribution(mu, sigma, k);
}
@@ -113,7 +113,7 @@ public class GeneralizedExtremeValueLMMEstimator extends AbstractLMMEstimator<Ge
if (t3 < -.8) {
// Newton-Raphson iteration for t3 < -.8
if (t3 <= -.97) {
- g = 1. - Math.log(1. + t3) / MathUtil.LOG2;
+ g = 1. - Math.log1p(t3) * MathUtil.ONE_BY_LOG2;
}
double t0 = .5 * (t3 + 3.);
for (int it = 1;; it++) {
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedLogisticAlternateLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedLogisticAlternateLMMEstimator.java
index dfcbcd52..3807c700 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedLogisticAlternateLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GeneralizedLogisticAlternateLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/GumbelLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelLMMEstimator.java
index c0f64006..539d9a88 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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
@@ -65,7 +65,7 @@ public class GumbelLMMEstimator extends AbstractLMMEstimator<GumbelDistribution>
@Override
public GumbelDistribution estimateFromLMoments(double[] xmom) {
- double scale = xmom[1] / MathUtil.LOG2;
+ double scale = xmom[1] * MathUtil.ONE_BY_LOG2;
return new GumbelDistribution(xmom[0] - Math.E * scale, scale);
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelMADEstimator.java
index ebf6354a..2f74b36a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GumbelMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LMMDistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LMMDistributionEstimator.java
index f3d8d1b2..56339504 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LMMDistributionEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LMMDistributionEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LaplaceLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceLMMEstimator.java
index 4026fdc5..7ac2ae25 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LaplaceMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMADEstimator.java
index 6fe6da0f..10e2f9de 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LaplaceMLEEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMLEEstimator.java
index 8d2c5707..acd755a6 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMLEEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMLEEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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
@@ -44,7 +44,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @apiviz.has LaplaceDistribution
*/
-@Reference(title = "The Double Exponential Distribution: Using Calculus to Find a Maximum Likelihood Estimator", authors = "R. M. Norton", booktitle = "The American Statistician 38 (2)", url = "http://dx.doi.org/10.2307%2F2683252")
+@Reference(title = "The Double Exponential Distribution: Using Calculus to Find a Maximum Likelihood Estimator", //
+authors = "R. M. Norton", booktitle = "The American Statistician 38 (2)", //
+url = "http://dx.doi.org/10.2307/2683252")
public class LaplaceMLEEstimator implements DistributionEstimator<LaplaceDistribution> {
/**
* Static instance.
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaAlternateExpMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaAlternateExpMADEstimator.java
index 7ea0a6be..a4a3aa87 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaAlternateExpMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaAlternateExpMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LogGammaChoiWetteEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaChoiWetteEstimator.java
index ba3a899d..996132dc 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaChoiWetteEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaChoiWetteEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LogGammaLogMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMADEstimator.java
index ed34870c..44d8abf6 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LogGammaLogMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMOMEstimator.java
index ddc6cbb9..e5552714 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMOMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogGammaLogMOMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LogLogisticMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogLogisticMADEstimator.java
index 61b111c9..a9ea3efd 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogLogisticMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogLogisticMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LogMADDistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMADDistributionEstimator.java
index 9c281952..8b29ad46 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMADDistributionEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMADDistributionEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LogMOMDistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMOMDistributionEstimator.java
index 5a589faa..bc482378 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMOMDistributionEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogMOMDistributionEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LogNormalBilkovaLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalBilkovaLMMEstimator.java
index e8fab89f..8ec1560b 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalBilkovaLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalBilkovaLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LogNormalLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLMMEstimator.java
index 48865d3f..40afd20c 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LogNormalLevenbergMarquardtKDEEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLevenbergMarquardtKDEEstimator.java
index b4b8ff0d..22afe9e6 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLevenbergMarquardtKDEEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLevenbergMarquardtKDEEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LogNormalLogMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMADEstimator.java
index 6ad1dc33..ef197776 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LogNormalLogMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMOMEstimator.java
index 5b753c54..a44441fa 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMOMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogNormalLogMOMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LogisticLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticLMMEstimator.java
index 973a91de..543e7043 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/LogisticMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticMADEstimator.java
index 45181486..fff6830e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LogisticMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/MADDistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MADDistributionEstimator.java
index 6bf2b3ae..3ea05e53 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MADDistributionEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MADDistributionEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/MOMDistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MOMDistributionEstimator.java
index 383f68cc..8257994c 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MOMDistributionEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MOMDistributionEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/MeanVarianceDistributionEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MeanVarianceDistributionEstimator.java
index 4d84465f..6605acdb 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MeanVarianceDistributionEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/MeanVarianceDistributionEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/NormalLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLMMEstimator.java
index 67880950..df0bcb74 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/NormalLevenbergMarquardtKDEEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLevenbergMarquardtKDEEstimator.java
index bbbcda76..75ffccae 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLevenbergMarquardtKDEEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalLevenbergMarquardtKDEEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/NormalMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMADEstimator.java
index 2221ad4b..e716432f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/NormalMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMOMEstimator.java
index dae05eb0..6cc48f4a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMOMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/NormalMOMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/RayleighLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighLMMEstimator.java
index a827e1e8..42372102 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/RayleighMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMADEstimator.java
index 7382ada2..3e1d6e47 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/RayleighMLEEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMLEEstimator.java
index aa5dc300..f4e1ba82 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMLEEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/RayleighMLEEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/SkewGNormalLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/SkewGNormalLMMEstimator.java
index df05eef9..a66ac5ee 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/SkewGNormalLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/SkewGNormalLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/UniformEnhancedMinMaxEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformEnhancedMinMaxEstimator.java
index 834b0d94..c4401c87 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformEnhancedMinMaxEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformEnhancedMinMaxEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/UniformLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformLMMEstimator.java
index 5b3e868f..7ad57dbf 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/UniformMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMADEstimator.java
index 47dad134..ec52ed2a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/UniformMinMaxEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMinMaxEstimator.java
index 11bb8231..a1409839 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMinMaxEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMinMaxEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/WaldMLEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMLEstimator.java
index 16a33f89..b2d4836c 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMLEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMLEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/WaldMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMOMEstimator.java
index 82b70936..c8476794 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMOMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WaldMOMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/WeibullLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLMMEstimator.java
index 9d7d8e8e..6d68e643 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLMMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/WeibullLogMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMADEstimator.java
index aacceae7..469fb93f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMADEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/WeibullLogMOMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMOMEstimator.java
index 9182a7ce..f189fc45 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMOMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/WeibullLogMOMEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/estimator/meta/BestFitEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/BestFitEstimator.java
index 8d57e0b7..54fdf035 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/BestFitEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/BestFitEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.meta;
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
@@ -199,7 +199,7 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> {
}
if (mom.getMax() <= mom.getMin()) {
LOG.warning("Constant distribution detected. Cannot fit.");
- return new UniformDistribution(mom.getMin() - .1, mom.getMax() + .1);
+ return new UniformDistribution(mom.getMin() - 1., mom.getMax() + 1.);
}
// Sort: for L-Moments, but getting the median is now also cheap.
Arrays.sort(x);
@@ -253,9 +253,7 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> {
LOG.debugFine("Fitting distribution " + est.getClass().getSimpleName() + " failed: " + e.getMessage());
}
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
}
for (MADDistributionEstimator<?> est : madests) {
try {
@@ -274,9 +272,7 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> {
LOG.debugFine("Fitting distribution " + est.getClass().getSimpleName() + " failed: " + e.getMessage());
}
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
}
for (LMMDistributionEstimator<?> est : lmmests) {
if (lmm != null) {
@@ -297,9 +293,7 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> {
}
}
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
}
for (LogMOMDistributionEstimator<?> est : logmomests) {
try {
@@ -318,9 +312,7 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> {
LOG.debugFine("Fitting distribution " + est.getClass().getSimpleName() + " failed: " + e.getMessage());
}
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
}
for (LogMADDistributionEstimator<?> est : logmadests) {
try {
@@ -339,9 +331,7 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> {
LOG.debugFine("Fitting distribution " + est.getClass().getSimpleName() + " failed: " + e.getMessage());
}
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
}
{ // Uniform estimators.
final UniformMinMaxEstimator est = UniformMinMaxEstimator.STATIC;
@@ -361,9 +351,7 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> {
LOG.debugFine("Fitting distribution " + est.getClass().getSimpleName() + " failed: " + e.getMessage());
}
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(prog);
}
{ // Uniform estimators.
final UniformEnhancedMinMaxEstimator est = UniformEnhancedMinMaxEstimator.STATIC;
@@ -383,13 +371,9 @@ public class BestFitEstimator implements DistributionEstimator<Distribution> {
LOG.debugFine("Fitting distribution " + est.getClass().getSimpleName() + " failed: " + e.getMessage());
}
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if (prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
if (LOG.isVeryVerbose()) {
LOG.veryverbose("Best distribution fit: " + bestscore + " " + best.toString() + " via " + bestest);
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/TrimmedEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/TrimmedEstimator.java
index a78d9760..d2d81a41 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/TrimmedEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/TrimmedEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.meta;
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/math/statistics/distribution/estimator/meta/WinsorisingEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/WinsorisingEstimator.java
index 47fe427e..7726adaa 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/WinsorisingEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/WinsorisingEstimator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.meta;
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/math/statistics/distribution/estimator/meta/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/package-info.java
index c06be5d7..fc1812a1 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/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/math/statistics/distribution/estimator/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/package-info.java
index 9a9f0993..6fa3a6ed 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/package-info.java
@@ -11,7 +11,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;
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/math/statistics/distribution/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/package-info.java
index 49357049..707e1b7d 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/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/math/statistics/kernelfunctions/BiweightKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/BiweightKernelDensityFunction.java
index 4b6ec7b7..7a508dd1 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/BiweightKernelDensityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/BiweightKernelDensityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions;
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/math/statistics/kernelfunctions/CosineKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/CosineKernelDensityFunction.java
index 230cb404..e6935da5 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/CosineKernelDensityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/CosineKernelDensityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions;
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/math/statistics/kernelfunctions/EpanechnikovKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/EpanechnikovKernelDensityFunction.java
index bf91e227..ab8c885c 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/EpanechnikovKernelDensityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/EpanechnikovKernelDensityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions;
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/math/statistics/kernelfunctions/GaussianKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/GaussianKernelDensityFunction.java
index 2e666871..4c4fca33 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/GaussianKernelDensityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/GaussianKernelDensityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions;
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/math/statistics/kernelfunctions/KernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/KernelDensityFunction.java
index ce6d5a0d..ffd0a39e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/KernelDensityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/KernelDensityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions;
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/math/statistics/kernelfunctions/TriangularKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriangularKernelDensityFunction.java
index c6acf031..fa8237df 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriangularKernelDensityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriangularKernelDensityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions;
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/math/statistics/kernelfunctions/TricubeKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TricubeKernelDensityFunction.java
index 933207ed..dc8c76fc 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TricubeKernelDensityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TricubeKernelDensityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions;
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/math/statistics/kernelfunctions/TriweightKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriweightKernelDensityFunction.java
index 993ab8bf..e2b7b4c5 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriweightKernelDensityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/TriweightKernelDensityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions;
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/math/statistics/kernelfunctions/UniformKernelDensityFunction.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/UniformKernelDensityFunction.java
index 2a820355..6ff8c91c 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/UniformKernelDensityFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/UniformKernelDensityFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions;
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/math/statistics/kernelfunctions/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/package-info.java
index 219509a5..9ebe8d46 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/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/math/statistics/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/package-info.java
index cc39a615..34d63a91 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/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/math/statistics/tests/GoodnessOfFitTest.java b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/GoodnessOfFitTest.java
index 363dbfea..668e74ca 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/tests/GoodnessOfFitTest.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/GoodnessOfFitTest.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.tests;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,18 +23,16 @@ package de.lmu.ifi.dbs.elki.math.statistics.tests;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
-
/**
* Interface for the statistical test used by HiCS.
*
- * Provides a single method that calculates the deviation between two data
+ * Constists of a single method that calculates the deviation between two data
* samples, given as arrays of double values
*
* @author Jan Brusis
* @author Erich Schubert
*/
-public interface GoodnessOfFitTest extends Parameterizable {
+public interface GoodnessOfFitTest {
/**
* Measure the deviation of a full sample from a conditional sample.
*
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/tests/KolmogorovSmirnovTest.java b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/KolmogorovSmirnovTest.java
index a134ab09..db9c985c 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/tests/KolmogorovSmirnovTest.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/KolmogorovSmirnovTest.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.tests;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ 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/math/statistics/tests/WelchTTest.java b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/WelchTTest.java
index 554a22db..9ae416d1 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/tests/WelchTTest.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/WelchTTest.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.math.statistics.tests;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ 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/math/statistics/tests/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/package-info.java
index 6698f462..a89e1031 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/tests/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/tests/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/package-info.java b/src/de/lmu/ifi/dbs/elki/package-info.java
index 8daf4487..0e0f2072 100644
--- a/src/de/lmu/ifi/dbs/elki/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/package-info.java
@@ -1,19 +1,18 @@
/**
- * <p>ELKI framework "Environment for Developing KDD-Applications Supported by Index-Structures"</p>
+ * ELKI framework "Environment for Developing KDD-Applications Supported by Index-Structures".
*
- * <p>{@link de.lmu.ifi.dbs.elki.KDDTask} is the main class of the ELKI-Framework
- * for command-line interaction. It will setup a
- * {@link de.lmu.ifi.dbs.elki.datasource.DatabaseConnection DatabaseConnection},
- * run an {@link de.lmu.ifi.dbs.elki.algorithm.Algorithm Algorithm} on it and pass the
- * result to a {@link de.lmu.ifi.dbs.elki.result.ResultHandler ResultHandler}.</p>
- *
+ * <p>{@link de.lmu.ifi.dbs.elki.KDDTask} is the basic work-flow for unsupervised knowledge discovery.
+ * It will setup a {@link de.lmu.ifi.dbs.elki.datasource.DatabaseConnection DatabaseConnection},
+ * run an {@link de.lmu.ifi.dbs.elki.algorithm.Algorithm Algorithm} on it and pass the
+ * result to a {@link de.lmu.ifi.dbs.elki.result.ResultHandler ResultHandler}.</p>
+ *
* @apiviz.exclude ^experimentalcode\.
*/
/*
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/parallel/Executor.java b/src/de/lmu/ifi/dbs/elki/parallel/Executor.java
new file mode 100644
index 00000000..27cd4cb9
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/Executor.java
@@ -0,0 +1,45 @@
+package de.lmu.ifi.dbs.elki.parallel;
+
+/*
+ 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.parallel.variables.SharedVariable;
+
+/**
+ * Processor executor.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.uses de.lmu.ifi.dbs.elki.parallel.processor.Processor
+ * @apiviz.uses SharedVariable
+ */
+public interface Executor {
+ /**
+ * Get a channel for this executor.
+ *
+ * @param parent Channel parent
+ * @return Channel instance
+ * @param <I> Variable type
+ */
+ <I extends SharedVariable.Instance<?>> I getInstance(SharedVariable<I> parent);
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/ParallelCore.java b/src/de/lmu/ifi/dbs/elki/parallel/ParallelCore.java
new file mode 100644
index 00000000..98ca2ec8
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/ParallelCore.java
@@ -0,0 +1,134 @@
+package de.lmu.ifi.dbs.elki.parallel;
+
+/*
+ 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.concurrent.Callable;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Core for parallel processing in ELKI, based on {@link ThreadPoolExecutor}.
+ *
+ * TODO: make configurable how many threads are used.
+ *
+ * @author Erich Schubert
+ */
+public class ParallelCore {
+ /**
+ * The number of CPUs to use.
+ */
+ public static final int ALL_PROCESSORS = Runtime.getRuntime().availableProcessors();
+
+ /**
+ * Static core
+ */
+ private static final ParallelCore STATIC = new ParallelCore(ALL_PROCESSORS);
+
+ /**
+ * Executor service.
+ */
+ ThreadPoolExecutor executor;
+
+ /**
+ * Number of connected submitters.
+ */
+ private AtomicInteger connected = new AtomicInteger(0);
+
+ /**
+ * Maximum number of processors to use.
+ */
+ private int processors;
+
+ /**
+ * Constructor.
+ */
+ protected ParallelCore(int processors) {
+ super();
+ this.processors = processors;
+ }
+
+ /**
+ * Get the static core object.
+ *
+ * @return Core
+ */
+ public static ParallelCore getCore() {
+ return STATIC;
+ }
+
+ /**
+ * Get desired level of parallelism
+ *
+ * @return Number of threads to run in parallel
+ */
+ public int getParallelism() {
+ return executor.getMaximumPoolSize();
+ }
+
+ /**
+ * Submit a task to the executor core.
+ *
+ * @param task Submitted task
+ *
+ * @return Future to observe completion
+ */
+ public <T> Future<T> submit(Callable<T> task) {
+ return executor.submit(task);
+ }
+
+ /**
+ * Connect to the executor.
+ */
+ public void connect() {
+ if(executor == null) {
+ synchronized(this) {
+ if(executor == null) {
+ executor = new ThreadPoolExecutor(0, processors, 10L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
+ executor.allowCoreThreadTimeOut(true);
+ }
+ }
+ }
+ int c = this.connected.incrementAndGet();
+ if(c == 1) {
+ executor.allowCoreThreadTimeOut(false);
+ executor.setCorePoolSize(executor.getMaximumPoolSize());
+ }
+ }
+
+ /**
+ * Disconnect to the executor.
+ */
+ public void disconnect() {
+ int c = this.connected.decrementAndGet();
+ if(c == 0) {
+ synchronized(this) {
+ executor.allowCoreThreadTimeOut(true);
+ executor.setCorePoolSize(0);
+ }
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/ParallelExecutor.java b/src/de/lmu/ifi/dbs/elki/parallel/ParallelExecutor.java
new file mode 100644
index 00000000..57b226be
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/ParallelExecutor.java
@@ -0,0 +1,173 @@
+package de.lmu.ifi.dbs.elki.parallel;
+
+/*
+ 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.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.parallel.processor.Processor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedVariable;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedVariable.Instance;
+
+/**
+ * Class to run processors in parallel, on all available cores.
+ *
+ * TODO: add progress
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has BlockArrayRunner
+ * @apiviz.uses ParallelCore
+ */
+public class ParallelExecutor {
+ /**
+ * Run a task on all available CPUs.
+ *
+ * @param ids IDs to process
+ * @param procs Processors to run
+ */
+ public static final void run(DBIDs ids, Processor... procs) {
+ // TODO: try different strategies anyway!
+ ArrayDBIDs aids = DBIDUtil.ensureArray(ids);
+ ParallelCore core = ParallelCore.getCore();
+ try {
+ final int size = aids.size();
+ core.connect();
+ int numparts = core.getParallelism();
+ // TODO: are there better heuristics for choosing this?
+ numparts = (size > numparts * numparts * 16) ? numparts * numparts - 1 : numparts;
+
+ final int blocksize = (size + (numparts - 1)) / numparts;
+ List<Future<ArrayDBIDs>> parts = new ArrayList<>(numparts);
+ for(int i = 0; i < numparts; i++) {
+ final int start = i * blocksize;
+ final int end = (start + blocksize < size) ? start + blocksize : size;
+ Callable<ArrayDBIDs> run = new BlockArrayRunner(aids, start, end, procs);
+ parts.add(core.submit(run));
+ }
+
+ for(Future<ArrayDBIDs> fut : parts) {
+ fut.get();
+ }
+ }
+ catch(ExecutionException e) {
+ throw new RuntimeException("Processor execution failed.", e);
+ }
+ catch(InterruptedException e) {
+ throw new RuntimeException("Parallel execution interrupted.");
+ }
+ finally {
+ core.disconnect();
+ }
+ }
+
+ /**
+ * Run for an array part, without step size.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.uses Processor
+ */
+ protected static class BlockArrayRunner implements Callable<ArrayDBIDs>, Executor {
+ /**
+ * Array IDs to process
+ */
+ private ArrayDBIDs ids;
+
+ /**
+ * Start position
+ */
+ private int start;
+
+ /**
+ * End position
+ */
+ private int end;
+
+ /**
+ * The processor masters that own the instances.
+ */
+ private Processor[] procs;
+
+ /**
+ * Variables map.
+ */
+ private HashMap<SharedVariable<?>, SharedVariable.Instance<?>> variables = new HashMap<>();
+
+ /**
+ * Constructor.
+ *
+ * @param ids IDs to process
+ * @param start Starting position
+ * @param end End position
+ * @param procs Processors to run
+ */
+ protected BlockArrayRunner(ArrayDBIDs ids, int start, int end, Processor[] procs) {
+ super();
+ this.ids = ids;
+ this.start = start;
+ this.end = end;
+ this.procs = procs;
+ }
+
+ @Override
+ public ArrayDBIDs call() {
+ Processor.Instance[] instances = new Processor.Instance[procs.length];
+ for(int i = 0; i < procs.length; i++) {
+ instances[i] = procs[i].instantiate(this);
+ }
+
+ DBIDArrayIter iter = ids.iter();
+ iter.seek(start);
+ for(int c = end - start; iter.valid() && c >= 0; iter.advance(), c--) {
+ for(int i = 0; i < instances.length; i++) {
+ instances[i].map(iter);
+ }
+ }
+ for(int i = 0; i < instances.length; i++) {
+ procs[i].cleanup(instances[i]);
+ }
+ return ids;
+ }
+
+ @Override
+ public <I extends Instance<?>> I getInstance(SharedVariable<I> parent) {
+ @SuppressWarnings("unchecked")
+ I inst = (I) variables.get(parent);
+ if(inst == null) {
+ inst = parent.instantiate();
+ variables.put(parent, inst);
+ }
+ return inst;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/SingleThreadedExecutor.java b/src/de/lmu/ifi/dbs/elki/parallel/SingleThreadedExecutor.java
new file mode 100644
index 00000000..71811b3a
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/SingleThreadedExecutor.java
@@ -0,0 +1,114 @@
+package de.lmu.ifi.dbs.elki.parallel;
+
+/*
+ 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.HashMap;
+
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.parallel.processor.Processor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedVariable;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedVariable.Instance;
+
+/**
+ * Class to process the whole data set in a single thread.
+ *
+ * Currently not used.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has SingleThreadedRunner
+ */
+public class SingleThreadedExecutor {
+ /**
+ * Run a task on a single thread.
+ *
+ * @param ids IDs to process
+ * @param procs Processors to run
+ */
+ public static final void run(DBIDs ids, Processor... procs) {
+ new SingleThreadedRunner(ids, procs).run();
+ }
+
+ /**
+ * Run for an array part, without step size.
+ *
+ * @author Erich Schubert
+ */
+ protected static class SingleThreadedRunner implements Executor {
+ /**
+ * Array IDs to process
+ */
+ private DBIDs ids;
+
+ /**
+ * The process masters that own the instances.
+ */
+ private Processor[] procs;
+
+ /**
+ * Variables map.
+ */
+ private HashMap<SharedVariable<?>, SharedVariable.Instance<?>> variables = new HashMap<>();
+
+ /**
+ * Constructor.
+ *
+ * @param ids IDs to process
+ * @param procs Processor functions to run
+ */
+ protected SingleThreadedRunner(DBIDs ids, Processor[] procs) {
+ super();
+ this.ids = ids;
+ this.procs = procs;
+ }
+
+ public void run() {
+ Processor.Instance[] instances = new Processor.Instance[procs.length];
+ for(int i = 0; i < procs.length; i++) {
+ instances[i] = procs[i].instantiate(this);
+ }
+
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(int i = 0; i < instances.length; i++) {
+ instances[i].map(iter);
+ }
+ }
+ for(int i = 0; i < instances.length; i++) {
+ procs[i].cleanup(instances[i]);
+ }
+ }
+
+ @Override
+ public <I extends Instance<?>> I getInstance(SharedVariable<I> parent) {
+ @SuppressWarnings("unchecked")
+ I inst = (I) variables.get(parent);
+ if(inst == null) {
+ inst = parent.instantiate();
+ variables.put(parent, inst);
+ }
+ return inst;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/package-info.java b/src/de/lmu/ifi/dbs/elki/parallel/package-info.java
new file mode 100644
index 00000000..d6ecfdc4
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/package-info.java
@@ -0,0 +1,32 @@
+/**
+ * Parallel processing core for ELKI.
+ *
+ * Parallel processing is a tricky topic on its own.
+ * ELKI will probably not be able to provide the ultimate parallel processing architecture,
+ * and this package aims at providing some basic functionality that allows at least naive
+ * parallelization of popular data mining algorithms.
+ */
+
+/*
+ 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.parallel; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/processor/AbstractDoubleProcessor.java b/src/de/lmu/ifi/dbs/elki/parallel/processor/AbstractDoubleProcessor.java
new file mode 100644
index 00000000..6232a12c
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/processor/AbstractDoubleProcessor.java
@@ -0,0 +1,85 @@
+package de.lmu.ifi.dbs.elki.parallel.processor;
+
+/*
+ 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.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.parallel.Executor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedDouble;
+
+/**
+ * Abstract base class for processors that output double values.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has Instance
+ * @apiviz.uses SharedDouble
+ */
+public abstract class AbstractDoubleProcessor implements Processor {
+ /**
+ * Output variable
+ */
+ protected SharedDouble output;
+
+ /**
+ * Connect the output variable.
+ *
+ * @param output Output variable
+ */
+ public void connectOutput(SharedDouble output) {
+ this.output = output;
+ }
+
+ @Override
+ public abstract Processor.Instance instantiate(Executor exectutor);
+
+ @Override
+ public void cleanup(Processor.Instance inst) {
+ // Do nothing by default.
+ }
+
+ /**
+ * Instance.
+ *
+ * @author Erich Schubert
+ */
+ public static abstract class Instance implements Processor.Instance {
+ /**
+ * Output variable
+ */
+ protected SharedDouble.Instance output;
+
+ /**
+ * Constructor.
+ *
+ * @param output Output variable
+ */
+ public Instance(SharedDouble.Instance output) {
+ super();
+ this.output = output;
+ }
+
+ @Override
+ public abstract void map(DBIDRef id);
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/processor/DoubleMinMaxProcessor.java b/src/de/lmu/ifi/dbs/elki/parallel/processor/DoubleMinMaxProcessor.java
new file mode 100644
index 00000000..542f7a09
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/processor/DoubleMinMaxProcessor.java
@@ -0,0 +1,127 @@
+package de.lmu.ifi.dbs.elki.parallel.processor;
+
+/*
+ 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.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
+import de.lmu.ifi.dbs.elki.parallel.Executor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedDouble;
+
+/**
+ * Sink collecting minimum and maximum values.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has Instance
+ * @apiviz.uses SharedDouble
+ * @apiviz.has DoubleMinMax
+ */
+public class DoubleMinMaxProcessor implements Processor {
+ /**
+ * The central data store.
+ */
+ DoubleMinMax minmax = new DoubleMinMax();
+
+ /**
+ * Input channel
+ */
+ SharedDouble input;
+
+ /**
+ * Constructor.
+ */
+ public DoubleMinMaxProcessor() {
+ super();
+ }
+
+ /**
+ * Connect an input channel.
+ *
+ * @param input Input channel
+ */
+ public void connectInput(SharedDouble input) {
+ this.input = input;
+ }
+
+ @Override
+ public Instance instantiate(Executor executor) {
+ return new Instance(executor.getInstance(input));
+ }
+
+ @Override
+ public void cleanup(Processor.Instance inst) {
+ merge(((Instance) inst).minmax);
+ }
+
+ /**
+ * Merge the result of an instance.
+ *
+ * @param minmax Minmax value
+ */
+ protected synchronized void merge(DoubleMinMax minmax) {
+ this.minmax.put(minmax.getMin());
+ this.minmax.put(minmax.getMax());
+ }
+
+ /**
+ * Get the minmax object.
+ *
+ * @return Minmax object
+ */
+ public DoubleMinMax getMinMax() {
+ return minmax;
+ }
+
+ /**
+ * Instance for a particular sub-channel / part of the data set.
+ *
+ * @author Erich Schubert
+ */
+ private static class Instance implements Processor.Instance {
+ /**
+ * The central data store.
+ */
+ private DoubleMinMax minmax = new DoubleMinMax();
+
+ /**
+ * Input channel instance
+ */
+ private SharedDouble.Instance input;
+
+ /**
+ * Constructor.
+ *
+ * @param input Input channel instance.
+ */
+ public Instance(SharedDouble.Instance input) {
+ super();
+ this.input = input;
+ }
+
+ @Override
+ public void map(DBIDRef id) {
+ minmax.put(input.doubleValue());
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/processor/KDistanceProcessor.java b/src/de/lmu/ifi/dbs/elki/parallel/processor/KDistanceProcessor.java
new file mode 100644
index 00000000..65119f98
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/processor/KDistanceProcessor.java
@@ -0,0 +1,111 @@
+package de.lmu.ifi.dbs.elki.parallel.processor;
+
+/*
+ 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.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.parallel.Executor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedDouble;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedObject;
+
+/**
+ * Compute the kNN distance for each object.
+ *
+ * Needs the k nearest neighbors as input, for example from {@link KNNProcessor}.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has Instance
+ * @apiviz.uses KNNList
+ * @apiviz.uses SharedObject
+ */
+public class KDistanceProcessor extends AbstractDoubleProcessor {
+ /**
+ * K parameter
+ */
+ int k;
+
+ /**
+ * Constructor.
+ *
+ * @param k K parameter
+ */
+ public KDistanceProcessor(int k) {
+ super();
+ this.k = k;
+ }
+
+ /**
+ * KNN query object
+ */
+ SharedObject<? extends KNNList> input;
+
+ /**
+ * Connect the input channel.
+ *
+ * @param input Input channel
+ */
+ public void connectKNNInput(SharedObject<? extends KNNList> input) {
+ this.input = input;
+ }
+
+ @Override
+ public Instance instantiate(Executor executor) {
+ return new Instance(k, executor.getInstance(input), executor.getInstance(output));
+ }
+
+ /**
+ * Instance for precomputing the kNN.
+ *
+ * @author Erich Schubert
+ */
+ public static class Instance extends AbstractDoubleProcessor.Instance {
+ /**
+ * k Parameter
+ */
+ int k;
+
+ /**
+ * kNN query
+ */
+ SharedObject.Instance<? extends KNNList> input;
+
+ /**
+ * Constructor.
+ *
+ * @param k K parameter
+ * @param input kNN input data
+ * @param store Datastore to write to
+ */
+ protected Instance(int k, SharedObject.Instance<? extends KNNList> input, SharedDouble.Instance store) {
+ super(store);
+ this.k = k;
+ this.input = input;
+ }
+
+ @Override
+ public void map(DBIDRef id) {
+ output.set(input.get().get(k - 1).doubleValue());
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/processor/KNNProcessor.java b/src/de/lmu/ifi/dbs/elki/parallel/processor/KNNProcessor.java
new file mode 100644
index 00000000..45813b3b
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/processor/KNNProcessor.java
@@ -0,0 +1,130 @@
+package de.lmu.ifi.dbs.elki.parallel.processor;
+
+/*
+ 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.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.parallel.Executor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedObject;
+
+/**
+ * Processor to compute the kNN of each object.
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Object type
+ *
+ * @apiviz.has Instance
+ * @apiviz.uses KNNQuery
+ * @apiviz.uses SharedObject
+ * @apiviz.has KNNList
+ */
+public class KNNProcessor<O> implements Processor {
+ /**
+ * K parameter
+ */
+ int k;
+
+ /**
+ * KNN query object
+ */
+ KNNQuery<O> knnq;
+
+ /**
+ * Output channel to write to
+ */
+ SharedObject<KNNList> out;
+
+ /**
+ * Constructor.
+ *
+ * @param k K parameter
+ * @param knnq Distance query to use
+ */
+ public KNNProcessor(int k, KNNQuery<O> knnq) {
+ super();
+ this.k = k;
+ this.knnq = knnq;
+ }
+
+ /**
+ * Connect the output channel.
+ *
+ * @param output Output channel
+ */
+ public void connectKNNOutput(SharedObject<KNNList> output) {
+ this.out = output;
+ }
+
+ @Override
+ public Instance<O> instantiate(Executor executor) {
+ return new Instance<>(k, knnq, executor.getInstance(out));
+ }
+
+ @Override
+ public void cleanup(Processor.Instance inst) {
+ // Nothing to do.
+ }
+
+ /**
+ * Instance for precomputing the kNN.
+ *
+ * @author Erich Schubert
+ */
+ public static class Instance<O> implements Processor.Instance {
+ /**
+ * k Parameter
+ */
+ int k;
+
+ /**
+ * kNN query
+ */
+ KNNQuery<O> knnq;
+
+ /**
+ * Output data store
+ */
+ SharedObject.Instance<KNNList> out;
+
+ /**
+ * Constructor.
+ *
+ * @param k K parameter
+ * @param knnq KNN query
+ * @param out Output channel to write to
+ */
+ protected Instance(int k, KNNQuery<O> knnq, SharedObject.Instance<KNNList> out) {
+ super();
+ this.k = k;
+ this.knnq = knnq;
+ this.out = out;
+ }
+
+ @Override
+ public void map(DBIDRef id) {
+ out.set(knnq.getKNNForDBID(id, k));
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDPair.java b/src/de/lmu/ifi/dbs/elki/parallel/processor/Processor.java
index a9d879d9..b7875e91 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDPair.java
+++ b/src/de/lmu/ifi/dbs/elki/parallel/processor/Processor.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.database.ids.distance;
+package de.lmu.ifi.dbs.elki.parallel.processor;
/*
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,30 +24,43 @@ package de.lmu.ifi.dbs.elki.database.ids.distance;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
+import de.lmu.ifi.dbs.elki.parallel.Executor;
/**
- * Pair containing a distance an an object ID
- *
- * Note: there is no getter for the object, as this is a {@link DBIDRef}.
+ * Class to represent a processor factory.
*
* @author Erich Schubert
- *
- * @param <D> Distance
+ *
+ * @apiviz.has Instance
*/
-public interface DistanceDBIDPair<D extends Distance<D>> extends DBIDRef {
+public interface Processor {
/**
- * Get the distance.
+ * Create an instance. May be called multiple times, for example for multiple
+ * threads.
*
- * @return Distance
+ * @param executor Job executor
+ * @return Instance
*/
- public D getDistance();
-
+ public Instance instantiate(Executor executor);
+
+ /**
+ * Invoke cleanup.
+ *
+ * @param inst Instance to cleanup.
+ */
+ public void cleanup(Instance inst);
+
/**
- * Compare to another result, by distance, smaller first.
+ * Instance.
*
- * @param other Other result
- * @return Comparison result
+ * @author Erich Schubert
*/
- public int compareByDistance(DistanceDBIDPair<D> other);
-}
+ public interface Instance {
+ /**
+ * Process ("map") a single object
+ *
+ * @param id Object to map.
+ */
+ public void map(DBIDRef id);
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/processor/WriteDataStoreProcessor.java b/src/de/lmu/ifi/dbs/elki/parallel/processor/WriteDataStoreProcessor.java
new file mode 100644
index 00000000..66ebf0a2
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/processor/WriteDataStoreProcessor.java
@@ -0,0 +1,108 @@
+package de.lmu.ifi.dbs.elki.parallel.processor;
+
+/*
+ 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.database.datastore.WritableDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.parallel.Executor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedObject;
+
+/**
+ * Output channel to store data in a {@link WritableDataStore}.
+ *
+ * @author Erich Schubert
+ *
+ * @param <T> data type
+ *
+ * @apiviz.has Instance
+ * @apiviz.uses SharedObject
+ * @apiviz.uses WritableDataStore
+ */
+public class WriteDataStoreProcessor<T> implements Processor {
+ /**
+ * Store to write to
+ */
+ WritableDataStore<T> store;
+
+ /**
+ * Input variable
+ */
+ SharedObject<T> input;
+
+ /**
+ * Constructor.
+ *
+ * @param store Data store to write to
+ */
+ public WriteDataStoreProcessor(WritableDataStore<T> store) {
+ super();
+ this.store = store;
+ }
+
+ /**
+ * Connect the data source
+ *
+ * @param input Input
+ */
+ public void connectInput(SharedObject<T> input) {
+ this.input = input;
+ }
+
+ @Override
+ public Instance instantiate(Executor executor) {
+ return new Instance(executor.getInstance(input));
+ }
+
+ @Override
+ public void cleanup(Processor.Instance inst) {
+ // Nothing to do.
+ }
+
+ /**
+ * Instance for a sub-channel.
+ *
+ * @author Erich Schubert
+ */
+ public class Instance implements Processor.Instance {
+ /**
+ * Variable to exchange data over
+ */
+ SharedObject.Instance<T> input;
+
+ /**
+ * Constructor.
+ *
+ * @param input Input object
+ */
+ public Instance(SharedObject.Instance<T> input) {
+ super();
+ this.input = input;
+ }
+
+ @Override
+ public void map(DBIDRef id) {
+ store.put(id, input.get());
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/processor/WriteDoubleDataStoreProcessor.java b/src/de/lmu/ifi/dbs/elki/parallel/processor/WriteDoubleDataStoreProcessor.java
new file mode 100644
index 00000000..f8bf5b74
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/processor/WriteDoubleDataStoreProcessor.java
@@ -0,0 +1,106 @@
+package de.lmu.ifi.dbs.elki.parallel.processor;
+
+/*
+ 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.database.datastore.WritableDoubleDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.parallel.Executor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedDouble;
+
+/**
+ * Write double values into a {@link WritableDoubleDataStore}.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has Instance
+ * @apiviz.uses SharedDouble
+ * @apiviz.uses WritableDoubleDataStore
+ */
+public class WriteDoubleDataStoreProcessor implements Processor {
+ /**
+ * Store to write to
+ */
+ WritableDoubleDataStore store;
+
+ /**
+ * Shared double variable
+ */
+ SharedDouble input;
+
+ /**
+ * Constructor.
+ *
+ * @param store Data store to write to
+ */
+ public WriteDoubleDataStoreProcessor(WritableDoubleDataStore store) {
+ super();
+ this.store = store;
+ }
+
+ /**
+ * Connect the input variable
+ *
+ * @param input Input variable
+ */
+ public void connectInput(SharedDouble input) {
+ this.input = input;
+ }
+
+ @Override
+ public Instance instantiate(Executor executor) {
+ return new Instance(executor.getInstance(input));
+ }
+
+ @Override
+ public void cleanup(Processor.Instance inst) {
+ // Nothing to do.
+ }
+
+ /**
+ * Instance for a sub-channel.
+ *
+ * @author Erich Schubert
+ */
+ public class Instance implements Processor.Instance {
+ /**
+ * Shared double variable
+ */
+ SharedDouble.Instance input;
+
+ /**
+ * Constructor.
+ *
+ * @param input Input
+ */
+ public Instance(SharedDouble.Instance input) {
+ super();
+ this.input = input;
+ }
+
+ @Override
+ public void map(DBIDRef id) {
+ store.putDouble(id, input.doubleValue());
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/processor/WriteIntegerDataStoreProcessor.java b/src/de/lmu/ifi/dbs/elki/parallel/processor/WriteIntegerDataStoreProcessor.java
new file mode 100644
index 00000000..3b68117f
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/processor/WriteIntegerDataStoreProcessor.java
@@ -0,0 +1,106 @@
+package de.lmu.ifi.dbs.elki.parallel.processor;
+
+/*
+ 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.database.datastore.WritableIntegerDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.parallel.Executor;
+import de.lmu.ifi.dbs.elki.parallel.variables.SharedInteger;
+
+/**
+ * Write int values into a {@link WritableIntegerDataStore}.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has Instance
+ * @apiviz.uses SharedInteger
+ * @apiviz.uses WritableIntegerDataStore
+ */
+public class WriteIntegerDataStoreProcessor implements Processor {
+ /**
+ * Store to write to
+ */
+ WritableIntegerDataStore store;
+
+ /**
+ * Shared int variable
+ */
+ SharedInteger input;
+
+ /**
+ * Constructor.
+ *
+ * @param store Data store to write to
+ */
+ public WriteIntegerDataStoreProcessor(WritableIntegerDataStore store) {
+ super();
+ this.store = store;
+ }
+
+ /**
+ * Connect the input variable
+ *
+ * @param input Input variable
+ */
+ public void connectInput(SharedInteger input) {
+ this.input = input;
+ }
+
+ @Override
+ public Instance instantiate(Executor executor) {
+ return new Instance(executor.getInstance(input));
+ }
+
+ @Override
+ public void cleanup(Processor.Instance inst) {
+ // Nothing to do.
+ }
+
+ /**
+ * Instance for a sub-channel.
+ *
+ * @author Erich Schubert
+ */
+ public class Instance implements Processor.Instance {
+ /**
+ * Shared int variable
+ */
+ SharedInteger.Instance input;
+
+ /**
+ * Constructor.
+ *
+ * @param input Input
+ */
+ public Instance(SharedInteger.Instance input) {
+ super();
+ this.input = input;
+ }
+
+ @Override
+ public void map(DBIDRef id) {
+ store.putInt(id, input.intValue());
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/processor/package-info.java b/src/de/lmu/ifi/dbs/elki/parallel/processor/package-info.java
new file mode 100644
index 00000000..52b750e1
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/processor/package-info.java
@@ -0,0 +1,47 @@
+/**
+ * Processor API of ELKI, and some essential shared processors.
+ *
+ * A processor in ELKI is a function, that can be applied in parallel to different objects
+ * in the database. It follows the factory design pattern, as it needs to be instantiated
+ * for every thread separately.
+ *
+ * While this bears some similarity to mappers as used in Map Reduce,
+ * this is not an implementation of a map-reduce framework. This is why there
+ * is no "reducer" in the ELKI framework.
+ *
+ * A key difference is that mappers may be combined into the same thread, and exchange values
+ * via the {@link de.lmu.ifi.dbs.elki.parallel.variables.SharedVariable} API.
+ *
+ * The other key difference is that ELKI is not (yet?) running in a distributed framework,
+ * therefore it is perfectly possible to have a mapper query the database, or write to
+ * an output storage. It may be necessary to apply locking in such cases!
+ *
+ * As we want to write to some storage at the end, the last processor usually will not have
+ * an "output", thus the name "map" is not a good match anymore.
+ *
+ * @apiviz.exclude .*\.Instance$
+ */
+
+/*
+ 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.parallel.processor; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/variables/SharedDouble.java b/src/de/lmu/ifi/dbs/elki/parallel/variables/SharedDouble.java
new file mode 100644
index 00000000..4dc0348b
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/variables/SharedDouble.java
@@ -0,0 +1,86 @@
+package de.lmu.ifi.dbs.elki.parallel.variables;
+
+/*
+ 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/>.
+ */
+
+/**
+ * Direct channel connecting two processors.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has SharedDouble.Instance
+ */
+public class SharedDouble implements SharedVariable<SharedDouble.Instance> {
+ @Override
+ public Instance instantiate() {
+ return new Instance();
+ }
+
+ /**
+ * Instance for a sub-channel.
+ *
+ * @author Erich Schubert
+ */
+ public static class Instance implements SharedVariable.Instance<Double> {
+ /**
+ * Cache for last data consumed/produced
+ */
+ private double data = Double.NaN;
+
+ /**
+ * @deprecated use {@link #doubleValue}!
+ */
+ @Deprecated
+ @Override
+ public Double get() {
+ return data;
+ }
+
+ /**
+ * @deprecated use {@link #set(double)}!
+ */
+ @Deprecated
+ @Override
+ public void set(Double data) {
+ this.data = data;
+ }
+
+ /**
+ * Get the variables value.
+ *
+ * @return Double value
+ */
+ public double doubleValue() {
+ return data;
+ }
+
+ /**
+ * Set the variables value.
+ *
+ * @param data New value
+ */
+ public void set(double data) {
+ this.data = data;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/variables/SharedInteger.java b/src/de/lmu/ifi/dbs/elki/parallel/variables/SharedInteger.java
new file mode 100644
index 00000000..0804c262
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/variables/SharedInteger.java
@@ -0,0 +1,86 @@
+package de.lmu.ifi.dbs.elki.parallel.variables;
+
+/*
+ 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/>.
+ */
+
+/**
+ * Direct channel connecting two processors.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has SharedInteger.Instance
+ */
+public class SharedInteger implements SharedVariable<SharedInteger.Instance> {
+ @Override
+ public Instance instantiate() {
+ return new Instance();
+ }
+
+ /**
+ * Instance for a sub-channel.
+ *
+ * @author Erich Schubert
+ */
+ public static class Instance implements SharedVariable.Instance<Integer> {
+ /**
+ * Cache for last data consumed/produced
+ */
+ private int data = 0xDEADBEEF;
+
+ /**
+ * @deprecated use {@link #intValue}!
+ */
+ @Deprecated
+ @Override
+ public Integer get() {
+ return data;
+ }
+
+ /**
+ * @deprecated use {@link #set(int)}!
+ */
+ @Deprecated
+ @Override
+ public void set(Integer data) {
+ this.data = data;
+ }
+
+ /**
+ * Get the variables value.
+ *
+ * @return Integer value
+ */
+ public int intValue() {
+ return data;
+ }
+
+ /**
+ * Set the variables value.
+ *
+ * @param data New value
+ */
+ public void set(int data) {
+ this.data = data;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDListIter.java b/src/de/lmu/ifi/dbs/elki/parallel/variables/SharedObject.java
index 68b2de1e..06ff3da6 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDListIter.java
+++ b/src/de/lmu/ifi/dbs/elki/parallel/variables/SharedObject.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.database.ids.distance;
+package de.lmu.ifi.dbs.elki.parallel.variables;
/*
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,38 +23,42 @@ package de.lmu.ifi.dbs.elki.database.ids.distance;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-
/**
- * Iterator for double valued distance-based query results.
+ * Variable to share between different processors (within one thread only!)
*
* @author Erich Schubert
+ *
+ * @apiviz.has SharedObject.Instance
+ *
+ * @param <T> Data type
*/
-public interface DoubleDistanceDBIDListIter extends DistanceDBIDListIter<DoubleDistance> {
- /**
- * Get the distance
- *
- * @return distance
- */
- public double doubleDistance();
-
- /**
- * Get an object pair.
- *
- * @return object pair
- */
+public class SharedObject<T> implements SharedVariable<SharedObject.Instance<T>> {
@Override
- public DoubleDistanceDBIDPair getDistancePair();
+ public Instance<T> instantiate() {
+ return new Instance<>();
+ }
/**
- * Get the distance
+ * Instance for a particular thread.
*
- * @deprecated Use {@link #doubleDistance} to avoid creating unnecessary
- * objects.
+ * @author Erich Schubert
*
- * @return distance
+ * @param <T> Data type
*/
- @Deprecated
- @Override
- public DoubleDistance getDistance();
-}
+ public static class Instance<T> implements SharedVariable.Instance<T> {
+ /**
+ * Cache for last data consumed/produced
+ */
+ private T data = null;
+
+ @Override
+ public T get() {
+ return data;
+ }
+
+ @Override
+ public void set(T data) {
+ this.data = data;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDPair.java b/src/de/lmu/ifi/dbs/elki/parallel/variables/SharedVariable.java
index 5286029b..7dc798aa 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDPair.java
+++ b/src/de/lmu/ifi/dbs/elki/parallel/variables/SharedVariable.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.database.ids.distance;
+package de.lmu.ifi.dbs.elki.parallel.variables;
/*
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,32 +23,43 @@ package de.lmu.ifi.dbs.elki.database.ids.distance;
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.distance.distancevalue.DoubleDistance;
-
/**
- * Pair containing a double distance a DBID.
- *
- * There is no getter for the DBID, as this is a {@link DBIDRef} already.
+ * Shared variables storing a particular type.
*
* @author Erich Schubert
+ *
+ * @apiviz.has SharedVariable.Instance
+ *
+ * @param <I> Instance type
*/
-public interface DoubleDistanceDBIDPair extends DistanceDBIDPair<DoubleDistance> {
+public interface SharedVariable<I extends SharedVariable.Instance<?>> {
/**
- * Get the distance.
+ * Instantiate for an execution thread.
*
- * @deprecated Would produce a DoubleDistance object. Use {@link #doubleDistance} instead!
- *
- * @return Distance
+ * @return new Instance
*/
- @Override
- @Deprecated
- public DoubleDistance getDistance();
+ I instantiate();
/**
- * Get the distance.
+ * Instance for a single execution thread.
+ *
+ * @author Erich Schubert
*
- * @return Distance
+ * @param <T> Payload type
*/
- public double doubleDistance();
+ public static interface Instance<T> {
+ /**
+ * Get the current value
+ *
+ * @return Value
+ */
+ T get();
+
+ /**
+ * Set a new value
+ *
+ * @param data Setter
+ */
+ void set(T data);
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/parallel/variables/package-info.java b/src/de/lmu/ifi/dbs/elki/parallel/variables/package-info.java
new file mode 100644
index 00000000..293faa38
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/parallel/variables/package-info.java
@@ -0,0 +1,28 @@
+/**
+ * Variables are instantiated for each thread, and allow passing values from
+ * one processor to another within the same thread.
+ */
+
+/*
+ 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.parallel.variables; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/persistent/AbstractExternalizablePage.java b/src/de/lmu/ifi/dbs/elki/persistent/AbstractExternalizablePage.java
index 7e060012..3aa2bb37 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/AbstractExternalizablePage.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/AbstractExternalizablePage.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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/persistent/AbstractPageFile.java b/src/de/lmu/ifi/dbs/elki/persistent/AbstractPageFile.java
index d6e750b8..4ea4c555 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/AbstractPageFile.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/AbstractPageFile.java
@@ -7,7 +7,7 @@ import de.lmu.ifi.dbs.elki.logging.statistics.Counter;
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/persistent/AbstractPageFileFactory.java b/src/de/lmu/ifi/dbs/elki/persistent/AbstractPageFileFactory.java
index 3dce60eb..aa05e9d7 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/AbstractPageFileFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/AbstractPageFileFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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/persistent/AbstractStoringPageFile.java b/src/de/lmu/ifi/dbs/elki/persistent/AbstractStoringPageFile.java
index 6ac6eda9..d5d156e1 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/AbstractStoringPageFile.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/AbstractStoringPageFile.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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/persistent/DefaultPageHeader.java b/src/de/lmu/ifi/dbs/elki/persistent/DefaultPageHeader.java
index 5ae3312a..31118d69 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/DefaultPageHeader.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/DefaultPageHeader.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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,6 +26,8 @@ package de.lmu.ifi.dbs.elki.persistent;
import java.io.IOException;
import java.io.RandomAccessFile;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+
/**
* Default implementation of a page header.
*
diff --git a/src/de/lmu/ifi/dbs/elki/persistent/ExternalizablePage.java b/src/de/lmu/ifi/dbs/elki/persistent/ExternalizablePage.java
index 0ec0f7fb..a3878915 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/ExternalizablePage.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/ExternalizablePage.java
@@ -6,7 +6,7 @@ import java.io.Externalizable;
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/persistent/LRUCache.java b/src/de/lmu/ifi/dbs/elki/persistent/LRUCache.java
index 18726ec7..7ad67c03 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/LRUCache.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/LRUCache.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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/persistent/LRUCachePageFileFactory.java b/src/de/lmu/ifi/dbs/elki/persistent/LRUCachePageFileFactory.java
index 54c3e58f..00fe01f8 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/LRUCachePageFileFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/LRUCachePageFileFactory.java
@@ -11,7 +11,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
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/persistent/MemoryPageFile.java b/src/de/lmu/ifi/dbs/elki/persistent/MemoryPageFile.java
index 46d10fb4..29579409 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/MemoryPageFile.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/MemoryPageFile.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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/persistent/MemoryPageFileFactory.java b/src/de/lmu/ifi/dbs/elki/persistent/MemoryPageFileFactory.java
index 812e65c9..a90da76c 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/MemoryPageFileFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/MemoryPageFileFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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/persistent/OnDiskArray.java b/src/de/lmu/ifi/dbs/elki/persistent/OnDiskArray.java
index 3f0965e2..c5fde881 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/OnDiskArray.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/OnDiskArray.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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,6 +32,7 @@ import java.nio.channels.FileChannel.MapMode;
import java.nio.channels.FileLock;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
/**
* On Disc Array storage for records of a given size.
diff --git a/src/de/lmu/ifi/dbs/elki/persistent/OnDiskArrayPageFile.java b/src/de/lmu/ifi/dbs/elki/persistent/OnDiskArrayPageFile.java
index 061d4ce9..8fa62dd9 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/OnDiskArrayPageFile.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/OnDiskArrayPageFile.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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,6 +34,7 @@ import java.util.logging.Level;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferInputStream;
/**
* A OnDiskArrayPageFile stores objects persistently that implement the
diff --git a/src/de/lmu/ifi/dbs/elki/persistent/OnDiskArrayPageFileFactory.java b/src/de/lmu/ifi/dbs/elki/persistent/OnDiskArrayPageFileFactory.java
index 4ddfdf4d..7fff0194 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/OnDiskArrayPageFileFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/OnDiskArrayPageFileFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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/persistent/OnDiskUpperTriangleMatrix.java b/src/de/lmu/ifi/dbs/elki/persistent/OnDiskUpperTriangleMatrix.java
index 6a6cad01..41e47887 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/OnDiskUpperTriangleMatrix.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/OnDiskUpperTriangleMatrix.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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/persistent/Page.java b/src/de/lmu/ifi/dbs/elki/persistent/Page.java
index 9be6141c..30b9216a 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/Page.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/Page.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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/persistent/PageFile.java b/src/de/lmu/ifi/dbs/elki/persistent/PageFile.java
index e3978a51..d9eae091 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/PageFile.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/PageFile.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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/persistent/PageFileFactory.java b/src/de/lmu/ifi/dbs/elki/persistent/PageFileFactory.java
index 3c7fa86d..570c7126 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/PageFileFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/PageFileFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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/persistent/PageHeader.java b/src/de/lmu/ifi/dbs/elki/persistent/PageHeader.java
index 9729b1e7..2bc4dcf6 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/PageHeader.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/PageHeader.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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/persistent/PersistentPageFile.java b/src/de/lmu/ifi/dbs/elki/persistent/PersistentPageFile.java
index 5e0282c5..728e2fb2 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/PersistentPageFile.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/PersistentPageFile.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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
@@ -305,24 +305,6 @@ public class PersistentPageFile<P extends ExternalizablePage> extends AbstractSt
}
/**
- * Increases the {@link AbstractStoringPageFile#readAccess readAccess} counter by
- * one.
- */
- @Deprecated
- public void increaseReadAccess() {
- countRead();
- }
-
- /**
- * Increases the {@link AbstractStoringPageFile#writeAccess writeAccess} counter by
- * one.
- */
- @Deprecated
- public void increaseWriteAccess() {
- countWrite();
- }
-
- /**
* Set the next page id to the given value. If this means that any page ids
* stored in <code>emptyPages</code> are smaller than
* <code>next_page_id</code>, they are removed from this file's observation
diff --git a/src/de/lmu/ifi/dbs/elki/persistent/PersistentPageFileFactory.java b/src/de/lmu/ifi/dbs/elki/persistent/PersistentPageFileFactory.java
index 5dfe9ecb..2ea6a609 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/PersistentPageFileFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/PersistentPageFileFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.persistent;
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/persistent/package-info.java b/src/de/lmu/ifi/dbs/elki/persistent/package-info.java
index 45f575c1..9303256d 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/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/result/AbstractHierarchicalResult.java b/src/de/lmu/ifi/dbs/elki/result/AbstractHierarchicalResult.java
index 203e8395..67286b65 100644
--- a/src/de/lmu/ifi/dbs/elki/result/AbstractHierarchicalResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/AbstractHierarchicalResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/AprioriResult.java b/src/de/lmu/ifi/dbs/elki/result/AprioriResult.java
index 45e82b92..b39f15d9 100644
--- a/src/de/lmu/ifi/dbs/elki/result/AprioriResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/AprioriResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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,58 +23,58 @@ package de.lmu.ifi.dbs.elki.result;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.BitSet;
import java.util.List;
-import java.util.Map;
+
+import de.lmu.ifi.dbs.elki.algorithm.itemsetmining.Itemset;
+import de.lmu.ifi.dbs.elki.data.BitVector;
+import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
+import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable;
+import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
/**
* Result class for Apriori Algorithm.
*
* @author Erich Schubert
- *
*/
-public class AprioriResult extends BasicResult {
+public class AprioriResult extends BasicResult implements TextWriteable {
/**
- * The frequent itemsets.
+ * The supports of all frequent itemsets.
*/
- private List<BitSet> solution;
+ private List<Itemset> itemsets;
/**
- * The supports of all itemsets.
+ * Metadata of the data relation, for item labels.
*/
- private Map<BitSet, Integer> supports;
+ private VectorFieldTypeInformation<BitVector> meta;
/**
* Constructor.
*
* @param name The long name (for pretty printing)
* @param shortname the short name (for filenames etc.)
- * @param solution Frequent itemsets
- * @param supports Supports for the itemsets
+ * @param itemsets Frequent itemsets
+ * @param meta Metadata
*/
- public AprioriResult(String name, String shortname, List<BitSet> solution, Map<BitSet, Integer> supports) {
+ public AprioriResult(String name, String shortname, List<Itemset> itemsets, VectorFieldTypeInformation<BitVector> meta) {
super(name, shortname);
- this.solution = solution;
- this.supports = supports;
+ this.itemsets = itemsets;
+ this.meta = meta;
}
/**
* Returns the frequent item sets.
- *
+ *
* @return the frequent item sets.
*/
- public List<BitSet> getSolution() {
- return solution;
+ public List<Itemset> getItemsets() {
+ return itemsets;
}
- /**
- * Returns the frequencies of the frequent item sets.
- *
- * @return the frequencies of the frequent item sets
- */
- public Map<BitSet, Integer> getSupports() {
- return supports;
+ @Override
+ public void writeToText(TextWriterStream out, String label) {
+ for(Itemset itemset : itemsets) {
+ out.inlinePrintNoQuotes(itemset.appendTo(new StringBuilder(), meta));
+ out.flush();
+ }
}
-
- // TODO: text writer for AprioriResult!
}
diff --git a/src/de/lmu/ifi/dbs/elki/result/BasicResult.java b/src/de/lmu/ifi/dbs/elki/result/BasicResult.java
index f2d10149..06ef2d6d 100644
--- a/src/de/lmu/ifi/dbs/elki/result/BasicResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/BasicResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/ClusteringVectorDumper.java b/src/de/lmu/ifi/dbs/elki/result/ClusteringVectorDumper.java
new file mode 100644
index 00000000..7d78ca65
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/result/ClusteringVectorDumper.java
@@ -0,0 +1,269 @@
+package de.lmu.ifi.dbs.elki.result;
+
+/*
+ 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.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.database.Database;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRange;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.datasource.parser.ClusteringVectorParser;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy.Iter;
+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.FileParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.StringParameter;
+
+/**
+ * <p>
+ * Class to output a clustering result in a simple and compact ascii format:
+ * whitespace separated cluster indexes
+ * </p>
+ *
+ * This format can be read using {@link ClusteringVectorParser} for analysis.
+ *
+ * @author Erich Schubert
+ */
+public class ClusteringVectorDumper implements ResultHandler {
+ /**
+ * Class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(ClusteringVectorDumper.class);
+
+ /**
+ * Output file.
+ */
+ private File outputFile;
+
+ /**
+ * Optional label to force for this output.
+ */
+ private String forceLabel;
+
+ /**
+ * Always append to the output file.
+ */
+ private boolean append;
+
+ /**
+ * Constructor.
+ *
+ * @param outputFile Output file
+ * @param append Append to output file (overwrite otherwise).
+ * @param forceLabel Forced label to use for the output, may be {@code null}.
+ */
+ public ClusteringVectorDumper(File outputFile, boolean append, String forceLabel) {
+ super();
+ this.outputFile = outputFile;
+ this.forceLabel = forceLabel;
+ this.append = append;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param outputFile Output file
+ * @param append Append to output file (overwrite otherwise).
+ */
+ public ClusteringVectorDumper(File outputFile, boolean append) {
+ this(outputFile, append, null);
+ }
+
+ @Override
+ public void processNewResult(HierarchicalResult baseResult, Result newResult) {
+ List<Clustering<?>> cs = ResultUtil.getClusteringResults(newResult);
+ if(cs.size() < 1) {
+ return;
+ }
+ if(forceLabel != null && forceLabel.length() > 0 && cs.size() > 1) {
+ LOG.warning("Found more than one clustering result, they will have the same (forced) label.");
+ }
+
+ // Open output stream - or use stdout.
+ if(outputFile != null) {
+ try (FileOutputStream os = new FileOutputStream(outputFile, append); //
+ PrintStream writer = new PrintStream(os)) {
+ // TODO: dump settings, too?
+ for(Clustering<?> c : cs) {
+ dumpClusteringOutput(writer, baseResult.getHierarchy(), c);
+ }
+ append = true; // Append future results.
+ }
+ catch(IOException e) {
+ LOG.exception("Error writing to output stream.", e);
+ }
+ }
+ else {
+ for(Clustering<?> c : cs) {
+ dumpClusteringOutput(System.out, baseResult.getHierarchy(), c);
+ }
+ }
+ }
+
+ /**
+ * Dump a single clustering result.
+ *
+ * @param writer Output writer
+ * @param hierarchy Cluster hierarchy to process
+ * @param c Clustering result
+ */
+ protected void dumpClusteringOutput(PrintStream writer, ResultHierarchy hierarchy, Clustering<?> c) {
+ DBIDRange ids = null;
+ for(Iter<Result> iter = hierarchy.iterParents(c); iter.valid(); iter.advance()) {
+ Result parent = iter.get();
+ if(parent instanceof Relation) {
+ DBIDs pids = ((Relation<?>) parent).getDBIDs();
+ if(pids instanceof DBIDRange) {
+ ids = (DBIDRange) pids;
+ break;
+ }
+ LOG.warning("Parent result " + parent.getLongName() + " has DBID type " + pids.getClass());
+ }
+ }
+ // Fallback: try to locate a database.
+ if(ids == null) {
+ for(Iter<Result> iter = hierarchy.iterAll(); iter.valid(); iter.advance()) {
+ Result parent = iter.get();
+ if(parent instanceof Database) {
+ DBIDs pids = ((Database) parent).getRelation(TypeUtil.ANY).getDBIDs();
+ if(pids instanceof DBIDRange) {
+ ids = (DBIDRange) pids;
+ break;
+ }
+ LOG.warning("Parent result " + parent.getLongName() + " has DBID type " + pids.getClass());
+ }
+ }
+ }
+ if(ids == null) {
+ LOG.warning("Cannot dump cluster assignment, as I do not have a well-defined DBIDRange to use for a unique column assignment. DBIDs must be a continuous range.");
+ return;
+ }
+
+ WritableIntegerDataStore map = DataStoreUtil.makeIntegerStorage(ids, DataStoreFactory.HINT_TEMP);
+ int cnum = 0;
+ for(Cluster<?> clu : c.getAllClusters()) {
+ for(DBIDIter iter = clu.getIDs().iter(); iter.valid(); iter.advance()) {
+ map.putInt(iter, cnum);
+ }
+ ++cnum;
+ }
+ for(DBIDArrayIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ if(iter.getOffset() > 0) {
+ writer.append(' ');
+ }
+ writer.append(Integer.toString(map.intValue(iter)));
+ }
+ if(forceLabel != null) {
+ if(forceLabel.length() > 0) {
+ writer.append(' ').append(forceLabel);
+ }
+ }
+ else {
+ writer.append(' ').append(c.getLongName());
+ }
+ writer.append('\n');
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Output file name parameter.
+ */
+ public static final OptionID OUT_ID = new OptionID("clustering.output", "Output file name. When not given, the result will be written to stdout.");
+
+ /**
+ * Append flag.
+ */
+ public static final OptionID APPEND_ID = new OptionID("clustering.output.append", "Always append to the output file.");
+
+ /**
+ * Force label parameter.
+ */
+ public static final OptionID FORCE_LABEL_ID = new OptionID("clustering.label", "Parameter to override the clustering label, mostly to give a more descriptive label.");
+
+ /**
+ * Output file.
+ */
+ private File outputFile = null;
+
+ /**
+ * Optional label to force for this output.
+ */
+ private String forceLabel;
+
+ /**
+ * Always append to the output file.
+ */
+ private boolean append;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ FileParameter outputP = new FileParameter(OUT_ID, FileParameter.FileType.OUTPUT_FILE) //
+ .setOptional(true);
+ if(config.grab(outputP)) {
+ outputFile = outputP.getValue();
+ }
+
+ Flag appendF = new Flag(APPEND_ID);
+ if(config.grab(appendF)) {
+ append = appendF.isTrue();
+ }
+
+ StringParameter labelP = new StringParameter(FORCE_LABEL_ID) //
+ .setOptional(true);
+ if(config.grab(labelP)) {
+ forceLabel = labelP.getValue();
+ }
+ }
+
+ @Override
+ protected ClusteringVectorDumper makeInstance() {
+ return new ClusteringVectorDumper(outputFile, append, forceLabel);
+ }
+
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/result/CollectionResult.java b/src/de/lmu/ifi/dbs/elki/result/CollectionResult.java
index 76e35e48..de0442d9 100644
--- a/src/de/lmu/ifi/dbs/elki/result/CollectionResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/CollectionResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/DBIDSelection.java b/src/de/lmu/ifi/dbs/elki/result/DBIDSelection.java
index 97459a6a..d70089d7 100644
--- a/src/de/lmu/ifi/dbs/elki/result/DBIDSelection.java
+++ b/src/de/lmu/ifi/dbs/elki/result/DBIDSelection.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/DiscardResultHandler.java b/src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java
index 847e22fb..165fa070 100644
--- a/src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java
+++ b/src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/EvaluationResult.java b/src/de/lmu/ifi/dbs/elki/result/EvaluationResult.java
new file mode 100644
index 00000000..aaf01821
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/result/EvaluationResult.java
@@ -0,0 +1,305 @@
+package de.lmu.ifi.dbs.elki.result;
+
+/*
+ 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.ArrayList;
+import java.util.Iterator;
+
+import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable;
+import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
+
+/**
+ * Abstract evaluation result.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.composedOf EvaluationResult.MeasurementGroup
+ */
+public class EvaluationResult extends BasicResult implements TextWriteable, Iterable<EvaluationResult.MeasurementGroup> {
+ /**
+ * Measurements.
+ */
+ ArrayList<EvaluationResult.MeasurementGroup> groups = new ArrayList<>();
+
+ /**
+ * Header lines.
+ */
+ ArrayList<String> header = new ArrayList<>();
+
+ /**
+ * Constructor.
+ *
+ * @param name Evaluation name
+ * @param shortname Short name
+ */
+ public EvaluationResult(String name, String shortname) {
+ super(name, shortname);
+ }
+
+ /**
+ * Add a new measurement group.
+ *
+ * @param string Group name
+ * @return Measurement group.
+ */
+ public EvaluationResult.MeasurementGroup newGroup(String string) {
+ EvaluationResult.MeasurementGroup g = new MeasurementGroup(string);
+ groups.add(g);
+ return g;
+ }
+
+ @Override
+ public void writeToText(TextWriterStream out, String label) {
+ for(EvaluationResult.MeasurementGroup g : groups) {
+ out.commentPrintLn(g.getName());
+ out.flush();
+ for(Measurement m : g) {
+ out.inlinePrintNoQuotes(m.name);
+ out.inlinePrintNoQuotes(m.val);
+ out.flush();
+ }
+ }
+ }
+
+ /**
+ * Add a header line to this result.
+ *
+ * @param line Header line
+ */
+ public void addHeader(String line) {
+ header.add(line);
+ }
+
+ /**
+ * Get the header lines.
+ *
+ * @return Header lines
+ */
+ public Iterable<String> getHeaderLines() {
+ return header;
+ }
+
+ @Override
+ public Iterator<MeasurementGroup> iterator() {
+ return groups.iterator();
+ }
+
+ /**
+ * A group of evaluation measurements.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.composedOf EvaluationResult.Measurement
+ */
+ public static class MeasurementGroup implements Iterable<Measurement> {
+ /**
+ * Group name
+ */
+ private String groupname;
+
+ /**
+ * Measurements in this group.
+ */
+ private ArrayList<Measurement> measurements = new ArrayList<>();
+
+ /**
+ * Constructor.
+ *
+ * @param gname Group name
+ */
+ protected MeasurementGroup(String gname) {
+ this.groupname = gname;
+ }
+
+ /**
+ * Get the group name.
+ *
+ * @return Group name
+ */
+ public String getName() {
+ return groupname;
+ }
+
+ /**
+ * Add a single measurement.
+ *
+ * @param name Measurement name
+ * @param val Observed value
+ * @param min Minimum value
+ * @param max Maximum value
+ * @param lowerisbetter Flag
+ * @return {@code this} (Builder pattern)
+ */
+ public MeasurementGroup addMeasure(String name, double val, double min, double max, boolean lowerisbetter) {
+ measurements.add(new Measurement(name, val, min, max, lowerisbetter));
+ return this;
+ }
+
+ /**
+ * Add a single measurement.
+ *
+ * @param name Measurement name
+ * @param val Observed value
+ * @param min Minimum value
+ * @param exp Expected value
+ * @param lowerisbetter Flag
+ * @return {@code this} (Builder pattern)
+ */
+ public MeasurementGroup addMeasure(String name, double val, double min, double max, double exp, boolean lowerisbetter) {
+ measurements.add(new Measurement(name, val, min, max, exp, lowerisbetter));
+ return this;
+ }
+
+ @Override
+ public Iterator<Measurement> iterator() {
+ return measurements.iterator();
+ }
+ }
+
+ /**
+ * Class representing a single measurement.
+ *
+ * TODO: indicate whether high or low is better.
+ *
+ * @author Erich Schubert
+ */
+ public static class Measurement {
+ /**
+ * Measurement name.
+ */
+ String name;
+
+ /**
+ * Observed value, minimum, maximum, expected value.
+ */
+ double val;
+
+ /**
+ * Observed value, minimum, maximum, expected value.
+ */
+ double min;
+
+ /**
+ * Observed value, minimum, maximum, expected value.
+ */
+ double max;
+
+ /**
+ * Observed value, minimum, maximum, expected value.
+ */
+ double exp;
+
+ /**
+ * Indicates low values are better.
+ */
+ private boolean lowerisbetter;
+
+ /**
+ * Constructor.
+ *
+ * @param name Name
+ * @param val Value
+ * @param min Minimum
+ * @param max Maximum
+ * @param lowerisbetter Flag
+ */
+ protected Measurement(String name, double val, double min, double max, boolean lowerisbetter) {
+ this(name, val, min, max, Double.NaN, lowerisbetter);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param name Name
+ * @param val Value
+ * @param min Minimum
+ * @param max Maximum
+ * @param exp Expected value
+ * @param lowerisbetter Flag
+ */
+ protected Measurement(String name, double val, double min, double max, double exp, boolean lowerisbetter) {
+ super();
+ this.name = name;
+ this.val = val;
+ this.min = min;
+ this.max = max;
+ this.exp = exp;
+ this.lowerisbetter = lowerisbetter;
+ }
+
+ /**
+ * Get the name of this measurement.
+ *
+ * @return Measurement name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Get the observed value.
+ *
+ * @return observed value.
+ */
+ public double getVal() {
+ return val;
+ }
+
+ /**
+ * Get the minimum value.
+ *
+ * @return Minimum value.
+ */
+ public double getMin() {
+ return min;
+ }
+
+ /**
+ * Get the maximum value.
+ *
+ * @return Maximum value.
+ */
+ public double getMax() {
+ return max;
+ }
+
+ /**
+ * Get the expected value. May be {@code Double.NaN}.
+ *
+ * @return Expected value.
+ */
+ public double getExp() {
+ return exp;
+ }
+
+ /**
+ * Return {@code true} if low values are better.
+ *
+ * @return {@code true} when low values are better.
+ */
+ public boolean lowerIsBetter() {
+ return lowerisbetter;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/result/HierarchicalResult.java b/src/de/lmu/ifi/dbs/elki/result/HierarchicalResult.java
index 28841ddf..fce7b6d9 100644
--- a/src/de/lmu/ifi/dbs/elki/result/HierarchicalResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/HierarchicalResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/HistogramResult.java b/src/de/lmu/ifi/dbs/elki/result/HistogramResult.java
index 6e3fc745..936fa933 100644
--- a/src/de/lmu/ifi/dbs/elki/result/HistogramResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/HistogramResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/IterableResult.java b/src/de/lmu/ifi/dbs/elki/result/IterableResult.java
index e7a6f35c..d539a896 100644
--- a/src/de/lmu/ifi/dbs/elki/result/IterableResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/IterableResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/KMLOutputHandler.java b/src/de/lmu/ifi/dbs/elki/result/KMLOutputHandler.java
index 11391036..108d8c08 100644
--- a/src/de/lmu/ifi/dbs/elki/result/KMLOutputHandler.java
+++ b/src/de/lmu/ifi/dbs/elki/result/KMLOutputHandler.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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,7 +30,11 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -38,30 +42,40 @@ import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
+import de.lmu.ifi.dbs.elki.data.Cluster;
+import de.lmu.ifi.dbs.elki.data.Clustering;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.data.spatial.Polygon;
import de.lmu.ifi.dbs.elki.data.spatial.PolygonsObject;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
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.DoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.geometry.GrahamScanConvexHull2D;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy.Iter;
import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.ArrayListIter;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
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.Parameterizable;
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.Flag;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
+import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleObjPair;
import de.lmu.ifi.dbs.elki.utilities.scaling.outlier.OutlierLinearScaling;
import de.lmu.ifi.dbs.elki.utilities.scaling.outlier.OutlierScalingFunction;
import de.lmu.ifi.dbs.elki.workflow.OutputStep;
@@ -77,11 +91,18 @@ import de.lmu.ifi.dbs.elki.workflow.OutputStep;
* (SSTD), Minneapolis, MN, 2011
* </p>
*
+ * Note: This class - currently - is an ugly hack. This code needs to be
+ * modularized to make it more reusable, to support multiple results and
+ * different result types.
+ *
* @author Erich Schubert
*/
// TODO: make configurable color scheme
-@Reference(authors = "E. Achtert, A. Hettab, H.-P. Kriegel, E. Schubert, A. Zimek", booktitle = "Proc. 12th International Symposium on Spatial and Temporal Databases (SSTD), Minneapolis, MN, 2011", title = "Spatial Outlier Detection: Data, Algorithms, Visualizations")
-public class KMLOutputHandler implements ResultHandler, Parameterizable {
+@Reference(authors = "E. Achtert, A. Hettab, H.-P. Kriegel, E. Schubert, A. Zimek", //
+booktitle = "Proc. 12th International Symposium on Spatial and Temporal Databases (SSTD), Minneapolis, MN, 2011", //
+title = "Spatial Outlier Detection: Data, Algorithms, Visualizations", //
+url = "http://dx.doi.org/10.1007/978-3-642-22922-0_41")
+public class KMLOutputHandler implements ResultHandler {
/**
* Logger class to use.
*/
@@ -131,50 +152,70 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable {
@Override
public void processNewResult(HierarchicalResult baseResult, Result newResult) {
ArrayList<OutlierResult> ors = ResultUtil.filterResults(newResult, OutlierResult.class);
- if (ors.size() > 1) {
- throw new AbortException("More than one outlier result found. The KML writer only supports a single outlier result!");
+ ArrayList<Clustering<?>> crs = ResultUtil.filterResults(newResult, Clustering.class);
+ if(ors.size() + crs.size() > 1) {
+ throw new AbortException("More than one visualizable result found. The KML writer only supports a single result!");
+ }
+ for(OutlierResult outlierResult : ors) {
+ Database database = ResultUtil.findDatabase(baseResult);
+ try {
+ XMLOutputFactory factory = XMLOutputFactory.newInstance();
+ ZipOutputStream out = new ZipOutputStream(new FileOutputStream(filename));
+ out.putNextEntry(new ZipEntry("doc.kml"));
+ final XMLStreamWriter xmlw = factory.createXMLStreamWriter(out);
+ writeOutlierResult(xmlw, outlierResult, database);
+ xmlw.flush();
+ xmlw.close();
+ out.closeEntry();
+ out.flush();
+ out.close();
+ if(autoopen) {
+ Desktop.getDesktop().open(filename);
+ }
+ }
+ catch(XMLStreamException e) {
+ LOG.exception(e);
+ throw new AbortException("XML error in KML output.", e);
+ }
+ catch(IOException e) {
+ LOG.exception(e);
+ throw new AbortException("IO error in KML output.", e);
+ }
}
- if (ors.size() == 1) {
+ for(Clustering<?> clusteringResult : crs) {
Database database = ResultUtil.findDatabase(baseResult);
try {
XMLOutputFactory factory = XMLOutputFactory.newInstance();
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(filename));
out.putNextEntry(new ZipEntry("doc.kml"));
final XMLStreamWriter xmlw = factory.createXMLStreamWriter(out);
- writeKMLData(xmlw, ors.get(0), database);
+ @SuppressWarnings("unchecked")
+ Clustering<Model> cres = (Clustering<Model>) clusteringResult;
+ writeClusteringResult(xmlw, cres, database);
xmlw.flush();
xmlw.close();
out.closeEntry();
out.flush();
out.close();
- if (autoopen) {
+ if(autoopen) {
Desktop.getDesktop().open(filename);
}
- } catch (XMLStreamException e) {
+ }
+ catch(XMLStreamException e) {
LOG.exception(e);
throw new AbortException("XML error in KML output.", e);
- } catch (IOException e) {
+ }
+ catch(IOException e) {
LOG.exception(e);
throw new AbortException("IO error in KML output.", e);
}
}
}
- private void writeKMLData(XMLStreamWriter xmlw, OutlierResult outlierResult, Database database) throws XMLStreamException {
- Relation<Double> scores = outlierResult.getScores();
+ private void writeOutlierResult(XMLStreamWriter xmlw, OutlierResult outlierResult, Database database) throws XMLStreamException {
Relation<PolygonsObject> polys = database.getRelation(TypeUtil.POLYGON_TYPE);
Relation<String> labels = DatabaseUtil.guessObjectLabelRepresentation(database);
- Collection<Relation<?>> otherrel = new LinkedList<>(database.getRelations());
- otherrel.remove(scores);
- otherrel.remove(polys);
- otherrel.remove(labels);
- otherrel.remove(database.getRelation(TypeUtil.DBID));
-
- ArrayModifiableDBIDs ids = DBIDUtil.newArray(scores.getDBIDs());
-
- scaling.prepare(outlierResult);
-
xmlw.writeStartDocument();
xmlw.writeCharacters("\n");
xmlw.writeStartElement("kml");
@@ -194,7 +235,7 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable {
}
{
// TODO: generate styles from color scheme
- for (int i = 0; i < NUMSTYLES; i++) {
+ for(int i = 0; i < NUMSTYLES; i++) {
Color col = getColorForValue(i / (NUMSTYLES - 1.0));
xmlw.writeStartElement("Style");
xmlw.writeAttribute("id", "s" + i);
@@ -227,14 +268,26 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable {
writeNewlineOnDebug(xmlw);
}
}
- for (DBIDIter iter = outlierResult.getOrdering().iter(ids).iter(); iter.valid(); iter.advance()) {
- Double score = scores.get(iter);
+
+ DoubleRelation scores = outlierResult.getScores();
+ Collection<Relation<?>> otherrel = new LinkedList<>(database.getRelations());
+ otherrel.remove(scores);
+ otherrel.remove(polys);
+ otherrel.remove(labels);
+ otherrel.remove(database.getRelation(TypeUtil.DBID));
+
+ ArrayModifiableDBIDs ids = DBIDUtil.newArray(scores.getDBIDs());
+
+ scaling.prepare(outlierResult);
+
+ for(DBIDIter iter = outlierResult.getOrdering().iter(ids).iter(); iter.valid(); iter.advance()) {
+ double score = scores.doubleValue(iter);
PolygonsObject poly = polys.get(iter);
String label = labels.get(iter);
- if (score == null) {
+ if(Double.isNaN(score)) {
LOG.warning("No score for object " + DBIDUtil.toString(iter));
}
- if (poly == null) {
+ if(poly == null) {
LOG.warning("No polygon for object " + DBIDUtil.toString(iter) + " - skipping.");
continue;
}
@@ -256,7 +309,7 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable {
{
xmlw.writeStartElement("Polygon");
writeNewlineOnDebug(xmlw);
- if (compat) {
+ if(compat) {
xmlw.writeStartElement("altitudeMode");
xmlw.writeCharacters("relativeToGround");
xmlw.writeEndElement(); // close altitude mode
@@ -264,10 +317,11 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable {
}
// First polygon clockwise?
boolean first = true;
- for (Polygon p : poly.getPolygons()) {
- if (first) {
+ for(Polygon p : poly.getPolygons()) {
+ if(first) {
xmlw.writeStartElement("outerBoundaryIs");
- } else {
+ }
+ else {
xmlw.writeStartElement("innerBoundaryIs");
}
xmlw.writeStartElement("LinearRing");
@@ -276,19 +330,20 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable {
// Reverse anti-clockwise polygons.
boolean reverse = (p.testClockwise() >= 0);
ArrayListIter<Vector> it = p.iter();
- if (reverse) {
+ if(reverse) {
it.seek(p.size() - 1);
}
- while (it.valid()) {
+ while(it.valid()) {
Vector v = it.get();
xmlw.writeCharacters(FormatUtil.format(v.getArrayRef(), ","));
- if (compat && (v.getDimensionality() == 2)) {
+ if(compat && (v.getDimensionality() == 2)) {
xmlw.writeCharacters(",500");
}
xmlw.writeCharacters(" ");
- if (!reverse) {
+ if(!reverse) {
it.advance();
- } else {
+ }
+ else {
it.retract();
}
}
@@ -308,6 +363,187 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable {
xmlw.writeEndDocument();
}
+ private void writeClusteringResult(XMLStreamWriter xmlw, Clustering<Model> clustering, Database database) throws XMLStreamException {
+ xmlw.writeStartDocument();
+ xmlw.writeCharacters("\n");
+ xmlw.writeStartElement("kml");
+ xmlw.writeDefaultNamespace("http://earth.google.com/kml/2.2");
+ xmlw.writeStartElement("Document");
+ {
+ // TODO: can we automatically generate more helpful data here?
+ xmlw.writeStartElement("name");
+ xmlw.writeCharacters("ELKI KML output for " + clustering.getLongName());
+ xmlw.writeEndElement(); // name
+ writeNewlineOnDebug(xmlw);
+ // TODO: e.g. list the settings in the description?
+ xmlw.writeStartElement("description");
+ xmlw.writeCharacters("ELKI KML output for " + clustering.getLongName());
+ xmlw.writeEndElement(); // description
+ writeNewlineOnDebug(xmlw);
+ }
+
+ List<Cluster<Model>> clusters = clustering.getAllClusters();
+ Relation<NumberVector> coords = database.getRelation(TypeUtil.NUMBER_VECTOR_FIELD_2D);
+ List<Cluster<Model>> topc = clustering.getToplevelClusters();
+ Hierarchy<Cluster<Model>> hier = clustering.getClusterHierarchy();
+ Map<Object, DoubleObjPair<Polygon>> hullmap = new HashMap<>();
+ for(Cluster<Model> clu : topc) {
+ buildHullsRecursively(clu, hier, hullmap, coords);
+ }
+
+ int numc = clusters.size();
+ {
+ final double projarea = 90. * 90.; // 1/8 of earth
+ // TODO: generate styles from color scheme
+ Iterator<Cluster<Model>> it = clusters.iterator();
+ for(int i = 0; it.hasNext(); i++) {
+ Cluster<Model> clus = it.next();
+ Color col = Color.getHSBColor(i * 51.f / (float) numc, 1.f, .5f);
+ DoubleObjPair<Polygon> pair = hullmap.get(clus);
+ // Approximate area (using bounding box)
+ double hullarea = SpatialUtil.volume(pair.second);
+ final double relativeArea = 1. - (hullarea / projarea);
+ // final double relativeSize = pair.first / coords.size();
+ final double opacity = 1. * Math.sqrt(relativeArea);
+ xmlw.writeStartElement("Style");
+ xmlw.writeAttribute("id", "s" + i);
+ writeNewlineOnDebug(xmlw);
+ {
+ xmlw.writeStartElement("LineStyle");
+ xmlw.writeStartElement("width");
+ xmlw.writeCharacters("0");
+ xmlw.writeEndElement(); // width
+
+ xmlw.writeEndElement(); // LineStyle
+ }
+ writeNewlineOnDebug(xmlw);
+ {
+ xmlw.writeStartElement("PolyStyle");
+ xmlw.writeStartElement("color");
+ // KML uses AABBGGRR format!
+ xmlw.writeCharacters(String.format("%02x%02x%02x%02x", (int) (255 * Math.min(1., opacity)), col.getBlue(), col.getGreen(), col.getRed()));
+ xmlw.writeEndElement(); // color
+ // out.writeStartElement("fill");
+ // out.writeCharacters("1"); // Default 1
+ // out.writeEndElement(); // fill
+ xmlw.writeStartElement("outline");
+ xmlw.writeCharacters("0");
+ xmlw.writeEndElement(); // outline
+ xmlw.writeEndElement(); // PolyStyle
+ }
+ writeNewlineOnDebug(xmlw);
+ xmlw.writeEndElement(); // Style
+ writeNewlineOnDebug(xmlw);
+ }
+ }
+
+ Cluster<?> ignore = topc.size() == 1 ? topc.get(0) : null;
+ Iterator<Cluster<Model>> it = clusters.iterator();
+ for(int cnum = 0; it.hasNext(); cnum++) {
+ Cluster<?> c = it.next();
+ // Ignore sole toplevel cluster (usually: noise)
+ if(c == ignore) {
+ continue;
+ }
+ Polygon p = hullmap.get(c).second;
+ xmlw.writeStartElement("Placemark");
+ {
+ xmlw.writeStartElement("name");
+ xmlw.writeCharacters(c.getNameAutomatic());
+ xmlw.writeEndElement(); // name
+ xmlw.writeStartElement("description");
+ xmlw.writeCData(makeDescription(c).toString());
+ xmlw.writeEndElement(); // description
+ xmlw.writeStartElement("styleUrl");
+ xmlw.writeCharacters("#s" + cnum);
+ xmlw.writeEndElement(); // styleUrl
+ }
+ {
+ xmlw.writeStartElement("Polygon");
+ writeNewlineOnDebug(xmlw);
+ if(compat) {
+ xmlw.writeStartElement("altitudeMode");
+ xmlw.writeCharacters("relativeToGround");
+ xmlw.writeEndElement(); // close altitude mode
+ writeNewlineOnDebug(xmlw);
+ }
+ {
+ xmlw.writeStartElement("outerBoundaryIs");
+ xmlw.writeStartElement("LinearRing");
+ xmlw.writeStartElement("coordinates");
+
+ // Reverse anti-clockwise polygons.
+ boolean reverse = (p.testClockwise() >= 0);
+ ArrayListIter<Vector> itp = p.iter();
+ if(reverse) {
+ itp.seek(p.size() - 1);
+ }
+ while(itp.valid()) {
+ Vector v = itp.get();
+ xmlw.writeCharacters(FormatUtil.format(v.getArrayRef(), ","));
+ if(compat && (v.getDimensionality() == 2)) {
+ xmlw.writeCharacters(",500");
+ }
+ xmlw.writeCharacters(" ");
+ if(!reverse) {
+ itp.advance();
+ }
+ else {
+ itp.retract();
+ }
+ }
+ xmlw.writeEndElement(); // close coordinates
+ xmlw.writeEndElement(); // close LinearRing
+ xmlw.writeEndElement(); // close *BoundaryIs
+ }
+ writeNewlineOnDebug(xmlw);
+ xmlw.writeEndElement(); // Polygon
+ }
+ xmlw.writeEndElement(); // Placemark
+ writeNewlineOnDebug(xmlw);
+ }
+ xmlw.writeEndElement(); // Document
+ xmlw.writeEndElement(); // kml
+ xmlw.writeEndDocument();
+ }
+
+ /**
+ * Recursively step through the clusters to build the hulls.
+ *
+ * @param clu Current cluster
+ * @param hier Clustering hierarchy
+ * @param hulls Hull map
+ */
+ private DoubleObjPair<Polygon> buildHullsRecursively(Cluster<Model> clu, Hierarchy<Cluster<Model>> hier, Map<Object, DoubleObjPair<Polygon>> hulls, Relation<? extends NumberVector> coords) {
+ final DBIDs ids = clu.getIDs();
+
+ GrahamScanConvexHull2D hull = new GrahamScanConvexHull2D();
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ hull.add(coords.get(iter).getColumnVector());
+ }
+ double weight = ids.size();
+ if(hier != null && hulls != null) {
+ final int numc = hier.numChildren(clu);
+ if(numc > 0) {
+ for(Iter<Cluster<Model>> iter = hier.iterChildren(clu); iter.valid(); iter.advance()) {
+ final Cluster<Model> iclu = iter.get();
+ DoubleObjPair<Polygon> poly = hulls.get(iclu);
+ if(poly == null) {
+ poly = buildHullsRecursively(iclu, hier, hulls, coords);
+ }
+ // Add inner convex hull to outer convex hull.
+ for(ArrayListIter<Vector> vi = poly.second.iter(); vi.valid(); vi.advance()) {
+ hull.add(vi.get());
+ }
+ weight += poly.first / numc;
+ }
+ }
+ }
+ DoubleObjPair<Polygon> pair = new DoubleObjPair<>(weight, hull.getHull());
+ hulls.put(clu, pair);
+ return pair;
+ }
+
/**
* Make an HTML description.
*
@@ -317,15 +553,15 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable {
*/
private StringBuilder makeDescription(Collection<Relation<?>> relations, DBIDRef id) {
StringBuilder buf = new StringBuilder();
- for (Relation<?> rel : relations) {
+ for(Relation<?> rel : relations) {
Object o = rel.get(id);
- if (o == null) {
+ if(o == null) {
continue;
}
String s = o.toString();
// FIXME: strip html characters
- if (s != null) {
- if (buf.length() > 0) {
+ if(s != null) {
+ if(buf.length() > 0) {
buf.append("<br />");
}
buf.append(s);
@@ -335,13 +571,29 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable {
}
/**
+ * Make an HTML description.
+ *
+ * @param c Cluster
+ * @return Buffer
+ */
+ private StringBuilder makeDescription(Cluster<?> c) {
+ StringBuilder buf = new StringBuilder();
+ buf.append("<div>");
+ buf.append(c.getNameAutomatic());
+ buf.append("<br />");
+ buf.append("Size: " + c.size());
+ buf.append("</div>");
+ return buf;
+ }
+
+ /**
* Print a newline when debugging.
*
* @param out Output XML stream
* @throws XMLStreamException
*/
private void writeNewlineOnDebug(XMLStreamWriter out) throws XMLStreamException {
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
out.writeCharacters("\n");
}
}
@@ -358,12 +610,12 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable {
// Colors at these positions
Color[] cols = new Color[] { new Color(0.0f, 0.0f, 0.0f, 0.6f), new Color(0.0f, 0.0f, 1.0f, 0.8f), new Color(1.0f, 0.0f, 0.0f, 0.9f), new Color(1.0f, 1.0f, 0.0f, 1.0f) };
assert (pos.length == cols.length);
- if (val < pos[0]) {
+ if(val < pos[0]) {
val = pos[0];
}
// Linear interpolation:
- for (int i = 1; i < pos.length; i++) {
- if (val <= pos[i]) {
+ for(int i = 1; i < pos.length; i++) {
+ if(val <= pos[i]) {
Color prev = cols[i - 1];
Color next = cols[i];
final double mix = (val - pos[i - 1]) / (pos[i] - pos[i - 1]);
@@ -438,22 +690,22 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable {
super.makeOptions(config);
FileParameter outputP = new FileParameter(OutputStep.Parameterizer.OUTPUT_ID, FileParameter.FileType.OUTPUT_FILE);
outputP.setShortDescription("Filename the KMZ file (compressed KML) is written to.");
- if (config.grab(outputP)) {
+ if(config.grab(outputP)) {
filename = outputP.getValue();
}
ObjectParameter<OutlierScalingFunction> scalingP = new ObjectParameter<>(SCALING_ID, OutlierScalingFunction.class, OutlierLinearScaling.class);
- if (config.grab(scalingP)) {
+ if(config.grab(scalingP)) {
scaling = scalingP.instantiateClass(config);
}
Flag compatF = new Flag(COMPAT_ID);
- if (config.grab(compatF)) {
+ if(config.grab(compatF)) {
compat = compatF.getValue();
}
Flag autoopenF = new Flag(AUTOOPEN_ID);
- if (config.grab(autoopenF)) {
+ if(config.grab(autoopenF)) {
autoopen = autoopenF.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/result/KNNDistanceOrderResult.java b/src/de/lmu/ifi/dbs/elki/result/KNNDistanceOrderResult.java
deleted file mode 100644
index bbe21b0a..00000000
--- a/src/de/lmu/ifi/dbs/elki/result/KNNDistanceOrderResult.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package de.lmu.ifi.dbs.elki.result;
-
-/*
- 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.Iterator;
-import java.util.List;
-
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-
-/**
- * Wraps a list containing the knn distances.
- *
- * @author Arthur Zimek
- * @param <D> the type of Distance used by this Result
- *
- */
-public class KNNDistanceOrderResult<D extends Distance<D>> extends BasicResult implements IterableResult<D> {
- /**
- * Store the kNN Distances
- */
- private final List<D> knnDistances;
-
- /**
- * Construct result
- *
- * @param name The long name (for pretty printing)
- * @param shortname the short name (for filenames etc.)
- * @param knnDistances distance list to wrap.
- */
- public KNNDistanceOrderResult(String name, String shortname, final List<D> knnDistances) {
- super(name, shortname);
- this.knnDistances = knnDistances;
- }
-
- /**
- * Return an iterator.
- */
- @Override
- public Iterator<D> iterator() {
- return knnDistances.iterator();
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/result/LogResultStructureResultHandler.java b/src/de/lmu/ifi/dbs/elki/result/LogResultStructureResultHandler.java
index 4224ae0a..92ccab42 100644
--- a/src/de/lmu/ifi/dbs/elki/result/LogResultStructureResultHandler.java
+++ b/src/de/lmu/ifi/dbs/elki/result/LogResultStructureResultHandler.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/OrderingFromDataStore.java b/src/de/lmu/ifi/dbs/elki/result/OrderingFromDataStore.java
index 74eb5323..076ecdd6 100644
--- a/src/de/lmu/ifi/dbs/elki/result/OrderingFromDataStore.java
+++ b/src/de/lmu/ifi/dbs/elki/result/OrderingFromDataStore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/OrderingResult.java b/src/de/lmu/ifi/dbs/elki/result/OrderingResult.java
index b3261e61..8e8f0c61 100644
--- a/src/de/lmu/ifi/dbs/elki/result/OrderingResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/OrderingResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/PixmapResult.java b/src/de/lmu/ifi/dbs/elki/result/PixmapResult.java
index f6b4512b..5bbdd72f 100644
--- a/src/de/lmu/ifi/dbs/elki/result/PixmapResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/PixmapResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/RangeSelection.java b/src/de/lmu/ifi/dbs/elki/result/RangeSelection.java
index b4cc092f..051788a7 100644
--- a/src/de/lmu/ifi/dbs/elki/result/RangeSelection.java
+++ b/src/de/lmu/ifi/dbs/elki/result/RangeSelection.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/ReferencePointsResult.java b/src/de/lmu/ifi/dbs/elki/result/ReferencePointsResult.java
index 92f59101..aade3c02 100644
--- a/src/de/lmu/ifi/dbs/elki/result/ReferencePointsResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/ReferencePointsResult.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/Result.java b/src/de/lmu/ifi/dbs/elki/result/Result.java
index 99f68402..2d7cec6a 100644
--- a/src/de/lmu/ifi/dbs/elki/result/Result.java
+++ b/src/de/lmu/ifi/dbs/elki/result/Result.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/ResultAdapter.java b/src/de/lmu/ifi/dbs/elki/result/ResultAdapter.java
index fa02b57b..238338a4 100644
--- a/src/de/lmu/ifi/dbs/elki/result/ResultAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/result/ResultAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/ResultHandler.java b/src/de/lmu/ifi/dbs/elki/result/ResultHandler.java
index 56e25d27..2d96f4b6 100644
--- a/src/de/lmu/ifi/dbs/elki/result/ResultHandler.java
+++ b/src/de/lmu/ifi/dbs/elki/result/ResultHandler.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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,6 @@ package de.lmu.ifi.dbs.elki.result;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
-
/**
* Interface for any class that can handle results
*
@@ -33,6 +31,6 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
* @apiviz.landmark
* @apiviz.uses Result oneway - - processes
*/
-public interface ResultHandler extends Parameterizable, ResultProcessor {
+public interface ResultHandler extends ResultProcessor {
// Empty - moved to ResultProcessor, this interface merely serves UI purposes.
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java b/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java
index 52b63d3b..6b844a39 100644
--- a/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java
+++ b/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/ResultListener.java b/src/de/lmu/ifi/dbs/elki/result/ResultListener.java
index 899aa008..dc007141 100644
--- a/src/de/lmu/ifi/dbs/elki/result/ResultListener.java
+++ b/src/de/lmu/ifi/dbs/elki/result/ResultListener.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/ResultProcessor.java b/src/de/lmu/ifi/dbs/elki/result/ResultProcessor.java
index 88eb3607..df73b4c1 100644
--- a/src/de/lmu/ifi/dbs/elki/result/ResultProcessor.java
+++ b/src/de/lmu/ifi/dbs/elki/result/ResultProcessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/ResultUtil.java b/src/de/lmu/ifi/dbs/elki/result/ResultUtil.java
index e0e59482..9721245f 100644
--- a/src/de/lmu/ifi/dbs/elki/result/ResultUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/result/ResultUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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
@@ -252,7 +252,7 @@ public class ResultUtil {
* @param rel Relation
* @return associated scales result
*/
- public static ScalesResult getScalesResult(final Relation<? extends NumberVector<?>> rel) {
+ public static ScalesResult getScalesResult(final Relation<? extends NumberVector> rel) {
Collection<ScalesResult> scas = ResultUtil.filterResults(rel, ScalesResult.class);
if (scas.size() == 0) {
final ScalesResult newsca = new ScalesResult(rel);
diff --git a/src/de/lmu/ifi/dbs/elki/result/ResultWriter.java b/src/de/lmu/ifi/dbs/elki/result/ResultWriter.java
index f3b39580..4ffc39c6 100644
--- a/src/de/lmu/ifi/dbs/elki/result/ResultWriter.java
+++ b/src/de/lmu/ifi/dbs/elki/result/ResultWriter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/SamplingResult.java b/src/de/lmu/ifi/dbs/elki/result/SamplingResult.java
index 17471b9a..1d8b71da 100644
--- a/src/de/lmu/ifi/dbs/elki/result/SamplingResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/SamplingResult.java
@@ -7,7 +7,7 @@ import de.lmu.ifi.dbs.elki.database.relation.Relation;
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/result/ScalesResult.java b/src/de/lmu/ifi/dbs/elki/result/ScalesResult.java
index 8f9653d8..b8c45bfc 100644
--- a/src/de/lmu/ifi/dbs/elki/result/ScalesResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/ScalesResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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
@@ -46,7 +46,7 @@ public class ScalesResult extends BasicResult {
*
* @param relation Relation to use
*/
- public ScalesResult(Relation<? extends NumberVector<?>> relation) {
+ public ScalesResult(Relation<? extends NumberVector> relation) {
this(Scales.calcScales(relation));
}
diff --git a/src/de/lmu/ifi/dbs/elki/result/SelectionResult.java b/src/de/lmu/ifi/dbs/elki/result/SelectionResult.java
index fda68c68..7b9364e6 100644
--- a/src/de/lmu/ifi/dbs/elki/result/SelectionResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/SelectionResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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/result/SettingsResult.java b/src/de/lmu/ifi/dbs/elki/result/SettingsResult.java
index ea6664e8..f389236b 100644
--- a/src/de/lmu/ifi/dbs/elki/result/SettingsResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/SettingsResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result;
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,7 @@ package de.lmu.ifi.dbs.elki.result;
import java.util.Collection;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackedParameter;
/**
* Result that keeps track of settings that were used in generating this
@@ -38,14 +37,14 @@ public class SettingsResult extends BasicResult {
/**
* Settings storage.
*/
- Collection<Pair<Object, Parameter<?>>> settings;
+ Collection<TrackedParameter> settings;
/**
* Constructor.
*
* @param settings Settings to store
*/
- public SettingsResult(Collection<Pair<Object, Parameter<?>>> settings) {
+ public SettingsResult(Collection<TrackedParameter> settings) {
super("Settings", "settings");
this.settings = settings;
}
@@ -55,7 +54,7 @@ public class SettingsResult extends BasicResult {
*
* @return the settings
*/
- public Collection<Pair<Object, Parameter<?>>> getSettings() {
+ public Collection<TrackedParameter> getSettings() {
return settings;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java b/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java
deleted file mode 100644
index bd500dfa..00000000
--- a/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java
+++ /dev/null
@@ -1,384 +0,0 @@
-package de.lmu.ifi.dbs.elki.result.optics;
-
-/*
- 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.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-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.Database;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStore;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
-import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
-import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
-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.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.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.result.BasicResult;
-import de.lmu.ifi.dbs.elki.result.IterableResult;
-import de.lmu.ifi.dbs.elki.result.OrderingResult;
-import de.lmu.ifi.dbs.elki.result.ResultAdapter;
-import de.lmu.ifi.dbs.elki.result.ResultHierarchy;
-
-/**
- * Class to store the result of an ordering clustering algorithm such as OPTICS.
- *
- * @author Erich Schubert
- *
- * @apiviz.landmark
- *
- * @apiviz.has ClusterOrderEntry oneway - - contains
- * @apiviz.composedOf ClusterOrderResult.ClusterOrderAdapter
- * @apiviz.composedOf ClusterOrderResult.ReachabilityDistanceAdapter
- * @apiviz.composedOf ClusterOrderResult.PredecessorAdapter
- *
- * @param <D> distance type.
- */
-public class ClusterOrderResult<D extends Distance<D>> extends BasicResult implements IterableResult<ClusterOrderEntry<D>> {
- /**
- * Cluster order storage
- */
- private ArrayList<ClusterOrderEntry<D>> clusterOrder;
-
- /**
- * Map of object IDs to their cluster order entry
- */
- private WritableDataStore<ClusterOrderEntry<D>> map;
-
- /**
- * The DBIDs we are defined for
- */
- ModifiableDBIDs dbids;
-
- /**
- * Constructor
- *
- * @param name The long name (for pretty printing)
- * @param shortname the short name (for filenames etc.)
- */
- public ClusterOrderResult(String name, String shortname) {
- super(name, shortname);
- clusterOrder = new ArrayList<>();
- dbids = DBIDUtil.newHashSet();
- map = DataStoreUtil.makeStorage(dbids, DataStoreFactory.HINT_DB, ClusterOrderEntry.class);
-
- addChildResult(new ClusterOrderAdapter(clusterOrder));
- addChildResult(new ReachabilityDistanceAdapter(map, dbids));
- addChildResult(new PredecessorAdapter(map, dbids));
- }
-
- /**
- * Retrieve the complete cluster order.
- *
- * @return cluster order
- */
- public List<ClusterOrderEntry<D>> getClusterOrder() {
- return clusterOrder;
- }
-
- /**
- * The cluster order is iterable
- */
- @Override
- public Iterator<ClusterOrderEntry<D>> iterator() {
- return clusterOrder.iterator();
- }
-
- /**
- * Add an object to the cluster order.
- *
- * @param id Object ID
- * @param predecessor Predecessor ID
- * @param reachability Reachability distance
- */
- public void add(DBID id, DBID predecessor, D reachability) {
- add(new GenericClusterOrderEntry<>(id, predecessor, reachability));
- dbids.add(id);
- }
-
- /**
- * Add an object to the cluster order.
- *
- * @param ce Entry
- */
- public void add(ClusterOrderEntry<D> ce) {
- clusterOrder.add(ce);
- map.put(ce.getID(), ce);
- dbids.add(ce.getID());
- }
-
- /**
- * Get the distance class
- *
- * @return distance class. Can be {@code null} for an all-undefined result!
- */
- public Class<?> getDistanceClass() {
- for(ClusterOrderEntry<D> ce : clusterOrder) {
- D dist = ce.getReachability();
- if(dist != null) {
- return dist.getClass();
- }
- }
- return null;
- }
-
- /**
- * Ordering part of the result.
- *
- * @author Erich Schubert
- */
- class ClusterOrderAdapter implements OrderingResult, ResultAdapter {
- /**
- * Access reference.
- */
- private ArrayList<ClusterOrderEntry<D>> clusterOrder;
-
- /**
- * Constructor.
- *
- * @param clusterOrder order to return
- */
- public ClusterOrderAdapter(final ArrayList<ClusterOrderEntry<D>> clusterOrder) {
- super();
- this.clusterOrder = clusterOrder;
- }
-
- @Override
- public DBIDs getDBIDs() {
- return dbids;
- }
-
- /**
- * Use the cluster order to sort the given collection ids.
- *
- * Implementation of the {@link OrderingResult} interface.
- */
- @Override
- public ArrayModifiableDBIDs iter(DBIDs ids) {
- ArrayModifiableDBIDs res = DBIDUtil.newArray(ids.size());
- for(ClusterOrderEntry<D> e : clusterOrder) {
- if(ids.contains(e.getID())) {
- res.add(e.getID());
- }
- }
- return res;
- }
-
- @Override
- public String getLongName() {
- return "Derived Object Order";
- }
-
- @Override
- public String getShortName() {
- return "clusterobjectorder";
- }
- }
-
- /**
- * Result containing the reachability distances.
- *
- * @author Erich Schubert
- */
- class ReachabilityDistanceAdapter implements Relation<D>, ResultAdapter {
- /**
- * Access reference.
- */
- private DataStore<ClusterOrderEntry<D>> map;
-
- /**
- * DBIDs
- */
- private DBIDs dbids;
-
- /**
- * Constructor.
- *
- * @param map Map that stores the results.
- * @param dbids DBIDs we are defined for.
- */
- public ReachabilityDistanceAdapter(DataStore<ClusterOrderEntry<D>> map, DBIDs dbids) {
- super();
- this.map = map;
- this.dbids = dbids;
- }
-
- @Override
- public D get(DBIDRef objID) {
- return map.get(objID).getReachability();
- }
-
- @Override
- public String getLongName() {
- return "Reachability";
- }
-
- @Override
- public String getShortName() {
- return "reachability";
- }
-
- @Override
- public DBIDs getDBIDs() {
- return DBIDUtil.makeUnmodifiable(dbids);
- }
-
- @Override
- public DBIDIter iterDBIDs() {
- return dbids.iter();
- }
-
- @Override
- public int size() {
- return dbids.size();
- }
-
- @Override
- public Database getDatabase() {
- return null; // FIXME
- }
-
- @Override
- public void set(DBIDRef id, D val) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void delete(DBIDRef id) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public SimpleTypeInformation<D> getDataTypeInformation() {
- return new SimpleTypeInformation<>(Distance.class);
- }
-
- @Override
- public ResultHierarchy getHierarchy() {
- return ClusterOrderResult.this.getHierarchy();
- }
-
- @Override
- public void setHierarchy(ResultHierarchy hierarchy) {
- ClusterOrderResult.this.setHierarchy(hierarchy);
- }
- }
-
- /**
- * Result containing the predecessor ID.
- *
- * @author Erich Schubert
- */
- class PredecessorAdapter implements Relation<DBID>, ResultAdapter {
- /**
- * Access reference.
- */
- private DataStore<ClusterOrderEntry<D>> map;
-
- /**
- * Database IDs
- */
- private DBIDs dbids;
-
- /**
- * Constructor.
- *
- * @param map Map that stores the results.
- * @param dbids DBIDs we are defined for
- */
- public PredecessorAdapter(DataStore<ClusterOrderEntry<D>> map, DBIDs dbids) {
- super();
- this.map = map;
- this.dbids = dbids;
- }
-
- @Override
- public DBID get(DBIDRef objID) {
- return map.get(objID).getPredecessorID();
- }
-
- @Override
- public String getLongName() {
- return "Predecessor";
- }
-
- @Override
- public String getShortName() {
- return "predecessor";
- }
-
- @Override
- public DBIDs getDBIDs() {
- return DBIDUtil.makeUnmodifiable(dbids);
- }
-
- @Override
- public DBIDIter iterDBIDs() {
- return dbids.iter();
- }
-
- @Override
- public int size() {
- return dbids.size();
- }
-
- @Override
- public Database getDatabase() {
- return null; // FIXME
- }
-
- @Override
- public void set(DBIDRef id, DBID val) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void delete(DBIDRef id) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public SimpleTypeInformation<DBID> getDataTypeInformation() {
- return TypeUtil.DBID;
- }
-
- @Override
- public ResultHierarchy getHierarchy() {
- return ClusterOrderResult.this.getHierarchy();
- }
-
- @Override
- public void setHierarchy(ResultHierarchy hierarchy) {
- ClusterOrderResult.this.setHierarchy(hierarchy);
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/result/optics/GenericClusterOrderEntry.java b/src/de/lmu/ifi/dbs/elki/result/optics/GenericClusterOrderEntry.java
deleted file mode 100644
index 7af8a3ec..00000000
--- a/src/de/lmu/ifi/dbs/elki/result/optics/GenericClusterOrderEntry.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package de.lmu.ifi.dbs.elki.result.optics;
-
-/*
- 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.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-
-/**
- * Provides an entry in a cluster order.
- *
- * @author Elke Achtert
- * @param <D> the type of Distance used by the ClusterOrderEntry
- */
-public class GenericClusterOrderEntry<D extends Distance<D>> implements Comparable<ClusterOrderEntry<D>>, ClusterOrderEntry<D> {
- /**
- * The id of the entry.
- */
- private DBID objectID;
-
- /**
- * The id of the entry's predecessor.
- */
- private DBID predecessorID;
-
- /**
- * The reachability of the entry.
- */
- private D reachability;
-
- /**
- * Creates a new entry in a cluster order with the specified parameters.
- *
- * @param objectID the id of the entry
- * @param predecessorID the id of the entry's predecessor
- * @param reachability the reachability of the entry
- */
- public GenericClusterOrderEntry(DBID objectID, DBID predecessorID, D reachability) {
- this.objectID = objectID;
- this.predecessorID = predecessorID;
- this.reachability = reachability;
- }
-
- /**
- * Indicates whether some other object is "equal to" this one.
- *
- * NOTE: for the use in an UpdatableHeap, only the ID is compared!
- *
- * @param o the reference object with which to compare.
- * @return <code>true</code> if this object has the same attribute values as
- * the o argument; <code>false</code> otherwise.
- */
- @Override
- public boolean equals(Object o) {
- if(this == o) {
- return true;
- }
- if(!(o instanceof ClusterOrderEntry)) {
- return false;
- }
-
- final ClusterOrderEntry<?> that = (ClusterOrderEntry<?>) o;
- // Compare by ID only, for UpdatableHeap!
- return DBIDUtil.equal(objectID, that.getID());
- }
-
- /**
- * Returns a hash code value for the object.
- *
- * @return the object id if this entry
- */
- @Override
- public int hashCode() {
- return objectID.hashCode();
- }
-
- /**
- * Returns a string representation of the object.
- *
- * @return a string representation of the object.
- */
- @Override
- public String toString() {
- return objectID + "(" + predecessorID + "," + reachability + ")";
- }
-
- /**
- * Returns the object id of this entry.
- *
- * @return the object id of this entry
- */
- @Override
- public DBID getID() {
- return objectID;
- }
-
- /**
- * Returns the id of the predecessor of this entry if this entry has a
- * predecessor, null otherwise.
- *
- * @return the id of the predecessor of this entry
- */
- @Override
- public DBID getPredecessorID() {
- return predecessorID;
- }
-
- /**
- * Returns the reachability distance of this entry
- *
- * @return the reachability distance of this entry
- */
- @Override
- public D getReachability() {
- return reachability;
- }
-
- @Override
- public int compareTo(ClusterOrderEntry<D> o) {
- int delta = this.getReachability().compareTo(o.getReachability());
- if(delta != 0) {
- return delta;
- }
- return -getID().compareTo(o.getID());
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/BasicOutlierScoreMeta.java b/src/de/lmu/ifi/dbs/elki/result/outlier/BasicOutlierScoreMeta.java
index 4dc64b2c..0a87fd98 100644
--- a/src/de/lmu/ifi/dbs/elki/result/outlier/BasicOutlierScoreMeta.java
+++ b/src/de/lmu/ifi/dbs/elki/result/outlier/BasicOutlierScoreMeta.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier;
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/result/outlier/InvertedOutlierScoreMeta.java b/src/de/lmu/ifi/dbs/elki/result/outlier/InvertedOutlierScoreMeta.java
index d4ea456a..a3b40682 100644
--- a/src/de/lmu/ifi/dbs/elki/result/outlier/InvertedOutlierScoreMeta.java
+++ b/src/de/lmu/ifi/dbs/elki/result/outlier/InvertedOutlierScoreMeta.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier;
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/result/outlier/OrderingFromRelation.java b/src/de/lmu/ifi/dbs/elki/result/outlier/OrderingFromRelation.java
index 2950a2f8..013be8f9 100644
--- a/src/de/lmu/ifi/dbs/elki/result/outlier/OrderingFromRelation.java
+++ b/src/de/lmu/ifi/dbs/elki/result/outlier/OrderingFromRelation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier;
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.result.outlier;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.Comparator;
-
import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
-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.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.result.OrderingResult;
/**
@@ -37,38 +35,38 @@ import de.lmu.ifi.dbs.elki.result.OrderingResult;
*
* @author Erich Schubert
*
- * @apiviz.uses Relation
+ * @apiviz.uses DoubleRelation
*/
public class OrderingFromRelation implements OrderingResult {
/**
* Outlier scores.
*/
- protected Relation<Double> scores;
+ protected DoubleRelation scores;
/**
* Factor for ascending (+1) and descending (-1) ordering.
*/
- protected int ascending = +1;
-
+ protected boolean ascending = false;
+
/**
* Constructor for outlier orderings
*
* @param scores outlier score result
* @param ascending Ascending when {@code true}, descending otherwise
*/
- public OrderingFromRelation(Relation<Double> scores, boolean ascending) {
+ public OrderingFromRelation(DoubleRelation scores, boolean ascending) {
super();
this.scores = scores;
- this.ascending = ascending ? +1 : -1;
+ this.ascending = ascending;
}
-
+
/**
* Ascending constructor.
*
* @param scores
*/
- public OrderingFromRelation(Relation<Double> scores) {
- this(scores, true);
+ public OrderingFromRelation(DoubleRelation scores) {
+ this(scores, false);
}
@Override
@@ -79,35 +77,19 @@ public class OrderingFromRelation implements OrderingResult {
@Override
public ArrayModifiableDBIDs iter(DBIDs ids) {
ArrayModifiableDBIDs sorted = DBIDUtil.newArray(ids);
- sorted.sort(new ImpliedComparator());
+ sorted.sort(ascending ? //
+ new RelationUtil.AscendingByDoubleRelation(scores) //
+ : new RelationUtil.DescendingByDoubleRelation(scores));
return sorted;
}
@Override
public String getLongName() {
- return scores.getLongName()+" Order";
+ return scores.getLongName() + " Order";
}
@Override
public String getShortName() {
- return scores.getShortName()+"_order";
- }
-
- /**
- * Internal comparator, accessing the map to sort objects
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- protected final class ImpliedComparator implements Comparator<DBIDRef> {
- @Override
- public int compare(DBIDRef id1, DBIDRef id2) {
- Double k1 = scores.get(id1);
- Double k2 = scores.get(id2);
- assert (k1 != null);
- assert (k2 != null);
- return ascending * k2.compareTo(k1);
- }
+ return scores.getShortName() + "_order";
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java b/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java
index 13d5c1a0..3289723f 100644
--- a/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier;
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.result.outlier;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.result.BasicResult;
import de.lmu.ifi.dbs.elki.result.OrderingResult;
@@ -35,7 +35,7 @@ import de.lmu.ifi.dbs.elki.result.OrderingResult;
*
* @apiviz.landmark
* @apiviz.composedOf OutlierScoreMeta
- * @apiviz.composedOf Relation oneway - - contains
+ * @apiviz.composedOf DoubleRelation oneway - - contains
* @apiviz.composedOf OrderingFromRelation
*/
public class OutlierResult extends BasicResult {
@@ -47,7 +47,7 @@ public class OutlierResult extends BasicResult {
/**
* Outlier scores.
*/
- private Relation<Double> scores;
+ private DoubleRelation scores;
/**
* Outlier ordering.
@@ -60,11 +60,11 @@ public class OutlierResult extends BasicResult {
* @param meta Outlier score metadata.
* @param scores Scores result.
*/
- public OutlierResult(OutlierScoreMeta meta, Relation<Double> scores) {
+ public OutlierResult(OutlierScoreMeta meta, DoubleRelation scores) {
super(scores.getLongName(), scores.getShortName());
this.meta = meta;
this.scores = scores;
- this.ordering = new OrderingFromRelation(scores, !(meta instanceof InvertedOutlierScoreMeta));
+ this.ordering = new OrderingFromRelation(scores, meta instanceof InvertedOutlierScoreMeta);
this.addChildResult(scores);
this.addChildResult(ordering);
this.addChildResult(meta);
@@ -84,7 +84,7 @@ public class OutlierResult extends BasicResult {
*
* @return the scores
*/
- public Relation<Double> getScores() {
+ public DoubleRelation getScores() {
return scores;
}
diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierScoreMeta.java b/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierScoreMeta.java
index a17bade5..e619b3e3 100644
--- a/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierScoreMeta.java
+++ b/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierScoreMeta.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier;
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/result/outlier/ProbabilisticOutlierScore.java b/src/de/lmu/ifi/dbs/elki/result/outlier/ProbabilisticOutlierScore.java
index 36cd081e..c4f48838 100644
--- a/src/de/lmu/ifi/dbs/elki/result/outlier/ProbabilisticOutlierScore.java
+++ b/src/de/lmu/ifi/dbs/elki/result/outlier/ProbabilisticOutlierScore.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier;
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/result/outlier/QuotientOutlierScoreMeta.java b/src/de/lmu/ifi/dbs/elki/result/outlier/QuotientOutlierScoreMeta.java
index 3ac643e6..eb4ee1e1 100644
--- a/src/de/lmu/ifi/dbs/elki/result/outlier/QuotientOutlierScoreMeta.java
+++ b/src/de/lmu/ifi/dbs/elki/result/outlier/QuotientOutlierScoreMeta.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier;
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/result/outlier/package-info.java b/src/de/lmu/ifi/dbs/elki/result/outlier/package-info.java
index 7007c8b4..ff28fa05 100644
--- a/src/de/lmu/ifi/dbs/elki/result/outlier/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/result/outlier/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/result/package-info.java b/src/de/lmu/ifi/dbs/elki/result/package-info.java
index 0f3e3aa8..a7a28f68 100644
--- a/src/de/lmu/ifi/dbs/elki/result/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/result/package-info.java
@@ -12,7 +12,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/result/textwriter/MultipleFilesOutput.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/MultipleFilesOutput.java
index 22bde5be..f811f051 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/MultipleFilesOutput.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/MultipleFilesOutput.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter;
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/result/textwriter/SingleStreamOutput.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/SingleStreamOutput.java
index eb2b6170..23d75a29 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/SingleStreamOutput.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/SingleStreamOutput.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter;
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/result/textwriter/StreamFactory.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/StreamFactory.java
index 431fdc2c..33b6de74 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/StreamFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/StreamFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter;
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/result/textwriter/TextWriteable.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriteable.java
index 5b56cee6..019bab49 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriteable.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriteable.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter;
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/result/textwriter/TextWriter.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java
index 0cbc81f2..836292ac 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter;
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
@@ -41,7 +41,6 @@ import de.lmu.ifi.dbs.elki.data.FeatureVector;
import de.lmu.ifi.dbs.elki.data.HierarchicalClassLabel;
import de.lmu.ifi.dbs.elki.data.LabelList;
import de.lmu.ifi.dbs.elki.data.SimpleClassLabel;
-import de.lmu.ifi.dbs.elki.data.model.ClusterModel;
import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.Database;
@@ -51,7 +50,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.datasource.bundle.SingleObjectBundle;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.result.CollectionResult;
import de.lmu.ifi.dbs.elki.result.IterableResult;
@@ -66,17 +64,15 @@ import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterObjectArray;
import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterObjectInline;
import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterPair;
import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterTextWriteable;
-import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterTriple;
import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterVector;
import de.lmu.ifi.dbs.elki.utilities.HandlerList;
import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy;
import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackedParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.SerializedParameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleDoublePair;
import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Triple;
/**
* Class to write a result to human-readable text output.
@@ -108,7 +104,6 @@ public class TextWriter {
TextWriterObjectInline trivialwriter = new TextWriterObjectInline();
writers.insertHandler(Pair.class, new TextWriterPair());
writers.insertHandler(DoubleDoublePair.class, new TextWriterDoubleDoublePair());
- writers.insertHandler(Triple.class, new TextWriterTriple());
writers.insertHandler(FeatureVector.class, trivialwriter);
// these object can be serialized inline with toString()
writers.insertHandler(String.class, trivialwriter);
@@ -119,7 +114,6 @@ public class TextWriter {
writers.insertHandler(Integer[].class, new TextWriterObjectArray<Integer>());
writers.insertHandler(BitSet.class, trivialwriter);
writers.insertHandler(Vector.class, new TextWriterVector());
- writers.insertHandler(Distance.class, trivialwriter);
writers.insertHandler(SimpleClassLabel.class, trivialwriter);
writers.insertHandler(HierarchicalClassLabel.class, trivialwriter);
writers.insertHandler(LabelList.class, trivialwriter);
@@ -141,19 +135,20 @@ public class TextWriter {
* @return unique filename
*/
protected String getFilename(Object result, String filenamepre) {
- if (filenamepre == null || filenamepre.length() == 0) {
+ if(filenamepre == null || filenamepre.length() == 0) {
filenamepre = "result";
}
int i = 0;
- while (true) {
+ while(true) {
String filename;
- if (i > 0) {
+ if(i > 0) {
filename = filenamepre + "-" + i;
- } else {
+ }
+ else {
filename = filenamepre;
}
Object existing = filenames.get(filename);
- if (existing == null || existing == result) {
+ if(existing == null || existing == result) {
filenames.put(filename, result);
return filename;
}
@@ -183,33 +178,33 @@ public class TextWriter {
// Split result objects in different known types:
{
List<Result> results = ResultUtil.filterResults(r, Result.class);
- for (Result res : results) {
- if (filter != null) {
+ for(Result res : results) {
+ if(filter != null) {
final String nam = res.getShortName();
- if (nam == null || !filter.matcher(nam).find()) {
+ if(nam == null || !filter.matcher(nam).find()) {
continue;
}
}
- if (res instanceof Database) {
+ if(res instanceof Database) {
continue;
}
- if (res instanceof Relation) {
+ if(res instanceof Relation) {
ra.add((Relation<?>) res);
continue;
}
- if (res instanceof OrderingResult) {
+ if(res instanceof OrderingResult) {
ro.add((OrderingResult) res);
continue;
}
- if (res instanceof Clustering) {
+ if(res instanceof Clustering) {
rc.add((Clustering<?>) res);
continue;
}
- if (res instanceof IterableResult) {
+ if(res instanceof IterableResult) {
ri.add((IterableResult<?>) res);
continue;
}
- if (res instanceof SettingsResult) {
+ if(res instanceof SettingsResult) {
rs.add((SettingsResult) res);
continue;
}
@@ -219,19 +214,19 @@ public class TextWriter {
writeSettingsResult(streamOpener, rs);
- for (IterableResult<?> rii : ri) {
+ for(IterableResult<?> rii : ri) {
writeIterableResult(streamOpener, rii);
}
- for (Clustering<?> c : rc) {
+ for(Clustering<?> c : rc) {
NamingScheme naming = new SimpleEnumeratingScheme(c);
- for (Cluster<?> clus : c.getAllClusters()) {
+ for(Cluster<?> clus : c.getAllClusters()) {
writeClusterResult(db, streamOpener, (Clustering<Model>) c, (Cluster<Model>) clus, ra, naming);
}
}
- for (OrderingResult ror : ro) {
+ for(OrderingResult ror : ro) {
writeOrderingResult(db, streamOpener, ror, ra);
}
- for (Result otherr : otherres) {
+ for(Result otherr : otherres) {
writeOtherResult(streamOpener, otherr);
}
}
@@ -239,16 +234,16 @@ public class TextWriter {
private void printObject(TextWriterStream out, Database db, final DBIDRef objID, List<Relation<?>> ra) throws UnableToComplyException, IOException {
SingleObjectBundle bundle = db.getBundle(objID);
// Write database element itself.
- for (int i = 0; i < bundle.metaLength(); i++) {
+ for(int i = 0; i < bundle.metaLength(); i++) {
Object obj = bundle.data(i);
- if (obj != null) {
+ if(obj != null) {
TextWriterWriterInterface<?> owriter = out.getWriterFor(obj);
- if (owriter == null) {
+ if(owriter == null) {
throw new UnableToComplyException("No handler for database object itself: " + obj.getClass().getSimpleName());
}
String lbl = null;
// TODO: ugly compatibility hack...
- if (TypeUtil.DBID.isAssignableFromType(bundle.meta(i))) {
+ if(TypeUtil.DBID.isAssignableFromType(bundle.meta(i))) {
lbl = "ID";
}
owriter.writeObject(out, lbl, obj);
@@ -257,19 +252,19 @@ public class TextWriter {
Collection<Relation<?>> dbrels = db.getRelations();
// print the annotations
- if (ra != null) {
- for (Relation<?> a : ra) {
+ if(ra != null) {
+ for(Relation<?> a : ra) {
// Avoid duplicated output.
- if (dbrels.contains(a)) {
+ if(dbrels.contains(a)) {
continue;
}
String label = a.getShortName();
Object value = a.get(objID);
- if (value == null) {
+ if(value == null) {
continue;
}
TextWriterWriterInterface<?> writer = out.getWriterFor(value);
- if (writer == null) {
+ if(writer == null) {
// Ignore
continue;
}
@@ -281,9 +276,10 @@ public class TextWriter {
private void writeClusterResult(Database db, StreamFactory streamOpener, Clustering<Model> clustering, Cluster<Model> clus, List<Relation<?>> ra, NamingScheme naming) throws FileNotFoundException, UnableToComplyException, IOException {
String filename = null;
- if (naming != null) {
+ if(naming != null) {
filename = filenameFromLabel(naming.getNameFor(clus));
- } else {
+ }
+ else {
filename = "cluster";
}
@@ -292,25 +288,19 @@ public class TextWriter {
// Write cluster information
out.commentPrintLn("Cluster: " + naming.getNameFor(clus));
- Model model = clus.getModel();
- if (model != ClusterModel.CLUSTER && model != null) {
- TextWriterWriterInterface<?> mwri = out.getWriterFor(model);
- if (mwri != null) {
- mwri.writeObject(out, null, model);
- }
- }
- if (clustering.getClusterHierarchy().numParents(clus) > 0) {
+ clus.writeToText(out, null);
+ if(clustering.getClusterHierarchy().numParents(clus) > 0) {
StringBuilder buf = new StringBuilder();
buf.append("Parents:");
- for (Hierarchy.Iter<Cluster<Model>> iter = clustering.getClusterHierarchy().iterParents(clus); iter.valid(); iter.advance()) {
+ for(Hierarchy.Iter<Cluster<Model>> iter = clustering.getClusterHierarchy().iterParents(clus); iter.valid(); iter.advance()) {
buf.append(' ').append(naming.getNameFor(iter.get()));
}
out.commentPrintLn(buf.toString());
}
- if (clustering.getClusterHierarchy().numChildren(clus) > 0) {
+ if(clustering.getClusterHierarchy().numChildren(clus) > 0) {
StringBuilder buf = new StringBuilder();
buf.append("Children:");
- for (Hierarchy.Iter<Cluster<Model>> iter = clustering.getClusterHierarchy().iterChildren(clus); iter.valid(); iter.advance()) {
+ for(Hierarchy.Iter<Cluster<Model>> iter = clustering.getClusterHierarchy().iterChildren(clus); iter.valid(); iter.advance()) {
buf.append(' ').append(naming.getNameFor(iter.get()));
}
out.commentPrintLn(buf.toString());
@@ -319,7 +309,7 @@ public class TextWriter {
// print ids.
DBIDs ids = clus.getIDs();
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
printObject(out, db, iter, ra);
}
out.flush();
@@ -331,20 +321,20 @@ public class TextWriter {
TextWriterStream out = new TextWriterStream(outStream, writers);
// hack to print collectionResult header information
- if (ri instanceof CollectionResult<?>) {
+ if(ri instanceof CollectionResult<?>) {
final Collection<String> hdr = ((CollectionResult<?>) ri).getHeader();
- if (hdr != null) {
- for (String header : hdr) {
+ if(hdr != null) {
+ for(String header : hdr) {
out.commentPrintLn(header);
}
out.flush();
}
}
Iterator<?> i = ri.iterator();
- while (i.hasNext()) {
+ while(i.hasNext()) {
Object o = i.next();
TextWriterWriterInterface<?> writer = out.getWriterFor(o);
- if (writer != null) {
+ if(writer != null) {
writer.writeObject(out, null, o);
}
out.flush();
@@ -357,7 +347,7 @@ public class TextWriter {
PrintStream outStream = streamOpener.openStream(getFilename(or, or.getShortName()));
TextWriterStream out = new TextWriterStream(outStream, writers);
- for (DBIDIter i = or.iter(or.getDBIDs()).iter(); i.valid(); i.advance()) {
+ for(DBIDIter i = or.iter(or.getDBIDs()).iter(); i.valid(); i.advance()) {
printObject(out, db, i, ra);
}
out.flush();
@@ -365,7 +355,7 @@ public class TextWriter {
}
private void writeSettingsResult(StreamFactory streamOpener, List<SettingsResult> rs) throws UnableToComplyException, IOException {
- if (rs.size() < 1) {
+ if(rs.size() < 1) {
return;
}
SettingsResult r = rs.get(0);
@@ -373,38 +363,41 @@ public class TextWriter {
TextWriterStream out = new TextWriterStream(outStream, writers);
// Write settings preamble
out.commentPrintLn("Settings:");
-
- if (rs != null) {
- for (SettingsResult settings : rs) {
+
+ if(rs != null) {
+ for(SettingsResult settings : rs) {
Object last = null;
- for (Pair<Object, Parameter<?>> setting : settings.getSettings()) {
- if (setting.first != last && setting.first != null) {
- if (last != null) {
+ for(TrackedParameter setting : settings.getSettings()) {
+ if(setting.getOwner() != last && setting.getOwner() != null) {
+ if(last != null) {
out.commentPrintLn("");
}
String name;
try {
- if (setting.first instanceof Class) {
- name = ((Class<?>) setting.first).getName();
- } else {
- name = setting.first.getClass().getName();
+ if(setting.getOwner() instanceof Class) {
+ name = ((Class<?>) setting.getOwner()).getName();
+ }
+ else {
+ name = setting.getOwner().getClass().getName();
}
- if (ClassParameter.class.isInstance(setting.first)) {
- name = ((ClassParameter<?>) setting.first).getValue().getName();
+ if(ClassParameter.class.isInstance(setting.getOwner())) {
+ name = ((ClassParameter<?>) setting.getOwner()).getValue().getName();
}
- } catch (NullPointerException e) {
+ }
+ catch(NullPointerException e) {
name = "[null]";
}
out.commentPrintLn(name);
- last = setting.first;
+ last = setting.getOwner();
}
- String name = setting.second.getOptionID().getName();
+ String name = setting.getParameter().getOptionID().getName();
String value = "[unset]";
try {
- if (setting.second.isDefined()) {
- value = setting.second.getValueAsString();
+ if(setting.getParameter().isDefined()) {
+ value = setting.getParameter().getValueAsString();
}
- } catch (NullPointerException e) {
+ }
+ catch(NullPointerException e) {
value = "[null]";
}
out.commentPrintLn(SerializedParameterization.OPTION_PREFIX + name + " " + value);
@@ -416,11 +409,11 @@ public class TextWriter {
}
private void writeOtherResult(StreamFactory streamOpener, Result r) throws UnableToComplyException, IOException {
- if (writers.getHandler(r) != null) {
+ if(writers.getHandler(r) != null) {
PrintStream outStream = streamOpener.openStream(getFilename(r, r.getShortName()));
TextWriterStream out = new TextWriterStream(outStream, writers);
TextWriterWriterInterface<?> owriter = out.getWriterFor(r);
- if (owriter == null) {
+ if(owriter == null) {
throw new UnableToComplyException("No handler for result class: " + r.getClass().getSimpleName());
}
// Write data
diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterStream.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterStream.java
index 542be099..c174963d 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterStream.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterStream.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter;
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/result/textwriter/TextWriterWriterInterface.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterWriterInterface.java
index 35fa487f..cbbbdd21 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterWriterInterface.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterWriterInterface.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter;
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/result/textwriter/naming/NamingScheme.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/NamingScheme.java
index a63d3726..42b57149 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/NamingScheme.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/NamingScheme.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.naming;
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/result/textwriter/naming/SimpleEnumeratingScheme.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/SimpleEnumeratingScheme.java
index dacb342b..2e0885fd 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/SimpleEnumeratingScheme.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/SimpleEnumeratingScheme.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.naming;
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/result/textwriter/naming/package-info.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/package-info.java
index ab4b93d0..85fa0278 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/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/result/textwriter/package-info.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/package-info.java
index 60f2f534..7b178fe5 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/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/result/textwriter/writers/TextWriterDoubleDoublePair.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterDoubleDoublePair.java
index a9975195..b39c0b1e 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterDoubleDoublePair.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterDoubleDoublePair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers;
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/result/textwriter/writers/TextWriterObjectArray.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectArray.java
index 34d5b419..5f9d5000 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectArray.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectArray.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers;
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/result/textwriter/writers/TextWriterObjectComment.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectComment.java
index d3de4ff3..e56c9dfe 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectComment.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectComment.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers;
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/result/textwriter/writers/TextWriterObjectInline.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectInline.java
index 28c549d7..57bf699f 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectInline.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectInline.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers;
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/result/textwriter/writers/TextWriterPair.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterPair.java
index 1705f5cc..decc9efa 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterPair.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterPair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers;
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/result/textwriter/writers/TextWriterTextWriteable.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTextWriteable.java
index 04e56ae5..62e22a1b 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTextWriteable.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTextWriteable.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers;
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,7 +32,7 @@ import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterWriterInterface;
*
* @author Erich Schubert
*
- * @apiviz.has TextWriteable
+ * @apiviz.uses TextWriteable
*/
public class TextWriterTextWriteable extends TextWriterWriterInterface<TextWriteable> {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTriple.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTriple.java
deleted file mode 100644
index 1efde342..00000000
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTriple.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package de.lmu.ifi.dbs.elki.result.textwriter.writers;
-
-/*
- 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 de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream;
-import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterWriterInterface;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Triple;
-
-/**
- * Write a triple
- *
- * @author Erich Schubert
- *
- */
-public class TextWriterTriple extends TextWriterWriterInterface<Triple<?,?,?>> {
- /**
- * Serialize a triple, component-wise
- */
- @Override
- @SuppressWarnings("unchecked")
- public void write(TextWriterStream out, String label, Triple<?,?,?> object) throws UnableToComplyException, IOException {
- if (object != null) {
- Object first = object.getFirst();
- if (first != null) {
- TextWriterWriterInterface<Object> tw = (TextWriterWriterInterface<Object>) out.getWriterFor(first);
- if (tw == null) {
- throw new UnableToComplyException("No handler for database object itself: " + first.getClass().getSimpleName());
- }
- tw.write(out, label, first);
- }
- Object second = object.getSecond();
- if (second != null) {
- TextWriterWriterInterface<Object> tw = (TextWriterWriterInterface<Object>) out.getWriterFor(second);
- if (tw == null) {
- throw new UnableToComplyException("No handler for database object itself: " + second.getClass().getSimpleName());
- }
- tw.write(out, label, second);
- }
- Object third = object.getThird();
- if (third != null) {
- TextWriterWriterInterface<Object> tw = (TextWriterWriterInterface<Object>) out.getWriterFor(third);
- if (tw == null) {
- throw new UnableToComplyException("No handler for database object itself: " + third.getClass().getSimpleName());
- }
- tw.write(out, label, third);
- }
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterVector.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterVector.java
index 46197e21..5cdfa574 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterVector.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterVector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers;
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/result/textwriter/writers/package-info.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/package-info.java
index da527a67..ecae74ee 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/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/utilities/Alias.java b/src/de/lmu/ifi/dbs/elki/utilities/Alias.java
index 839fc406..e3360b1e 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/Alias.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/Alias.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities;
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/utilities/Base64.java b/src/de/lmu/ifi/dbs/elki/utilities/Base64.java
deleted file mode 100644
index c6a22f20..00000000
--- a/src/de/lmu/ifi/dbs/elki/utilities/Base64.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities;
-/*
- 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.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-
-/**
- * Class to wrap various Base64 encoders that could be available.
- *
- * This is a rather ugly hack; it would maybe have been sensible to just import
- * one of the publicly available (and fast) Base64 encoders. The expectation was
- * that at some point, Oracle will actually include a public and fast Base64
- * encoder in Java...
- *
- * @author Erich Schubert
- */
-public final class Base64 {
- /**
- * Instance of sun.misc.BASE64Encoder
- */
- private static Object sunj6i;
-
- /**
- * Encode method
- */
- private static Method sunj6m;
-
- /**
- * Instance of java.util.prefs.Base64
- */
- private static Object jup6i;
-
- /**
- * Encode method
- */
- private static Method jup6m;
-
- // Initialize
- static {
- // Try Java 6
- {
- try {
- Class<?> c = ClassLoader.getSystemClassLoader().loadClass("sun.misc.BASE64Encoder");
- sunj6i = c.newInstance();
- sunj6m = c.getMethod("encode", byte[].class);
- }
- catch(Throwable e) {
- // de.lmu.ifi.dbs.elki.logging.LoggingUtil.exception(e);
- // Ignore.
- sunj6i = null;
- sunj6m = null;
- }
- }
- // Try private class in Java6 preferences
- {
- try {
- Class<?> c = ClassLoader.getSystemClassLoader().loadClass("java.util.prefs.Base64");
- Constructor<?> cons = c.getDeclaredConstructor();
- cons.setAccessible(true);
- jup6i = cons.newInstance();
- jup6m = c.getDeclaredMethod("byteArrayToBase64", byte[].class);
- jup6m.setAccessible(true);
- }
- catch(Throwable e) {
- // de.lmu.ifi.dbs.elki.logging.LoggingUtil.exception(e);
- // Ignore.
- jup6i = null;
- jup6m = null;
- }
- }
- if(sunj6i == null && jup6i == null) {
- de.lmu.ifi.dbs.elki.logging.LoggingUtil.warning("No usable Base64 encoders detected.");
- }
- }
-
- /**
- * Encode a string as Base64.
- *
- * @param s Bytes to encode
- * @return Result string
- */
- public static final String encodeBase64(byte[] s) {
- if(jup6i != null && jup6m != null) {
- try {
- return (String) jup6m.invoke(jup6i, s);
- }
- catch(Exception e) {
- throw new RuntimeException("java.util.prefs.Base64 is not working.");
- }
- }
- if(sunj6i != null && sunj6m != null) {
- try {
- return (String) sunj6m.invoke(sunj6i, s);
- }
- catch(Exception e) {
- throw new RuntimeException("sun.misc.BASE64Encoder is not working.");
- }
- }
- throw new RuntimeException("No usable Base64 encoder detected.");
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/BitsUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/BitsUtil.java
index 64d5be25..9ed9097e 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/BitsUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/BitsUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities;
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,6 +23,8 @@ package de.lmu.ifi.dbs.elki.utilities;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import gnu.trove.strategy.HashingStrategy;
+
import java.util.Arrays;
/**
@@ -61,13 +63,33 @@ public final class BitsUtil {
9765625, 48828125, 244140625, 1220703125 };
/**
+ * Hashing strategy to use with Trove.
+ */
+ public static final HashingStrategy<long[]> TROVE_HASH_STRATEGY = new HashingStrategy<long[]>() {
+ /**
+ * Serial version number.
+ */
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public int computeHashCode(long[] arg0) {
+ return BitsUtil.hashCode(arg0);
+ }
+
+ @Override
+ public boolean equals(long[] arg0, long[] arg1) {
+ return equal(arg0, arg1);
+ }
+ };
+
+ /**
* Allocate a new long[].
*
* @param bits Number of bits in storage
* @return New array
*/
public static long[] zero(int bits) {
- return new long[((bits - 1) >>> LONG_LOG2_SIZE) + 1];
+ return new long[(bits > 0) ? ((bits - 1) >>> LONG_LOG2_SIZE) + 1 : 1];
}
/**
@@ -120,7 +142,7 @@ public final class BitsUtil {
*/
public static long[] copy(long[] v, int mincap) {
int words = ((mincap - 1) >>> LONG_LOG2_SIZE) + 1;
- if (v.length == words) {
+ if(v.length == words) {
return Arrays.copyOf(v, v.length);
}
long[] ret = new long[words];
@@ -140,15 +162,15 @@ public final class BitsUtil {
*/
public static long[] copy(long[] v, int mincap, int shift) {
int words = ((mincap - 1) >>> LONG_LOG2_SIZE) + 1;
- if (v.length == words && shift == 0) {
+ if(v.length == words && shift == 0) {
return Arrays.copyOf(v, v.length);
}
long[] ret = new long[words];
final int shiftWords = shift >>> LONG_LOG2_SIZE;
final int shiftBits = shift & LONG_LOG2_MASK;
// Simple case - multiple of word size
- if (shiftBits == 0) {
- for (int i = shiftWords; i < ret.length; i++) {
+ if(shiftBits == 0) {
+ for(int i = shiftWords; i < ret.length; i++) {
ret[i] |= v[i - shiftWords];
}
return ret;
@@ -156,7 +178,7 @@ public final class BitsUtil {
// Overlapping case
final int unshiftBits = Long.SIZE - shiftBits;
final int end = Math.min(ret.length, v.length + shiftWords) - 1;
- for (int i = end; i > shiftWords; i--) {
+ for(int i = end; i > shiftWords; i--) {
final int src = i - shiftWords;
ret[i] |= (v[src] << shiftBits) | (v[src - 1] >>> unshiftBits);
}
@@ -214,15 +236,15 @@ public final class BitsUtil {
final int last = v.length - 1;
int o;
// Sub word level:
- for (o = 1; o < Long.SIZE; o <<= 1) {
- for (int i = 0; i < last; i++) {
+ for(o = 1; o < Long.SIZE; o <<= 1) {
+ for(int i = 0; i < last; i++) {
v[i] ^= (v[i] >>> o) ^ (v[i + 1] << (Long.SIZE - o));
}
v[last] ^= (v[last] >>> o);
}
// Word level:
- for (o = 1; o <= last; o <<= 1) {
- for (int i = o; i <= last; i++) {
+ for(o = 1; o <= last; o <<= 1) {
+ for(int i = o; i <= last; i++) {
v[i - o] ^= v[i];
}
}
@@ -236,8 +258,8 @@ public final class BitsUtil {
* @return true when all zero
*/
public static boolean isZero(long[] v) {
- for (int i = 0; i < v.length; i++) {
- if (v[i] != 0) {
+ for(int i = 0; i < v.length; i++) {
+ if(v[i] != 0) {
return false;
}
}
@@ -262,9 +284,9 @@ public final class BitsUtil {
* @param v Value
* @return Number of bits set in long[]
*/
- public static long cardinality(long[] v) {
+ public static int cardinality(long[] v) {
int sum = 0;
- for (int i = 0; i < v.length; i++) {
+ for(int i = 0; i < v.length; i++) {
sum += Long.bitCount(v[i]);
}
return sum;
@@ -321,6 +343,22 @@ public final class BitsUtil {
}
/**
+ * Put o onto v inplace, i.e. v = o
+ *
+ * @param v Primary object
+ * @param o data to initialize to.
+ * @return v
+ */
+ public static long[] setI(long[] v, long[] o) {
+ assert (o.length <= v.length) : "Bit set sizes do not agree.";
+ final int max = Math.min(v.length, o.length);
+ for(int i = 0; i < max; i++) {
+ v[i] = o[i];
+ }
+ return v;
+ }
+
+ /**
* Clear bit number "off" in v.
*
* @param v Buffer
@@ -365,7 +403,7 @@ public final class BitsUtil {
*/
public static boolean get(long[] v, int off) {
final int wordindex = off >>> LONG_LOG2_SIZE;
- return (v[wordindex] & (1L << off)) != 0;
+ return (wordindex < v.length) && (v[wordindex] & (1L << off)) != 0;
}
/**
@@ -390,7 +428,7 @@ public final class BitsUtil {
*/
public static long[] xorI(long[] v, long[] o) {
assert (o.length <= v.length) : "Bit set sizes do not agree.";
- for (int i = 0; i < o.length; i++) {
+ for(int i = 0; i < o.length; i++) {
v[i] ^= o[i];
}
return v;
@@ -405,23 +443,23 @@ public final class BitsUtil {
* @return v
*/
public static long[] xorI(long[] v, long[] o, int off) {
- if (off == 0) {
+ if(off == 0) {
return xorI(v, o);
}
- if (off < 0) {
+ if(off < 0) {
throw new UnsupportedOperationException("Negative shifts are not supported.");
}
// Break shift into integers to shift and bits to shift
final int shiftWords = off >>> LONG_LOG2_SIZE;
final int shiftBits = off & LONG_LOG2_MASK;
- if (shiftWords >= v.length) {
+ if(shiftWords >= v.length) {
return v;
}
// Simple case - multiple of word size
- if (shiftBits == 0) {
+ if(shiftBits == 0) {
final int end = Math.min(v.length, o.length + shiftWords);
- for (int i = shiftWords; i < end; i++) {
+ for(int i = shiftWords; i < end; i++) {
v[i] ^= o[i - shiftWords];
}
return v;
@@ -429,7 +467,7 @@ public final class BitsUtil {
// Overlapping case
final int unshiftBits = Long.SIZE - shiftBits;
final int end = Math.min(v.length, o.length + shiftWords) - 1;
- for (int i = end; i > shiftWords; i--) {
+ for(int i = end; i > shiftWords; i--) {
final int src = i - shiftWords;
v[i] ^= (o[src] << shiftBits) | (o[src - 1] >>> unshiftBits);
}
@@ -447,7 +485,7 @@ public final class BitsUtil {
public static long[] orI(long[] v, long[] o) {
assert (o.length <= v.length) : "Bit set sizes do not agree.";
final int max = Math.min(v.length, o.length);
- for (int i = 0; i < max; i++) {
+ for(int i = 0; i < max; i++) {
v[i] |= o[i];
}
return v;
@@ -464,23 +502,23 @@ public final class BitsUtil {
* @return v
*/
public static long[] orI(long[] v, long[] o, int off) {
- if (off == 0) {
+ if(off == 0) {
return orI(v, o);
}
- if (off < 0) {
+ if(off < 0) {
throw new UnsupportedOperationException("Negative shifts are not supported.");
}
// Break shift into integers to shift and bits to shift
final int shiftWords = off >>> LONG_LOG2_SIZE;
final int shiftBits = off & LONG_LOG2_MASK;
- if (shiftWords >= v.length) {
+ if(shiftWords >= v.length) {
return v;
}
// Simple case - multiple of word size
- if (shiftBits == 0) {
+ if(shiftBits == 0) {
final int end = Math.min(v.length, o.length + shiftWords);
- for (int i = shiftWords; i < end; i++) {
+ for(int i = shiftWords; i < end; i++) {
v[i] |= o[i - shiftWords];
}
return v;
@@ -488,7 +526,7 @@ public final class BitsUtil {
// Overlapping case
final int unshiftBits = Long.SIZE - shiftBits;
final int end = Math.min(v.length, o.length + shiftWords) - 1;
- for (int i = end; i > shiftWords; i--) {
+ for(int i = end; i > shiftWords; i--) {
final int src = i - shiftWords;
v[i] |= (o[src] << shiftBits) | (o[src - 1] >>> unshiftBits);
}
@@ -505,8 +543,8 @@ public final class BitsUtil {
*/
public static long[] andI(long[] v, long[] o) {
int i = 0;
- for (; i < o.length; i++) {
- v[i] |= o[i];
+ for(; i < o.length; i++) {
+ v[i] &= o[i];
}
// Zero higher words
Arrays.fill(v, i, v.length, 0);
@@ -522,23 +560,23 @@ public final class BitsUtil {
* @return v
*/
public static long[] andI(long[] v, long[] o, int off) {
- if (off == 0) {
+ if(off == 0) {
return andI(v, o);
}
- if (off < 0) {
+ if(off < 0) {
throw new UnsupportedOperationException("Negative shifts are not supported.");
}
// Break shift into integers to shift and bits to shift
final int shiftWords = off >>> LONG_LOG2_SIZE;
final int shiftBits = off & LONG_LOG2_MASK;
- if (shiftWords >= v.length) {
+ if(shiftWords >= v.length) {
return v;
}
// Simple case - multiple of word size
- if (shiftBits == 0) {
+ if(shiftBits == 0) {
final int end = Math.min(v.length, o.length + shiftWords);
- for (int i = shiftWords; i < end; i++) {
+ for(int i = shiftWords; i < end; i++) {
v[i] &= o[i - shiftWords];
}
// Clear bottom words
@@ -549,7 +587,7 @@ public final class BitsUtil {
final int unshiftBits = Long.SIZE - shiftBits;
final int end = Math.min(v.length, o.length + shiftWords) - 1;
Arrays.fill(v, end + 1, v.length, 0);
- for (int i = end; i > shiftWords; i--) {
+ for(int i = end; i > shiftWords; i--) {
final int src = i - shiftWords;
v[i] &= (o[src] << shiftBits) | (o[src - 1] >>> unshiftBits);
}
@@ -560,13 +598,74 @@ public final class BitsUtil {
}
/**
+ * AND o onto v in a copy, i.e. v & o
+ *
+ * The resulting array will have the shorter length of the two.
+ *
+ * @param v Primary object
+ * @param o data to and
+ * @return Copy of v and o
+ */
+ public static long[] andCMin(long[] v, long[] o) {
+ final int min = Math.min(v.length, o.length);
+ long[] out = new long[min];
+ int i = 0;
+ for(; i < min; i++) {
+ out[i] = v[i] & o[i];
+ }
+ return out;
+ }
+
+ /**
+ * AND o onto v in a copy, i.e. v & o
+ *
+ * The resulting array will have the shorter length of the two.
+ *
+ * @param v Primary object
+ * @param o data to and
+ * @return Copy of v and o
+ */
+ public static long[] andCMax(long[] v, long[] o) {
+ final int min, max;
+ if(v.length < o.length) {
+ min = v.length;
+ max = o.length;
+ }
+ else {
+ min = o.length;
+ max = v.length;
+ }
+ long[] out = new long[max];
+ int i = 0;
+ for(; i < min; i++) {
+ out[i] = v[i] & o[i];
+ }
+ return out;
+ }
+
+ /**
+ * NOTAND o onto v inplace, i.e. v &= ~o
+ *
+ * @param v Primary object
+ * @param o data to and
+ * @return v
+ */
+ public static long[] nandI(long[] v, long[] o) {
+ int i = 0;
+ for(; i < o.length; i++) {
+ v[i] &= ~o[i];
+ }
+ return v;
+ }
+
+ /**
* Invert v inplace.
*
* @param v Object to invert
* @return v
*/
public static long[] invertI(long[] v) {
- for (int i = 0; i < v.length; i++) {
+ for(int i = 0; i < v.length; i++) {
v[i] = ~v[i];
}
return v;
@@ -582,21 +681,21 @@ public final class BitsUtil {
* @return Bitset
*/
public static long[] shiftRightI(long[] v, int off) {
- if (off == 0) {
+ if(off == 0) {
return v;
}
- if (off < 0) {
+ if(off < 0) {
return shiftLeftI(v, -off);
}
// Break shift into integers to shift and bits to shift
final int shiftWords = off >>> LONG_LOG2_SIZE;
final int shiftBits = off & LONG_LOG2_MASK;
- if (shiftWords >= v.length) {
+ if(shiftWords >= v.length) {
return zeroI(v);
}
// Simple case - multiple of word size
- if (shiftBits == 0) {
+ if(shiftBits == 0) {
// Move whole words down
System.arraycopy(v, shiftWords, v, 0, v.length - shiftWords);
// Fill top words with zeros
@@ -606,7 +705,7 @@ public final class BitsUtil {
// Overlapping case
final int unshiftBits = Long.SIZE - shiftBits;
// Bottom-up to not overlap the operations.
- for (int i = 0; i < v.length - shiftWords - 1; i++) {
+ for(int i = 0; i < v.length - shiftWords - 1; i++) {
final int src = i + shiftWords;
v[i] = (v[src + 1] << unshiftBits) | (v[src] >>> shiftBits);
}
@@ -627,21 +726,21 @@ public final class BitsUtil {
* @return Bitset
*/
public static long[] shiftLeftI(long[] v, int off) {
- if (off == 0) {
+ if(off == 0) {
return v;
}
- if (off < 0) {
+ if(off < 0) {
return shiftRightI(v, -off);
}
// Break shift into integers to shift and bits to shift
final int shiftWords = off >>> LONG_LOG2_SIZE;
final int shiftBits = off & LONG_LOG2_MASK;
- if (shiftWords >= v.length) {
+ if(shiftWords >= v.length) {
return zeroI(v);
}
// Simple case - multiple of word size
- if (shiftBits == 0) {
+ if(shiftBits == 0) {
// Move whole words up
System.arraycopy(v, 0, v, shiftWords, v.length - shiftWords);
// Fill the initial words with zeros
@@ -651,7 +750,7 @@ public final class BitsUtil {
// Overlapping case
final int unshiftBits = Long.SIZE - shiftBits;
// Top-Down to not overlap the operations.
- for (int i = v.length - 1; i > shiftWords; i--) {
+ for(int i = v.length - 1; i > shiftWords; i--) {
final int src = i - shiftWords;
v[i] = (v[src] << shiftBits) | (v[src - 1] >>> unshiftBits);
}
@@ -670,10 +769,10 @@ public final class BitsUtil {
* @return cycled bit set
*/
public static long cycleRightC(long v, int shift, int len) {
- if (shift == 0) {
+ if(shift == 0) {
return v;
}
- if (shift < 0) {
+ if(shift < 0) {
return cycleLeftC(v, -shift, len);
}
final long ones = (1 << len) - 1;
@@ -706,7 +805,7 @@ public final class BitsUtil {
final int zapWords = (zap >>> LONG_LOG2_SIZE);
final int zapbits = zap & LONG_LOG2_MASK;
Arrays.fill(v, v.length - zapWords, v.length, 0);
- if (zapbits > 0) {
+ if(zapbits > 0) {
v[v.length - zapWords - 1] &= (LONG_ALL_BITS >>> zapbits);
}
return v;
@@ -721,10 +820,10 @@ public final class BitsUtil {
* @return cycled bit set
*/
public static long cycleLeftC(long v, int shift, int len) {
- if (shift == 0) {
+ if(shift == 0) {
return v;
}
- if (shift < 0) {
+ if(shift < 0) {
return cycleRightC(v, -shift, len);
}
final long ones = (1 << len) - 1;
@@ -753,25 +852,30 @@ public final class BitsUtil {
* @return String representation
*/
public static String toString(long[] v) {
+ if(v == null) {
+ return "null";
+ }
final int mag = magnitude(v);
- if (v.length == 0 || mag == 0) {
+ if(mag == 0) {
return "0";
}
- final int words = ((mag - 1) >>> LONG_LOG2_SIZE) + 1;
char[] digits = new char[mag];
-
int pos = mag - 1;
- for (int w = 0; w < words; w++) {
+
+ outer: for(int w = 0; w < v.length; w++) {
long f = 1L;
- for (int i = 0; i < Long.SIZE; i++) {
+ for(int i = 0; i < Long.SIZE; i++) {
digits[pos] = ((v[w] & f) == 0) ? '0' : '1';
- pos--;
f <<= 1;
- if (pos < 0) {
- break;
+ --pos;
+ if(pos < 0) {
+ break outer;
}
}
}
+ for(; pos >= 0; --pos) {
+ digits[pos] = '0';
+ }
return new String(digits);
}
@@ -783,25 +887,30 @@ public final class BitsUtil {
* @return String representation
*/
public static String toString(long[] v, int minw) {
+ if(v == null) {
+ return "null";
+ }
final int mag = Math.max(magnitude(v), minw);
- if (v.length == 0 || mag == 0) {
+ if(mag == 0) {
return "0";
}
- final int words = ((mag - 1) >>> LONG_LOG2_SIZE) + 1;
char[] digits = new char[mag];
-
int pos = mag - 1;
- for (int w = 0; w < words; w++) {
+
+ outer: for(int w = 0; w < v.length; w++) {
long f = 1L;
- for (int i = 0; i < Long.SIZE; i++) {
+ for(int i = 0; i < Long.SIZE; i++) {
digits[pos] = ((v[w] & f) == 0) ? '0' : '1';
- pos--;
f <<= 1;
- if (pos < 0) {
- break;
+ --pos;
+ if(pos < 0) {
+ break outer;
}
}
}
+ for(; pos >= 0; --pos) {
+ digits[pos] = '0';
+ }
return new String(digits);
}
@@ -813,36 +922,140 @@ public final class BitsUtil {
*/
public static String toString(long v) {
final int mag = magnitude(v);
- if (mag == 0) {
+ if(mag == 0) {
return "0";
}
char[] digits = new char[mag];
- int pos = mag - 1;
long f = 1L;
- for (int i = 0; i < Long.SIZE; i++) {
+ for(int pos = mag - 1; pos >= 0; --pos, f <<= 1) {
digits[pos] = ((v & f) == 0) ? '0' : '1';
- pos--;
- f <<= 1;
- if (pos < 0) {
- break;
+ }
+ return new String(digits);
+ }
+
+ /**
+ * Convert bitset to a string consisting of "0" and "1", in low-endian order.
+ *
+ * @param v Value to process
+ * @return String representation
+ */
+ public static String toStringLow(long[] v) {
+ if(v == null) {
+ return "null";
+ }
+ final int mag = magnitude(v);
+ if(mag == 0) {
+ return "0";
+ }
+ char[] digits = new char[mag];
+ int pos = 0;
+
+ outer: for(int w = 0; w < v.length; w++) {
+ long f = 1L;
+ for(int i = 0; i < Long.SIZE; i++) {
+ digits[pos] = ((v[w] & f) == 0) ? '0' : '1';
+ f <<= 1;
+ ++pos;
+ if(pos >= mag) {
+ break outer;
+ }
}
}
+ for(; pos < mag; ++pos) {
+ digits[pos] = '0';
+ }
+ return new String(digits);
+ }
+
+ /**
+ * Convert bitset to a string consisting of "0" and "1", in low-endian order.
+ *
+ * @param v Value to process
+ * @param minw Minimum width
+ * @return String representation
+ */
+ public static String toStringLow(long[] v, int minw) {
+ if(v == null) {
+ return "null";
+ }
+ final int mag = Math.max(magnitude(v), minw);
+ if(mag == 0) {
+ return "0";
+ }
+ char[] digits = new char[mag];
+ int pos = 0;
+
+ outer: for(int w = 0; w < v.length; w++) {
+ long f = 1L;
+ for(int i = 0; i < Long.SIZE; i++) {
+ digits[pos] = ((v[w] & f) == 0) ? '0' : '1';
+ f <<= 1;
+ ++pos;
+ if(pos >= mag) {
+ break outer;
+ }
+ }
+ }
+ for(; pos < mag; ++pos) {
+ digits[pos] = '0';
+ }
+ return new String(digits);
+ }
+
+ /**
+ * Convert bitset to a string consisting of "0" and "1", in low-endian order.
+ *
+ * @param v Value to process
+ * @return String representation
+ */
+ public static String toStringLow(long v) {
+ final int mag = magnitude(v);
+ if(mag == 0) {
+ return "0";
+ }
+ char[] digits = new char[mag];
+
+ long f = 1L;
+ for(int pos = 0; pos < mag; ++pos, f <<= 1) {
+ digits[pos] = ((v & f) == 0) ? '0' : '1';
+ }
return new String(digits);
}
/**
+ * Convert the bitset into a decimal representation, e.g. <tt>0, 3, 5</tt>
+ *
+ * @param v Value
+ * @param sep Value separator
+ * @param offset Counting offset (usually, 0 or 1)
+ * @return String representation
+ */
+ public static String toString(long[] v, String sep, int offset) {
+ int p = nextSetBit(v, 0);
+ if(p < 0) {
+ return "";
+ }
+ StringBuilder buf = new StringBuilder();
+ buf.append(p + offset);
+ for(p = nextSetBit(v, p + 1); p >= 0; p = nextSetBit(v, p + 1)) {
+ buf.append(sep).append(p + offset);
+ }
+ return buf.toString();
+ }
+
+ /**
* Find the number of trailing zeros.
*
* @param v Bitset
* @return Position of first set bit, -1 if no set bit was found.
*/
public static int numberOfTrailingZerosSigned(long[] v) {
- for (int p = 0;; p++) {
- if (p == v.length) {
+ for(int p = 0;; p++) {
+ if(p == v.length) {
return -1;
}
- if (v[p] != 0) {
+ if(v[p] != 0) {
return Long.numberOfTrailingZeros(v[p]) + p * Long.SIZE;
}
}
@@ -855,11 +1068,11 @@ public final class BitsUtil {
* @return Position of first set bit, v.length * 64 if no set bit was found.
*/
public static int numberOfTrailingZeros(long[] v) {
- for (int p = 0;; p++) {
- if (p == v.length) {
+ for(int p = 0;; p++) {
+ if(p == v.length) {
return p * Long.SIZE;
}
- if (v[p] != 0) {
+ if(v[p] != 0) {
return Long.numberOfTrailingZeros(v[p]) + p * Long.SIZE;
}
}
@@ -909,11 +1122,11 @@ public final class BitsUtil {
* @return Position of first set bit, -1 if no set bit was found.
*/
public static int numberOfLeadingZerosSigned(long[] v) {
- for (int p = 0, ip = v.length - 1;; p++, ip--) {
- if (p == v.length) {
+ for(int p = 0, ip = v.length - 1;; p++, ip--) {
+ if(p == v.length) {
return -1;
}
- if (v[ip] != 0) {
+ if(v[ip] != 0) {
return Long.numberOfLeadingZeros(v[ip]) + p * Long.SIZE;
}
}
@@ -926,11 +1139,11 @@ public final class BitsUtil {
* @return Position of first set bit, v.length * 64 if no set bit was found.
*/
public static int numberOfLeadingZeros(long[] v) {
- for (int p = 0, ip = v.length - 1;; p++, ip--) {
- if (p == v.length) {
+ for(int p = 0, ip = v.length - 1;; p++, ip--) {
+ if(p == v.length) {
return p * Long.SIZE;
}
- if (v[ip] != 0) {
+ if(v[ip] != 0) {
return Long.numberOfLeadingZeros(v[ip]) + p * Long.SIZE;
}
}
@@ -946,7 +1159,7 @@ public final class BitsUtil {
* @return Position of first set bit, -1 if no set bit was found.
*/
public static int numberOfLeadingZerosSigned(long v) {
- if (v == 0) {
+ if(v == 0) {
return -1;
}
return Long.numberOfLeadingZeros(v);
@@ -962,7 +1175,7 @@ public final class BitsUtil {
* @return Position of first set bit, -1 if no set bit was found.
*/
public static int numberOfLeadingZerosSigned(int v) {
- if (v == 0) {
+ if(v == 0) {
return -1;
}
return Integer.numberOfLeadingZeros(v);
@@ -999,22 +1212,40 @@ public final class BitsUtil {
* @param start Start position (inclusive)
* @return Position of previous set bit, or -1.
*/
+ public static int previousSetBit(long v, int start) {
+ if(start == -1 || start >= Long.SIZE) {
+ return -1;
+ }
+ long cur = v & (LONG_ALL_BITS >>> start);
+ if(cur == 0) {
+ return -1;
+ }
+ return Long.SIZE - 1 - Long.numberOfLeadingZeros(cur);
+ }
+
+ /**
+ * Find the previous set bit.
+ *
+ * @param v Values to process
+ * @param start Start position (inclusive)
+ * @return Position of previous set bit, or -1.
+ */
public static int previousSetBit(long[] v, int start) {
- if (start == -1) {
+ if(start == -1) {
return -1;
}
int wordindex = start >>> LONG_LOG2_SIZE;
- if (wordindex >= v.length) {
+ if(wordindex >= v.length) {
return magnitude(v) - 1;
}
// Initial word
final int off = Long.SIZE - 1 - (start & LONG_LOG2_MASK);
long cur = v[wordindex] & (LONG_ALL_BITS >>> off);
- for (;;) {
- if (cur != 0) {
+ for(;;) {
+ if(cur != 0) {
return (wordindex + 1) * Long.SIZE - 1 - Long.numberOfLeadingZeros(cur);
}
- if (wordindex == 0) {
+ if(wordindex == 0) {
return -1;
}
wordindex--;
@@ -1029,22 +1260,40 @@ public final class BitsUtil {
* @param start Start position (inclusive)
* @return Position of previous clear bit, or -1.
*/
+ public static int previousClearBit(long v, int start) {
+ if(start < 0 || start >= Long.SIZE) {
+ return -1;
+ }
+ long cur = ~v & (LONG_ALL_BITS >>> start);
+ if(cur == 0) {
+ return -1;
+ }
+ return Long.SIZE - 1 - Long.numberOfTrailingZeros(cur);
+ }
+
+ /**
+ * Find the previous clear bit.
+ *
+ * @param v Values to process
+ * @param start Start position (inclusive)
+ * @return Position of previous clear bit, or -1.
+ */
public static int previousClearBit(long[] v, int start) {
- if (start == -1) {
+ if(start == -1) {
return -1;
}
int wordindex = start >>> LONG_LOG2_SIZE;
- if (wordindex >= v.length) {
+ if(wordindex >= v.length) {
return magnitude(v);
}
final int off = Long.SIZE + 1 - (start & LONG_LOG2_MASK);
// Initial word
long cur = ~v[wordindex] & (LONG_ALL_BITS >>> off);
- for (;;) {
- if (cur != 0) {
+ for(;;) {
+ if(cur != 0) {
return (wordindex + 1) * Long.SIZE - 1 - Long.numberOfTrailingZeros(cur);
}
- if (wordindex == 0) {
+ if(wordindex == 0) {
return -1;
}
wordindex--;
@@ -1059,20 +1308,38 @@ public final class BitsUtil {
* @param start Start position (inclusive)
* @return Position of next set bit, or -1.
*/
+ public static int nextSetBit(long v, int start) {
+ if(start >= Long.SIZE) {
+ return -1;
+ }
+ long cur = v & (LONG_ALL_BITS << start);
+ if(cur == 0) {
+ return -1;
+ }
+ return Long.numberOfTrailingZeros(cur);
+ }
+
+ /**
+ * Find the next set bit.
+ *
+ * @param v Value to process
+ * @param start Start position (inclusive)
+ * @return Position of next set bit, or -1.
+ */
public static int nextSetBit(long[] v, int start) {
int wordindex = start >>> LONG_LOG2_SIZE;
- if (wordindex >= v.length) {
+ if(wordindex >= v.length) {
return -1;
}
// Initial word
long cur = v[wordindex] & (LONG_ALL_BITS << start);
- for (;;) {
- if (cur != 0) {
+ for(;;) {
+ if(cur != 0) {
return (wordindex * Long.SIZE) + Long.numberOfTrailingZeros(cur);
}
wordindex++;
- if (wordindex == v.length) {
+ if(wordindex == v.length) {
return -1;
}
cur = v[wordindex];
@@ -1086,16 +1353,34 @@ public final class BitsUtil {
* @param start Start position (inclusive)
* @return Position of next clear bit, or -1.
*/
+ public static int nextClearBit(long v, int start) {
+ if(start >= Long.SIZE) {
+ return -1;
+ }
+ long cur = ~v & (LONG_ALL_BITS << start);
+ if(cur == 0) {
+ return -1;
+ }
+ return Long.numberOfTrailingZeros(cur);
+ }
+
+ /**
+ * Find the next clear bit.
+ *
+ * @param v Value to process
+ * @param start Start position (inclusive)
+ * @return Position of next clear bit, or -1.
+ */
public static int nextClearBit(long[] v, int start) {
int wordindex = start >>> LONG_LOG2_SIZE;
- if (wordindex >= v.length) {
+ if(wordindex >= v.length) {
return -1;
}
// Initial word
long cur = ~v[wordindex] & (LONG_ALL_BITS << start);
- for (; wordindex < v.length;) {
- if (cur != 0) {
+ for(; wordindex < v.length;) {
+ if(cur != 0) {
return (wordindex * Long.SIZE) + Long.numberOfTrailingZeros(cur);
}
wordindex++;
@@ -1136,6 +1421,132 @@ public final class BitsUtil {
}
/**
+ * Test whether two Bitsets intersect.
+ *
+ * @param x First bitset
+ * @param y Second bitset
+ * @return {@code true} when the bitsets intersect.
+ */
+ public static boolean intersect(long x, long y) {
+ return (x & y) != 0L;
+ }
+
+ /**
+ * Test whether two Bitsets intersect.
+ *
+ * @param x First bitset
+ * @param y Second bitset
+ * @return {@code true} when the bitsets intersect.
+ */
+ public static boolean intersect(long[] x, long[] y) {
+ final int min = (x.length < y.length) ? x.length : y.length;
+ for(int i = 0; i < min; i++) {
+ if((x[i] & y[i]) != 0L) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Compute the intersection size of two Bitsets.
+ *
+ * @param x First bitset
+ * @param y Second bitset
+ * @return Intersection size
+ */
+ public static int intersectionSize(long x, long y) {
+ return Long.bitCount(x & y);
+ }
+
+ /**
+ * Compute the intersection size of two Bitsets.
+ *
+ * @param x First bitset
+ * @param y Second bitset
+ * @return Intersection size
+ */
+ public static int intersectionSize(long[] x, long[] y) {
+ final int lx = x.length, ly = y.length;
+ final int min = (lx < ly) ? lx : ly;
+ int res = 0;
+ for(int i = 0; i < min; i++) {
+ res += Long.bitCount(x[i] & y[i]);
+ }
+ return res;
+ }
+
+ /**
+ * Compute the union size of two Bitsets.
+ *
+ * @param x First bitset
+ * @param y Second bitset
+ * @return Union size
+ */
+ public static int unionSize(long x, long y) {
+ return Long.bitCount(x | y);
+ }
+
+ /**
+ * Compute the union size of two Bitsets.
+ *
+ * @param x First bitset
+ * @param y Second bitset
+ * @return Union size
+ */
+ public static int unionSize(long[] x, long[] y) {
+ final int lx = x.length, ly = y.length;
+ final int min = (lx < ly) ? lx : ly;
+ int i = 0, res = 0;
+ for(; i < min; i++) {
+ res += Long.bitCount(x[i] | y[i]);
+ }
+ for(; i < lx; i++) {
+ res += Long.bitCount(x[i]);
+ }
+ for(; i < ly; i++) {
+ res += Long.bitCount(y[i]);
+ }
+ return res;
+ }
+
+ /**
+ * Compute the Hamming distance (Size of symmetric difference), i.e.
+ * {@code cardinality(a ^ b)}.
+ *
+ * @param b1 First vector
+ * @param b2 Second vector
+ * @return Cardinality of symmetric difference
+ */
+ public static int hammingDistance(long b1, long b2) {
+ return Long.bitCount(b1 ^ b2);
+ }
+
+ /**
+ * Compute the Hamming distance (Size of symmetric difference), i.e.
+ * {@code cardinality(a ^ b)}.
+ *
+ * @param x First vector
+ * @param y Second vector
+ * @return Cardinality of symmetric difference
+ */
+ public static int hammingDistance(long[] x, long[] y) {
+ final int lx = x.length, ly = y.length;
+ final int min = (lx < ly) ? lx : ly;
+ int i = 0, h = 0;
+ for(; i < min; i++) {
+ h += Long.bitCount(x[i] ^ y[i]);
+ }
+ for(; i < lx; i++) {
+ h += Long.bitCount(x[i]);
+ }
+ for(; i < ly; i++) {
+ h += Long.bitCount(y[i]);
+ }
+ return h;
+ }
+
+ /**
* Capacity of the vector v.
*
* @param v Vector v
@@ -1146,6 +1557,36 @@ public final class BitsUtil {
}
/**
+ * Test two bitsets for equality
+ *
+ * @param x First bitset
+ * @param y Second bitset
+ * @return {@code true} when the bitsets are equal
+ */
+ public static boolean equal(long[] x, long[] y) {
+ if(x == null || y == null) {
+ return (x == null) && (y == null);
+ }
+ int p = Math.min(x.length, y.length) - 1;
+ for(int i = x.length - 1; i > p; i--) {
+ if(x[i] != 0L) {
+ return false;
+ }
+ }
+ for(int i = y.length - 1; i > p; i--) {
+ if(y[i] != 0L) {
+ return false;
+ }
+ }
+ for(; p >= 0; p--) {
+ if(x[p] != y[p]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
* Compare two bitsets.
*
* @param x First bitset
@@ -1153,31 +1594,40 @@ public final class BitsUtil {
* @return Comparison result
*/
public static int compare(long[] x, long[] y) {
+ if(x == null) {
+ return (y == null) ? 0 : -1;
+ }
+ if(y == null) {
+ return +1;
+ }
int p = Math.min(x.length, y.length) - 1;
- for (int i = x.length - 1; i > p; i--) {
- if (x[i] != 0) {
+ for(int i = x.length - 1; i > p; i--) {
+ if(x[i] != 0) {
return +1;
}
}
- for (int i = y.length - 1; i > p; i--) {
- if (y[i] != 0) {
+ for(int i = y.length - 1; i > p; i--) {
+ if(y[i] != 0) {
return -1;
}
}
- for (; p >= 0; p--) {
+ for(; p >= 0; p--) {
final long xp = x[p];
final long yp = y[p];
- if (xp != yp) {
- if (xp < 0) {
- if (yp < 0) {
+ if(xp != yp) {
+ if(xp < 0) {
+ if(yp < 0) {
return (yp < xp) ? -1 : ((yp == xp) ? 0 : 1);
- } else {
+ }
+ else {
return +1;
}
- } else {
- if (yp < 0) {
+ }
+ else {
+ if(yp < 0) {
return -1;
- } else {
+ }
+ else {
return (xp < yp) ? -1 : ((xp == yp) ? 0 : 1);
}
}
@@ -1186,25 +1636,63 @@ public final class BitsUtil {
return 0;
}
+ /**
+ * Compute a hash code for the given bitset.
+ *
+ * @param x Bitset bitset
+ * @return Hash code
+ */
+ public static int hashCode(long x) {
+ // We use almost the same hash code function as Java BitSet.
+ // Optimized for speed only, not protected against collision attacks
+ // If you need that, consider using murmur hashing with custom seeds.
+ long hash = 0x76543210L ^ x;
+ return (int) ((hash >> 32) ^ hash);
+ }
+
+ /**
+ * Compute a hash code for the given bitset.
+ *
+ * @param x Bitset bitset
+ * @return Hash code
+ */
+ public static int hashCode(long[] x) {
+ // We use almost the same hash code function as Java BitSet.
+ // Optimized for speed only, not protected against collision attacks
+ // If you need that, consider using murmur hashing with custom seeds.
+ long hash = 0x76543210L;
+ for(int i = 0; i < x.length;) {
+ hash ^= x[i] * ++i;
+ }
+ return (int) ((hash >> 32) ^ hash);
+ }
+
+ /**
+ * Compute <code>m * pow(2., n)</code> using bit operations.
+ *
+ * @param m Mantissa
+ * @param n Exponent
+ * @return Double value
+ */
public static double lpow2(long m, int n) {
- if (m == 0) {
+ if(m == 0) {
return 0.0;
}
- if (m == Long.MIN_VALUE) {
+ if(m == Long.MIN_VALUE) {
return lpow2(Long.MIN_VALUE >> 1, n + 1);
}
- if (m < 0) {
+ if(m < 0) {
return -lpow2(-m, n);
}
- assert(m >= 0);
+ assert (m >= 0);
int bitLength = magnitude(m);
int shift = bitLength - 53;
long exp = 1023L + 52 + n + shift; // Use long to avoid overflow.
- if (exp >= 0x7FF) {
+ if(exp >= 0x7FF) {
return Double.POSITIVE_INFINITY;
}
- if (exp <= 0) { // Degenerated number (subnormal, assume 0 for bit 52)
- if (exp <= -54) {
+ if(exp <= 0) { // Degenerated number (subnormal, assume 0 for bit 52)
+ if(exp <= -54) {
return 0.0;
}
return lpow2(m, n + 54) / 18014398509481984L; // 2^54 Exact.
@@ -1212,7 +1700,7 @@ public final class BitsUtil {
// Normal number.
long bits = (shift > 0) ? (m >> shift) + ((m >> (shift - 1)) & 1) : // Rounding.
m << -shift;
- if (((bits >> 52) != 1) && (++exp >= 0x7FF)) {
+ if(((bits >> 52) != 1) && (++exp >= 0x7FF)) {
return Double.POSITIVE_INFINITY;
}
bits &= 0x000fffffffffffffL; // Clears MSB (bit 52)
@@ -1229,17 +1717,17 @@ public final class BitsUtil {
* @return Double value.
*/
public static double lpow10(long m, int n) {
- if (m == 0) {
+ if(m == 0) {
return 0.0;
}
- if (m == Long.MIN_VALUE) {
+ if(m == Long.MIN_VALUE) {
return lpow10(Long.MIN_VALUE / 10, n + 1);
}
- if (m < 0) {
+ if(m < 0) {
return -lpow10(-m, n);
}
- if (n >= 0) { // Positive power.
- if (n > 308) {
+ if(n >= 0) { // Positive power.
+ if(n > 308) {
return Double.POSITIVE_INFINITY;
}
// Works with 4 x 32 bits registers (x3:x2:x1:x0)
@@ -1248,14 +1736,14 @@ public final class BitsUtil {
long x2 = m & LONG_32_BITS; // 32 bits.
long x3 = m >>> 32; // 32 bits.
int pow2 = 0;
- while (n != 0) {
+ while(n != 0) {
int i = (n >= POW5_INT.length) ? POW5_INT.length - 1 : n;
int coef = POW5_INT[i]; // 31 bits max.
- if (((int) x0) != 0) {
+ if(((int) x0) != 0) {
x0 *= coef; // 63 bits max.
}
- if (((int) x1) != 0) {
+ if(((int) x1) != 0) {
x1 *= coef; // 63 bits max.
}
x2 *= coef; // 63 bits max.
@@ -1276,7 +1764,7 @@ public final class BitsUtil {
// Normalizes (x3 should be 32 bits max).
long carry = x3 >>> 32;
- if (carry != 0) { // Shift.
+ if(carry != 0) { // Shift.
x0 = x1;
x1 = x2;
x2 = x3 & LONG_32_BITS;
@@ -1286,14 +1774,15 @@ public final class BitsUtil {
}
// Merges registers to a 63 bits mantissa.
- assert(x3 >= 0);
+ assert (x3 >= 0);
int shift = 31 - magnitude(x3); // -1..30
pow2 -= shift;
long mantissa = (shift < 0) ? (x3 << 31) | (x2 >>> 1) : // x3 is 32 bits.
(((x3 << 32) | x2) << shift) | (x1 >>> (32 - shift));
return lpow2(mantissa, pow2);
- } else { // n < 0
- if (n < -324 - 20) {
+ }
+ else { // n < 0
+ if(n < -324 - 20) {
return 0.;
}
@@ -1301,9 +1790,9 @@ public final class BitsUtil {
long x1 = m; // 63 bits.
long x0 = 0; // 63 bits.
int pow2 = 0;
- while (true) {
+ while(true) {
// Normalizes x1:x0
- assert(x1 >= 0);
+ assert (x1 >= 0);
int shift = 63 - magnitude(x1);
x1 <<= shift;
x1 |= x0 >>> (63 - shift);
@@ -1311,7 +1800,7 @@ public final class BitsUtil {
pow2 -= shift;
// Checks if division has to be performed.
- if (n == 0) {
+ if(n == 0) {
break; // Done.
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ClassGenericsUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/ClassGenericsUtil.java
index a60bf15f..f1d7304e 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/ClassGenericsUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/ClassGenericsUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities;
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,6 +34,7 @@ import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -106,17 +107,22 @@ public final class ClassGenericsUtil {
try {
try {
instance = type.cast(loader.loadClass(className).newInstance());
- } catch (ClassNotFoundException e) {
+ }
+ catch(ClassNotFoundException e) {
// try package of type
instance = type.cast(loader.loadClass(type.getPackage().getName() + "." + className).newInstance());
}
- } catch (InstantiationException e) {
+ }
+ catch(InstantiationException e) {
throw new UnableToComplyException(e);
- } catch (IllegalAccessException e) {
+ }
+ catch(IllegalAccessException e) {
throw new UnableToComplyException(e);
- } catch (ClassNotFoundException e) {
+ }
+ catch(ClassNotFoundException e) {
throw new UnableToComplyException(e);
- } catch (ClassCastException e) {
+ }
+ catch(ClassCastException e) {
throw new UnableToComplyException(e);
}
return instance;
@@ -152,17 +158,22 @@ public final class ClassGenericsUtil {
try {
try {
instance = ((Class<T>) type).cast(loader.loadClass(className).newInstance());
- } catch (ClassNotFoundException e) {
+ }
+ catch(ClassNotFoundException e) {
// try package of type
instance = ((Class<T>) type).cast(loader.loadClass(type.getPackage().getName() + "." + className).newInstance());
}
- } catch (InstantiationException e) {
+ }
+ catch(InstantiationException e) {
throw new UnableToComplyException(e);
- } catch (IllegalAccessException e) {
+ }
+ catch(IllegalAccessException e) {
throw new UnableToComplyException(e);
- } catch (ClassNotFoundException e) {
+ }
+ catch(ClassNotFoundException e) {
throw new UnableToComplyException(e);
- } catch (ClassCastException e) {
+ }
+ catch(ClassCastException e) {
throw new UnableToComplyException(e);
}
return instance;
@@ -183,13 +194,13 @@ public final class ClassGenericsUtil {
*/
public static <C> Method getParameterizationFactoryMethod(Class<C> c, Class<?> ret) throws NoSuchMethodException {
Method m = c.getMethod(FACTORY_METHOD_NAME, Parameterization.class);
- if (m == null) {
+ if(m == null) {
throw new NoSuchMethodException("No parameterization method found.");
}
- if (!ret.isAssignableFrom(m.getReturnType())) {
+ if(!ret.isAssignableFrom(m.getReturnType())) {
throw new NoSuchMethodException("Return type doesn't match: " + m.getReturnType().getName() + ", expected: " + ret.getName());
}
- if (!java.lang.reflect.Modifier.isStatic(m.getModifiers())) {
+ if(!java.lang.reflect.Modifier.isStatic(m.getModifiers())) {
throw new NoSuchMethodException("Factory method is not static.");
}
return m;
@@ -202,11 +213,12 @@ public final class ClassGenericsUtil {
* @return Parameterizer or null.
*/
public static Parameterizer getParameterizer(Class<?> c) {
- for (Class<?> inner : c.getDeclaredClasses()) {
- if (Parameterizer.class.isAssignableFrom(inner)) {
+ for(Class<?> inner : c.getDeclaredClasses()) {
+ if(Parameterizer.class.isAssignableFrom(inner)) {
try {
return inner.asSubclass(Parameterizer.class).newInstance();
- } catch (Exception e) {
+ }
+ catch(Exception e) {
LOG.warning("Non-usable Parameterizer in class: " + c.getName());
}
}
@@ -229,14 +241,14 @@ public final class ClassGenericsUtil {
* @throws Exception when other instantiation errors occurred
*/
public static <C> C tryInstantiate(Class<C> r, Class<?> c, Parameterization config) throws InvocationTargetException, NoSuchMethodException, Exception {
- if (c == null) {
+ if(c == null) {
// TODO: better class? AbortException maybe?
throw new UnsupportedOperationException("Trying to instantiate 'null' class!");
}
// Try a V3 parameterization class
Parameterizer par = getParameterizer(c);
// TODO: API good?
- if (par instanceof AbstractParameterizer) {
+ if(par instanceof AbstractParameterizer) {
final Object instance = ((AbstractParameterizer) par).make(config);
return r.cast(instance);
}
@@ -245,7 +257,8 @@ public final class ClassGenericsUtil {
final Method factory = getParameterizationFactoryMethod(c, r);
final Object instance = factory.invoke(null, config);
return r.cast(instance);
- } catch (NoSuchMethodException e) {
+ }
+ catch(NoSuchMethodException e) {
// continue.
}
// Try a regular "parameterization" constructor
@@ -253,7 +266,8 @@ public final class ClassGenericsUtil {
final Constructor<?> constructor = c.getConstructor(Parameterization.class);
final Object instance = constructor.newInstance(config);
return r.cast(instance);
- } catch (NoSuchMethodException e) {
+ }
+ catch(NoSuchMethodException e) {
// continue
}
// Try a default constructor.
@@ -275,8 +289,18 @@ public final class ClassGenericsUtil {
@SuppressWarnings("unchecked")
public static <C> C parameterizeOrAbort(Class<?> c, Parameterization config) {
try {
- return tryInstantiate((Class<C>) c, c, config);
- } catch (Exception e) {
+ C ret = tryInstantiate((Class<C>) c, c, config);
+ if(ret == null) {
+ throw new AbortException("Could not instantiate class. Check parameters.");
+ }
+ return ret;
+ }
+ catch(Exception e) {
+ if (config.hasErrors()) {
+ for (ParameterException err : config.getErrors()) {
+ LOG.warning(err.toString());
+ }
+ }
throw new AbortException("Instantiation failed", e);
}
}
@@ -324,7 +348,7 @@ public final class ClassGenericsUtil {
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T> ArrayList<T>[] newArrayOfEmptyArrayList(int len) {
ArrayList[] result = new ArrayList[len];
- for (int i = 0; i < len; i++) {
+ for(int i = 0; i < len; i++) {
result[i] = new ArrayList<>();
}
return result;
@@ -343,7 +367,7 @@ public final class ClassGenericsUtil {
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T> HashSet<T>[] newArrayOfEmptyHashSet(int len) {
HashSet[] result = new HashSet[len];
- for (int i = 0; i < len; i++) {
+ for(int i = 0; i < len; i++) {
result[i] = new HashSet<>();
}
return result;
@@ -398,8 +422,8 @@ public final class ClassGenericsUtil {
*/
@SuppressWarnings("unchecked")
public static <BASE, FROM extends BASE, TO extends BASE> Class<TO> uglyCrossCast(Class<FROM> cls, Class<BASE> base) {
- if (!base.isAssignableFrom(cls)) {
- if (cls == null) {
+ if(!base.isAssignableFrom(cls)) {
+ if(cls == null) {
throw new ClassCastException("Attempted to use 'null' as class.");
}
throw new ClassCastException(cls.getName() + " is not a superclass of " + base);
@@ -424,7 +448,8 @@ public final class ClassGenericsUtil {
public static <B, T extends B> T castWithGenericsOrNull(Class<B> base, Object obj) {
try {
return (T) base.cast(obj);
- } catch (ClassCastException e) {
+ }
+ catch(ClassCastException e) {
return null;
}
}
@@ -445,7 +470,8 @@ public final class ClassGenericsUtil {
try {
Object n = obj.getClass().getConstructor().newInstance();
return (T) n;
- } catch (NullPointerException e) {
+ }
+ catch(NullPointerException e) {
throw new IllegalArgumentException("Null pointer exception in newInstance()", e);
}
}
@@ -473,7 +499,7 @@ public final class ClassGenericsUtil {
*/
@SuppressWarnings("unchecked")
public static <T> T[] newArray(Class<? extends T> k, int size) {
- if (k.isPrimitive()) {
+ if(k.isPrimitive()) {
throw new IllegalArgumentException("Argument cannot be primitive: " + k);
}
Object a = java.lang.reflect.Array.newInstance(k, size);
@@ -505,13 +531,17 @@ public final class ClassGenericsUtil {
C copy = newInstance(coll);
copy.addAll(coll);
return copy;
- } catch (InstantiationException e) {
+ }
+ catch(InstantiationException e) {
throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
+ }
+ catch(IllegalAccessException e) {
throw new RuntimeException(e);
- } catch (InvocationTargetException e) {
+ }
+ catch(InvocationTargetException e) {
throw new RuntimeException(e);
- } catch (NoSuchMethodException e) {
+ }
+ catch(NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
@@ -525,15 +555,15 @@ public final class ClassGenericsUtil {
* @return new array containing the collection elements
*/
public static <T> T[] collectionToArray(Collection<T> c, T[] a) {
- if (a.length < c.size()) {
+ if(a.length < c.size()) {
a = newArray(a, c.size());
}
int i = 0;
- for (T x : c) {
+ for(T x : c) {
a[i] = x;
i++;
}
- if (i < a.length) {
+ if(i < a.length) {
a[i] = null;
}
return a;
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/DatabaseUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/DatabaseUtil.java
index baa90829..110b5bad 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/DatabaseUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/DatabaseUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities;
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,44 +23,32 @@ package de.lmu.ifi.dbs.elki.utilities;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.AbstractCollection;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.regex.Pattern;
import de.lmu.ifi.dbs.elki.data.ClassLabel;
-import de.lmu.ifi.dbs.elki.data.FeatureVector;
import de.lmu.ifi.dbs.elki.data.LabelList;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.NoSupportedDataTypeException;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
-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.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
+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.query.knn.PreprocessorKNNQuery;
import de.lmu.ifi.dbs.elki.database.relation.ConvertToStringView;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNPreprocessor;
/**
* Class with Database-related utility functions such as centroid computation,
* covariances etc.
*
* @author Erich Schubert
- *
- * @apiviz.landmark
- *
- * @apiviz.has RelationObjectIterator
- * @apiviz.has CollectionFromRelation
*/
public final class DatabaseUtil {
/**
@@ -69,124 +57,6 @@ public final class DatabaseUtil {
private DatabaseUtil() {
// Do not instantiate!
}
-
- /**
- * Get the dimensionality of a relation.
- *
- * @param relation Relation
- * @return Dimensionality
- *
- * @deprecated Use {@link RelationUtil#dimensionality(Relation)} instead!
- */
- @Deprecated
- public static <V extends FeatureVector<?>> int dimensionality(Relation<V> relation) {
- return RelationUtil.dimensionality(relation);
- }
-
- /**
- * Determines the variances in each dimension of the specified objects stored
- * in the given database.
- *
- * @param database the database storing the objects
- * @param ids the ids of the objects
- * @param centroid the centroid or reference vector of the ids
- * @return the variances in each dimension of the specified objects
- */
- public static double[] variances(Relation<? extends NumberVector<?>> database, NumberVector<?> centroid, DBIDs ids) {
- final int size = ids.size();
- double[] variances = new double[centroid.getDimensionality()];
-
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- NumberVector<?> o = database.get(iter);
- for (int d = 0; d < centroid.getDimensionality(); d++) {
- final double diff = o.doubleValue(d) - centroid.doubleValue(d);
- variances[d ] += diff * diff / size;
- }
- }
- return variances;
- }
-
- /**
- * Determines the minimum and maximum values in each dimension of all objects
- * stored in the given database.
- *
- * @param <NV> vector type
- * @param relation the database storing the objects
- * @return Minimum and Maximum vector for the hyperrectangle
- */
- public static <NV extends NumberVector<?>> Pair<NV, NV> computeMinMax(Relation<NV> relation) {
- int dim = RelationUtil.dimensionality(relation);
- double[] mins = new double[dim];
- double[] maxs = new double[dim];
- for (int i = 0; i < dim; i++) {
- mins[i] = Double.MAX_VALUE;
- maxs[i] = -Double.MAX_VALUE;
- }
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- final NV o = relation.get(iditer);
- for (int d = 0; d < dim; d++) {
- final double v = o.doubleValue(d);
- mins[d] = Math.min(mins[d], v);
- maxs[d] = Math.max(maxs[d], v);
- }
- }
- NumberVector.Factory<NV, ?> factory = RelationUtil.getNumberVectorFactory(relation);
- NV min = factory.newNumberVector(mins);
- NV max = factory.newNumberVector(maxs);
- return new Pair<>(min, max);
- }
-
- /**
- * Returns the median of a data set in the given dimension by using a sampling
- * method.
- *
- * @param relation Relation to process
- * @param ids DBIDs to process
- * @param dimension Dimensionality
- * @param numberOfSamples Number of samples to draw
- * @return Median value
- */
- public static <V extends NumberVector<?>> double quickMedian(Relation<V> relation, ArrayDBIDs ids, int dimension, int numberOfSamples) {
- final int everyNthItem = (int) Math.max(1, Math.floor(ids.size() / (double) numberOfSamples));
- final double[] vals = new double[numberOfSamples];
- for (int i = 0; i < numberOfSamples; i++) {
- final DBID id = ids.get(i * everyNthItem);
- vals[i] = relation.get(id).doubleValue(dimension);
- }
- Arrays.sort(vals);
- if (vals.length % 2 == 1) {
- return vals[((vals.length + 1) >> 1) - 1];
- } else {
- final double v1 = vals[vals.length >> 1];
- final double v2 = vals[(vals.length >> 1) - 1];
- return (v1 + v2) / 2.0;
- }
- }
-
- /**
- * Returns the median of a data set in the given dimension.
- *
- * @param relation Relation to process
- * @param ids DBIDs to process
- * @param dimension Dimensionality
- * @return Median value
- */
- public static <V extends NumberVector<?>> double exactMedian(Relation<V> relation, DBIDs ids, int dimension) {
- final double[] vals = new double[ids.size()];
- int i = 0;
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- vals[i] = relation.get(iter).doubleValue(dimension);
- i++;
- }
- Arrays.sort(vals);
- if (vals.length % 2 == 1) {
- return vals[((vals.length + 1) >> 1) - 1];
- } else {
- final double v1 = vals[vals.length >> 1];
- final double v2 = vals[(vals.length >> 1) - 1];
- return (v1 + v2) / 2.0;
- }
- }
/**
* Guess a potentially label-like representation, preferring class labels.
@@ -197,26 +67,29 @@ public final class DatabaseUtil {
public static Relation<String> guessLabelRepresentation(Database database) throws NoSupportedDataTypeException {
try {
Relation<? extends ClassLabel> classrep = database.getRelation(TypeUtil.CLASSLABEL);
- if (classrep != null) {
+ if(classrep != null) {
return new ConvertToStringView(classrep);
}
- } catch (NoSupportedDataTypeException e) {
+ }
+ catch(NoSupportedDataTypeException e) {
// retry.
}
try {
Relation<? extends LabelList> labelsrep = database.getRelation(TypeUtil.LABELLIST);
- if (labelsrep != null) {
+ if(labelsrep != null) {
return new ConvertToStringView(labelsrep);
}
- } catch (NoSupportedDataTypeException e) {
+ }
+ catch(NoSupportedDataTypeException e) {
// retry.
}
try {
Relation<String> stringrep = database.getRelation(TypeUtil.STRING);
- if (stringrep != null) {
+ if(stringrep != null) {
return stringrep;
}
- } catch (NoSupportedDataTypeException e) {
+ }
+ catch(NoSupportedDataTypeException e) {
// retry.
}
throw new NoSupportedDataTypeException("No label-like representation was found.");
@@ -231,26 +104,29 @@ public final class DatabaseUtil {
public static Relation<String> guessObjectLabelRepresentation(Database database) throws NoSupportedDataTypeException {
try {
Relation<? extends LabelList> labelsrep = database.getRelation(TypeUtil.LABELLIST);
- if (labelsrep != null) {
+ if(labelsrep != null) {
return new ConvertToStringView(labelsrep);
}
- } catch (NoSupportedDataTypeException e) {
+ }
+ catch(NoSupportedDataTypeException e) {
// retry.
}
try {
Relation<String> stringrep = database.getRelation(TypeUtil.STRING);
- if (stringrep != null) {
+ if(stringrep != null) {
return stringrep;
}
- } catch (NoSupportedDataTypeException e) {
+ }
+ catch(NoSupportedDataTypeException e) {
// retry.
}
try {
Relation<? extends ClassLabel> classrep = database.getRelation(TypeUtil.CLASSLABEL);
- if (classrep != null) {
+ if(classrep != null) {
return new ConvertToStringView(classrep);
}
- } catch (NoSupportedDataTypeException e) {
+ }
+ catch(NoSupportedDataTypeException e) {
// retry.
}
throw new NoSupportedDataTypeException("No label-like representation was found.");
@@ -265,7 +141,7 @@ public final class DatabaseUtil {
*/
public static SortedSet<ClassLabel> getClassLabels(Relation<? extends ClassLabel> database) {
SortedSet<ClassLabel> labels = new TreeSet<>();
- for (DBIDIter it = database.iterDBIDs(); it.valid(); it.advance()) {
+ for(DBIDIter it = database.iterDBIDs(); it.valid(); it.advance()) {
labels.add(database.get(it));
}
return labels;
@@ -284,83 +160,6 @@ public final class DatabaseUtil {
}
/**
- * Do a cheap guess at the databases object class.
- *
- * @param <O> Restriction type
- * @param database Database
- * @return Class of first object in the Database.
- */
- @SuppressWarnings("unchecked")
- public static <O> Class<? extends O> guessObjectClass(Relation<O> database) {
- return (Class<? extends O>) database.get(database.iterDBIDs()).getClass();
- }
-
- /**
- * Do a full inspection of the database to find the base object class.
- *
- * Note: this can be an abstract class or interface!
- *
- * TODO: Implement a full search for shared superclasses. But since currently
- * the databases will always use only once class, this is not yet implemented.
- *
- * @param <O> Restriction type
- * @param database Database
- * @return Superclass of all objects in the database
- */
- public static <O> Class<?> getBaseObjectClassExpensive(Relation<O> database) {
- List<Class<?>> candidates = new ArrayList<>();
- DBIDIter iditer = database.iterDBIDs();
- // empty database?!
- if (!iditer.valid()) {
- return null;
- }
- // put first class into result set.
- candidates.add(database.get(iditer).getClass());
- iditer.advance();
- // other objects
- for (; iditer.valid(); iditer.advance()) {
- Class<?> newcls = database.get(iditer).getClass();
- // validate all candidates
- Iterator<Class<?>> ci = candidates.iterator();
- while (ci.hasNext()) {
- Class<?> cand = ci.next();
- if (cand.isAssignableFrom(newcls)) {
- continue;
- }
- // TODO: resolve conflicts by finding all superclasses!
- // Does this code here work?
- for (Class<?> interf : cand.getInterfaces()) {
- candidates.add(interf);
- }
- candidates.add(cand.getSuperclass());
- ci.remove();
- }
- }
- // if we have any candidates left ...
- if (candidates.size() > 0) {
- // remove subclasses
- Iterator<Class<?>> ci = candidates.iterator();
- while (ci.hasNext()) {
- Class<?> cand = ci.next();
- for (Class<?> oc : candidates) {
- if (!oc.equals(cand) && cand.isAssignableFrom(oc)) {
- ci.remove();
- break;
- }
- }
- }
- assert (candidates.size() > 0);
- try {
- return candidates.get(0);
- } catch (ClassCastException e) {
- // ignore, and retry with next
- }
- }
- // no resulting class.
- return null;
- }
-
- /**
* Find object by matching their labels.
*
* @param database Database to search in
@@ -369,12 +168,12 @@ public final class DatabaseUtil {
*/
public static ArrayModifiableDBIDs getObjectsByLabelMatch(Database database, Pattern name_pattern) {
Relation<String> relation = guessLabelRepresentation(database);
- if (name_pattern == null) {
+ if(name_pattern == null) {
return DBIDUtil.newArray();
}
ArrayModifiableDBIDs ret = DBIDUtil.newArray();
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- if (name_pattern.matcher(relation.get(iditer)).find()) {
+ for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ if(name_pattern.matcher(relation.get(iditer)).find()) {
ret.add(iditer);
}
}
@@ -382,104 +181,45 @@ public final class DatabaseUtil {
}
/**
- * An ugly vector type cast unavoidable in some situations due to Generics.
+ * Get (or create) a precomputed kNN query for the database.
*
- * @param <V> Base vector type
- * @param <T> Derived vector type (is actually V, too)
* @param database Database
- * @return Database
- */
- @SuppressWarnings("unchecked")
- public static <V extends NumberVector<?>, T extends NumberVector<?>> Relation<V> relationUglyVectorCast(Relation<T> database) {
- return (Relation<V>) database;
- }
-
- /**
- * Iterator class that retrieves the given objects from the database.
- *
- * @author Erich Schubert
+ * @param relation Relation
+ * @param dq Distance query
+ * @param k required number of neighbors
+ * @return KNNQuery for the given relation, that is precomputed.
*/
- public static class RelationObjectIterator<O> implements Iterator<O> {
- /**
- * The real iterator.
- */
- final DBIDIter iter;
-
- /**
- * The database we use.
- */
- final Relation<? extends O> database;
-
- /**
- * Full Constructor.
- *
- * @param iter Original iterator.
- * @param database Database
- */
- public RelationObjectIterator(DBIDIter iter, Relation<? extends O> database) {
- super();
- this.iter = iter;
- this.database = database;
- }
-
- /**
- * Simplified constructor.
- *
- * @param database Database
- */
- public RelationObjectIterator(Relation<? extends O> database) {
- super();
- this.database = database;
- this.iter = database.iterDBIDs();
- }
-
- @Override
- public boolean hasNext() {
- return iter.valid();
- }
-
- @Override
- public O next() {
- O ret = database.get(iter);
- iter.advance();
- return ret;
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
+ public static <O> KNNQuery<O> precomputedKNNQuery(Database database, Relation<O> relation, DistanceQuery<O> dq, int k) {
+ // "HEAVY" flag for knn query since it is used more than once
+ KNNQuery<O> knnq = database.getKNNQuery(dq, k, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
+ // No optimized kNN query - use a preprocessor!
+ if(knnq instanceof PreprocessorKNNQuery) {
+ return knnq;
}
+ MaterializeKNNPreprocessor<O> preproc = new MaterializeKNNPreprocessor<>(relation, dq.getDistanceFunction(), k);
+ preproc.initialize();
+ return preproc.getKNNQuery(dq, k);
}
/**
- * Collection view on a database that retrieves the objects when needed.
+ * Get (or create) a precomputed kNN query for the database.
*
- * @author Erich Schubert
- */
- public static class CollectionFromRelation<O> extends AbstractCollection<O> implements Collection<O> {
- /**
- * The database we query.
- */
- Relation<? extends O> db;
-
- /**
- * Constructor.
- *
- * @param db Database
- */
- public CollectionFromRelation(Relation<? extends O> db) {
- super();
- this.db = db;
- }
-
- @Override
- public Iterator<O> iterator() {
- return new DatabaseUtil.RelationObjectIterator<>(db);
- }
-
- @Override
- public int size() {
- return db.size();
- }
+ * @param database Database
+ * @param relation Relation
+ * @param distf Distance function
+ * @param k required number of neighbors
+ * @return KNNQuery for the given relation, that is precomputed.
+ */
+ public static <O> KNNQuery<O> precomputedKNNQuery(Database database, Relation<O> relation, DistanceFunction<? super O> distf, int k) {
+ DistanceQuery<O> dq = database.getDistanceQuery(relation, distf);
+ // "HEAVY" flag for knn query since it is used more than once
+ KNNQuery<O> knnq = database.getKNNQuery(dq, k, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
+ // No optimized kNN query - use a preprocessor!
+ if(knnq instanceof PreprocessorKNNQuery) {
+ return knnq;
+ }
+ MaterializeKNNPreprocessor<O> preproc = new MaterializeKNNPreprocessor<>(relation, dq.getDistanceFunction(), k);
+ preproc.initialize();
+ return preproc.getKNNQuery(dq, k);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ELKIServiceLoader.java b/src/de/lmu/ifi/dbs/elki/utilities/ELKIServiceLoader.java
index d42b2834..ce40e988 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/ELKIServiceLoader.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/ELKIServiceLoader.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities;
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,6 +24,7 @@ package de.lmu.ifi.dbs.elki.utilities;
*/
import java.io.BufferedReader;
+import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
@@ -50,7 +51,7 @@ public class ELKIServiceLoader implements Iterator<Class<?>> {
/**
* Prefix for the ELKI functionality discovery.
*/
- public static final String PREFIX = "META-INF/elki/";
+ public static final String PREFIX = "META-INF" + File.separator + "elki" + File.separator;
/**
* Comment character
@@ -112,19 +113,20 @@ public class ELKIServiceLoader implements Iterator<Class<?>> {
try {
String fullName = PREFIX + parent.getName();
configfiles = cl.getResources(fullName);
- } catch (IOException x) {
+ }
+ catch(IOException x) {
throw new AbortException("Could not load service configuration files.", x);
}
}
@Override
public boolean hasNext() {
- if (nextclass != null) {
+ if(nextclass != null) {
return true;
}
// Find next iterator
- while ((curiter == null) || !curiter.hasNext()) {
- if (!configfiles.hasMoreElements()) {
+ while((curiter == null) || !curiter.hasNext()) {
+ if(!configfiles.hasMoreElements()) {
return false;
}
curiter = parseFile(configfiles.nextElement());
@@ -137,52 +139,55 @@ public class ELKIServiceLoader implements Iterator<Class<?>> {
ArrayList<Class<?>> classes = new ArrayList<>();
try {
BufferedReader r = new BufferedReader(new InputStreamReader(nextElement.openStream(), "utf-8"));
- while (parseLine(r.readLine(), classes, nextElement)) {
+ while(parseLine(r.readLine(), classes, nextElement)) {
// Continue
}
- } catch (IOException x) {
+ }
+ catch(IOException x) {
throw new AbortException("Error reading configuration file", x);
}
return classes.iterator();
}
private boolean parseLine(String line, ArrayList<Class<?>> classes, URL nextElement) {
- if (line == null) {
+ if(line == null) {
return false;
}
// Ignore comments, trim whitespace
{
int begin = 0;
int end = line.indexOf(COMMENT_CHAR);
- if (end < 0) {
+ if(end < 0) {
end = line.length();
}
- while (begin < end && line.charAt(begin) == ' ') {
+ while(begin < end && line.charAt(begin) == ' ') {
begin++;
}
- while (end - 1 > begin && line.charAt(end - 1) == ' ') {
+ while(end - 1 > begin && line.charAt(end - 1) == ' ') {
end--;
}
- if (begin > 0 || end < line.length()) {
+ if(begin > 0 || end < line.length()) {
line = line.substring(begin, end);
}
}
- if (line.length() <= 0) {
+ if(line.length() <= 0) {
return true; // Empty/comment lines are okay, continue
}
// Try to load the class
try {
Class<?> cls = cl.loadClass(line);
// Should not happen. Check anyway.
- if (cls == null) {
+ if(cls == null) {
return true;
}
- if (parent.isAssignableFrom(cls)) {
+ if(parent.isAssignableFrom(cls)) {
classes.add(cls);
- } else {
+ }
+ else {
LOG.warning("Class " + line + " does not implement " + parent + " but listed in service file " + nextElement);
}
- } catch (ClassNotFoundException e) {
+ }
+ catch(ClassNotFoundException e) {
LOG.warning("Class not found: " + line + "; listed in service file " + nextElement, e);
}
return true;
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/FileUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/FileUtil.java
index 5c3c78b5..63f842c4 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/FileUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/FileUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities;
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
@@ -68,11 +68,11 @@ public final class FileUtil {
* <code>null</code>
*/
public static String getFilenameExtension(String name) {
- if (name == null) {
+ if(name == null) {
return null;
}
int index = name.lastIndexOf('.');
- if (index >= name.length() - 1) {
+ if(index >= name.length() - 1) {
return null;
}
return name.substring(name.lastIndexOf('.') + 1).toLowerCase();
@@ -89,11 +89,12 @@ public final class FileUtil {
public static InputStream openSystemFile(String filename) throws FileNotFoundException {
try {
return new FileInputStream(filename);
- } catch (FileNotFoundException e) {
+ }
+ catch(FileNotFoundException e) {
// try with classloader
String resname = filename.replace(File.separatorChar, '/');
InputStream result = ClassLoader.getSystemResourceAsStream(resname);
- if (result == null) {
+ if(result == null) {
throw e;
}
return result;
@@ -111,25 +112,24 @@ public final class FileUtil {
*/
public static InputStream tryGzipInput(InputStream in) throws IOException {
// try autodetecting gzip compression.
- if (!in.markSupported()) {
+ if(!in.markSupported()) {
PushbackInputStream pb = new PushbackInputStream(in, 16);
in = pb;
// read a magic from the file header
byte[] magic = { 0, 0 };
pb.read(magic);
pb.unread(magic);
- if (magic[0] == 31 && magic[1] == -117) {
- in = new GZIPInputStream(pb);
- }
- } else {
- in.mark(16);
- if (in.read() == 31 && in.read() == -117) {
- in.reset();
- in = new GZIPInputStream(in);
- } else {
- // just rewind the stream
- in.reset();
+ if(magic[0] == 31 && magic[1] == -117) {
+ return new GZIPInputStream(pb);
}
+ return in;
+ }
+ // Mark is supported.
+ in.mark(16);
+ boolean isgzip = (in.read() == 31 && in.read() == -117);
+ in.reset(); // Rewind
+ if(isgzip) {
+ in = new GZIPInputStream(in);
}
return in;
}
@@ -144,24 +144,24 @@ public final class FileUtil {
public static File locateFile(String name, String basedir) {
// Try exact match first.
File f = new File(name);
- if (f.exists()) {
+ if(f.exists()) {
return f;
}
// Try with base directory
- if (basedir != null) {
+ if(basedir != null) {
f = new File(basedir, name);
// logger.warning("Trying: "+f.getAbsolutePath());
- if (f.exists()) {
+ if(f.exists()) {
return f;
}
}
// try stripping whitespace
{
String name2 = name.trim();
- if (!name.equals(name2)) {
+ if(!name.equals(name2)) {
// logger.warning("Trying without whitespace.");
f = locateFile(name2, basedir);
- if (f != null) {
+ if(f != null) {
return f;
}
}
@@ -169,27 +169,27 @@ public final class FileUtil {
// try substituting path separators
{
String name2 = name.replace('/', File.separatorChar);
- if (!name.equals(name2)) {
+ if(!name.equals(name2)) {
// logger.warning("Trying with replaced separators.");
f = locateFile(name2, basedir);
- if (f != null) {
+ if(f != null) {
return f;
}
}
name2 = name.replace('\\', File.separatorChar);
- if (!name.equals(name2)) {
+ if(!name.equals(name2)) {
// logger.warning("Trying with replaced separators.");
f = locateFile(name2, basedir);
- if (f != null) {
+ if(f != null) {
return f;
}
}
}
// try stripping extra characters, such as quotes.
- if (name.length() > 2 && name.charAt(0) == '"' && name.charAt(name.length() - 1) == '"') {
+ if(name.length() > 2 && name.charAt(0) == '"' && name.charAt(name.length() - 1) == '"') {
// logger.warning("Trying without quotes.");
f = locateFile(name.substring(1, name.length() - 1), basedir);
- if (f != null) {
+ if(f != null) {
return f;
}
}
@@ -207,7 +207,7 @@ public final class FileUtil {
public static String slurp(InputStream is) throws IOException {
StringBuilder buf = new StringBuilder();
final byte[] b = new byte[4096];
- for (int n; (n = is.read(b)) != -1;) {
+ for(int n; (n = is.read(b)) != -1;) {
buf.append(new String(b, 0, n));
}
is.close();
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/FormatUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/FormatUtil.java
index 4601cce9..2599a3a5 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/FormatUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/FormatUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities;
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,6 +30,7 @@ import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.Formatter;
+import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@@ -56,6 +57,11 @@ public final class FormatUtil {
public static final NumberFormat NF2 = NumberFormat.getInstance(Locale.US);
/**
+ * Number Formatter (3 digits) for output purposes.
+ */
+ public static final NumberFormat NF3 = NumberFormat.getInstance(Locale.US);
+
+ /**
* Number Formatter (4 digits) for output purposes.
*/
public static final NumberFormat NF4 = NumberFormat.getInstance(Locale.US);
@@ -80,6 +86,9 @@ public final class FormatUtil {
NF2.setMinimumFractionDigits(2);
NF2.setMaximumFractionDigits(2);
NF2.setGroupingUsed(false);
+ NF3.setMinimumFractionDigits(3);
+ NF3.setMaximumFractionDigits(3);
+ NF3.setGroupingUsed(false);
NF4.setMinimumFractionDigits(4);
NF4.setMaximumFractionDigits(4);
NF4.setGroupingUsed(false);
@@ -122,39 +131,34 @@ public final class FormatUtil {
private static final int[] TIME_UNIT_DIGITS = new int[] { 3, 2, 2, 2, 2 };
/**
- * Formats the double d with the specified fraction digits.
+ * Initialize a number format with ELKI standard options (US locale, no
+ * grouping).
*
- * @param d the double array to be formatted
- * @param digits the number of fraction digits
- * @return a String representing the double d
- */
- public static String format(final double d, int digits) {
+ * @param digits Number of digits to use
+ * @return Number format
+ */
+ public static NumberFormat makeNumberFormat(int digits) {
+ // Prefer predefined number formats where applicable.
+ // TODO: cache others, too?
+ switch(digits){
+ case 0:
+ return NF0;
+ case 2:
+ return NF2;
+ case 3:
+ return NF3;
+ case 4:
+ return NF4;
+ case 6:
+ return NF6;
+ case 8:
+ return NF8;
+ }
final NumberFormat nf = NumberFormat.getInstance(Locale.US);
nf.setMaximumFractionDigits(digits);
nf.setMinimumFractionDigits(digits);
nf.setGroupingUsed(false);
- return nf.format(d);
- }
-
- /**
- * Formats the double d with the specified number format.
- *
- * @param d the double array to be formatted
- * @param nf the number format to be used for formatting
- * @return a String representing the double d
- */
- public static String format(final double d, NumberFormat nf) {
- return nf.format(d);
- }
-
- /**
- * Formats the double d with 2 fraction digits.
- *
- * @param d the double to be formatted
- * @return a String representing the double d
- */
- public static String format(final double d) {
- return format(d, 2);
+ return nf;
}
/**
@@ -166,50 +170,37 @@ public final class FormatUtil {
* @return a String representing the double array d
*/
public static String format(double[] d, String sep) {
- StringBuilder buffer = new StringBuilder();
- for(int i = 0; i < d.length; i++) {
- if(i > 0) {
- buffer.append(sep).append(d[i]);
- }
- else {
- buffer.append(d[i]);
- }
+ if(d.length == 0) {
+ return "";
}
- return buffer.toString();
+ return formatTo(new StringBuilder(), d, sep).toString();
}
/**
- * Formats the double array d with the specified separator and the specified
- * fraction digits.
+ * Formats the double array d with the specified number format.
*
* @param d the double array to be formatted
- * @param sep the separator between the single values of the double array,
- * e.g. ','
- * @param digits the number of fraction digits
+ * @param nf the number format to be used for formatting
* @return a String representing the double array d
*/
- public static String format(double[] d, String sep, int digits) {
- StringBuilder buffer = new StringBuilder();
- for(int i = 0; i < d.length; i++) {
- if(i < d.length - 1) {
- buffer.append(format(d[i], digits)).append(sep);
- }
- else {
- buffer.append(format(d[i], digits));
- }
- }
- return buffer.toString();
+ public static String format(double[] d, NumberFormat nf) {
+ return format(d, " ", nf);
}
/**
* Formats the double array d with the specified number format.
*
* @param d the double array to be formatted
+ * @param sep the separator between the single values of the double array,
+ * e.g. ','
* @param nf the number format to be used for formatting
* @return a String representing the double array d
*/
- public static String format(double[] d, NumberFormat nf) {
- return format(d, " ", nf);
+ public static String format(double[] d, String sep, NumberFormat nf) {
+ if(d.length == 0) {
+ return "";
+ }
+ return formatTo(new StringBuilder(), d, sep, nf).toString();
}
/**
@@ -218,42 +209,49 @@ public final class FormatUtil {
* @param d the double array to be formatted
* @param sep the separator between the single values of the double array,
* e.g. ','
- * @param nf the number format to be used for formatting
* @return a String representing the double array d
*/
- public static String format(double[] d, String sep, NumberFormat nf) {
- StringBuilder buffer = new StringBuilder();
- for(int i = 0; i < d.length; i++) {
- if(i < d.length - 1) {
- buffer.append(format(d[i], nf)).append(sep);
- }
- else {
- buffer.append(format(d[i], nf));
- }
+ public static StringBuilder formatTo(StringBuilder a, double[] d, String sep) {
+ if(d.length == 0) {
+ return a;
}
- return buffer.toString();
+ a.append(d[0]);
+ for(int i = 1; i < d.length; i++) {
+ a.append(sep);
+ a.append(d[i]);
+ }
+ return a;
}
/**
- * Formats the double array d with ',' as separator and 2 fraction digits.
+ * Formats the double array d with the specified number format.
*
* @param d the double array to be formatted
+ * @param sep the separator between the single values of the double array,
+ * e.g. ','
+ * @param nf the number format to be used for formatting
* @return a String representing the double array d
*/
- public static String format(double[] d) {
- return format(d, ", ", 2);
+ public static StringBuilder formatTo(StringBuilder a, double[] d, String sep, NumberFormat nf) {
+ if(d.length == 0) {
+ return a;
+ }
+ a.append(nf.format(d[0]));
+ for(int i = 1; i < d.length; i++) {
+ a.append(sep);
+ a.append(nf.format(d[i]));
+ }
+ return a;
}
/**
- * Formats the double array d with ', ' as separator and with the specified
- * fraction digits.
+ * Formats the double array d with ', ' as separator and 2 fraction digits.
*
* @param d the double array to be formatted
- * @param digits the number of fraction digits
* @return a String representing the double array d
*/
- public static String format(double[] d, int digits) {
- return format(d, ", ", digits);
+ public static String format(double[] d) {
+ return formatTo(new StringBuilder(), d, ", ").toString();
}
/**
@@ -263,11 +261,7 @@ public final class FormatUtil {
* @return a String representing the double array d
*/
public static String format(double[][] d) {
- StringBuilder buffer = new StringBuilder();
- for(double[] array : d) {
- buffer.append(format(array, ", ", 2)).append('\n');
- }
- return buffer.toString();
+ return format(d, "\n", ", ", NF2);
}
/**
@@ -277,110 +271,40 @@ public final class FormatUtil {
* @param d the double array to be formatted
* @param sep1 the first separator of the outer array
* @param sep2 the second separator of the inner array
- * @param digits the number of fraction digits
+ * @param nf the number format to use
* @return a String representing the double array d
*/
- public static String format(double[][] d, String sep1, String sep2, int digits) {
- StringBuilder buffer = new StringBuilder();
-
- for(int i = 0; i < d.length; i++) {
- if(i < d.length - 1) {
- buffer.append(format(d[i], sep2, digits)).append(sep1);
- }
- else {
- buffer.append(format(d[i], sep2, digits));
- }
+ public static String format(double[][] d, String sep1, String sep2, NumberFormat nf) {
+ if(d.length == 0) {
+ return "";
}
-
- return buffer.toString();
- }
-
- /**
- * Formats the Double array f with the specified separator and the specified
- * fraction digits.
- *
- * @param f the Double array to be formatted
- * @param sep the separator between the single values of the Double array,
- * e.g. ','
- * @param digits the number of fraction digits
- * @return a String representing the Double array f
- */
- public static String format(Double[] f, String sep, int digits) {
StringBuilder buffer = new StringBuilder();
- for(int i = 0; i < f.length; i++) {
- if(i < f.length - 1) {
- buffer.append(format(f[i].doubleValue(), digits)).append(sep);
- }
- else {
- buffer.append(format(f[i].doubleValue(), digits));
- }
+ formatTo(buffer, d[0], sep2, nf);
+ for(int i = 1; i < d.length; i++) {
+ buffer.append(sep1);
+ formatTo(buffer, d[i], sep2, nf);
}
return buffer.toString();
}
/**
- * Formats the Double array f with ',' as separator and 2 fraction digits.
- *
- * @param f the Double array to be formatted
- * @return a String representing the Double array f
- */
- public static String format(Double[] f) {
- return format(f, ", ", 2);
- }
-
- /**
- * Formats the Double array f with the specified separator and the specified
- * fraction digits.
+ * Formats the double array d with the specified number format.
*
- * @param f the Double array to be formatted
- * @param sep the separator between the single values of the Double array,
+ * @param d the double array to be formatted
+ * @param sep the separator between the single values of the double array,
* e.g. ','
- * @param nf the number format
- * @return a String representing the Double array f
+ * @param nf the number format to be used for formatting
+ * @return a String representing the double array d
*/
- public static String format(Double[] f, String sep, NumberFormat nf) {
- StringBuilder buffer = new StringBuilder();
- for(int i = 0; i < f.length; i++) {
- if(i < f.length - 1) {
- buffer.append(format(f[i].doubleValue(), nf)).append(sep);
- }
- else {
- buffer.append(format(f[i].doubleValue(), nf));
- }
+ public static String format(float[] d, String sep, NumberFormat nf) {
+ if(d.length == 0) {
+ return "";
}
- return buffer.toString();
- }
-
- /**
- * Formats the Double array f with ',' as separator and 2 fraction digits.
- *
- * @param f the Double array to be formatted
- * @param nf the Number format
- * @return a String representing the Double array f
- */
- public static String format(Double[] f, NumberFormat nf) {
- return format(f, ", ", nf);
- }
-
- /**
- * Formats the float array f with the specified separator and the specified
- * fraction digits.
- *
- * @param f the float array to be formatted
- * @param sep the separator between the single values of the float array, e.g.
- * ','
- * @param digits the number of fraction digits
- * @return a String representing the float array f
- */
- public static String format(float[] f, String sep, int digits) {
StringBuilder buffer = new StringBuilder();
- for(int i = 0; i < f.length; i++) {
- if(i < f.length - 1) {
- buffer.append(format(f[i], digits)).append(sep);
- }
- else {
- buffer.append(format(f[i], digits));
- }
+ buffer.append(nf.format((double) d[0]));
+ for(int i = 1; i < d.length; i++) {
+ buffer.append(sep);
+ buffer.append(nf.format((double) d[i]));
}
return buffer.toString();
}
@@ -392,7 +316,7 @@ public final class FormatUtil {
* @return a String representing the float array f
*/
public static String format(float[] f) {
- return format(f, ", ", 2);
+ return format(f, ", ", NF2);
}
/**
@@ -404,14 +328,14 @@ public final class FormatUtil {
* @return a String representing the int array a
*/
public static String format(int[] a, String sep) {
+ if(a.length == 0) {
+ return "";
+ }
StringBuilder buffer = new StringBuilder();
- for(int i = 0; i < a.length; i++) {
- if(i < a.length - 1) {
- buffer.append(a[i]).append(sep);
- }
- else {
- buffer.append(a[i]);
- }
+ buffer.append(a[0]);
+ for(int i = 1; i < a.length; i++) {
+ buffer.append(sep);
+ buffer.append(a[i]);
}
return buffer.toString();
}
@@ -427,51 +351,20 @@ public final class FormatUtil {
}
/**
- * Formats the Integer array a for printing purposes.
- *
- * @param a the Integer array to be formatted
- * @param sep the separator between the single values of the float array, e.g.
- * ','
- * @return a String representing the Integer array a
- */
- public static String format(Integer[] a, String sep) {
- StringBuilder buffer = new StringBuilder();
- for(int i = 0; i < a.length; i++) {
- if(i < a.length - 1) {
- buffer.append(a[i]).append(sep);
- }
- else {
- buffer.append(a[i]);
- }
- }
- return buffer.toString();
- }
-
- /**
- * Formats the Integer array a for printing purposes.
- *
- * @param a the Integer array to be formatted
- * @return a String representing the Integer array a
- */
- public static String format(Integer[] a) {
- return format(a, ", ");
- }
-
- /**
* Formats the long array a for printing purposes.
*
* @param a the long array to be formatted
* @return a String representing the long array a
*/
public static String format(long[] a) {
+ if(a.length == 0) {
+ return "";
+ }
StringBuilder buffer = new StringBuilder();
- for(int i = 0; i < a.length; i++) {
- if(i < a.length - 1) {
- buffer.append(a[i]).append(", ");
- }
- else {
- buffer.append(a[i]);
- }
+ buffer.append(a[0]);
+ for(int i = 1; i < a.length; i++) {
+ buffer.append(", ");
+ buffer.append(a[i]);
}
return buffer.toString();
}
@@ -483,14 +376,14 @@ public final class FormatUtil {
* @return a String representing the byte array a
*/
public static String format(byte[] a) {
+ if(a.length == 0) {
+ return "";
+ }
StringBuilder buffer = new StringBuilder();
- for(int i = 0; i < a.length; i++) {
- if(i < a.length - 1) {
- buffer.append(a[i]).append(", ");
- }
- else {
- buffer.append(a[i]);
- }
+ buffer.append(a[0]);
+ for(int i = 1; i < a.length; i++) {
+ buffer.append(", ");
+ buffer.append(a[i]);
}
return buffer.toString();
}
@@ -504,14 +397,14 @@ public final class FormatUtil {
* @return a String representing the boolean array b
*/
public static String format(boolean[] b, final String sep) {
+ if(b.length == 0) {
+ return "";
+ }
StringBuilder buffer = new StringBuilder();
- for(int i = 0; i < b.length; i++) {
- if(i < b.length - 1) {
- buffer.append(format(b[i])).append(sep);
- }
- else {
- buffer.append(format(b[i]));
- }
+ buffer.append(format(b[0]));
+ for(int i = 1; i < b.length; i++) {
+ buffer.append(sep);
+ buffer.append(format(b[i]));
}
return buffer.toString();
}
@@ -523,10 +416,7 @@ public final class FormatUtil {
* @return a String representing of the boolean b
*/
public static String format(final boolean b) {
- if(b) {
- return "1";
- }
- return "0";
+ return b ? "1" : "0";
}
/**
@@ -539,19 +429,11 @@ public final class FormatUtil {
*/
public static String format(BitSet bitSet, int dim, String sep) {
StringBuilder msg = new StringBuilder();
-
- for(int d = 0; d < dim; d++) {
- if(d > 0) {
- msg.append(sep);
- }
- if(bitSet.get(d)) {
- msg.append('1');
- }
- else {
- msg.append('0');
- }
+ msg.append(bitSet.get(0) ? '1' : '0');
+ for(int d = 1; d < dim; d++) {
+ msg.append(sep);
+ msg.append(bitSet.get(d) ? '1' : '0');
}
-
return msg.toString();
}
@@ -583,13 +465,11 @@ public final class FormatUtil {
return d.iterator().next();
}
StringBuilder buffer = new StringBuilder();
- boolean first = true;
- for(String str : d) {
- if(!first) {
- buffer.append(sep);
- }
- buffer.append(str);
- first = false;
+ Iterator<String> it = d.iterator();
+ buffer.append(it.next());
+ while(it.hasNext()) {
+ buffer.append(sep);
+ buffer.append(it.next());
}
return buffer.toString();
}
@@ -745,7 +625,11 @@ public final class FormatUtil {
* given NumberFormat
*/
public static String format(Vector m, NumberFormat nf) {
- return "[" + FormatUtil.format(m.getArrayRef(), nf) + "]";
+ StringBuilder buf = new StringBuilder();
+ buf.append('[');
+ formatTo(buf, m.getArrayRef(), ", ", nf);
+ buf.append(']');
+ return buf.toString();
}
/**
@@ -754,7 +638,7 @@ public final class FormatUtil {
* @return String representation of this Vector
*/
public static String format(Vector m) {
- return format(m, FormatUtil.NF);
+ return format(m.getArrayRef());
}
/**
@@ -1025,6 +909,18 @@ public final class FormatUtil {
/**
* Preallocated exceptions.
*/
+ private static final NumberFormatException EMPTY_STRING = new NumberFormatException("Parser called on an empty string.") {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public synchronized Throwable fillInStackTrace() {
+ return this;
+ }
+ };
+
+ /**
+ * Preallocated exceptions.
+ */
private static final NumberFormatException EXPONENT_OVERFLOW = new NumberFormatException("Precision overflow for double exponent.") {
private static final long serialVersionUID = 1L;
@@ -1111,6 +1007,9 @@ public final class FormatUtil {
* @return Double value
*/
public static double parseDouble(final CharSequence str, final int start, final int end) {
+ if(start >= end) {
+ throw EMPTY_STRING;
+ }
// Current position and character.
int pos = start;
char cur = str.charAt(pos);
@@ -1165,7 +1064,7 @@ public final class FormatUtil {
// Reads exponent.
int exp = 0;
- if((pos < end) && ((cur == 'E') || (cur == 'e'))) {
+ if((pos + 1 < end) && ((cur == 'E') || (cur == 'e'))) {
cur = str.charAt(++pos);
final boolean isNegativeExp = (cur == '-');
if((isNegativeExp || (cur == '+')) && (++pos < end)) {
@@ -1211,6 +1110,122 @@ public final class FormatUtil {
}
/**
+ * Parse a double from a character sequence.
+ *
+ * In contrast to Javas {@link Double#parseDouble}, this will <em>not</em>
+ * create an object and thus is expected to put less load on the garbage
+ * collector. It will accept some more spellings of NaN and infinity, thus
+ * removing the need for checking for these independently.
+ *
+ * @param str String
+ * @param start Begin
+ * @param end End
+ * @return Double value
+ */
+ public static double parseDouble(final byte[] str, final int start, final int end) {
+ if(start >= end) {
+ throw EMPTY_STRING;
+ }
+ // Current position and character.
+ int pos = start;
+ byte cur = str[pos];
+
+ // Match for NaN spellings
+ if(matchNaN(str, cur, pos, end)) {
+ return Double.NaN;
+ }
+ // Match sign
+ boolean isNegative = (cur == '-');
+ // Carefully consume the - character, update c and i:
+ if((isNegative || (cur == '+')) && (++pos < end)) {
+ cur = str[pos];
+ }
+ if(matchInf(str, cur, pos, end)) {
+ return isNegative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
+ }
+
+ // Begin parsing real numbers!
+ if(((cur < '0') || (cur > '9')) && (cur != '.')) {
+ throw NOT_A_NUMBER;
+ }
+
+ // Parse digits into a long, remember offset of decimal point.
+ long decimal = 0;
+ int decimalPoint = -1;
+ while(true) {
+ final int digit = cur - '0';
+ if((digit >= 0) && (digit <= 9)) {
+ final long tmp = (decimal << 3) + (decimal << 1) + digit;
+ if((decimal > MAX_LONG_OVERFLOW) || (tmp < decimal)) {
+ throw PRECISION_OVERFLOW;
+ }
+ decimal = tmp;
+ }
+ else if((cur == '.') && (decimalPoint < 0)) {
+ decimalPoint = pos;
+ }
+ else { // No more digits, or a second dot.
+ break;
+ }
+ if(++pos < end) {
+ cur = str[pos];
+ }
+ else {
+ break;
+ }
+ }
+ // We need the offset from the back for adjusting the exponent:
+ // Note that we need the current value of i!
+ decimalPoint = (decimalPoint >= 0) ? pos - decimalPoint - 1 : 0;
+
+ // Reads exponent.
+ int exp = 0;
+ if((pos + 1 < end) && ((cur == 'E') || (cur == 'e'))) {
+ cur = str[++pos];
+ final boolean isNegativeExp = (cur == '-');
+ if((isNegativeExp || (cur == '+')) && (++pos < end)) {
+ cur = str[pos];
+ }
+ if((cur < '0') || (cur > '9')) { // At least one digit required.
+ throw INVALID_EXPONENT;
+ }
+ while(true) {
+ final int digit = cur - '0';
+ if((digit >= 0) && (digit < 10)) {
+ final int tmp = (exp << 3) + (exp << 1) + digit;
+ // Actually, double can only handle Double.MAX_EXPONENT? How about
+ // subnormal?
+ if((exp > MAX_INT_OVERFLOW) || (tmp < exp)) {
+ throw EXPONENT_OVERFLOW;
+ }
+ exp = tmp;
+ }
+ else {
+ break;
+ }
+ if(++pos < end) {
+ cur = str[pos];
+ }
+ else {
+ break;
+ }
+ }
+ if(isNegativeExp) {
+ exp = -exp;
+ }
+ }
+ // Adjust exponent by the offset of the dot in our long.
+ if(decimalPoint >= 0) {
+ exp = exp - decimalPoint;
+ }
+ if(pos != end) {
+ throw TRAILING_CHARACTERS;
+ }
+
+ return BitsUtil.lpow10(isNegative ? -decimal : decimal, exp);
+ }
+
+ /**
* Match "NaN" in a number of different capitalizations.
*
* @param str String to match
@@ -1243,6 +1258,38 @@ public final class FormatUtil {
}
/**
+ * Match "NaN" in a number of different capitalizations.
+ *
+ * @param str String to match
+ * @param firstchar First character
+ * @param start Interval begin
+ * @param end Interval end
+ * @return {@code true} when NaN was recognized.
+ */
+ private static boolean matchNaN(byte[] str, byte firstchar, int start, int end) {
+ final int len = end - start;
+ if(len < 2 || len > 3) {
+ return false;
+ }
+ if(firstchar != 'N' && firstchar != 'n') {
+ return false;
+ }
+ final byte c1 = str[start + 1];
+ if(c1 != 'a' && c1 != 'A') {
+ return false;
+ }
+ // Accept just "NA", too:
+ if(len == 2) {
+ return true;
+ }
+ final byte c2 = str[start + 2];
+ if(c2 != 'N' && c2 != 'n') {
+ return false;
+ }
+ return true;
+ }
+
+ /**
* Maximum long that we can process without overflowing.
*/
private static final long MAX_LONG_OVERFLOW = Long.MAX_VALUE / 10;
@@ -1297,6 +1344,40 @@ public final class FormatUtil {
}
/**
+ * Match "inf", "infinity" in a number of different capitalizations.
+ *
+ * @param str String to match
+ * @param firstchar First character
+ * @param start Interval begin
+ * @param end Interval end
+ * @return {@code true} when infinity was recognized.
+ */
+ private static boolean matchInf(byte[] str, byte firstchar, int start, int end) {
+ final int len = end - start;
+ // The wonders of unicode. This is more than one byte on UTF-8
+ if(len == 1 && firstchar == '∞') {
+ return true;
+ }
+ if(len != 3 && len != INFINITY_LENGTH) {
+ return false;
+ }
+ // Test beginning: "inf"
+ if(firstchar != 'I' && firstchar != 'i') {
+ return false;
+ }
+ for(int i = 1, j = INFINITY_LENGTH + 1; i < INFINITY_LENGTH; i++, j++) {
+ final byte c = str[start + i];
+ if(c != INFINITY_PATTERN[i] && c != INFINITY_PATTERN[j]) {
+ return false;
+ }
+ if(i == 2 && len == 3) {
+ return true;
+ }
+ }
+ return true;
+ }
+
+ /**
* Parse a long integer from a character sequence.
*
* @param str String
@@ -1348,4 +1429,143 @@ public final class FormatUtil {
return isNegative ? -decimal : decimal;
}
+
+ /**
+ * Format a boolean value as string "true" or "false".
+ *
+ * @param b Boolean to Format
+ * @param buf Buffer to append to
+ * @return Same buffer
+ */
+ public static StringBuilder format(boolean b, StringBuilder buf) {
+ return buf.append(b ? "true" : "false");
+ }
+
+ /**
+ * Format a boolean value as string "1" or "0".
+ *
+ * @param b Boolean to Format
+ * @param buf Buffer to append to
+ * @return Same buffer
+ */
+ public static StringBuilder formatBit(boolean b, StringBuilder buf) {
+ return buf.append(b ? '1' : '0');
+ }
+
+ /**
+ * Format an integer value as decimal.
+ *
+ * @param i Integer value to format.
+ * @param buf Buffer to append to
+ * @return Same buffer
+ */
+ public static StringBuilder format(int i, StringBuilder buf) {
+ // Int seems to be well optimized
+ return buf.append(i);
+ }
+
+ /**
+ * Format a long value as decimal.
+ *
+ * @param i Long value to format.
+ * @param buf Buffer to append to
+ * @return Same buffer
+ */
+ public static StringBuilder format(long i, StringBuilder buf) {
+ // Long seems to be well optimized
+ return buf.append(i);
+ }
+
+ /**
+ * Buffer for zero padding.
+ */
+ private static final char[] ZEROPADDING = new char[] { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' };
+
+ /**
+ * Buffer for whitespace padding.
+ */
+ private static final char[] SPACEPADDING = new char[] { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' };
+
+ /**
+ * Append zeros to a buffer.
+ *
+ * @param buf Buffer to append to
+ * @param zeros Number of zeros to append.
+ * @return Buffer
+ */
+ public static StringBuilder appendZeros(StringBuilder buf, int zeros) {
+ for(int i = zeros; i > 0; i -= ZEROPADDING.length) {
+ buf.append(ZEROPADDING, 0, i < ZEROPADDING.length ? i : ZEROPADDING.length);
+ }
+ return buf;
+ }
+
+ /**
+ * Append whitespace to a buffer.
+ *
+ * @param buf Buffer to append to
+ * @param spaces Number of spaces to append.
+ * @return Buffer
+ */
+ public static StringBuilder appendSpace(StringBuilder buf, int spaces) {
+ for(int i = spaces; i > 0; i -= SPACEPADDING.length) {
+ buf.append(SPACEPADDING, 0, i < SPACEPADDING.length ? i : SPACEPADDING.length);
+ }
+ return buf;
+ }
+
+ /**
+ * Compute the number of characters needed to represent the integer x.
+ *
+ * Reimplementation of {@link Long#stringSize}, but public and without loop.
+ *
+ * @param x Integer value
+ * @return Number of digits needed
+ */
+ public static int stringSize(int x) {
+ if(x < 0) {
+ // Avoid overflow on extreme negative
+ return (x == Integer.MIN_VALUE) ? 11 : stringSize(-x) + 1;
+ }
+ // This is almost a binary search - 10 cases is not a power of two, and we
+ // assume that the smaller values are more frequent.
+ return //
+ (x < 10000) ? // 1-4 vs. 5-10
+ /**/(x < 100) ? // 1-2 vs. 3-4
+ /* */((x < 10) ? 1 : 2) : //
+ /* */((x < 1000) ? 3 : 4) : //
+ /**/(x < 1000000) ? // 5-6 vs. 7-10
+ /* */((x < 100000) ? 5 : 6) : // 5-6
+ /* */(x < 100000000) ? // 7-8 vs. 9-10
+ /* */((x < 10000000) ? 7 : 8) : // 7-8
+ /* */((x < 1000000000) ? 9 : 10) // 9-10
+ ;
+ }
+
+ /**
+ * Compute the number of characters needed to represent the integer x.
+ *
+ * Reimplementation of {@link Long#stringSize}, but public and without loop.
+ *
+ * @param x Integer value
+ * @return Number of digits needed
+ */
+ public static int stringSize(long x) {
+ if(x < 0) {
+ // Avoid overflow on extreme negative
+ return (x == Long.MIN_VALUE) ? 20 : stringSize(-x) + 1;
+ }
+ // This is almost a binary search.
+ return (x <= Integer.MAX_VALUE) ? stringSize((int) x) : //
+ (x < 10000000000000L) ? // 10-13 vs. 14-19
+ /**/(x < 100000000000L) ? // 10-11 vs. 12-13
+ /* */((x < 10000000000L) ? 10 : 11) : //
+ /* */((x < 1000000000000L) ? 12 : 13) : //
+ /**/(x < 1000000000000000L) ? // 14-15 vs. 16-19
+ /* */((x < 100000000000000L) ? 14 : 15) : // 14-15
+ /* */(x < 100000000000000000L) ? // 16-17 vs. 18-19
+ /* */((x < 10000000000000000L) ? 16 : 17) : // 16-17
+ /* */((x < 1000000000000000000L) ? 18 : 19) // 18-19
+ ;
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/HandlerList.java b/src/de/lmu/ifi/dbs/elki/utilities/HandlerList.java
index fa17e04f..82d7703c 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/HandlerList.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/HandlerList.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities;
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/utilities/InspectionUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/InspectionUtil.java
index 29745335..856e5d3d 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/InspectionUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/InspectionUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities;
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,6 +30,7 @@ import java.io.IOException;
import java.lang.reflect.Modifier;
import java.net.URISyntaxException;
import java.net.URL;
+import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -55,7 +56,7 @@ public class InspectionUtil {
/**
* Class loader
*/
- private static final ClassLoader CLASSLOADER = ClassLoader.getSystemClassLoader();
+ private static final URLClassLoader CLASSLOADER = (URLClassLoader) ClassLoader.getSystemClassLoader();
/**
* Default package ignores.
@@ -83,28 +84,10 @@ public class InspectionUtil {
};
/**
- * If we have a non-static classpath, we do more extensive scanning for user
- * extensions.
- */
- public static final boolean NONSTATIC_CLASSPATH;
-
- /**
* Factory class postfix.
*/
public static final String FACTORY_POSTFIX = "$Factory";
- // Check for non-jar entries in classpath.
- static {
- String[] classpath = System.getProperty("java.class.path").split(System.getProperty("path.separator"));
- boolean hasnonstatic = false;
- for (String path : classpath) {
- if (!path.endsWith(".jar")) {
- hasnonstatic = true;
- }
- }
- NONSTATIC_CLASSPATH = hasnonstatic;
- }
-
/**
* Weak hash map for class lookups
*/
@@ -123,12 +106,12 @@ public class InspectionUtil {
* @return Found implementations
*/
public static List<Class<?>> cachedFindAllImplementations(Class<?> c) {
- if (c == null) {
+ if(c == null) {
return Collections.emptyList();
}
List<Class<?>> res = CLASS_CACHE.get(c);
- if (res == null) {
- res = findAllImplementations(c, false);
+ if(res == null) {
+ res = findAllImplementations(c, false, true);
CLASS_CACHE.put(c, res);
}
return res;
@@ -141,42 +124,61 @@ public class InspectionUtil {
*
* @param c Class restriction
* @param everything include interfaces, abstract and private classes
+ * @param parameterizable only return classes instantiable by the
+ * parameterizable API
* @return List of found classes.
*/
- public static List<Class<?>> findAllImplementations(Class<?> c, boolean everything) {
- ArrayList<Class<?>> list = new ArrayList<>();
+ public static List<Class<?>> findAllImplementations(Class<?> c, boolean everything, boolean parameterizable) {
+ // For removing duplicates:
+ THashSet<Class<?>> dupes = new THashSet<>();
+ ArrayList<Class<?>> known = new ArrayList<>();
// Add all from service files (i.e. jars)
{
Iterator<Class<?>> iter = new ELKIServiceLoader(c);
- while (iter.hasNext()) {
- list.add(iter.next());
+ while(iter.hasNext()) {
+ known.add(iter.next());
}
+ dupes.addAll(known);
+ }
+ // Build cache on first use:
+ if(MASTER_CACHE == null) {
+ MASTER_CACHE = slowScan();
}
- if (!InspectionUtil.NONSTATIC_CLASSPATH) {
- if (list.size() == 0) {
- LOG.warning("No implementations for " + c.getName() + " were found using index files.");
+ Iterator<Class<?>> iter = MASTER_CACHE.iterator();
+ while(iter.hasNext()) {
+ Class<?> cls = iter.next();
+ if(dupes.contains(cls)) {
+ continue;
}
- } else {
- // Duplicate checking
- THashSet<Class<?>> dupes = new THashSet<>(list);
- // Build cache on first use:
- if (MASTER_CACHE == null) {
- MASTER_CACHE = slowScan();
+ // skip abstract / private classes.
+ if(!everything && (Modifier.isInterface(cls.getModifiers()) || Modifier.isAbstract(cls.getModifiers()) || Modifier.isPrivate(cls.getModifiers()))) {
+ continue;
}
- Iterator<Class<?>> iter = MASTER_CACHE.iterator();
- while (iter.hasNext()) {
- Class<?> cls = iter.next();
- // skip abstract / private classes.
- if (!everything && (Modifier.isInterface(cls.getModifiers()) || Modifier.isAbstract(cls.getModifiers()) || Modifier.isPrivate(cls.getModifiers()))) {
- continue;
+ if(!c.isAssignableFrom(cls)) {
+ continue;
+ }
+ if(parameterizable) {
+ boolean instantiable = false;
+ try {
+ instantiable = cls.getConstructor() != null;
}
- if (c.isAssignableFrom(cls) && !dupes.contains(cls)) {
- list.add(cls);
- dupes.add(cls);
+ catch(Exception | Error e) {
+ // ignore
+ }
+ try {
+ instantiable = instantiable || ClassGenericsUtil.getParameterizer(cls) != null;
+ }
+ catch(Exception | Error e) {
+ // ignore
+ }
+ if(!instantiable) {
+ continue;
}
}
+ known.add(cls);
+ dupes.add(cls);
}
- return list;
+ return known;
}
/**
@@ -192,33 +194,37 @@ public class InspectionUtil {
// Try exact class factory first.
try {
return (Class<? extends C>) CLASSLOADER.loadClass(value + FACTORY_POSTFIX);
- } catch (ClassNotFoundException e) {
+ }
+ catch(ClassNotFoundException e) {
// Ignore, retry
}
try {
return (Class<? extends C>) CLASSLOADER.loadClass(value);
- } catch (ClassNotFoundException e) {
+ }
+ catch(ClassNotFoundException e) {
// Ignore, retry
}
final String completedName = restrictionClass.getPackage().getName() + "." + value;
// Try factory for guessed name next
try {
return (Class<? extends C>) CLASSLOADER.loadClass(completedName + FACTORY_POSTFIX);
- } catch (ClassNotFoundException e) {
+ }
+ catch(ClassNotFoundException e) {
// Ignore, retry
}
// Last try: guessed name prefix only
try {
return (Class<? extends C>) CLASSLOADER.loadClass(completedName);
- } catch (ClassNotFoundException e) {
+ }
+ catch(ClassNotFoundException e) {
// Ignore, retry
}
// Try aliases:
- for (Class<?> c : InspectionUtil.cachedFindAllImplementations(restrictionClass)) {
- if (c.isAnnotationPresent(Alias.class)) {
+ for(Class<?> c : InspectionUtil.cachedFindAllImplementations(restrictionClass)) {
+ if(c.isAnnotationPresent(Alias.class)) {
Alias aliases = c.getAnnotation(Alias.class);
- for (String alias : aliases.value()) {
- if (alias.equalsIgnoreCase(value) || alias.equalsIgnoreCase(completedName)) {
+ for(String alias : aliases.value()) {
+ if(alias.equalsIgnoreCase(value) || alias.equalsIgnoreCase(completedName)) {
return (Class<? extends C>) c;
}
}
@@ -234,43 +240,51 @@ public class InspectionUtil {
*/
private static List<Class<?>> slowScan() {
ArrayList<Class<?>> res = new ArrayList<>();
+ Enumeration<URL> cps;
try {
- Enumeration<URL> cps = CLASSLOADER.getResources("");
- while (cps.hasMoreElements()) {
- URL u = cps.nextElement();
- // Scan file sources only.
- if ("file".equals(u.getProtocol())) {
- File path;
+ cps = CLASSLOADER.getResources("");
+ }
+ catch(IOException e) {
+ de.lmu.ifi.dbs.elki.logging.LoggingUtil.exception(e);
+ return res;
+ }
+ while(cps.hasMoreElements()) {
+ URL u = cps.nextElement();
+ // Scan file sources only.
+ if("file".equals(u.getProtocol())) {
+ File path;
+ try {
+ path = new File(u.toURI());
+ }
+ catch(URISyntaxException e) {
+ LOG.exception("Error in classpath: " + u, e);
+ continue;
+ }
+ Iterator<String> it = new DirClassIterator(path, DEFAULT_IGNORES);
+ while(it.hasNext()) {
+ String classname = it.next();
try {
- path = new File(u.toURI());
- } catch (URISyntaxException e) {
- LOG.exception("Error in classpath: " + u, e);
- continue;
- }
- Iterator<String> it = new DirClassIterator(path, DEFAULT_IGNORES);
- while (it.hasNext()) {
- String classname = it.next();
- try {
- Class<?> cls = CLASSLOADER.loadClass(classname);
- // skip classes where we can't get a full name.
- if (cls.getCanonicalName() == null) {
- continue;
- }
- res.add(cls);
- } catch (ClassNotFoundException e) {
- continue;
- } catch (NoClassDefFoundError e) {
- continue;
- } catch (Exception e) {
- continue;
- } catch (Error e) {
+ Class<?> cls = CLASSLOADER.loadClass(classname);
+ // skip classes where we can't get a full name.
+ if(cls.getCanonicalName() == null) {
continue;
}
+ res.add(cls);
+ }
+ catch(ClassNotFoundException e) {
+ continue;
+ }
+ catch(NoClassDefFoundError e) {
+ continue;
+ }
+ catch(Exception e) {
+ continue;
+ }
+ catch(Error e) {
+ continue;
}
}
}
- } catch (IOException e) {
- LOG.exception(e);
}
Collections.sort(res, new ClassSorter());
return res;
@@ -306,7 +320,7 @@ public class InspectionUtil {
public DirClassIterator(File path, String[] ignorepackages) {
this.ignorepackages = ignorepackages;
this.prefix = path.getAbsolutePath();
- if (prefix.charAt(prefix.length() - 1) != File.separatorChar) {
+ if(prefix.charAt(prefix.length() - 1) != File.separatorChar) {
prefix = prefix + File.separatorChar;
}
@@ -315,7 +329,7 @@ public class InspectionUtil {
@Override
public boolean hasNext() {
- if (files.size() == 0) {
+ if(files.size() == 0) {
findNext();
}
return (files.size() > 0);
@@ -325,19 +339,19 @@ public class InspectionUtil {
* Find the next entry, since we need to skip some directories.
*/
private void findNext() {
- while (folders.size() > 0) {
+ while(folders.size() > 0) {
Pair<File, String> pair = folders.remove(folders.size() - 1);
// recurse into directories
- if (pair.first.isDirectory()) {
- nextfile: for (String localname : pair.first.list()) {
+ if(pair.first.isDirectory()) {
+ nextfile: for(String localname : pair.first.list()) {
// Ignore unix-hidden files/dirs
- if (localname.charAt(0) == '.') {
+ if(localname.charAt(0) == '.') {
continue;
}
// Classes
- if (localname.endsWith(CLASS_EXT)) {
- if (localname.indexOf('$') >= 0) {
- if (!localname.endsWith(FACTORY_FILE_EXT)) {
+ if(localname.endsWith(CLASS_EXT)) {
+ if(localname.indexOf('$') >= 0) {
+ if(!localname.endsWith(FACTORY_FILE_EXT)) {
continue;
}
}
@@ -346,10 +360,10 @@ public class InspectionUtil {
}
// Recurse into directories
File newf = new File(pair.first, localname);
- if (newf.isDirectory()) {
+ if(newf.isDirectory()) {
String newpref = pair.second + localname + '.';
- for (String ignore : ignorepackages) {
- if (ignore.equals(newpref)) {
+ for(String ignore : ignorepackages) {
+ if(ignore.equals(newpref)) {
continue nextfile;
}
}
@@ -362,10 +376,10 @@ public class InspectionUtil {
@Override
public String next() {
- if (files.size() == 0) {
+ if(files.size() == 0) {
findNext();
}
- if (files.size() > 0) {
+ if(files.size() > 0) {
return files.remove(files.size() - 1);
}
return null;
@@ -389,14 +403,14 @@ public class InspectionUtil {
public int compare(Class<?> o1, Class<?> o2) {
Package p1 = o1.getPackage();
Package p2 = o2.getPackage();
- if (p1 == null) {
+ if(p1 == null) {
return -1;
}
- if (p2 == null) {
+ if(p2 == null) {
return 1;
}
int pkgcmp = p1.getName().compareTo(p2.getName());
- if (pkgcmp != 0) {
+ if(pkgcmp != 0) {
return pkgcmp;
}
return o1.getCanonicalName().compareTo(o2.getCanonicalName());
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/Util.java b/src/de/lmu/ifi/dbs/elki/utilities/Util.java
index ffac6573..252cdcf1 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/Util.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/Util.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities;
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/utilities/datastructures/QuickSelect.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/QuickSelect.java
index d0a2cd20..89cbdc1e 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/QuickSelect.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/QuickSelect.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures;
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/utilities/datastructures/arraylike/ArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayAdapter.java
index 2c5eeed1..c1b7a280 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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/utilities/datastructures/arraylike/ArrayDBIDsAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayDBIDsAdapter.java
index da831471..b8123e2d 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayDBIDsAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayDBIDsAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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/utilities/datastructures/arraylike/ArrayLikeUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayLikeUtil.java
index f03d39e9..2e8496c6 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayLikeUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayLikeUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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
@@ -63,7 +63,7 @@ public final class ArrayLikeUtil {
/**
* Use a number vector in the array API.
*/
- public static final NumberVectorAdapter<?> NUMBERVECTORADAPTER = new NumberVectorAdapter<Double>();
+ public static final NumberVectorAdapter NUMBERVECTORADAPTER = new NumberVectorAdapter();
/**
* Adapter for matrixes, reinterpreted as flat arrays.
@@ -152,9 +152,8 @@ public final class ArrayLikeUtil {
* @param prototype Prototype value, for type inference
* @return Instance
*/
- @SuppressWarnings("unchecked")
- public static <N extends Number> NumberVectorAdapter<N> numberVectorAdapter(NumberVector<N> prototype) {
- return (NumberVectorAdapter<N>) NUMBERVECTORADAPTER;
+ public static NumberVectorAdapter numberVectorAdapter(NumberVector prototype) {
+ return NUMBERVECTORADAPTER;
}
/**
@@ -236,7 +235,7 @@ public final class ArrayLikeUtil {
* @param obj Object to convert
* @return primitive double array
*/
- public static <N extends Number> double[] toPrimitiveDoubleArray(NumberVector<N> obj) {
+ public static double[] toPrimitiveDoubleArray(NumberVector obj) {
return toPrimitiveDoubleArray(obj, numberVectorAdapter(obj));
}
@@ -274,7 +273,7 @@ public final class ArrayLikeUtil {
* @param obj Object to convert
* @return primitive float array
*/
- public static <N extends Number> float[] toPrimitiveFloatArray(NumberVector<N> obj) {
+ public static float[] toPrimitiveFloatArray(NumberVector obj) {
return toPrimitiveFloatArray(obj, numberVectorAdapter(obj));
}
@@ -309,7 +308,7 @@ public final class ArrayLikeUtil {
* @param obj Object to convert
* @return primitive double array
*/
- public static <N extends Number> int[] toPrimitiveIntegerArray(NumberVector<N> obj) {
+ public static int[] toPrimitiveIntegerArray(NumberVector obj) {
return toPrimitiveIntegerArray(obj, numberVectorAdapter(obj));
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/DoubleArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/DoubleArrayAdapter.java
index 0e31a61a..462cd763 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/DoubleArrayAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/DoubleArrayAdapter.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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/utilities/datastructures/arraylike/ExtendedArray.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ExtendedArray.java
index 3af14982..aeeeafea 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ExtendedArray.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ExtendedArray.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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/utilities/datastructures/arraylike/FeatureVectorAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FeatureVectorAdapter.java
index deb5aafc..d353812a 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FeatureVectorAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FeatureVectorAdapter.java
@@ -6,7 +6,7 @@ import de.lmu.ifi.dbs.elki.data.FeatureVector;
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/utilities/datastructures/arraylike/FlatMatrixAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FlatMatrixAdapter.java
index 18fbae5d..175a672d 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FlatMatrixAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FlatMatrixAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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/utilities/datastructures/arraylike/FloatArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FloatArrayAdapter.java
index 831dc929..0ef25d78 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FloatArrayAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FloatArrayAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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/utilities/datastructures/arraylike/IdentityArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/IdentityArrayAdapter.java
index dfde46b7..99a3dd80 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/IdentityArrayAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/IdentityArrayAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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/utilities/datastructures/arraylike/ListArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ListArrayAdapter.java
index 729dfab8..ab947111 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ListArrayAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ListArrayAdapter.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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/utilities/datastructures/arraylike/NumberArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberArrayAdapter.java
index 5ebbcb0d..d4911f95 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberArrayAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberArrayAdapter.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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/utilities/datastructures/arraylike/NumberListArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberListArrayAdapter.java
index a2606347..d1ccd560 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberListArrayAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberListArrayAdapter.java
@@ -6,7 +6,7 @@ import java.util.List;
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/utilities/datastructures/arraylike/NumberVectorAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberVectorAdapter.java
index 5e674026..b4f1cca1 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberVectorAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberVectorAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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,10 +31,8 @@ import de.lmu.ifi.dbs.elki.data.NumberVector;
* Use the static instance from {@link ArrayLikeUtil}!
*
* @author Erich Schubert
- *
- * @param <N> Number type
*/
-public class NumberVectorAdapter<N extends Number> implements NumberArrayAdapter<N, NumberVector<N>> {
+public class NumberVectorAdapter implements NumberArrayAdapter<Number, NumberVector> {
/**
* Constructor.
*
@@ -45,43 +43,43 @@ public class NumberVectorAdapter<N extends Number> implements NumberArrayAdapter
}
@Override
- public int size(NumberVector<N> array) {
+ public int size(NumberVector array) {
return array.getDimensionality();
}
@Override
@Deprecated
- public N get(NumberVector<N> array, int off) throws IndexOutOfBoundsException {
+ public Number get(NumberVector array, int off) throws IndexOutOfBoundsException {
return array.getValue(off + 1);
}
@Override
- public double getDouble(NumberVector<N> array, int off) throws IndexOutOfBoundsException {
+ public double getDouble(NumberVector array, int off) throws IndexOutOfBoundsException {
return array.doubleValue(off);
}
@Override
- public float getFloat(NumberVector<N> array, int off) throws IndexOutOfBoundsException {
+ public float getFloat(NumberVector array, int off) throws IndexOutOfBoundsException {
return array.floatValue(off);
}
@Override
- public int getInteger(NumberVector<N> array, int off) throws IndexOutOfBoundsException {
+ public int getInteger(NumberVector array, int off) throws IndexOutOfBoundsException {
return array.intValue(off);
}
@Override
- public short getShort(NumberVector<N> array, int off) throws IndexOutOfBoundsException {
+ public short getShort(NumberVector array, int off) throws IndexOutOfBoundsException {
return array.shortValue(off);
}
@Override
- public long getLong(NumberVector<N> array, int off) throws IndexOutOfBoundsException {
+ public long getLong(NumberVector array, int off) throws IndexOutOfBoundsException {
return array.longValue(off);
}
@Override
- public byte getByte(NumberVector<N> array, int off) throws IndexOutOfBoundsException {
+ public byte getByte(NumberVector array, int off) throws IndexOutOfBoundsException {
return array.byteValue(off);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SingleSubsetArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SingleSubsetArrayAdapter.java
index 941c6245..abf88cbc 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SingleSubsetArrayAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SingleSubsetArrayAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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/utilities/datastructures/arraylike/SubsetArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetArrayAdapter.java
index 746647cc..f6b54c9e 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetArrayAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetArrayAdapter.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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/utilities/datastructures/arraylike/SubsetNumberArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetNumberArrayAdapter.java
index c394f9b7..9e46a94a 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetNumberArrayAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetNumberArrayAdapter.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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/utilities/datastructures/arraylike/TDoubleListAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/TDoubleListAdapter.java
index a52ff15e..e72d23d1 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/TDoubleListAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/TDoubleListAdapter.java
@@ -6,7 +6,7 @@ import gnu.trove.list.TDoubleList;
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/utilities/datastructures/arraylike/VectorAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/VectorAdapter.java
index 0bb979e9..6d28888d 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/VectorAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/VectorAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike;
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/utilities/datastructures/arraylike/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/package-info.java
index 33058cf4..489d0316 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/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/database/ids/integer/DoubleIntegerArrayQuickSort.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/DoubleIntegerArrayQuickSort.java
index 8f1c58d6..851fed11 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerArrayQuickSort.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/DoubleIntegerArrayQuickSort.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.database.ids.integer;
+package de.lmu.ifi.dbs.elki.utilities.datastructures.arrays;
/*
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 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
*
* @author Erich Schubert
*/
-class DoubleIntegerArrayQuickSort {
+public class DoubleIntegerArrayQuickSort {
/**
* Threshold for using insertion sort.
*/
@@ -68,19 +68,11 @@ class DoubleIntegerArrayQuickSort {
*/
private static void quickSort(double[] keys, int[] vals, final int start, final int end) {
final int len = end - start;
- if (len < INSERTION_THRESHOLD) {
- // Classic insertion sort.
- for (int i = start + 1; i < end; i++) {
- for (int j = i; j > start; j--) {
- if (keys[j] < keys[j - 1]) {
- swap(keys, vals, j, j - 1);
- } else {
- break;
- }
- }
- }
+ if(len < INSERTION_THRESHOLD) {
+ insertionSort(keys, vals, start, end);
return;
}
+ final int last = end - 1;
// Choose pivots by looking at five candidates.
final int seventh = (len >> 3) + (len >> 6) + 1;
@@ -91,35 +83,7 @@ class DoubleIntegerArrayQuickSort {
final int m5 = m4 + seventh;
// Mixture of insertion and merge sort:
- if (keys[m1] > keys[m2]) {
- swap(keys, vals, m1, m2);
- }
- if (keys[m3] > keys[m4]) {
- swap(keys, vals, m3, m4);
- }
- // Merge 1+2 and 3+4
- if (keys[m2] > keys[m4]) {
- swap(keys, vals, m2, m4);
- }
- if (keys[m1] > keys[m3]) {
- swap(keys, vals, m1, m3);
- }
- if (keys[m2] > keys[m3]) {
- swap(keys, vals, m2, m3);
- }
- // Insertion sort m5:
- if (keys[m4] > keys[m5]) {
- swap(keys, vals, m4, m5);
- if (keys[m3] > keys[m4]) {
- swap(keys, vals, m3, m4);
- if (keys[m2] > keys[m3]) {
- swap(keys, vals, m2, m3);
- if (keys[m1] > keys[m1]) {
- swap(keys, vals, m1, m2);
- }
- }
- }
- }
+ sort5(keys, vals, m1, m2, m3, m4, m5);
// Move pivot to the front.
double pivotkey = keys[m3];
@@ -128,37 +92,110 @@ class DoubleIntegerArrayQuickSort {
vals[m3] = vals[start];
// The interval to pivotize
- int left = start + 1;
- int right = end - 1;
+ int left = start + 1; // Without pivot
+ int right = last; // inclusive
// This is the classic QuickSort loop:
- while (true) {
- while (left <= right && keys[left] <= pivotkey) {
+ while(true) {
+ // Move duplicates to right partition, i.e. < here, <= below.
+ while(left <= right && keys[left] < pivotkey) {
left++;
}
- while (left <= right && pivotkey <= keys[right]) {
+ while(left <= right && pivotkey <= keys[right]) {
right--;
}
- if (right <= left) {
+ if(right <= left) {
break;
}
swap(keys, vals, left, right);
left++;
right--;
}
-
+ // right now points to the last element smaller than the pivot.
// Move pivot back into the appropriate place
keys[start] = keys[right];
vals[start] = vals[right];
keys[right] = pivotkey;
vals[right] = pivotval;
- // Recursion:
- if (start + 1 < right) {
+ // Recursion when more than one element only:
+ if(start + 1 < right) {
quickSort(keys, vals, start, right);
}
- if (right + 2 < end) {
- quickSort(keys, vals, right + 1, end);
+ int rstart = right + 1;
+ // Avoid recursing on duplicates of the pivot:
+ while(rstart < last && keys[rstart] <= keys[right]) {
+ rstart++;
+ }
+ // Recurse when _more_ than 1 element only
+ if(rstart < last) {
+ quickSort(keys, vals, rstart, end);
+ }
+ }
+
+ /**
+ * An explicit sort, for the five pivot candidates.
+ *
+ * Note that this <em>must</em> only be used with
+ * {@code m1 < m2 < m3 < m4 < m5}.
+ *
+ * @param keys Keys
+ * @param vals Values
+ * @param m1 Pivot candidate position
+ * @param m2 Pivot candidate position
+ * @param m3 Pivot candidate position
+ * @param m4 Pivot candidate position
+ * @param m5 Pivot candidate position
+ */
+ private static void sort5(double[] keys, int[] vals, final int m1, final int m2, final int m3, final int m4, final int m5) {
+ if(keys[m1] > keys[m2]) {
+ swap(keys, vals, m1, m2);
+ }
+ if(keys[m3] > keys[m4]) {
+ swap(keys, vals, m3, m4);
+ }
+ // Merge 1+2 and 3+4
+ if(keys[m2] > keys[m4]) {
+ swap(keys, vals, m2, m4);
+ }
+ if(keys[m1] > keys[m3]) {
+ swap(keys, vals, m1, m3);
+ }
+ if(keys[m2] > keys[m3]) {
+ swap(keys, vals, m2, m3);
+ }
+ // Insertion sort m5:
+ if(keys[m4] > keys[m5]) {
+ swap(keys, vals, m4, m5);
+ if(keys[m3] > keys[m4]) {
+ swap(keys, vals, m3, m4);
+ if(keys[m2] > keys[m3]) {
+ swap(keys, vals, m2, m3);
+ if(keys[m1] > keys[m1]) {
+ swap(keys, vals, m1, m2);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Sort via insertion sort.
+ *
+ * @param keys Keys
+ * @param vals Values
+ * @param start Interval start
+ * @param end Interval end
+ */
+ private static void insertionSort(double[] keys, int[] vals, final int start, final int end) {
+ // Classic insertion sort.
+ for(int i = start + 1; i < end; i++) {
+ for(int j = i; j > start; j--) {
+ if(keys[j] >= keys[j - 1]) {
+ break;
+ }
+ swap(keys, vals, j, j - 1);
+ }
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerArrayQuickSort.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerArrayQuickSort.java
index eaf47738..b91d79b1 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerArrayQuickSort.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerArrayQuickSort.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arrays;
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,15 +34,17 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* Vladimir Yaroslavskiy
* </p>
*
- * and differs mostly in that we sort different kinds of arrays,
- * and allow the use of comparators - useful in particular when
- * the array references external objects.
+ * and differs mostly in that we sort different kinds of arrays, and allow the
+ * use of comparators - useful in particular when the array references external
+ * objects.
*
* @author Erich Schubert
*
* @apiviz.uses IntegerComparator
*/
-@Reference(authors = "Vladimir Yaroslavskiy", title = "Dual-Pivot Quicksort", booktitle = "http://iaroslavski.narod.ru/quicksort/", url = "http://iaroslavski.narod.ru/quicksort/")
+@Reference(authors = "Vladimir Yaroslavskiy", //
+title = "Dual-Pivot Quicksort", booktitle = "http://iaroslavski.narod.ru/quicksort/", //
+url = "http://iaroslavski.narod.ru/quicksort/")
public class IntegerArrayQuickSort {
/**
* Threshold for using insertion sort. Value taken from Javas QuickSort,
@@ -69,7 +71,7 @@ public class IntegerArrayQuickSort {
* @param comp Comparator
*/
public static void sort(int[] data, int start, int end, IntegerComparator comp) {
- quickSort(data, start, end - 1, comp);
+ quickSort(data, start, end, comp);
}
/**
@@ -77,24 +79,14 @@ public class IntegerArrayQuickSort {
*
* @param data Data to sort
* @param start First index
- * @param end Last index (inclusive!)
+ * @param end Last index (exclusive!)
* @param comp Comparator
*/
private static void quickSort(int[] data, final int start, final int end, IntegerComparator comp) {
final int len = end - start;
- if (len < INSERTION_THRESHOLD) {
- // Classic insertion sort.
- for (int i = start + 1; i <= end; i++) {
- for (int j = i; j > start; j--) {
- if (comp.compare(data[j], data[j - 1]) < 0) {
- final int tmp = data[j - 1];
- data[j - 1] = data[j];
- data[j] = tmp;
- } else {
- break;
- }
- }
- }
+ final int last = end - 1;
+ if(len < INSERTION_THRESHOLD) {
+ insertionSort(data, start, end, comp);
return;
}
@@ -108,51 +100,7 @@ public class IntegerArrayQuickSort {
// Explicit (and optimal) sorting network for 5 elements
// See Knuth for details.
- if (comp.compare(data[m1], data[m2]) > 0) {
- final int tmp = data[m2];
- data[m2] = data[m1];
- data[m1] = tmp;
- }
- if (comp.compare(data[m1], data[m3]) > 0) {
- final int tmp = data[m3];
- data[m3] = data[m1];
- data[m1] = tmp;
- }
- if (comp.compare(data[m2], data[m3]) > 0) {
- final int tmp = data[m3];
- data[m3] = data[m2];
- data[m2] = tmp;
- }
- if (comp.compare(data[m4], data[m5]) > 0) {
- final int tmp = data[m5];
- data[m5] = data[m4];
- data[m4] = tmp;
- }
- if (comp.compare(data[m1], data[m4]) > 0) {
- final int tmp = data[m4];
- data[m4] = data[m1];
- data[m1] = tmp;
- }
- if (comp.compare(data[m3], data[m4]) > 0) {
- final int tmp = data[m4];
- data[m4] = data[m3];
- data[m3] = tmp;
- }
- if (comp.compare(data[m2], data[m5]) > 0) {
- final int tmp = data[m5];
- data[m5] = data[m2];
- data[m2] = tmp;
- }
- if (comp.compare(data[m2], data[m3]) > 0) {
- final int tmp = data[m3];
- data[m3] = data[m2];
- data[m2] = tmp;
- }
- if (comp.compare(data[m4], data[m5]) > 0) {
- final int tmp = data[m5];
- data[m5] = data[m4];
- data[m4] = tmp;
- }
+ sort5(data, m1, m2, m3, m4, m5, comp);
// Choose the 2 and 4th as pivots, as we want to get three parts
// Copy to variables v1 and v3, replace them with the start and end
@@ -160,35 +108,38 @@ public class IntegerArrayQuickSort {
final int lpivot = data[m2];
final int rpivot = data[m4];
data[m2] = data[start];
- data[m4] = data[end];
+ data[m4] = data[last];
// A tie is when the two chosen pivots are the same
final boolean tied = comp.compare(lpivot, rpivot) == 0;
// Insertion points for pivot areas.
int left = start + 1;
- int right = end - 1;
+ int right = last - 1;
// Note: we merged the ties and no ties cases.
// This likely is marginally slower, but not at a macro level
// And you never know with hotspot.
- for (int k = left; k <= right; k++) {
+ for(int k = left; k <= right; k++) {
final int tmp = data[k];
final int c = comp.compare(tmp, lpivot);
- if (c == 0) {
+ if(c == 0) {
continue;
- } else if (c < 0) {
+ }
+ else if(c < 0) {
// Traditional quicksort
data[k] = data[left];
data[left] = tmp;
left++;
- } else if (tied || comp.compare(tmp, rpivot) > 0) {
+ }
+ else if(tied || comp.compare(tmp, rpivot) > 0) {
// Now look at the right. First skip correct entries there, too
- while (true) {
+ while(true) {
final int tmp2 = data[right];
- if (comp.compare(tmp2, rpivot) > 0 && k < right) {
+ if(comp.compare(tmp2, rpivot) > 0 && k < right) {
right--;
- } else {
+ }
+ else {
break;
}
}
@@ -197,7 +148,7 @@ public class IntegerArrayQuickSort {
data[right] = tmp;
right--;
// Test the element we just inserted: left or center?
- if (comp.compare(data[k], lpivot) < 0) {
+ if(comp.compare(data[k], lpivot) < 0) {
final int tmp2 = data[k];
data[k] = data[left];
data[left] = tmp2;
@@ -209,17 +160,105 @@ public class IntegerArrayQuickSort {
// Remember: we must not modify v1 and v3 above.
data[start] = data[left - 1];
data[left - 1] = lpivot;
- data[end] = data[right + 1];
+ data[last] = data[right + 1];
data[right + 1] = rpivot;
// v1 and v3 are now safe to modify again. Perform recursion:
- quickSort(data, start, left - 2, comp);
+ quickSort(data, start, left - 1, comp);
// Handle the middle part - if necessary:
- if (!tied) {
+ if(!tied) {
// TODO: the original publication had a special tie handling here.
// It shouldn't affect correctness, but probably improves situations
// with a lot of tied elements.
- quickSort(data, left, right, comp);
+ quickSort(data, left, right + 1, comp);
}
quickSort(data, right + 2, end, comp);
}
+
+ /**
+ * Insertion sort, for short arrays.
+ *
+ * @param data Data to sort
+ * @param start First index
+ * @param end Last index (exclusive!)
+ * @param comp Comparator
+ */
+ private static void insertionSort(int[] data, final int start, final int end, IntegerComparator comp) {
+ // Classic insertion sort.
+ for(int i = start + 1; i < end; i++) {
+ final int cur = data[i];
+ int j = i - 1;
+ while(j >= start) {
+ final int pre = data[j];
+ if(comp.compare(cur, pre) >= 0) {
+ break;
+ }
+ data[j + 1] = pre;
+ --j;
+ }
+ data[j + 1] = cur;
+ }
+ }
+
+ /**
+ * An explicit sort, for the five pivot candidates.
+ *
+ * Note that this <em>must</em> only be used with
+ * {@code m1 < m2 < m3 < m4 < m5}.
+ *
+ * @param data Data
+ * @param m1 Pivot candidate position
+ * @param m2 Pivot candidate position
+ * @param m3 Pivot candidate position
+ * @param m4 Pivot candidate position
+ * @param m5 Pivot candidate position
+ * @param comp Comparator
+ */
+ private static void sort5(int[] data, int m1, int m2, int m3, int m4, int m5, IntegerComparator comp) {
+ // Sort m1, m2
+ if(comp.compare(data[m1], data[m2]) > 0) {
+ final int tmp = data[m2];
+ data[m2] = data[m1];
+ data[m1] = tmp;
+ }
+ // Sort m3, m4
+ if(comp.compare(data[m3], data[m4]) > 0) {
+ final int tmp = data[m4];
+ data[m4] = data[m3];
+ data[m3] = tmp;
+ }
+ // Merge 1+2 and 3+4
+ if(comp.compare(data[m2], data[m4]) > 0) {
+ final int tmp = data[m4];
+ data[m4] = data[m2];
+ data[m2] = tmp;
+ }
+ if(comp.compare(data[m1], data[m3]) > 0) {
+ final int tmp = data[m3];
+ data[m3] = data[m1];
+ data[m1] = tmp;
+ }
+ if(comp.compare(data[m2], data[m3]) > 0) {
+ final int tmp = data[m3];
+ data[m3] = data[m2];
+ data[m2] = tmp;
+ }
+ // Insertion sort m5:
+ final int tmp = data[m5];
+ if(comp.compare(data[m4], tmp) > 0) {
+ data[m5] = data[m4];
+ data[m4] = tmp;
+ if(comp.compare(data[m3], tmp) > 0) {
+ data[m4] = data[m3];
+ data[m3] = tmp;
+ if(comp.compare(data[m2], tmp) > 0) {
+ data[m3] = data[m2];
+ data[m2] = tmp;
+ if(comp.compare(data[m1], tmp) > 0) {
+ data[m2] = data[m1];
+ data[m1] = tmp;
+ }
+ }
+ }
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerComparator.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerComparator.java
index 0ccd47db..47b0ccfd 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerComparator.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerComparator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arrays;
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,13 +24,13 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arrays;
*/
/**
- * Interface for comparing two integers.
+ * Interface for comparing two Integer.
*
* @author Erich Schubert
*/
public interface IntegerComparator {
/**
- * Compare two integers.
+ * Compare two Integer.
*
* @param x First int
* @param y Second int
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/package-info.java
index 874a6d44..921de083 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/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/utilities/datastructures/hash/Unique.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hash/Unique.java
new file mode 100644
index 00000000..ab149c39
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hash/Unique.java
@@ -0,0 +1,132 @@
+package de.lmu.ifi.dbs.elki.utilities.datastructures.hash;
+
+/*
+ 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 gnu.trove.impl.hash.TObjectHash;
+
+import java.util.Arrays;
+
+/**
+ * This hash set is designed to keep only a unique copy of each object (hence
+ * its name). For this, the method {@link #addOrGet} is the key API, which
+ * allows retrieving existing values.
+ *
+ * @author Erich Schubert
+ *
+ * @param <E>
+ */
+public class Unique<E> extends TObjectHash<E> {
+ /**
+ * Serial version number.
+ */
+ static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor with default size and load factors.
+ */
+ public Unique() {
+ super();
+ }
+
+ /**
+ * Constructor with desired initial size.
+ *
+ * @param initialCapacity desired initial size.
+ */
+ public Unique(int initialCapacity) {
+ super(initialCapacity);
+ }
+
+ /**
+ * Constructor with desired initial size, and with the specified load factor.
+ *
+ * @param initialCapacity desired initial size
+ * @param loadFactor load factor
+ */
+ public Unique(int initialCapacity, float loadFactor) {
+ super(initialCapacity, loadFactor);
+ }
+
+ /**
+ * Inserts a value into the set, unless it is already present.
+ *
+ * This function returns the existing value, if present.
+ *
+ * @param obj Object to insert or retrieve
+ * @return Existing object if already present, or the new object.
+ */
+ @SuppressWarnings("unchecked")
+ public E addOrGet(E obj) {
+ int index = insertKey(obj);
+
+ if(index < 0) {
+ obj = (E) _set[-index - 1];
+ }
+
+ postInsertHook(consumeFreeSlot);
+ return obj;
+ }
+
+ /**
+ * Removes an existing object from the set.
+ *
+ * @param obj Object to remove
+ * @return true if the object was found and removed.
+ */
+ public boolean remove(Object obj) {
+ int index = index(obj);
+ if(index >= 0) {
+ removeAt(index);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void clear() {
+ super.clear();
+
+ Arrays.fill(_set, 0, _set.length, FREE);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void rehash(int newCapacity) {
+ final int oldCapacity = _set.length, oldSize = size();
+ // Replace data storage:
+ Object oldSet[] = _set;
+ _set = new Object[newCapacity];
+ Arrays.fill(_set, FREE);
+
+ // Reinsert all objects:
+ for(int i = oldCapacity; i-- > 0;) {
+ E o = (E) oldSet[i];
+ if(o != FREE && o != REMOVED) {
+ insertKey(o);
+ }
+ }
+ // Last check: size before and after should be the same
+ reportPotentialConcurrentMod(size(), oldSize);
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hash/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hash/package-info.java
new file mode 100644
index 00000000..03746389
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hash/package-info.java
@@ -0,0 +1,30 @@
+/**
+ * Hashing based data structures.
+ *
+ * Note: much of the desired functionality is provided by the very good GNU Trove library.
+ *
+ * This package will only contain slight extensions or variations, not provided by Trove already.
+ */
+/*
+ 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.utilities.datastructures.hash; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMaxHeap.java
index d6937b4d..1433bd4e 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMaxHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMaxHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -233,8 +233,9 @@ public class ComparableMaxHeap<K extends Comparable<? super K>> implements Objec
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@SuppressWarnings("unchecked")
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMinHeap.java
index 167c6bc7..76104644 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMinHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMinHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -233,8 +233,9 @@ public class ComparableMinHeap<K extends Comparable<? super K>> implements Objec
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@SuppressWarnings("unchecked")
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMaxHeap.java
index e5887c73..516177fd 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMaxHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMaxHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -242,8 +242,9 @@ public class ComparatorMaxHeap<K> implements ObjectHeap<K> {
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@SuppressWarnings("unchecked")
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMinHeap.java
index 215a78b6..11518553 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMinHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMinHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -242,8 +242,9 @@ public class ComparatorMinHeap<K> implements ObjectHeap<K> {
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@SuppressWarnings("unchecked")
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleHeap.java
index c82f2a4a..d32a07a9 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ 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/utilities/datastructures/heap/DoubleIntegerHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerHeap.java
index 5d8d31f7..6899e327 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ 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/utilities/datastructures/heap/DoubleIntegerMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMaxHeap.java
index e903c23d..1a9f8dbe 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMaxHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMaxHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -249,8 +249,9 @@ public class DoubleIntegerMaxHeap implements DoubleIntegerHeap {
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMinHeap.java
index 0e4e2204..11237841 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMinHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMinHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -249,8 +249,9 @@ public class DoubleIntegerMinHeap implements DoubleIntegerHeap {
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongHeap.java
index b93adafa..1b02d3c7 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ 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/utilities/datastructures/heap/DoubleLongMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMaxHeap.java
index b7508a61..7caa7cd4 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMaxHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMaxHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -249,8 +249,9 @@ public class DoubleLongMaxHeap implements DoubleLongHeap {
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMinHeap.java
index 9fbe0300..1e1a5956 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMinHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMinHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -249,8 +249,9 @@ public class DoubleLongMinHeap implements DoubleLongHeap {
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMaxHeap.java
index 2c74b34b..78743779 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMaxHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMaxHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -226,8 +226,9 @@ public class DoubleMaxHeap implements DoubleHeap {
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMinHeap.java
index afc50296..1c6954b7 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMinHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMinHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -226,8 +226,9 @@ public class DoubleMinHeap implements DoubleHeap {
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectHeap.java
index 7323cd8d..ad964c08 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ 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/utilities/datastructures/heap/DoubleObjectMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMaxHeap.java
index 939c4d7e..3999c218 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMaxHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMaxHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -251,8 +251,9 @@ public class DoubleObjectMaxHeap<V> implements DoubleObjectHeap<V> {
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMinHeap.java
index 01b8e58d..18713455 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMinHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMinHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -251,8 +251,9 @@ public class DoubleObjectMinHeap<V> implements DoubleObjectHeap<V> {
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoublePriorityObject.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoublePriorityObject.java
index 82453885..d940cd21 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoublePriorityObject.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoublePriorityObject.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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.utilities.datastructures.heap;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.utilities.pairs.PairInterface;
/**
* Object for a priority queue with integer priority. Can be used in the
@@ -35,7 +34,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.PairInterface;
*
* @param <O> Stored object type.
*/
-public class DoublePriorityObject<O> implements PairInterface<Double, O>, Comparable<DoublePriorityObject<?>> {
+public class DoublePriorityObject<O> implements Comparable<DoublePriorityObject<?>> {
/**
* Priority.
*/
@@ -79,17 +78,6 @@ public class DoublePriorityObject<O> implements PairInterface<Double, O>, Compar
}
@Override
- @Deprecated
- public Double getFirst() {
- return Double.valueOf(priority);
- }
-
- @Override
- public O getSecond() {
- return object;
- }
-
- @Override
public int hashCode() {
return ((object == null) ? 0 : object.hashCode());
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/Heap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/Heap.java
index 2c278110..dad6f1d7 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/Heap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/Heap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -442,8 +442,9 @@ public class Heap<E> {
}
@Override
- public void advance() {
+ public UnorderedIter advance() {
pos++;
+ return this;
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerHeap.java
index 77e5f3e5..80d8882b 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ 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/utilities/datastructures/heap/IntegerMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMaxHeap.java
index 4f3b1495..b3fc51ca 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMaxHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMaxHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -226,8 +226,9 @@ public class IntegerMaxHeap implements IntegerHeap {
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMinHeap.java
index b02e04db..6632d005 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMinHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMinHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -226,8 +226,9 @@ public class IntegerMinHeap implements IntegerHeap {
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectHeap.java
index e4f577af..f4c7043f 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ 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/utilities/datastructures/heap/IntegerObjectMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMaxHeap.java
index 036a9520..5a4bd70f 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMaxHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMaxHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -251,8 +251,9 @@ public class IntegerObjectMaxHeap<V> implements IntegerObjectHeap<V> {
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMinHeap.java
index cc816a0e..b6fc9a74 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMinHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMinHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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
@@ -251,8 +251,9 @@ public class IntegerObjectMinHeap<V> implements IntegerObjectHeap<V> {
}
@Override
- public void advance() {
+ public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() {
pos++;
+ return this;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerPriorityObject.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerPriorityObject.java
index f007b9fc..11f8c7d5 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerPriorityObject.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerPriorityObject.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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.utilities.datastructures.heap;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.utilities.pairs.PairInterface;
/**
* Object for a priority queue with integer priority. Can be used in the
@@ -35,7 +34,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.PairInterface;
*
* @param <O> Stored object type.
*/
-public class IntegerPriorityObject<O> implements PairInterface<Integer, O>, Comparable<IntegerPriorityObject<?>> {
+public class IntegerPriorityObject<O> implements Comparable<IntegerPriorityObject<?>> {
/**
* Priority.
*/
@@ -79,17 +78,6 @@ public class IntegerPriorityObject<O> implements PairInterface<Integer, O>, Comp
}
@Override
- @Deprecated
- public Integer getFirst() {
- return Integer.valueOf(priority);
- }
-
- @Override
- public O getSecond() {
- return object;
- }
-
- @Override
public int hashCode() {
return ((object == null) ? 0 : object.hashCode());
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ObjectHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ObjectHeap.java
index 2b03740e..3aa1dd7f 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ObjectHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ObjectHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ 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/utilities/datastructures/heap/TiedTopBoundedHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedHeap.java
index 32f57999..14e708c5 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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/utilities/datastructures/heap/TiedTopBoundedUpdatableHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedUpdatableHeap.java
index 3905030f..4c8c6ddb 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedUpdatableHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedUpdatableHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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/utilities/datastructures/heap/TopBoundedHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedHeap.java
index 9adda9f3..29880fd7 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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/utilities/datastructures/heap/TopBoundedUpdatableHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedUpdatableHeap.java
index 4a591d4c..d80f209f 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedUpdatableHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedUpdatableHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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/utilities/datastructures/heap/UpdatableHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/UpdatableHeap.java
index a585d94d..f3c42e90 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/UpdatableHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/UpdatableHeap.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
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/utilities/datastructures/heap/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/package-info.java
index 83be37f4..7062650e 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/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/utilities/datastructures/hierarchy/HashMapHierarchy.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/HashMapHierarchy.java
index c77a9329..f8bd27a8 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/HashMapHierarchy.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/HashMapHierarchy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy;
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
@@ -353,8 +353,9 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> {
}
@Override
- public void advance() {
+ public Iter<O> advance() {
pos++;
+ return this;
}
@SuppressWarnings("unchecked")
@@ -380,8 +381,9 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> {
}
@Override
- public void advance() {
+ public Iter<O> advance() {
pos++;
+ return this;
}
@SuppressWarnings("unchecked")
@@ -425,7 +427,7 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> {
}
@Override
- public void advance() {
+ public Iter<O> advance() {
if (subiter == null) { // Not yet descended
assert (childiter.valid());
subiter = iterDescendants(childiter.get());
@@ -433,11 +435,12 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> {
subiter.advance();
}
if (subiter.valid()) {
- return;
+ return this;
}
// Proceed to next child.
childiter.advance();
subiter = null;
+ return this;
}
@Override
@@ -485,7 +488,7 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> {
}
@Override
- public void advance() {
+ public Iter<O> advance() {
if (subiter == null) { // Not yet descended
assert (parentiter.valid());
subiter = iterAncestors(parentiter.get());
@@ -493,11 +496,12 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> {
subiter.advance();
}
if (subiter.valid()) {
- return;
+ return this;
}
// Proceed to next child.
parentiter.advance();
subiter = null;
+ return this;
}
@Override
@@ -544,12 +548,13 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> {
}
@Override
- public void advance() {
+ public Iter<O> advance() {
if (iter.hasNext()) {
cur = iter.next();
} else {
cur = null;
}
+ return this;
}
@Override
@@ -568,7 +573,7 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> {
}
@Override
- public void advance() {
+ public Iter<Object> advance() {
throw new UnsupportedOperationException("Empty iterators must not be advanced.");
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/Hierarchy.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/Hierarchy.java
index fec9c7b4..7d751dc1 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/Hierarchy.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/Hierarchy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy;
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
@@ -113,5 +113,8 @@ public interface Hierarchy<O> {
* @return Current object
*/
O get();
+
+ @Override
+ Iter<O> advance();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/ModifiableHierarchy.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/ModifiableHierarchy.java
index 06001d6b..0b1b0534 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/ModifiableHierarchy.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/ModifiableHierarchy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy;
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/utilities/datastructures/hierarchy/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/package-info.java
index 965b15fc..4ea54ef2 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/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/utilities/datastructures/histogram/AbstractObjDynamicHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjDynamicHistogram.java
index 165c2c8b..d3d3f006 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjDynamicHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjDynamicHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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
@@ -74,12 +74,12 @@ public abstract class AbstractObjDynamicHistogram<T> extends AbstractObjStaticHi
@SuppressWarnings("unchecked")
void materialize() {
// already materialized?
- if (cachefill <= 0) {
+ if(cachefill <= 0) {
return;
}
// Compute minimum and maximum
double min = Double.MAX_VALUE, max = Double.MIN_VALUE;
- for (int i = 0; i < cachefill; i++) {
+ for(int i = 0; i < cachefill; i++) {
min = Math.min(min, cacheposs[i]);
max = Math.max(max, cacheposs[i]);
}
@@ -93,14 +93,14 @@ public abstract class AbstractObjDynamicHistogram<T> extends AbstractObjStaticHi
this.binsize = (max - min) / this.destsize;
// initialize array
this.data = new Object[this.destsize << 1];
- for (int i = 0; i < this.destsize; i++) {
+ for(int i = 0; i < this.destsize; i++) {
this.data[i] = makeObject();
}
size = destsize;
// re-insert data we have
final int end = cachefill;
cachefill = -1; // So reinsert works!
- for (int i = 0; i < end; i++) {
+ for(int i = 0; i < end; i++) {
putData(cacheposs[i], (T) cachevals[i]);
}
// delete cache, signal that we're initialized
@@ -125,21 +125,24 @@ public abstract class AbstractObjDynamicHistogram<T> extends AbstractObjStaticHi
@Override
public void putData(double coord, T value) {
// Store in cache
- if (cachefill >= 0) {
- if (cachefill < cacheposs.length) {
+ if(cachefill >= 0) {
+ if(cachefill < cacheposs.length) {
cacheposs[cachefill] = coord;
cachevals[cachefill] = cloneForCache(value);
++cachefill;
return;
}
}
- if (coord == Double.NEGATIVE_INFINITY) {
+ if(coord == Double.NEGATIVE_INFINITY) {
aggregateSpecial(value, 0);
- } else if (coord == Double.POSITIVE_INFINITY) {
+ }
+ else if(coord == Double.POSITIVE_INFINITY) {
aggregateSpecial(value, 1);
- } else if (Double.isNaN(coord)) {
+ }
+ else if(Double.isNaN(coord)) {
aggregateSpecial(value, 2);
- } else {
+ }
+ else {
// super class will handle histogram resizing / shifting
T exist = get(coord);
data[getBinNr(coord)] = aggregate(exist, value);
@@ -167,17 +170,19 @@ public abstract class AbstractObjDynamicHistogram<T> extends AbstractObjStaticHi
private void testResample(double coord) {
final int bin = getBinNr(coord);
final int sizereq, off;
- if (bin < 0) {
+ if(bin < 0) {
sizereq = size - bin;
off = -bin;
- } else if (bin >= data.length) {
+ }
+ else if(bin >= data.length) {
sizereq = bin + 1;
off = 0;
- } else {
+ }
+ else {
// Within the designated size - nothing to do.
return;
}
- if (sizereq < data.length) {
+ if(sizereq < data.length) {
// Accomodate by shifting. Let super do the job in {@link #get}
return;
}
@@ -186,31 +191,33 @@ public abstract class AbstractObjDynamicHistogram<T> extends AbstractObjStaticHi
assert (levels > 0) : "No resampling required?!?";
final int step = 1 << levels;
+ // We want to map [i ... i+step[ -> (i+off)/step
+ // Fix point: i = (i+off)/step; i*(step-1)=off; i=off/(step-1)
final int fixpoint = off / (step - 1);
{
// Start positions for in-place bottom-up downsampling.
- int oup = fixpoint;
+ int oup = (fixpoint >= 0) ? fixpoint : 0;
int inp = (oup << levels) - off;
assert (-step < inp && inp <= oup && oup < inp + step) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels);
- for (; inp < size; inp += step, oup++) {
+ for(; inp < size; inp += step, oup++) {
assert (oup < inp + step && oup < data.length);
data[oup] = downsample(data, Math.max(0, inp), Math.min(size, inp + step), step);
}
// Clean upwards
- for (; oup < data.length; oup++) {
+ for(; oup < data.length; oup++) {
data[oup] = null;
}
}
- if (off >= step) {
+ if(off >= step) {
// Start positions for in-place downsampling top-down:
- int oup = fixpoint - 1;
+ int oup = (fixpoint - 1 < size) ? fixpoint - 1 : size - 1;
int inp = (oup << levels) - off;
assert (oup > inp) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels);
- for (; inp > -step; inp -= step, oup--) {
+ for(; inp > -step; inp -= step, oup--) {
assert (oup >= inp && oup >= 0);
data[oup] = downsample(data, Math.max(0, inp), Math.min(size, inp + step), step);
}
- for (; oup >= 0; oup--) {
+ for(; oup >= 0; oup--) {
data[oup] = makeObject();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjStaticHistogram.java
index 4a1649af..cbfb29c0 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjStaticHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjStaticHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/AbstractStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractStaticHistogram.java
index 3363e61e..798e1d80 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractStaticHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractStaticHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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
@@ -193,8 +193,9 @@ public abstract class AbstractStaticHistogram implements Histogram {
}
@Override
- public void advance() {
+ public Iter advance() {
bin++;
+ return this;
}
@Override
@@ -203,18 +204,21 @@ public abstract class AbstractStaticHistogram implements Histogram {
}
@Override
- public void advance(int count) {
+ public Iter advance(int count) {
bin += count;
+ return this;
}
@Override
- public void retract() {
+ public Iter retract() {
bin--;
+ return this;
}
@Override
- public void seek(int off) {
+ public Iter seek(int off) {
bin = off;
+ return this;
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleArrayStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleArrayStaticHistogram.java
index 86b53d03..192abceb 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleArrayStaticHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleArrayStaticHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/DoubleDynamicHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleDynamicHistogram.java
index 84f97dfe..1c0f5f33 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleDynamicHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleDynamicHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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
@@ -162,10 +162,12 @@ public class DoubleDynamicHistogram extends DoubleStaticHistogram {
assert (levels > 0) : "No resampling required?!? sizereq=" + sizereq + " destsize=" + destsize + " array=" + data.length;
final int step = 1 << levels;
+ // We want to map [i ... i+step[ -> (i+off)/step
+ // Fix point: i = (i+off)/step; i*(step-1)=off; i=off/(step-1)
final int fixpoint = off / (step - 1);
{
// Start positions for in-place bottom-up downsampling.
- int oup = fixpoint;
+ int oup = (fixpoint >= 0) ? fixpoint : 0;
int inp = (oup << levels) - off;
assert (-step < inp && inp <= oup && oup < inp + step) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels);
for (; inp < size; inp += step, oup++) {
@@ -177,9 +179,9 @@ public class DoubleDynamicHistogram extends DoubleStaticHistogram {
data[oup] = 0;
}
}
- if (off > 0) {
+ if(off >= step) {
// Start positions for in-place downsampling top-down:
- int oup = fixpoint - 1;
+ int oup = (fixpoint - 1 < size) ? fixpoint - 1 : size - 1;
int inp = (oup << levels) - off;
assert (oup > inp) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels);
for (; inp > -step; inp -= step, oup--) {
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleHistogram.java
index e4a24c95..1d8ae54d 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/DoubleStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleStaticHistogram.java
index 5a634cf2..7475e00c 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleStaticHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleStaticHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/FloatDynamicHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatDynamicHistogram.java
index 9829eaf8..1d816e2d 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatDynamicHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatDynamicHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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
@@ -162,10 +162,12 @@ public class FloatDynamicHistogram extends FloatStaticHistogram {
assert (levels > 0) : "No resampling required?!? sizereq=" + sizereq + " destsize=" + destsize + " array=" + data.length;
final int step = 1 << levels;
+ // We want to map [i ... i+step[ -> (i+off)/step
+ // Fix point: i = (i+off)/step; i*(step-1)=off; i=off/(step-1)
final int fixpoint = off / (step - 1);
{
// Start positions for in-place bottom-up downsampling.
- int oup = fixpoint;
+ int oup = (fixpoint >= 0) ? fixpoint : 0;
int inp = (oup << levels) - off;
assert (-step < inp && inp <= oup && oup < inp + step) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels);
for (; inp < size; inp += step, oup++) {
@@ -177,9 +179,9 @@ public class FloatDynamicHistogram extends FloatStaticHistogram {
data[oup] = 0;
}
}
- if (off > 0) {
+ if(off >= step) {
// Start positions for in-place downsampling top-down:
- int oup = fixpoint - 1;
+ int oup = (fixpoint - 1 < size) ? fixpoint - 1 : size - 1;
int inp = (oup << levels) - off;
assert (oup > inp) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels);
for (; inp > -step; inp -= step, oup--) {
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatHistogram.java
index 7f034152..a7cb7153 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/FloatStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatStaticHistogram.java
index 063bd80a..c42c0bec 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatStaticHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatStaticHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/Histogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/Histogram.java
index 8c8d9a87..7e94d522 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/Histogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/Histogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/IntArrayStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntArrayStaticHistogram.java
index ff9a82aa..784fe86b 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntArrayStaticHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntArrayStaticHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/IntDynamicHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntDynamicHistogram.java
index b131af7d..f241b036 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntDynamicHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntDynamicHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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
@@ -162,10 +162,12 @@ public class IntDynamicHistogram extends IntStaticHistogram {
assert (levels > 0) : "No resampling required?!? sizereq=" + sizereq + " destsize=" + destsize + " array=" + data.length;
final int step = 1 << levels;
+ // We want to map [i ... i+step[ -> (i+off)/step
+ // Fix point: i = (i+off)/step; i*(step-1)=off; i=off/(step-1)
final int fixpoint = off / (step - 1);
{
// Start positions for in-place bottom-up downsampling.
- int oup = fixpoint;
+ int oup = (fixpoint >= 0) ? fixpoint : 0;
int inp = (oup << levels) - off;
assert (-step < inp && inp <= oup && oup < inp + step) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels);
for (; inp < size; inp += step, oup++) {
@@ -177,9 +179,9 @@ public class IntDynamicHistogram extends IntStaticHistogram {
data[oup] = 0;
}
}
- if (off > 0) {
+ if (off >= step) {
// Start positions for in-place downsampling top-down:
- int oup = fixpoint - 1;
+ int oup = (fixpoint - 1 < size) ? fixpoint - 1 : size - 1;
int inp = (oup << levels) - off;
assert (oup > inp) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels);
for (; inp > -step; inp -= step, oup--) {
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntHistogram.java
index 9bfae100..94cf6b34 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/IntStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntStaticHistogram.java
index 84b55cd1..96f57399 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntStaticHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntStaticHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/LongArrayStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongArrayStaticHistogram.java
index e3580792..8447d3ba 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongArrayStaticHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongArrayStaticHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/LongDynamicHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongDynamicHistogram.java
index 93c4eee5..d1f8d8fd 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongDynamicHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongDynamicHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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
@@ -162,10 +162,12 @@ public class LongDynamicHistogram extends LongStaticHistogram {
assert (levels > 0) : "No resampling required?!? sizereq=" + sizereq + " destsize=" + destsize + " array=" + data.length;
final int step = 1 << levels;
+ // We want to map [i ... i+step[ -> (i+off)/step
+ // Fix point: i = (i+off)/step; i*(step-1)=off; i=off/(step-1)
final int fixpoint = off / (step - 1);
{
// Start positions for in-place bottom-up downsampling.
- int oup = fixpoint;
+ int oup = (fixpoint >= 0) ? fixpoint : 0;
int inp = (oup << levels) - off;
assert (-step < inp && inp <= oup && oup < inp + step) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels);
for (; inp < size; inp += step, oup++) {
@@ -177,9 +179,9 @@ public class LongDynamicHistogram extends LongStaticHistogram {
data[oup] = 0;
}
}
- if (off > 0) {
+ if(off >= step) {
// Start positions for in-place downsampling top-down:
- int oup = fixpoint - 1;
+ int oup = (fixpoint - 1 < size) ? fixpoint - 1 : size - 1;
int inp = (oup << levels) - off;
assert (oup > inp) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels);
for (; inp > -step; inp -= step, oup--) {
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongHistogram.java
index 16577c38..c55f7705 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/LongStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongStaticHistogram.java
index b270908d..6d8b8cf7 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongStaticHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongStaticHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/MeanVarianceStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/MeanVarianceStaticHistogram.java
index 0f1ea0a3..7b9c648c 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/MeanVarianceStaticHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/MeanVarianceStaticHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/ObjHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ObjHistogram.java
index bad4eec1..9546efee 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ObjHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ObjHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/ShortDynamicHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortDynamicHistogram.java
index a49810ee..4a6a3de7 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortDynamicHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortDynamicHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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
@@ -162,10 +162,12 @@ public class ShortDynamicHistogram extends ShortStaticHistogram {
assert (levels > 0) : "No resampling required?!? sizereq=" + sizereq + " destsize=" + destsize + " array=" + data.length;
final int step = 1 << levels;
+ // We want to map [i ... i+step[ -> (i+off)/step
+ // Fix point: i = (i+off)/step; i*(step-1)=off; i=off/(step-1)
final int fixpoint = off / (step - 1);
{
// Start positions for in-place bottom-up downsampling.
- int oup = fixpoint;
+ int oup = (fixpoint >= 0) ? fixpoint : 0;
int inp = (oup << levels) - off;
assert (-step < inp && inp <= oup && oup < inp + step) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels);
for (; inp < size; inp += step, oup++) {
@@ -177,9 +179,9 @@ public class ShortDynamicHistogram extends ShortStaticHistogram {
data[oup] = 0;
}
}
- if (off > 0) {
+ if(off >= step) {
// Start positions for in-place downsampling top-down:
- int oup = fixpoint - 1;
+ int oup = (fixpoint - 1 < size) ? fixpoint - 1 : size - 1;
int inp = (oup << levels) - off;
assert (oup > inp) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels);
for (; inp > -step; inp -= step, oup--) {
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortHistogram.java
index 0b83bc4c..4e65e3a7 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/ShortStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortStaticHistogram.java
index 2819d966..375e5945 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortStaticHistogram.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortStaticHistogram.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
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/utilities/datastructures/histogram/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/package-info.java
index cee1836b..702bd0a5 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/package-info.java
@@ -13,7 +13,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/utilities/datastructures/iterator/ArrayIter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayIter.java
index 7b2a96ad..fe3c54f0 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayIter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayIter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.iterator;
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,29 +31,36 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.iterator;
* @apiviz.excludeSubtypes
*/
public interface ArrayIter extends Iter {
- /**
- * Get current iterator offset.
- *
- * @return Iterator position
- */
- public int getOffset();
+ @Override
+ ArrayIter advance();
/**
* Moves the iterator forward or backward by the given offset.
*
* @param count offset to move forward or backwards
+ * @return Iterator
*/
- public void advance(int count);
+ ArrayIter advance(int count);
/**
* Moves the iterator backward to the previous entry.
+ *
+ * @return Iterator
*/
- public void retract();
+ ArrayIter retract();
/**
* Moves the iterator to the given position
*
* @param off Seek offset
+ * @return Iterator
+ */
+ ArrayIter seek(int off);
+
+ /**
+ * Get current iterator offset.
+ *
+ * @return Iterator position
*/
- public void seek(int off);
+ int getOffset();
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayListIter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayListIter.java
index 820217ec..68cd0448 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayListIter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayListIter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.iterator;
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
@@ -60,12 +60,13 @@ public class ArrayListIter<O> implements ArrayIter {
@Override
public boolean valid() {
- return pos < data.size();
+ return pos < data.size() && pos >= 0;
}
@Override
- public void advance() {
+ public ArrayIter advance() {
pos++;
+ return this;
}
@Override
@@ -74,18 +75,21 @@ public class ArrayListIter<O> implements ArrayIter {
}
@Override
- public void advance(int count) {
+ public ArrayIter advance(int count) {
pos += count;
+ return this;
}
@Override
- public void retract() {
+ public ArrayIter retract() {
pos--;
+ return this;
}
@Override
- public void seek(int off) {
+ public ArrayIter seek(int off) {
pos = off;
+ return this;
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/Iter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/Iter.java
index 3d111f14..b6ff34ad 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/Iter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/Iter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.iterator;
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
@@ -62,10 +62,12 @@ public interface Iter {
*
* @return a <code>boolean</code> value, whether the position is valid.
*/
- public boolean valid();
+ boolean valid();
/**
* Moves the iterator forward to the next entry.
+ *
+ * @return The iterator itself.
*/
- public void advance();
+ Iter advance();
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/MIter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/MIter.java
index 14e5443d..76be972f 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/MIter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/MIter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.iterator;
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/utilities/datastructures/iterator/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/package-info.java
index d241fcc4..17dc7e44 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/package-info.java
@@ -19,7 +19,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/utilities/datastructures/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/package-info.java
index a0d894a9..db324217 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/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/utilities/documentation/Description.java b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Description.java
index 3ce24e4e..e63ca693 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/documentation/Description.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Description.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.documentation;
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/utilities/documentation/DocumentationUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/documentation/DocumentationUtil.java
index a1d649d4..336dd4db 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/documentation/DocumentationUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/documentation/DocumentationUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.documentation;
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/utilities/documentation/Reference.java b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Reference.java
index 8d2768e2..c9f13e64 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/documentation/Reference.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Reference.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.documentation;
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
@@ -36,7 +36,7 @@ import java.lang.annotation.Target;
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
-@Target( { ElementType.TYPE, ElementType.METHOD, ElementType.FIELD })
+@Target( { ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PACKAGE })
public @interface Reference {
/**
* Publication title.
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/documentation/Restricted.java b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Restricted.java
index 0cb205df..e4f6bc68 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/documentation/Restricted.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Restricted.java
@@ -10,7 +10,7 @@ import java.lang.annotation.Target;
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/utilities/documentation/Title.java b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Title.java
index c77ca875..0c832526 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/documentation/Title.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Title.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.documentation;
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/utilities/documentation/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/documentation/package-info.java
index d6f9ac3c..dd7ced9d 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/documentation/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/documentation/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/utilities/ensemble/EnsembleVoting.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVoting.java
index 47c46d46..b8e67e76 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVoting.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVoting.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble;
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.utilities.ensemble;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
-
/**
* Interface for ensemble voting rules
*
* @author Erich Schubert
*/
-public interface EnsembleVoting extends Parameterizable {
+public interface EnsembleVoting {
/**
* Combine scores function. Note: it is assumed that the scores are
* comparable.
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingInverseMultiplicative.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingInverseMultiplicative.java
index 2e082761..bc511b1a 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingInverseMultiplicative.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingInverseMultiplicative.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble;
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/utilities/ensemble/EnsembleVotingMax.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMax.java
index e179999d..67fbade9 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMax.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMax.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble;
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,8 +30,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble;
*/
public class EnsembleVotingMax implements EnsembleVoting {
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public EnsembleVotingMax() {
// empty
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMean.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMean.java
index 19643782..08b3fada 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMean.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMean.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble;
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,8 +30,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble;
*/
public class EnsembleVotingMean implements EnsembleVoting {
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public EnsembleVotingMean() {
// Empty.
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMedian.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMedian.java
index 85e7f6c8..8d3f5ff2 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMedian.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMedian.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble;
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/utilities/ensemble/EnsembleVotingMin.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMin.java
index b4baa4ab..9b7b754d 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMin.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMin.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble;
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,8 +31,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble;
*/
public class EnsembleVotingMin implements EnsembleVoting {
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public EnsembleVotingMin() {
// empty
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMultiplicative.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMultiplicative.java
index 3d99b8aa..bb941b5a 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMultiplicative.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMultiplicative.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble;
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/utilities/ensemble/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/package-info.java
index 76ee4ab8..552607dd 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/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/utilities/exceptions/APIViolationException.java b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/APIViolationException.java
index ab6430f4..5271a9d3 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/APIViolationException.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/APIViolationException.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.exceptions;
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/utilities/exceptions/AbortException.java b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/AbortException.java
index 21179a62..9fda136a 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/AbortException.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/AbortException.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.exceptions;
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/utilities/exceptions/ExceptionMessages.java b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/ExceptionMessages.java
index cdaa6220..1214afeb 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/ExceptionMessages.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/ExceptionMessages.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.exceptions;
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,12 +40,6 @@ public interface ExceptionMessages {
public static final String DATABASE_EMPTY = "database empty: must contain elements";
/**
- * Message when a new label was discovered in a database, that did not exist
- * before.
- */
- public static final String INCONSISTENT_STATE_NEW_LABEL = "inconsistent state of database - found new label";
-
- /**
* Message when an empty clustering is encountered.
*/
public static final String CLUSTERING_EMPTY = "Clustering doesn't contain any cluster.";
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/NotImplementedException.java b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/NotImplementedException.java
index 343a5b38..ecd644f0 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/NotImplementedException.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/NotImplementedException.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.exceptions;
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/utilities/exceptions/ObjectNotFoundException.java b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/ObjectNotFoundException.java
index 266ad0bb..1014e37c 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/ObjectNotFoundException.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/ObjectNotFoundException.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.exceptions;
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/utilities/exceptions/UnableToComplyException.java b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/UnableToComplyException.java
index ecb80950..2d90d58f 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/UnableToComplyException.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/UnableToComplyException.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.exceptions;
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/utilities/exceptions/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/package-info.java
index b55fd8ee..a156d821 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/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/persistent/ByteArrayUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteArrayUtil.java
index ba25435f..20225ded 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/ByteArrayUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteArrayUtil.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.persistent;
+package de.lmu.ifi.dbs.elki.utilities.io;
/*
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/persistent/ByteBufferInputStream.java b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferInputStream.java
index dbc5ed2d..57cd352d 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/ByteBufferInputStream.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferInputStream.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.persistent;
+package de.lmu.ifi.dbs.elki.utilities.io;
/*
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/persistent/ByteBufferOutputStream.java b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferOutputStream.java
index 28137393..d589a782 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/ByteBufferOutputStream.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferOutputStream.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.persistent;
+package de.lmu.ifi.dbs.elki.utilities.io;
/*
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/persistent/ByteBufferSerializer.java b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferSerializer.java
index 8605dd07..c20e999b 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/ByteBufferSerializer.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferSerializer.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.persistent;
+package de.lmu.ifi.dbs.elki.utilities.io;
/*
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/persistent/FixedSizeByteBufferSerializer.java b/src/de/lmu/ifi/dbs/elki/utilities/io/FixedSizeByteBufferSerializer.java
index a1d8600c..b46c5ac8 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/FixedSizeByteBufferSerializer.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/io/FixedSizeByteBufferSerializer.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.persistent;
+package de.lmu.ifi.dbs.elki.utilities.io;
/*
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.persistent;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
/**
* Serializers with a fixed length serialization.
*
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/io/LineReader.java b/src/de/lmu/ifi/dbs/elki/utilities/io/LineReader.java
new file mode 100644
index 00000000..115a5df6
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/utilities/io/LineReader.java
@@ -0,0 +1,122 @@
+package de.lmu.ifi.dbs.elki.utilities.io;
+
+/*
+ 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.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+/**
+ * Fast class to read a file, line per line.
+ *
+ * Lines must be split using Unix newlines <code>\n</code>, linefeeds
+ * <code>\r</code> are ignored.
+ *
+ * This is a rather minimal implementation, which supposedly pays off in
+ * performance. In particular, this class allows recycling the buffer, which
+ * will yield less object allocations and thus less garbage collection.
+ *
+ * Usage example:
+ *
+ * <pre>
+ * StringBuilder buf = new StringBuilder();
+ * LineReader reader = new LineReader(inputStream);
+ * // Clear buffer, and append next line.
+ * while(reader.readLine(buf.delete(0, buf.length()))) {
+ * // process string in buffer.
+ * }
+ * </pre>
+ *
+ * @author Erich Schubert
+ */
+public class LineReader implements AutoCloseable {
+ /** Buffer size to use */
+ final static int BUFFER_SIZE = 4096;
+
+ /** Input stream to read from */
+ Reader in;
+
+ /** Character buffer */
+ char[] buffer = new char[BUFFER_SIZE];
+
+ /** Current position, and length of buffer */
+ int pos = 0, end = 0;
+
+ /**
+ * Constructor
+ *
+ * @param in Stream
+ */
+ public LineReader(InputStream in) {
+ this(new InputStreamReader(in));
+ }
+
+ /**
+ * Constructor
+ *
+ * @param in Reader
+ */
+ public LineReader(Reader in) {
+ this.in = in;
+ }
+
+ /**
+ * Read a line into the given buffer.
+ *
+ * @param buf Buffer.
+ * @return {@code true} if some characters have been read.
+ */
+ public boolean readLine(Appendable buf) throws IOException {
+ boolean success = false;
+ while(true) {
+ // Process buffer:
+ while(pos < end) {
+ success = true;
+ final char c = buffer[pos++];
+ if(c == '\n') {
+ return success;
+ }
+ if(c == '\r') {
+ continue;
+ }
+ buf.append(c);
+ }
+ // Refill buffer:
+ assert (pos >= end) : "Buffer wasn't empty when refilling!";
+ end = in.read(buffer, 0, buffer.length);
+ pos = 0;
+ if(end < 0) { // End of stream.
+ return success;
+ }
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if(in != null) {
+ in.close();
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/Tokenizer.java b/src/de/lmu/ifi/dbs/elki/utilities/io/Tokenizer.java
index 0cf4c81a..497c1a2b 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/Tokenizer.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/io/Tokenizer.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.datasource.parser;
+package de.lmu.ifi.dbs.elki.utilities.io;
/*
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
@@ -42,11 +42,6 @@ public class Tokenizer implements Iter {
private static final Logging LOG = Logging.getLogger(Tokenizer.class);
/**
- * Separator pattern.
- */
- private Pattern colSep;
-
- /**
* Quote characters
*/
public static final String QUOTE_CHAR = "\"'";
@@ -64,14 +59,14 @@ public class Tokenizer implements Iter {
*/
public Tokenizer(Pattern colSep, String quoteChars) {
super();
- this.colSep = colSep;
- this.quoteChars = quoteChars.toCharArray();
+ this.matcher = colSep.matcher("Dummy text");
+ this.quoteChars = quoteChars != null ? quoteChars.toCharArray() : new char[0];
}
/**
* Regular expression match helper.
*/
- private Matcher m = null;
+ private Matcher matcher;
/**
* Data currently processed.
@@ -89,6 +84,11 @@ public class Tokenizer implements Iter {
private int start, end, index;
/**
+ * Whether the current token is a quoted string.
+ */
+ private boolean quoted;
+
+ /**
* Initialize parser with a new string.
*
* @param input New string to parse.
@@ -98,7 +98,7 @@ public class Tokenizer implements Iter {
public void initialize(CharSequence input, int begin, int end) {
this.input = input;
this.send = end;
- this.m = colSep.matcher(input).region(begin, end);
+ this.matcher.reset(input).region(begin, end);
this.index = begin;
advance();
}
@@ -109,41 +109,46 @@ public class Tokenizer implements Iter {
}
@Override
- public void advance() {
+ public Tokenizer advance() {
char inquote = isQuote(index);
- while(m.find()) {
+ while(matcher.find()) {
// Quoted code path vs. regular code path
if(inquote != 0) {
// Matching closing quote found?
- if(m.start() > index + 1 && input.charAt(m.start() - 1) == inquote) {
+ if(matcher.start() > index + 1 && input.charAt(matcher.start() - 1) == inquote) {
this.start = index + 1;
- this.end = m.start() - 1;
- this.index = m.end();
- return;
+ this.end = matcher.start() - 1;
+ this.index = matcher.end();
+ this.quoted = true;
+ return this;
}
continue;
}
else {
this.start = index;
- this.end = m.start();
- this.index = m.end();
- return;
+ this.end = matcher.start();
+ this.index = matcher.end();
+ this.quoted = false;
+ return this;
}
}
// Add tail after last separator.
this.start = index;
this.end = send;
this.index = end + 1;
+ this.quoted = false;
if(inquote != 0) {
final int last = send - 1;
if(input.charAt(last) == inquote) {
++this.start;
--this.end;
+ this.quoted = true;
}
else {
LOG.warning("Invalid quoted line in input: no closing quote found in: " + input);
}
}
+ return this;
}
/**
@@ -158,6 +163,32 @@ public class Tokenizer implements Iter {
}
/**
+ * Get the current part as substring
+ *
+ * @return Current value as substring.
+ */
+ public String getStrippedSubstring() {
+ // TODO: detect Java <6 and make sure we only return the substring?
+ // With java 7, String.substring will arraycopy the characters.
+ int sstart = start, send = end;
+ while(sstart < send) {
+ char c = input.charAt(sstart);
+ if(c != ' ' || c != '\n' || c != '\r' || c != '\t') {
+ break;
+ }
+ ++sstart;
+ }
+ while(--send >= sstart) {
+ char c = input.charAt(send);
+ if(c != ' ' || c != '\n' || c != '\r' || c != '\t') {
+ break;
+ }
+ }
+ ++send;
+ return (sstart < send) ? input.subSequence(sstart, send).toString() : "";
+ }
+
+ /**
* Get current value as double.
*
* @return double value
@@ -211,6 +242,15 @@ public class Tokenizer implements Iter {
}
/**
+ * Test if the current string was quoted.
+ *
+ * @return {@code true} when quoted.
+ */
+ public boolean isQuoted() {
+ return quoted;
+ }
+
+ /**
* Get start of token.
*
* @return Start
@@ -227,4 +267,12 @@ public class Tokenizer implements Iter {
public int getEnd() {
return end;
}
+
+ /**
+ * Perform cleanup.
+ */
+ public void cleanup() {
+ input = null;
+ matcher.reset("");
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/io/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/io/package-info.java
new file mode 100644
index 00000000..3518e7b7
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/utilities/io/package-info.java
@@ -0,0 +1,29 @@
+/**
+ * Utility classes for input/output.
+ *
+ * @author Erich Schubert
+ */
+
+/*
+ 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.utilities.io; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/AbstractParameterizer.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/AbstractParameterizer.java
index 6aa22964..0fa9b240 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/AbstractParameterizer.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/AbstractParameterizer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling;
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/utilities/optionhandling/InternalParameterizationErrors.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/InternalParameterizationErrors.java
index 1cff200a..aa77c364 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/InternalParameterizationErrors.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/InternalParameterizationErrors.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling;
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/utilities/optionhandling/NoParameterValueException.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/NoParameterValueException.java
index 53d992ff..e0266028 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/NoParameterValueException.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/NoParameterValueException.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling;
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/utilities/optionhandling/OptionID.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionID.java
index 60e51a98..60afb2b1 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionID.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionID.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling;
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
@@ -42,10 +42,7 @@ public final class OptionID {
private String description;
/**
- * Provides a new OptionID of the given name and description.
- * <p/>
- * All OptionIDs are unique w.r.t. their name. An OptionID provides
- * additionally a description of the option.
+ * Constructor.
*
* @param name the name of the option
* @param description the description of the option
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionUtil.java
index ea28aa42..32d7a84d 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling;
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,10 +31,10 @@ import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.DocumentationUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackedParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.SerializedParameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Utility functions related to Option handling.
@@ -123,11 +123,11 @@ public final class OptionUtil {
* @param indent Indentation string
* @param options List of options
*/
- public static void formatForConsole(StringBuilder buf, int width, String indent, Collection<Pair<Object, Parameter<?>>> options) {
- for(Pair<Object, Parameter<?>> pair : options) {
- String currentOption = pair.getSecond().getName();
- String syntax = pair.getSecond().getSyntax();
- String longDescription = pair.getSecond().getFullDescription();
+ public static void formatForConsole(StringBuilder buf, int width, String indent, Collection<TrackedParameter> options) {
+ for(TrackedParameter pair : options) {
+ String currentOption = pair.getParameter().getName();
+ String syntax = pair.getParameter().getSyntax();
+ String longDescription = pair.getParameter().getFullDescription();
buf.append(SerializedParameterization.OPTION_PREFIX);
buf.append(currentOption);
@@ -196,7 +196,7 @@ public final class OptionUtil {
TrackParameters track = new TrackParameters(config);
@SuppressWarnings("unused")
Object p = ClassGenericsUtil.tryInstantiate(Object.class, pcls, track);
- Collection<Pair<Object, Parameter<?>>> options = track.getAllParameters();
+ Collection<TrackedParameter> options = track.getAllParameters();
if(options.size() > 0) {
OptionUtil.formatForConsole(buf, width, indent, options);
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/ParameterException.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/ParameterException.java
index 326335fd..0c9d5421 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/ParameterException.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/ParameterException.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling;
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/utilities/optionhandling/Parameterizable.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizable.java
deleted file mode 100644
index ead565b1..00000000
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizable.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.optionhandling;
-
-/*
- 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/>.
- */
-
-/**
- * Interface to define the required methods for command line interaction.
- *
- * <b>Important note:</b>
- *
- * <p>
- * Although <em>this cannot be specified in a Java interface</em>, any class
- * implementing this interface <em>must</em> also have a constructor that takes
- * a single
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization}
- * as option, which is used to set the class parameters.
- * </p>
- *
- * <p>
- * Alternatively, a constructor with no options is also allowed.
- * </p>
- *
- * <p>
- * This means, each class implementing Parameterizable
- * <em>must have a constructor that either is</em> <blockquote>
- *
- * <pre>
- * {@code
- * public Class(Parameterizable config) { ... }
- * }
- * </pre>
- *
- * </blockquote> or <blockquote>
- *
- * <pre>
- * {@code
- * public Class() { ... }
- * }
- * </pre>
- *
- * </blockquote>
- * </p>
- *
- * <p>
- * Constructors <em>MUST</em> not do expensive operations or allocations, since
- * they will also be called just to determine and validate parameters.
- * </p>
- *
- * <p>
- * For <em>documentation</em>, the classes should also be annotated with
- * {@link de.lmu.ifi.dbs.elki.utilities.documentation.Title}
- * {@link de.lmu.ifi.dbs.elki.utilities.documentation.Description} and
- * {@link de.lmu.ifi.dbs.elki.utilities.documentation.Reference} (where
- * possible).
- * </p>
- *
- * <p>
- * Please check the <em>package documentation</em> for full information on this
- * interface.
- * </p>
- *
- * <p>
- * The application
- * {@link de.lmu.ifi.dbs.elki.application.internal.CheckParameterizables} can be
- * used to check this class contracts.
- * </p>
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- * @apiviz.excludeSubtypes
- * @apiviz.has de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter
- * oneway - n
- * @apiviz.uses de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization
- * .Parameterization oneway
- */
-public interface Parameterizable {
- // Empty marker interface - the \@Description / \@Title / \@Reference and
- // constructor requirements cannot be specified in Java!
-}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizer.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizer.java
index 7e3a848c..b7017206 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizer.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling;
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/utilities/optionhandling/UnspecifiedParameterException.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnspecifiedParameterException.java
index 31af6d87..8d22b113 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnspecifiedParameterException.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnspecifiedParameterException.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling;
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/utilities/optionhandling/UnusedParameterException.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnusedParameterException.java
index d5dbd4b2..6bd13429 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnusedParameterException.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnusedParameterException.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling;
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/utilities/optionhandling/WrongParameterValueException.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/WrongParameterValueException.java
index eeb6a9e7..3f34efb7 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/WrongParameterValueException.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/WrongParameterValueException.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling;
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
@@ -54,7 +54,7 @@ public class WrongParameterValueException extends ParameterException {
* @param cause the cause
*/
public WrongParameterValueException(Parameter<?> parameter, String read, Throwable cause) {
- this("Wrong value of parameter \"" + parameter.getName() + "\".\n" + "Read: " + read + ".\n" + "Expected: " + parameter.getFullDescription() + "\n" + cause.getMessage(), cause);
+ this("Wrong value of parameter \"" + parameter.getName() + "\".\n" + "Read: " + read + ".\n" + "Expected: " + parameter.getFullDescription() + "\n" + formatCause(cause), cause);
}
/**
@@ -66,7 +66,7 @@ public class WrongParameterValueException extends ParameterException {
* @param cause the cause
*/
public WrongParameterValueException(Parameter<?> parameter, String read, String reason, Throwable cause) {
- this("Wrong value of parameter " + parameter.getName() + ".\n" + "Read: " + read + ".\n" + "Expected: " + parameter.getFullDescription() + "\n" + reason + "\n" + cause.getMessage(), cause);
+ this("Wrong value of parameter " + parameter.getName() + ".\n" + "Read: " + read + ".\n" + "Expected: " + parameter.getFullDescription() + "\n" + reason + "\n" + formatCause(cause), cause);
}
/**
@@ -98,4 +98,21 @@ public class WrongParameterValueException extends ParameterException {
public WrongParameterValueException(String message, Throwable e) {
super(message, e);
}
+
+ /**
+ * Format the error cause.
+ *
+ * @param cause Error cause.
+ * @return String representation
+ */
+ private static String formatCause(Throwable cause) {
+ if(cause == null) {
+ return "";
+ }
+ String message = cause.getMessage();
+ if(message != null) {
+ return message;
+ }
+ return cause.toString();
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AbstractNumberConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AbstractNumberConstraint.java
index fc4a673e..edd6166e 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AbstractNumberConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AbstractNumberConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/AllOrNoneMustBeSetGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AllOrNoneMustBeSetGlobalConstraint.java
index a87af1a8..dfa9ffae 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AllOrNoneMustBeSetGlobalConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AllOrNoneMustBeSetGlobalConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/CommonConstraints.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/CommonConstraints.java
index ea1caed9..6464ed13 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/CommonConstraints.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/CommonConstraints.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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,6 +29,9 @@ import java.util.List;
* Class storing a number of very common constraints.
*
* @author Erich Schubert
+ *
+ * @apiviz.landmark
+ * @apiviz.composedOf ParameterConstraint
*/
public final class CommonConstraints {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualSizeGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualSizeGlobalConstraint.java
index 586b4257..56ecd0b6 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualSizeGlobalConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualSizeGlobalConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/EqualStringConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualStringConstraint.java
index 1ab35cc1..3dda08b6 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualStringConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualStringConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/GlobalListSizeConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalListSizeConstraint.java
index 7c35045e..997e7295 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalListSizeConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalListSizeConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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
@@ -71,7 +71,7 @@ public class GlobalListSizeConstraint implements GlobalParameterConstraint {
return;
}
- if(list.getListSize() != length.getValue().intValue()) {
+ if(list.getListSize() != length.intValue()) {
throw new WrongParameterValueException("Global Parameter Constraint Error." + "\nThe size of the list parameter \"" + list.getName() + "\" must be " + length.getValue() + ", current size is " + list.getListSize() + ". The value is defined by the integer parameter " + length.getName() + ".\n");
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalParameterConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalParameterConstraint.java
index 5e38b2b7..e249e0ef 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalParameterConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalParameterConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/GlobalVectorListElementSizeConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalVectorListElementSizeConstraint.java
index 01c99d42..9afd0a56 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalVectorListElementSizeConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalVectorListElementSizeConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.List;
-
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
@@ -74,8 +73,8 @@ public class GlobalVectorListElementSizeConstraint implements GlobalParameterCon
return;
}
- for(List<Double> vec : vector.getValue()) {
- if(vec.size() != size.getValue().intValue()) {
+ for(Vector vec : vector.getValue()) {
+ if(vec.getDimensionality() != size.intValue()) {
throw new WrongParameterValueException("Global Parameter Constraint Error.\n" + "The vectors of vector list parameter " + vector.getName() + " have not the required dimension of " + size.getValue() + " given by integer parameter " + size.getName() + ".");
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterConstraint.java
index 33c73fb8..8ec817e9 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/GreaterEqualConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterEqualConstraint.java
index d05235c1..ba3d63e9 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterEqualConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterEqualConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/IntervalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/IntervalConstraint.java
deleted file mode 100644
index 00c2f5ad..00000000
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/IntervalConstraint.java
+++ /dev/null
@@ -1,217 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
-
-/*
- 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.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException;
-
-/**
- * Represents an interval parameter constraint testing if a given value lies
- * within the specified interval. The value of the number parameter (
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.NumberParameter}
- * ) tested has to be greater than (or equal to, if specified) than the
- * specified low constraint value and less than (or equal to, if specified) than
- * the specified high constraint value.
- *
- * @author Steffi Wanka
- *
- * @apiviz.uses de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.NumberParameter
- *
- * @deprecated Use two constraints instead.
- */
-@Deprecated
-public class IntervalConstraint implements ParameterConstraint<Number> {
- /**
- * Available interval boundary types types:
- * {@link IntervalConstraint.IntervalBoundary#OPEN} denotes an open interval,
- * i.e. less than (or greater than) comparison
- * {@link IntervalConstraint.IntervalBoundary#CLOSE} denotes a closed
- * interval, i.e. an equal to or less than (or equal to or greater than)
- * comparison
- *
- * @apiviz.exclude
- */
- public enum IntervalBoundary {
- /**
- * Open interval boundary
- */
- OPEN,
- /**
- * Closed interval boundary
- */
- CLOSE
- }
-
- /**
- * The low constraint value (left interval boundary).
- */
- private final Number lowConstraintValue;
-
- /**
- * The interval boundary for the low constraint value.
- *
- * @see IntervalBoundary
- */
- private final IntervalBoundary lowBoundary;
-
- /**
- * The high constraint value (right interval boundary).
- */
- private final Number highConstraintValue;
-
- /**
- * The interval boundary for the high constraint value.
- *
- * @see IntervalBoundary
- */
- private final IntervalBoundary highBoundary;
-
- /**
- * Creates an IntervalConstraint parameter constraint.
- * <p/>
- * That is, the value of the number parameter given has to be greater than (or
- * equal to, if specified) than the specified low constraint value and less
- * than (or equal to, if specified) than the specified high constraint value.
- *
- * @param lowConstraintValue the low constraint value (left interval boundary)
- * @param lowBoundary the interval boundary for the low constraint value (see {@link IntervalBoundary})
- * @param highConstraintValue the high constraint value (right interval
- * boundary)
- * @param highBoundary the interval boundary for the high constraint value
- * (see {@link IntervalBoundary})
- */
- public IntervalConstraint(Number lowConstraintValue, IntervalBoundary lowBoundary, Number highConstraintValue, IntervalBoundary highBoundary) {
- if(lowConstraintValue.doubleValue() >= highConstraintValue.doubleValue()) {
- throw new IllegalArgumentException("Left interval boundary is greater than " + "or equal to right interval boundary!");
- }
-
- this.lowConstraintValue = lowConstraintValue;
- this.lowBoundary = lowBoundary;
- this.highConstraintValue = highConstraintValue;
- this.highBoundary = highBoundary;
- }
-
- /**
- * Creates an IntervalConstraint parameter constraint.
- * <p/>
- * That is, the value of the number parameter given has to be greater than (or
- * equal to, if specified) than the specified low constraint value and less
- * than (or equal to, if specified) than the specified high constraint value.
- *
- * @param lowConstraintValue the low constraint value (left interval boundary)
- * @param lowBoundary the interval boundary for the low constraint value (see {@link IntervalBoundary})
- * @param highConstraintValue the high constraint value (right interval
- * boundary)
- * @param highBoundary the interval boundary for the high constraint value
- * (see {@link IntervalBoundary})
- */
- public IntervalConstraint(int lowConstraintValue, IntervalBoundary lowBoundary, int highConstraintValue, IntervalBoundary highBoundary) {
- if(lowConstraintValue >= highConstraintValue) {
- throw new IllegalArgumentException("Left interval boundary is greater than " + "or equal to right interval boundary!");
- }
-
- this.lowConstraintValue = Integer.valueOf(lowConstraintValue);
- this.lowBoundary = lowBoundary;
- this.highConstraintValue = Integer.valueOf(highConstraintValue);
- this.highBoundary = highBoundary;
- }
-
- /**
- * Creates an IntervalConstraint parameter constraint.
- * <p/>
- * That is, the value of the number parameter given has to be greater than (or
- * equal to, if specified) than the specified low constraint value and less
- * than (or equal to, if specified) than the specified high constraint value.
- *
- * @param lowConstraintValue the low constraint value (left interval boundary)
- * @param lowBoundary the interval boundary for the low constraint value (see {@link IntervalBoundary})
- * @param highConstraintValue the high constraint value (right interval
- * boundary)
- * @param highBoundary the interval boundary for the high constraint value
- * (see {@link IntervalBoundary})
- */
- public IntervalConstraint(double lowConstraintValue, IntervalBoundary lowBoundary, double highConstraintValue, IntervalBoundary highBoundary) {
- if(lowConstraintValue >= highConstraintValue) {
- throw new IllegalArgumentException("Left interval boundary is greater than " + "or equal to right interval boundary!");
- }
-
- this.lowConstraintValue = Double.valueOf(lowConstraintValue);
- this.lowBoundary = lowBoundary;
- this.highConstraintValue = Double.valueOf(highConstraintValue);
- this.highBoundary = highBoundary;
- }
-
- /**
- * Checks if the number value given by the number parameter is greater equal
- * than the constraint value. If not, a parameter exception is thrown.
- *
- */
- @Override
- public void test(Number t) throws ParameterException {
- // lower value
- if(lowBoundary.equals(IntervalBoundary.CLOSE)) {
- if(t.doubleValue() < lowConstraintValue.doubleValue()) {
- throw new WrongParameterValueException("Parameter Constraint Error: \n" + "The parameter value specified has to be " + "equal to or greater than " + lowConstraintValue.toString() + ". (current value: " + t.doubleValue() + ")\n");
- }
- }
- else if(lowBoundary.equals(IntervalBoundary.OPEN)) {
- if(t.doubleValue() <= lowConstraintValue.doubleValue()) {
- throw new WrongParameterValueException("Parameter Constraint Error: \n" + "The parameter value specified has to be " + "greater than " + lowConstraintValue.toString() + ". (current value: " + t.doubleValue() + ")\n");
- }
- }
-
- // higher value
- if(highBoundary.equals(IntervalBoundary.CLOSE)) {
- if(t.doubleValue() > highConstraintValue.doubleValue()) {
- throw new WrongParameterValueException("Parameter Constraint Error: \n" + "The parameter value specified has to be " + "equal to or less than " + highConstraintValue.toString() + ". (current value: " + t.doubleValue() + ")\n");
- }
- }
- else if(highBoundary.equals(IntervalBoundary.OPEN)) {
- if(t.doubleValue() >= highConstraintValue.doubleValue()) {
- throw new WrongParameterValueException("Parameter Constraint Error: \n" + "The parameter value specified has to be " + "less than " + highConstraintValue.toString() + ". (current value: " + t.doubleValue() + ")\n");
- }
- }
- }
-
- @Override
- public String getDescription(String parameterName) {
- String description = parameterName + " in ";
- if(lowBoundary.equals(IntervalBoundary.CLOSE)) {
- description += "[";
- }
- else if(lowBoundary.equals(IntervalBoundary.OPEN)) {
- description += "(";
- }
-
- description += lowConstraintValue.toString() + ", " + highConstraintValue;
-
- if(highBoundary.equals(IntervalBoundary.CLOSE)) {
- description += "]";
- }
- if(highBoundary.equals(IntervalBoundary.OPEN)) {
- description += ")";
- }
- return description;
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessConstraint.java
index 5c4d0635..e4273272 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/LessEqualConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualConstraint.java
index d81c821b..ce84412a 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/LessEqualGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualGlobalConstraint.java
index 9fa0ee99..aae6012e 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualGlobalConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualGlobalConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/LessGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessGlobalConstraint.java
index 989f6e29..cbc29edf 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessGlobalConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessGlobalConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/ListEachConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListEachConstraint.java
index 918c59f5..a561b884 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListEachConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListEachConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/ListParameterNoDuplicateValueConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListParameterNoDuplicateValueConstraint.java
index 1ff23f80..533db703 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListParameterNoDuplicateValueConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListParameterNoDuplicateValueConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/ListSizeConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListSizeConstraint.java
index 95b5214b..b23ae76d 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListSizeConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListSizeConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/NoDuplicateValueGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/NoDuplicateValueGlobalConstraint.java
index 7036ecef..c6d9d93f 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/NoDuplicateValueGlobalConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/NoDuplicateValueGlobalConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/OneMustBeSetGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OneMustBeSetGlobalConstraint.java
index e7802685..fd708d47 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OneMustBeSetGlobalConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OneMustBeSetGlobalConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/OnlyOneIsAllowedToBeSetGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OnlyOneIsAllowedToBeSetGlobalConstraint.java
index bdd55572..0a22096f 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OnlyOneIsAllowedToBeSetGlobalConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OnlyOneIsAllowedToBeSetGlobalConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/ParameterConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterConstraint.java
index 2847260a..fa600907 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/ParameterFlagGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterFlagGlobalConstraint.java
index ab77240a..87db36dc 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterFlagGlobalConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterFlagGlobalConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/StringLengthConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/StringLengthConstraint.java
index ff42a21f..98dd588e 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/StringLengthConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/StringLengthConstraint.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
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/utilities/optionhandling/constraints/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/package-info.java
index e05ca2fa..371bd643 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/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/utilities/optionhandling/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/package-info.java
index d2106865..8f2dc2e5 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/package-info.java
@@ -246,14 +246,12 @@
* {@link de.lmu.ifi.dbs.elki.utilities.documentation.Title}
* {@link de.lmu.ifi.dbs.elki.utilities.documentation.Description} and
* {@link de.lmu.ifi.dbs.elki.utilities.documentation.Reference} (where possible).</p>
- *
- * @apiviz.excludeSubtypes de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable
*/
/*
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/utilities/optionhandling/parameterization/AbstractParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/AbstractParameterization.java
index 75a5be86..6b804777 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/AbstractParameterization.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/AbstractParameterization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization;
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/utilities/optionhandling/parameterization/ChainedParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ChainedParameterization.java
index 97cdb51f..9d8c171b 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ChainedParameterization.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ChainedParameterization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization;
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/utilities/optionhandling/parameterization/EmptyParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/EmptyParameterization.java
index 02802593..b43fed45 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/EmptyParameterization.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/EmptyParameterization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization;
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/utilities/optionhandling/parameterization/ListParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ListParameterization.java
index b870b57b..3cb309f5 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ListParameterization.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ListParameterization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization;
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/utilities/optionhandling/parameterization/MergedParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/MergedParameterization.java
index 9f765963..8e6e10c8 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/MergedParameterization.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/MergedParameterization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization;
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/utilities/optionhandling/parameterization/Parameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/Parameterization.java
index 01c46583..32ab5bdb 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/Parameterization.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/Parameterization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization;
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/utilities/optionhandling/parameterization/SerializedParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/SerializedParameterization.java
index b3e3f214..7eb3cf45 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/SerializedParameterization.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/SerializedParameterization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization;
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/utilities/optionhandling/parameterization/TrackParameters.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/TrackParameters.java
index 5a20bd9e..a9ccda98 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/TrackParameters.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/TrackParameters.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization;
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,11 +32,9 @@ import java.util.Map;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.InternalParameterizationErrors;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GlobalParameterConstraint;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Utility wrapper to track parameters for a configuration session.
@@ -54,7 +52,7 @@ public class TrackParameters implements Parameterization {
/**
* Tracking storage
*/
- List<Pair<Object, Parameter<?>>> options = new ArrayList<>();
+ List<TrackedParameter> options = new ArrayList<>();
/**
* Tree information: parent links
@@ -70,7 +68,7 @@ public class TrackParameters implements Parameterization {
/**
* Current parent for nested parameterization
*/
- Object cur = null;
+ Object owner = null;
/**
* Constructor.
@@ -83,18 +81,30 @@ public class TrackParameters implements Parameterization {
}
/**
+ * Constructor.
+ *
+ * @param inner Inner parameterization to wrap.
+ * @param owner Class/instance owning the parameter
+ */
+ public TrackParameters(Parameterization inner, Object owner) {
+ super();
+ this.inner = inner;
+ this.owner = owner;
+ }
+
+ /**
* Internal constructor, for nested tracking.
*
* @param inner Inner parameterization
- * @param option Option
+ * @param owner Object owning the current parameters
* @param options List of options
* @param parents Parent map
* @param children Child map
*/
- private TrackParameters(Parameterization inner, Object option, List<Pair<Object, Parameter<?>>> options, Map<Object, Object> parents, Map<Object, List<Object>> children) {
+ private TrackParameters(Parameterization inner, Object owner, List<TrackedParameter> options, Map<Object, Object> parents, Map<Object, List<Object>> children) {
super();
- this.inner = inner.descend(option);
- this.cur = option;
+ this.inner = inner.descend(owner);
+ this.owner = owner;
this.options = options;
this.parents = parents;
this.children = children;
@@ -113,7 +123,7 @@ public class TrackParameters implements Parameterization {
@Override
public boolean grab(Parameter<?> opt) {
registerChild(opt);
- options.add(new Pair<Object, Parameter<?>>(cur, opt));
+ options.add(new TrackedParameter(owner, opt));
return inner.grab(opt);
}
@@ -130,7 +140,7 @@ public class TrackParameters implements Parameterization {
@Override
public boolean setValueForOption(Parameter<?> opt) throws ParameterException {
registerChild(opt);
- options.add(new Pair<Object, Parameter<?>>(cur, opt));
+ options.add(new TrackedParameter(owner, opt));
return inner.setValueForOption(opt);
}
@@ -139,33 +149,19 @@ public class TrackParameters implements Parameterization {
*
* @return Parameters seen
*/
- public Collection<Pair<Object, Parameter<?>>> getAllParameters() {
+ public Collection<TrackedParameter> getAllParameters() {
return options;
}
- /**
- * Get the tracked parameters that were actually set.
- *
- * @return Parameters given
- */
- public Collection<Pair<OptionID, Object>> getGivenParameters() {
- ArrayList<Pair<OptionID, Object>> ret = new ArrayList<>();
- for(Pair<Object, Parameter<?>> pair : options) {
- if(pair.second.isDefined() && pair.second.getGivenValue() != null) {
- ret.add(new Pair<>(pair.second.getOptionID(), pair.second.getGivenValue()));
- }
- }
- return ret;
- }
-
@Override
public boolean checkConstraint(GlobalParameterConstraint constraint) {
return inner.checkConstraint(constraint);
}
/**
- * {@inheritDoc} Track parameters using a shared options list with parent
- * tracker.
+ * {@inheritDoc}
+ *
+ * Track parameters using a shared options list with parent tracker.
*/
@Override
public Parameterization descend(Object option) {
@@ -174,14 +170,14 @@ public class TrackParameters implements Parameterization {
}
private void registerChild(Object opt) {
- if(opt == cur) {
+ if(opt == owner) {
LoggingUtil.exception("Options shouldn't have themselves as parents!", new Throwable());
}
- parents.put(opt, cur);
- List<Object> c = children.get(cur);
+ parents.put(opt, owner);
+ List<Object> c = children.get(owner);
if(c == null) {
c = new ArrayList<>();
- children.put(cur, c);
+ children.put(owner, c);
}
if(!c.contains(opt)) {
c.add(opt);
@@ -204,7 +200,7 @@ public class TrackParameters implements Parameterization {
return ClassGenericsUtil.tryInstantiate(r, c, this);
}
catch(Exception e) {
- reportError(new InternalParameterizationErrors("Error instantiating internal class: "+c.getName(), e));
+ reportError(new InternalParameterizationErrors("Error instantiating internal class: " + c.getName(), e));
return null;
}
}
@@ -215,7 +211,7 @@ public class TrackParameters implements Parameterization {
return ClassGenericsUtil.tryInstantiate(c, c, this);
}
catch(Exception e) {
- reportError(new InternalParameterizationErrors("Error instantiating internal class: "+c.getName(), e));
+ reportError(new InternalParameterizationErrors("Error instantiating internal class: " + c.getName(), e));
return null;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DBIDIterAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/TrackedParameter.java
index 85fdcffd..01969302 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DBIDIterAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/TrackedParameter.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.database.ids.generic;
+package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization;
/*
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,61 +22,50 @@ package de.lmu.ifi.dbs.elki.database.ids.generic;
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.Iterator;
-
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDMIter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
/**
- * Iterator for classic collections.
+ * Class containing an object, and the associated value.
*
* @author Erich Schubert
*/
-public class DBIDIterAdapter implements DBIDMIter {
+public class TrackedParameter {
/**
- * Current DBID.
+ * Option ID
*/
- DBID cur = null;
+ private Object owner;
/**
- * The real iterator.
+ * Parameter value
*/
- Iterator<DBID> iter;
+ private Parameter<?> parameter;
/**
* Constructor.
- *
- * @param iter Iterator
+ *
+ * @param owner Object owning the parameter value
+ * @param parameter Parameter
*/
- public DBIDIterAdapter(Iterator<DBID> iter) {
- super();
- this.iter = iter;
- advance();
- }
-
- @Override
- public boolean valid() {
- return cur != null;
- }
-
- @Override
- public void advance() {
- if(iter.hasNext()) {
- cur = iter.next();
- }
- else {
- cur = null;
- }
+ public TrackedParameter(Object owner, Parameter<?> parameter) {
+ this.owner = owner;
+ this.parameter = parameter;
}
- @Override
- public int internalGetIndex() {
- return cur.internalGetIndex();
+ /**
+ * Get the owner object.
+ *
+ * @return Parameter owner
+ */
+ public Object getOwner() {
+ return owner;
}
- @Override
- public void remove() {
- iter.remove();
+ /**
+ * Get the parameter observed.
+ *
+ * @return Parameter
+ */
+ public Parameter<?> getParameter() {
+ return parameter;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/UnParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/UnParameterization.java
index 2a05a766..dfdbe7ac 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/UnParameterization.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/UnParameterization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization;
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/utilities/optionhandling/parameterization/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/package-info.java
index ce9c89b4..d330d343 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/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/utilities/optionhandling/parameters/AbstractParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/AbstractParameter.java
index cdad8583..05e82152 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/AbstractParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/AbstractParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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
@@ -131,10 +131,12 @@ public abstract class AbstractParameter<THIS extends AbstractParameter<THIS, T>,
this(optionID, false);
}
+ @SuppressWarnings("unchecked")
@Override
- public void setDefaultValue(T defaultValue) {
+ public THIS setDefaultValue(T defaultValue) {
this.defaultValue = defaultValue;
this.optionalParameter = true;
+ return (THIS) this;
}
@Override
@@ -142,7 +144,6 @@ public abstract class AbstractParameter<THIS extends AbstractParameter<THIS, T>,
return !(defaultValue == null);
}
- // TODO: can we do this more elegantly?
@Override
public void useDefaultValue() {
setValueInternal(defaultValue);
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassListParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassListParameter.java
index 1cea7fac..bd41e139 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassListParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassListParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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/utilities/optionhandling/parameters/ClassParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassParameter.java
index 42288738..02545582 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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,6 +26,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
+import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
@@ -51,6 +52,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
// TODO: turn restrictionClass into a constraint?
public class ClassParameter<C> extends AbstractParameter<ClassParameter<C>, Class<? extends C>> {
/**
+ * The class logger.
+ */
+ private static final Logging LOG = Logging.getLogger(ClassParameter.class);
+
+ /**
* The restriction class for this class parameter.
*/
protected Class<C> restrictionClass;
@@ -176,7 +182,27 @@ public class ClassParameter<C> extends AbstractParameter<ClassParameter<C>, Clas
@Override
public String getValuesDescription() {
if(restrictionClass != null && restrictionClass != Object.class) {
- return restrictionString();
+ StringBuilder info = new StringBuilder();
+ if(restrictionClass.isInterface()) {
+ info.append("Implementing ");
+ }
+ else {
+ info.append("Extending ");
+ }
+ info.append(restrictionClass.getName());
+ info.append(FormatUtil.NEWLINE);
+
+ List<Class<?>> known = getKnownImplementations();
+ if(!known.isEmpty()) {
+ info.append("Known classes (default package " + restrictionClass.getPackage().getName() + "):");
+ info.append(FormatUtil.NEWLINE);
+ for(Class<?> c : known) {
+ info.append("->").append(FormatUtil.NONBREAKING_SPACE);
+ info.append(canonicalClassName(c, getRestrictionClass()));
+ info.append(FormatUtil.NEWLINE);
+ }
+ }
+ return info.toString();
}
return "";
}
@@ -214,6 +240,9 @@ public class ClassParameter<C> extends AbstractParameter<ClassParameter<C>, Clas
throw new WrongParameterValueException(this, getValue().getCanonicalName(), "Error instantiating class - no usable public constructor.");
}
catch(Exception e) {
+ if(LOG.isVerbose()) {
+ LOG.exception("Class initialization failed.", e);
+ }
throw new WrongParameterValueException(this, getValue().getCanonicalName(), "Error instantiating class.", e);
}
return instance;
@@ -243,37 +272,6 @@ public class ClassParameter<C> extends AbstractParameter<ClassParameter<C>, Clas
}
/**
- * Provides a description string listing all classes for the given superclass
- * or interface as specified in the properties.
- *
- * @return a description string listing all classes for the given superclass
- * or interface as specified in the properties
- */
- public String restrictionString() {
- StringBuilder info = new StringBuilder();
- if(restrictionClass.isInterface()) {
- info.append("Implementing ");
- }
- else {
- info.append("Extending ");
- }
- info.append(restrictionClass.getName());
- info.append(FormatUtil.NEWLINE);
-
- List<Class<?>> known = getKnownImplementations();
- if(!known.isEmpty()) {
- info.append("Known classes (default package " + restrictionClass.getPackage().getName() + "):");
- info.append(FormatUtil.NEWLINE);
- for(Class<?> c : known) {
- info.append("->" + FormatUtil.NONBREAKING_SPACE);
- info.append(canonicalClassName(c, getRestrictionClass()));
- info.append(FormatUtil.NEWLINE);
- }
- }
- return info.toString();
- }
-
- /**
* Get the "simple" form of a class name.
*
* @param c Class
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DistanceParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DistanceParameter.java
deleted file mode 100644
index eda54082..00000000
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DistanceParameter.java
+++ /dev/null
@@ -1,149 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
-
-/*
- 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.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException;
-
-/**
- * Parameter class for a parameter specifying a double value.
- *
- * @author Steffi Wanka
- * @author Erich Schubert
- *
- * @param <D> Distance type
- */
-public class DistanceParameter<D extends Distance<D>> extends AbstractParameter<DistanceParameter<D>, D> {
- /**
- * Distance type
- */
- D dist;
-
- /**
- * Constructs a double parameter with the given optionID and default value.
- *
- * @param optionID the unique optionID
- * @param dist distance factory
- * @param defaultValue the default value for this double parameter
- */
- public DistanceParameter(OptionID optionID, D dist, D defaultValue) {
- super(optionID, defaultValue);
- this.dist = dist;
- }
-
- /**
- * Constructs a double parameter with the given optionID and default value.
- *
- * @param optionID the unique optionID
- * @param dist distance factory
- * @param defaultValue the default value for this double parameter
- */
- public DistanceParameter(OptionID optionID, DistanceFunction<?, D> dist, D defaultValue) {
- super(optionID, defaultValue);
- this.dist = (dist != null) ? dist.getDistanceFactory() : null;
- }
-
- /**
- * Constructs a double parameter with the given optionID and optional flag.
- *
- * @param optionID the unique id of this parameter
- * @param dist distance factory
- * @param optional specifies whether this parameter is an optional parameter
- */
- public DistanceParameter(OptionID optionID, D dist, boolean optional) {
- super(optionID, optional);
- this.dist = dist;
- }
-
- /**
- * Constructs a double parameter with the given optionID and optional flag.
- *
- * @param optionID the unique id of this parameter
- * @param dist distance factory
- * @param optional specifies whether this parameter is an optional parameter
- */
- public DistanceParameter(OptionID optionID, DistanceFunction<?, D> dist, boolean optional) {
- super(optionID, optional);
- this.dist = (dist != null) ? dist.getDistanceFactory() : null;
- }
-
- /**
- * Constructs a double parameter with the given optionID.
- *
- * @param optionID the unique id of this parameter
- * @param dist distance factory
- */
- public DistanceParameter(OptionID optionID, D dist) {
- super(optionID);
- this.dist = dist;
- }
-
- /**
- * Constructs a double parameter with the given optionID.
- *
- * @param optionID the unique id of this parameter
- * @param dist distance factory
- */
- public DistanceParameter(OptionID optionID, DistanceFunction<?, D> dist) {
- super(optionID);
- this.dist = (dist != null) ? dist.getDistanceFactory() : null;
- }
-
- @Override
- public String getValueAsString() {
- return getValue().toString();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- protected D parseValue(Object obj) throws WrongParameterValueException {
- if (dist == null) {
- throw new WrongParameterValueException("Wrong parameter format! Parameter \"" + getName() + "\" requires a distance value, but the distance was not set!");
- }
- if (obj == null) {
- throw new WrongParameterValueException("Wrong parameter format! Parameter \"" + getName() + "\" requires a distance value, but a null value was given!");
- }
- if(dist.nullDistance().getClass().isAssignableFrom(obj.getClass())) {
- return (D) dist.nullDistance().getClass().cast(obj);
- }
- try {
- return dist.parseString(obj.toString());
- }
- catch(IllegalArgumentException e) {
- throw new WrongParameterValueException("Wrong parameter format! Parameter \"" + getName() + "\" requires a distance value, read: " + obj + "!\n");
- }
- }
-
- /**
- * Returns a string representation of the parameter's type.
- *
- * @return &quot;&lt;distance&gt;&quot;
- */
- @Override
- public String getSyntax() {
- return "<distance>";
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleListParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleListParameter.java
index 84f97734..b5c651c2 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleListParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleListParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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,6 +27,7 @@ import java.util.ArrayList;
import java.util.List;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException;
@@ -59,7 +60,7 @@ public class DoubleListParameter extends ListParameter<DoubleListParameter, Doub
@Override
public String getValueAsString() {
- return FormatUtil.format(getValue().toArray(new Double[getValue().size()]), LIST_SEP, FormatUtil.NF);
+ return FormatUtil.format(ArrayLikeUtil.toPrimitiveDoubleArray(getValue()), LIST_SEP);
}
@SuppressWarnings("unchecked")
@@ -68,15 +69,16 @@ public class DoubleListParameter extends ListParameter<DoubleListParameter, Doub
try {
List<?> l = List.class.cast(obj);
// do extra validation:
- for (Object o : l) {
- if (!(o instanceof Double)) {
+ for(Object o : l) {
+ if(!(o instanceof Double)) {
throw new WrongParameterValueException("Wrong parameter format for parameter \"" + getName() + "\". Given list contains objects of different type!");
}
}
// TODO: can we use reflection to get extra checks?
// TODO: Should we copy the list?
- return (List<Double>)l;
- } catch (ClassCastException e) {
+ return (List<Double>) l;
+ }
+ catch(ClassCastException e) {
// continue with others
}
if(obj instanceof String) {
@@ -87,6 +89,11 @@ public class DoubleListParameter extends ListParameter<DoubleListParameter, Doub
}
return doubleValue;
}
+ if(obj instanceof Double) {
+ ArrayList<Double> doubleValue = new ArrayList<>(1);
+ doubleValue.add((Double) obj);
+ return doubleValue;
+ }
throw new WrongParameterValueException("Wrong parameter format! Parameter \"" + getName() + "\" requires a list of Double values!");
}
@@ -97,11 +104,10 @@ public class DoubleListParameter extends ListParameter<DoubleListParameter, Doub
* parameter
*/
// Unused?
- /*public void setDefaultValue(double allListDefaultValue) {
- for(int i = 0; i < defaultValue.size(); i++) {
- defaultValue.set(i, allListDefaultValue);
- }
- }*/
+ /*
+ * public void setDefaultValue(double allListDefaultValue) { for(int i = 0; i
+ * < defaultValue.size(); i++) { defaultValue.set(i, allListDefaultValue); } }
+ */
/**
* Returns a string representation of the parameter's type.
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleParameter.java
index efa64370..109d3204 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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/utilities/optionhandling/parameters/EnumParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/EnumParameter.java
index 22d7dd54..ed86b542 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/EnumParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/EnumParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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
@@ -26,6 +26,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
import java.util.ArrayList;
import java.util.Collection;
+import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.UnspecifiedParameterException;
@@ -111,16 +112,17 @@ public class EnumParameter<E extends Enum<E>> extends AbstractParameter<EnumPara
@Override
protected E parseValue(Object obj) throws ParameterException {
- if (obj == null) {
+ if(obj == null) {
throw new UnspecifiedParameterException(this);
}
- if (enumClass.isInstance(obj)) {
+ if(enumClass.isInstance(obj)) {
return enumClass.cast(obj);
}
- if (obj instanceof String) {
+ if(obj instanceof String) {
try {
return Enum.valueOf(enumClass, (String) obj);
- } catch (IllegalArgumentException ex) {
+ }
+ catch(IllegalArgumentException ex) {
throw new WrongParameterValueException("Enum parameter " + getName() + " is invalid (must be one of [" + joinEnumNames(", ") + "].");
}
}
@@ -133,6 +135,26 @@ public class EnumParameter<E extends Enum<E>> extends AbstractParameter<EnumPara
}
/**
+ * This class sometimes provides a list of value descriptions.
+ *
+ * @see de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.AbstractParameter#hasValuesDescription()
+ */
+ @Override
+ public boolean hasValuesDescription() {
+ return true;
+ }
+
+ @Override
+ public String getValuesDescription() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("One of:").append(FormatUtil.NEWLINE);
+ for(String s : getPossibleValues()) {
+ buf.append("->").append(FormatUtil.NONBREAKING_SPACE).append(s).append(FormatUtil.NEWLINE);
+ }
+ return buf.toString();
+ }
+
+ /**
* Get a list of possible values for this enum parameter.
*
* @return list of strings representing possible enum values.
@@ -141,7 +163,7 @@ public class EnumParameter<E extends Enum<E>> extends AbstractParameter<EnumPara
// Convert to string array
final E[] enums = enumClass.getEnumConstants();
ArrayList<String> values = new ArrayList<>(enums.length);
- for (E t : enums) {
+ for(E t : enums) {
values.add(t.name());
}
return values;
@@ -157,8 +179,8 @@ public class EnumParameter<E extends Enum<E>> extends AbstractParameter<EnumPara
private String joinEnumNames(String separator) {
E[] enumTypes = enumClass.getEnumConstants();
StringBuilder sb = new StringBuilder();
- for (int i = 0; i < enumTypes.length; ++i) {
- if (i > 0) {
+ for(int i = 0; i < enumTypes.length; ++i) {
+ if(i > 0) {
sb.append(separator);
}
sb.append(enumTypes[i].name());
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileListParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileListParameter.java
index 9e115dc7..f4301fd7 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileListParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileListParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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/utilities/optionhandling/parameters/FileParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileParameter.java
index 3e9fdc7d..2d2cd43a 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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/utilities/optionhandling/parameters/Flag.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Flag.java
index f9e1a1f1..8c2e35e2 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Flag.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Flag.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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/utilities/optionhandling/parameters/IntListParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntListParameter.java
index cc8327b4..036aaff0 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntListParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntListParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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/utilities/optionhandling/parameters/IntParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntParameter.java
index 3d867770..68c1ff2e 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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/utilities/optionhandling/parameters/ListParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ListParameter.java
index df520daa..b10a2779 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ListParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ListParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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
@@ -49,9 +49,9 @@ public abstract class ListParameter<THIS extends ListParameter<THIS, T>, T> exte
public static final String LIST_SEP = ",";
/**
- * A pattern defining a &quot:&quot.
+ * A pattern defining a &quot:&quot or &quot;;&quot;.
*/
- public static final Pattern VECTOR_SPLIT = Pattern.compile(":");
+ public static final Pattern VECTOR_SPLIT = Pattern.compile("[:;]");
/**
* Vector separator character - &quot;:&quot;
@@ -93,7 +93,7 @@ public abstract class ListParameter<THIS extends ListParameter<THIS, T>, T> exte
* @return the size of this list parameter.
*/
public int getListSize() {
- if (getValue() == null && isOptional()) {
+ if(getValue() == null && isOptional()) {
return 0;
}
@@ -106,15 +106,15 @@ public abstract class ListParameter<THIS extends ListParameter<THIS, T>, T> exte
*/
// TODO: keep? remove?
protected String asString() {
- if (getValue() == null) {
+ if(getValue() == null) {
return "";
}
StringBuilder buffer = new StringBuilder();
buffer.append('[');
- for (int i = 0; i < getValue().size(); i++) {
+ for(int i = 0; i < getValue().size(); i++) {
buffer.append(getValue().get(i).toString());
- if (i != getValue().size() - 1) {
+ if(i != getValue().size() - 1) {
buffer.append(',');
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/LongParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/LongParameter.java
index 5ab6b487..67995a5d 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/LongParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/LongParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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/utilities/optionhandling/parameters/NumberParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/NumberParameter.java
index fabdce53..8c7381fd 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/NumberParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/NumberParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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/utilities/optionhandling/parameters/ObjectListParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectListParameter.java
index ada6239a..96e6a80e 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectListParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectListParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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/utilities/optionhandling/parameters/ObjectParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectParameter.java
index 4166d0a2..34b0ed3e 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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/utilities/optionhandling/parameters/Parameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Parameter.java
index ffacb6d1..8ff5199c 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Parameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Parameter.java
@@ -9,7 +9,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.ParameterConstra
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
@@ -49,8 +49,9 @@ public interface Parameter<T> {
* Sets the default value of this parameter.
*
* @param defaultValue default value of this parameter
+ * @return the parameter itself, for chaining
*/
- public abstract void setDefaultValue(T defaultValue);
+ public abstract Parameter<T> setDefaultValue(T defaultValue);
/**
* Checks if this parameter has a default value.
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/PatternParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/PatternParameter.java
index e3cb4bcf..2e8121ba 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/PatternParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/PatternParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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/utilities/optionhandling/parameters/RandomParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/RandomParameter.java
index bf5e0cb0..40fa6d53 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/RandomParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/RandomParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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.utilities.optionhandling.parameters;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException;
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/StringParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/StringParameter.java
index dc2a2a32..9dd6ea26 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/StringParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/StringParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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/utilities/optionhandling/parameters/VectorListParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/VectorListParameter.java
index 43fa0797..51578fb5 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/VectorListParameter.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/VectorListParameter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
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,10 +23,13 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import gnu.trove.list.array.TDoubleArrayList;
+
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
@@ -39,7 +42,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.ParameterConstra
* @author Steffi Wanka
* @author Erich Schubert
*/
-public class VectorListParameter extends ListParameter<VectorListParameter, List<Double>> {
+public class VectorListParameter extends ListParameter<VectorListParameter, Vector> {
/**
* Constructs a vector list parameter with the given name and description.
*
@@ -47,7 +50,7 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List
* @param constraint Constraint
* @param defaultValue Default value
*/
- public VectorListParameter(OptionID optionID, ParameterConstraint<List<List<Double>>> constraint, List<List<Double>> defaultValue) {
+ public VectorListParameter(OptionID optionID, ParameterConstraint<List<Vector>> constraint, List<Vector> defaultValue) {
super(optionID, defaultValue);
addConstraint(constraint);
}
@@ -59,7 +62,7 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List
* @param constraint Constraint
* @param optional Optional flag
*/
- public VectorListParameter(OptionID optionID, ParameterConstraint<List<List<Double>>> constraint, boolean optional) {
+ public VectorListParameter(OptionID optionID, ParameterConstraint<List<Vector>> constraint, boolean optional) {
super(optionID, optional);
addConstraint(constraint);
}
@@ -70,7 +73,7 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List
* @param optionID Option ID
* @param constraint Constraint
*/
- public VectorListParameter(OptionID optionID, ParameterConstraint<List<List<Double>>> constraint) {
+ public VectorListParameter(OptionID optionID, ParameterConstraint<List<Vector>> constraint) {
super(optionID);
addConstraint(constraint);
}
@@ -83,8 +86,8 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List
*/
// Indiscernible from optionID, constraints
/*
- * public VectorListParameter(OptionID optionID, List<List<Double>>
- * defaultValue) { super(optionID, defaultValue); }
+ * public VectorListParameter(OptionID optionID, List<Vector> defaultValue) {
+ * super(optionID, defaultValue); }
*/
/**
@@ -109,17 +112,10 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List
@Override
public String getValueAsString() {
StringBuilder buf = new StringBuilder();
- List<List<Double>> val = getValue();
- Iterator<List<Double>> valiter = val.iterator();
+ List<Vector> val = getValue();
+ Iterator<Vector> valiter = val.iterator();
while(valiter.hasNext()) {
- List<Double> vec = valiter.next();
- Iterator<Double> veciter = vec.iterator();
- while(veciter.hasNext()) {
- buf.append(veciter.next().toString());
- if(veciter.hasNext()) {
- buf.append(LIST_SEP);
- }
- }
+ buf.append(FormatUtil.format(valiter.next().getArrayRef(), LIST_SEP));
// Append separation character
if(valiter.hasNext()) {
buf.append(VECTOR_SEP);
@@ -130,7 +126,7 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List
@SuppressWarnings("unchecked")
@Override
- protected List<List<Double>> parseValue(Object obj) throws ParameterException {
+ protected List<Vector> parseValue(Object obj) throws ParameterException {
try {
List<?> l = List.class.cast(obj);
// do extra validation:
@@ -144,7 +140,7 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List
}
// TODO: can we use reflection to get extra checks?
// TODO: Should we copy the list and vectors?
- return (List<List<Double>>) l;
+ return (List<Vector>) l;
}
catch(ClassCastException e) {
// continue with other attempts.
@@ -154,11 +150,12 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List
if(vectors.length == 0) {
throw new WrongParameterValueException("Wrong parameter format! Given list of vectors for parameter \"" + getName() + "\" is empty!");
}
- ArrayList<List<Double>> vecs = new ArrayList<>();
+ ArrayList<Vector> vecs = new ArrayList<>();
+ TDoubleArrayList vectorCoord = new TDoubleArrayList();
for(String vector : vectors) {
+ vectorCoord.clear();
String[] coordinates = SPLIT.split(vector);
- ArrayList<Double> vectorCoord = new ArrayList<>();
for(String coordinate : coordinates) {
try {
vectorCoord.add(FormatUtil.parseDouble(coordinate));
@@ -167,11 +164,11 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List
throw new WrongParameterValueException("Wrong parameter format! Coordinates of vector \"" + vector + "\" are not valid!");
}
}
- vecs.add(vectorCoord);
+ vecs.add(new Vector(vectorCoord.toArray()));
}
return vecs;
}
- throw new WrongParameterValueException("Wrong parameter format! Parameter \"" + getName() + "\" requires a list of Double values!");
+ throw new WrongParameterValueException("Wrong parameter format! Parameter \"" + getName() + "\" requires a list of double values!");
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/package-info.java
index 75d7c5a1..272cb8f2 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/package-info.java
@@ -12,7 +12,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/utilities/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/package-info.java
index 1e110d8e..45447362 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/package-info.java
@@ -8,12 +8,11 @@
* <ul>
* <li>Basic and low-level:<ul>
* <li>{@link de.lmu.ifi.dbs.elki.utilities.Util}: Miscellaneous utility functions.</li>
- * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.PairUtil}: for Pair Comparators.</li>
* <li>{@link de.lmu.ifi.dbs.elki.logging.LoggingUtil}: simple logging access.</li>
* <li>{@link de.lmu.ifi.dbs.elki.math.MathUtil}: Mathematics utility functions.</li>
* <li>{@link de.lmu.ifi.dbs.elki.data.VectorUtil}: Vector and Matrix functions.</li>
* <li>{@link de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil}: Spatial MBR computations (intersection, union etc.).</li>
- * <li>{@link de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil}: byte array processing (low-level IO via byte arrays).</li>
+ * <li>{@link de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil}: byte array processing (low-level IO via byte arrays).</li>
* <li>{@link de.lmu.ifi.dbs.elki.utilities.FileUtil}: File and file name utility functions.</li>
* <li>{@link de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil}: Generic classes (instantiation, arrays of arrays, sets that require safe but unchecked casts).</li>
* </ul></li>
@@ -23,7 +22,6 @@
* <li>{@link de.lmu.ifi.dbs.elki.database.ids.DBIDUtil}: Database ID DBID handling.</li>
* <li>{@link de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil}: Data storage layer (like Maps).</li>
* <li>{@link de.lmu.ifi.dbs.elki.utilities.DatabaseUtil}: database utility functions (centroid etc.).</li>
- * <li>{@link de.lmu.ifi.dbs.elki.distance.DistanceUtil}: distance functions related (min, max for {@link de.lmu.ifi.dbs.elki.distance.distancevalue.Distance}s).</li>
* <li>{@link de.lmu.ifi.dbs.elki.result.ResultUtil}: result processing functions (e.g. extracting sub-results).</li>
* </ul></li>
* <li>Output-related:<ul>
@@ -34,7 +32,6 @@
* <li>{@link de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizerUtil}: Visualizer handling.</li>
* </ul></li>
* <li>Specialized:<ul>
- * <li>{@link de.lmu.ifi.dbs.elki.data.images.ImageUtil}: image handling.</li>
* <li>{@link de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionUtil}: Managing parameter settings</li>
* <li>{@link de.lmu.ifi.dbs.elki.utilities.InspectionUtil}: class and classpath inspection.</li>
* <li>{@link de.lmu.ifi.dbs.elki.utilities.documentation.DocumentationUtil}: documentation extraction from annotations.</li>
@@ -46,7 +43,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/utilities/pairs/CPair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/CPair.java
deleted file mode 100644
index 036eaea2..00000000
--- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/CPair.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.pairs;
-
-/*
- 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.utilities.ClassGenericsUtil;
-
-/**
- * Pair with canonical comparison function derived from the components comparable interfaces.
- *
- * @author Erich Schubert
- *
- * @param <FIRST> first type
- * @param <SECOND> second type
- */
-public class CPair<FIRST extends Comparable<? super FIRST>, SECOND extends Comparable<? super SECOND>> extends Pair<FIRST, SECOND> implements Comparable<CPair<FIRST,SECOND>> {
- /**
- * Initialize pair
- *
- * @param first first parameter
- * @param second second parameter
- */
- public CPair(FIRST first, SECOND second) {
- super(first, second);
- }
-
- /**
- * Generic derived compare function.
- *
- * @param other Object to compare to
- * @return comparison result
- */
- @Override
- public int compareTo(CPair<FIRST, SECOND> other) {
- // try comparing by first
- if(this.first != null) {
- if(other.first == null) {
- return -1;
- }
- int delta1 = this.first.compareTo(other.first);
- if(delta1 != 0) {
- return delta1;
- }
- }
- else if(other.first != null) {
- return +1;
- }
- // try comparing by second
- if(this.second != null) {
- if(other.second == null) {
- return -1;
- }
- int delta2 = this.second.compareTo(other.second);
- if(delta2 != 0) {
- return delta2;
- }
- }
- else if(other.second != null) {
- return +1;
- }
- return 0;
- }
-
- /**
- * Array constructor for generics
- *
- * @param <F> First type
- * @param <S> Second type
- * @param size Size of array to be constructed
- * @return New array of requested size
- */
- public static final <F extends Comparable<? super F>, S extends Comparable<? super S>> CPair<F, S>[] newArray(int size) {
- Class<CPair<F,S>> paircls = ClassGenericsUtil.uglyCastIntoSubclass(CPair.class);
- return ClassGenericsUtil.newArrayOfNull(size, paircls);
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/CTriple.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/CTriple.java
deleted file mode 100644
index 88ed35eb..00000000
--- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/CTriple.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.pairs;
-
-/*
- 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/>.
- */
-
-/**
- * Triple with canonical comparison function.
- *
- * @author Erich Schubert
- *
- * @param <FIRST> first type
- * @param <SECOND> second type
- * @param <THIRD> second type
- */
-public final class CTriple<FIRST extends Comparable<? super FIRST>, SECOND extends Comparable<? super SECOND>, THIRD extends Comparable<? super THIRD>> extends Triple<FIRST, SECOND, THIRD> implements Comparable<CTriple<FIRST, SECOND, THIRD>> {
- /**
- * Constructor with fields
- *
- * @param first Value of first component
- * @param second Value of second component
- * @param third Value of third component
- */
- public CTriple(FIRST first, SECOND second, THIRD third) {
- super(first, second, third);
- }
-
- /**
- * Canonical toString operator
- */
- @Override
- public String toString() {
- return "Triple(" + first.toString() + ", " + second.toString() + ", " + third.toString() + ")";
- }
-
- /**
- * Generic derived compare function.
- *
- * @param other Object to compare to
- * @return comparison result
- */
- @Override
- public int compareTo(CTriple<FIRST, SECOND, THIRD> other) {
- // try comparing by first
- if(this.first != null) {
- if(other.first == null) {
- return -1;
- }
- int delta1 = this.first.compareTo(other.first);
- if(delta1 != 0) {
- return delta1;
- }
- }
- else if(other.first != null) {
- return +1;
- }
- // try comparing by second
- if(this.second != null) {
- if(other.second == null) {
- return -1;
- }
- int delta2 = this.second.compareTo(other.second);
- if(delta2 != 0) {
- return delta2;
- }
- }
- else if(other.second != null) {
- return +1;
- }
- // try comparing by third
- if(this.third != null) {
- if(other.third == null) {
- return -1;
- }
- int delta3 = this.third.compareTo(other.third);
- if(delta3 != 0) {
- return delta3;
- }
- }
- else if(other.third != null) {
- return +1;
- }
- return 0;
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleDoublePair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleDoublePair.java
index 092d6635..bc17fff3 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleDoublePair.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleDoublePair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.pairs;
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,14 +28,11 @@ import java.util.Comparator;
/**
* Pair storing two doubles.
*
- * Since double is a native type, this can't be done via the {@link CPair}
- * generic.
- *
* @author Erich Schubert
*
* @apiviz.has Comparator
*/
-public class DoubleDoublePair implements Comparable<DoubleDoublePair>, PairInterface<Double, Double> {
+public class DoubleDoublePair implements Comparable<DoubleDoublePair> {
/**
* first value
*/
@@ -134,15 +131,6 @@ public class DoubleDoublePair implements Comparable<DoubleDoublePair>, PairInter
}
/**
- * @deprecated use pair.first to avoid boxing!
- */
- @Override
- @Deprecated
- public final Double getFirst() {
- return Double.valueOf(first);
- }
-
- /**
* Set first value
*
* @param first new value
@@ -152,15 +140,6 @@ public class DoubleDoublePair implements Comparable<DoubleDoublePair>, PairInter
}
/**
- * @deprecated use pair.first to avoid boxing!
- */
- @Override
- @Deprecated
- public final Double getSecond() {
- return Double.valueOf(second);
- }
-
- /**
* Set second value
*
* @param second new value
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleIntPair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleIntPair.java
index be18c712..731d5cf6 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleIntPair.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleIntPair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.pairs;
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,14 +28,11 @@ import java.util.Comparator;
/**
* Pair storing an integer and a double.
*
- * Since double and int are native types, this can't be done via the
- * {@link CPair} generic.
- *
* @author Erich Schubert
*
* @apiviz.has Comparator
*/
-public class DoubleIntPair implements Comparable<DoubleIntPair>, PairInterface<Double, Integer> {
+public class DoubleIntPair implements Comparable<DoubleIntPair> {
/**
* first value
*/
@@ -122,15 +119,6 @@ public class DoubleIntPair implements Comparable<DoubleIntPair>, PairInterface<D
}
/**
- * @deprecated use pair.first to avoid boxing!
- */
- @Override
- @Deprecated
- public final Double getFirst() {
- return Double.valueOf(first);
- }
-
- /**
* Set first value
*
* @param first new value
@@ -140,15 +128,6 @@ public class DoubleIntPair implements Comparable<DoubleIntPair>, PairInterface<D
}
/**
- * @deprecated use pair.first to avoid boxing!
- */
- @Override
- @Deprecated
- public final Integer getSecond() {
- return Integer.valueOf(second);
- }
-
- /**
* Set second value
*
* @param second new value
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleObjPair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleObjPair.java
index 678d4532..945f58aa 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleObjPair.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleObjPair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.pairs;
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,7 +31,7 @@ package de.lmu.ifi.dbs.elki.utilities.pairs;
*
* @param <O> Object type
*/
-public class DoubleObjPair<O> implements PairInterface<Double, O>, Comparable<DoubleObjPair<O>> {
+public class DoubleObjPair<O> implements Comparable<DoubleObjPair<O>> {
/**
* Double value
*/
@@ -53,20 +53,6 @@ public class DoubleObjPair<O> implements PairInterface<Double, O>, Comparable<Do
this.second = second;
}
- /**
- * @deprecated use pair.first to avoid boxing!
- */
- @Override
- @Deprecated
- public Double getFirst() {
- return Double.valueOf(first);
- }
-
- @Override
- public O getSecond() {
- return second;
- }
-
@Override
public int compareTo(DoubleObjPair<O> o) {
return Double.compare(first, o.first);
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/FCPair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/FCPair.java
deleted file mode 100644
index 4d2f707c..00000000
--- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/FCPair.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.pairs;
-
-/*
- 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.utilities.ClassGenericsUtil;
-
-/**
- * Pair that can <em>only</em> be compared by it's first component.
- *
- * @author Erich Schubert
- *
- * @param <FIRST> first type (comparable)
- * @param <SECOND> second type
- */
-public class FCPair<FIRST extends Comparable<? super FIRST>, SECOND> extends Pair<FIRST, SECOND> implements Comparable<FCPair<FIRST, SECOND>> {
- /**
- * Initialize pair
- *
- * @param first first parameter
- * @param second second parameter
- */
- public FCPair(FIRST first, SECOND second) {
- super(first, second);
- }
-
- /**
- * Generic derived compare function.
- *
- * @param other Object to compare to
- * @return comparison result
- */
- @Override
- public int compareTo(FCPair<FIRST, SECOND> other) {
- // try comparing by first
- if(this.first != null) {
- if(other.first == null) {
- return -1;
- }
- int delta1 = this.first.compareTo(other.first);
- if(delta1 != 0) {
- return delta1;
- }
- }
- else if(other.first != null) {
- return +1;
- }
- return 0;
- }
-
- /**
- * Array constructor for generics
- *
- * @param <F> First type
- * @param <S> Second type
- * @param size Size of array to be constructed
- * @return New array of requested size
- */
- public static final <F extends Comparable<? super F>, S> FCPair<F, S>[] newArray(int size) {
- Class<FCPair<F,S>> paircls = ClassGenericsUtil.uglyCastIntoSubclass(FCPair.class);
- return ClassGenericsUtil.newArrayOfNull(size, paircls);
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntDoublePair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntDoublePair.java
index bfcf5971..805cf6dc 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntDoublePair.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntDoublePair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.pairs;
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,14 +28,11 @@ import java.util.Comparator;
/**
* Pair storing an integer and a double.
*
- * Since double and int are native types, this can't be done via the
- * {@link CPair} generic.
- *
* @author Erich Schubert
*
* @apiviz.has Comparator
*/
-public class IntDoublePair implements Comparable<IntDoublePair>, PairInterface<Integer, Double> {
+public class IntDoublePair implements Comparable<IntDoublePair> {
/**
* first value
*/
@@ -122,15 +119,6 @@ public class IntDoublePair implements Comparable<IntDoublePair>, PairInterface<I
}
/**
- * @deprecated use pair.first to avoid boxing!
- */
- @Override
- @Deprecated
- public final Integer getFirst() {
- return Integer.valueOf(first);
- }
-
- /**
* Set first value
*
* @param first new value
@@ -140,15 +128,6 @@ public class IntDoublePair implements Comparable<IntDoublePair>, PairInterface<I
}
/**
- * @deprecated use pair.first to avoid boxing!
- */
- @Override
- @Deprecated
- public final Double getSecond() {
- return Double.valueOf(second);
- }
-
- /**
* Set second value
*
* @param second new value
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntIntPair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntIntPair.java
index 5d3210a4..bf4f810f 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntIntPair.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntIntPair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.pairs;
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,13 +28,11 @@ import java.util.Comparator;
/**
* Pair storing two integers.
*
- * Since int is a native type, this can't be done via the {@link CPair} generic.
- *
* @author Erich Schubert
*
* @apiviz.has Comparator
*/
-public class IntIntPair implements Comparable<IntIntPair>, PairInterface<Integer, Integer> {
+public class IntIntPair implements Comparable<IntIntPair> {
/**
* first value
*/
@@ -119,15 +117,6 @@ public class IntIntPair implements Comparable<IntIntPair>, PairInterface<Integer
}
/**
- * @deprecated use pair.first to avoid boxing!
- */
- @Override
- @Deprecated
- public final Integer getFirst() {
- return Integer.valueOf(first);
- }
-
- /**
* Set first value
*
* @param first new value
@@ -137,15 +126,6 @@ public class IntIntPair implements Comparable<IntIntPair>, PairInterface<Integer
}
/**
- * @deprecated use pair.first to avoid boxing!
- */
- @Override
- @Deprecated
- public final Integer getSecond() {
- return Integer.valueOf(second);
- }
-
- /**
* Set second value
*
* @param second new value
@@ -153,14 +133,14 @@ public class IntIntPair implements Comparable<IntIntPair>, PairInterface<Integer
public final void setSecond(int second) {
this.second = second;
}
-
+
@Override
public String toString() {
return "(" + first + ", " + second + ")";
}
/**
- * Comparator to compare by second component only
+ * Comparator to compare by second component only
*/
public static final Comparator<IntIntPair> BYFIRST_COMPARATOR = new Comparator<IntIntPair>() {
@Override
@@ -168,9 +148,9 @@ public class IntIntPair implements Comparable<IntIntPair>, PairInterface<Integer
return o1.first - o2.first;
}
};
-
+
/**
- * Comparator to compare by second component only
+ * Comparator to compare by second component only
*/
public static final Comparator<IntIntPair> BYSECOND_COMPARATOR = new Comparator<IntIntPair>() {
@Override
@@ -178,7 +158,7 @@ public class IntIntPair implements Comparable<IntIntPair>, PairInterface<Integer
return o1.second - o2.second;
}
};
-
+
/**
* Comparator to compare by swapped components
*/
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/Pair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/Pair.java
index ca8db67d..c423cdd8 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/Pair.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/pairs/Pair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.pairs;
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,17 +26,21 @@ package de.lmu.ifi.dbs.elki.utilities.pairs;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
/**
- * Generic SimplePair<FIRST,SECOND> class.
+ * Simple class wrapping two objects.
*
- * Does not implement any "special" interfaces such as Comparable, use
- * {@link CPair} if you want comparable pairs.
+ * <b>Do not use this for primitive types such as {@code Integer} and
+ * {@code Double} - avoid the memory waste and garbage collection overhead!</b>
+ *
+ * Does not implement any "special" interfaces such as Comparable. If you need
+ * more complicated pairs, please use <em>domain specific</em> code, with more
+ * meaningful field names and comparators.
*
* @author Erich Schubert
*
* @param <FIRST> first type
* @param <SECOND> second type
*/
-public class Pair<FIRST, SECOND> implements PairInterface<FIRST, SECOND> {
+public class Pair<FIRST, SECOND> {
/**
* First value in pair
*/
@@ -71,7 +75,6 @@ public class Pair<FIRST, SECOND> implements PairInterface<FIRST, SECOND> {
*
* @return first element in pair
*/
- @Override
public final FIRST getFirst() {
return first;
}
@@ -90,7 +93,6 @@ public class Pair<FIRST, SECOND> implements PairInterface<FIRST, SECOND> {
*
* @return second element in pair
*/
- @Override
public final SECOND getSecond() {
return second;
}
@@ -145,8 +147,9 @@ public class Pair<FIRST, SECOND> implements PairInterface<FIRST, SECOND> {
if(other.first != null) {
return false;
}
- } else {
- if (!this.first.equals(other.first)) {
+ }
+ else {
+ if(!this.first.equals(other.first)) {
return false;
}
}
@@ -154,8 +157,9 @@ public class Pair<FIRST, SECOND> implements PairInterface<FIRST, SECOND> {
if(other.second != null) {
return false;
}
- } else {
- if (!this.second.equals(other.second)) {
+ }
+ else {
+ if(!this.second.equals(other.second)) {
return false;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/PairInterface.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/PairInterface.java
deleted file mode 100644
index fde1f3a9..00000000
--- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/PairInterface.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.pairs;
-
-/*
- 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/>.
- */
-
-
-/**
- * Pair interface.
- *
- * Note: this currently is <em>empty by design</em>. You should always decide
- * explicitly whether to use boxing pairs {@link Pair} or primitive pairs such
- * as {@link IntIntPair}
- *
- * @author Erich Schubert
- *
- * @param FIRST first type
- * @param SECOND second type
- */
-public interface PairInterface<FIRST, SECOND> {
- /**
- * Get the first object - note: this may cause autoboxing, use pair.first for native pairs!
- *
- * @return First object
- */
- public FIRST getFirst();
-
- /**
- * Get the second object - note: this may cause autoboxing, use pair.second for native pairs!
- *
- * @return Second object
- */
- public SECOND getSecond();
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/PairUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/PairUtil.java
deleted file mode 100644
index 387d4f79..00000000
--- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/PairUtil.java
+++ /dev/null
@@ -1,478 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.pairs;
-
-/*
- 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.Comparator;
-
-/**
- * Utility functions for (boxed) Pair classes.
- *
- * @author Erich Schubert
- *
- * @apiviz.uses Pair
- * @apiviz.has CompareNatural
- * @apiviz.has CompareNaturalFirst
- * @apiviz.has CompareNaturalSecond
- * @apiviz.has CompareNaturalSwapped
- * @apiviz.has Compare
- * @apiviz.has CompareByFirst
- * @apiviz.has CompareBySecond
- * @apiviz.has CompareSwapped
- */
-public final class PairUtil {
- /**
- * Return a comparator for this pair, given that both components are already
- * comparable. (So it could have been a CPair)
- *
- * @param <FIRST> First type
- * @param <SECOND> Second type
- * @return Comparator
- */
- public static <FIRST extends Comparable<? super FIRST>, SECOND extends Comparable<? super SECOND>> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparator() {
- return new CompareNatural<>();
- }
-
- /**
- * Return a derived comparator given a comparator for each component.
- *
- * @param <FIRST> First type
- * @param <SECOND> Second type
- * @param c1 First comparator
- * @param c2 Second comparator
- * @return Comparator
- */
- public static <FIRST, SECOND> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparator(Comparator<? super FIRST> c1, Comparator<? super SECOND> c2) {
- return new Compare<>(c1, c2);
- }
-
- /**
- * Return a comparator by first component for this pair, given that the first
- * component is already comparable. (So it could have been a FCPair)
- *
- * @param <FIRST> First type
- * @param <SECOND> Second type
- * @return Comparator
- */
- public static <FIRST extends Comparable<? super FIRST>, SECOND> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparatorFirst() {
- return new CompareNaturalFirst<>();
- }
-
- /**
- * Return a derived comparator by first component given a comparator for this
- * component.
- *
- * @param <FIRST> First type
- * @param <SECOND> Second type
- * @param c1 Comparator for first
- * @return Comparator
- */
- public static <FIRST, SECOND> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparatorFirst(Comparator<? super FIRST> c1) {
- return new CompareByFirst<>(c1);
- }
-
- /**
- * Return a comparator by first component for this pair, given that the first
- * component is already comparable. (So it could have been a FCPair)
- *
- * @param <FIRST> First type
- * @param <SECOND> Second type
- * @return Comparator
- */
- public static <FIRST, SECOND extends Comparable<? super SECOND>> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparatorSecond() {
- return new CompareNaturalSecond<>();
- }
-
- /**
- * Return a derived comparator by first component given a comparator for this
- * component.
- *
- * @param <FIRST> First type
- * @param <SECOND> Second type
- * @param c2 Comparator for second
- * @return Comparator
- */
- public static <FIRST, SECOND> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparatorSecond(Comparator<? super SECOND> c2) {
- return new CompareBySecond<>(c2);
- }
-
- /**
- * Return a component-swapped comparator for this pair, given that both
- * components are already comparable. (So it could have been a CPair)
- *
- * @param <FIRST> First type
- * @param <SECOND> Second type
- * @return Comparator
- */
- public static <FIRST extends Comparable<? super FIRST>, SECOND extends Comparable<? super SECOND>> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparatorSwapped() {
- return new CompareNaturalSwapped<>();
- }
-
- /**
- * Return a derived component-swapped comparator given a comparator for each
- * component.
- *
- * @param <FIRST> First type
- * @param <SECOND> Second type
- * @param c1 First comparator
- * @param c2 Second comparator
- * @return Comparator
- */
- public static <FIRST, SECOND> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparatorSwapped(Comparator<? super FIRST> c1, Comparator<? super SECOND> c2) {
- return new CompareSwapped<>(c1, c2);
- }
-
- /**
- * Class to do a "natural order" comparison on this class.
- *
- * @param <FIRST> First type
- * @param <SECOND> Second type
- */
- public static final class CompareNatural<FIRST extends Comparable<? super FIRST>, SECOND extends Comparable<? super SECOND>> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> {
- /**
- * Compare by first, then by second.
- *
- * @param o1 First object
- * @param o2 Second object
- */
- @Override
- public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) {
- // try comparing by first
- if(o1.first != null) {
- if(o2.first == null) {
- return -1;
- }
- int delta1 = o1.first.compareTo(o2.first);
- if(delta1 != 0) {
- return delta1;
- }
- }
- else if(o2.first != null) {
- return +1;
- }
- // try comparing by second
- if(o1.second != null) {
- if(o2.second == null) {
- return -1;
- }
- int delta2 = o1.second.compareTo(o2.second);
- if(delta2 != 0) {
- return delta2;
- }
- }
- else if(o2.second != null) {
- return +1;
- }
- return 0;
- }
-
- }
-
- /**
- * Class to do a natural comparison on this class' first component.
- *
- * @param <FIRST> First type
- * @param <SECOND> Second type
- */
- public static final class CompareNaturalFirst<FIRST extends Comparable<? super FIRST>, SECOND> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> {
- /**
- * Compare by first component natural ordering
- *
- * @param o1 First object
- * @param o2 Second object
- */
- @Override
- public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) {
- // try comparing by first
- if(o1.first != null) {
- if(o2.first == null) {
- return -1;
- }
- int delta1 = o1.first.compareTo(o2.first);
- if(delta1 != 0) {
- return delta1;
- }
- }
- else if(o2.first != null) {
- return +1;
- }
- return 0;
- }
-
- }
-
- /**
- * Class to do a natural comparison on this class' second component.
- *
- * @param <FIRST> First type
- * @param <SECOND> Second type
- */
- public static final class CompareNaturalSecond<FIRST, SECOND extends Comparable<? super SECOND>> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> {
- /**
- * Compare by second components natural ordering
- *
- * @param o1 First object
- * @param o2 Second object
- */
- @Override
- public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) {
- // try comparing by second
- if(o1.second != null) {
- if(o2.second == null) {
- return -1;
- }
- int delta2 = o1.second.compareTo(o2.second);
- if(delta2 != 0) {
- return delta2;
- }
- }
- else if(o2.second != null) {
- return +1;
- }
- return 0;
- }
-
- }
-
- /**
- * Class to do a canonical swapped comparison on this class.
- *
- * @param <FIRST> First type
- * @param <SECOND> Second type
- */
- public static final class CompareNaturalSwapped<FIRST extends Comparable<? super FIRST>, SECOND extends Comparable<? super SECOND>> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> {
- /**
- * Compare by second component, using the ComparableSwapped interface.
- *
- * @param o1 First object
- * @param o2 Second object
- */
- @Override
- public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) {
- // try comparing by second
- if(o1.second != null) {
- if(o2.second == null) {
- return -1;
- }
- int delta2 = o1.second.compareTo(o2.second);
- if(delta2 != 0) {
- return delta2;
- }
- }
- else if(o2.second != null) {
- return +1;
- }
- // try comparing by first
- if(o1.first != null) {
- if(o2.first == null) {
- return -1;
- }
- int delta1 = o1.first.compareTo(o2.first);
- if(delta1 != 0) {
- return delta1;
- }
- }
- else if(o2.first != null) {
- return +1;
- }
- return 0;
- }
-
- }
-
- /**
- * Compare two SimplePairs based on two comparators
- *
- * @param <FIRST> first type
- * @param <SECOND> second type
- */
- public static class Compare<FIRST, SECOND> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> {
- /**
- * A comparator for type FIRST.
- */
- private Comparator<? super FIRST> fcomparator;
-
- /**
- * A comparator for type FIRST.
- */
- private Comparator<? super SECOND> scomparator;
-
- /**
- * Provides a comparator for an {@link Pair} based on the given Comparator
- * for type <code>P</code>.
- *
- * @param fcomparator Comparator for the first component
- * @param scomparator Comparator for the second component
- */
- public Compare(Comparator<? super FIRST> fcomparator, Comparator<? super SECOND> scomparator) {
- this.fcomparator = fcomparator;
- this.scomparator = scomparator;
- }
-
- /**
- * Two Objects of type {@link Pair} are compared based on the comparison of
- * their property using the comparators {@link #fcomparator}, then
- * {@link #scomparator}.
- *
- * @param o1 First object
- * @param o2 Second object
- * @return comparison result
- * @see java.util.Comparator#compare
- */
- @Override
- public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) {
- int delta1 = fcomparator.compare(o1.getFirst(), o2.getFirst());
- if(delta1 != 0) {
- return delta1;
- }
- return scomparator.compare(o1.getSecond(), o2.getSecond());
- }
- }
-
- /**
- * Compare two SimplePairs based on a comparator for the first component.
- *
- * @param <FIRST> first type
- * @param <SECOND> second type
- */
- public static class CompareByFirst<FIRST, SECOND> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> {
- /**
- * A comparator for type P.
- */
- private Comparator<? super FIRST> comparator;
-
- /**
- * Provides a comparator for an {@link Pair} based on the given Comparator
- * for type <code>P</code>.
- *
- * @param comparator a Comparator for type <code>P</code> to base the
- * comparison of an {@link Pair} on
- */
- public CompareByFirst(Comparator<? super FIRST> comparator) {
- this.comparator = comparator;
- }
-
- /**
- * To Objects of type {@link Pair} are compared based on the comparison of
- * their property using the current {@link #comparator}.
- *
- * @param o1 First object
- * @param o2 Second object
- * @return comparison result
- * @see java.util.Comparator#compare
- */
- @Override
- public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) {
- return comparator.compare(o1.getFirst(), o2.getFirst());
- }
- }
-
- /**
- * Compare two SimplePairs based on a comparator for the second component.
- *
- * @param <FIRST> first type
- * @param <SECOND> second type
- */
- public static class CompareBySecond<FIRST, SECOND> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> {
- /**
- * A comparator for type P.
- */
- private Comparator<? super SECOND> comparator;
-
- /**
- * Provides a comparator for an {@link Pair} based on the given Comparator
- * for type <code>P</code>.
- *
- * @param comparator a Comparator for type <code>P</code> to base the
- * comparison of an {@link Pair} on
- */
- public CompareBySecond(Comparator<? super SECOND> comparator) {
- this.comparator = comparator;
- }
-
- /**
- * To Objects of type {@link Pair} are compared based on the comparison of
- * their property using the current {@link #comparator}.
- *
- * @param o1 First object
- * @param o2 Second object
- * @return comparison result
- * @see java.util.Comparator#compare
- */
- @Override
- public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) {
- return comparator.compare(o1.getSecond(), o2.getSecond());
- }
- }
-
- /**
- * Compare two SimplePairs based on two comparators, but by second component
- * first.
- *
- * @param <FIRST> first type
- * @param <SECOND> second type
- */
- public static class CompareSwapped<FIRST, SECOND> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> {
- /**
- * A comparator for type FIRST.
- */
- private Comparator<? super FIRST> fcomparator;
-
- /**
- * A comparator for type FIRST.
- */
- private Comparator<? super SECOND> scomparator;
-
- /**
- * Provides a comparator for an {@link Pair} based on the given Comparator
- * for type <code>P</code>.
- *
- * @param fcomparator Comparator for the first component
- * @param scomparator Comparator for the second component
- */
- public CompareSwapped(Comparator<? super FIRST> fcomparator, Comparator<? super SECOND> scomparator) {
- this.fcomparator = fcomparator;
- this.scomparator = scomparator;
- }
-
- /**
- * Two Objects of type {@link Pair} are compared based on the comparison of
- * their property using the given comparators {@link #scomparator}, then
- * {@link #fcomparator}.
- *
- * @param o1 First object
- * @param o2 Second object
- * @return comparison result
- * @see java.util.Comparator#compare
- */
- @Override
- public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) {
- int delta2 = scomparator.compare(o1.getSecond(), o2.getSecond());
- if(delta2 != 0) {
- return delta2;
- }
- return fcomparator.compare(o1.getFirst(), o2.getFirst());
- }
- }
-
-}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/SCPair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/SCPair.java
deleted file mode 100644
index 90d7f738..00000000
--- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/SCPair.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.pairs;
-
-/*
- 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.utilities.ClassGenericsUtil;
-
-/**
- * Pair that can <em>only</em> be compared by it's second component.
- *
- * @author Erich Schubert
- *
- * @param <FIRST> first type (comparable)
- * @param <SECOND> second type
- */
-public class SCPair<FIRST, SECOND extends Comparable<? super SECOND>> extends Pair<FIRST, SECOND> implements Comparable<SCPair<FIRST, SECOND>> {
- /**
- * Initialize pair
- *
- * @param first first parameter
- * @param second second parameter
- */
- public SCPair(FIRST first, SECOND second) {
- super(first, second);
- }
-
- /**
- * Generic derived compare function.
- *
- * @param other Object to compare to
- * @return comparison result
- */
- @Override
- public int compareTo(SCPair<FIRST, SECOND> other) {
- // try comparing by first
- if(this.second != null) {
- if(other.second == null) {
- return -1;
- }
- int delta1 = this.second.compareTo(other.second);
- if(delta1 != 0) {
- return delta1;
- }
- }
- else if(other.second != null) {
- return +1;
- }
- return 0;
- }
-
- /**
- * Array constructor for generics
- *
- * @param <F> First type
- * @param <S> Second type
- * @param size Size of array to be constructed
- * @return New array of requested size
- */
- public static final <F, S extends Comparable<? super S>> SCPair<F, S>[] newArray(int size) {
- Class<SCPair<F,S>> paircls = ClassGenericsUtil.uglyCastIntoSubclass(SCPair.class);
- return ClassGenericsUtil.newArrayOfNull(size, paircls);
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/Triple.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/Triple.java
deleted file mode 100644
index 4cac1e9c..00000000
--- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/Triple.java
+++ /dev/null
@@ -1,215 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.pairs;
-
-/*
- 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.utilities.ClassGenericsUtil;
-
-/**
- * Triple without comparison.
- *
- * See also {@link CTriple}
- *
- * @author Erich Schubert
- *
- * @param <FIRST> first type
- * @param <SECOND> second type
- * @param <THIRD> second type
- */
-public class Triple<FIRST, SECOND, THIRD> {
- /**
- * First value
- */
- public FIRST first;
-
- /**
- * Second value
- */
- public SECOND second;
-
- /**
- * Third value
- */
- public THIRD third;
-
- /**
- * Constructor with fields
- *
- * @param first Value of first component
- * @param second Value of second component
- * @param third Value of third component
- */
- public Triple(FIRST first, SECOND second, THIRD third) {
- this.first = first;
- this.second = second;
- this.third = third;
- }
-
- /**
- * Canonical toString operator
- */
- @Override
- public String toString() {
- return "Triple(" + (first != null ? first.toString() : "null") + ", " + (second != null ? second.toString() : "null") + ", " + (third != null ? third.toString() : "null") + ")";
- }
-
- /**
- * Getter for first
- *
- * @return first element in triple
- */
- public final FIRST getFirst() {
- return first;
- }
-
- /**
- * Setter for first
- *
- * @param first new value for first element
- */
- public final void setFirst(FIRST first) {
- this.first = first;
- }
-
- /**
- * Getter for second element in triple
- *
- * @return second element in triple
- */
- public final SECOND getSecond() {
- return second;
- }
-
- /**
- * Setter for second
- *
- * @param second new value for second element
- */
- public final void setSecond(SECOND second) {
- this.second = second;
- }
-
- /**
- * Getter for third
- *
- * @return third element in triple
- */
- public final THIRD getThird() {
- return third;
- }
-
- /**
- * Setter for third
- *
- * @param third new value for third element
- */
- public final void setThird(THIRD third) {
- this.third = third;
- }
-
- /**
- * Array constructor for generics
- * @param <F> First type
- * @param <S> Second type
- * @param <T> Third type
- *
- * @param size Size of array to be constructed.
- * @return new array of the requested size.
- */
- public static final <F, S, T> Triple<F, S, T>[] newArray(int size) {
- Class<Triple<F,S,T>> tripcls = ClassGenericsUtil.uglyCastIntoSubclass(Triple.class);
- return ClassGenericsUtil.newArrayOfNull(size, tripcls);
- }
-
- /**
- * Canonical equals function
- *
- * @param obj Object to compare to
- */
- @SuppressWarnings("unchecked")
- @Override
- public boolean equals(Object obj) {
- if(obj == null) {
- return false;
- }
- if(!(obj instanceof Triple)) {
- return false;
- }
- Triple<FIRST, SECOND, THIRD> other = (Triple<FIRST, SECOND, THIRD>) obj;
- if(this.first == null) {
- if(other.getFirst() != null) {
- return false;
- }
- }
- else {
- if(other.getFirst() == null) {
- return false;
- }
- if(!this.first.equals(other.getFirst())) {
- return false;
- }
- }
- if(this.second == null) {
- if(other.getSecond() != null) {
- return false;
- }
- }
- else {
- if(other.getSecond() == null) {
- return false;
- }
- if(!this.second.equals(other.getSecond())) {
- return false;
- }
- }
- if(this.third == null) {
- if(other.getThird() != null) {
- return false;
- }
- }
- else {
- if(other.getThird() == null) {
- return false;
- }
- if(!this.third.equals(other.getThird())) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Canonical derived hash function
- */
- @Override
- public int hashCode() {
- // primitive hash function mixing the three integer hash values.
- // this number does supposedly not have any factors in common with 2^32
- final long prime = 2654435761L;
- long result = 1;
- result = prime * result + ((first == null) ? 0 : first.hashCode());
- result = prime * result + ((second == null) ? 0 : second.hashCode());
- result = prime * result + ((third == null) ? 0 : third.hashCode());
- return (int) result;
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/package-info.java
index 6a4e9501..b1d1fb90 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/pairs/package-info.java
@@ -1,20 +1,7 @@
/**
- * <p>Pairs and triples utility classes.</p>
- * <p>Pairs and triples are frequently used classes and reimplemented too often.</p>
- *
- * <ul>
- * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.Pair Pair} is the generic <em>non-comparable</em> pair (you can use external comparators!).</li>
- * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.FCPair FCPair} is the generic pair comparable in the <em>first</em> component only.</li>
- * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.CPair CPair} is the pair comparable in <em>both</em> components.</li>
- * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.SCPair SCPair} is the generic pair comparable in the <em>second</em> component only.</li>
- * </ul>
- *
- * <p>Due to limitations in object subclassing, {@link de.lmu.ifi.dbs.elki.utilities.pairs.CPair CPair} cannot be
- * a subclass of {@link de.lmu.ifi.dbs.elki.utilities.pairs.FCPair FCPair}, since a class cannot implement
- * the Comparable interface twice.</p>
- *
- * <p>Also primitive types cannot be used in Generics, resulting in the following classes for primitive types:</p>
+ * <p>Pairs utility classes.</p>
*
+ * A number of commonly needed primitive pairs are the following:
* <ul>
* <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.IntIntPair IntIntPair} storing two <code>int</code> values</li>
* <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair DoubleIntPair} storing one <code>double</code> and one <code>int</code> value.</li>
@@ -22,37 +9,34 @@
* <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.DoubleDoublePair DoubleDoublePair} storing two <code>double</code> values</li>
* </ul>
*
- * <p>Triples can be used via:</p>
+ * Why no more {@code Pair<A,B>}?
* <ul>
- * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.Triple Triple} is the generic non-comparable triple.</li>
- * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.CTriple CTriple} is the triple comparable in <em>all</em> components.</li>
- * </ul>
- *
- * <p>If you need a triple comparable in just particular components, either define a comparator for sorting
- * or subclass Triple appropriately.</p>
+ * <li>Because such pairs are expensive in Java when using primitive types.</li>
+ * <li>Because domain-specific code can often be optimized better by the HotSpot VM.</li>
+ * </ul>
*
* @apiviz.exclude java.lang.
*/
/*
-This file is part of ELKI:
-Environment for Developing KDD-Applications Supported by Index-Structures
+ 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
+ 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 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.
+ 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/>.
-*/
+ 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.utilities.pairs; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/AxisBasedReferencePoints.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/AxisBasedReferencePoints.java
index d8544cd4..35cf11f2 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/AxisBasedReferencePoints.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/AxisBasedReferencePoints.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints;
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,12 @@ import java.util.Collection;
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.utilities.DatabaseUtil;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
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.DoubleParameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Strategy to pick reference points by placing them on the axis ends.
@@ -44,21 +43,10 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
* surrounding cube.
*
* @author Erich Schubert
- *
- * @param <V> Vector type
*/
-public class AxisBasedReferencePoints<V extends NumberVector<?>> implements ReferencePointsHeuristic<V> {
- /**
- * Parameter to specify the extra scaling of the space, to allow
- * out-of-data-space reference points.
- * <p>
- * Key: {@code -axisref.scale}
- * </p>
- */
- public static final OptionID SPACE_SCALE_ID = new OptionID("axisref.scale", "Scale the data space extension by the given factor.");
-
+public class AxisBasedReferencePoints implements ReferencePointsHeuristic {
/**
- * Holds the value of {@link #SPACE_SCALE_ID}.
+ * Scaling factor.
*/
protected double spacescale;
@@ -73,33 +61,29 @@ public class AxisBasedReferencePoints<V extends NumberVector<?>> implements Refe
}
@Override
- public <T extends V> Collection<V> getReferencePoints(Relation<T> db) {
- Relation<V> database = DatabaseUtil.relationUglyVectorCast(db);
- Pair<V, V> minmax = DatabaseUtil.computeMinMax(database);
- NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(database);
-
+ public Collection<? extends NumberVector> getReferencePoints(Relation<? extends NumberVector> db) {
+ double[][] minmax = RelationUtil.computeMinMax(db);
int dim = RelationUtil.dimensionality(db);
// Compute mean and extend from minmax.
- double[] mean = new double[dim];
- double[] delta = new double[dim];
+ double[] mean = minmax[0], delta = minmax[1];
for(int d = 0; d < dim; d++) {
- mean[d] = (minmax.first.doubleValue(d) + minmax.second.doubleValue(d)) * .5;
- delta[d] = spacescale * (minmax.second.doubleValue(d) - mean[d]);
+ delta[d] -= mean[d];
+ mean[d] -= delta[d] * .5;
}
- ArrayList<V> result = new ArrayList<>(2 + dim);
+ ArrayList<Vector> result = new ArrayList<>(2 + dim);
double[] vec = new double[dim];
// Use min and max
for(int d = 0; d < dim; d++) {
vec[d] = mean[d] - delta[d];
}
- result.add(factory.newNumberVector(vec));
+ result.add(new Vector(vec));
for(int d = 0; d < dim; d++) {
vec[d] = mean[d] + delta[d];
}
- result.add(factory.newNumberVector(vec));
+ result.add(new Vector(vec));
// Plus axis end points:
for(int i = 0; i < dim; i++) {
@@ -111,7 +95,7 @@ public class AxisBasedReferencePoints<V extends NumberVector<?>> implements Refe
vec[d] = mean[d] + delta[d];
}
}
- result.add(factory.newNumberVector(vec));
+ result.add(new Vector(vec));
}
return result;
@@ -124,7 +108,16 @@ public class AxisBasedReferencePoints<V extends NumberVector<?>> implements Refe
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Parameter to specify the extra scaling of the space, to allow
+ * out-of-data-space reference points.
+ * <p>
+ * Key: {@code -axisref.scale}
+ * </p>
+ */
+ public static final OptionID SPACE_SCALE_ID = new OptionID("axisref.scale", "Scale the data space extension by the given factor.");
+
/**
* Holds the value of {@link #SPACE_SCALE_ID}.
*/
@@ -133,16 +126,16 @@ public class AxisBasedReferencePoints<V extends NumberVector<?>> implements Refe
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- DoubleParameter spacescaleP = new DoubleParameter(SPACE_SCALE_ID, 1.0);
- spacescaleP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ DoubleParameter spacescaleP = new DoubleParameter(SPACE_SCALE_ID, 1.0)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
if(config.grab(spacescaleP)) {
spacescale = spacescaleP.getValue();
}
}
@Override
- protected AxisBasedReferencePoints<V> makeInstance() {
- return new AxisBasedReferencePoints<>(spacescale);
+ protected AxisBasedReferencePoints makeInstance() {
+ return new AxisBasedReferencePoints(spacescale);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/FullDatabaseReferencePoints.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/FullDatabaseReferencePoints.java
index b92d0575..644dccba 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/FullDatabaseReferencePoints.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/FullDatabaseReferencePoints.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints;
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,16 +27,14 @@ import java.util.Collection;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
+import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
/**
* Strategy to use the complete database as reference points.
*
* @author Erich Schubert
- *
- * @param <O> Object type.
*/
-public class FullDatabaseReferencePoints<O extends NumberVector<?>> implements ReferencePointsHeuristic<O> {
+public class FullDatabaseReferencePoints implements ReferencePointsHeuristic {
/**
* Constructor, Parameterizable style.
*/
@@ -45,7 +43,7 @@ public class FullDatabaseReferencePoints<O extends NumberVector<?>> implements R
}
@Override
- public <T extends O> Collection<O> getReferencePoints(Relation<T> db) {
- return new DatabaseUtil.CollectionFromRelation<O>(db);
+ public Collection<? extends NumberVector> getReferencePoints(Relation<? extends NumberVector> db) {
+ return new RelationUtil.CollectionFromRelation<>(db);
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/GridBasedReferencePoints.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/GridBasedReferencePoints.java
index 007efe6f..5ebee64b 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/GridBasedReferencePoints.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/GridBasedReferencePoints.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints;
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,50 +29,35 @@ import java.util.Collection;
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.logging.Logging;
import de.lmu.ifi.dbs.elki.math.MathUtil;
-import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+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.constraints.CommonConstraints;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Grid-based strategy to pick reference points.
*
* @author Erich Schubert
- *
- * @param <V> Object type
*/
-public class GridBasedReferencePoints<V extends NumberVector<?>> implements ReferencePointsHeuristic<V> {
- // TODO: add "grid sampling" option.
-
- /**
- * Parameter to specify the grid resolution.
- * <p>
- * Key: {@code -grid.size}
- * </p>
- */
- public static final OptionID GRID_ID = new OptionID("grid.size", "The number of partitions in each dimension. Points will be placed on the edges of the grid, except for a grid size of 0, where only the mean is generated as reference point.");
-
+public class GridBasedReferencePoints implements ReferencePointsHeuristic {
/**
- * Parameter to specify the extra scaling of the space, to allow
- * out-of-data-space reference points.
- * <p>
- * Key: {@code -grid.oversize}
- * </p>
+ * Class logger.
*/
- public static final OptionID GRID_SCALE_ID = new OptionID("grid.scale", "Scale the grid by the given factor. This can be used to obtain reference points outside the used data space.");
+ private static final Logging LOG = Logging.getLogger(GridBasedReferencePoints.class);
/**
- * Holds the value of {@link #GRID_ID}.
+ * Holds the grid resolution.
*/
protected int gridres;
/**
- * Holds the value of {@link #GRID_SCALE_ID}.
+ * Holds the grid scale.
*/
protected double gridscale;
@@ -89,46 +74,47 @@ public class GridBasedReferencePoints<V extends NumberVector<?>> implements Refe
}
@Override
- public <T extends V> Collection<V> getReferencePoints(Relation<T> db) {
- Relation<V> database = DatabaseUtil.relationUglyVectorCast(db);
- Pair<V, V> minmax = DatabaseUtil.computeMinMax(database);
- NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(database);
-
- int dim = RelationUtil.dimensionality(db);
+ public Collection<? extends NumberVector> getReferencePoints(Relation<? extends NumberVector> db) {
+ double[][] minmax = RelationUtil.computeMinMax(db);
+ final int dim = minmax[0].length;
// Compute mean from minmax.
double[] mean = new double[dim];
for(int d = 0; d < dim; d++) {
- mean[d] = (minmax.first.doubleValue(d) + minmax.second.doubleValue(d)) * .5;
+ mean[d] = (minmax[0][d] + minmax[1][d]) * .5;
}
- int gridpoints = Math.max(1, MathUtil.ipowi(gridres + 1, dim));
- ArrayList<V> result = new ArrayList<>(gridpoints);
+ if(gridres <= 0) {
+ LOG.warning("Grid of resolution " + gridres + " will have a single point only.");
+ ArrayList<Vector> result = new ArrayList<>(1);
+ result.add(new Vector(mean));
+ return result;
+ }
+ final int grids = gridres + 1;
+ final int gridpoints = MathUtil.ipowi(grids, dim);
+ if(gridpoints < 0) {
+ throw new AbortException("Grids with more than 2^31 are not supported, or meaningful.");
+ }
+ if(gridpoints < 0 || gridpoints > db.size()) {
+ LOG.warning("Grid has " + gridpoints + " points, but you only have " + db.size() + " observations.");
+ }
+ ArrayList<Vector> result = new ArrayList<>(gridpoints);
double[] delta = new double[dim];
- if(gridres > 0) {
- double halfgrid = gridres / 2.0;
- for(int d = 0; d < dim; d++) {
- delta[d] = (minmax.second.doubleValue(d) - minmax.first.doubleValue(d)) / gridres;
- }
+ for(int d = 0; d < dim; d++) {
+ delta[d] = (minmax[1][d] - minmax[0][d]) / gridres;
+ }
- double[] vec = new double[dim];
- for(int i = 0; i < gridpoints; i++) {
- int acc = i;
- for(int d = 0; d < dim; d++) {
- int coord = acc % (gridres + 1);
- acc = acc / (gridres + 1);
- vec[d] = mean[d] + (coord - halfgrid) * delta[d] * gridscale;
- }
- V newp = factory.newNumberVector(vec);
- // logger.debug("New reference point: " + FormatUtil.format(vec));
- result.add(newp);
+ double halfgrid = gridres * .5;
+ for(int i = 0; i < gridpoints; i++) {
+ double[] vec = new double[dim]; // Will be returned!
+ int acc = i;
+ for(int d = 0; d < dim; d++) {
+ int coord = acc % grids;
+ acc /= grids;
+ vec[d] = mean[d] + (coord - halfgrid) * delta[d] * gridscale;
}
+ result.add(new Vector(vec));
}
- else {
- result.add(factory.newNumberVector(mean));
- // logger.debug("New reference point: " + FormatUtil.format(mean));
- }
-
return result;
}
@@ -139,7 +125,26 @@ public class GridBasedReferencePoints<V extends NumberVector<?>> implements Refe
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer extends AbstractParameterizer {
+ // TODO: add "grid sampling" option.
+
+ /**
+ * Parameter to specify the grid resolution.
+ * <p>
+ * Key: {@code -grid.size}
+ * </p>
+ */
+ public static final OptionID GRID_ID = new OptionID("grid.size", "The number of partitions in each dimension. Points will be placed on the edges of the grid, except for a grid size of 0, where only the mean is generated as reference point.");
+
+ /**
+ * Parameter to specify the extra scaling of the space, to allow
+ * out-of-data-space reference points.
+ * <p>
+ * Key: {@code -grid.oversize}
+ * </p>
+ */
+ public static final OptionID GRID_SCALE_ID = new OptionID("grid.scale", "Scale the grid by the given factor. This can be used to obtain reference points outside the used data space.");
+
/**
* Holds the value of {@link #GRID_ID}.
*/
@@ -167,8 +172,8 @@ public class GridBasedReferencePoints<V extends NumberVector<?>> implements Refe
}
@Override
- protected GridBasedReferencePoints<V> makeInstance() {
- return new GridBasedReferencePoints<>(gridres, gridscale);
+ protected GridBasedReferencePoints makeInstance() {
+ return new GridBasedReferencePoints(gridres, gridscale);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomGeneratedReferencePoints.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomGeneratedReferencePoints.java
index 9d866ecc..58d1c886 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomGeneratedReferencePoints.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomGeneratedReferencePoints.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints;
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,86 +29,70 @@ import java.util.Collection;
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.utilities.DatabaseUtil;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
/**
* Reference points generated randomly within the used data space.
*
* @author Erich Schubert
- *
- * @param <V> Object type
*/
-// TODO: Erich: use reproducible random
-public class RandomGeneratedReferencePoints<V extends NumberVector<?>> implements ReferencePointsHeuristic<V> {
- /**
- * Parameter to specify the number of requested reference points.
- * <p>
- * Key: {@code -generate.n}
- * </p>
- */
- public static final OptionID N_ID = new OptionID("generate.n", "The number of reference points to be generated.");
-
+public class RandomGeneratedReferencePoints implements ReferencePointsHeuristic {
/**
- * Parameter for additional scaling of the space, to allow out-of-space
- * reference points.
- * <p>
- * Key: {@code -generate.scale}
- * </p>
+ * Holds the sample size.
*/
- public static final OptionID SCALE_ID = new OptionID("generate.scale", "Scale the grid by the given factor. This can be used to obtain reference points outside the used data space.");
+ protected int samplesize;
/**
- * Holds the value of {@link #N_ID}.
+ * Holds the scaling factor.
*/
- protected int samplesize;
+ protected double scale = 1.0;
/**
- * Holds the value of {@link #SCALE_ID}.
+ * Random generator.
*/
- protected double scale = 1.0;
+ protected RandomFactory rnd;
/**
* Constructor.
*
* @param samplesize Size of desired sample set
* @param scale Scaling factor
+ * @param rnd Random generator
*/
- public RandomGeneratedReferencePoints(int samplesize, double scale) {
+ public RandomGeneratedReferencePoints(int samplesize, double scale, RandomFactory rnd) {
super();
this.samplesize = samplesize;
this.scale = scale;
+ this.rnd = rnd;
}
@Override
- public <T extends V> Collection<V> getReferencePoints(Relation<T> db) {
- Relation<V> database = DatabaseUtil.relationUglyVectorCast(db);
- Pair<V, V> minmax = DatabaseUtil.computeMinMax(database);
- NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(database);
-
+ public Collection<? extends NumberVector> getReferencePoints(Relation<? extends NumberVector> db) {
+ double[][] minmax = RelationUtil.computeMinMax(db);
int dim = RelationUtil.dimensionality(db);
- // Compute mean from minmax.
- double[] mean = new double[dim];
- double[] delta = new double[dim];
+ // Compute mean and extend from minmax.
+ double[] mean = minmax[0], delta = minmax[1];
for(int d = 0; d < dim; d++) {
- mean[d] = (minmax.first.doubleValue(d + 1) + minmax.second.doubleValue(d + 1)) * .5;
- delta[d] = (minmax.second.doubleValue(d + 1) - minmax.first.doubleValue(d + 1));
+ delta[d] -= mean[d];
+ mean[d] -= delta[d] * .5;
}
- ArrayList<V> result = new ArrayList<>(samplesize);
+ ArrayList<Vector> result = new ArrayList<>(samplesize);
double[] vec = new double[dim];
for(int i = 0; i < samplesize; i++) {
for(int d = 0; d < dim; d++) {
vec[d] = mean[d] + (Math.random() - 0.5) * scale * delta[d];
}
- V newp = factory.newNumberVector(vec);
+ Vector newp = new Vector(vec);
// logger.debug("New reference point: " + FormatUtil.format(vec));
result.add(newp);
}
@@ -123,7 +107,32 @@ public class RandomGeneratedReferencePoints<V extends NumberVector<?>> implement
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Parameter to specify the number of requested reference points.
+ * <p>
+ * Key: {@code -generate.n}
+ * </p>
+ */
+ public static final OptionID N_ID = new OptionID("generate.n", "The number of reference points to be generated.");
+
+ /**
+ * Parameter for additional scaling of the space, to allow out-of-space
+ * reference points.
+ * <p>
+ * Key: {@code -generate.scale}
+ * </p>
+ */
+ public static final OptionID SCALE_ID = new OptionID("generate.scale", "Scale the grid by the given factor. This can be used to obtain reference points outside the used data space.");
+
+ /**
+ * Parameter to specify the sample size.
+ * <p>
+ * Key: {@code -generate.random}
+ * </p>
+ */
+ public static final OptionID RANDOM_ID = new OptionID("generate.random", "Random generator seed.");
+
/**
* Holds the value of {@link #N_ID}.
*/
@@ -134,26 +143,36 @@ public class RandomGeneratedReferencePoints<V extends NumberVector<?>> implement
*/
protected double scale = 1.0;
+ /**
+ * Random generator.
+ */
+ protected RandomFactory rnd;
+
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- IntParameter samplesizeP = new IntParameter(N_ID);
- samplesizeP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ IntParameter samplesizeP = new IntParameter(N_ID) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
if(config.grab(samplesizeP)) {
samplesize = samplesizeP.getValue();
}
- DoubleParameter scaleP = new DoubleParameter(SCALE_ID, 1.0);
- scaleP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ DoubleParameter scaleP = new DoubleParameter(SCALE_ID, 1.0) //
+ .addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
if(config.grab(scaleP)) {
scale = scaleP.getValue();
}
+
+ RandomParameter randomP = new RandomParameter(RANDOM_ID);
+ if(config.grab(randomP)) {
+ rnd = randomP.getValue();
+ }
}
@Override
- protected RandomGeneratedReferencePoints<V> makeInstance() {
- return new RandomGeneratedReferencePoints<>(samplesize, scale);
+ protected RandomGeneratedReferencePoints makeInstance() {
+ return new RandomGeneratedReferencePoints(samplesize, scale, rnd);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomSampleReferencePoints.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomSampleReferencePoints.java
index ea80d9d9..472d36d3 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomSampleReferencePoints.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomSampleReferencePoints.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints;
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,112 +25,62 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashSet;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.database.relation.RelationUtil;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
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.RandomParameter;
/**
* Random-Sampling strategy for picking reference points.
*
* @author Erich Schubert
- *
- * @param <V> Vector type
*/
-public class RandomSampleReferencePoints<V extends NumberVector<?>> implements ReferencePointsHeuristic<V> {
- // TODO: use reproducible Random
-
- /**
- * Parameter to specify the sample size.
- * <p>
- * Key: {@code -sample.n}
- * </p>
- */
- public static final OptionID N_ID = new OptionID("sample.n", "The number of samples to draw.");
-
+public class RandomSampleReferencePoints implements ReferencePointsHeuristic {
/**
- * Constant used in choosing optimal table sizes.
+ * Sample size.
*/
- private static final double LOG4 = Math.log(4);
+ protected int samplesize;
/**
- * Holds the value of {@link #N_ID}.
+ * Random generator.
*/
- private int samplesize;
+ protected RandomFactory rnd;
/**
* Constructor.
*
* @param samplesize Sampling size
*/
- public RandomSampleReferencePoints(int samplesize) {
+ public RandomSampleReferencePoints(int samplesize, RandomFactory rnd) {
super();
this.samplesize = samplesize;
+ this.rnd = rnd;
}
@Override
- public <T extends V> Collection<V> getReferencePoints(Relation<T> db) {
+ public Collection<? extends NumberVector> getReferencePoints(Relation<? extends NumberVector> db) {
if(samplesize >= db.size()) {
- LoggingUtil.warning("Sample size is larger than database size!");
-
- ArrayList<V> selection = new ArrayList<>(db.size());
- for(DBIDIter iditer = db.iterDBIDs(); iditer.valid(); iditer.advance()) {
- selection.add(db.get(iditer));
- }
- return selection;
+ LoggingUtil.warning("Requested sample size is larger than database size!");
+ return new RelationUtil.CollectionFromRelation<>(db);
}
- ArrayList<V> result = new ArrayList<>(samplesize);
- int dbsize = db.size();
+ ArrayList<NumberVector> result = new ArrayList<>(samplesize);
+ DBIDs sample = DBIDUtil.randomSample(db.getDBIDs(), samplesize, rnd);
- // Guess the memory requirements of a hashmap.
- // The values are based on Python code, and might need modification for
- // Java!
- // If the hashmap is likely to become too big, lazy-shuffle a list instead.
- int setsize = 21;
- if(samplesize > 5) {
- setsize += 2 << (int) Math.ceil(Math.log(samplesize * 3) / LOG4);
- }
- // logger.debug("Setsize: "+setsize);
- ArrayDBIDs ids = DBIDUtil.ensureArray(db.getDBIDs());
- boolean fastrandomaccess = false;
- if(ArrayList.class.isAssignableFrom(ids.getClass())) {
- fastrandomaccess = true;
- }
- if(samplesize <= setsize || !fastrandomaccess) {
- // use pool approach
- // if getIDs() is an array list, we don't need to copy it again.
- ArrayModifiableDBIDs pool = ((ArrayModifiableDBIDs.class.isAssignableFrom(ids.getClass())) ? (ArrayModifiableDBIDs) ids : DBIDUtil.newArray(ids));
- for(int i = 0; i < samplesize; i++) {
- int j = (int) Math.floor(Math.random() * (dbsize - i));
- result.add(db.get(pool.get(j)));
- pool.set(j, pool.get(dbsize - i - 1));
- }
- ids = null; // dirty!
- }
- else {
- HashSet<Integer> selected = new HashSet<>();
- for(int i = 0; i < samplesize; i++) {
- int j = (int) Math.floor(Math.random() * dbsize);
- // Redraw from pool.
- while(selected.contains(j)) {
- j = (int) Math.floor(Math.random() * dbsize);
- }
- selected.add(j);
- result.add(db.get(ids.get(j)));
- }
+ for(DBIDIter it = sample.iter(); it.valid(); it.advance()) {
+ result.add(db.get(it));
}
- assert (result.size() == samplesize);
return result;
}
@@ -141,25 +91,50 @@ public class RandomSampleReferencePoints<V extends NumberVector<?>> implements R
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Parameter to specify the sample size.
+ * <p>
+ * Key: {@code -sample.n}
+ * </p>
+ */
+ public static final OptionID N_ID = new OptionID("sample.n", "The number of samples to draw.");
+
/**
- * Holds the value of {@link #N_ID}.
+ * Parameter to specify the sample size.
+ * <p>
+ * Key: {@code -sample.random}
+ * </p>
+ */
+ public static final OptionID RANDOM_ID = new OptionID("sample.random", "Random generator seed.");
+
+ /**
+ * Sample size.
*/
protected int samplesize;
+ /**
+ * Random generator.
+ */
+ protected RandomFactory rnd;
+
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- IntParameter samplesizeP = new IntParameter(N_ID);
- samplesizeP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ IntParameter samplesizeP = new IntParameter(N_ID)//
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
if(config.grab(samplesizeP)) {
samplesize = samplesizeP.intValue();
}
+ RandomParameter randomP = new RandomParameter(RANDOM_ID);
+ if(config.grab(randomP)) {
+ rnd = randomP.getValue();
+ }
}
@Override
- protected RandomSampleReferencePoints<V> makeInstance() {
- return new RandomSampleReferencePoints<>(samplesize);
+ protected RandomSampleReferencePoints makeInstance() {
+ return new RandomSampleReferencePoints(samplesize, rnd);
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/ReferencePointsHeuristic.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/ReferencePointsHeuristic.java
index 672b5240..a20fdfd6 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/ReferencePointsHeuristic.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/ReferencePointsHeuristic.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints;
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,22 +25,20 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints;
import java.util.Collection;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Simple Interface for an heuristic to pick reference points.
*
* @author Erich Schubert
- *
- * @param <O> Object type
*/
-public interface ReferencePointsHeuristic<O> extends Parameterizable {
+public interface ReferencePointsHeuristic {
/**
* Get the reference points for the given database.
*
* @param db Database
* @return Collection of reference points.
*/
- public <T extends O> Collection<O> getReferencePoints(Relation<T> db);
+ public Collection<? extends NumberVector> getReferencePoints(Relation<? extends NumberVector> db);
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/StarBasedReferencePoints.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/StarBasedReferencePoints.java
index 74cdf92b..b8de4338 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/StarBasedReferencePoints.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/StarBasedReferencePoints.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints;
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,7 +30,7 @@ import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
-import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
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;
@@ -42,34 +42,15 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
* Star-based strategy to pick reference points.
*
* @author Erich Schubert
- *
- * @param <V> Object type
*/
-public class StarBasedReferencePoints<V extends NumberVector<?>> implements ReferencePointsHeuristic<V> {
- /**
- * Parameter to specify the grid resolution.
- * <p>
- * Key: {@code -star.nocenter}
- * </p>
- */
- public static final OptionID NOCENTER_ID = new OptionID("star.nocenter", "Do not use the center as extra reference point.");
-
+public class StarBasedReferencePoints implements ReferencePointsHeuristic {
/**
- * Parameter to specify the extra scaling of the space, to allow
- * out-of-data-space reference points.
- * <p>
- * Key: {@code -star.scale}
- * </p>
- */
- public static final OptionID SCALE_ID = new OptionID("star.scale", "Scale the reference points by the given factor. This can be used to obtain reference points outside the used data space.");
-
- /**
- * Holds the value of {@link #NOCENTER_ID}.
+ * Exclude the center vector.
*/
protected boolean nocenter;
/**
- * Holds the value of {@link #SCALE_ID}.
+ * Scaling factor.
*/
protected double scale;
@@ -86,10 +67,7 @@ public class StarBasedReferencePoints<V extends NumberVector<?>> implements Refe
}
@Override
- public <T extends V> Collection<V> getReferencePoints(Relation<T> db) {
- Relation<V> database = DatabaseUtil.relationUglyVectorCast(db);
- NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(database);
-
+ public Collection<? extends NumberVector> getReferencePoints(Relation<? extends NumberVector> db) {
int dim = RelationUtil.dimensionality(db);
// Compute minimum, maximum and centroid
@@ -101,10 +79,10 @@ public class StarBasedReferencePoints<V extends NumberVector<?>> implements Refe
min[d] = Double.MAX_VALUE;
max[d] = -Double.MAX_VALUE;
}
- for(DBIDIter iditer = database.iterDBIDs(); iditer.valid(); iditer.advance()) {
- V obj = database.get(iditer);
+ for(DBIDIter iditer = db.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ NumberVector obj = db.get(iditer);
for(int d = 0; d < dim; d++) {
- double val = obj.doubleValue(d + 1);
+ double val = obj.doubleValue(d);
centroid[d] += val;
min[d] = Math.min(min[d], val);
max[d] = Math.max(max[d], val);
@@ -112,27 +90,23 @@ public class StarBasedReferencePoints<V extends NumberVector<?>> implements Refe
}
// finish centroid, scale min, max
for(int d = 0; d < dim; d++) {
- centroid[d] = centroid[d] / database.size();
+ centroid[d] = centroid[d] / db.size();
min[d] = (min[d] - centroid[d]) * scale + centroid[d];
max[d] = (max[d] - centroid[d]) * scale + centroid[d];
}
- ArrayList<V> result = new ArrayList<>(2 * dim + 1);
+ ArrayList<Vector> result = new ArrayList<>(2 * dim + 1);
if(!nocenter) {
- result.add(factory.newNumberVector(centroid));
+ result.add(new Vector(centroid));
}
// Plus axis end points through centroid
- double[] vec = new double[dim];
for(int i = 0; i < dim; i++) {
- for(int d = 0; d < dim; d++) {
- if(d != i) {
- vec[d] = centroid[d];
- }
- }
+ double[] vec = centroid.clone();
vec[i] = min[i];
- result.add(factory.newNumberVector(vec));
+ result.add(new Vector(vec));
+ vec = centroid.clone();
vec[i] = max[i];
- result.add(factory.newNumberVector(vec));
+ result.add(new Vector(vec));
}
return result;
@@ -145,7 +119,24 @@ public class StarBasedReferencePoints<V extends NumberVector<?>> implements Refe
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Parameter to specify the grid resolution.
+ * <p>
+ * Key: {@code -star.nocenter}
+ * </p>
+ */
+ public static final OptionID NOCENTER_ID = new OptionID("star.nocenter", "Do not use the center as extra reference point.");
+
+ /**
+ * Parameter to specify the extra scaling of the space, to allow
+ * out-of-data-space reference points.
+ * <p>
+ * Key: {@code -star.scale}
+ * </p>
+ */
+ public static final OptionID SCALE_ID = new OptionID("star.scale", "Scale the reference points by the given factor. This can be used to obtain reference points outside the used data space.");
+
/**
* Holds the value of {@link #NOCENTER_ID}.
*/
@@ -164,16 +155,16 @@ public class StarBasedReferencePoints<V extends NumberVector<?>> implements Refe
nocenter = nocenterF.getValue();
}
- DoubleParameter scaleP = new DoubleParameter(SCALE_ID, 1.0);
- scaleP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ DoubleParameter scaleP = new DoubleParameter(SCALE_ID, 1.0) //
+ .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
if(config.grab(scaleP)) {
scale = scaleP.getValue();
}
}
@Override
- protected StarBasedReferencePoints<V> makeInstance() {
- return new StarBasedReferencePoints<>(nocenter, scale);
+ protected StarBasedReferencePoints makeInstance() {
+ return new StarBasedReferencePoints(nocenter, scale);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/package-info.java
index 6268d5d2..1fa77206 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/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/utilities/scaling/ClipScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/ClipScaling.java
index 068e1230..3fa42408 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/ClipScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/ClipScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling;
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/utilities/scaling/GammaScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/GammaScaling.java
index daff7275..998b3c52 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/GammaScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/GammaScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling;
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/utilities/scaling/IdentityScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/IdentityScaling.java
index 7f24431d..6820f3c1 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/IdentityScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/IdentityScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling;
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/utilities/scaling/LinearScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/LinearScaling.java
index ef28c434..01721c34 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/LinearScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/LinearScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling;
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/utilities/scaling/MinusLogScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/MinusLogScaling.java
index 8e497dd9..0a18ca00 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/MinusLogScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/MinusLogScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling;
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/utilities/scaling/ScalingFunction.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/ScalingFunction.java
index c738aa9a..9aedddc9 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/ScalingFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/ScalingFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling;
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,6 @@ package de.lmu.ifi.dbs.elki.utilities.scaling;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
-
/**
* Interface for scaling functions used e.g. by outlier evaluation such as
* Histograms and visualization.
@@ -39,7 +37,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
*
* @author Erich Schubert
*/
-public interface ScalingFunction extends Parameterizable {
+public interface ScalingFunction {
/**
* Transform a given value using the scaling function.
*
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/StaticScalingFunction.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/StaticScalingFunction.java
index 27d12db4..633fad16 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/StaticScalingFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/StaticScalingFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling;
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/utilities/scaling/outlier/COPOutlierScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/COPOutlierScaling.java
index 202d1044..9f00d9ab 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/COPOutlierScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/COPOutlierScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.math.statistics.distribution.Distribution;
import de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.meta.BestFitEstimator;
import de.lmu.ifi.dbs.elki.result.outlier.InvertedOutlierScoreMeta;
@@ -117,11 +117,11 @@ public class COPOutlierScaling implements OutlierScalingFunction {
public void prepare(OutlierResult or) {
double[] s;
{
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
s = new double[scores.size()];
int i = 0;
for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance(), i++) {
- s[i] = scores.get(id);
+ s[i] = scores.doubleValue(id);
}
}
Arrays.sort(s);
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/HeDESNormalizationOutlierScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/HeDESNormalizationOutlierScaling.java
index 5e55c2e0..4d7d4d9f 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/HeDESNormalizationOutlierScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/HeDESNormalizationOutlierScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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.utilities.scaling.outlier;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
@@ -63,9 +63,9 @@ public class HeDESNormalizationOutlierScaling implements OutlierScalingFunction
MeanVariance mv = new MeanVariance();
DoubleMinMax minmax = new DoubleMinMax();
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double val = scores.get(id);
+ double val = scores.doubleValue(id);
if (!Double.isNaN(val) && !Double.isInfinite(val)) {
mv.put(val);
minmax.put(val);
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogGammaScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogGammaScaling.java
index effbcfe0..0ba85d79 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogGammaScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogGammaScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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.utilities.scaling.outlier;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
import de.lmu.ifi.dbs.elki.math.statistics.distribution.GammaDistribution;
@@ -68,9 +68,9 @@ public class MinusLogGammaScaling extends OutlierGammaScaling {
meta = or.getOutlierMeta();
// Determine Minimum and Maximum.
DoubleMinMax mm = new DoubleMinMax();
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for(DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double score = scores.get(id);
+ double score = scores.doubleValue(id);
if(!Double.isNaN(score) && !Double.isInfinite(score)) {
mm.put(score);
}
@@ -80,7 +80,7 @@ public class MinusLogGammaScaling extends OutlierGammaScaling {
// with the prescaling, do Gamma Scaling.
MeanVariance mv = new MeanVariance();
for(DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double score = scores.get(id);
+ double score = scores.doubleValue(id);
score = preScale(score);
if(!Double.isNaN(score) && !Double.isInfinite(score)) {
mv.put(score);
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogStandardDeviationScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogStandardDeviationScaling.java
index d30fbac7..1b5c7023 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogStandardDeviationScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogStandardDeviationScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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.utilities.scaling.outlier;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.Mean;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
@@ -69,9 +69,9 @@ public class MinusLogStandardDeviationScaling extends StandardDeviationScaling {
public void prepare(OutlierResult or) {
if(fixedmean == null) {
MeanVariance mv = new MeanVariance();
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for(DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double val = -Math.log(scores.get(id));
+ double val = -Math.log(scores.doubleValue(id));
if(!Double.isNaN(val) && !Double.isInfinite(val)) {
mv.put(val);
}
@@ -82,9 +82,9 @@ public class MinusLogStandardDeviationScaling extends StandardDeviationScaling {
else {
mean = fixedmean;
Mean sqsum = new Mean();
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for(DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double val = -Math.log(scores.get(id));
+ double val = -Math.log(scores.doubleValue(id));
if(!Double.isNaN(val) && !Double.isInfinite(val)) {
sqsum.put((val - mean) * (val - mean));
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MixtureModelOutlierScalingFunction.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MixtureModelOutlierScalingFunction.java
index 9c5ad920..5c1d8f5f 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MixtureModelOutlierScalingFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MixtureModelOutlierScalingFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
@@ -122,9 +122,9 @@ public class MixtureModelOutlierScalingFunction implements OutlierScalingFunctio
public void prepare(OutlierResult or) {
// Initial parameters - are these defaults sounds?
MeanVariance mv = new MeanVariance();
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double val = scores.get(id);
+ double val = scores.doubleValue(id);
if (!Double.isNaN(val) && !Double.isInfinite(val)) {
mv.put(val);
}
@@ -151,7 +151,7 @@ public class MixtureModelOutlierScalingFunction implements OutlierScalingFunctio
// Weighted deviation from previous mean
double sqsum = 0.0;
for (int i = 0; i < ids.size(); i++) {
- double val = or.getScores().get(ids.get(i));
+ double val = or.getScores().doubleValue(ids.get(i));
// E-Step
double ti = calcPosterior(val, curAlpha, curMu, curSigma, curLambda);
// M-Step
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MultiplicativeInverseScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MultiplicativeInverseScaling.java
index d5cd3f40..718ca3be 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MultiplicativeInverseScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MultiplicativeInverseScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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.utilities.scaling.outlier;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
@@ -41,11 +41,13 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
*
* @author Erich Schubert
*/
-@Reference(authors="H.-P. Kriegel, P. Kröger, E. Schubert, A. Zimek", title="Interpreting and Unifying Outlier Scores", booktitle="Proc. 11th SIAM International Conference on Data Mining (SDM), Mesa, AZ, 2011", url="http://siam.omnibooksonline.com/2011datamining/data/papers/018.pdf")
+@Reference(authors="H.-P. Kriegel, P. Kröger, E. Schubert, A. Zimek", //
+title="Interpreting and Unifying Outlier Scores", //
+booktitle="Proc. 11th SIAM International Conference on Data Mining (SDM), Mesa, AZ, 2011", //
+url="http://siam.omnibooksonline.com/2011datamining/data/papers/018.pdf")
public class MultiplicativeInverseScaling implements OutlierScalingFunction {
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public MultiplicativeInverseScaling() {
super();
@@ -70,9 +72,9 @@ public class MultiplicativeInverseScaling implements OutlierScalingFunction {
@Override
public void prepare(OutlierResult or) {
double max = Double.MIN_VALUE;
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for(DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double val = scores.get(id);
+ double val = scores.doubleValue(id);
double inv = Math.abs(1.0 / val);
if(!Double.isInfinite(inv) && !Double.isNaN(inv)) {
max = Math.max(max, inv);
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierGammaScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierGammaScaling.java
index 7da0c933..b8c4e23a 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierGammaScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierGammaScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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.utilities.scaling.outlier;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
import de.lmu.ifi.dbs.elki.math.statistics.distribution.GammaDistribution;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
@@ -102,9 +102,9 @@ public class OutlierGammaScaling implements OutlierScalingFunction {
public void prepare(OutlierResult or) {
meta = or.getOutlierMeta();
MeanVariance mv = new MeanVariance();
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double score = scores.get(id);
+ double score = scores.doubleValue(id);
score = preScale(score);
if (!Double.isNaN(score) && !Double.isInfinite(score)) {
mv.put(score);
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierLinearScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierLinearScaling.java
index dfae1068..710ddc91 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierLinearScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierLinearScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
import java.util.ArrayList;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
@@ -149,9 +149,9 @@ public class OutlierLinearScaling implements OutlierScalingFunction {
MeanVariance mv = new MeanVariance();
DoubleMinMax mm = (max == null) ? new DoubleMinMax() : null;
boolean skippedzeros = false;
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double val = scores.get(id);
+ double val = scores.doubleValue(id);
if (nozeros && val == 0.0) {
skippedzeros = true;
continue;
@@ -175,9 +175,9 @@ public class OutlierLinearScaling implements OutlierScalingFunction {
if (min == null || max == null) {
boolean skippedzeros = false;
DoubleMinMax mm = new DoubleMinMax();
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double val = scores.get(id);
+ double val = scores.doubleValue(id);
if (nozeros && val == 0.0) {
skippedzeros = true;
continue;
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierMinusLogScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierMinusLogScaling.java
index f0e04913..932ee691 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierMinusLogScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierMinusLogScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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.utilities.scaling.outlier;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
@@ -34,7 +34,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
* Scaling function to invert values by computing -1 * Math.log(x)
*
* Useful for example for scaling
- * {@link de.lmu.ifi.dbs.elki.algorithm.outlier.ABOD}, but see
+ * {@link de.lmu.ifi.dbs.elki.algorithm.outlier.anglebased.ABOD}, but see
* {@link MinusLogStandardDeviationScaling} and {@link MinusLogGammaScaling} for
* more advanced scalings for this algorithm.
*
@@ -53,8 +53,7 @@ public class OutlierMinusLogScaling implements OutlierScalingFunction {
double mlogmax;
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public OutlierMinusLogScaling() {
super();
@@ -79,9 +78,9 @@ public class OutlierMinusLogScaling implements OutlierScalingFunction {
@Override
public void prepare(OutlierResult or) {
DoubleMinMax mm = new DoubleMinMax();
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double val = scores.get(id);
+ double val = scores.doubleValue(id);
if (!Double.isNaN(val) && !Double.isInfinite(val)) {
mm.put(val);
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierScalingFunction.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierScalingFunction.java
index 9de05e78..ac2533c1 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierScalingFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierScalingFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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/utilities/scaling/outlier/OutlierSqrtScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierSqrtScaling.java
index 302602d4..2f318ea4 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierSqrtScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierSqrtScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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.utilities.scaling.outlier;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
@@ -83,9 +83,9 @@ public class OutlierSqrtScaling implements OutlierScalingFunction {
public void prepare(OutlierResult or) {
if (pmin == null || pmax == null) {
DoubleMinMax mm = new DoubleMinMax();
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double val = scores.get(id);
+ double val = scores.doubleValue(id);
if (!Double.isInfinite(val)) {
mm.put(val);
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/RankingPseudoOutlierScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/RankingPseudoOutlierScaling.java
index 505f2002..4f8fec79 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/RankingPseudoOutlierScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/RankingPseudoOutlierScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
import java.util.Arrays;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.result.outlier.InvertedOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;
@@ -54,14 +54,14 @@ public class RankingPseudoOutlierScaling implements OutlierScalingFunction {
@Override
public void prepare(OutlierResult or) {
// collect all outlier scores
- Relation<Double> oscores = or.getScores();
+ DoubleRelation oscores = or.getScores();
scores = new double[oscores.size()];
int pos = 0;
if(or.getOutlierMeta() instanceof InvertedOutlierScoreMeta) {
inverted = true;
}
for(DBIDIter iditer = oscores.iterDBIDs(); iditer.valid(); iditer.advance()) {
- scores[pos] = oscores.get(iditer);
+ scores[pos] = oscores.doubleValue(iditer);
pos++;
}
if(pos != oscores.size()) {
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SigmoidOutlierScalingFunction.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SigmoidOutlierScalingFunction.java
index 34911169..0887933f 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SigmoidOutlierScalingFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SigmoidOutlierScalingFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
@@ -63,9 +63,9 @@ public class SigmoidOutlierScalingFunction implements OutlierScalingFunction {
public void prepare(OutlierResult or) {
// Initial parameters - are these defaults sounds?
MeanVariance mv = new MeanVariance();
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double val = scores.get(id);
+ double val = scores.doubleValue(id);
mv.put(val);
}
double a = 1.0;
@@ -81,7 +81,7 @@ public class SigmoidOutlierScalingFunction implements OutlierScalingFunction {
// E-Step
it.seek(0);
for (int i = 0; i < ids.size(); i++, it.advance()) {
- double val = or.getScores().get(it);
+ double val = or.getScores().doubleValue(it);
double targ = a * val + b;
if (targ > 0) {
if (!t.get(i)) {
@@ -196,7 +196,7 @@ public class SigmoidOutlierScalingFunction implements OutlierScalingFunction {
* @param scores Scores
* @return new values for A and B.
*/
- private final double[] MStepLevenbergMarquardt(double a, double b, ArrayDBIDs ids, BitSet t, Relation<Double> scores) {
+ private final double[] MStepLevenbergMarquardt(double a, double b, ArrayDBIDs ids, BitSet t, DoubleRelation scores) {
final int prior1 = t.cardinality();
final int prior0 = ids.size() - prior1;
DBIDArrayIter iter = ids.iter();
@@ -216,7 +216,7 @@ public class SigmoidOutlierScalingFunction implements OutlierScalingFunction {
double fval = 0.0;
iter.seek(0);
for (int i = 0; i < ids.size(); i++, iter.advance()) {
- final double val = scores.get(iter);
+ final double val = scores.doubleValue(iter);
final double fApB = val * a + b;
final double ti = t.get(i) ? hiTarget : loTarget;
if (fApB >= 0) {
@@ -235,7 +235,7 @@ public class SigmoidOutlierScalingFunction implements OutlierScalingFunction {
double g2 = 0.0;
iter.seek(0);
for (int i = 0; i < ids.size(); i++, iter.advance()) {
- final double val = scores.get(iter);
+ final double val = scores.doubleValue(iter);
final double fApB = val * a + b;
final double p;
final double q;
@@ -270,7 +270,7 @@ public class SigmoidOutlierScalingFunction implements OutlierScalingFunction {
double newf = 0.0;
iter.seek(0);
for (int i = 0; i < ids.size(); i++, iter.advance()) {
- final double val = scores.get(iter);
+ final double val = scores.doubleValue(iter);
final double fApB = val * newA + newB;
final double ti = t.get(i) ? hiTarget : loTarget;
if (fApB >= 0) {
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SqrtStandardDeviationScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SqrtStandardDeviationScaling.java
index 2110570e..ad631bb7 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SqrtStandardDeviationScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SqrtStandardDeviationScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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.utilities.scaling.outlier;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.Mean;
import de.lmu.ifi.dbs.elki.math.MeanVarianceMinMax;
@@ -99,9 +99,9 @@ public class SqrtStandardDeviationScaling implements OutlierScalingFunction {
public void prepare(OutlierResult or) {
if (pmean == null) {
MeanVarianceMinMax mv = new MeanVarianceMinMax();
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double val = scores.get(id);
+ double val = scores.doubleValue(id);
val = (val <= min) ? 0 : Math.sqrt(val - min);
mv.put(val);
}
@@ -112,10 +112,10 @@ public class SqrtStandardDeviationScaling implements OutlierScalingFunction {
mean = pmean;
double sqsum = 0;
int cnt = 0;
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
double mm = Double.POSITIVE_INFINITY;
for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double val = scores.get(id);
+ double val = scores.doubleValue(id);
mm = Math.min(mm, val);
val = (val <= min) ? 0 : Math.sqrt(val - min);
sqsum += (val - mean) * (val - mean);
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/StandardDeviationScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/StandardDeviationScaling.java
index b0040571..c9486b9d 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/StandardDeviationScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/StandardDeviationScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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.utilities.scaling.outlier;
*/
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.Mean;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
@@ -109,9 +109,9 @@ public class StandardDeviationScaling implements OutlierScalingFunction {
public void prepare(OutlierResult or) {
if (fixedmean == null) {
MeanVariance mv = new MeanVariance();
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double val = scores.get(id);
+ double val = scores.doubleValue(id);
if (!Double.isNaN(val) && !Double.isInfinite(val)) {
mv.put(val);
}
@@ -124,9 +124,9 @@ public class StandardDeviationScaling implements OutlierScalingFunction {
} else {
mean = fixedmean;
Mean sqsum = new Mean();
- Relation<Double> scores = or.getScores();
+ DoubleRelation scores = or.getScores();
for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) {
- double val = scores.get(id);
+ double val = scores.doubleValue(id);
if (!Double.isNaN(val) && !Double.isInfinite(val)) {
sqsum.put((val - mean) * (val - mean));
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/TopKOutlierScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/TopKOutlierScaling.java
index 71a495a6..f00a18b3 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/TopKOutlierScaling.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/TopKOutlierScaling.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier;
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
@@ -102,7 +102,7 @@ public class TopKOutlierScaling implements OutlierScalingFunction {
}
DBIDIter order = or.getOrdering().iter(or.getOrdering().getDBIDs()).iter();
for(int i = 0; i < k && order.valid(); i++, order.advance()) {
- cutoff = or.getScores().get(order);
+ cutoff = or.getScores().doubleValue(order);
}
max = or.getOutlierMeta().getActualMaximum();
ground = or.getOutlierMeta().getTheoreticalBaseline();
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/package-info.java
index a34aac08..80c9c2d5 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/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/utilities/scaling/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/package-info.java
index 633aa65a..e88a2df5 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/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/utilities/xml/DOMCloner.java b/src/de/lmu/ifi/dbs/elki/utilities/xml/DOMCloner.java
index 44116dfe..e8b5145e 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/xml/DOMCloner.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/xml/DOMCloner.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.xml;
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/utilities/xml/HTMLUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/xml/HTMLUtil.java
index a68631d5..7a90361f 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/xml/HTMLUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/xml/HTMLUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.xml;
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/utilities/xml/XMLNodeIterator.java b/src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeIterator.java
index c1decfe1..8586bc66 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeIterator.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeIterator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.xml;
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/utilities/xml/XMLNodeListIterator.java b/src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeListIterator.java
index 1fb39663..eea27828 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeListIterator.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeListIterator.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.xml;
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/utilities/xml/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/xml/package-info.java
index 8f6d8a04..651c5aac 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/xml/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/xml/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/visualization/ExportVisualizations.java b/src/de/lmu/ifi/dbs/elki/visualization/ExportVisualizations.java
index 9c19d15f..b7a361e0 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/ExportVisualizations.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/ExportVisualizations.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization;
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/visualization/VisualizationTask.java b/src/de/lmu/ifi/dbs/elki/visualization/VisualizationTask.java
index cb791905..83d743e1 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/VisualizationTask.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/VisualizationTask.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization;
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/visualization/VisualizerContext.java b/src/de/lmu/ifi/dbs/elki/visualization/VisualizerContext.java
index d6d65f79..5c2684f4 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/VisualizerContext.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/VisualizerContext.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization;
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
@@ -129,7 +129,7 @@ public class VisualizerContext implements DataStoreListener, Result {
// FIXME: this is a really ugly workaround. :-(
if (TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(rel.getDataTypeInformation())) {
@SuppressWarnings("unchecked")
- Relation<? extends NumberVector<?>> vrel = (Relation<? extends NumberVector<?>>) rel;
+ Relation<? extends NumberVector> vrel = (Relation<? extends NumberVector>) rel;
ResultUtil.getScalesResult(vrel);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/VisualizerParameterizer.java b/src/de/lmu/ifi/dbs/elki/visualization/VisualizerParameterizer.java
index 69976532..ab1db370 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/VisualizerParameterizer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/VisualizerParameterizer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization;
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
@@ -35,6 +35,7 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.datasource.FileBasedDatabaseConnection;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
@@ -42,20 +43,17 @@ import de.lmu.ifi.dbs.elki.result.SamplingResult;
import de.lmu.ifi.dbs.elki.result.SettingsResult;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
import de.lmu.ifi.dbs.elki.utilities.InspectionUtil;
-import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
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.Parameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.MergedParameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackedParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.PatternParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.StringParameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
import de.lmu.ifi.dbs.elki.visualization.projector.ProjectorFactory;
import de.lmu.ifi.dbs.elki.visualization.style.PropertiesBasedStyleLibrary;
import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary;
@@ -72,7 +70,7 @@ import de.lmu.ifi.dbs.elki.workflow.AlgorithmStep;
* @apiviz.has VisualizerContext oneway - - «create»
* @apiviz.uses VisFactory oneway - n «configure»
*/
-public class VisualizerParameterizer implements Parameterizable {
+public class VisualizerParameterizer {
/**
* Get a logger for this class.
*/
@@ -204,7 +202,7 @@ public class VisualizerParameterizer implements Parameterizable {
* @return generated title
*/
public static String getTitle(Database db, Result result) {
- List<Pair<Object, Parameter<?>>> settings = new ArrayList<>();
+ List<TrackedParameter> settings = new ArrayList<>();
for(SettingsResult sr : ResultUtil.getSettingsResults(result)) {
settings.addAll(sr.getSettings());
}
@@ -212,15 +210,15 @@ public class VisualizerParameterizer implements Parameterizable {
String distance = null;
String dataset = null;
- for(Pair<Object, Parameter<?>> setting : settings) {
- if(setting.second.equals(AlgorithmStep.Parameterizer.ALGORITHM_ID)) {
- algorithm = setting.second.getValue().toString();
+ for(TrackedParameter setting : settings) {
+ if(setting.getParameter().equals(AlgorithmStep.Parameterizer.ALGORITHM_ID)) {
+ algorithm = setting.getParameter().getValue().toString();
}
- if(setting.second.equals(DistanceBasedAlgorithm.DISTANCE_FUNCTION_ID)) {
- distance = setting.second.getValue().toString();
+ if(setting.getParameter().equals(DistanceBasedAlgorithm.DISTANCE_FUNCTION_ID)) {
+ distance = setting.getParameter().getValue().toString();
}
- if(setting.second.equals(FileBasedDatabaseConnection.Parameterizer.INPUT_ID)) {
- dataset = setting.second.getValue().toString();
+ if(setting.getParameter().equals(FileBasedDatabaseConnection.Parameterizer.INPUT_ID)) {
+ dataset = setting.getParameter().getValue().toString();
}
}
StringBuilder buf = new StringBuilder();
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/AddCSSClass.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/AddCSSClass.java
index 1bc64b20..48c6648e 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/AddCSSClass.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/AddCSSClass.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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/visualization/batikutil/AttributeModifier.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/AttributeModifier.java
index d6a48013..6e1030d2 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/AttributeModifier.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/AttributeModifier.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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/visualization/batikutil/BatikUtil.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/BatikUtil.java
index 7774cde6..b0c7d14c 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/BatikUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/BatikUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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/visualization/batikutil/CSSHoverClass.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/CSSHoverClass.java
index 021878b2..fbe79d44 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/CSSHoverClass.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/CSSHoverClass.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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/visualization/batikutil/CloneInlineImages.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/CloneInlineImages.java
index 33cf6d8a..9a7942a7 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/CloneInlineImages.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/CloneInlineImages.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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/visualization/batikutil/DragableArea.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/DragableArea.java
index 56a7b223..482662a6 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/DragableArea.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/DragableArea.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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/visualization/batikutil/JSVGSynchronizedCanvas.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/JSVGSynchronizedCanvas.java
index 2e08a2dc..08f8f426 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/JSVGSynchronizedCanvas.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/JSVGSynchronizedCanvas.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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.visualization.batikutil;
import org.apache.batik.bridge.UpdateManager;
import org.apache.batik.swing.JSVGCanvas;
import org.w3c.dom.Document;
-import org.w3c.dom.svg.SVGDocument;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.visualization.svg.SVGPlot;
@@ -66,16 +65,12 @@ public class JSVGSynchronizedCanvas extends JSVGCanvas {
}
/**
- * Use {@link #setPlot} instead if you need synchronization!
+ * Get the currently displayed SVG plot.
*
- * @deprecated Document cannot be synchronized - use {@link #setPlot} and a
- * {@link SVGPlot} object!
+ * @return current SVG plot. May be {@code null}!
*/
- @Override
- @Deprecated
- public synchronized void setDocument(Document doc) {
- // Note: this will call this.setSVGDocument!
- super.setDocument(doc);
+ public SVGPlot getPlot() {
+ return this.plot;
}
/**
@@ -86,9 +81,9 @@ public class JSVGSynchronizedCanvas extends JSVGCanvas {
*/
@Override
@Deprecated
- public synchronized void setSVGDocument(SVGDocument doc) {
- setPlot(null);
- super.setSVGDocument(doc);
+ public synchronized void setDocument(Document doc) {
+ // Note: this will call this.setSVGDocument!
+ super.setDocument(doc);
}
/**
@@ -98,18 +93,19 @@ public class JSVGSynchronizedCanvas extends JSVGCanvas {
*/
public void setPlot(final SVGPlot newplot) {
final SVGPlot oldplot = this.plot;
-
this.plot = newplot;
- if(newplot != null) {
- newplot.synchronizeWith(this.synchronizer);
- super.setSVGDocument(newplot.getDocument());
- super.setDisableInteractions(newplot.getDisableInteractions());
- }
- else {
+ if(newplot == null) {
super.setSVGDocument(null);
+ if(oldplot != null) {
+ scheduleDetach(oldplot);
+ }
+ return;
}
+ newplot.synchronizeWith(this.synchronizer);
+ super.setSVGDocument(newplot.getDocument());
+ super.setDisableInteractions(newplot.getDisableInteractions());
// We only know we're detached when the synchronizer has run again.
- if(oldplot != null) {
+ if(oldplot != null && oldplot != newplot) {
scheduleDetach(oldplot);
}
}
@@ -121,44 +117,35 @@ public class JSVGSynchronizedCanvas extends JSVGCanvas {
*/
private void scheduleDetach(final SVGPlot oldplot) {
UpdateManager um = this.getUpdateManager();
- if(um != null) {
- synchronized(um) {
- if(um.isRunning()) {
- //LoggingUtil.warning("Scheduling detach: " + this + " " + oldplot);
- um.getUpdateRunnableQueue().preemptLater(new Runnable() {
- @Override
- public void run() {
- detachPlot(oldplot);
- }
- });
- return;
- }
+ if(um == null) {
+ return;
+ }
+ synchronized(um) {
+ if(um.isRunning()) {
+ // LoggingUtil.warning("Scheduling detach: " + this + " " + oldplot);
+ um.getUpdateRunnableQueue().preemptLater(new Runnable() {
+ @Override
+ public void run() {
+ detachPlot(oldplot);
+ }
+ });
+ return;
}
}
detachPlot(oldplot);
}
/**
- * Get the currently displayed SVG plot.
- *
- * @return current SVG plot. May be {@code null}!
- */
- public SVGPlot getPlot() {
- return this.plot;
- }
-
- /**
* Execute the detaching event.
*
* @param oldplot Plot to detach from.
*/
protected void detachPlot(SVGPlot oldplot) {
- //LoggingUtil.warning("Detaching: " + this + " " + oldplot);
- if(oldplot != plot) {
- oldplot.unsynchronizeWith(JSVGSynchronizedCanvas.this.synchronizer);
- }
- else {
- LoggingUtil.warning("Detaching from a plot I'm already attached to again?!?");
+ // LoggingUtil.warning("Detaching: " + this + " " + oldplot);
+ if(oldplot == plot) {
+ LoggingUtil.warning("Detaching from a plot I'm already attached to again?!?", new Throwable());
+ return;
}
+ oldplot.unsynchronizeWith(JSVGSynchronizedCanvas.this.synchronizer);
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/JSVGUpdateSynchronizer.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/JSVGUpdateSynchronizer.java
index ab064e43..2201e1f8 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/JSVGUpdateSynchronizer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/JSVGUpdateSynchronizer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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.visualization.batikutil;
*/
import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
import org.apache.batik.bridge.UpdateManager;
import org.apache.batik.bridge.UpdateManagerAdapter;
@@ -51,7 +51,7 @@ class JSVGUpdateSynchronizer implements UpdateSynchronizer {
/**
* The UpdateRunner we are put into
*/
- private List<WeakReference<UpdateRunner>> updaterunner = new ArrayList<>();
+ private Set<WeakReference<UpdateRunner>> updaterunner = new CopyOnWriteArraySet<>();
/**
* Adapter to track component changes
@@ -87,7 +87,7 @@ class JSVGUpdateSynchronizer implements UpdateSynchronizer {
*/
protected void makeRunnerIfNeeded() {
// Nothing to do if not connected to a plot
- if(updaterunner.size() == 0) {
+ if(updaterunner.isEmpty()) {
return;
}
// we don't need to make a SVG runner when there are no pending updates.
@@ -130,6 +130,11 @@ class JSVGUpdateSynchronizer implements UpdateSynchronizer {
@Override
public void addUpdateRunner(UpdateRunner updateRunner) {
+ for(WeakReference<UpdateRunner> wur : updaterunner) {
+ if(wur.get() == null) {
+ updaterunner.remove(wur);
+ }
+ }
updaterunner.add(new WeakReference<>(updateRunner));
}
@@ -173,9 +178,10 @@ class JSVGUpdateSynchronizer implements UpdateSynchronizer {
// Wake up all runners
for(WeakReference<UpdateRunner> wur : updaterunner) {
UpdateRunner ur = wur.get();
- if(ur != null && !ur.isEmpty()) {
- ur.runQueue();
+ if(ur == null || ur.isEmpty()) {
+ continue;
}
+ ur.runQueue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/LazyCanvasResizer.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/LazyCanvasResizer.java
index a046b4d6..b8b9bec0 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/LazyCanvasResizer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/LazyCanvasResizer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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/visualization/batikutil/NodeAppendChild.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeAppendChild.java
index 3b640c8d..b94dd033 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeAppendChild.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeAppendChild.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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/visualization/batikutil/NodeReplaceChild.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeReplaceChild.java
index 524bf2c7..d6cef4d9 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeReplaceChild.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeReplaceChild.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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/visualization/batikutil/NodeReplacer.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeReplacer.java
index 72a42b2f..f529c1c0 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeReplacer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeReplacer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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/visualization/batikutil/RemoveCSSClass.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/RemoveCSSClass.java
index 3f80117f..d972cb08 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/RemoveCSSClass.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/RemoveCSSClass.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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/visualization/batikutil/ThumbnailRegistryEntry.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailRegistryEntry.java
index 9bab635c..46481206 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailRegistryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailRegistryEntry.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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/visualization/batikutil/ThumbnailTranscoder.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailTranscoder.java
index a07b42f2..7470586a 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailTranscoder.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailTranscoder.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.batikutil;
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/visualization/colors/ColorLibrary.java b/src/de/lmu/ifi/dbs/elki/visualization/colors/ColorLibrary.java
index 10041b1b..50a0bfd9 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/colors/ColorLibrary.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/colors/ColorLibrary.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.colors;
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/visualization/colors/ListBasedColorLibrary.java b/src/de/lmu/ifi/dbs/elki/visualization/colors/ListBasedColorLibrary.java
index e3fadfd0..139531b2 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/colors/ListBasedColorLibrary.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/colors/ListBasedColorLibrary.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.colors;
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/visualization/css/CSSClass.java b/src/de/lmu/ifi/dbs/elki/visualization/css/CSSClass.java
index 3f9bc095..040529e7 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/css/CSSClass.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/css/CSSClass.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.css;
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/visualization/css/CSSClassManager.java b/src/de/lmu/ifi/dbs/elki/visualization/css/CSSClassManager.java
index 4d34d9cd..f363990d 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/css/CSSClassManager.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/css/CSSClassManager.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.css;
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/visualization/gui/ResultVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/ResultVisualizer.java
index 92171f47..7cfa5f14 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/gui/ResultVisualizer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/ResultVisualizer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.gui;
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
@@ -131,7 +131,6 @@ public class ResultVisualizer implements ResultHandler {
ResultWindow window = new ResultWindow(title, top, context, single);
window.setVisible(true);
window.setExtendedState(window.getExtendedState() | JFrame.MAXIMIZED_BOTH);
- window.showOverview();
} catch (Throwable e) {
LOG.exception("Error in starting visualizer window.", e);
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/gui/ResultWindow.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/ResultWindow.java
index 0cfa5166..191a8658 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/gui/ResultWindow.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/ResultWindow.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.gui;
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
@@ -176,7 +176,7 @@ public class ResultWindow extends JFrame implements ResultListener {
JMenuBar menubar = new JMenuBar();
JMenu filemenu = new JMenu("File");
filemenu.setMnemonic(KeyEvent.VK_F);
-
+
// setup buttons
if(!single) {
overviewItem = new JMenuItem("Overview");
@@ -201,7 +201,7 @@ public class ResultWindow extends JFrame implements ResultListener {
}
});
filemenu.add(exportItem);
-
+
editItem = new JMenuItem("Table View/Edit");
editItem.setMnemonic(KeyEvent.VK_T);
editItem.addActionListener(new ActionListener() {
@@ -244,6 +244,11 @@ public class ResultWindow extends JFrame implements ResultListener {
if(e instanceof DetailViewSelectedEvent) {
showSubplot((DetailViewSelectedEvent) e);
}
+ if(OverviewPlot.OVERVIEW_REFRESHED.equals(e.getActionCommand())) {
+ if (currentSubplot == null) {
+ svgCanvas.setPlot(overview.getPlot());
+ }
+ }
}
});
@@ -257,34 +262,27 @@ public class ResultWindow extends JFrame implements ResultListener {
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
// resize listener
- LazyCanvasResizer listener = new LazyCanvasResizer(this) {
+ LazyCanvasResizer listener = new LazyCanvasResizer(this, 0.1) {
@Override
public void executeResize(double newratio) {
- setRatio(newratio);
+ ResultWindow.this.handleResize(newratio);
}
};
- setRatio(listener.getActiveRatio());
+ this.overview.initialize(listener.getCurrentRatio());
+
this.addComponentListener(listener);
context.addResultListener(this);
- update();
- }
-
- /**
- * Change the plot ratio. Will only be applied to new plots for now.
- *
- * @param newratio New ratio
- */
- protected void setRatio(double newratio) {
- ResultWindow.this.overview.setRatio(newratio);
+ // update();
+ updateVisualizerMenus();
}
@Override
public void dispose() {
context.removeResultListener(this);
svgCanvas.setPlot(null);
- overview.dispose();
+ overview.destroy();
if(currentSubplot != null) {
currentSubplot.dispose();
currentSubplot = null;
@@ -308,7 +306,7 @@ public class ResultWindow extends JFrame implements ResultListener {
currentSubplot.destroy();
}
currentSubplot = null;
- showPlot(overview);
+ showPlot(overview.getPlot());
}
/**
@@ -333,8 +331,8 @@ public class ResultWindow extends JFrame implements ResultListener {
((DetailView) svgCanvas.getPlot()).destroy();
}
svgCanvas.setPlot(plot);
- if (overviewItem != null) {
- overviewItem.setEnabled(plot != overview);
+ if(overviewItem != null) {
+ overviewItem.setEnabled(plot != overview.getPlot());
}
exportItem.setEnabled(plot != null);
}
@@ -425,6 +423,17 @@ public class ResultWindow extends JFrame implements ResultListener {
return true;
}
+ /**
+ * Handle a resize event.
+ *
+ * @param newratio New window size ratio.
+ */
+ protected void handleResize(double newratio) {
+ if(currentSubplot == null) {
+ ResultWindow.this.overview.setRatio(newratio);
+ }
+ }
+
public JMenuItem makeMenuItemForVisualizer(Result r) {
if(VisualizationTask.class.isInstance(r)) {
final VisualizationTask v = (VisualizationTask) r;
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/gui/SimpleSVGViewer.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/SimpleSVGViewer.java
index 8172de4e..2a82b1f4 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/gui/SimpleSVGViewer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/SimpleSVGViewer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.gui;
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/visualization/gui/detail/DetailView.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/detail/DetailView.java
index 9bcd64b9..008dae35 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/gui/detail/DetailView.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/detail/DetailView.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.gui.detail;
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/visualization/gui/overview/DetailViewSelectedEvent.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/DetailViewSelectedEvent.java
index 6723c77f..a4f05531 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/DetailViewSelectedEvent.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/DetailViewSelectedEvent.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.gui.overview;
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/visualization/gui/overview/LayerMap.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/LayerMap.java
index 5fb7019e..8e00cc63 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/LayerMap.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/LayerMap.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.visualization.gui.overview;
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/visualization/gui/overview/OverviewPlot.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/OverviewPlot.java
index c4825b1e..34471bdd 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/OverviewPlot.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/OverviewPlot.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.gui.overview;
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,6 +29,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicReference;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
@@ -70,20 +71,28 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization;
* @apiviz.has DetailViewSelectedEvent
* @apiviz.uses DetailView
*/
-// FIXME: there still is a synchronization issue, that causes the initialization
-// to be run twice in parallel.
-public class OverviewPlot extends SVGPlot implements ResultListener {
+public class OverviewPlot implements ResultListener {
/**
* Our logging class
*/
private static final Logging LOG = Logging.getLogger(OverviewPlot.class);
/**
+ * Event when the overview plot was refreshed.
+ */
+ public static final String OVERVIEW_REFRESHED = "Overview refreshed";
+
+ /**
* Visualizer context
*/
private VisualizerContext context;
/**
+ * The SVG plot object.
+ */
+ private SVGPlot plot;
+
+ /**
* Map of coordinates to plots.
*/
protected RectangleArranger<PlotItem> plotmap;
@@ -141,7 +150,7 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
/**
* Pending refresh, for lazy refreshing
*/
- Runnable pendingRefresh = null;
+ AtomicReference<Runnable> pendingRefresh = new AtomicReference<>(null);
/**
* Reinitialize on refresh
@@ -160,26 +169,6 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
this.context = context;
this.single = single;
- // Add a background element:
- {
- CSSClass cls = new CSSClass(this, "background");
- cls.setStatement(SVGConstants.CSS_FILL_PROPERTY, context.getStyleResult().getStyleLibrary().getBackgroundColor(StyleLibrary.PAGE));
- addCSSClassOrLogError(cls);
- Element background = this.svgElement(SVGConstants.SVG_RECT_TAG);
- background.setAttribute(SVGConstants.SVG_X_ATTRIBUTE, "0");
- background.setAttribute(SVGConstants.SVG_Y_ATTRIBUTE, "0");
- background.setAttribute(SVGConstants.SVG_WIDTH_ATTRIBUTE, "100%");
- background.setAttribute(SVGConstants.SVG_HEIGHT_ATTRIBUTE, "100%");
- SVGUtil.setCSSClass(background, cls.getName());
- getRoot().appendChild(background);
- }
-
- if (single) {
- setDisableInteractions(true);
- }
- SVGEffects.addShadowFilter(this);
- SVGEffects.addLightGradient(this);
-
// register context listener
context.addResultListener(this);
}
@@ -196,47 +185,57 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
ArrayList<Projector> projectors = ResultUtil.filterResults(context.getResult(), Projector.class);
// Rectangle layout
- for (Projector p : projectors) {
+ for(Projector p : projectors) {
Collection<PlotItem> projs = p.arrange();
- for (PlotItem it : projs) {
- if (it.w <= 0.0 || it.h <= 0.0) {
+ for(PlotItem it : projs) {
+ if(it.w <= 0.0 || it.h <= 0.0) {
LOG.warning("Plot item with improper size information: " + it);
- } else {
- plotmap.put(it.w, it.h, it);
+ continue;
}
+ plotmap.put(it.w, it.h, it);
}
}
ResultHierarchy hier = context.getHierarchy();
ArrayList<VisualizationTask> tasks = ResultUtil.filterResults(context.getResult(), VisualizationTask.class);
- nextTask: for (VisualizationTask task : tasks) {
- if (!task.visible) {
+ nextTask: for(VisualizationTask task : tasks) {
+ if(!task.visible) {
continue;
}
- for (Hierarchy.Iter<Result> iter = hier.iterParents(task); iter.valid(); iter.advance()) {
- if (iter.get() instanceof Projector) {
+ for(Hierarchy.Iter<Result> iter = hier.iterParents(task); iter.valid(); iter.advance()) {
+ if(iter.get() instanceof Projector) {
continue nextTask;
}
}
- if (task.getWidth() <= 0.0 || task.getHeight() <= 0.0) {
+ if(task.getWidth() <= 0.0 || task.getHeight() <= 0.0) {
LOG.warning("Task with improper size information: " + task);
- } else {
- PlotItem it = new PlotItem(task.getWidth(), task.getHeight(), null);
- it.tasks.add(task);
- plotmap.put(it.w, it.h, it);
+ continue;
}
+ PlotItem it = new PlotItem(task.getWidth(), task.getHeight(), null);
+ it.tasks.add(task);
+ plotmap.put(it.w, it.h, it);
}
return plotmap;
}
/**
+ * Initialize the plot.
+ *
+ * @param ratio Initial ratio
+ */
+ public void initialize(double ratio) {
+ this.ratio = ratio;
+ reinitialize();
+ }
+
+ /**
* Refresh the overview plot.
*/
private void reinitialize() {
- setupHoverer();
+ initializePlot();
plotmap = arrangeVisualizations(ratio, 1.0);
double s = plotmap.relativeFill();
- if (s < 0.9) {
+ if(s < 0.9) {
// Retry, sometimes this yields better results
plotmap = arrangeVisualizations(plotmap.getWidth() * s, plotmap.getHeight() * s);
}
@@ -246,7 +245,7 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
// TODO: cancel pending thumbnail requests!
// Detach existing elements:
- for (Pair<Element, Visualization> pair : vistoelem.values()) {
+ for(Pair<Element, Visualization> pair : vistoelem.values()) {
SVGUtil.removeFromParent(pair.first);
}
// Replace the layer map
@@ -254,44 +253,42 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
vistoelem = new LayerMap();
// Redo main layers
- SVGUtil.removeFromParent(plotlayer);
- SVGUtil.removeFromParent(hoverlayer);
- plotlayer = this.svgElement(SVGConstants.SVG_G_TAG);
- hoverlayer = this.svgElement(SVGConstants.SVG_G_TAG);
+ plotlayer = plot.svgElement(SVGConstants.SVG_G_TAG);
+ hoverlayer = plot.svgElement(SVGConstants.SVG_G_TAG);
// Redo the layout
- for (Entry<PlotItem, double[]> e : plotmap.entrySet()) {
+ for(Entry<PlotItem, double[]> e : plotmap.entrySet()) {
final double basex = e.getValue()[0];
final double basey = e.getValue()[1];
- for (Iterator<PlotItem> iter = e.getKey().itemIterator(); iter.hasNext();) {
+ for(Iterator<PlotItem> iter = e.getKey().itemIterator(); iter.hasNext();) {
PlotItem it = iter.next();
boolean hasDetails = false;
// Container element for main plot item
- Element g = this.svgElement(SVGConstants.SVG_G_TAG);
+ Element g = plot.svgElement(SVGConstants.SVG_G_TAG);
SVGUtil.setAtt(g, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, "translate(" + (basex + it.x) + " " + (basey + it.y) + ")");
plotlayer.appendChild(g);
vistoelem.put(it, null, g, null);
// Add the actual tasks:
- for (VisualizationTask task : it.tasks) {
- if (!visibleInOverview(task)) {
+ for(VisualizationTask task : it.tasks) {
+ if(!visibleInOverview(task)) {
continue;
}
hasDetails |= !task.nodetail;
Pair<Element, Visualization> pair = oldlayers.remove(it, task);
- if (pair == null) {
+ if(pair == null) {
pair = new Pair<>(null, null);
- pair.first = svgElement(SVGConstants.SVG_G_TAG);
+ pair.first = plot.svgElement(SVGConstants.SVG_G_TAG);
}
- if (pair.second == null) {
+ if(pair.second == null) {
pair.second = embedOrThumbnail(thumbsize, it, task, pair.first);
}
g.appendChild(pair.first);
vistoelem.put(it, task, pair);
}
// When needed, add a hover effect
- if (hasDetails && !single) {
- Element hover = this.svgRect(basex + it.x, basey + it.y, it.w, it.h);
+ if(hasDetails && !single) {
+ Element hover = plot.svgRect(basex + it.x, basey + it.y, it.w, it.h);
SVGUtil.addCSSClass(hover, selcss.getName());
// link hoverer.
EventTarget targ = (EventTarget) hover;
@@ -304,14 +301,66 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
}
}
}
- for (Pair<Element, Visualization> pair : oldlayers.values()) {
- if (pair.second != null) {
+ for(Pair<Element, Visualization> pair : oldlayers.values()) {
+ if(pair.second != null) {
pair.second.destroy();
}
}
- getRoot().appendChild(plotlayer);
- getRoot().appendChild(hoverlayer);
- updateStyleElement();
+ plot.getRoot().appendChild(plotlayer);
+ plot.getRoot().appendChild(hoverlayer);
+ plot.updateStyleElement();
+
+ // Notify listeners.
+ for(ActionListener actionListener : actionListeners) {
+ actionListener.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, OVERVIEW_REFRESHED));
+ }
+ }
+
+ /**
+ * Initialize the SVG plot.
+ */
+ private void initializePlot() {
+ if(plot != null) {
+ plot.dispose();
+ }
+ plot = new SVGPlot();
+ { // Add a background element:
+ CSSClass cls = new CSSClass(this, "background");
+ final String bgcol = context.getStyleResult().getStyleLibrary().getBackgroundColor(StyleLibrary.PAGE);
+ cls.setStatement(SVGConstants.CSS_FILL_PROPERTY, bgcol);
+ plot.addCSSClassOrLogError(cls);
+ Element background = plot.svgElement(SVGConstants.SVG_RECT_TAG);
+ background.setAttribute(SVGConstants.SVG_X_ATTRIBUTE, "0");
+ background.setAttribute(SVGConstants.SVG_Y_ATTRIBUTE, "0");
+ background.setAttribute(SVGConstants.SVG_WIDTH_ATTRIBUTE, "100%");
+ background.setAttribute(SVGConstants.SVG_HEIGHT_ATTRIBUTE, "100%");
+ SVGUtil.setCSSClass(background, cls.getName());
+ // Don't export a white background:
+ if("white".equals(bgcol)) {
+ background.setAttribute(SVGPlot.NO_EXPORT_ATTRIBUTE, SVGPlot.NO_EXPORT_ATTRIBUTE);
+ }
+ plot.getRoot().appendChild(background);
+ }
+ { // setup the hover CSS classes.
+ selcss = new CSSClass(this, "s");
+ selcss.setStatement(SVGConstants.CSS_FILL_PROPERTY, SVGConstants.CSS_RED_VALUE);
+ selcss.setStatement(SVGConstants.CSS_STROKE_PROPERTY, SVGConstants.CSS_NONE_VALUE);
+ selcss.setStatement(SVGConstants.CSS_FILL_OPACITY_PROPERTY, "0");
+ selcss.setStatement(SVGConstants.CSS_CURSOR_PROPERTY, SVGConstants.CSS_POINTER_VALUE);
+ CSSClass hovcss = new CSSClass(this, "h");
+ hovcss.setStatement(SVGConstants.CSS_FILL_OPACITY_PROPERTY, "0.25");
+ plot.addCSSClassOrLogError(selcss);
+ plot.addCSSClassOrLogError(hovcss);
+ // Hover listener.
+ hoverer = new CSSHoverClass(hovcss.getName(), null, true);
+ }
+
+ if(single) {
+ plot.setDisableInteractions(true);
+ }
+ SVGEffects.addShadowFilter(plot);
+ SVGEffects.addLightGradient(plot);
+ plot.updateStyleElement();
}
/**
@@ -323,71 +372,70 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
* @param parent Parent element to draw to
*/
private Visualization embedOrThumbnail(final int thumbsize, PlotItem it, VisualizationTask task, Element parent) {
- if (single) {
- VisualizationTask thumbtask = task.clone(this, context, it.proj, it.w, it.h);
- final Visualization vis = thumbtask.getFactory().makeVisualization(thumbtask);
- if (vis.getLayer() == null) {
- LoggingUtil.warning("Visualization returned empty layer: " + vis);
- } else {
- if (task.noexport) {
- vis.getLayer().setAttribute(NO_EXPORT_ATTRIBUTE, NO_EXPORT_ATTRIBUTE);
- }
- parent.appendChild(vis.getLayer());
- }
- return vis;
- } else {
- VisualizationTask thumbtask = task.clone(this, context, it.proj, it.w, it.h);
+ VisualizationTask thumbtask = task.clone(plot, context, it.proj, it.w, it.h);
+ final Visualization vis;
+ if(!single) {
thumbtask.thumbnail = true;
thumbtask.thumbsize = thumbsize;
- final Visualization vis = thumbtask.getFactory().makeVisualizationOrThumbnail(thumbtask);
- if (vis.getLayer() == null) {
- LoggingUtil.warning("Visualization returned empty layer: " + vis);
- } else {
- parent.appendChild(vis.getLayer());
- }
+ vis = thumbtask.getFactory().makeVisualizationOrThumbnail(thumbtask);
+ }
+ else {
+ vis = thumbtask.getFactory().makeVisualization(thumbtask);
+ }
+ if(vis.getLayer() == null) {
+ LoggingUtil.warning("Visualization returned empty layer: " + vis);
return vis;
}
+ if(task.noexport) {
+ vis.getLayer().setAttribute(SVGPlot.NO_EXPORT_ATTRIBUTE, SVGPlot.NO_EXPORT_ATTRIBUTE);
+ }
+ parent.appendChild(vis.getLayer());
+ return vis;
}
/**
* Do a refresh (when visibilities have changed).
*/
- synchronized void refresh() {
- pendingRefresh = null;
- if (reinitOnRefresh) {
- LOG.debug("Reinitialize");
+ void refresh() {
+ pendingRefresh.set(null); // Clear
+ if(reinitOnRefresh) {
+ LOG.debug("Reinitialize in thread " + Thread.currentThread().getName());
reinitialize();
reinitOnRefresh = false;
- } else {
+ return;
+ }
+ synchronized(plot) {
LOG.debug("Incremental refresh");
boolean refreshcss = false;
final int thumbsize = (int) Math.max(screenwidth / plotmap.getWidth(), screenheight / plotmap.getHeight());
- for (PlotItem pi : plotmap.keySet()) {
- for (Iterator<PlotItem> iter = pi.itemIterator(); iter.hasNext();) {
+ for(PlotItem pi : plotmap.keySet()) {
+ for(Iterator<PlotItem> iter = pi.itemIterator(); iter.hasNext();) {
PlotItem it = iter.next();
- for (Iterator<VisualizationTask> tit = it.tasks.iterator(); tit.hasNext();) {
+ for(Iterator<VisualizationTask> tit = it.tasks.iterator(); tit.hasNext();) {
VisualizationTask task = tit.next();
Pair<Element, Visualization> pair = vistoelem.get(it, task);
// New task?
- if (pair == null) {
- if (visibleInOverview(task)) {
+ if(pair == null) {
+ if(visibleInOverview(task)) {
pair = new Pair<>(null, null);
- pair.first = svgElement(SVGConstants.SVG_G_TAG);
+ pair.first = plot.svgElement(SVGConstants.SVG_G_TAG);
pair.second = embedOrThumbnail(thumbsize, it, task, pair.first);
vistoelem.get(it, null).first.appendChild(pair.first);
vistoelem.put(it, task, pair);
refreshcss = true;
}
- } else {
- if (visibleInOverview(task)) {
+ }
+ else {
+ if(visibleInOverview(task)) {
// unhide if hidden.
- if (pair.first.hasAttribute(SVGConstants.CSS_VISIBILITY_PROPERTY)) {
+ if(pair.first.hasAttribute(SVGConstants.CSS_VISIBILITY_PROPERTY)) {
pair.first.removeAttribute(SVGConstants.CSS_VISIBILITY_PROPERTY);
}
- } else {
+ }
+ else {
// hide if there is anything to hide.
- if (pair.first != null && pair.first.hasChildNodes()) {
+ if(pair.first != null && pair.first.hasChildNodes()) {
pair.first.setAttribute(SVGConstants.CSS_VISIBILITY_PROPERTY, SVGConstants.CSS_HIDDEN_VALUE);
}
}
@@ -396,8 +444,8 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
}
}
}
- if (refreshcss) {
- updateStyleElement();
+ if(refreshcss) {
+ plot.updateStyleElement();
}
}
}
@@ -409,9 +457,10 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
* @return visibility
*/
protected boolean visibleInOverview(VisualizationTask task) {
- if (single) {
+ if(single) {
return task.visible && !task.noembed;
- } else {
+ }
+ else {
return task.visible && task.thumbnail;
}
}
@@ -423,28 +472,9 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
// Recalculate bounding box.
String vb = "0 0 " + plotmap.getWidth() + " " + plotmap.getHeight();
// Reset root bounding box.
- SVGUtil.setAtt(getRoot(), SVGConstants.SVG_WIDTH_ATTRIBUTE, "20cm");
- SVGUtil.setAtt(getRoot(), SVGConstants.SVG_HEIGHT_ATTRIBUTE, (20 / plotmap.getWidth() * plotmap.getHeight()) + "cm");
- SVGUtil.setAtt(getRoot(), SVGConstants.SVG_VIEW_BOX_ATTRIBUTE, vb);
- }
-
- /**
- * Setup the CSS hover effect.
- */
- private void setupHoverer() {
- // setup the hover CSS classes.
- selcss = new CSSClass(this, "s");
- selcss.setStatement(SVGConstants.CSS_FILL_PROPERTY, SVGConstants.CSS_RED_VALUE);
- selcss.setStatement(SVGConstants.CSS_STROKE_PROPERTY, SVGConstants.CSS_NONE_VALUE);
- selcss.setStatement(SVGConstants.CSS_FILL_OPACITY_PROPERTY, "0");
- selcss.setStatement(SVGConstants.CSS_CURSOR_PROPERTY, SVGConstants.CSS_POINTER_VALUE);
- CSSClass hovcss = new CSSClass(this, "h");
- hovcss.setStatement(SVGConstants.CSS_FILL_OPACITY_PROPERTY, "0.25");
- addCSSClassOrLogError(selcss);
- addCSSClassOrLogError(hovcss);
- // Hover listener.
- hoverer = new CSSHoverClass(hovcss.getName(), null, true);
- updateStyleElement();
+ SVGUtil.setAtt(plot.getRoot(), SVGConstants.SVG_WIDTH_ATTRIBUTE, "20cm");
+ SVGUtil.setAtt(plot.getRoot(), SVGConstants.SVG_HEIGHT_ATTRIBUTE, (20 * plotmap.getHeight() / plotmap.getWidth()) + "cm");
+ SVGUtil.setAtt(plot.getRoot(), SVGConstants.SVG_VIEW_BOX_ATTRIBUTE, vb);
}
/**
@@ -473,7 +503,7 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
*/
protected void triggerSubplotSelectEvent(PlotItem it) {
// forward event to all listeners.
- for (ActionListener actionListener : actionListeners) {
+ for(ActionListener actionListener : actionListeners) {
actionListener.actionPerformed(new DetailViewSelectedEvent(this, ActionEvent.ACTION_PERFORMED, null, 0, it));
}
}
@@ -508,12 +538,20 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
}
/**
- * Cancel the overview, i.e. stop the thumbnailer
+ * Destroy this overview plot.
*/
- @Override
- public void dispose() {
+ public void destroy() {
context.removeResultListener(this);
- super.dispose();
+ plot.dispose();
+ }
+
+ /**
+ * Get the SVGPlot object.
+ *
+ * @return SVG plot
+ */
+ public SVGPlot getPlot() {
+ return plot;
}
/**
@@ -527,30 +565,37 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
* @param ratio the ratio to set
*/
public void setRatio(double ratio) {
- this.ratio = ratio;
+ if(ratio != this.ratio) {
+ this.ratio = ratio;
+ reinitOnRefresh = true;
+ lazyRefresh();
+ }
}
/**
* Trigger a redraw, but avoid excessive redraws.
*/
public final void lazyRefresh() {
+ if(plot == null) {
+ LOG.warning("'lazyRefresh' called before initialized!");
+ }
LOG.debug("Scheduling refresh.");
Runnable pr = new Runnable() {
@Override
public void run() {
- if (OverviewPlot.this.pendingRefresh == this) {
+ if(OverviewPlot.this.pendingRefresh.compareAndSet(this, null)) {
OverviewPlot.this.refresh();
}
}
};
- pendingRefresh = pr;
- scheduleUpdate(pr);
+ OverviewPlot.this.pendingRefresh.set(pr);
+ plot.scheduleUpdate(pr);
}
@Override
public void resultAdded(Result child, Result parent) {
LOG.debug("result added: " + child);
- if (child instanceof VisualizationTask) {
+ if(child instanceof VisualizationTask) {
reinitOnRefresh = true;
}
lazyRefresh();
@@ -559,17 +604,13 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
@Override
public void resultChanged(Result current) {
LOG.debug("result changed: " + current);
- if (current instanceof VisualizationTask) {
- boolean relayout = true;
- for (Hierarchy.Iter<Result> iter = context.getHierarchy().iterParents(current); iter.valid(); iter.advance()) {
- if (iter.get() instanceof Projector) {
- relayout = false;
+ if(current instanceof VisualizationTask) {
+ for(Hierarchy.Iter<Result> iter = context.getHierarchy().iterParents(current); iter.valid(); iter.advance()) {
+ if(iter.get() instanceof Projector) {
+ reinitOnRefresh = true;
break;
}
}
- if (relayout) {
- reinitOnRefresh = true;
- }
}
lazyRefresh();
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/PlotItem.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/PlotItem.java
index 7919e07e..0c0d41ea 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/PlotItem.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/PlotItem.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.gui.overview;
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/visualization/gui/overview/RectangleArranger.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/RectangleArranger.java
index 441f7ae2..fad6fc07 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/RectangleArranger.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/RectangleArranger.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.gui.overview;
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/visualization/opticsplot/OPTICSColorAdapter.java b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorAdapter.java
index 5a16c91c..671ccb01 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.opticsplot;
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.visualization.opticsplot;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
/**
* Class to handle coloring of the OPTICS plot.
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorFromStylingPolicy.java b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorFromStylingPolicy.java
index 1f9bccdc..1f24bd8f 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorFromStylingPolicy.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorFromStylingPolicy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.opticsplot;
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.visualization.opticsplot;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
import de.lmu.ifi.dbs.elki.visualization.style.StylingPolicy;
/**
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorStatic.java b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorStatic.java
index b6933e63..ddc3a3cd 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorStatic.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorStatic.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.opticsplot;
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.visualization.opticsplot;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
/**
* Pseudo-coloring for OPTICS plot that just uses a static color.
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSCorrelationDimensionalityDistance.java b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSCorrelationDimensionalityDistanceAdapter.java
index 1261c668..1b12db86 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSCorrelationDimensionalityDistance.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSCorrelationDimensionalityDistanceAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.opticsplot;
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,36 +23,31 @@ package de.lmu.ifi.dbs.elki.visualization.opticsplot;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.CorrelationDistance;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.CorrelationClusterOrderEntry;
/**
* Adapter that will map a correlation distance to its dimensionality.
*
* @author Erich Schubert
*/
-public class OPTICSCorrelationDimensionalityDistance<D extends CorrelationDistance<D>> implements OPTICSDistanceAdapter<D> {
+public class OPTICSCorrelationDimensionalityDistanceAdapter implements OPTICSDistanceAdapter<CorrelationClusterOrderEntry<?>> {
/**
* Default constructor.
*/
- public OPTICSCorrelationDimensionalityDistance() {
+ public OPTICSCorrelationDimensionalityDistanceAdapter() {
super();
}
@Override
- public double getDoubleForEntry(ClusterOrderEntry<D> coe) {
- final D reachability = coe.getReachability();
- if (reachability == null) {
+ public double getDoubleForEntry(CorrelationClusterOrderEntry<?> coe) {
+ if(coe.getCorrelationValue() == Integer.MAX_VALUE) {
return Double.POSITIVE_INFINITY;
}
- if (reachability.isInfiniteDistance() || reachability.isUndefinedDistance()) {
- return Double.POSITIVE_INFINITY;
- }
- return reachability.getCorrelationValue();
+ return coe.getCorrelationValue();
}
@Override
- public boolean isInfinite(ClusterOrderEntry<D> coe) {
- return coe.getReachability().isInfiniteDistance();
+ public boolean isInfinite(CorrelationClusterOrderEntry<?> coe) {
+ return coe.getCorrelationValue() == Integer.MAX_VALUE;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSCut.java b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSCut.java
index 452cf6af..434169d8 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSCut.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSCut.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.opticsplot;
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,15 +25,14 @@ package de.lmu.ifi.dbs.elki.visualization.opticsplot;
import java.util.List;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderResult;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.model.ClusterModel;
import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
/**
* Compute a partitioning from an OPTICS plot by doing a horizontal cut.
@@ -49,14 +48,14 @@ public class OPTICSCut {
/**
* Compute an OPTICS cut clustering
*
- * @param <D> Distance type
+ * @param <E> Cluster order entry type
* @param co Cluster order result
* @param adapter Distance adapter
* @param epsilon Epsilon value for cut
* @return New partitioning clustering
*/
- public static <D extends Distance<D>> Clustering<Model> makeOPTICSCut(ClusterOrderResult<D> co, OPTICSDistanceAdapter<D> adapter, double epsilon) {
- List<ClusterOrderEntry<D>> order = co.getClusterOrder();
+ public static <E extends ClusterOrderEntry<?>> Clustering<Model> makeOPTICSCut(ClusterOrderResult<E> co, OPTICSDistanceAdapter<E> adapter, double epsilon) {
+ List<E> order = co.getClusterOrder();
// Clustering model we are building
Clustering<Model> clustering = new Clustering<>("OPTICS Cut Clustering", "optics-cut");
// Collects noise elements
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSDistanceAdapter.java b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSDistanceAdapter.java
index 8a6f13ba..728a490e 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSDistanceAdapter.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSDistanceAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.opticsplot;
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,24 +23,24 @@ package de.lmu.ifi.dbs.elki.visualization.opticsplot;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
/**
- * Interface to map ClusterOrderEntries to double values to use in the OPTICS plot.
+ * Interface to map ClusterOrderEntries to double values to use in the OPTICS
+ * plot.
*
* @author Erich Schubert
- *
- * @param <D> Distance type
+ *
+ * @param <E> Cluster order entry type.
*/
-public interface OPTICSDistanceAdapter<D extends Distance<D>> {
+public interface OPTICSDistanceAdapter<E extends ClusterOrderEntry<?>> {
/**
* Get the double value for plotting for a cluster order entry.
*
* @param coe Cluster Order Entry
* @return Double value (height)
*/
- double getDoubleForEntry(ClusterOrderEntry<D> coe);
+ double getDoubleForEntry(E coe);
/**
* Test whether the reachability is infinite.
@@ -48,5 +48,5 @@ public interface OPTICSDistanceAdapter<D extends Distance<D>> {
* @param coe Cluster order entry
* @return true, when infinite
*/
- boolean isInfinite(ClusterOrderEntry<D> coe);
+ boolean isInfinite(E coe);
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSNumberDistance.java b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSNumberDistanceAdapter.java
index ad7112f3..9f91966f 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSNumberDistance.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSNumberDistanceAdapter.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.opticsplot;
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,32 +23,28 @@ package de.lmu.ifi.dbs.elki.visualization.opticsplot;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.DoubleDistanceClusterOrderEntry;
/**
* Adapter that will map a regular number distance to its double value.
*
* @author Erich Schubert
*/
-public class OPTICSNumberDistance<D extends NumberDistance<D, ?>> implements OPTICSDistanceAdapter<D> {
+public class OPTICSNumberDistanceAdapter implements OPTICSDistanceAdapter<DoubleDistanceClusterOrderEntry> {
/**
* Default constructor.
*/
- public OPTICSNumberDistance() {
+ public OPTICSNumberDistanceAdapter() {
super();
}
@Override
- public double getDoubleForEntry(ClusterOrderEntry<D> coe) {
- if (coe.getReachability() == null) {
- return Double.POSITIVE_INFINITY;
- }
- return coe.getReachability().doubleValue();
+ public double getDoubleForEntry(DoubleDistanceClusterOrderEntry coe) {
+ return coe.getReachability();
}
@Override
- public boolean isInfinite(ClusterOrderEntry<D> coe) {
- return coe.getReachability().isInfiniteDistance();
+ public boolean isInfinite(DoubleDistanceClusterOrderEntry coe) {
+ return coe.getReachability() >= Double.POSITIVE_INFINITY;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSPlot.java b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSPlot.java
index 4663ef1a..a7f87fd2 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSPlot.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSPlot.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.opticsplot;
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,14 @@ import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.util.List;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.CorrelationDistance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderResult;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.CorrelationClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.DoubleDistanceClusterOrderEntry;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.math.scales.LinearScale;
import de.lmu.ifi.dbs.elki.result.Result;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
import de.lmu.ifi.dbs.elki.visualization.VisualizerContext;
import de.lmu.ifi.dbs.elki.visualization.batikutil.ThumbnailRegistryEntry;
import de.lmu.ifi.dbs.elki.visualization.style.StylingPolicy;
@@ -50,9 +49,9 @@ import de.lmu.ifi.dbs.elki.visualization.style.StylingPolicy;
* @apiviz.composedOf OPTICSDistanceAdapter
* @apiviz.has ClusterOrderResult oneway - - renders
*
- * @param <D> Distance type
+ * @param <E> Cluster order entry type
*/
-public class OPTICSPlot<D extends Distance<D>> implements Result {
+public class OPTICSPlot<E extends ClusterOrderEntry<?>> implements Result {
/**
* Logger
*/
@@ -76,7 +75,7 @@ public class OPTICSPlot<D extends Distance<D>> implements Result {
/**
* The result to plot
*/
- final ClusterOrderResult<D> co;
+ final ClusterOrderResult<E> co;
/**
* Color adapter to use
@@ -86,7 +85,7 @@ public class OPTICSPlot<D extends Distance<D>> implements Result {
/**
* The mapping from cluster order entry to value
*/
- final OPTICSDistanceAdapter<D> distanceAdapter;
+ final OPTICSDistanceAdapter<E> distanceAdapter;
/**
* The Optics plot.
@@ -105,7 +104,7 @@ public class OPTICSPlot<D extends Distance<D>> implements Result {
* @param colors Coloring strategy
* @param distanceAdapter Distance adapter
*/
- public OPTICSPlot(ClusterOrderResult<D> co, OPTICSColorAdapter colors, OPTICSDistanceAdapter<D> distanceAdapter) {
+ public OPTICSPlot(ClusterOrderResult<E> co, OPTICSColorAdapter colors, OPTICSDistanceAdapter<E> distanceAdapter) {
super();
this.co = co;
this.colors = colors;
@@ -118,7 +117,7 @@ public class OPTICSPlot<D extends Distance<D>> implements Result {
* @param co Cluster order to plot.
* @param colors Coloring strategy
*/
- public OPTICSPlot(ClusterOrderResult<D> co, OPTICSColorAdapter colors) {
+ public OPTICSPlot(ClusterOrderResult<E> co, OPTICSColorAdapter colors) {
super();
this.co = co;
this.colors = colors;
@@ -128,18 +127,18 @@ public class OPTICSPlot<D extends Distance<D>> implements Result {
/**
* Try to find a distance adapter.
*
- * @param <D> distance type
+ * @param <E> cluster order entry type
* @param co ClusterOrderResult
* @return distance adapter
*/
- @SuppressWarnings({ "unchecked", "rawtypes" })
- private static <D extends Distance<D>> OPTICSDistanceAdapter<D> getAdapterForDistance(ClusterOrderResult<D> co) {
- Class<?> dcls = co.getDistanceClass();
- if(dcls != null && NumberDistance.class.isAssignableFrom(dcls)) {
- return new OPTICSNumberDistance();
+ @SuppressWarnings({ "unchecked" })
+ private static <E extends ClusterOrderEntry<?>> OPTICSDistanceAdapter<E> getAdapterForDistance(ClusterOrderResult<E> co) {
+ Class<?> dcls = co.getEntryType();
+ if(dcls != null && DoubleDistanceClusterOrderEntry.class.isAssignableFrom(dcls)) {
+ return (OPTICSDistanceAdapter<E>) new OPTICSNumberDistanceAdapter();
}
- else if(dcls != null && CorrelationDistance.class.isAssignableFrom(dcls)) {
- return new OPTICSCorrelationDimensionalityDistance();
+ else if(dcls != null && CorrelationClusterOrderEntry.class.isAssignableFrom(dcls)) {
+ return (OPTICSDistanceAdapter<E>) new OPTICSCorrelationDimensionalityDistanceAdapter();
}
else if(dcls == null) {
throw new UnsupportedOperationException("No distance in cluster order?!?");
@@ -153,11 +152,11 @@ public class OPTICSPlot<D extends Distance<D>> implements Result {
* Test whether this class can produce an OPTICS plot for the given cluster
* order.
*
- * @param <D> Distance type
+ * @param <E> Cluster order entry type
* @param co Cluster order result
* @return test result
*/
- public static <D extends Distance<D>> boolean canPlot(ClusterOrderResult<D> co) {
+ public static <E extends ClusterOrderEntry<?>> boolean canPlot(ClusterOrderResult<E> co) {
try {
if(getAdapterForDistance(co) != null) {
return true;
@@ -173,7 +172,7 @@ public class OPTICSPlot<D extends Distance<D>> implements Result {
* Trigger a redraw of the OPTICS plot
*/
public void replot() {
- List<ClusterOrderEntry<D>> order = co.getClusterOrder();
+ List<E> order = co.getClusterOrder();
width = order.size();
height = Math.min(200, (int) Math.ceil(width / 5));
@@ -184,7 +183,7 @@ public class OPTICSPlot<D extends Distance<D>> implements Result {
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
int x = 0;
- for(ClusterOrderEntry<D> coe : order) {
+ for(E coe : order) {
double reach = distanceAdapter.getDoubleForEntry(coe);
final int y;
if(!Double.isInfinite(reach) && !Double.isNaN(reach)) {
@@ -214,10 +213,10 @@ public class OPTICSPlot<D extends Distance<D>> implements Result {
* @param order Cluster order to process
* @return Scale for value range of cluster order
*/
- protected LinearScale computeScale(List<ClusterOrderEntry<D>> order) {
+ protected LinearScale computeScale(List<E> order) {
DoubleMinMax range = new DoubleMinMax();
// calculate range
- for(ClusterOrderEntry<D> coe : order) {
+ for(E coe : order) {
double reach = distanceAdapter.getDoubleForEntry(coe);
if(!distanceAdapter.isInfinite(coe) && !Double.isNaN(reach)) {
range.put(reach);
@@ -290,7 +289,7 @@ public class OPTICSPlot<D extends Distance<D>> implements Result {
*
* @return the distanceAdapter
*/
- public OPTICSDistanceAdapter<D> getDistanceAdapter() {
+ public OPTICSDistanceAdapter<E> getDistanceAdapter() {
return distanceAdapter;
}
@@ -328,13 +327,13 @@ public class OPTICSPlot<D extends Distance<D>> implements Result {
* Static method to find an optics plot for a result, or to create a new one
* using the given context.
*
- * @param <D> Distance type
+ * @param <E> Cluster order entry type
* @param co Cluster order
* @param context Context (for colors and reference clustering)
*
* @return New or existing optics plot
*/
- public static <D extends Distance<D>> OPTICSPlot<D> plotForClusterOrder(ClusterOrderResult<D> co, VisualizerContext context) {
+ public static <E extends ClusterOrderEntry<?>> OPTICSPlot<E> plotForClusterOrder(ClusterOrderResult<E> co, VisualizerContext context) {
// Check for an existing plot
// ArrayList<OPTICSPlot<D>> plots = ResultUtil.filterResults(co,
// OPTICSPlot.class);
@@ -348,7 +347,7 @@ public class OPTICSPlot<D extends Distance<D>> implements Result {
final StylingPolicy policy = context.getStyleResult().getStylingPolicy();
final OPTICSColorAdapter opcolor = new OPTICSColorFromStylingPolicy(policy);
- OPTICSPlot<D> opticsplot = new OPTICSPlot<>(co, opcolor);
+ OPTICSPlot<E> opticsplot = new OPTICSPlot<>(co, opcolor);
// co.addChildResult(opticsplot);
return opticsplot;
}
@@ -358,7 +357,7 @@ public class OPTICSPlot<D extends Distance<D>> implements Result {
*
* @return Cluster order
*/
- public ClusterOrderResult<D> getClusterOrder() {
+ public ClusterOrderResult<E> getClusterOrder() {
return co;
}
-} \ No newline at end of file
+}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projections/AbstractFullProjection.java b/src/de/lmu/ifi/dbs/elki/visualization/projections/AbstractFullProjection.java
index 5f698192..4a0273ca 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projections/AbstractFullProjection.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projections/AbstractFullProjection.java
@@ -8,7 +8,7 @@ import de.lmu.ifi.dbs.elki.math.scales.LinearScale;
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
@@ -52,7 +52,7 @@ public abstract class AbstractFullProjection extends AbstractProjection implemen
* @return vector in scaled space
*/
@Override
- public Vector projectDataToScaledSpace(NumberVector<?> data) {
+ public Vector projectDataToScaledSpace(NumberVector data) {
final int dim = data.getDimensionality();
Vector vec = new Vector(dim);
double[] ds = vec.getArrayRef();
@@ -86,7 +86,7 @@ public abstract class AbstractFullProjection extends AbstractProjection implemen
* @return relative vector in scaled space
*/
@Override
- public Vector projectRelativeDataToScaledSpace(NumberVector<?> data) {
+ public Vector projectRelativeDataToScaledSpace(NumberVector data) {
final int dim = data.getDimensionality();
Vector vec = new Vector(dim);
double[] ds = vec.getArrayRef();
@@ -120,7 +120,7 @@ public abstract class AbstractFullProjection extends AbstractProjection implemen
* @return vector in rendering space
*/
@Override
- public Vector projectDataToRenderSpace(NumberVector<?> data) {
+ public Vector projectDataToRenderSpace(NumberVector data) {
return projectScaledToRender(projectDataToScaledSpace(data));
}
@@ -142,7 +142,7 @@ public abstract class AbstractFullProjection extends AbstractProjection implemen
* @return relative vector in rendering space
*/
@Override
- public Vector projectRelativeDataToRenderSpace(NumberVector<?> data) {
+ public Vector projectRelativeDataToRenderSpace(NumberVector data) {
return projectRelativeScaledToRender(projectRelativeDataToScaledSpace(data));
}
@@ -166,7 +166,7 @@ public abstract class AbstractFullProjection extends AbstractProjection implemen
* @return vector in data space
*/
@Override
- public <NV extends NumberVector<?>> NV projectScaledToDataSpace(Vector v, NumberVector.Factory<NV, ?> factory) {
+ public <NV extends NumberVector> NV projectScaledToDataSpace(Vector v, NumberVector.Factory<NV> factory) {
final int dim = v.getDimensionality();
Vector vec = v.copy();
double[] ds = vec.getArrayRef();
@@ -185,7 +185,7 @@ public abstract class AbstractFullProjection extends AbstractProjection implemen
* @return vector in data space
*/
@Override
- public <NV extends NumberVector<?>> NV projectRenderToDataSpace(Vector v, NumberVector.Factory<NV, ?> prototype) {
+ public <NV extends NumberVector> NV projectRenderToDataSpace(Vector v, NumberVector.Factory<NV> prototype) {
final int dim = v.getDimensionality();
Vector vec = projectRenderToScaled(v);
double[] ds = vec.getArrayRef();
@@ -206,7 +206,7 @@ public abstract class AbstractFullProjection extends AbstractProjection implemen
* @return relative vector in data space
*/
@Override
- public <NV extends NumberVector<?>> NV projectRelativeScaledToDataSpace(Vector v, NumberVector.Factory<NV, ?> prototype) {
+ public <NV extends NumberVector> NV projectRelativeScaledToDataSpace(Vector v, NumberVector.Factory<NV> prototype) {
final int dim = v.getDimensionality();
Vector vec = v.copy();
double[] ds = vec.getArrayRef();
@@ -225,7 +225,7 @@ public abstract class AbstractFullProjection extends AbstractProjection implemen
* @return relative vector in data space
*/
@Override
- public <NV extends NumberVector<?>> NV projectRelativeRenderToDataSpace(Vector v, NumberVector.Factory<NV, ?> prototype) {
+ public <NV extends NumberVector> NV projectRelativeRenderToDataSpace(Vector v, NumberVector.Factory<NV> prototype) {
final int dim = v.getDimensionality();
Vector vec = projectRelativeRenderToScaled(v);
double[] ds = vec.getArrayRef();
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projections/AbstractProjection.java b/src/de/lmu/ifi/dbs/elki/visualization/projections/AbstractProjection.java
index a1629d77..21fb6d56 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projections/AbstractProjection.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projections/AbstractProjection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projections;
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/visualization/projections/AbstractSimpleProjection.java b/src/de/lmu/ifi/dbs/elki/visualization/projections/AbstractSimpleProjection.java
index ea93dbda..d188eb85 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projections/AbstractSimpleProjection.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projections/AbstractSimpleProjection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projections;
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/visualization/projections/AffineProjection.java b/src/de/lmu/ifi/dbs/elki/visualization/projections/AffineProjection.java
index f29c1d50..3e9bfcbb 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projections/AffineProjection.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projections/AffineProjection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projections;
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
@@ -173,7 +173,7 @@ public class AffineProjection extends AbstractFullProjection implements Projecti
}
@Override
- public double[] fastProjectDataToRenderSpace(NumberVector<?> data) {
+ public double[] fastProjectDataToRenderSpace(NumberVector data) {
return fastProjectScaledToRenderSpace(fastProjectDataToScaledSpace(data));
}
@@ -184,7 +184,7 @@ public class AffineProjection extends AbstractFullProjection implements Projecti
}
@Override
- public double[] fastProjectDataToScaledSpace(NumberVector<?> data) {
+ public double[] fastProjectDataToScaledSpace(NumberVector data) {
// FIXME: implement with less objects?
return projectDataToScaledSpace(data).getArrayRef();
}
@@ -222,7 +222,7 @@ public class AffineProjection extends AbstractFullProjection implements Projecti
}
@Override
- public double[] fastProjectRelativeDataToRenderSpace(NumberVector<?> data) {
+ public double[] fastProjectRelativeDataToRenderSpace(NumberVector data) {
// FIXME: implement with less objects?
return fastProjectRelativeScaledToRenderSpace(projectRelativeDataToScaledSpace(data).getArrayRef());
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projections/CanvasSize.java b/src/de/lmu/ifi/dbs/elki/visualization/projections/CanvasSize.java
index c53e62dd..21e0cb39 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projections/CanvasSize.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projections/CanvasSize.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projections;
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/visualization/projections/FullProjection.java b/src/de/lmu/ifi/dbs/elki/visualization/projections/FullProjection.java
index e715e859..c5f3e492 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projections/FullProjection.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projections/FullProjection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projections;
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
@@ -75,7 +75,7 @@ public interface FullProjection extends Projection {
* @param data vector in data space
* @return vector in scaled space
*/
- Vector projectDataToScaledSpace(NumberVector<?> data);
+ Vector projectDataToScaledSpace(NumberVector data);
/**
* Project a data vector from data space to scaled space.
@@ -91,7 +91,7 @@ public interface FullProjection extends Projection {
* @param data relative vector in data space
* @return relative vector in scaled space
*/
- Vector projectRelativeDataToScaledSpace(NumberVector<?> data);
+ Vector projectRelativeDataToScaledSpace(NumberVector data);
/**
* Project a relative data vector from data space to scaled space.
@@ -107,7 +107,7 @@ public interface FullProjection extends Projection {
* @param data vector in data space
* @return vector in rendering space
*/
- Vector projectDataToRenderSpace(NumberVector<?> data);
+ Vector projectDataToRenderSpace(NumberVector data);
/**
* Project a data vector from data space to rendering space.
@@ -125,7 +125,7 @@ public interface FullProjection extends Projection {
* @param factory Object factory
* @return vector in data space
*/
- <NV extends NumberVector<?>> NV projectScaledToDataSpace(Vector v, NumberVector.Factory<NV, ?> factory);
+ <NV extends NumberVector> NV projectScaledToDataSpace(Vector v, NumberVector.Factory<NV> factory);
/**
* Project a vector from rendering space to data space.
@@ -135,7 +135,7 @@ public interface FullProjection extends Projection {
* @param prototype Object factory
* @return vector in data space
*/
- <NV extends NumberVector<?>> NV projectRenderToDataSpace(Vector v, NumberVector.Factory<NV, ?> prototype);
+ <NV extends NumberVector> NV projectRenderToDataSpace(Vector v, NumberVector.Factory<NV> prototype);
/**
* Project a relative data vector from data space to rendering space.
@@ -143,7 +143,7 @@ public interface FullProjection extends Projection {
* @param data relative vector in data space
* @return relative vector in rendering space
*/
- Vector projectRelativeDataToRenderSpace(NumberVector<?> data);
+ Vector projectRelativeDataToRenderSpace(NumberVector data);
/**
* Project a relative data vector from data space to rendering space.
@@ -161,7 +161,7 @@ public interface FullProjection extends Projection {
* @param prototype Object factory
* @return relative vector in data space
*/
- <NV extends NumberVector<?>> NV projectRelativeScaledToDataSpace(Vector v, NumberVector.Factory<NV, ?> prototype);
+ <NV extends NumberVector> NV projectRelativeScaledToDataSpace(Vector v, NumberVector.Factory<NV> prototype);
/**
* Project a relative vector from rendering space to data space.
@@ -171,5 +171,5 @@ public interface FullProjection extends Projection {
* @param prototype Object factory
* @return relative vector in data space
*/
- <NV extends NumberVector<?>> NV projectRelativeRenderToDataSpace(Vector v, NumberVector.Factory<NV, ?> prototype);
+ <NV extends NumberVector> NV projectRelativeRenderToDataSpace(Vector v, NumberVector.Factory<NV> prototype);
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projections/OPTICSProjection.java b/src/de/lmu/ifi/dbs/elki/visualization/projections/OPTICSProjection.java
index 13409ee0..e0032144 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projections/OPTICSProjection.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projections/OPTICSProjection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projections;
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,10 +23,10 @@ package de.lmu.ifi.dbs.elki.visualization.projections;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderResult;
import de.lmu.ifi.dbs.elki.math.scales.LinearScale;
import de.lmu.ifi.dbs.elki.result.AbstractHierarchicalResult;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
import de.lmu.ifi.dbs.elki.visualization.VisualizerContext;
import de.lmu.ifi.dbs.elki.visualization.opticsplot.OPTICSPlot;
import de.lmu.ifi.dbs.elki.visualization.projector.OPTICSProjector;
@@ -36,19 +36,21 @@ import de.lmu.ifi.dbs.elki.visualization.projector.OPTICSProjector;
* consistency in the visualizer API.
*
* @author Erich Schubert
+ *
+ * @param <E> Cluster order entry type
*/
-public class OPTICSProjection<D extends Distance<D>> extends AbstractHierarchicalResult implements Projection {
+public class OPTICSProjection<E extends ClusterOrderEntry<?>> extends AbstractHierarchicalResult implements Projection {
/**
* The projector we were generated from.
*/
- OPTICSProjector<D> projector;
+ OPTICSProjector<E> projector;
/**
* Constructor.
- *
+ *
* @param opticsProjector OPTICS projector
*/
- public OPTICSProjection(OPTICSProjector<D> opticsProjector) {
+ public OPTICSProjection(OPTICSProjector<E> opticsProjector) {
super();
this.projector = opticsProjector;
}
@@ -79,7 +81,7 @@ public class OPTICSProjection<D extends Distance<D>> extends AbstractHierarchica
* @param context Context to use
* @return Plot
*/
- public OPTICSPlot<D> getOPTICSPlot(VisualizerContext context) {
+ public OPTICSPlot<E> getOPTICSPlot(VisualizerContext context) {
return projector.getOPTICSPlot(context);
}
@@ -88,7 +90,7 @@ public class OPTICSProjection<D extends Distance<D>> extends AbstractHierarchica
*
* @return Cluster oder result.
*/
- public ClusterOrderResult<D> getResult() {
+ public ClusterOrderResult<E> getResult() {
return projector.getResult();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projections/Projection.java b/src/de/lmu/ifi/dbs/elki/visualization/projections/Projection.java
index d141838e..991c5605 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projections/Projection.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projections/Projection.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projections;
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/visualization/projections/Projection1D.java b/src/de/lmu/ifi/dbs/elki/visualization/projections/Projection1D.java
index a5f5e7e9..47487efc 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projections/Projection1D.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projections/Projection1D.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projections;
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
@@ -48,7 +48,7 @@ public interface Projection1D extends Projection {
* @param data vector in data space
* @return vector in rendering space
*/
- public double fastProjectDataToRenderSpace(NumberVector<?> data);
+ public double fastProjectDataToRenderSpace(NumberVector data);
/**
* Project a vector from scaled space to rendering space.
@@ -72,7 +72,7 @@ public interface Projection1D extends Projection {
* @param data vector in data space
* @return vector in rendering space
*/
- public double fastProjectRelativeDataToRenderSpace(NumberVector<?> data);
+ public double fastProjectRelativeDataToRenderSpace(NumberVector data);
/**
* Project a vector from scaled space to rendering space.
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projections/Projection2D.java b/src/de/lmu/ifi/dbs/elki/visualization/projections/Projection2D.java
index 1a8b1952..d9c9ff0e 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projections/Projection2D.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projections/Projection2D.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projections;
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
@@ -52,7 +52,7 @@ public interface Projection2D extends Projection {
* @param data vector in data space
* @return vector in rendering space
*/
- public double[] fastProjectDataToRenderSpace(NumberVector<?> data);
+ public double[] fastProjectDataToRenderSpace(NumberVector data);
/**
* Project a data vector from data space to scaled space.
@@ -68,7 +68,7 @@ public interface Projection2D extends Projection {
* @param data vector in data space
* @return vector in scaled space
*/
- public double[] fastProjectDataToScaledSpace(NumberVector<?> data);
+ public double[] fastProjectDataToScaledSpace(NumberVector data);
/**
* Project a vector from scaled space to rendering space.
@@ -93,7 +93,7 @@ public interface Projection2D extends Projection {
* @param prototype Prototype to create vector from
* @return vector in data space
*/
- // public <V extends NumberVector<?>> V fastProjectRenderToDataSpace(double[] data, V prototype);
+ // public <V extends NumberVector> V fastProjectRenderToDataSpace(double[] data, V prototype);
/**
* Project a vector from rendering space to scaled space.
@@ -117,7 +117,7 @@ public interface Projection2D extends Projection {
* @param data vector in data space
* @return vector in rendering space
*/
- public double[] fastProjectRelativeDataToRenderSpace(NumberVector<?> data);
+ public double[] fastProjectRelativeDataToRenderSpace(NumberVector data);
/**
* Project a vector from scaled space to rendering space.
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projections/ProjectionParallel.java b/src/de/lmu/ifi/dbs/elki/visualization/projections/ProjectionParallel.java
index 576c3290..c3344726 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projections/ProjectionParallel.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projections/ProjectionParallel.java
@@ -166,7 +166,7 @@ public interface ProjectionParallel extends Projection {
* @param v Input vector
* @return Vector with reordering, inversions and scales applied.
*/
- public double[] fastProjectDataToRenderSpace(NumberVector<?> v);
+ public double[] fastProjectDataToRenderSpace(NumberVector v);
/**
* Project the value of a single axis to its display value
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projections/Simple1D.java b/src/de/lmu/ifi/dbs/elki/visualization/projections/Simple1D.java
index 97ac38cc..6a812bf9 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projections/Simple1D.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projections/Simple1D.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projections;
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
@@ -55,7 +55,7 @@ public class Simple1D extends AbstractSimpleProjection implements Projection1D {
}
@Override
- public double fastProjectDataToRenderSpace(NumberVector<?> data) {
+ public double fastProjectDataToRenderSpace(NumberVector data) {
return (scales[dnum].getScaled(data.doubleValue(dnum)) - 0.5) * SCALE;
}
@@ -70,7 +70,7 @@ public class Simple1D extends AbstractSimpleProjection implements Projection1D {
}
@Override
- public double fastProjectRelativeDataToRenderSpace(NumberVector<?> data) {
+ public double fastProjectRelativeDataToRenderSpace(NumberVector data) {
return (data.doubleValue(dnum) - 0.5) * SCALE;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projections/Simple2D.java b/src/de/lmu/ifi/dbs/elki/visualization/projections/Simple2D.java
index 9b27af5a..2d7033d2 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projections/Simple2D.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projections/Simple2D.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projections;
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
@@ -66,7 +66,7 @@ public class Simple2D extends AbstractSimpleProjection implements Projection2D {
}
@Override
- public double[] fastProjectDataToRenderSpace(NumberVector<?> data) {
+ public double[] fastProjectDataToRenderSpace(NumberVector data) {
double x = (scales[dim1].getScaled(data.doubleValue(dim1)) - 0.5) * SCALE;
double y = (scales[dim2].getScaled(data.doubleValue(dim2)) - 0.5) * -SCALE;
return new double[] { x, y };
@@ -83,7 +83,7 @@ public class Simple2D extends AbstractSimpleProjection implements Projection2D {
}
@Override
- public double[] fastProjectDataToScaledSpace(NumberVector<?> data) {
+ public double[] fastProjectDataToScaledSpace(NumberVector data) {
final int dim = data.getDimensionality();
double[] ds = new double[dim];
for(int d = 0; d < dim; d++) {
@@ -141,7 +141,7 @@ public class Simple2D extends AbstractSimpleProjection implements Projection2D {
}
@Override
- public double[] fastProjectRelativeDataToRenderSpace(NumberVector<?> data) {
+ public double[] fastProjectRelativeDataToRenderSpace(NumberVector data) {
double x = scales[dim1].getRelativeScaled(data.doubleValue(dim1)) * SCALE;
double y = scales[dim2].getRelativeScaled(data.doubleValue(dim2)) * -SCALE;
return new double[] { x, y };
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projections/SimpleParallel.java b/src/de/lmu/ifi/dbs/elki/visualization/projections/SimpleParallel.java
index 6b07895d..55c86d26 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projections/SimpleParallel.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projections/SimpleParallel.java
@@ -215,7 +215,7 @@ public class SimpleParallel extends BasicResult implements ProjectionParallel {
}
@Override
- public double[] fastProjectDataToRenderSpace(NumberVector<?> data) {
+ public double[] fastProjectDataToRenderSpace(NumberVector data) {
double[] v = new double[visDims];
for(int j = 0, o = 0; j < scales.length; j++) {
if(isDimHidden(j)) {
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramFactory.java
index 894bd264..fa4be47c 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projector;
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
@@ -66,9 +66,9 @@ public class HistogramFactory implements ProjectorFactory {
for(Relation<?> rel : rels) {
if(TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(rel.getDataTypeInformation())) {
@SuppressWarnings("unchecked")
- Relation<NumberVector<?>> vrel = (Relation<NumberVector<?>>) rel;
+ Relation<NumberVector> vrel = (Relation<NumberVector>) rel;
final int dim = RelationUtil.dimensionality(vrel);
- HistogramProjector<NumberVector<?>> proj = new HistogramProjector<>(vrel, Math.min(dim, maxdim));
+ HistogramProjector<NumberVector> proj = new HistogramProjector<>(vrel, Math.min(dim, maxdim));
baseResult.getHierarchy().add(vrel, proj);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java
index 3503692c..49025ec5 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projector;
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
@@ -50,7 +50,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.LabelVisualizatio
*
* @param <V> Vector type
*/
-public class HistogramProjector<V extends NumberVector<?>> extends AbstractHierarchicalResult implements Projector {
+public class HistogramProjector<V extends NumberVector> extends AbstractHierarchicalResult implements Projector {
/**
* Relation we project.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjector.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjector.java
index 832184f0..a3b4f4b5 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjector.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projector;
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,10 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderResult;
import de.lmu.ifi.dbs.elki.result.AbstractHierarchicalResult;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.VisualizerContext;
import de.lmu.ifi.dbs.elki.visualization.gui.overview.PlotItem;
@@ -41,24 +41,26 @@ import de.lmu.ifi.dbs.elki.visualization.projections.OPTICSProjection;
* Projection for OPTICS plots.
*
* @author Erich Schubert
+ *
+ * @param <E> Cluster order entry type
*/
-public class OPTICSProjector<D extends Distance<D>> extends AbstractHierarchicalResult implements Projector {
+public class OPTICSProjector<E extends ClusterOrderEntry<?>> extends AbstractHierarchicalResult implements Projector {
/**
* Cluster order result
*/
- private ClusterOrderResult<D> clusterOrder;
+ private ClusterOrderResult<E> clusterOrder;
/**
* OPTICS plot image
*/
- private OPTICSPlot<D> plot = null;
+ private OPTICSPlot<E> plot = null;
/**
* Constructor.
*
* @param co Cluster order
*/
- public OPTICSProjector(ClusterOrderResult<D> co) {
+ public OPTICSProjector(ClusterOrderResult<E> co) {
super();
this.clusterOrder = co;
}
@@ -77,7 +79,7 @@ public class OPTICSProjector<D extends Distance<D>> extends AbstractHierarchical
public Collection<PlotItem> arrange() {
List<PlotItem> col = new ArrayList<>(1);
List<VisualizationTask> tasks = ResultUtil.filterResults(this, VisualizationTask.class);
- if (tasks.size() > 0) {
+ if(tasks.size() > 0) {
final PlotItem it = new PlotItem(4., 1., new OPTICSProjection<>(this));
it.tasks = tasks;
col.add(it);
@@ -90,7 +92,7 @@ public class OPTICSProjector<D extends Distance<D>> extends AbstractHierarchical
*
* @return the cluster order
*/
- public ClusterOrderResult<D> getResult() {
+ public ClusterOrderResult<E> getResult() {
return clusterOrder;
}
@@ -100,7 +102,7 @@ public class OPTICSProjector<D extends Distance<D>> extends AbstractHierarchical
* @param context Context to use
* @return Plot
*/
- public OPTICSPlot<D> getOPTICSPlot(VisualizerContext context) {
+ public OPTICSPlot<E> getOPTICSPlot(VisualizerContext context) {
if(plot == null) {
plot = OPTICSPlot.plotForClusterOrder(clusterOrder, context);
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjectorFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjectorFactory.java
index 797c4031..155f0d07 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjectorFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjectorFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projector;
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,11 +25,12 @@ package de.lmu.ifi.dbs.elki.visualization.projector;
import java.util.Collection;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderResult;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.DoubleDistanceClusterOrderEntry;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
import de.lmu.ifi.dbs.elki.visualization.opticsplot.OPTICSPlot;
/**
@@ -49,11 +50,11 @@ public class OPTICSProjectorFactory implements ProjectorFactory {
@Override
public void processNewResult(HierarchicalResult baseResult, Result newResult) {
- Collection<ClusterOrderResult<?>> cos = ResultUtil.filterResults(newResult, ClusterOrderResult.class);
- for(ClusterOrderResult<?> co : cos) {
+ Collection<ClusterOrderResult<? extends ClusterOrderEntry<?>>> cos = ResultUtil.filterResults(newResult, ClusterOrderResult.class);
+ for(ClusterOrderResult<? extends ClusterOrderEntry<?>> co : cos) {
if(OPTICSPlot.canPlot(co)) {
@SuppressWarnings("unchecked")
- OPTICSProjector<?> proj = new OPTICSProjector<>((ClusterOrderResult<DoubleDistance>) co);
+ OPTICSProjector<?> proj = new OPTICSProjector<>((ClusterOrderResult<DoubleDistanceClusterOrderEntry>) co);
baseResult.getHierarchy().add(co, proj);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/ParallelPlotFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/ParallelPlotFactory.java
index e744ae5b..07a05ff0 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/ParallelPlotFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/ParallelPlotFactory.java
@@ -54,8 +54,8 @@ public class ParallelPlotFactory implements ProjectorFactory {
// TODO: multi-relational parallel plots
if(TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(rel.getDataTypeInformation())) {
@SuppressWarnings("unchecked")
- Relation<NumberVector<?>> vrel = (Relation<NumberVector<?>>) rel;
- ParallelPlotProjector<NumberVector<?>> proj = new ParallelPlotProjector<>(vrel);
+ Relation<NumberVector> vrel = (Relation<NumberVector>) rel;
+ ParallelPlotProjector<NumberVector> proj = new ParallelPlotProjector<>(vrel);
baseResult.getHierarchy().add(vrel, proj);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/ParallelPlotProjector.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/ParallelPlotProjector.java
index bc981924..31a86534 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/ParallelPlotProjector.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/ParallelPlotProjector.java
@@ -47,7 +47,7 @@ import de.lmu.ifi.dbs.elki.visualization.projections.SimpleParallel;
* @param <V> Vector type
*/
// TODO: support categorical features, and multiple relations too
-public class ParallelPlotProjector<V extends NumberVector<?>> extends AbstractHierarchicalResult implements Projector {
+public class ParallelPlotProjector<V extends NumberVector> extends AbstractHierarchicalResult implements Projector {
/**
* Relation we project.
*/
@@ -71,7 +71,7 @@ public class ParallelPlotProjector<V extends NumberVector<?>> extends AbstractHi
ScalesResult scales = ResultUtil.getScalesResult(rel);
ProjectionParallel proj = new SimpleParallel(scales.getScales());
- final double width = Math.ceil(Math.log(scales.getScales().length) / MathUtil.LOG2);
+ final double width = Math.ceil(MathUtil.log2(scales.getScales().length));
final PlotItem it = new PlotItem(width, 1., proj);
it.tasks = tasks;
col.add(it);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/Projector.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/Projector.java
index 8febb94b..a323b914 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/Projector.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/Projector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projector;
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/visualization/projector/ProjectorFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/ProjectorFactory.java
index 25a9ddc1..b5424442 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/ProjectorFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/ProjectorFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projector;
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.visualization.projector;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultProcessor;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* A projector is responsible for adding projections to the visualization by
@@ -36,7 +35,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
*
* @apiviz.has Projector
*/
-public interface ProjectorFactory extends ResultProcessor, Parameterizable {
+public interface ProjectorFactory extends ResultProcessor {
/**
* Add projections for the given result (tree) to the result tree.
*
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotFactory.java
index f1d61698..de41b85a 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projector;
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
@@ -74,9 +74,9 @@ public class ScatterPlotFactory implements ProjectorFactory {
for(Relation<?> rel : rels) {
if(TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(rel.getDataTypeInformation())) {
@SuppressWarnings("unchecked")
- Relation<NumberVector<?>> vrel = (Relation<NumberVector<?>>) rel;
+ Relation<NumberVector> vrel = (Relation<NumberVector>) rel;
final int dim = RelationUtil.dimensionality(vrel);
- ScatterPlotProjector<NumberVector<?>> proj = new ScatterPlotProjector<>(vrel, Math.min(maxdim, dim));
+ ScatterPlotProjector<NumberVector> proj = new ScatterPlotProjector<>(vrel, Math.min(maxdim, dim));
baseResult.getHierarchy().add(vrel, proj);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java
index 84035058..9c6c2bbe 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.projector;
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
@@ -52,7 +52,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.LabelVisualizatio
*
* @param <V> Vector type
*/
-public class ScatterPlotProjector<V extends NumberVector<?>> extends AbstractHierarchicalResult implements Projector {
+public class ScatterPlotProjector<V extends NumberVector> extends AbstractHierarchicalResult implements Projector {
/**
* Relation we project.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/savedialog/SVGSaveDialog.java b/src/de/lmu/ifi/dbs/elki/visualization/savedialog/SVGSaveDialog.java
index a12f4820..34501e78 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/savedialog/SVGSaveDialog.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/savedialog/SVGSaveDialog.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.savedialog;
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/visualization/savedialog/SaveOptionsPanel.java b/src/de/lmu/ifi/dbs/elki/visualization/savedialog/SaveOptionsPanel.java
index 913fdee2..ce65c449 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/savedialog/SaveOptionsPanel.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/savedialog/SaveOptionsPanel.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.savedialog;
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/visualization/style/ClassStylingPolicy.java b/src/de/lmu/ifi/dbs/elki/visualization/style/ClassStylingPolicy.java
index 0e60b051..6dd78b35 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/ClassStylingPolicy.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/ClassStylingPolicy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.style;
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/visualization/style/ClusterStylingPolicy.java b/src/de/lmu/ifi/dbs/elki/visualization/style/ClusterStylingPolicy.java
index cd2fd17b..dd3302d2 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/ClusterStylingPolicy.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/ClusterStylingPolicy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.style;
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/visualization/style/PropertiesBasedStyleLibrary.java b/src/de/lmu/ifi/dbs/elki/visualization/style/PropertiesBasedStyleLibrary.java
index d936a9d5..53071462 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/PropertiesBasedStyleLibrary.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/PropertiesBasedStyleLibrary.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.style;
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/visualization/style/SingleObjectsStylingPolicy.java b/src/de/lmu/ifi/dbs/elki/visualization/style/SingleObjectsStylingPolicy.java
index c367eb24..286893e1 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/SingleObjectsStylingPolicy.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/SingleObjectsStylingPolicy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.style;
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/visualization/style/StyleLibrary.java b/src/de/lmu/ifi/dbs/elki/visualization/style/StyleLibrary.java
index 6c7b841f..d31b216b 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/StyleLibrary.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/StyleLibrary.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.style;
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/visualization/style/StyleResult.java b/src/de/lmu/ifi/dbs/elki/visualization/style/StyleResult.java
index 231a1cd8..93704d0a 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/StyleResult.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/StyleResult.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.style;
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/visualization/style/StylingPolicy.java b/src/de/lmu/ifi/dbs/elki/visualization/style/StylingPolicy.java
index 98ed25e1..8834adae 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/StylingPolicy.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/StylingPolicy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.style;
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/visualization/style/lines/DashedLineStyleLibrary.java b/src/de/lmu/ifi/dbs/elki/visualization/style/lines/DashedLineStyleLibrary.java
index 35c47eb7..04d7f6d7 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/lines/DashedLineStyleLibrary.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/lines/DashedLineStyleLibrary.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.style.lines;
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/visualization/style/lines/LineStyleLibrary.java b/src/de/lmu/ifi/dbs/elki/visualization/style/lines/LineStyleLibrary.java
index 6c817778..7177e01a 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/lines/LineStyleLibrary.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/lines/LineStyleLibrary.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.style.lines;
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/visualization/style/lines/SolidLineStyleLibrary.java b/src/de/lmu/ifi/dbs/elki/visualization/style/lines/SolidLineStyleLibrary.java
index 340381a1..25964999 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/lines/SolidLineStyleLibrary.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/lines/SolidLineStyleLibrary.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.style.lines;
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/visualization/style/lines/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/style/lines/package-info.java
index ef9d9af7..b96f025c 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/lines/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/lines/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/visualization/style/marker/CircleMarkers.java b/src/de/lmu/ifi/dbs/elki/visualization/style/marker/CircleMarkers.java
index f78c72de..05df3834 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/marker/CircleMarkers.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/marker/CircleMarkers.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.style.marker;
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/visualization/style/marker/MarkerLibrary.java b/src/de/lmu/ifi/dbs/elki/visualization/style/marker/MarkerLibrary.java
index 75591c93..2d665af8 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/marker/MarkerLibrary.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/marker/MarkerLibrary.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.style.marker;
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/visualization/style/marker/MinimalMarkers.java b/src/de/lmu/ifi/dbs/elki/visualization/style/marker/MinimalMarkers.java
index 4111dbbc..5e455e5e 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/marker/MinimalMarkers.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/marker/MinimalMarkers.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.style.marker;
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/visualization/style/marker/PrettyMarkers.java b/src/de/lmu/ifi/dbs/elki/visualization/style/marker/PrettyMarkers.java
index d99d92a7..881a22a7 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/style/marker/PrettyMarkers.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/style/marker/PrettyMarkers.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.style.marker;
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/visualization/svg/SVGArrow.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGArrow.java
index cbae03e2..86ba3cfa 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGArrow.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGArrow.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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/visualization/svg/SVGButton.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGButton.java
index 9b69ab14..dbcb33fc 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGButton.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGButton.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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/visualization/svg/SVGCheckbox.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGCheckbox.java
index dc27b989..2e837ce5 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGCheckbox.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGCheckbox.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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/visualization/svg/SVGCloneVisible.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGCloneVisible.java
index 6397348c..0172b77b 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGCloneVisible.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGCloneVisible.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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/visualization/svg/SVGEffects.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGEffects.java
index 9382e0b6..d3e17abb 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGEffects.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGEffects.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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/visualization/svg/SVGHyperCube.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGHyperCube.java
index 64f5e9be..5ed7ca5a 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGHyperCube.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGHyperCube.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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 @@ public class SVGHyperCube {
* @param max Opposite corner
* @return path element
*/
- public static <V extends NumberVector<?>> Element drawFrame(SVGPlot svgp, Projection2D proj, V min, V max) {
+ public static <V extends NumberVector> Element drawFrame(SVGPlot svgp, Projection2D proj, V min, V max) {
SVGPath path = new SVGPath();
ArrayList<double[]> edges = getVisibleEdges(proj, min.getColumnVector().getArrayRef(), max.getColumnVector().getArrayRef());
double[] rv_min = proj.fastProjectDataToRenderSpace(min);
@@ -107,7 +107,7 @@ public class SVGHyperCube {
* @param max Opposite corner
* @return group element
*/
- public static <V extends NumberVector<?>> Element drawFilled(SVGPlot svgp, String cls, Projection2D proj, V min, V max) {
+ public static <V extends NumberVector> Element drawFilled(SVGPlot svgp, String cls, Projection2D proj, V min, V max) {
Element group = svgp.svgElement(SVGConstants.SVG_G_TAG);
ArrayList<double[]> edges = getVisibleEdges(proj, min.getColumnVector().getArrayRef(), max.getColumnVector().getArrayRef());
double[] rv_min = proj.fastProjectDataToRenderSpace(min);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGHyperSphere.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGHyperSphere.java
index 14acc5c3..2a4afa83 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGHyperSphere.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGHyperSphere.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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 java.util.BitSet;
import org.w3c.dom.Element;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.visualization.projections.Projection2D;
/**
@@ -56,7 +55,7 @@ public class SVGHyperSphere {
* @param radius radius
* @return path element
*/
- public static Element drawManhattan(SVGPlot svgp, Projection2D proj, NumberVector<?> mid, double radius) {
+ public static Element drawManhattan(SVGPlot svgp, Projection2D proj, NumberVector mid, double radius) {
final double[] v_mid = mid.getColumnVector().getArrayRef(); // a copy
final BitSet dims = proj.getVisibleDimensions2D();
@@ -101,7 +100,7 @@ public class SVGHyperSphere {
* @param radius radius
* @return path element
*/
- public static Element drawEuclidean(SVGPlot svgp, Projection2D proj, NumberVector<?> mid, double radius) {
+ public static Element drawEuclidean(SVGPlot svgp, Projection2D proj, NumberVector mid, double radius) {
double[] v_mid = mid.getColumnVector().getArrayRef(); // a copy
BitSet dims = proj.getVisibleDimensions2D();
@@ -152,7 +151,7 @@ public class SVGHyperSphere {
* @param p L_p value
* @return path element
*/
- public static Element drawLp(SVGPlot svgp, Projection2D proj, NumberVector<?> mid, double radius, double p) {
+ public static Element drawLp(SVGPlot svgp, Projection2D proj, NumberVector mid, double radius, double p) {
final double[] v_mid = mid.getColumnVector().getArrayRef();
final BitSet dims = proj.getVisibleDimensions2D();
@@ -260,15 +259,13 @@ public class SVGHyperSphere {
/**
* Wireframe "cross" hypersphere
*
- * @param <D> radius
* @param svgp SVG Plot
* @param proj Visualization projection
* @param mid mean vector
- * @param rad radius
+ * @param radius radius
* @return path element
*/
- public static <D extends NumberDistance<?, ?>> Element drawCross(SVGPlot svgp, Projection2D proj, NumberVector<?> mid, D rad) {
- final double radius = rad.doubleValue();
+ public static Element drawCross(SVGPlot svgp, Projection2D proj, NumberVector mid, double radius) {
final double[] v_mid = mid.getColumnVector().getArrayRef();
final BitSet dims = proj.getVisibleDimensions2D();
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGPath.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGPath.java
index 6937ab3e..4af270b5 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGPath.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGPath.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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/visualization/svg/SVGPlot.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGPlot.java
index 44ec906b..f87f2443 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGPlot.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGPlot.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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/visualization/svg/SVGScoreBar.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGScoreBar.java
index e421cafa..a481bf05 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGScoreBar.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGScoreBar.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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,8 +28,6 @@ import java.text.NumberFormat;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-
/**
* Draw a score bar. Essentially like a progress bar, left-to-right, displaying
* a relative score.
@@ -39,14 +37,9 @@ import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
// TODO: refactor to get a progress bar?
public class SVGScoreBar {
/**
- * Fill value
- */
- protected double fill = 0.0;
-
- /**
- * Total size
+ * Value, minimum and maximum values
*/
- protected double size = 1.0;
+ protected double val, min = 0., max = 1.;
/**
* Label (on the right)
@@ -68,12 +61,14 @@ public class SVGScoreBar {
/**
* Set the fill of the score bar.
*
- * @param fill Fill value
- * @param size Total size
+ * @param val Value
+ * @param min Minimum value
+ * @param max Maximum value
*/
- public void setFill(double fill, double size) {
- this.fill = fill;
- this.size = size;
+ public void setFill(double val, double min, double max) {
+ this.val = val;
+ this.min = min;
+ this.max = max;
}
/**
@@ -114,8 +109,8 @@ public class SVGScoreBar {
bar.setAttribute(SVGConstants.SVG_STROKE_WIDTH_ATTRIBUTE, String.valueOf(height * 0.01));
barchart.appendChild(bar);
- if(fill >= 0 && fill <= size + 1) {
- double fpos = (fill / size) * (width - (0.04 * height));
+ if(val >= min && val <= max && min < max) {
+ double fpos = (val - min) / (max - min) * (width - (0.04 * height));
Element chart = svgp.svgRect(x + 0.02 * height, y + 0.02 * height, fpos, height - 0.04 * height);
chart.setAttribute(SVGConstants.SVG_FILL_ATTRIBUTE, "#d4e4f1");
chart.setAttribute(SVGConstants.SVG_STROKE_ATTRIBUTE, "#a0a0a0");
@@ -125,7 +120,7 @@ public class SVGScoreBar {
// Draw the values:
if(format != null) {
- String num = Double.isNaN(fill) ? "NaN" : FormatUtil.format(fill, format);
+ String num = Double.isNaN(val) ? "NaN" : format.format(val);
Element lbl = svgp.svgText(x + 0.05 * width, y + 0.75 * height, num);
lbl.setAttribute(SVGConstants.SVG_STYLE_ATTRIBUTE, "font-size: " + 0.75 * height + "; font-weight: bold");
barchart.appendChild(lbl);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGSimpleLinearAxis.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGSimpleLinearAxis.java
index 3fd28d3d..a50ce8c5 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGSimpleLinearAxis.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGSimpleLinearAxis.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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/visualization/svg/SVGUtil.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGUtil.java
index 0e680e12..7749cd09 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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/visualization/svg/UpdateRunner.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/UpdateRunner.java
index edf40621..74d943ae 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/UpdateRunner.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/UpdateRunner.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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
@@ -125,9 +125,10 @@ public class UpdateRunner {
* @param newsync Update synchronizer
*/
public synchronized void synchronizeWith(UpdateSynchronizer newsync) {
- // LoggingUtil.warning("Synchronizing: " + sync + " " + newsync);
+ // LoggingUtil.warning("Synchronizing: " + sync + " " + newsync, new
+ // Throwable());
if(synchronizer == newsync) {
- LoggingUtil.warning("Double-synced to the same plot!");
+ LoggingUtil.warning("Double-synced to the same plot!", new Throwable());
return;
}
if(synchronizer != null) {
@@ -136,7 +137,6 @@ public class UpdateRunner {
}
synchronizer = newsync;
newsync.addUpdateRunner(this);
-
}
/**
@@ -147,12 +147,11 @@ public class UpdateRunner {
public synchronized void unsynchronizeWith(UpdateSynchronizer oldsync) {
if(synchronizer == null) {
LoggingUtil.warning("Warning: was not synchronized.");
+ return;
}
- else {
- if(synchronizer != oldsync) {
- LoggingUtil.warning("Warning: was synchronized differently!");
- return;
- }
+ if(synchronizer != oldsync) {
+ LoggingUtil.warning("Warning: was synchronized differently!");
+ return;
}
// LoggingUtil.warning("Unsynchronizing: " + sync + " " + oldsync);
synchronizer = null;
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/svg/UpdateSynchronizer.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/UpdateSynchronizer.java
index a91fb142..b0b45f2f 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/UpdateSynchronizer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/UpdateSynchronizer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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/visualization/svg/VoronoiDraw.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/VoronoiDraw.java
index e5824fba..9eb554bd 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/svg/VoronoiDraw.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/VoronoiDraw.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.visualization.svg;
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/visualization/visualizers/AbstractVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisFactory.java
index 320ecd4c..6e03a68e 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers;
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/visualization/visualizers/AbstractVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisualization.java
index cad9283e..921523b9 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers;
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/visualization/visualizers/StaticVisualizationInstance.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/StaticVisualizationInstance.java
index 8c7ad9a7..f5449582 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/StaticVisualizationInstance.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/StaticVisualizationInstance.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers;
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/visualization/visualizers/VisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisFactory.java
index c65a1c63..c166a8e9 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers;
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.visualization.visualizers;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultProcessor;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
/**
@@ -41,7 +40,7 @@ import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
* @apiviz.uses Visualization - - «create»
* @apiviz.uses VisualizationTask - - «create»
*/
-public interface VisFactory extends ResultProcessor, Parameterizable {
+public interface VisFactory extends ResultProcessor {
/**
* Add visualizers for the given result (tree) to the context.
*
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/Visualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/Visualization.java
index 5c1be0ab..5e211830 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/Visualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/Visualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers;
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/visualization/visualizers/VisualizerUtil.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisualizerUtil.java
index 947f5841..0416f87d 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisualizerUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisualizerUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers;
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/visualization/visualizers/histogram/AbstractHistogramVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/AbstractHistogramVisualization.java
index 8d3616ac..deb451bd 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/AbstractHistogramVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/AbstractHistogramVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.histogram;
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/visualization/visualizers/histogram/ColoredHistogramVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/ColoredHistogramVisualizer.java
index eb737a6d..b940da67 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/ColoredHistogramVisualizer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/ColoredHistogramVisualizer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.histogram;
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
@@ -142,7 +142,7 @@ public class ColoredHistogramVisualizer extends AbstractVisFactory {
*/
// FIXME: make non-static, react to database changes!
// FIXME: cache histogram instead of recomputing it.
- public class Instance<NV extends NumberVector<?>> extends AbstractHistogramVisualization {
+ public class Instance<NV extends NumberVector> extends AbstractHistogramVisualization {
/**
* Generic tag to indicate the type of element. Used in IDs, CSS-Classes
* etc.
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/AbstractOPTICSVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/AbstractOPTICSVisualization.java
index d734fc9e..3cb40170 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/AbstractOPTICSVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/AbstractOPTICSVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.optics;
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,7 @@ import java.util.List;
import org.apache.batik.util.SVGConstants;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.projections.OPTICSProjection;
import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary;
@@ -42,13 +41,13 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisualization;
*
* @apiviz.uses OPTICSProjection
*
- * @param <D>
+ * @param <E> Cluster order entry type
*/
-public abstract class AbstractOPTICSVisualization<D extends Distance<D>> extends AbstractVisualization {
+public abstract class AbstractOPTICSVisualization<E extends ClusterOrderEntry<?>> extends AbstractVisualization {
/**
* The plot
*/
- final protected OPTICSProjection<D> optics;
+ final protected OPTICSProjection<E> optics;
/**
* Width of plot (in display units)
@@ -87,7 +86,7 @@ public abstract class AbstractOPTICSVisualization<D extends Distance<D>> extends
*
* @return Cluster order
*/
- protected List<ClusterOrderEntry<D>> getClusterOrder() {
+ protected List<E> getClusterOrder() {
return optics.getResult().getClusterOrder();
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSClusterVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSClusterVisualization.java
index dd4462c9..bd0adfda 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSClusterVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSClusterVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.optics;
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,11 +30,10 @@ import java.util.Map;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.model.OPTICSModel;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
@@ -70,8 +69,7 @@ public class OPTICSClusterVisualization extends AbstractVisFactory {
private static final String NAME = "OPTICS Cluster Ranges";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public OPTICSClusterVisualization() {
super();
@@ -80,9 +78,9 @@ public class OPTICSClusterVisualization extends AbstractVisFactory {
@Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
Collection<OPTICSProjector<?>> ops = ResultUtil.filterResults(result, OPTICSProjector.class);
- for (OPTICSProjector<?> p : ops) {
+ for(OPTICSProjector<?> p : ops) {
final Clustering<OPTICSModel> ocl = findOPTICSClustering(baseResult);
- if (ocl != null) {
+ if(ocl != null) {
final VisualizationTask task = new VisualizationTask(NAME, ocl, null, this);
task.level = VisualizationTask.LEVEL_DATA;
baseResult.getHierarchy().add(p, task);
@@ -94,7 +92,7 @@ public class OPTICSClusterVisualization extends AbstractVisFactory {
@Override
public Visualization makeVisualization(VisualizationTask task) {
- return new Instance<DoubleDistance>(task);
+ return new Instance(task);
}
@Override
@@ -112,16 +110,17 @@ public class OPTICSClusterVisualization extends AbstractVisFactory {
@SuppressWarnings("unchecked")
protected static Clustering<OPTICSModel> findOPTICSClustering(Result result) {
Collection<Clustering<?>> cs = ResultUtil.filterResults(result, Clustering.class);
- for (Clustering<?> clus : cs) {
- if (clus.getToplevelClusters().size() == 0) {
+ for(Clustering<?> clus : cs) {
+ if(clus.getToplevelClusters().size() == 0) {
continue;
}
try {
Cluster<?> firstcluster = clus.getToplevelClusters().iterator().next();
- if (firstcluster.getModel() instanceof OPTICSModel) {
+ if(firstcluster.getModel() instanceof OPTICSModel) {
return (Clustering<OPTICSModel>) clus;
}
- } catch (Exception e) {
+ }
+ catch(Exception e) {
// Empty clustering? Shouldn't happen.
LOG.warning("Clustering with no cluster detected.", e);
}
@@ -135,10 +134,8 @@ public class OPTICSClusterVisualization extends AbstractVisFactory {
* @author Erich Schubert
*
* @apiviz.uses Clustering oneway - - «visualizes»
- *
- * @param <D> Distance type (actually unused)
*/
- public class Instance<D extends Distance<D>> extends AbstractOPTICSVisualization<D> {
+ public class Instance extends AbstractOPTICSVisualization<ClusterOrderEntry<?>> {
/**
* CSS class for markers
*/
@@ -169,7 +166,7 @@ public class OPTICSClusterVisualization extends AbstractVisFactory {
ColorLibrary colors = context.getStyleResult().getStyleLibrary().getColorSet(StyleLibrary.PLOT);
HashMap<Cluster<?>, String> colormap = new HashMap<>();
int cnum = 0;
- for (Cluster<?> c : clus.getAllClusters()) {
+ for(Cluster<?> c : clus.getAllClusters()) {
colormap.put(c, colors.getColor(cnum));
cnum++;
}
@@ -186,7 +183,7 @@ public class OPTICSClusterVisualization extends AbstractVisFactory {
private void drawClusters(Clustering<OPTICSModel> clustering, Hierarchy.Iter<Cluster<OPTICSModel>> clusters, int depth, Map<Cluster<?>, String> colormap) {
final double scale = StyleLibrary.SCALE;
- for (; clusters.valid(); clusters.advance()) {
+ for(; clusters.valid(); clusters.advance()) {
Cluster<OPTICSModel> cluster = clusters.get();
try {
OPTICSModel model = cluster.getModel();
@@ -196,16 +193,17 @@ public class OPTICSClusterVisualization extends AbstractVisFactory {
Element e = svgp.svgLine(x1, y, x2, y);
SVGUtil.addCSSClass(e, CSS_BRACKET);
String color = colormap.get(cluster);
- if (color != null) {
+ if(color != null) {
SVGUtil.setAtt(e, SVGConstants.SVG_STYLE_ATTRIBUTE, SVGConstants.CSS_STROKE_PROPERTY + ":" + color);
}
layer.appendChild(e);
- } catch (ClassCastException e) {
+ }
+ catch(ClassCastException e) {
LOG.warning("Expected OPTICSModel, got: " + cluster.getModel().getClass().getSimpleName());
}
// Descend
final Hierarchy.Iter<Cluster<OPTICSModel>> children = clustering.getClusterHierarchy().iterChildren(cluster);
- if (children != null) {
+ if(children != null) {
drawClusters(clustering, children, depth + 1, colormap);
}
}
@@ -216,7 +214,7 @@ public class OPTICSClusterVisualization extends AbstractVisFactory {
*/
private void addCSSClasses() {
// Class for the markers
- if (!svgp.getCSSClassManager().contains(CSS_BRACKET)) {
+ if(!svgp.getCSSClassManager().contains(CSS_BRACKET)) {
final CSSClass cls = new CSSClass(this, CSS_BRACKET);
final StyleLibrary style = context.getStyleResult().getStyleLibrary();
cls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, style.getColor(StyleLibrary.PLOT));
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotCutVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotCutVisualization.java
index e53c4c9d..a56c83d2 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotCutVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotCutVisualization.java
@@ -31,14 +31,14 @@ import org.w3c.dom.Element;
import org.w3c.dom.events.Event;
import org.w3c.dom.svg.SVGPoint;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderResult;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.DoubleDistanceClusterOrderEntry;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.model.Model;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.batikutil.DragableArea;
@@ -76,7 +76,7 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory {
@Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
Collection<OPTICSProjector<?>> ops = ResultUtil.filterResults(result, OPTICSProjector.class);
- for (OPTICSProjector<?> p : ops) {
+ for(OPTICSProjector<?> p : ops) {
final VisualizationTask task = new VisualizationTask(NAME, p, null, this);
task.level = VisualizationTask.LEVEL_INTERACTIVE;
baseResult.getHierarchy().add(p, task);
@@ -85,7 +85,7 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory {
@Override
public Visualization makeVisualization(VisualizationTask task) {
- return new Instance<DoubleDistance>(task);
+ return new Instance<DoubleDistanceClusterOrderEntry>(task);
}
@Override
@@ -100,9 +100,9 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory {
* @author Heidi Kolb
* @author Erich Schubert
*
- * @param <D> distance type
+ * @param <E> cluster order entry type
*/
- public class Instance<D extends Distance<D>> extends AbstractOPTICSVisualization<D> implements DragableArea.DragListener {
+ public class Instance<E extends ClusterOrderEntry<?>> extends AbstractOPTICSVisualization<E> implements DragableArea.DragListener {
/**
* CSS-Styles
*/
@@ -154,43 +154,46 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory {
@Override
protected void incrementalRedraw() {
- if (layer == null) {
+ if(layer == null) {
makeLayerElement();
addCSSClasses();
}
// TODO make the number of digits configurable
- final String label = (epsilon > 0.0) ? FormatUtil.format(epsilon, 4) : "";
+ final String label = (epsilon > 0.0) ? FormatUtil.NF4.format(epsilon) : "";
// compute absolute y-value of bar
final double yAct = plotheight - getYFromEpsilon(epsilon);
- if (elemText == null) {
+ if(elemText == null) {
elemText = svgp.svgText(StyleLibrary.SCALE * 1.05, yAct, label);
SVGUtil.setAtt(elemText, SVGConstants.SVG_CLASS_ATTRIBUTE, CSS_EPSILON);
layer.appendChild(elemText);
- } else {
+ }
+ else {
elemText.setTextContent(label);
SVGUtil.setAtt(elemText, SVGConstants.SVG_Y_ATTRIBUTE, yAct);
}
// line and handle
- if (elementLine == null) {
+ if(elementLine == null) {
elementLine = svgp.svgLine(0, yAct, StyleLibrary.SCALE * 1.04, yAct);
SVGUtil.addCSSClass(elementLine, CSS_LINE);
layer.appendChild(elementLine);
- } else {
+ }
+ else {
SVGUtil.setAtt(elementLine, SVG12Constants.SVG_Y1_ATTRIBUTE, yAct);
SVGUtil.setAtt(elementLine, SVG12Constants.SVG_Y2_ATTRIBUTE, yAct);
}
- if (elementPoint == null) {
+ if(elementPoint == null) {
elementPoint = svgp.svgCircle(StyleLibrary.SCALE * 1.04, yAct, StyleLibrary.SCALE * 0.004);
SVGUtil.addCSSClass(elementPoint, CSS_LINE);
layer.appendChild(elementPoint);
- } else {
+ }
+ else {
SVGUtil.setAtt(elementPoint, SVG12Constants.SVG_CY_ATTRIBUTE, yAct);
}
- if (eventarea == null) {
+ if(eventarea == null) {
eventarea = new DragableArea(svgp, StyleLibrary.SCALE, 0, StyleLibrary.SCALE * 0.1, plotheight, this);
layer.appendChild(eventarea.getElement());
}
@@ -209,10 +212,10 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory {
* @return epsilon
*/
protected double getEpsilonFromY(double y) {
- if (y < 0) {
+ if(y < 0) {
y = 0;
}
- if (y > plotheight) {
+ if(y > plotheight) {
y = plotheight;
}
return optics.getOPTICSPlot(context).getScale().getUnscaled(y / plotheight);
@@ -226,10 +229,10 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory {
*/
protected double getYFromEpsilon(double epsilon) {
double y = optics.getOPTICSPlot(context).getScale().getScaled(epsilon) * plotheight;
- if (y < 0) {
+ if(y < 0) {
y = 0;
}
- if (y > plotheight) {
+ if(y > plotheight) {
y = plotheight;
}
return y;
@@ -245,7 +248,7 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory {
@Override
public boolean duringDrag(SVGPoint start, SVGPoint end, Event evt, boolean inside) {
- if (inside) {
+ if(inside) {
epsilon = getEpsilonFromY(plotheight - end.getY());
}
// opvis.unsetEpsilonExcept(this);
@@ -255,12 +258,12 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory {
@Override
public boolean endDrag(SVGPoint start, SVGPoint end, Event evt, boolean inside) {
- if (inside) {
+ if(inside) {
epsilon = getEpsilonFromY(plotheight - end.getY());
// opvis.unsetEpsilonExcept(this);
// FIXME: replace an existing optics cut result!
- final ClusterOrderResult<D> order = optics.getResult();
+ final ClusterOrderResult<E> order = optics.getResult();
Clustering<Model> cl = OPTICSCut.makeOPTICSCut(order, optics.getOPTICSPlot(context).getDistanceAdapter(), epsilon);
order.addChildResult(cl);
}
@@ -281,7 +284,7 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory {
private void addCSSClasses() {
// Class for the epsilon-value
final StyleLibrary style = context.getStyleResult().getStyleLibrary();
- if (!svgp.getCSSClassManager().contains(CSS_EPSILON)) {
+ if(!svgp.getCSSClassManager().contains(CSS_EPSILON)) {
final CSSClass label = new CSSClass(svgp, CSS_EPSILON);
label.setStatement(SVGConstants.CSS_FILL_PROPERTY, style.getTextColor(StyleLibrary.AXIS_LABEL));
label.setStatement(SVGConstants.CSS_FONT_FAMILY_PROPERTY, style.getFontFamily(StyleLibrary.AXIS_LABEL));
@@ -289,7 +292,7 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory {
svgp.addCSSClassOrLogError(label);
}
// Class for the epsilon cut line
- if (!svgp.getCSSClassManager().contains(CSS_LINE)) {
+ if(!svgp.getCSSClassManager().contains(CSS_LINE)) {
final CSSClass lcls = new CSSClass(svgp, CSS_LINE);
lcls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, style.getColor(StyleLibrary.PLOT));
lcls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, 0.5 * style.getLineWidth(StyleLibrary.PLOT));
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotSelectionVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotSelectionVisualization.java
index bd2d0946..9149a590 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotSelectionVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotSelectionVisualization.java
@@ -32,19 +32,17 @@ import org.w3c.dom.Element;
import org.w3c.dom.events.Event;
import org.w3c.dom.svg.SVGPoint;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
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.HashSetModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.result.DBIDSelection;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.SelectionResult;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.batikutil.DragableArea;
import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
@@ -83,8 +81,7 @@ public class OPTICSPlotSelectionVisualization extends AbstractVisFactory {
}
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public OPTICSPlotSelectionVisualization() {
super();
@@ -102,7 +99,7 @@ public class OPTICSPlotSelectionVisualization extends AbstractVisFactory {
@Override
public Visualization makeVisualization(VisualizationTask task) {
- return new Instance<DoubleDistance>(task);
+ return new Instance(task);
}
@Override
@@ -118,10 +115,8 @@ public class OPTICSPlotSelectionVisualization extends AbstractVisFactory {
* @author Erich Schubert
*
* @apiviz.uses DBIDSelection oneway - 1 visualizes
- *
- * @param <D> distance type
*/
- public class Instance<D extends Distance<D>> extends AbstractOPTICSVisualization<D> implements DragableArea.DragListener {
+ public class Instance extends AbstractOPTICSVisualization<ClusterOrderEntry<?>> implements DragableArea.DragListener {
/**
* CSS class for markers
*/
@@ -172,7 +167,7 @@ public class OPTICSPlotSelectionVisualization extends AbstractVisFactory {
* Add marker for the selected IDs to mtag
*/
public void addMarker() {
- List<ClusterOrderEntry<D>> order = getClusterOrder();
+ List<? extends ClusterOrderEntry<?>> order = getClusterOrder();
// TODO: replace mtag!
DBIDSelection selContext = context.getSelection();
if(selContext != null) {
@@ -218,7 +213,7 @@ public class OPTICSPlotSelectionVisualization extends AbstractVisFactory {
@Override
public boolean startDrag(SVGPoint startPoint, Event evt) {
- List<ClusterOrderEntry<D>> order = getClusterOrder();
+ List<? extends ClusterOrderEntry<?>> order = getClusterOrder();
int mouseActIndex = getSelectedIndex(order, startPoint);
if(mouseActIndex >= 0 && mouseActIndex < order.size()) {
double width = plotwidth / order.size();
@@ -233,7 +228,7 @@ public class OPTICSPlotSelectionVisualization extends AbstractVisFactory {
@Override
public boolean duringDrag(SVGPoint startPoint, SVGPoint dragPoint, Event evt, boolean inside) {
- List<ClusterOrderEntry<D>> order = getClusterOrder();
+ List<? extends ClusterOrderEntry<?>> order = getClusterOrder();
int mouseDownIndex = getSelectedIndex(order, startPoint);
int mouseActIndex = getSelectedIndex(order, dragPoint);
final int begin = Math.max(Math.min(mouseDownIndex, mouseActIndex), 0);
@@ -250,7 +245,7 @@ public class OPTICSPlotSelectionVisualization extends AbstractVisFactory {
@Override
public boolean endDrag(SVGPoint startPoint, SVGPoint dragPoint, Event evt, boolean inside) {
- List<ClusterOrderEntry<D>> order = getClusterOrder();
+ List<? extends ClusterOrderEntry<?>> order = getClusterOrder();
int mouseDownIndex = getSelectedIndex(order, startPoint);
int mouseActIndex = getSelectedIndex(order, dragPoint);
Mode mode = getInputMode(evt);
@@ -291,7 +286,7 @@ public class OPTICSPlotSelectionVisualization extends AbstractVisFactory {
* @param cPt clicked point
* @return Index of the object
*/
- private int getSelectedIndex(List<ClusterOrderEntry<D>> order, SVGPoint cPt) {
+ private int getSelectedIndex(List<? extends ClusterOrderEntry<?>> order, SVGPoint cPt) {
int mouseActIndex = (int) ((cPt.getX() / plotwidth) * order.size());
return mouseActIndex;
}
@@ -304,7 +299,7 @@ public class OPTICSPlotSelectionVisualization extends AbstractVisFactory {
* @param end last index to select
*/
protected void updateSelection(Mode mode, int begin, int end) {
- List<ClusterOrderEntry<D>> order = getClusterOrder();
+ List<? extends ClusterOrderEntry<?>> order = getClusterOrder();
if(begin < 0 || begin > end || end >= order.size()) {
LOG.warning("Invalid range in updateSelection: " + begin + " .. " + end);
return;
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotVisualizer.java
index 6a834cb8..430f918a 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotVisualizer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotVisualizer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.optics;
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,8 +28,7 @@ import java.util.Collection;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
@@ -59,8 +58,7 @@ public class OPTICSPlotVisualizer extends AbstractVisFactory {
private static final String NAME = "OPTICS Plot";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public OPTICSPlotVisualizer() {
super();
@@ -79,7 +77,7 @@ public class OPTICSPlotVisualizer extends AbstractVisFactory {
@Override
public Visualization makeVisualization(VisualizationTask task) {
- return new Instance<DoubleDistance>(task);
+ return new Instance(task);
}
@Override
@@ -92,10 +90,8 @@ public class OPTICSPlotVisualizer extends AbstractVisFactory {
* Instance.
*
* @author Erich Schubert
- *
- * @param <D> Distance type
*/
- public class Instance<D extends Distance<D>> extends AbstractOPTICSVisualization<D> {
+ public class Instance extends AbstractOPTICSVisualization<ClusterOrderEntry<?>> {
/**
* Constructor.
*
@@ -110,7 +106,7 @@ public class OPTICSPlotVisualizer extends AbstractVisFactory {
makeLayerElement();
// addCSSClasses();
- OPTICSPlot<D> opticsplot = optics.getOPTICSPlot(context);
+ OPTICSPlot<?> opticsplot = optics.getOPTICSPlot(context);
String ploturi = opticsplot.getSVGPlotURI();
Element itag = svgp.svgElement(SVGConstants.SVG_IMAGE_TAG);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSSteepAreaVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSSteepAreaVisualization.java
index d587b554..b557f493 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSSteepAreaVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSSteepAreaVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.optics;
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 java.util.List;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICSXi;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICSXi.SteepAreaResult;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderResult;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.DoubleDistanceClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.OPTICSXi;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.OPTICSXi.SteepAreaResult;
import de.lmu.ifi.dbs.elki.math.scales.LinearScale;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.SelectionResult;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
@@ -67,8 +66,7 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory {
private static final String NAME = "OPTICS Steep Areas";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public OPTICSSteepAreaVisualization() {
super();
@@ -77,9 +75,9 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory {
@Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
Collection<OPTICSProjector<?>> ops = ResultUtil.filterResults(result, OPTICSProjector.class);
- for (OPTICSProjector<?> p : ops) {
+ for(OPTICSProjector<?> p : ops) {
final SteepAreaResult steep = findSteepAreaResult(p.getResult());
- if (steep != null) {
+ if(steep != null) {
final VisualizationTask task = new VisualizationTask(NAME, p, null, this);
task.level = VisualizationTask.LEVEL_DATA + 1;
task.initDefaultVisibility(false);
@@ -91,7 +89,7 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory {
@Override
public Visualization makeVisualization(VisualizationTask task) {
- return new Instance<DoubleDistance>(task);
+ return new Instance<DoubleDistanceClusterOrderEntry>(task);
}
@Override
@@ -107,8 +105,8 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory {
* @return OPTICS clustering
*/
protected static OPTICSXi.SteepAreaResult findSteepAreaResult(ClusterOrderResult<?> co) {
- for (Hierarchy.Iter<Result> r = co.getHierarchy().iterChildren(co); r.valid(); r.advance()) {
- if (OPTICSXi.SteepAreaResult.class.isInstance(r.get())) {
+ for(Hierarchy.Iter<Result> r = co.getHierarchy().iterChildren(co); r.valid(); r.advance()) {
+ if(OPTICSXi.SteepAreaResult.class.isInstance(r.get())) {
return (OPTICSXi.SteepAreaResult) r.get();
}
}
@@ -121,9 +119,9 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory {
* @author Erich Schubert
*
* @apiviz.uses
- * de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICSXi.SteepAreaResult
+ * de.lmu.ifi.dbs.elki.algorithm.clustering.optics.OPTICSXi.SteepAreaResult
*/
- public class Instance<D extends Distance<D>> extends AbstractOPTICSVisualization<D> {
+ public class Instance<E extends ClusterOrderEntry<?>> extends AbstractOPTICSVisualization<E> {
/**
* CSS class for markers
*/
@@ -156,12 +154,12 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory {
makeLayerElement();
addCSSClasses();
- final OPTICSPlot<D> opticsplot = optics.getOPTICSPlot(context);
- final List<ClusterOrderEntry<D>> co = getClusterOrder();
- final OPTICSDistanceAdapter<D> adapter = opticsplot.getDistanceAdapter();
+ final OPTICSPlot<E> opticsplot = optics.getOPTICSPlot(context);
+ final List<E> co = getClusterOrder();
+ final OPTICSDistanceAdapter<E> adapter = opticsplot.getDistanceAdapter();
final LinearScale scale = opticsplot.getScale();
- for (OPTICSXi.SteepArea area : areas) {
+ for(OPTICSXi.SteepArea area : areas) {
final int st = area.getStartIndex();
final int en = area.getEndIndex();
// Note: make sure we are using doubles!
@@ -172,9 +170,10 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory {
final double y1 = (!Double.isInfinite(d1) && !Double.isNaN(d1)) ? (1. - scale.getScaled(d1)) : 0.;
final double y2 = (!Double.isInfinite(d2) && !Double.isNaN(d2)) ? (1. - scale.getScaled(d2)) : 0.;
Element e = svgp.svgLine(plotwidth * x1, plotheight * y1, plotwidth * x2, plotheight * y2);
- if (area instanceof OPTICSXi.SteepDownArea) {
+ if(area instanceof OPTICSXi.SteepDownArea) {
SVGUtil.addCSSClass(e, CSS_STEEP_DOWN);
- } else {
+ }
+ else {
SVGUtil.addCSSClass(e, CSS_STEEP_UP);
}
layer.appendChild(e);
@@ -187,10 +186,10 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory {
private void addCSSClasses() {
// Class for the markers
final StyleLibrary style = context.getStyleResult().getStyleLibrary();
- if (!svgp.getCSSClassManager().contains(CSS_STEEP_DOWN)) {
+ if(!svgp.getCSSClassManager().contains(CSS_STEEP_DOWN)) {
final CSSClass cls = new CSSClass(this, CSS_STEEP_DOWN);
Color color = SVGUtil.stringToColor(style.getColor(StyleLibrary.PLOT));
- if (color == null) {
+ if(color == null) {
color = Color.BLACK;
}
color = new Color((int) (color.getRed() * 0.8), (int) (color.getGreen() * 0.8 + 0.2 * 256.), (int) (color.getBlue() * 0.8));
@@ -198,10 +197,10 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory {
cls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, style.getLineWidth(StyleLibrary.PLOT));
svgp.addCSSClassOrLogError(cls);
}
- if (!svgp.getCSSClassManager().contains(CSS_STEEP_UP)) {
+ if(!svgp.getCSSClassManager().contains(CSS_STEEP_UP)) {
final CSSClass cls = new CSSClass(this, CSS_STEEP_UP);
Color color = SVGUtil.stringToColor(style.getColor(StyleLibrary.PLOT));
- if (color == null) {
+ if(color == null) {
color = Color.BLACK;
}
color = new Color((int) (color.getRed() * 0.8 + 0.2 * 256.), (int) (color.getGreen() * 0.8), (int) (color.getBlue() * 0.8));
@@ -213,7 +212,7 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory {
@Override
public void resultChanged(Result current) {
- if (current instanceof SelectionResult) {
+ if(current instanceof SelectionResult) {
synchronizedRedraw();
return;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/CircleSegmentsVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/CircleSegmentsVisualizer.java
index ff281a35..3db1b6ac 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/CircleSegmentsVisualizer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/CircleSegmentsVisualizer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.pairsegments;
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/visualization/visualizers/pairsegments/SegmentsStylingPolicy.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/SegmentsStylingPolicy.java
index 4dc35180..1b0a3eda 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/SegmentsStylingPolicy.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/SegmentsStylingPolicy.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.pairsegments;
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/visualization/visualizers/pairsegments/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/package-info.java
index 967ed347..adbf42bb 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/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/visualization/visualizers/parallel/AbstractParallelVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AbstractParallelVisualization.java
index a2039126..0847dcdb 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AbstractParallelVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AbstractParallelVisualization.java
@@ -44,7 +44,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisualization;
*
* @param <NV> Vector type in relation
*/
-public abstract class AbstractParallelVisualization<NV extends NumberVector<?>> extends AbstractVisualization {
+public abstract class AbstractParallelVisualization<NV extends NumberVector> extends AbstractVisualization {
/**
* The current projection
*/
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AxisReorderVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AxisReorderVisualization.java
index 6d77f592..011914ee 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AxisReorderVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AxisReorderVisualization.java
@@ -90,7 +90,7 @@ public class AxisReorderVisualization extends AbstractVisFactory {
* @author Robert Rödler
* @author Erich Schubert
*/
- public class Instance extends AbstractParallelVisualization<NumberVector<?>> {
+ public class Instance extends AbstractParallelVisualization<NumberVector> {
/**
* Generic tags to indicate the type of element. Used in IDs, CSS-Classes
* etc.
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AxisVisibilityVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AxisVisibilityVisualization.java
index 3c78120a..659a5e72 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AxisVisibilityVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AxisVisibilityVisualization.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.parallel;
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
@@ -89,7 +89,7 @@ public class AxisVisibilityVisualization extends AbstractVisFactory {
* @author Robert Rödler
* @author Erich Schubert
*/
- public class Instance extends AbstractParallelVisualization<NumberVector<?>> {
+ public class Instance extends AbstractParallelVisualization<NumberVector> {
/**
* Generic tags to indicate the type of element. Used in IDs, CSS-Classes
* etc.
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/LineVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/LineVisualization.java
index 1290372f..77d8a80b 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/LineVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/LineVisualization.java
@@ -94,7 +94,7 @@ public class LineVisualization extends AbstractVisFactory {
*
* @author Robert Rödler
*/
- public class Instance extends AbstractParallelVisualization<NumberVector<?>> implements DataStoreListener {
+ public class Instance extends AbstractParallelVisualization<NumberVector> implements DataStoreListener {
/**
* Generic tags to indicate the type of element. Used in IDs, CSS-Classes
* etc.
@@ -184,26 +184,22 @@ public class LineVisualization extends AbstractVisFactory {
private Element drawLine(DBIDRef iter) {
SVGPath path = new SVGPath();
double[] yPos = proj.fastProjectDataToRenderSpace(relation.get(iter));
- boolean draw = false, drawprev = false, drawn = false;
+ boolean drawn = false;
+ int valid = 0; /* run length of valid values */
for(int i = 0; i < yPos.length; i++) {
// NaN handling:
if(yPos[i] != yPos[i]) {
- draw = false;
- drawprev = false;
+ valid = 0;
continue;
}
- if(draw) {
- if(drawprev) {
+ ++valid;
+ if(valid > 1) {
+ if(valid == 2) {
path.moveTo(getVisibleAxisX(i - 1), yPos[i - 1]);
- drawprev = false;
}
path.lineTo(getVisibleAxisX(i), yPos[i]);
drawn = true;
}
- else {
- drawprev = true;
- }
- draw = true;
}
if(!drawn) {
return null; // Not enough data.
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/ParallelAxisVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/ParallelAxisVisualization.java
index 00ef60ed..f3a0b9b1 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/ParallelAxisVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/ParallelAxisVisualization.java
@@ -97,7 +97,7 @@ public class ParallelAxisVisualization extends AbstractVisFactory {
* @apiviz.uses SVGSimpleLinearAxis
*/
// TODO: split into interactive / non-interactive parts?
- public class Instance extends AbstractParallelVisualization<NumberVector<?>> {
+ public class Instance extends AbstractParallelVisualization<NumberVector> {
/**
* Axis label class.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterOutlineVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterOutlineVisualization.java
index 10aa6309..b155005e 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterOutlineVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterOutlineVisualization.java
@@ -40,18 +40,26 @@ import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
+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.DoubleParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.colors.ColorLibrary;
import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
import de.lmu.ifi.dbs.elki.visualization.projector.ParallelPlotProjector;
+import de.lmu.ifi.dbs.elki.visualization.style.ClusterStylingPolicy;
import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary;
+import de.lmu.ifi.dbs.elki.visualization.style.StyleResult;
+import de.lmu.ifi.dbs.elki.visualization.style.StylingPolicy;
import de.lmu.ifi.dbs.elki.visualization.svg.SVGPath;
import de.lmu.ifi.dbs.elki.visualization.svg.SVGPlot;
import de.lmu.ifi.dbs.elki.visualization.svg.SVGUtil;
import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisFactory;
import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization;
import de.lmu.ifi.dbs.elki.visualization.visualizers.parallel.AbstractParallelVisualization;
+import de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.cluster.ClusterHullVisualization;
/**
* Generates a SVG-Element that visualizes the area covered by a cluster.
@@ -66,45 +74,41 @@ public class ClusterOutlineVisualization extends AbstractVisFactory {
/**
* A short name characterizing this Visualizer.
*/
- public static final String NAME = "Parallel Cluster Outline";
+ private static final String NAME = "Cluster Hull (Parallel Coordinates)";
/**
- * Currently unused option to enable/disable rounding
+ * Settings
*/
- public static final OptionID ROUNDED_ID = new OptionID("parallel.clusteroutline.rounded", "Draw lines rounded");
+ Parameterizer settings;
/**
- * Currently, always enabled.
- */
- private boolean rounded = true;
-
- /**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
+ *
+ * @param settings Settings
*/
- public ClusterOutlineVisualization() {
+ public ClusterOutlineVisualization(Parameterizer settings) {
super();
+ this.settings = settings;
}
@Override
public Visualization makeVisualization(VisualizationTask task) {
- return new Instance(task, rounded);
+ return new Instance(task);
}
@Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- // Find clusterings we can visualize:
- Collection<Clustering<?>> clusterings = ResultUtil.filterResults(result, Clustering.class);
- for(Clustering<?> c : clusterings) {
- if(c.getAllClusters().size() > 0) {
- Collection<ParallelPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ParallelPlotProjector.class);
- for(ParallelPlotProjector<?> p : ps) {
- final VisualizationTask task = new VisualizationTask(NAME, c, p.getRelation(), this);
- task.level = VisualizationTask.LEVEL_DATA - 1;
- task.initDefaultVisibility(false);
- baseResult.getHierarchy().add(c, task);
- baseResult.getHierarchy().add(p, task);
- }
+ // We attach ourselves to the style library, not the clustering, so there is
+ // only one hull.
+ Collection<StyleResult> styleres = ResultUtil.filterResults(result, StyleResult.class);
+ for(StyleResult s : styleres) {
+ Collection<ParallelPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ParallelPlotProjector.class);
+ for(ParallelPlotProjector<?> p : ps) {
+ final VisualizationTask task = new VisualizationTask(NAME, s, p.getRelation(), this);
+ task.level = VisualizationTask.LEVEL_DATA - 1;
+ task.initDefaultVisibility(false);
+ baseResult.getHierarchy().add(s, task);
+ baseResult.getHierarchy().add(p, task);
}
}
}
@@ -121,7 +125,7 @@ public class ClusterOutlineVisualization extends AbstractVisFactory {
* @author Robert Rödler
* @author Erich Schubert
*/
- public class Instance extends AbstractParallelVisualization<NumberVector<?>> implements DataStoreListener {
+ public class Instance extends AbstractParallelVisualization<NumberVector> implements DataStoreListener {
/**
* Generic tags to indicate the type of element. Used in IDs, CSS-Classes
* etc.
@@ -131,22 +135,16 @@ public class ClusterOutlineVisualization extends AbstractVisFactory {
/**
* The result we visualize
*/
- private Clustering<Model> clustering;
-
- /**
- * Flag for using rounded shapes
- */
- boolean rounded = true;
+ private StyleResult style;
/**
* Constructor.
*
* @param task VisualizationTask
*/
- public Instance(VisualizationTask task, boolean rounded) {
+ public Instance(VisualizationTask task) {
super(task);
- this.clustering = task.getResult();
- this.rounded = rounded;
+ this.style = task.getResult();
context.addDataStoreListener(this);
context.addResultListener(this);
incrementalRedraw();
@@ -161,17 +159,27 @@ public class ClusterOutlineVisualization extends AbstractVisFactory {
@Override
protected void redraw() {
- addCSSClasses(svgp);
+ final StylingPolicy spol = style.getStylingPolicy();
+ if(!(spol instanceof ClusterStylingPolicy)) {
+ return;
+ }
+ final ClusterStylingPolicy cpol = (ClusterStylingPolicy) spol;
+ @SuppressWarnings("unchecked")
+ Clustering<Model> clustering = (Clustering<Model>) cpol.getClustering();
+
int dim = proj.getVisibleDimensions();
DoubleMinMax[] mms = DoubleMinMax.newArray(dim);
DoubleMinMax[] midmm = DoubleMinMax.newArray(dim - 1);
+ // Heuristic value for transparency:
+ double baseopacity = .5;
+
Iterator<Cluster<Model>> ci = clustering.getAllClusters().iterator();
for(int cnum = 0; cnum < clustering.getAllClusters().size(); cnum++) {
Cluster<?> clus = ci.next();
final DBIDs ids = clus.getIDs();
- if (ids.size() < 1) {
+ if(ids.size() < 1) {
continue;
}
for(int i = 0; i < dim; i++) {
@@ -194,7 +202,7 @@ public class ClusterOutlineVisualization extends AbstractVisFactory {
}
SVGPath path = new SVGPath();
- if(!rounded) {
+ if(!settings.bend) {
// Straight lines
for(int i = 0; i < dim; i++) {
path.drawTo(getVisibleAxisX(i), mms[i].getMax());
@@ -208,7 +216,6 @@ public class ClusterOutlineVisualization extends AbstractVisFactory {
}
path.drawTo(getVisibleAxisX(i), mms[i].getMin());
}
- path.close();
}
else {
// Maxima
@@ -221,10 +228,19 @@ public class ClusterOutlineVisualization extends AbstractVisFactory {
for(int i = dim - 1; i > 0; i--) {
path.quadTo(getVisibleAxisX(i - .5), midmm[i - 1].getMin(), getVisibleAxisX(i - 1), mms[i - 1].getMin());
}
- path.close();
}
+ path.close();
+
+ // TODO: improve the visualization by adjusting the opacity by the
+ // cluster extends on each axis (maybe use a horizontal gradient?)
+ double weight = 0.;
+ for(int i = 0; i < dim; i++) {
+ weight += mms[i].getDiff();
+ }
+ weight = (weight > 0.) ? (dim * StyleLibrary.SCALE) / weight : 1.;
Element intervals = path.makeElement(svgp);
+ addCSSClasses(svgp, cpol.getStyleForCluster(clus), baseopacity * weight * ids.size() / relation.size());
SVGUtil.addCSSClass(intervals, CLUSTERAREA + cnum);
layer.appendChild(intervals);
}
@@ -234,33 +250,66 @@ public class ClusterOutlineVisualization extends AbstractVisFactory {
* Adds the required CSS-Classes
*
* @param svgp SVG-Plot
+ * @param clusterID Cluster ID to style
+ * @param opac Opacity
*/
- private void addCSSClasses(SVGPlot svgp) {
- if(!svgp.getCSSClassManager().contains(CLUSTERAREA)) {
- final StyleLibrary style = context.getStyleResult().getStyleLibrary();
- ColorLibrary colors = style.getColorSet(StyleLibrary.PLOT);
- int clusterID = 0;
-
- for(@SuppressWarnings("unused")
- Cluster<?> cluster : clustering.getAllClusters()) {
- CSSClass cls = new CSSClass(this, CLUSTERAREA + clusterID);
- // cls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY,
- // context.getStyleLibrary().getLineWidth(StyleLibrary.PLOT) / 2.0);
- cls.setStatement(SVGConstants.CSS_OPACITY_PROPERTY, 0.5);
- final String color;
- if(clustering.getAllClusters().size() == 1) {
- color = SVGConstants.CSS_BLACK_VALUE;
- }
- else {
- color = colors.getColor(clusterID);
- }
- // cls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, color);
- cls.setStatement(SVGConstants.CSS_FILL_PROPERTY, color);
+ private void addCSSClasses(SVGPlot svgp, int clusterID, double opac) {
+ final StyleLibrary style = context.getStyleResult().getStyleLibrary();
+ ColorLibrary colors = style.getColorSet(StyleLibrary.PLOT);
- svgp.addCSSClassOrLogError(cls);
- clusterID++;
- }
+ CSSClass cls = new CSSClass(this, CLUSTERAREA + clusterID);
+ final String color = colors.getColor(clusterID);
+
+ // cls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY,
+ // context.getStyleLibrary().getLineWidth(StyleLibrary.PLOT) / 2.0);
+ // cls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, color);
+ cls.setStatement(SVGConstants.CSS_FILL_PROPERTY, color);
+ cls.setStatement(SVGConstants.CSS_FILL_OPACITY_PROPERTY, opac);
+
+ svgp.addCSSClassOrLogError(cls);
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Option string to draw straight lines for hull.
+ */
+ public static final OptionID STRAIGHT_ID = new OptionID("parallel.clusteroutline.straight", "Draw straight lines");
+
+ /**
+ * Alpha value
+ */
+ double alpha = Double.POSITIVE_INFINITY;
+
+ /**
+ * Use bend curves
+ */
+ private boolean bend = true;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ DoubleParameter alphaP = new DoubleParameter(ClusterHullVisualization.Parameterizer.ALPHA_ID, Double.POSITIVE_INFINITY);
+ if(config.grab(alphaP)) {
+ alpha = alphaP.doubleValue();
}
+
+ Flag bendP = new Flag(STRAIGHT_ID);
+ if(config.grab(bendP)) {
+ bend = bendP.isFalse();
+ }
+ }
+
+ @Override
+ protected ClusterOutlineVisualization makeInstance() {
+ return new ClusterOutlineVisualization(this);
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterParallelMeanVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterParallelMeanVisualization.java
index ad3ed503..e98093d7 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterParallelMeanVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterParallelMeanVisualization.java
@@ -64,8 +64,7 @@ public class ClusterParallelMeanVisualization extends AbstractVisFactory {
private static final String NAME = "Cluster Means";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}.
+ * Constructor.
*/
public ClusterParallelMeanVisualization() {
super();
@@ -83,7 +82,7 @@ public class ClusterParallelMeanVisualization extends AbstractVisFactory {
for (Clustering<?> c : clusterings) {
if (c.getAllClusters().size() > 0) {
// Does the cluster have a model with cluster means?
- Clustering<MeanModel<? extends NumberVector<?>>> mcls = findMeanModel(c);
+ Clustering<MeanModel> mcls = findMeanModel(c);
if (mcls != null) {
Collection<ParallelPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ParallelPlotProjector.class);
for (ParallelPlotProjector<?> p : ps) {
@@ -104,9 +103,9 @@ public class ClusterParallelMeanVisualization extends AbstractVisFactory {
* @return the clustering cast to return a mean model, null otherwise.
*/
@SuppressWarnings("unchecked")
- private static Clustering<MeanModel<? extends NumberVector<?>>> findMeanModel(Clustering<?> c) {
- if (c.getAllClusters().get(0).getModel() instanceof MeanModel<?>) {
- return (Clustering<MeanModel<? extends NumberVector<?>>>) c;
+ private static Clustering<MeanModel> findMeanModel(Clustering<?> c) {
+ if (c.getAllClusters().get(0).getModel() instanceof MeanModel) {
+ return (Clustering<MeanModel>) c;
}
return null;
}
@@ -123,7 +122,7 @@ public class ClusterParallelMeanVisualization extends AbstractVisFactory {
* @author Robert Rödler
*
*/
- public class Instance extends AbstractParallelVisualization<NumberVector<?>> implements DataStoreListener {
+ public class Instance extends AbstractParallelVisualization<NumberVector> implements DataStoreListener {
/**
* Generic tags to indicate the type of element. Used in IDs, CSS-Classes
* etc.
@@ -133,7 +132,7 @@ public class ClusterParallelMeanVisualization extends AbstractVisFactory {
/**
* The result we visualize.
*/
- private Clustering<MeanModel<? extends NumberVector<?>>> clustering;
+ private Clustering<MeanModel> clustering;
/**
* Constructor.
@@ -159,13 +158,13 @@ public class ClusterParallelMeanVisualization extends AbstractVisFactory {
protected void redraw() {
addCSSClasses(svgp);
- Iterator<Cluster<MeanModel<? extends NumberVector<?>>>> ci = clustering.getAllClusters().iterator();
+ Iterator<Cluster<MeanModel>> ci = clustering.getAllClusters().iterator();
for (int cnum = 0; cnum < clustering.getAllClusters().size(); cnum++) {
- Cluster<MeanModel<? extends NumberVector<?>>> clus = ci.next();
+ Cluster<MeanModel> clus = ci.next();
if (clus.getModel() == null) {
continue;
}
- NumberVector<?> mean = clus.getModel().getMean();
+ NumberVector mean = clus.getModel().getMean();
if (mean == null) {
continue;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/package-info.java
index 0ae97b92..c2ffa94e 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/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/visualization/visualizers/parallel/index/RTreeParallelVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/RTreeParallelVisualization.java
index 04676905..f952f391 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/RTreeParallelVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/RTreeParallelVisualization.java
@@ -103,6 +103,7 @@ public class RTreeParallelVisualization extends AbstractVisFactory {
for(ParallelPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, (Result) tree, p.getRelation(), this);
task.level = VisualizationTask.LEVEL_BACKGROUND + 2;
+ task.default_visibility = false;
baseResult.getHierarchy().add((Result) tree, task);
baseResult.getHierarchy().add(p, task);
}
@@ -121,7 +122,7 @@ public class RTreeParallelVisualization extends AbstractVisFactory {
* @param <E> Tree entry type
*/
// TODO: listen for tree changes instead of data changes?
- public class Instance<N extends AbstractRStarTreeNode<N, E>, E extends SpatialEntry> extends AbstractParallelVisualization<NumberVector<?>> implements DataStoreListener {
+ public class Instance<N extends AbstractRStarTreeNode<N, E>, E extends SpatialEntry> extends AbstractParallelVisualization<NumberVector> implements DataStoreListener {
/**
* The tree we visualize
*/
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/package-info.java
index 93c1e75b..a1266943 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/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/visualization/visualizers/parallel/selection/SelectionAxisRangeVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionAxisRangeVisualization.java
index 6e2a9329..266c702b 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionAxisRangeVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionAxisRangeVisualization.java
@@ -96,7 +96,7 @@ public class SelectionAxisRangeVisualization extends AbstractVisFactory {
* @apiviz.has SelectionResult oneway - - visualizes
* @apiviz.has RangeSelection oneway - - visualizes
*/
- public class Instance extends AbstractParallelVisualization<NumberVector<?>> {
+ public class Instance extends AbstractParallelVisualization<NumberVector> {
/**
* CSS Class for the range marker
*/
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionLineVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionLineVisualization.java
index 92e5f64c..a0efe2c3 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionLineVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionLineVisualization.java
@@ -98,7 +98,7 @@ public class SelectionLineVisualization extends AbstractVisFactory {
*
* @apiviz.has SelectionResult oneway - - visualizes
*/
- public class Instance extends AbstractParallelVisualization<NumberVector<?>> implements DataStoreListener {
+ public class Instance extends AbstractParallelVisualization<NumberVector> implements DataStoreListener {
/**
* CSS Class for the range marker
*/
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolAxisRangeVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolAxisRangeVisualization.java
index 4fd00023..c2ea272e 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolAxisRangeVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolAxisRangeVisualization.java
@@ -74,8 +74,7 @@ public class SelectionToolAxisRangeVisualization extends AbstractVisFactory {
private static final String NAME = "Axis Range Selection";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public SelectionToolAxisRangeVisualization() {
super();
@@ -112,7 +111,7 @@ public class SelectionToolAxisRangeVisualization extends AbstractVisFactory {
* @apiviz.has SelectionResult oneway - - updates
* @apiviz.has RangeSelection oneway - - updates
*/
- public class Instance extends AbstractParallelVisualization<NumberVector<?>> implements DragableArea.DragListener {
+ public class Instance extends AbstractParallelVisualization<NumberVector> implements DragableArea.DragListener {
/**
* Generic tag to indicate the type of element. Used in IDs, CSS-Classes
* etc.
@@ -273,7 +272,7 @@ public class SelectionToolAxisRangeVisualization extends AbstractVisFactory {
selection.clear();
candidates: for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- NumberVector<?> dbTupel = relation.get(iditer);
+ NumberVector dbTupel = relation.get(iditer);
for(int i = 0; i < dim; i++) {
if(ranges != null && ranges[i] != null) {
if(dbTupel.doubleValue(i) < ranges[i].first || dbTupel.doubleValue(i) > ranges[i].second) {
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolLineVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolLineVisualization.java
index b7296492..907c8fc6 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolLineVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolLineVisualization.java
@@ -77,8 +77,7 @@ public class SelectionToolLineVisualization extends AbstractVisFactory {
}
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public SelectionToolLineVisualization() {
super();
@@ -115,7 +114,7 @@ public class SelectionToolLineVisualization extends AbstractVisFactory {
* @apiviz.has SelectionResult oneway - - updates
* @apiviz.has DBIDSelection oneway - - updates
*/
- public class Instance extends AbstractParallelVisualization<NumberVector<?>> implements DragableArea.DragListener {
+ public class Instance extends AbstractParallelVisualization<NumberVector> implements DragableArea.DragListener {
/**
* CSS class of the selection rectangle while selecting.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/package-info.java
index 52acab59..4f763940 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/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/visualization/visualizers/scatterplot/AbstractScatterplotVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractScatterplotVisualization.java
index 1f2d89d7..13c6c669 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractScatterplotVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractScatterplotVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot;
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
@@ -56,7 +56,7 @@ public abstract class AbstractScatterplotVisualization extends AbstractVisualiza
/**
* The representation we visualize
*/
- final protected Relation<? extends NumberVector<?>> rel;
+ final protected Relation<? extends NumberVector> rel;
/**
* The DBID sample
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractTooltipVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractTooltipVisualization.java
index 61bff7d4..4bfe80d2 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractTooltipVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractTooltipVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot;
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/visualization/visualizers/scatterplot/AxisVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AxisVisualization.java
index dd3f2218..e88ba006 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AxisVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AxisVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot;
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/visualization/visualizers/scatterplot/MarkerVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/MarkerVisualization.java
index 8a3d0849..9c899238 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/MarkerVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/MarkerVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot;
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
@@ -64,8 +64,7 @@ public class MarkerVisualization extends AbstractVisFactory {
private static final String NAME = "Markers";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public MarkerVisualization() {
super();
@@ -145,7 +144,7 @@ public class MarkerVisualization extends AbstractVisFactory {
continue; // TODO: can we test more efficiently than this?
}
try {
- final NumberVector<?> vec = rel.get(iter);
+ final NumberVector vec = rel.get(iter);
double[] v = proj.fastProjectDataToRenderSpace(vec);
if(v[0] != v[0] || v[1] != v[1]) {
continue; // NaN!
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/PolygonVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/PolygonVisualization.java
index 8037eae6..2c7c90b4 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/PolygonVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/PolygonVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot;
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/visualization/visualizers/scatterplot/ReferencePointsVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/ReferencePointsVisualization.java
index b3a66582..8ea851de 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/ReferencePointsVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/ReferencePointsVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot;
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
@@ -59,8 +59,7 @@ public class ReferencePointsVisualization extends AbstractVisFactory {
private static final String NAME = "Reference Points";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public ReferencePointsVisualization() {
super();
@@ -104,7 +103,7 @@ public class ReferencePointsVisualization extends AbstractVisFactory {
/**
* Serves reference points.
*/
- protected ReferencePointsResult<? extends NumberVector<?>> result;
+ protected ReferencePointsResult<? extends NumberVector> result;
/**
* Constructor.
@@ -121,11 +120,11 @@ public class ReferencePointsVisualization extends AbstractVisFactory {
public void redraw() {
final StyleLibrary style = context.getStyleResult().getStyleLibrary();
setupCSS(svgp);
- Iterator<? extends NumberVector<?>> iter = result.iterator();
+ Iterator<? extends NumberVector> iter = result.iterator();
final double dotsize = style.getSize(StyleLibrary.REFERENCE_POINTS);
while(iter.hasNext()) {
- NumberVector<?> v = iter.next();
+ NumberVector v = iter.next();
double[] projected = proj.fastProjectDataToRenderSpace(v);
Element dot = svgp.svgCircle(projected[0], projected[1], dotsize);
SVGUtil.addCSSClass(dot, REFPOINT);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipScoreVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipScoreVisualization.java
index 45351aec..eb011a26 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipScoreVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipScoreVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot;
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/visualization/visualizers/scatterplot/TooltipStringVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipStringVisualization.java
index 42da21d9..b3745504 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipStringVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipStringVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot;
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
@@ -78,8 +78,7 @@ public class TooltipStringVisualization extends AbstractVisFactory {
public static final String NAME_EID = "External ID Tooltips";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public TooltipStringVisualization() {
super();
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterHullVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterHullVisualization.java
index 9436b25c..54e715d6 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterHullVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterHullVisualization.java
@@ -86,7 +86,7 @@ public class ClusterHullVisualization extends AbstractVisFactory {
/**
* A short name characterizing this Visualizer.
*/
- private static final String NAME = "Cluster Hull Visualization";
+ private static final String NAME = "Cluster Hull (Scatterplot)";
/**
* Settings
@@ -114,13 +114,13 @@ public class ClusterHullVisualization extends AbstractVisFactory {
// We attach ourselves to the style library, not the clustering, so there is
// only one hull.
Collection<StyleResult> styleres = ResultUtil.filterResults(result, StyleResult.class);
- for (StyleResult c : styleres) {
+ for(StyleResult s : styleres) {
Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
- for (ScatterPlotProjector<?> p : ps) {
- final VisualizationTask task = new VisualizationTask(NAME, c, p.getRelation(), this);
+ for(ScatterPlotProjector<?> p : ps) {
+ final VisualizationTask task = new VisualizationTask(NAME, s, p.getRelation(), this);
task.level = VisualizationTask.LEVEL_DATA - 1;
task.initDefaultVisibility(false);
- baseResult.getHierarchy().add(c, task);
+ baseResult.getHierarchy().add(s, task);
baseResult.getHierarchy().add(p, task);
}
}
@@ -162,7 +162,7 @@ public class ClusterHullVisualization extends AbstractVisFactory {
@Override
protected void redraw() {
final StylingPolicy spol = style.getStylingPolicy();
- if (!(spol instanceof ClusterStylingPolicy)) {
+ if(!(spol instanceof ClusterStylingPolicy)) {
return;
}
final ClusterStylingPolicy cpol = (ClusterStylingPolicy) spol;
@@ -181,20 +181,19 @@ public class ClusterHullVisualization extends AbstractVisFactory {
double baseopacity = flat ? 0.5 : 0.5;
// Convex hull mode:
- if (settings.alpha >= Double.POSITIVE_INFINITY) {
+ if(settings.alpha >= Double.POSITIVE_INFINITY) {
// Build the convex hulls (reusing the hulls of nested clusters!)
Map<Object, DoubleObjPair<Polygon>> hullmap = new HashMap<>(clusters.size());
- for (Cluster<Model> clu : topc) {
+ for(Cluster<Model> clu : topc) {
buildHullsRecursively(clu, hier, hullmap);
}
// This way, we draw each cluster only once.
// Unfortunately, not depth ordered (TODO!)
- for (Cluster<Model> clu : clusters) {
+ for(Cluster<Model> clu : clusters) {
DoubleObjPair<Polygon> pair = hullmap.get(clu), mpair = hullmap.get(clu.getModel());
- ;
// Plot the convex hull:
- if (pair != null && pair.second != null && pair.second.size() > 1) {
+ if(pair != null && pair.second != null && pair.second.size() > 1) {
SVGPath path = new SVGPath(pair.second);
// Approximate area (using bounding box)
double hullarea = SpatialUtil.volume(pair.second);
@@ -209,7 +208,7 @@ public class ClusterHullVisualization extends AbstractVisFactory {
layer.appendChild(hulls);
}
// For core density models, over-plot the core:
- if (mpair != null && mpair.second != null && mpair.second.size() > 1) {
+ if(mpair != null && mpair.second != null && mpair.second.size() > 1) {
SVGPath path = new SVGPath(mpair.second);
// Approximate area (using bounding box)
double hullarea = SpatialUtil.volume(mpair.second);
@@ -223,25 +222,27 @@ public class ClusterHullVisualization extends AbstractVisFactory {
layer.appendChild(hulls);
}
}
- } else {
+ }
+ else {
// Alpha shape mode.
// For alpha shapes we can't use the shortcut of convex hulls,
// but have to revisit all child clusters.
- for (Cluster<Model> clu : clusters) {
+ for(Cluster<Model> clu : clusters) {
ArrayList<Vector> ps = new ArrayList<>();
double weight = addRecursively(ps, hier, clu);
List<Polygon> polys;
- if (ps.size() < 1) {
+ if(ps.size() < 1) {
continue;
}
- if (ps.size() > 2) {
+ if(ps.size() > 2) {
polys = (new AlphaShape(ps, settings.alpha * Projection.SCALE)).compute();
- } else {
+ }
+ else {
// Trivial polygon. Might still degenerate to a single point though.
polys = new ArrayList<>(1);
polys.add(new Polygon(ps));
}
- for (Polygon p : polys) {
+ for(Polygon p : polys) {
SVGPath path = new SVGPath(p);
Element hulls = path.makeElement(svgp);
addCSSClasses(svgp, cpol.getStyleForCluster(clu), baseopacity * weight / rel.size());
@@ -264,43 +265,43 @@ public class ClusterHullVisualization extends AbstractVisFactory {
final DBIDs ids = clu.getIDs();
boolean coremodel = false;
DBIDs cids = null;
- if (model instanceof CoreObjectsModel) {
+ if(model instanceof CoreObjectsModel) {
cids = ((CoreObjectsModel) model).getCoreObjects();
coremodel = cids.size() > 0;
}
GrahamScanConvexHull2D hull = new GrahamScanConvexHull2D();
GrahamScanConvexHull2D hull2 = coremodel ? new GrahamScanConvexHull2D() : null;
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
final double[] projv = proj.fastProjectDataToRenderSpace(rel.get(iter));
if(projv[0] != projv[0] || projv[1] != projv[1]) {
continue; // NaN!
}
Vector projP = new Vector(projv);
hull.add(projP);
- if (coremodel && cids.contains(iter)) {
+ if(coremodel && cids.contains(iter)) {
hull2.add(projP);
}
}
double weight = ids.size(), cweight = coremodel ? cids.size() : 0.0;
- if (hier != null && hulls != null) {
+ if(hier != null && hulls != null) {
final int numc = hier.numChildren(clu);
- if (numc > 0) {
- for (Iter<Cluster<Model>> iter = hier.iterChildren(clu); iter.valid(); iter.advance()) {
+ if(numc > 0) {
+ for(Iter<Cluster<Model>> iter = hier.iterChildren(clu); iter.valid(); iter.advance()) {
final Cluster<Model> iclu = iter.get();
DoubleObjPair<Polygon> poly = hulls.get(iclu);
- if (poly == null) {
+ if(poly == null) {
poly = buildHullsRecursively(iclu, hier, hulls);
}
// Add inner convex hull to outer convex hull.
- for (ArrayListIter<Vector> vi = poly.second.iter(); vi.valid(); vi.advance()) {
+ for(ArrayListIter<Vector> vi = poly.second.iter(); vi.valid(); vi.advance()) {
hull.add(vi.get());
}
// For a core model, include the inner core, too.
- if (coremodel) {
+ if(coremodel) {
DoubleObjPair<Polygon> ipoly = hulls.get(iclu.getModel());
- if (ipoly != null) {
- for (ArrayListIter<Vector> vi = ipoly.second.iter(); vi.valid(); vi.advance()) {
+ if(ipoly != null) {
+ for(ArrayListIter<Vector> vi = ipoly.second.iter(); vi.valid(); vi.advance()) {
hull2.add(vi.get());
}
cweight += ipoly.first / numc;
@@ -312,7 +313,7 @@ public class ClusterHullVisualization extends AbstractVisFactory {
}
DoubleObjPair<Polygon> pair = new DoubleObjPair<>(weight, hull.getHull());
hulls.put(clu, pair);
- if (coremodel) {
+ if(coremodel) {
hulls.put(model, new DoubleObjPair<>(cweight, hull2.getHull()));
}
return pair;
@@ -329,14 +330,14 @@ public class ClusterHullVisualization extends AbstractVisFactory {
private double addRecursively(ArrayList<Vector> hull, Hierarchy<Cluster<Model>> hier, Cluster<Model> clus) {
final DBIDs ids = clus.getIDs();
double weight = ids.size();
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
double[] projP = proj.fastProjectDataToRenderSpace(rel.get(iter));
if(projP[0] != projP[0] || projP[1] != projP[1]) {
continue; // NaN!
}
hull.add(new Vector(projP));
}
- for (Iter<Cluster<Model>> iter = hier.iterChildren(clus); iter.valid(); iter.advance()) {
+ for(Iter<Cluster<Model>> iter = hier.iterChildren(clus); iter.valid(); iter.advance()) {
weight += .5 * addRecursively(hull, hier, iter.get());
}
return weight;
@@ -352,7 +353,7 @@ public class ClusterHullVisualization extends AbstractVisFactory {
ColorLibrary colors = style.getColorSet(StyleLibrary.PLOT);
CSSClass cls = new CSSClass(this, CLUSTERHULL + clusterID);
- cls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, style.getLineWidth(StyleLibrary.PLOT));
+ cls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, .5 * style.getLineWidth(StyleLibrary.PLOT));
final String color = colors.getColor(clusterID);
cls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, color);
@@ -389,7 +390,7 @@ public class ClusterHullVisualization extends AbstractVisFactory {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
DoubleParameter alphaP = new DoubleParameter(ALPHA_ID, Double.POSITIVE_INFINITY);
- if (config.grab(alphaP)) {
+ if(config.grab(alphaP)) {
alpha = alphaP.doubleValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterMeanVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterMeanVisualization.java
index c07e5dca..5a7d8702 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterMeanVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterMeanVisualization.java
@@ -31,7 +31,6 @@ import org.w3c.dom.Element;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.model.MeanModel;
import de.lmu.ifi.dbs.elki.data.model.MedoidModel;
import de.lmu.ifi.dbs.elki.data.model.Model;
@@ -164,8 +163,7 @@ public class ClusterMeanVisualization extends AbstractVisFactory {
Model model = clus.getModel();
double[] mean;
if(model instanceof MeanModel) {
- @SuppressWarnings("unchecked")
- MeanModel<? extends NumberVector<?>> mmodel = (MeanModel<? extends NumberVector<?>>) model;
+ MeanModel mmodel = (MeanModel) model;
mean = proj.fastProjectDataToRenderSpace(mmodel.getMean());
}
else if(model instanceof MedoidModel) {
@@ -247,7 +245,7 @@ public class ClusterMeanVisualization extends AbstractVisFactory {
*/
private static boolean testMeanModel(Clustering<?> c) {
Model firstmodel = c.getAllClusters().get(0).getModel();
- if(firstmodel instanceof MeanModel<?>) {
+ if(firstmodel instanceof MeanModel) {
return true;
}
if(firstmodel instanceof MedoidModel) {
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterOrderVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterOrderVisualization.java
index 339b7c41..b277824e 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterOrderVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterOrderVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.cluster;
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,14 +27,13 @@ import java.util.Collection;
import org.w3c.dom.Element;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderEntry;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.optics.ClusterOrderResult;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreListener;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
import de.lmu.ifi.dbs.elki.visualization.projector.ScatterPlotProjector;
@@ -60,8 +59,7 @@ public class ClusterOrderVisualization extends AbstractVisFactory {
private static final String NAME = "Predecessor Graph";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public ClusterOrderVisualization() {
super();
@@ -74,8 +72,8 @@ public class ClusterOrderVisualization extends AbstractVisFactory {
@Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- Collection<ClusterOrderResult<DoubleDistance>> cos = ResultUtil.filterResults(result, ClusterOrderResult.class);
- for(ClusterOrderResult<DoubleDistance> co : cos) {
+ Collection<ClusterOrderResult<?>> cos = ResultUtil.filterResults(result, ClusterOrderResult.class);
+ for(ClusterOrderResult<?> co : cos) {
Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
for(ScatterPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, co, p.getRelation(), this);
@@ -104,7 +102,7 @@ public class ClusterOrderVisualization extends AbstractVisFactory {
/**
* The result we visualize
*/
- protected ClusterOrderResult<?> result;
+ protected ClusterOrderResult<? extends ClusterOrderEntry<?>> result;
public Instance(VisualizationTask task) {
super(task);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/EMClusterVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/EMClusterVisualization.java
index 9a5df4e4..98dc004f 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/EMClusterVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/EMClusterVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.cluster;
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,6 @@ import org.w3c.dom.Element;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.model.EMModel;
import de.lmu.ifi.dbs.elki.data.model.MeanModel;
import de.lmu.ifi.dbs.elki.data.model.Model;
@@ -71,7 +69,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.AbstractScatter
* @author Robert Rödler
*
* @apiviz.stereotype factory
- * @apiviz.uses EMClusterVisualization oneway - - «create»
+ * @apiviz.uses Instance oneway - - «create»
*/
public class EMClusterVisualization extends AbstractVisFactory {
/**
@@ -92,8 +90,8 @@ public class EMClusterVisualization extends AbstractVisFactory {
}
@Override
- public Instance<DoubleVector> makeVisualization(VisualizationTask task) {
- return new Instance<>(task);
+ public Instance makeVisualization(VisualizationTask task) {
+ return new Instance(task);
}
@Override
@@ -103,7 +101,7 @@ public class EMClusterVisualization extends AbstractVisFactory {
for(Clustering<?> c : clusterings) {
if(c.getAllClusters().size() > 0) {
// Does the cluster have a model with cluster means?
- Clustering<MeanModel<DoubleVector>> mcls = findMeanModel(c);
+ Clustering<MeanModel> mcls = findMeanModel(c);
if(mcls != null) {
Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
for(ScatterPlotProjector<?> p : ps) {
@@ -120,15 +118,14 @@ public class EMClusterVisualization extends AbstractVisFactory {
/**
* Test if the given clustering has a mean model.
*
- * @param <NV> Vector type
* @param c Clustering to inspect
* @return the clustering cast to return a mean model, null otherwise.
*/
@SuppressWarnings("unchecked")
- private static <NV extends NumberVector<?>> Clustering<MeanModel<NV>> findMeanModel(Clustering<?> c) {
+ private static Clustering<MeanModel> findMeanModel(Clustering<?> c) {
final Model firstModel = c.getAllClusters().get(0).getModel();
- if(c.getAllClusters().get(0).getModel() instanceof MeanModel<?> && firstModel instanceof EMModel<?>) {
- return (Clustering<MeanModel<NV>>) c;
+ if(c.getAllClusters().get(0).getModel() instanceof MeanModel && firstModel instanceof EMModel) {
+ return (Clustering<MeanModel>) c;
}
return null;
}
@@ -140,12 +137,10 @@ public class EMClusterVisualization extends AbstractVisFactory {
*
* @apiviz.has EMModel oneway - - visualizes
* @apiviz.uses GrahamScanConvexHull2D
- *
- * @param <NV> Type of the NumberVector being visualized.
*/
// TODO: nicer stacking of n-fold hulls
// TODO: can we find a proper sphere for 3+ dimensions?
- public class Instance<NV extends NumberVector<?>> extends AbstractScatterplotVisualization {
+ public class Instance extends AbstractScatterplotVisualization {
/**
* Generic tags to indicate the type of element. Used in IDs, CSS-Classes
* etc.
@@ -155,7 +150,7 @@ public class EMClusterVisualization extends AbstractVisFactory {
/**
* The result we work on
*/
- Clustering<EMModel<NV>> clustering;
+ Clustering<EMModel> clustering;
private static final double KAPPA = SVGHyperSphere.EUCLIDEAN_KAPPA;
@@ -187,16 +182,16 @@ public class EMClusterVisualization extends AbstractVisFactory {
addCSSClasses(svgp);
// PCARunner
- PCARunner<NV> pcarun = ClassGenericsUtil.parameterizeOrAbort(PCARunner.class, new EmptyParameterization());
+ PCARunner pcarun = ClassGenericsUtil.parameterizeOrAbort(PCARunner.class, new EmptyParameterization());
- Iterator<Cluster<EMModel<NV>>> ci = clustering.getAllClusters().iterator();
+ Iterator<Cluster<EMModel>> ci = clustering.getAllClusters().iterator();
for(int cnum = 0; cnum < clustering.getAllClusters().size(); cnum++) {
- Cluster<EMModel<NV>> clus = ci.next();
+ Cluster<EMModel> clus = ci.next();
DBIDs ids = clus.getIDs();
if(ids.size() > 0) {
Matrix covmat = clus.getModel().getCovarianceMatrix();
- NV centroid = clus.getModel().getMean();
+ Vector centroid = clus.getModel().getMean();
Vector cent = new Vector(proj.fastProjectDataToRenderSpace(centroid));
// Compute the eigenvectors
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/VoronoiVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/VoronoiVisualization.java
index 7c4b57f2..4c41759d 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/VoronoiVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/VoronoiVisualization.java
@@ -32,8 +32,6 @@ import org.w3c.dom.Element;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.model.KMeansModel;
import de.lmu.ifi.dbs.elki.data.model.MeanModel;
import de.lmu.ifi.dbs.elki.data.model.MedoidModel;
import de.lmu.ifi.dbs.elki.data.model.Model;
@@ -152,7 +150,7 @@ public class VoronoiVisualization extends AbstractVisFactory {
*/
private static boolean testMeanModel(Clustering<?> c) {
Model firstmodel = c.getAllClusters().get(0).getModel();
- if (firstmodel instanceof KMeansModel<?>) {
+ if (firstmodel instanceof MeanModel) {
return true;
}
if (firstmodel instanceof MedoidModel) {
@@ -209,12 +207,11 @@ public class VoronoiVisualization extends AbstractVisFactory {
Model model = clus.getModel();
double[] mean;
if (model instanceof MeanModel) {
- @SuppressWarnings("unchecked")
- MeanModel<? extends NumberVector<?>> mmodel = (MeanModel<? extends NumberVector<?>>) model;
- mean = proj.fastProjectDataToRenderSpace(mmodel.getMean());
+ MeanModel mmodel = (MeanModel) model;
+ mean = mmodel.getMean().getArrayRef();
} else if (model instanceof MedoidModel) {
MedoidModel mmodel = (MedoidModel) model;
- mean = proj.fastProjectDataToRenderSpace(rel.get(mmodel.getMedoid()));
+ mean = rel.get(mmodel.getMedoid()).getColumnVector().getArrayRef();
} else {
continue;
}
@@ -227,7 +224,8 @@ public class VoronoiVisualization extends AbstractVisFactory {
layer.appendChild(path);
}
if (settings.mode == Mode.DELAUNAY || settings.mode == Mode.V_AND_D) {
- Element path = new SVGPath(means.get(0)).drawTo(means.get(1)).makeElement(svgp);
+ Element path = new SVGPath(proj.fastProjectDataToRenderSpace(means.get(0)))//
+ .drawTo(proj.fastProjectDataToRenderSpace(means.get(1))).makeElement(svgp);
SVGUtil.addCSSClass(path, KMEANSBORDER);
layer.appendChild(path);
}
@@ -239,8 +237,7 @@ public class VoronoiVisualization extends AbstractVisFactory {
Model model = clus.getModel();
Vector mean;
if (model instanceof MeanModel) {
- @SuppressWarnings("unchecked")
- MeanModel<? extends NumberVector<?>> mmodel = (MeanModel<? extends NumberVector<?>>) model;
+ MeanModel mmodel = (MeanModel) model;
mean = mmodel.getMean().getColumnVector();
} else if (model instanceof MedoidModel) {
MedoidModel mmodel = (MedoidModel) model;
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/package-info.java
index 076b6563..3b0049dd 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/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/visualization/visualizers/scatterplot/density/DensityEstimationOverlay.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/density/DensityEstimationOverlay.java
index a2b34e0e..e1e1872c 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/density/DensityEstimationOverlay.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/density/DensityEstimationOverlay.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.density;
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
@@ -63,8 +63,7 @@ public class DensityEstimationOverlay extends AbstractVisFactory {
private static final String NAME = "Density estimation overlay";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public DensityEstimationOverlay() {
super();
@@ -134,7 +133,9 @@ public class DensityEstimationOverlay extends AbstractVisFactory {
layer.appendChild(itag);
}
- @Reference(authors = "D. W. Scott", title = "Multivariate density estimation", booktitle = "Multivariate Density Estimation: Theory, Practice, and Visualization", url = "http://dx.doi.org/10.1002/9780470316849.fmatter")
+ @Reference(authors = "D. W. Scott", title = "Multivariate density estimation: Theory, Practice, and Visualization", //
+ booktitle = "Multivariate Density Estimation: Theory, Practice, and Visualization", //
+ url = "http://dx.doi.org/10.1002/9780470316849")
private double[] initializeBandwidth(double[][] data) {
MeanVariance mv0 = new MeanVariance();
MeanVariance mv1 = new MeanVariance();
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeMBRVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeMBRVisualization.java
index 438eddb8..6b926525 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeMBRVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeMBRVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.index;
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
@@ -103,6 +103,7 @@ public class TreeMBRVisualization extends AbstractVisFactory {
for(ScatterPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, (Result) tree, p.getRelation(), this);
task.level = VisualizationTask.LEVEL_BACKGROUND + 1;
+ task.initDefaultVisibility(false);
baseResult.getHierarchy().add((Result) tree, task);
baseResult.getHierarchy().add(p, task);
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeSphereVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeSphereVisualization.java
index 4ced6de1..4b4e77a0 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeSphereVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeSphereVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.index;
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
@@ -35,8 +35,6 @@ import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.ManhattanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
@@ -66,7 +64,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.AbstractScatter
* @author Erich Schubert
*
* @apiviz.stereotype factory
- * @apiviz.uses TreeSphereVisualization oneway - - «create»
+ * @apiviz.uses Instance oneway - - «create»
*/
public class TreeSphereVisualization extends AbstractVisFactory {
/**
@@ -106,12 +104,13 @@ public class TreeSphereVisualization extends AbstractVisFactory {
@Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
- for (ScatterPlotProjector<?> p : ps) {
- Collection<AbstractMTree<?, DoubleDistance, ?, ?, ?>> trees = ResultUtil.filterResults(result, AbstractMTree.class);
- for (AbstractMTree<?, DoubleDistance, ?, ?, ?> tree : trees) {
- if (canVisualize(tree) && tree instanceof Result) {
+ for(ScatterPlotProjector<?> p : ps) {
+ Collection<AbstractMTree<?, ?, ?, ?>> trees = ResultUtil.filterResults(result, AbstractMTree.class);
+ for(AbstractMTree<?, ?, ?, ?> tree : trees) {
+ if(canVisualize(tree) && tree instanceof Result) {
final VisualizationTask task = new VisualizationTask(NAME, (Result) tree, p.getRelation(), this);
task.level = VisualizationTask.LEVEL_BACKGROUND + 1;
+ task.initDefaultVisibility(false);
baseResult.getHierarchy().add((Result) tree, task);
baseResult.getHierarchy().add(p, task);
}
@@ -121,7 +120,7 @@ public class TreeSphereVisualization extends AbstractVisFactory {
@Override
public Visualization makeVisualization(VisualizationTask task) {
- return new Instance<DoubleDistance, MTreeNode<Object, DoubleDistance>, MTreeEntry>(task);
+ return new Instance<MTreeNode<Object>, MTreeEntry>(task);
}
/**
@@ -130,11 +129,11 @@ public class TreeSphereVisualization extends AbstractVisFactory {
* @param tree Tree to visualize
* @return p value
*/
- public static double getLPNormP(AbstractMTree<?, ?, ?, ?, ?> tree) {
+ public static double getLPNormP(AbstractMTree<?, ?, ?, ?> tree) {
// Note: we deliberately lose generics here, so the compilers complain
// less on the next typecheck and cast!
- DistanceFunction<?, ?> distanceFunction = tree.getDistanceFunction();
- if (LPNormDistanceFunction.class.isInstance(distanceFunction)) {
+ DistanceFunction<?> distanceFunction = tree.getDistanceFunction();
+ if(LPNormDistanceFunction.class.isInstance(distanceFunction)) {
return ((LPNormDistanceFunction) distanceFunction).getP();
}
return 0;
@@ -146,7 +145,7 @@ public class TreeSphereVisualization extends AbstractVisFactory {
* @param tree Tree to visualize
* @return whether the tree is visualizable
*/
- public static boolean canVisualize(AbstractMTree<?, ?, ?, ?, ?> tree) {
+ public static boolean canVisualize(AbstractMTree<?, ?, ?, ?> tree) {
return getLPNormP(tree) > 0;
}
@@ -162,7 +161,7 @@ public class TreeSphereVisualization extends AbstractVisFactory {
* @param <E> Tree entry type
*/
// TODO: listen for tree changes!
- public class Instance<D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<?, D, N, E>, E extends MTreeEntry> extends AbstractScatterplotVisualization implements DataStoreListener {
+ public class Instance<N extends AbstractMTreeNode<?, N, E>, E extends MTreeEntry> extends AbstractScatterplotVisualization implements DataStoreListener {
protected double p;
/**
@@ -173,7 +172,7 @@ public class TreeSphereVisualization extends AbstractVisFactory {
/**
* The tree we visualize
*/
- protected AbstractMTree<?, D, N, E, ?> tree;
+ protected AbstractMTree<?, N, E, ?> tree;
/**
* Constructor
@@ -196,28 +195,31 @@ public class TreeSphereVisualization extends AbstractVisFactory {
ColorLibrary colors = style.getColorSet(StyleLibrary.PLOT);
p = getLPNormP(tree);
- if (tree != null) {
- if (ManhattanDistanceFunction.class.isInstance(tree.getDistanceFunction())) {
+ if(tree != null) {
+ if(ManhattanDistanceFunction.class.isInstance(tree.getDistanceFunction())) {
dist = Modus.MANHATTAN;
- } else if (EuclideanDistanceFunction.class.isInstance(tree.getDistanceFunction())) {
+ }
+ else if(EuclideanDistanceFunction.class.isInstance(tree.getDistanceFunction())) {
dist = Modus.EUCLIDEAN;
- } else {
+ }
+ else {
dist = Modus.LPCROSS;
}
E root = tree.getRootEntry();
final int mtheight = tree.getHeight();
- for (int i = 0; i < mtheight; i++) {
+ for(int i = 0; i < mtheight; i++) {
CSSClass cls = new CSSClass(this, INDEX + i);
// Relative depth of this level. 1.0 = toplevel
final double relDepth = 1. - (((double) i) / mtheight);
- if (settings.fill) {
+ if(settings.fill) {
cls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, colors.getColor(i));
cls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, relDepth * style.getLineWidth(StyleLibrary.PLOT));
cls.setStatement(SVGConstants.CSS_FILL_PROPERTY, colors.getColor(i));
cls.setStatement(SVGConstants.CSS_FILL_OPACITY_PROPERTY, 0.1 / (projdim - 1));
cls.setStatement(SVGConstants.CSS_STROKE_LINECAP_PROPERTY, SVGConstants.CSS_ROUND_VALUE);
cls.setStatement(SVGConstants.CSS_STROKE_LINEJOIN_PROPERTY, SVGConstants.CSS_ROUND_VALUE);
- } else {
+ }
+ else {
cls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, colors.getColor(i));
cls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, relDepth * style.getLineWidth(StyleLibrary.PLOT));
cls.setStatement(SVGConstants.CSS_FILL_PROPERTY, SVGConstants.CSS_NONE_VALUE);
@@ -240,16 +242,17 @@ public class TreeSphereVisualization extends AbstractVisFactory {
* @param entry Current entry
* @param depth Current depth
*/
- private void visualizeMTreeEntry(SVGPlot svgp, Element layer, Projection2D proj, AbstractMTree<?, D, N, E, ?> mtree, E entry, int depth) {
+ private void visualizeMTreeEntry(SVGPlot svgp, Element layer, Projection2D proj, AbstractMTree<?, N, E, ?> mtree, E entry, int depth) {
DBID roid = entry.getRoutingObjectID();
- if (roid != null) {
- NumberVector<?> ro = rel.get(roid);
+ if(roid != null) {
+ NumberVector ro = rel.get(roid);
double rad = entry.getCoveringRadius();
final Element r;
- if (dist == Modus.MANHATTAN) {
+ if(dist == Modus.MANHATTAN) {
r = SVGHyperSphere.drawManhattan(svgp, proj, ro, rad);
- } else if (dist == Modus.EUCLIDEAN) {
+ }
+ else if(dist == Modus.EUCLIDEAN) {
r = SVGHyperSphere.drawEuclidean(svgp, proj, ro, rad);
}
// TODO: add visualizer for infinity norm?
@@ -261,11 +264,11 @@ public class TreeSphereVisualization extends AbstractVisFactory {
layer.appendChild(r);
}
- if (!entry.isLeafEntry()) {
+ if(!entry.isLeafEntry()) {
N node = mtree.getNode(entry);
- for (int i = 0; i < node.getNumEntries(); i++) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
E child = node.getEntry(i);
- if (!child.isLeafEntry()) {
+ if(!child.isLeafEntry()) {
visualizeMTreeEntry(svgp, layer, proj, mtree, child, depth + 1);
}
}
@@ -293,7 +296,7 @@ public class TreeSphereVisualization extends AbstractVisFactory {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
Flag fillF = new Flag(TreeMBRVisualization.Parameterizer.FILL_ID);
- if (config.grab(fillF)) {
+ if(config.grab(fillF)) {
fill = fillF.isTrue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/package-info.java
index b82e9359..c47c6fbd 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/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/visualization/visualizers/scatterplot/outlier/BubbleVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/BubbleVisualization.java
index 752cf333..bca3f634 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/BubbleVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/BubbleVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.outlier;
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
@@ -180,7 +180,7 @@ public class BubbleVisualization extends AbstractVisFactory {
for(DBIDIter objId = sample.getSample().iter(); objId.valid(); objId.advance()) {
final double radius = getScaledForId(objId);
if(radius > 0.01 && !Double.isInfinite(radius)) {
- final NumberVector<?> vec = rel.get(objId);
+ final NumberVector vec = rel.get(objId);
if(vec != null) {
double[] v = proj.fastProjectDataToRenderSpace(vec);
if(v[0] != v[0] || v[1] != v[1]) {
@@ -198,7 +198,7 @@ public class BubbleVisualization extends AbstractVisFactory {
for(DBIDIter objId = sample.getSample().iter(); objId.valid(); objId.advance()) {
final double radius = getScaledForId(objId);
if(radius > 0.01 && !Double.isInfinite(radius)) {
- final NumberVector<?> vec = rel.get(objId);
+ final NumberVector vec = rel.get(objId);
if(vec != null) {
double[] v = proj.fastProjectDataToRenderSpace(vec);
if(v[0] != v[0] || v[1] != v[1]) {
@@ -270,7 +270,7 @@ public class BubbleVisualization extends AbstractVisFactory {
* by the given scales.
*/
protected double getScaledForId(DBIDRef id) {
- double d = result.getScores().get(id).doubleValue();
+ double d = result.getScores().doubleValue(id);
if(Double.isNaN(d) || Double.isInfinite(d)) {
return 0.0;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/COPVectorVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/COPVectorVisualization.java
index e62f0c3d..f169b0a8 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/COPVectorVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/COPVectorVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.outlier;
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
@@ -152,7 +152,7 @@ public class COPVectorVisualization extends AbstractVisFactory {
if (VMath.euclideanLength(ev) < 0.01) {
continue;
}
- final NumberVector<?> vec = rel.get(objId);
+ final NumberVector vec = rel.get(objId);
if (vec == null) {
continue;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/package-info.java
index f8da2afd..d0f5fa0f 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/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/visualization/visualizers/scatterplot/selection/DistanceFunctionVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/DistanceFunctionVisualization.java
index 38dc973f..40fd96f9 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/DistanceFunctionVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/DistanceFunctionVisualization.java
@@ -1,26 +1,27 @@
package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.selection;
-/*
- This file is part of ELKI:
+
+/*
+ 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
+
+ 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
+
+ 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
+
+ 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/>.
- */
+
+ 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.Collection;
@@ -32,15 +33,13 @@ import de.lmu.ifi.dbs.elki.data.VectorUtil;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreListener;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-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.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.distance.distancefunction.ArcCosineDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.CosineDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
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.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.preprocessed.knn.AbstractMaterializeKNNPreprocessor;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.math.MathUtil;
@@ -95,13 +94,13 @@ public class DistanceFunctionVisualization extends AbstractVisFactory {
@Override
public Visualization makeVisualization(VisualizationTask task) {
- return new Instance<DoubleDistance>(task);
+ return new Instance(task);
}
@Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- Collection<AbstractMaterializeKNNPreprocessor<?, ?, ?>> kNNIndex = ResultUtil.filterResults(result, AbstractMaterializeKNNPreprocessor.class);
- for(AbstractMaterializeKNNPreprocessor<?, ?, ?> kNN : kNNIndex) {
+ Collection<AbstractMaterializeKNNPreprocessor<?>> kNNIndex = ResultUtil.filterResults(result, AbstractMaterializeKNNPreprocessor.class);
+ for(AbstractMaterializeKNNPreprocessor<?> kNN : kNNIndex) {
Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
for(ScatterPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, kNN, p.getRelation(), this);
@@ -118,8 +117,8 @@ public class DistanceFunctionVisualization extends AbstractVisFactory {
* @param kNN kNN preprocessor
* @return p of LP norm, or NaN
*/
- public static double getLPNormP(AbstractMaterializeKNNPreprocessor<?, ?, ?> kNN) {
- DistanceFunction<?, ?> distanceFunction = kNN.getDistanceQuery().getDistanceFunction();
+ public static double getLPNormP(AbstractMaterializeKNNPreprocessor<?> kNN) {
+ DistanceFunction<?> distanceFunction = kNN.getDistanceQuery().getDistanceFunction();
if(LPNormDistanceFunction.class.isInstance(distanceFunction)) {
return ((LPNormDistanceFunction) distanceFunction).getP();
}
@@ -132,8 +131,8 @@ public class DistanceFunctionVisualization extends AbstractVisFactory {
* @param kNN kNN preprocessor
* @return true when angular
*/
- public static boolean isAngularDistance(AbstractMaterializeKNNPreprocessor<?, ?, ?> kNN) {
- DistanceFunction<?, ?> distanceFunction = kNN.getDistanceQuery().getDistanceFunction();
+ public static boolean isAngularDistance(AbstractMaterializeKNNPreprocessor<?> kNN) {
+ DistanceFunction<?> distanceFunction = kNN.getDistanceQuery().getDistanceFunction();
if(CosineDistanceFunction.class.isInstance(distanceFunction)) {
return true;
}
@@ -152,13 +151,13 @@ public class DistanceFunctionVisualization extends AbstractVisFactory {
* @param angle Opening angle in radians
* @return path element
*/
- public static Element drawCosine(SVGPlot svgp, Projection2D proj, NumberVector<?> mid, double angle) {
+ public static Element drawCosine(SVGPlot svgp, Projection2D proj, NumberVector mid, double angle) {
// Project origin
double[] pointOfOrigin = proj.fastProjectDataToRenderSpace(new double[proj.getInputDimensionality()]);
-
+
// direction of the selected Point
double[] selPoint = proj.fastProjectDataToRenderSpace(mid);
-
+
double[] range1, range2;
{
// Rotation plane:
@@ -195,7 +194,7 @@ public class DistanceFunctionVisualization extends AbstractVisFactory {
range1 = proj.fastProjectDataToRenderSpace(r1);
range2 = proj.fastProjectDataToRenderSpace(r2);
}
-
+
// Continue lines to viewport.
{
CanvasSize viewport = proj.estimateViewport();
@@ -213,7 +212,7 @@ public class DistanceFunctionVisualization extends AbstractVisFactory {
VMath.timesEquals(start2, viewport.continueToMargin(range2, start2));
VMath.plusEquals(start1, range1);
VMath.plusEquals(start2, range2);
-
+
// TODO: add filled variant?
SVGPath path = new SVGPath();
path.moveTo(start1);
@@ -233,9 +232,8 @@ public class DistanceFunctionVisualization extends AbstractVisFactory {
* @apiviz.has SelectionResult oneway - - visualizes
* @apiviz.has DBIDSelection oneway - - visualizes
*
- * @param <D> Distance type
*/
- public class Instance<D extends NumberDistance<D, ?>> extends AbstractScatterplotVisualization implements DataStoreListener {
+ public class Instance extends AbstractScatterplotVisualization implements DataStoreListener {
/**
* Generic tags to indicate the type of element. Used in IDs, CSS-Classes
* etc.
@@ -249,7 +247,7 @@ public class DistanceFunctionVisualization extends AbstractVisFactory {
/**
* The selection result we work on
*/
- private AbstractMaterializeKNNPreprocessor<? extends NumberVector<?>, D, ?> result;
+ private AbstractMaterializeKNNPreprocessor<? extends NumberVector> result;
/**
* Constructor
@@ -277,18 +275,18 @@ public class DistanceFunctionVisualization extends AbstractVisFactory {
DBIDs selection = selContext.getSelectedIds();
for(DBIDIter i = selection.iter(); i.valid(); i.advance()) {
- final KNNList<D> knn = result.get(i);
- for(DistanceDBIDListIter<D> iter = knn.iter(); iter.valid(); iter.advance()) {
+ final KNNList knn = result.get(i);
+ for(DoubleDBIDListIter iter = knn.iter(); iter.valid(); iter.advance()) {
try {
double[] v = proj.fastProjectDataToRenderSpace(rel.get(iter));
- if (v[0] != v[0] || v[1] != v[1]) {
+ if(v[0] != v[0] || v[1] != v[1]) {
continue; // NaN!
}
Element dot = svgp.svgCircle(v[0], v[1], size);
SVGUtil.addCSSClass(dot, KNNMARKER);
layer.appendChild(dot);
- Element lbl = svgp.svgText(v[0] + size, v[1] + size, iter.getDistance().toString());
+ Element lbl = svgp.svgText(v[0] + size, v[1] + size, Double.toString(iter.doubleValue()));
SVGUtil.addCSSClass(lbl, KNNDIST);
layer.appendChild(lbl);
}
@@ -297,21 +295,21 @@ public class DistanceFunctionVisualization extends AbstractVisFactory {
}
}
// Last element
- DistanceDBIDPair<D> last = knn.get(knn.size() - 1);
+ DoubleDBIDPair last = knn.get(knn.size() - 1);
// Draw hypersphere if possible
{
final Element dist;
if(p == 1.0) {
- dist = SVGHyperSphere.drawManhattan(svgp, proj, rel.get(i), last.getDistance().doubleValue());
+ dist = SVGHyperSphere.drawManhattan(svgp, proj, rel.get(i), last.doubleValue());
}
else if(p == 2.0) {
- dist = SVGHyperSphere.drawEuclidean(svgp, proj, rel.get(i), last.getDistance().doubleValue());
+ dist = SVGHyperSphere.drawEuclidean(svgp, proj, rel.get(i), last.doubleValue());
}
else if(!Double.isNaN(p)) {
- dist = SVGHyperSphere.drawLp(svgp, proj, rel.get(i), last.getDistance().doubleValue(), p);
+ dist = SVGHyperSphere.drawLp(svgp, proj, rel.get(i), last.doubleValue(), p);
}
else if(angular) {
- final NumberVector<?> refvec = rel.get(i);
+ final NumberVector refvec = rel.get(i);
// Recompute the angle - it could be cosine or arccosine distance
double maxangle = Math.acos(VectorUtil.cosAngle(refvec, rel.get(last)));
dist = drawCosine(svgp, proj, refvec, maxangle);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/MoveObjectsToolVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/MoveObjectsToolVisualization.java
index 0f9f99a4..7c49395c 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/MoveObjectsToolVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/MoveObjectsToolVisualization.java
@@ -160,7 +160,7 @@ public class MoveObjectsToolVisualization extends AbstractVisFactory {
private void updateDB(DBIDs dbids, Vector movingVector) {
throw new AbortException("FIXME: INCOMPLETE TRANSITION");
/*
- * NumberVector<?> nv = null; database.accumulateDataStoreEvents();
+ * NumberVector nv = null; database.accumulateDataStoreEvents();
* Representation<DatabaseObjectMetadata> mrep =
* database.getMetadataQuery(); for(DBID dbid : dbids) { NV obj =
* database.get(dbid); // Copy metadata to keep DatabaseObjectMetadata
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolCubeVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolCubeVisualization.java
index f088d219..9289c350 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolCubeVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolCubeVisualization.java
@@ -76,8 +76,7 @@ public class SelectionToolCubeVisualization extends AbstractVisFactory {
private static final String NAME = "Range Selection";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}.
+ * Constructor.
*/
public SelectionToolCubeVisualization() {
super();
@@ -261,7 +260,7 @@ public class SelectionToolCubeVisualization extends AbstractVisFactory {
selection.clear();
candidates: for (DBIDIter iditer = rel.iterDBIDs(); iditer.valid(); iditer.advance()) {
- NumberVector<?> dbTupel = rel.get(iditer);
+ NumberVector dbTupel = rel.get(iditer);
for (int i = 0; i < dim; i++) {
if (ranges != null && ranges[i] != null) {
if (dbTupel.doubleValue(i) < ranges[i].first || dbTupel.doubleValue(i) > ranges[i].second) {
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolDotVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolDotVisualization.java
index 6fa8200c..06b0e2ec 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolDotVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolDotVisualization.java
@@ -75,8 +75,7 @@ public class SelectionToolDotVisualization extends AbstractVisFactory {
}
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public SelectionToolDotVisualization() {
super();
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/package-info.java
index 86214f53..00422c31 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/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/visualization/visualizers/thumbs/ThumbnailThread.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailThread.java
index bf210fce..48a2b900 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailThread.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailThread.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.thumbs;
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/visualization/visualizers/thumbs/ThumbnailVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailVisualization.java
index 651f41c0..8ade1819 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.thumbs;
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/visualization/visualizers/visunproj/ClusterEvaluationVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/EvaluationVisualization.java
index 8d87945e..ea2ba9bc 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/EvaluationVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj;
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,20 +28,11 @@ import java.util.ArrayList;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.evaluation.clustering.BCubed;
-import de.lmu.ifi.dbs.elki.evaluation.clustering.ClusterContingencyTable;
-import de.lmu.ifi.dbs.elki.evaluation.clustering.EditDistance;
-import de.lmu.ifi.dbs.elki.evaluation.clustering.Entropy;
-import de.lmu.ifi.dbs.elki.evaluation.clustering.EvaluateClustering;
-import de.lmu.ifi.dbs.elki.evaluation.clustering.PairCounting;
-import de.lmu.ifi.dbs.elki.evaluation.clustering.SetMatchingPurity;
-import de.lmu.ifi.dbs.elki.math.MeanVariance;
+import de.lmu.ifi.dbs.elki.result.EvaluationResult;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary;
import de.lmu.ifi.dbs.elki.visualization.svg.SVGPlot;
@@ -54,6 +45,10 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization;
/**
* Pseudo-Visualizer, that lists the cluster evaluation results found.
*
+ * TODO: add indicator whether high values are better or low.
+ *
+ * TODO: add indication/warning when values are out-of-bounds.
+ *
* @author Erich Schubert
* @author Sascha Goldhofer
*
@@ -63,11 +58,11 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization;
* de.lmu.ifi.dbs.elki.evaluation.clustering.EvaluateClustering.ScoreResult
* oneway - - visualizes
*/
-public class ClusterEvaluationVisualization extends AbstractVisFactory {
+public class EvaluationVisualization extends AbstractVisFactory {
/**
* Name for this visualizer.
*/
- private static final String NAME = "Cluster Evaluation";
+ private static final String NAME = "Evaluation Bar Chart";
/**
* Constant: width of score bars
@@ -82,14 +77,14 @@ public class ClusterEvaluationVisualization extends AbstractVisFactory {
/**
* Constructor.
*/
- public ClusterEvaluationVisualization() {
+ public EvaluationVisualization() {
super();
}
@Override
public void processNewResult(HierarchicalResult baseResult, Result newResult) {
- final ArrayList<EvaluateClustering.ScoreResult> srs = ResultUtil.filterResults(newResult, EvaluateClustering.ScoreResult.class);
- for (EvaluateClustering.ScoreResult sr : srs) {
+ final ArrayList<EvaluationResult> srs = ResultUtil.filterResults(newResult, EvaluationResult.class);
+ for(EvaluationResult sr : srs) {
final VisualizationTask task = new VisualizationTask(NAME, sr, null, this);
task.width = .4;
task.height = 1.5;
@@ -98,9 +93,9 @@ public class ClusterEvaluationVisualization extends AbstractVisFactory {
}
}
- private double addBarChart(SVGPlot svgp, Element parent, double ypos, String label, double maxValue, double value) {
+ private double addBarChart(SVGPlot svgp, Element parent, double ypos, String label, double value, double minValue, double maxValue, double baseValue) {
SVGScoreBar barchart = new SVGScoreBar();
- barchart.setFill(value, maxValue);
+ barchart.setFill(value, baseValue == baseValue ? baseValue : minValue, maxValue);
barchart.showValues(FormatUtil.NF4);
barchart.addLabel(label);
parent.appendChild(barchart.build(svgp, 0.0, ypos, BARLENGTH, BARHEIGHT));
@@ -120,71 +115,29 @@ public class ClusterEvaluationVisualization extends AbstractVisFactory {
@Override
public Visualization makeVisualization(VisualizationTask task) {
// TODO: make a utility class to wrap SVGPlot + parent layer + ypos.
+ // TODO: use CSSClass and StyleLibrary
double ypos = -.5; // Skip space before first header
SVGPlot svgp = task.getPlot();
Element parent = svgp.svgElement(SVGConstants.SVG_G_TAG);
- EvaluateClustering.ScoreResult sr = task.getResult();
- ClusterContingencyTable cont = sr.getContingencyTable();
+ EvaluationResult sr = task.getResult();
- for (Hierarchy.Iter<Result> parents = task.getContext().getHierarchy().iterParents(sr); parents.valid(); parents.advance()) {
- Result r = parents.get();
- if (r instanceof Clustering) {
- ypos = addHeader(svgp, parent, ypos, r.getLongName());
- }
+ for(String header : sr.getHeaderLines()) {
+ ypos = addHeader(svgp, parent, ypos, header);
}
- // TODO: use CSSClass and StyleLibrary
-
- ypos = addHeader(svgp, parent, ypos, "Pair counting measures");
-
- PairCounting paircount = cont.getPaircount();
- ypos = addBarChart(svgp, parent, ypos, "Jaccard", 1, paircount.jaccard());
- ypos = addBarChart(svgp, parent, ypos, "F1-Measure", 1, paircount.f1Measure());
- ypos = addBarChart(svgp, parent, ypos, "Precision", 1, paircount.precision());
- ypos = addBarChart(svgp, parent, ypos, "Recall", 1, paircount.recall());
- ypos = addBarChart(svgp, parent, ypos, "Rand", 1, paircount.randIndex());
- ypos = addBarChart(svgp, parent, ypos, "ARI", 1, paircount.adjustedRandIndex());
- ypos = addBarChart(svgp, parent, ypos, "FowlkesMallows", 1, paircount.fowlkesMallows());
-
- ypos = addHeader(svgp, parent, ypos, "Entropy based measures");
-
- Entropy entropy = cont.getEntropy();
- ypos = addBarChart(svgp, parent, ypos, "NMI Joint", 1, entropy.entropyNMIJoint());
- ypos = addBarChart(svgp, parent, ypos, "NMI Sqrt", 1, entropy.entropyNMISqrt());
- ypos = addHeader(svgp, parent, ypos, "BCubed-based measures");
-
- BCubed bcubed = cont.getBCubed();
- ypos = addBarChart(svgp, parent, ypos, "F1-Measure", 1, bcubed.f1Measure());
- ypos = addBarChart(svgp, parent, ypos, "Recall", 1, bcubed.recall());
- ypos = addBarChart(svgp, parent, ypos, "Precision", 1, bcubed.precision());
-
- ypos = addHeader(svgp, parent, ypos, "Set-Matching-based measures");
-
- SetMatchingPurity setm = cont.getSetMatching();
- ypos = addBarChart(svgp, parent, ypos, "F1-Measure", 1, setm.f1Measure());
- ypos = addBarChart(svgp, parent, ypos, "Purity", 1, setm.purity());
- ypos = addBarChart(svgp, parent, ypos, "Inverse Purity", 1, setm.inversePurity());
-
- ypos = addHeader(svgp, parent, ypos, "Editing-distance measures");
-
- EditDistance edit = cont.getEdit();
- ypos = addBarChart(svgp, parent, ypos, "F1-Measure", 1, edit.f1Measure());
- ypos = addBarChart(svgp, parent, ypos, "Precision", 1, edit.editDistanceFirst());
- ypos = addBarChart(svgp, parent, ypos, "Recall", 1, edit.editDistanceSecond());
-
- ypos = addHeader(svgp, parent, ypos, "Gini measures");
-
- final MeanVariance gini = cont.averageSymmetricGini();
- ypos = addBarChart(svgp, parent, ypos, "Mean +-" + FormatUtil.format(gini.getSampleStddev(), FormatUtil.NF4), 1, gini.getMean());
+ for(EvaluationResult.MeasurementGroup g : sr) {
+ ypos = addHeader(svgp, parent, ypos, g.getName());
+ for(EvaluationResult.Measurement m : g) {
+ ypos = addBarChart(svgp, parent, ypos, m.getName(), m.getVal(), m.getMin(), m.getMax(), m.getExp());
+ }
+ }
// scale vis
- double cols = 10; // Math.max(10, (int) (i * task.getHeight() /
- // task.getWidth()));
- double rows = ypos;
+ double cols = 10;
final StyleLibrary style = task.getContext().getStyleResult().getStyleLibrary();
final double margin = style.getSize(StyleLibrary.MARGIN);
- final String transform = SVGUtil.makeMarginTransform(task.getWidth(), task.getHeight(), cols, rows, margin / StyleLibrary.SCALE);
+ final String transform = SVGUtil.makeMarginTransform(task.getWidth(), task.getHeight(), cols, ypos, margin / StyleLibrary.SCALE);
SVGUtil.setAtt(parent, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform);
return new StaticVisualizationInstance(task, parent);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisualization.java
index 77f096fb..60feb778 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj;
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
@@ -71,8 +71,7 @@ public class HistogramVisualization extends AbstractVisFactory {
private static final String SERIESID = "series";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public HistogramVisualization() {
super();
@@ -82,7 +81,7 @@ public class HistogramVisualization extends AbstractVisFactory {
public Visualization makeVisualization(VisualizationTask task) {
VisualizerContext context = task.getContext();
SVGPlot svgp = task.getPlot();
- HistogramResult<? extends NumberVector<?>> curve = task.getResult();
+ HistogramResult<? extends NumberVector> curve = task.getResult();
final StyleLibrary style = context.getStyleResult().getStyleLibrary();
final double sizex = StyleLibrary.SCALE;
@@ -96,7 +95,7 @@ public class HistogramVisualization extends AbstractVisFactory {
int dim = -1;
DoubleMinMax xminmax = new DoubleMinMax();
DoubleMinMax yminmax = new DoubleMinMax();
- for (NumberVector<?> vec : curve) {
+ for (NumberVector vec : curve) {
xminmax.put(vec.doubleValue(0));
if (dim < 0) {
dim = vec.getDimensionality();
@@ -104,7 +103,7 @@ public class HistogramVisualization extends AbstractVisFactory {
// TODO: test and throw always
assert (dim == vec.getDimensionality());
}
- for (int i = 0; i < dim; i++) {
+ for (int i = 1; i < dim; i++) {
yminmax.put(vec.doubleValue(i));
}
}
@@ -117,7 +116,7 @@ public class HistogramVisualization extends AbstractVisFactory {
double range = xminmax.getMax() - xminmax.getMin();
double binwidth = range / (size - 1);
- LinearScale xscale = new LinearScale(xminmax.getMin() - binwidth * .5, xminmax.getMax() + binwidth * .5);
+ LinearScale xscale = new LinearScale(xminmax.getMin() - binwidth * .49999, xminmax.getMax() + binwidth * .49999);
LinearScale yscale = new LinearScale(yminmax.getMin(), yminmax.getMax());
SVGPath[] path = new SVGPath[dim];
@@ -126,7 +125,7 @@ public class HistogramVisualization extends AbstractVisFactory {
}
// draw curves.
- for (NumberVector<?> vec : curve) {
+ for (NumberVector vec : curve) {
for (int d = 0; d < dim; d++) {
path[d].lineTo(sizex * (xscale.getScaled(vec.doubleValue(0) - binwidth * .5)), sizey * (1 - yscale.getScaled(vec.doubleValue(d + 1))));
path[d].lineTo(sizex * (xscale.getScaled(vec.doubleValue(0) + binwidth * .5)), sizey * (1 - yscale.getScaled(vec.doubleValue(d + 1))));
@@ -164,8 +163,8 @@ public class HistogramVisualization extends AbstractVisFactory {
@Override
public void processNewResult(HierarchicalResult baseResult, Result newResult) {
- List<HistogramResult<? extends NumberVector<?>>> histograms = ResultUtil.filterResults(newResult, HistogramResult.class);
- for (HistogramResult<? extends NumberVector<?>> histogram : histograms) {
+ List<HistogramResult<? extends NumberVector>> histograms = ResultUtil.filterResults(newResult, HistogramResult.class);
+ for (HistogramResult<? extends NumberVector> histogram : histograms) {
final VisualizationTask task = new VisualizationTask(NAME, histogram, null, this);
task.width = 2.0;
task.height = 1.0;
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisualization.java
index f18ef371..9576f3ca 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj;
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/visualization/visualizers/visunproj/LabelVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/LabelVisualization.java
index 0fe96e50..0738d499 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/LabelVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/LabelVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj;
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/visualization/visualizers/visunproj/PixmapVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/PixmapVisualizer.java
index 60080373..14e9c809 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/PixmapVisualizer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/PixmapVisualizer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj;
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
@@ -55,8 +55,7 @@ public class PixmapVisualizer extends AbstractVisFactory {
private static final String NAME = "Pixmap Visualizer";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public PixmapVisualizer() {
super();
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisualization.java
index d39d5bfd..ade20347 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj;
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,9 +32,8 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.SettingsResult;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackedParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.VisualizerContext;
import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary;
@@ -61,8 +60,7 @@ public class SettingsVisualization extends AbstractVisFactory {
private static final String NAME = "Settings";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public SettingsVisualization() {
super();
@@ -74,7 +72,7 @@ public class SettingsVisualization extends AbstractVisFactory {
VisualizerContext context = task.getContext();
SVGPlot svgp = task.getPlot();
- Collection<Pair<Object, Parameter<?>>> settings = sr.getSettings();
+ Collection<TrackedParameter> settings = sr.getSettings();
Element layer = svgp.svgElement(SVGConstants.SVG_G_TAG);
@@ -82,17 +80,17 @@ public class SettingsVisualization extends AbstractVisFactory {
int i = 0;
Object last = null;
- for(Pair<Object, Parameter<?>> setting : settings) {
- if(setting.first != last && setting.first != null) {
+ for(TrackedParameter setting : settings) {
+ if(setting.getOwner() != last && setting.getOwner() != null) {
String name;
try {
- if(setting.first instanceof Class) {
- name = ((Class<?>) setting.first).getName();
+ if(setting.getOwner() instanceof Class) {
+ name = ((Class<?>) setting.getOwner()).getName();
} else {
- name = setting.first.getClass().getName();
+ name = setting.getOwner().getClass().getName();
}
- if(ClassParameter.class.isInstance(setting.first)) {
- name = ((ClassParameter<?>) setting.first).getValue().getName();
+ if(ClassParameter.class.isInstance(setting.getOwner())) {
+ name = ((ClassParameter<?>) setting.getOwner()).getValue().getName();
}
}
catch(NullPointerException e) {
@@ -102,14 +100,14 @@ public class SettingsVisualization extends AbstractVisFactory {
object.setAttribute(SVGConstants.SVG_STYLE_ATTRIBUTE, "font-size: 0.6; font-weight: bold");
layer.appendChild(object);
i++;
- last = setting.first;
+ last = setting.getOwner();
}
// get name and value
- String name = setting.second.getOptionID().getName();
+ String name = setting.getParameter().getOptionID().getName();
String value = "[unset]";
try {
- if(setting.second.isDefined()) {
- value = setting.second.getValueAsString();
+ if(setting.getParameter().isDefined()) {
+ value = setting.getParameter().getValueAsString();
}
}
catch(NullPointerException e) {
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SimilarityMatrixVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SimilarityMatrixVisualizer.java
index b4570a32..d804d8c0 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SimilarityMatrixVisualizer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SimilarityMatrixVisualizer.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj;
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
@@ -60,8 +60,7 @@ public class SimilarityMatrixVisualizer extends AbstractVisFactory {
private static final String NAME = "Similarity Matrix Visualizer";
/**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
+ * Constructor.
*/
public SimilarityMatrixVisualizer() {
super();
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/XYCurveVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/XYCurveVisualization.java
index 691ab925..2a218065 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/XYCurveVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/XYCurveVisualization.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj;
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/workflow/AlgorithmStep.java b/src/de/lmu/ifi/dbs/elki/workflow/AlgorithmStep.java
index ff8d1c47..c264c259 100644
--- a/src/de/lmu/ifi/dbs/elki/workflow/AlgorithmStep.java
+++ b/src/de/lmu/ifi/dbs/elki/workflow/AlgorithmStep.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.workflow;
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
@@ -91,14 +91,11 @@ public class AlgorithmStep implements WorkflowStep {
}
}
for (Algorithm algorithm : algorithms) {
- Duration duration = LOG.isStatistics() ? LOG.newDuration(algorithm.getClass().getName()+".runtime") : null;
- if (duration != null) {
- duration.begin();
- }
+ Thread.currentThread().setName(algorithm.toString());
+ Duration duration = LOG.isStatistics() ? LOG.newDuration(algorithm.getClass().getName()+".runtime").begin() : null;
Result res = algorithm.run(database);
if (duration != null) {
- duration.end();
- LOG.statistics(duration);
+ LOG.statistics(duration.end());
}
if (LOG.isStatistics() && database.getIndexes().size() > 0) {
LOG.statistics("Index statistics after running algorithms:");
diff --git a/src/de/lmu/ifi/dbs/elki/workflow/EvaluationStep.java b/src/de/lmu/ifi/dbs/elki/workflow/EvaluationStep.java
index 0b6c9f8f..8ea4f2eb 100644
--- a/src/de/lmu/ifi/dbs/elki/workflow/EvaluationStep.java
+++ b/src/de/lmu/ifi/dbs/elki/workflow/EvaluationStep.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.workflow;
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
@@ -112,6 +112,7 @@ public class EvaluationStep implements WorkflowStep {
*/
public void update(Result r) {
for (Evaluator evaluator : evaluators) {
+ Thread.currentThread().setName(evaluator.toString());
/*
* if(normalizationUndo) { evaluator.setNormalization(normalization); }
*/
diff --git a/src/de/lmu/ifi/dbs/elki/workflow/InputStep.java b/src/de/lmu/ifi/dbs/elki/workflow/InputStep.java
index ea258889..bdcbf331 100644
--- a/src/de/lmu/ifi/dbs/elki/workflow/InputStep.java
+++ b/src/de/lmu/ifi/dbs/elki/workflow/InputStep.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.workflow;
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/workflow/LoggingStep.java b/src/de/lmu/ifi/dbs/elki/workflow/LoggingStep.java
index 9b598b0a..15865ff8 100644
--- a/src/de/lmu/ifi/dbs/elki/workflow/LoggingStep.java
+++ b/src/de/lmu/ifi/dbs/elki/workflow/LoggingStep.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.workflow;
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/workflow/OutputStep.java b/src/de/lmu/ifi/dbs/elki/workflow/OutputStep.java
index a196c752..74f65395 100644
--- a/src/de/lmu/ifi/dbs/elki/workflow/OutputStep.java
+++ b/src/de/lmu/ifi/dbs/elki/workflow/OutputStep.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.workflow;
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
@@ -33,7 +33,6 @@ 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.ObjectListParameter;
-import de.lmu.ifi.dbs.elki.visualization.gui.ResultVisualizer;
/**
* The "output" step, where data is analyzed.
@@ -66,7 +65,8 @@ public class OutputStep implements WorkflowStep {
*/
public void runResultHandlers(HierarchicalResult result) {
// Run result handlers
- for (ResultHandler resulthandler : resulthandlers) {
+ for(ResultHandler resulthandler : resulthandlers) {
+ Thread.currentThread().setName(resulthandler.toString());
resulthandler.processNewResult(result, result);
}
}
@@ -80,11 +80,20 @@ public class OutputStep implements WorkflowStep {
}
/**
- * Set the default handler to the {@link ResultVisualizer}.
+ * Set the default handler to the Batik addon visualizer, if available.
*/
+ @SuppressWarnings("unchecked")
public static void setDefaultHandlerVisualizer() {
defaultHandlers = new ArrayList<>(1);
- defaultHandlers.add(ResultVisualizer.class);
+ Class<? extends ResultHandler> clz;
+ try {
+ clz = (Class<? extends ResultHandler>) ClassLoader.getSystemClassLoader().loadClass(//
+ "de.lmu.ifi.dbs.elki.visualization.gui.ResultVisualizer");
+ }
+ catch(ClassNotFoundException e) {
+ clz = ResultWriter.class;
+ }
+ defaultHandlers.add(clz);
}
protected static ArrayList<Class<? extends ResultHandler>> defaultHandlers = null;
@@ -129,10 +138,10 @@ public class OutputStep implements WorkflowStep {
super.makeOptions(config);
// result handlers
final ObjectListParameter<ResultHandler> resultHandlerParam = new ObjectListParameter<>(RESULT_HANDLER_ID, ResultHandler.class);
- if (defaultHandlers != null) {
+ if(defaultHandlers != null) {
resultHandlerParam.setDefaultValue(defaultHandlers);
}
- if (config.grab(resultHandlerParam)) {
+ if(config.grab(resultHandlerParam)) {
resulthandlers = resultHandlerParam.instantiateClasses(config);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/workflow/WorkflowStep.java b/src/de/lmu/ifi/dbs/elki/workflow/WorkflowStep.java
index 9f9b54bf..549c261a 100644
--- a/src/de/lmu/ifi/dbs/elki/workflow/WorkflowStep.java
+++ b/src/de/lmu/ifi/dbs/elki/workflow/WorkflowStep.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.workflow;
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,6 @@ package de.lmu.ifi.dbs.elki.workflow;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
-
/**
* Trivial interface for workflow steps.
*
@@ -32,6 +30,6 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
*
* @author Erich Schubert
*/
-public interface WorkflowStep extends Parameterizable {
+public interface WorkflowStep {
// Empty
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/workflow/package-info.java b/src/de/lmu/ifi/dbs/elki/workflow/package-info.java
index 3e4396dd..a94f850f 100644
--- a/src/de/lmu/ifi/dbs/elki/workflow/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/workflow/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/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering1.java b/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering1.java
index 7477c064..b1406274 100644
--- a/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering1.java
+++ b/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering1.java
@@ -4,7 +4,7 @@ package tutorial.clustering;
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
@@ -46,7 +46,6 @@ import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
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.distancefunction.DistanceFunction;
-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.FiniteProgress;
import de.lmu.ifi.dbs.elki.result.Result;
@@ -69,7 +68,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*
* @param <O> Object type
*/
-public class NaiveAgglomerativeHierarchicalClustering1<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, Result> {
+public class NaiveAgglomerativeHierarchicalClustering1<O> extends AbstractDistanceBasedAlgorithm<O, Result> {
/**
* Class logger
*/
@@ -86,7 +85,7 @@ public class NaiveAgglomerativeHierarchicalClustering1<O, D extends NumberDistan
* @param distanceFunction Distance function to use
* @param numclusters Number of clusters
*/
- public NaiveAgglomerativeHierarchicalClustering1(DistanceFunction<? super O, D> distanceFunction, int numclusters) {
+ public NaiveAgglomerativeHierarchicalClustering1(DistanceFunction<? super O> distanceFunction, int numclusters) {
super(distanceFunction);
this.numclusters = numclusters;
}
@@ -99,7 +98,7 @@ public class NaiveAgglomerativeHierarchicalClustering1<O, D extends NumberDistan
* @return Clustering hierarchy
*/
public Result run(Database db, Relation<O> relation) {
- DistanceQuery<O, D> dq = db.getDistanceQuery(relation, getDistanceFunction());
+ DistanceQuery<O> dq = db.getDistanceQuery(relation, getDistanceFunction());
ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs());
final int size = ids.size();
@@ -108,10 +107,10 @@ public class NaiveAgglomerativeHierarchicalClustering1<O, D extends NumberDistan
// Compute the initial distance matrix.
double[][] matrix = new double[size][size];
DBIDArrayIter ix = ids.iter(), iy = ids.iter();
- for (int x = 0; ix.valid(); x++, ix.advance()) {
+ for(int x = 0; ix.valid(); x++, ix.advance()) {
iy.seek(0);
- for (int y = 0; y < x; y++, iy.advance()) {
- final double dist = dq.distance(ix, iy).doubleValue();
+ for(int y = 0; y < x; y++, iy.advance()) {
+ final double dist = dq.distance(ix, iy);
matrix[x][y] = dist;
matrix[y][x] = dist;
}
@@ -129,18 +128,18 @@ public class NaiveAgglomerativeHierarchicalClustering1<O, D extends NumberDistan
// Repeat until everything merged, except the desired number of clusters:
final int stop = size - numclusters;
FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Agglomerative clustering", stop, LOG) : null;
- for (int i = 0; i < stop; i++) {
+ for(int i = 0; i < stop; i++) {
double min = Double.POSITIVE_INFINITY;
int minx = -1, miny = -1;
- for (int x = 0; x < size; x++) {
- if (height[x] < Double.POSITIVE_INFINITY) {
+ for(int x = 0; x < size; x++) {
+ if(height[x] < Double.POSITIVE_INFINITY) {
continue;
}
- for (int y = 0; y < x; y++) {
- if (height[y] < Double.POSITIVE_INFINITY) {
+ for(int y = 0; y < x; y++) {
+ if(height[y] < Double.POSITIVE_INFINITY) {
continue;
}
- if (matrix[x][y] < min) {
+ if(matrix[x][y] < min) {
min = matrix[x][y];
minx = x;
miny = y;
@@ -158,36 +157,33 @@ public class NaiveAgglomerativeHierarchicalClustering1<O, D extends NumberDistan
// Merge into cluster
ModifiableDBIDs cx = clusters.get(minx);
ModifiableDBIDs cy = clusters.get(miny);
- if (cy == null) {
+ if(cy == null) {
cy = DBIDUtil.newHashSet();
cy.add(iy);
}
- if (cx == null) {
+ if(cx == null) {
cy.add(ix);
- } else {
+ }
+ else {
cy.addDBIDs(cx);
clusters.remove(minx);
}
clusters.put(miny, cy);
// Update distance matrix for y:
- for (int j = 0; j < size; j++) {
+ for(int j = 0; j < size; j++) {
matrix[j][miny] = Math.min(matrix[j][minx], matrix[j][miny]);
matrix[miny][j] = Math.min(matrix[minx][j], matrix[miny][j]);
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if (prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
// Build the clustering result
final Clustering<Model> dendrogram = new Clustering<>("Hierarchical-Clustering", "hierarchical-clustering");
- for (int x = 0; x < size; x++) {
- if (height[x] < Double.POSITIVE_INFINITY) {
+ for(int x = 0; x < size; x++) {
+ if(height[x] < Double.POSITIVE_INFINITY) {
DBIDs cids = clusters.get(x);
- if (cids == null) {
+ if(cids == null) {
ix.seek(x);
cids = DBIDUtil.deref(ix);
}
@@ -214,10 +210,11 @@ public class NaiveAgglomerativeHierarchicalClustering1<O, D extends NumberDistan
*
* @author Erich Schubert
*
+ * @apiviz.exclude
+ *
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Desired number of clusters.
*/
@@ -228,13 +225,13 @@ public class NaiveAgglomerativeHierarchicalClustering1<O, D extends NumberDistan
super.makeOptions(config);
IntParameter numclustersP = new IntParameter(ExtractFlatClusteringFromHierarchy.Parameterizer.MINCLUSTERS_ID);
numclustersP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
- if (config.grab(numclustersP)) {
+ if(config.grab(numclustersP)) {
numclusters = numclustersP.intValue();
}
}
@Override
- protected NaiveAgglomerativeHierarchicalClustering1<O, D> makeInstance() {
+ protected NaiveAgglomerativeHierarchicalClustering1<O> makeInstance() {
return new NaiveAgglomerativeHierarchicalClustering1<>(distanceFunction, numclusters);
}
}
diff --git a/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering2.java b/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering2.java
index d33ca768..0081a845 100644
--- a/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering2.java
+++ b/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering2.java
@@ -4,7 +4,7 @@ package tutorial.clustering;
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
@@ -46,7 +46,6 @@ import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
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.distancefunction.DistanceFunction;
-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.FiniteProgress;
import de.lmu.ifi.dbs.elki.result.Result;
@@ -69,7 +68,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*
* @param <O> Object type
*/
-public class NaiveAgglomerativeHierarchicalClustering2<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, Result> {
+public class NaiveAgglomerativeHierarchicalClustering2<O> extends AbstractDistanceBasedAlgorithm<O, Result> {
/**
* Class logger
*/
@@ -86,7 +85,7 @@ public class NaiveAgglomerativeHierarchicalClustering2<O, D extends NumberDistan
* @param distanceFunction Distance function to use
* @param numclusters Number of clusters
*/
- public NaiveAgglomerativeHierarchicalClustering2(DistanceFunction<? super O, D> distanceFunction, int numclusters) {
+ public NaiveAgglomerativeHierarchicalClustering2(DistanceFunction<? super O> distanceFunction, int numclusters) {
super(distanceFunction);
this.numclusters = numclusters;
}
@@ -99,7 +98,7 @@ public class NaiveAgglomerativeHierarchicalClustering2<O, D extends NumberDistan
* @return Clustering hierarchy
*/
public Result run(Database db, Relation<O> relation) {
- DistanceQuery<O, D> dq = db.getDistanceQuery(relation, getDistanceFunction());
+ DistanceQuery<O> dq = db.getDistanceQuery(relation, getDistanceFunction());
ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs());
final int size = ids.size();
@@ -116,7 +115,7 @@ public class NaiveAgglomerativeHierarchicalClustering2<O, D extends NumberDistan
for (int x = 0; ix.valid(); x++, ix.advance()) {
iy.seek(0);
for (int y = 0; y < x; y++, iy.advance()) {
- scratch[pos] = dq.distance(ix, iy).doubleValue();
+ scratch[pos] = dq.distance(ix, iy);
pos++;
}
}
@@ -200,13 +199,9 @@ public class NaiveAgglomerativeHierarchicalClustering2<O, D extends NumberDistan
final int jbase = triangleSize(j);
scratch[jbase + miny] = Math.min(scratch[jbase + minx], scratch[jbase + miny]);
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if (prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
// Build the clustering result
final Clustering<Model> dendrogram = new Clustering<>("Hierarchical-Clustering", "hierarchical-clustering");
@@ -251,10 +246,11 @@ public class NaiveAgglomerativeHierarchicalClustering2<O, D extends NumberDistan
*
* @author Erich Schubert
*
+ * @apiviz.exclude
+ *
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Desired number of clusters.
*/
@@ -271,7 +267,7 @@ public class NaiveAgglomerativeHierarchicalClustering2<O, D extends NumberDistan
}
@Override
- protected NaiveAgglomerativeHierarchicalClustering2<O, D> makeInstance() {
+ protected NaiveAgglomerativeHierarchicalClustering2<O> makeInstance() {
return new NaiveAgglomerativeHierarchicalClustering2<>(distanceFunction, numclusters);
}
}
diff --git a/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering3.java b/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering3.java
index d3312115..0b1590bd 100644
--- a/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering3.java
+++ b/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering3.java
@@ -4,7 +4,7 @@ package tutorial.clustering;
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
@@ -47,7 +47,6 @@ 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.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
-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.FiniteProgress;
import de.lmu.ifi.dbs.elki.result.Result;
@@ -81,7 +80,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* @param <O> Object type
*/
@Reference(title = "A Review of Classification", authors = "R. M. Cormack", booktitle = "Journal of the Royal Statistical Society. Series A, Vol. 134, No. 3", url = "http://www.jstor.org/stable/2344237")
-public class NaiveAgglomerativeHierarchicalClustering3<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, Result> {
+public class NaiveAgglomerativeHierarchicalClustering3<O> extends AbstractDistanceBasedAlgorithm<O, Result> {
/**
* Class logger
*/
@@ -94,6 +93,8 @@ public class NaiveAgglomerativeHierarchicalClustering3<O, D extends NumberDistan
* R. M. Cormack, A Review of Classification
*
* @author Erich Schubert
+ *
+ * @apiviz.exclude
*/
public static enum Linkage {//
SINGLE {
@@ -168,7 +169,7 @@ public class NaiveAgglomerativeHierarchicalClustering3<O, D extends NumberDistan
* @param numclusters Number of clusters
* @param linkage Linkage strategy
*/
- public NaiveAgglomerativeHierarchicalClustering3(DistanceFunction<? super O, D> distanceFunction, int numclusters, Linkage linkage) {
+ public NaiveAgglomerativeHierarchicalClustering3(DistanceFunction<? super O> distanceFunction, int numclusters, Linkage linkage) {
super(distanceFunction);
this.numclusters = numclusters;
this.linkage = linkage;
@@ -182,14 +183,14 @@ public class NaiveAgglomerativeHierarchicalClustering3<O, D extends NumberDistan
* @return Clustering hierarchy
*/
public Result run(Database db, Relation<O> relation) {
- DistanceQuery<O, D> dq = db.getDistanceQuery(relation, getDistanceFunction());
+ DistanceQuery<O> dq = db.getDistanceQuery(relation, getDistanceFunction());
ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs());
final int size = ids.size();
- if (size > 0x10000) {
+ if(size > 0x10000) {
throw new AbortException("This implementation does not scale to data sets larger than " + 0x10000 + " instances (~17 GB RAM), which results in an integer overflow.");
}
- if (Linkage.SINGLE.equals(linkage)) {
+ if(Linkage.SINGLE.equals(linkage)) {
LOG.verbose("Notice: SLINK is a much faster algorithm for single-linkage clustering!");
}
@@ -199,12 +200,12 @@ public class NaiveAgglomerativeHierarchicalClustering3<O, D extends NumberDistan
// Position counter - must agree with computeOffset!
int pos = 0;
boolean square = Linkage.WARD.equals(linkage) && !(SquaredEuclideanDistanceFunction.class.isInstance(getDistanceFunction()));
- for (int x = 0; ix.valid(); x++, ix.advance()) {
+ for(int x = 0; ix.valid(); x++, ix.advance()) {
iy.seek(0);
- for (int y = 0; y < x; y++, iy.advance()) {
- scratch[pos] = dq.distance(ix, iy).doubleValue();
+ for(int y = 0; y < x; y++, iy.advance()) {
+ scratch[pos] = dq.distance(ix, iy);
// Ward uses variances -- i.e. squared values
- if (square) {
+ if(square) {
scratch[pos] *= scratch[pos];
}
pos++;
@@ -223,20 +224,20 @@ public class NaiveAgglomerativeHierarchicalClustering3<O, D extends NumberDistan
// Repeat until everything merged, except the desired number of clusters:
final int stop = size - numclusters;
FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Agglomerative clustering", stop, LOG) : null;
- for (int i = 0; i < stop; i++) {
+ for(int i = 0; i < stop; i++) {
double min = Double.POSITIVE_INFINITY;
int minx = -1, miny = -1;
- for (int x = 0; x < size; x++) {
- if (height[x] < Double.POSITIVE_INFINITY) {
+ for(int x = 0; x < size; x++) {
+ if(height[x] < Double.POSITIVE_INFINITY) {
continue;
}
final int xbase = triangleSize(x);
- for (int y = 0; y < x; y++) {
- if (height[y] < Double.POSITIVE_INFINITY) {
+ for(int y = 0; y < x; y++) {
+ if(height[y] < Double.POSITIVE_INFINITY) {
continue;
}
final int idx = xbase + y;
- if (scratch[idx] < min) {
+ if(scratch[idx] < min) {
min = scratch[idx];
minx = x;
miny = y;
@@ -255,15 +256,17 @@ public class NaiveAgglomerativeHierarchicalClustering3<O, D extends NumberDistan
ModifiableDBIDs cx = clusters.get(minx);
ModifiableDBIDs cy = clusters.get(miny);
int sizex = 1, sizey = 1; // cluster sizes, for averaging
- if (cy == null) {
+ if(cy == null) {
cy = DBIDUtil.newHashSet();
cy.add(iy);
- } else {
+ }
+ else {
sizey = cy.size();
}
- if (cx == null) {
+ if(cx == null) {
cy.add(ix);
- } else {
+ }
+ else {
sizex = cx.size();
cy.addDBIDs(cx);
clusters.remove(minx);
@@ -276,8 +279,8 @@ public class NaiveAgglomerativeHierarchicalClustering3<O, D extends NumberDistan
// hashmap lookup.
final int xbase = triangleSize(minx), ybase = triangleSize(miny);
// Write to (y, j), with j < y
- for (int j = 0; j < miny; j++) {
- if (height[j] < Double.POSITIVE_INFINITY) {
+ for(int j = 0; j < miny; j++) {
+ if(height[j] < Double.POSITIVE_INFINITY) {
continue;
}
final DBIDs idsj = clusters.get(j);
@@ -285,8 +288,8 @@ public class NaiveAgglomerativeHierarchicalClustering3<O, D extends NumberDistan
scratch[ybase + j] = linkage.combine(sizex, scratch[xbase + j], sizey, scratch[ybase + j], sizej, min);
}
// Write to (j, y), with y < j < x
- for (int j = miny + 1; j < minx; j++) {
- if (height[j] < Double.POSITIVE_INFINITY) {
+ for(int j = miny + 1; j < minx; j++) {
+ if(height[j] < Double.POSITIVE_INFINITY) {
continue;
}
final int jbase = triangleSize(j);
@@ -295,8 +298,8 @@ public class NaiveAgglomerativeHierarchicalClustering3<O, D extends NumberDistan
scratch[jbase + miny] = linkage.combine(sizex, scratch[xbase + j], sizey, scratch[jbase + miny], sizej, min);
}
// Write to (j, y), with y < x < j
- for (int j = minx + 1; j < size; j++) {
- if (height[j] < Double.POSITIVE_INFINITY) {
+ for(int j = minx + 1; j < size; j++) {
+ if(height[j] < Double.POSITIVE_INFINITY) {
continue;
}
final DBIDs idsj = clusters.get(j);
@@ -304,20 +307,16 @@ public class NaiveAgglomerativeHierarchicalClustering3<O, D extends NumberDistan
final int jbase = triangleSize(j);
scratch[jbase + miny] = linkage.combine(sizex, scratch[jbase + minx], sizey, scratch[jbase + miny], sizej, min);
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if (prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
// Build the clustering result
final Clustering<Model> dendrogram = new Clustering<>("Hierarchical-Clustering", "hierarchical-clustering");
- for (int x = 0; x < size; x++) {
- if (height[x] < Double.POSITIVE_INFINITY) {
+ for(int x = 0; x < size; x++) {
+ if(height[x] < Double.POSITIVE_INFINITY) {
DBIDs cids = clusters.get(x);
- if (cids == null) {
+ if(cids == null) {
ix.seek(x);
cids = DBIDUtil.deref(ix);
}
@@ -355,10 +354,11 @@ public class NaiveAgglomerativeHierarchicalClustering3<O, D extends NumberDistan
*
* @author Erich Schubert
*
+ * @apiviz.exclude
+ *
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Option ID for linkage parameter.
*/
@@ -379,19 +379,19 @@ public class NaiveAgglomerativeHierarchicalClustering3<O, D extends NumberDistan
super.makeOptions(config);
IntParameter numclustersP = new IntParameter(ExtractFlatClusteringFromHierarchy.Parameterizer.MINCLUSTERS_ID);
numclustersP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
- if (config.grab(numclustersP)) {
+ if(config.grab(numclustersP)) {
numclusters = numclustersP.intValue();
}
EnumParameter<Linkage> linkageP = new EnumParameter<>(LINKAGE_ID, Linkage.class);
linkageP.setDefaultValue(Linkage.WARD);
- if (config.grab(linkageP)) {
+ if(config.grab(linkageP)) {
linkage = linkageP.getValue();
}
}
@Override
- protected NaiveAgglomerativeHierarchicalClustering3<O, D> makeInstance() {
+ protected NaiveAgglomerativeHierarchicalClustering3<O> makeInstance() {
return new NaiveAgglomerativeHierarchicalClustering3<>(distanceFunction, numclusters, linkage);
}
}
diff --git a/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering4.java b/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering4.java
index 23678ccc..997b657a 100644
--- a/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering4.java
+++ b/src/tutorial/clustering/NaiveAgglomerativeHierarchicalClustering4.java
@@ -4,7 +4,7 @@ package tutorial.clustering;
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
@@ -33,7 +33,7 @@ import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDBIDDataStore;
-import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDistanceDataStore;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
@@ -43,8 +43,6 @@ 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.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
-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.FiniteProgress;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
@@ -75,7 +73,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.EnumParameter;
* @param <O> Object type
*/
@Reference(title = "A Review of Classification", authors = "R. M. Cormack", booktitle = "Journal of the Royal Statistical Society. Series A, Vol. 134, No. 3", url = "http://www.jstor.org/stable/2344237")
-public class NaiveAgglomerativeHierarchicalClustering4<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, PointerHierarchyRepresentationResult<DoubleDistance>> implements HierarchicalClusteringAlgorithm<DoubleDistance> {
+public class NaiveAgglomerativeHierarchicalClustering4<O> extends AbstractDistanceBasedAlgorithm<O, PointerHierarchyRepresentationResult> implements HierarchicalClusteringAlgorithm {
/**
* Class logger
*/
@@ -88,6 +86,8 @@ public class NaiveAgglomerativeHierarchicalClustering4<O, D extends NumberDistan
* R. M. Cormack, A Review of Classification
*
* @author Erich Schubert
+ *
+ * @apiviz.exclude
*/
public static enum Linkage {//
SINGLE {
@@ -156,7 +156,7 @@ public class NaiveAgglomerativeHierarchicalClustering4<O, D extends NumberDistan
* @param distanceFunction Distance function to use
* @param linkage Linkage strategy
*/
- public NaiveAgglomerativeHierarchicalClustering4(DistanceFunction<? super O, D> distanceFunction, Linkage linkage) {
+ public NaiveAgglomerativeHierarchicalClustering4(DistanceFunction<? super O> distanceFunction, Linkage linkage) {
super(distanceFunction);
this.linkage = linkage;
}
@@ -168,15 +168,15 @@ public class NaiveAgglomerativeHierarchicalClustering4<O, D extends NumberDistan
* @param relation Relation
* @return Clustering hierarchy
*/
- public PointerHierarchyRepresentationResult<DoubleDistance> run(Database db, Relation<O> relation) {
- DistanceQuery<O, D> dq = db.getDistanceQuery(relation, getDistanceFunction());
+ public PointerHierarchyRepresentationResult run(Database db, Relation<O> relation) {
+ DistanceQuery<O> dq = db.getDistanceQuery(relation, getDistanceFunction());
ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs());
final int size = ids.size();
- if (size > 0x10000) {
+ if(size > 0x10000) {
throw new AbortException("This implementation does not scale to data sets larger than " + 0x10000 + " instances (~17 GB RAM), which results in an integer overflow.");
}
- if (Linkage.SINGLE.equals(linkage)) {
+ if(Linkage.SINGLE.equals(linkage)) {
LOG.verbose("Notice: SLINK is a much faster algorithm for single-linkage clustering!");
}
@@ -186,12 +186,12 @@ public class NaiveAgglomerativeHierarchicalClustering4<O, D extends NumberDistan
// Position counter - must agree with computeOffset!
int pos = 0;
boolean square = Linkage.WARD.equals(linkage) && !(SquaredEuclideanDistanceFunction.class.isInstance(getDistanceFunction()));
- for (int x = 0; ix.valid(); x++, ix.advance()) {
+ for(int x = 0; ix.valid(); x++, ix.advance()) {
iy.seek(0);
- for (int y = 0; y < x; y++, iy.advance()) {
- scratch[pos] = dq.distance(ix, iy).doubleValue();
+ for(int y = 0; y < x; y++, iy.advance()) {
+ scratch[pos] = dq.distance(ix, iy);
// Ward uses variances -- i.e. squared values
- if (square) {
+ if(square) {
scratch[pos] *= scratch[pos];
}
pos++;
@@ -200,9 +200,9 @@ public class NaiveAgglomerativeHierarchicalClustering4<O, D extends NumberDistan
// Initialize space for result:
WritableDBIDDataStore parent = DataStoreUtil.makeDBIDStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_STATIC);
- WritableDoubleDistanceDataStore height = DataStoreUtil.makeDoubleDistanceStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_STATIC);
+ WritableDoubleDataStore height = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_STATIC);
WritableIntegerDataStore csize = DataStoreUtil.makeIntegerStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
- for (DBIDIter it = ids.iter(); it.valid(); it.advance()) {
+ for(DBIDIter it = ids.iter(); it.valid(); it.advance()) {
parent.put(it, it);
height.put(it, Double.POSITIVE_INFINITY);
csize.put(it, 1);
@@ -210,20 +210,20 @@ public class NaiveAgglomerativeHierarchicalClustering4<O, D extends NumberDistan
// Repeat until everything merged, except the desired number of clusters:
FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Agglomerative clustering", size - 1, LOG) : null;
- for (int i = 1; i < size; i++) {
+ for(int i = 1; i < size; i++) {
double min = Double.POSITIVE_INFINITY;
int minx = -1, miny = -1;
- for (ix.seek(0); ix.valid(); ix.advance()) {
- if (height.doubleValue(ix) < Double.POSITIVE_INFINITY) {
+ for(ix.seek(0); ix.valid(); ix.advance()) {
+ if(height.doubleValue(ix) < Double.POSITIVE_INFINITY) {
continue;
}
final int xbase = triangleSize(ix.getOffset());
- for (iy.seek(0); iy.getOffset() < ix.getOffset(); iy.advance()) {
- if (height.doubleValue(iy) < Double.POSITIVE_INFINITY) {
+ for(iy.seek(0); iy.getOffset() < ix.getOffset(); iy.advance()) {
+ if(height.doubleValue(iy) < Double.POSITIVE_INFINITY) {
continue;
}
final int idx = xbase + iy.getOffset();
- if (scratch[idx] <= min) {
+ if(scratch[idx] <= min) {
min = scratch[idx];
minx = ix.getOffset();
miny = iy.getOffset();
@@ -244,16 +244,16 @@ public class NaiveAgglomerativeHierarchicalClustering4<O, D extends NumberDistan
// Update distance matrix. Note: miny < minx
final int xbase = triangleSize(minx), ybase = triangleSize(miny);
// Write to (y, j), with j < y
- for (ij.seek(0); ij.getOffset() < miny; ij.advance()) {
- if (height.doubleValue(ij) < Double.POSITIVE_INFINITY) {
+ for(ij.seek(0); ij.getOffset() < miny; ij.advance()) {
+ if(height.doubleValue(ij) < Double.POSITIVE_INFINITY) {
continue;
}
final int sizej = csize.intValue(ij);
scratch[ybase + ij.getOffset()] = linkage.combine(sizex, scratch[xbase + ij.getOffset()], sizey, scratch[ybase + ij.getOffset()], sizej, min);
}
// Write to (j, y), with y < j < x
- for (ij.seek(miny + 1); ij.getOffset() < minx; ij.advance()) {
- if (height.doubleValue(ij) < Double.POSITIVE_INFINITY) {
+ for(ij.seek(miny + 1); ij.getOffset() < minx; ij.advance()) {
+ if(height.doubleValue(ij) < Double.POSITIVE_INFINITY) {
continue;
}
final int jbase = triangleSize(ij.getOffset());
@@ -261,23 +261,19 @@ public class NaiveAgglomerativeHierarchicalClustering4<O, D extends NumberDistan
scratch[jbase + miny] = linkage.combine(sizex, scratch[xbase + ij.getOffset()], sizey, scratch[jbase + miny], sizej, min);
}
// Write to (j, y), with y < x < j
- for (ij.seek(minx + 1); ij.valid(); ij.advance()) {
- if (height.doubleValue(ij) < Double.POSITIVE_INFINITY) {
+ for(ij.seek(minx + 1); ij.valid(); ij.advance()) {
+ if(height.doubleValue(ij) < Double.POSITIVE_INFINITY) {
continue;
}
final int jbase = triangleSize(ij.getOffset());
final int sizej = csize.intValue(ij);
scratch[jbase + miny] = linkage.combine(sizex, scratch[jbase + minx], sizey, scratch[jbase + miny], sizej, min);
}
- if (prog != null) {
- prog.incrementProcessed(LOG);
- }
- }
- if (prog != null) {
- prog.ensureCompleted(LOG);
+ LOG.incrementProcessed(prog);
}
+ LOG.ensureCompleted(prog);
- return new PointerHierarchyRepresentationResult<>(ids, parent, height);
+ return new PointerHierarchyRepresentationResult(ids, parent, height);
}
/**
@@ -301,20 +297,16 @@ public class NaiveAgglomerativeHierarchicalClustering4<O, D extends NumberDistan
return LOG;
}
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
- }
-
/**
* Parameterization class
*
* @author Erich Schubert
*
+ * @apiviz.exclude
+ *
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Option ID for linkage parameter.
*/
@@ -330,13 +322,13 @@ public class NaiveAgglomerativeHierarchicalClustering4<O, D extends NumberDistan
super.makeOptions(config);
EnumParameter<Linkage> linkageP = new EnumParameter<>(LINKAGE_ID, Linkage.class);
linkageP.setDefaultValue(Linkage.WARD);
- if (config.grab(linkageP)) {
+ if(config.grab(linkageP)) {
linkage = linkageP.getValue();
}
}
@Override
- protected NaiveAgglomerativeHierarchicalClustering4<O, D> makeInstance() {
+ protected NaiveAgglomerativeHierarchicalClustering4<O> makeInstance() {
return new NaiveAgglomerativeHierarchicalClustering4<>(distanceFunction, linkage);
}
}
diff --git a/src/tutorial/clustering/SameSizeKMeansAlgorithm.java b/src/tutorial/clustering/SameSizeKMeansAlgorithm.java
index 91da44c5..ad57885e 100644
--- a/src/tutorial/clustering/SameSizeKMeansAlgorithm.java
+++ b/src/tutorial/clustering/SameSizeKMeansAlgorithm.java
@@ -4,7 +4,7 @@ package tutorial.clustering;
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,8 @@ import java.util.Comparator;
import java.util.List;
import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.AbstractKMeans;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansInitialization;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansPlusPlusInitialMeans;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansInitialization;
+import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.KMeansPlusPlusInitialMeans;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
@@ -48,12 +48,11 @@ 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.ModifiableDBIDs;
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.distancefunction.PrimitiveDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerArrayQuickSort;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.IntegerComparator;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -78,7 +77,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @param <V> Vector type
*/
-public class SameSizeKMeansAlgorithm<V extends NumberVector<?>> extends AbstractKMeans<V, DoubleDistance, MeanModel<V>> {
+public class SameSizeKMeansAlgorithm<V extends NumberVector> extends AbstractKMeans<V, MeanModel> {
/**
* Class logger
*/
@@ -92,7 +91,7 @@ public class SameSizeKMeansAlgorithm<V extends NumberVector<?>> extends Abstract
* @param maxiter Maximum number of iterations
* @param initializer
*/
- public SameSizeKMeansAlgorithm(PrimitiveDoubleDistanceFunction<? super NumberVector<?>> distanceFunction, int k, int maxiter, KMeansInitialization<V> initializer) {
+ public SameSizeKMeansAlgorithm(PrimitiveDistanceFunction<? super NumberVector> distanceFunction, int k, int maxiter, KMeansInitialization<? super V> initializer) {
super(distanceFunction, k, maxiter, initializer);
}
@@ -104,11 +103,11 @@ public class SameSizeKMeansAlgorithm<V extends NumberVector<?>> extends Abstract
* @return result
*/
@Override
- public Clustering<MeanModel<V>> run(Database database, Relation<V> relation) {
+ public Clustering<MeanModel> run(Database database, Relation<V> relation) {
// Database objects to process
final DBIDs ids = relation.getDBIDs();
// Choose initial means
- List<? extends NumberVector<?>> means = initializer.chooseInitialMeans(database, relation, k, getDistanceFunction());
+ List<Vector> means = initializer.chooseInitialMeans(database, relation, k, getDistanceFunction(), Vector.FACTORY);
// Setup cluster assignment store
List<ModifiableDBIDs> clusters = new ArrayList<>();
for(int i = 0; i < k; i++) {
@@ -125,11 +124,10 @@ public class SameSizeKMeansAlgorithm<V extends NumberVector<?>> extends Abstract
means = refineResult(relation, means, clusters, metas, tids);
// Wrap result
- Clustering<MeanModel<V>> result = new Clustering<>("k-Means Samesize Clustering", "kmeans-samesize-clustering");
- final NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(relation);
+ Clustering<MeanModel> result = new Clustering<>("k-Means Samesize Clustering", "kmeans-samesize-clustering");
for(int i = 0; i < clusters.size(); i++) {
- V mean = factory.newNumberVector(means.get(i).getColumnVector().getArrayRef());
- result.addToplevelCluster(new Cluster<>(clusters.get(i), new MeanModel<>(mean)));
+ Vector mean = means.get(i).getColumnVector();
+ result.addToplevelCluster(new Cluster<>(clusters.get(i), new MeanModel(mean)));
}
return result;
}
@@ -141,10 +139,8 @@ public class SameSizeKMeansAlgorithm<V extends NumberVector<?>> extends Abstract
* @param means Mean vectors
* @return Initialized storage
*/
- protected WritableDataStore<Meta> initializeMeta(Relation<V> relation, List<? extends NumberVector<?>> means) {
- // This is a safe cast - see constructor.
- @SuppressWarnings("unchecked")
- PrimitiveDoubleDistanceFunction<NumberVector<?>> df = (PrimitiveDoubleDistanceFunction<NumberVector<?>>) getDistanceFunction();
+ protected WritableDataStore<Meta> initializeMeta(Relation<V> relation, List<? extends NumberVector> means) {
+ PrimitiveDistanceFunction<? super NumberVector> df = getDistanceFunction();
// The actual storage
final WritableDataStore<Meta> metas = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, Meta.class);
// Build the metadata, track the two nearest cluster centers.
@@ -152,7 +148,7 @@ public class SameSizeKMeansAlgorithm<V extends NumberVector<?>> extends Abstract
Meta c = new Meta(k);
V fv = relation.get(id);
for(int i = 0; i < k; i++) {
- c.dists[i] = df.doubleDistance(fv, means.get(i));
+ c.dists[i] = df.distance(fv, means.get(i));
if(i > 0) {
if(c.dists[i] < c.dists[c.primary]) {
c.primary = i;
@@ -231,14 +227,14 @@ public class SameSizeKMeansAlgorithm<V extends NumberVector<?>> extends Abstract
* @param metas Metadata storage
* @param df Distance function
*/
- protected void updateDistances(Relation<V> relation, List<? extends NumberVector<?>> means, final WritableDataStore<Meta> metas, PrimitiveDoubleDistanceFunction<NumberVector<?>> df) {
+ protected void updateDistances(Relation<V> relation, List<Vector> means, final WritableDataStore<Meta> metas, PrimitiveDistanceFunction<? super NumberVector> df) {
for(DBIDIter id = relation.iterDBIDs(); id.valid(); id.advance()) {
Meta c = metas.get(id);
V fv = relation.get(id);
// Update distances to means.
c.secondary = -1;
for(int i = 0; i < k; i++) {
- c.dists[i] = df.doubleDistance(fv, means.get(i));
+ c.dists[i] = df.distance(fv, means.get(i));
if(c.primary != i) {
if(c.secondary < 0 || c.dists[i] < c.dists[c.secondary]) {
c.secondary = i;
@@ -259,10 +255,9 @@ public class SameSizeKMeansAlgorithm<V extends NumberVector<?>> extends Abstract
* @param tids DBIDs array
* @return final means
*/
- protected List<? extends NumberVector<?>> refineResult(Relation<V> relation, List<? extends NumberVector<?>> means, List<ModifiableDBIDs> clusters, final WritableDataStore<Meta> metas, ArrayModifiableDBIDs tids) {
+ protected List<Vector> refineResult(Relation<V> relation, List<Vector> means, List<ModifiableDBIDs> clusters, final WritableDataStore<Meta> metas, ArrayModifiableDBIDs tids) {
// This is a safe cast - see constructor.
- @SuppressWarnings("unchecked")
- PrimitiveDoubleDistanceFunction<NumberVector<?>> df = (PrimitiveDoubleDistanceFunction<NumberVector<?>>) getDistanceFunction();
+ PrimitiveDistanceFunction<? super NumberVector> df = getDistanceFunction();
// Our desired cluster size:
final int minsize = tids.size() / k; // rounded down
final int maxsize = (tids.size() + k - 1) / k; // rounded up
@@ -289,7 +284,7 @@ public class SameSizeKMeansAlgorithm<V extends NumberVector<?>> extends Abstract
transfers[i] = DBIDUtil.newArray();
}
- for(int iter = 0; maxiter < 0 || iter < maxiter; iter++) {
+ for(int iter = 0; maxiter <= 0 || iter < maxiter; iter++) {
updateDistances(relation, means, metas, df);
tids.sort(comp);
int active = 0; // Track if anything has changed
@@ -461,7 +456,7 @@ public class SameSizeKMeansAlgorithm<V extends NumberVector<?>> extends Abstract
*
* @apiviz.exclude
*/
- public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer {
+ public static class Parameterizer<V extends NumberVector> extends AbstractParameterizer {
/**
* k Parameter.
*/
@@ -480,12 +475,12 @@ public class SameSizeKMeansAlgorithm<V extends NumberVector<?>> extends Abstract
/**
* Distance function
*/
- protected PrimitiveDoubleDistanceFunction<? super NumberVector<?>> distanceFunction;
+ protected PrimitiveDistanceFunction<? super NumberVector> distanceFunction;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- ObjectParameter<PrimitiveDoubleDistanceFunction<? super NumberVector<?>>> distanceFunctionP = makeParameterDistanceFunction(SquaredEuclideanDistanceFunction.class, PrimitiveDoubleDistanceFunction.class);
+ ObjectParameter<PrimitiveDistanceFunction<? super NumberVector>> distanceFunctionP = makeParameterDistanceFunction(SquaredEuclideanDistanceFunction.class, PrimitiveDistanceFunction.class);
if(config.grab(distanceFunctionP)) {
distanceFunction = distanceFunctionP.instantiateClass(config);
if(!(distanceFunction instanceof EuclideanDistanceFunction) && !(distanceFunction instanceof SquaredEuclideanDistanceFunction)) {
diff --git a/src/tutorial/clustering/package-info.java b/src/tutorial/clustering/package-info.java
index ac7ab950..e2971ef8 100644
--- a/src/tutorial/clustering/package-info.java
+++ b/src/tutorial/clustering/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/tutorial/distancefunction/MultiLPNorm.java b/src/tutorial/distancefunction/MultiLPNorm.java
index b3a96ecb..823e00b1 100644
--- a/src/tutorial/distancefunction/MultiLPNorm.java
+++ b/src/tutorial/distancefunction/MultiLPNorm.java
@@ -3,7 +3,7 @@ package tutorial.distancefunction;
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.VectorFieldTypeInformation;
-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.datastructures.arraylike.ArrayLikeUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
@@ -14,7 +14,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleListParamet
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
@@ -42,7 +42,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleListParamet
*
* @author Erich Schubert
*/
-public class MultiLPNorm extends AbstractVectorDoubleDistanceFunction {
+public class MultiLPNorm extends AbstractNumberVectorDistanceFunction {
/**
* The exponents
*/
@@ -72,7 +72,7 @@ public class MultiLPNorm extends AbstractVectorDoubleDistanceFunction {
}
@Override
- public double doubleDistance(NumberVector<?> o1, NumberVector<?> o2) {
+ public double distance(NumberVector o1, NumberVector o2) {
assert o1.getDimensionality() == ps.length : "Inappropriate dimensionality!";
assert o2.getDimensionality() == ps.length : "Inappropriate dimensionality!";
@@ -87,8 +87,8 @@ public class MultiLPNorm extends AbstractVectorDoubleDistanceFunction {
}
@Override
- public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() {
- return new VectorFieldTypeInformation<>(NumberVector.class, ps.length);
+ public SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() {
+ return VectorFieldTypeInformation.typeRequest(NumberVector.class, ps.length, ps.length);
}
/**
diff --git a/src/tutorial/distancefunction/TutorialDistanceFunction.java b/src/tutorial/distancefunction/TutorialDistanceFunction.java
index 5e2fbcb6..825a3a0d 100644
--- a/src/tutorial/distancefunction/TutorialDistanceFunction.java
+++ b/src/tutorial/distancefunction/TutorialDistanceFunction.java
@@ -4,7 +4,7 @@ package tutorial.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,8 +25,8 @@ package tutorial.distancefunction;
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.VectorFieldTypeInformation;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractNumberVectorDistanceFunction;
/**
* Tutorial example for ELKI.
@@ -37,16 +37,16 @@ import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractVectorDoubleDistanc
*
* @author Erich Schubert
*/
-public class TutorialDistanceFunction extends AbstractVectorDoubleDistanceFunction {
+public class TutorialDistanceFunction extends AbstractNumberVectorDistanceFunction {
@Override
- public double doubleDistance(NumberVector<?> o1, NumberVector<?> o2) {
+ public double distance(NumberVector o1, NumberVector o2) {
double dx = (o1.doubleValue(0) - o2.doubleValue(0));
double dy = (o1.doubleValue(1) - o2.doubleValue(1));
return dx * dx + Math.abs(dy);
}
@Override
- public SimpleTypeInformation<? super NumberVector<?>> getInputTypeRestriction() {
- return new VectorFieldTypeInformation<>(NumberVector.class, 2);
+ public SimpleTypeInformation<? super NumberVector> getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_FIELD_2D;
}
}
diff --git a/src/tutorial/distancefunction/package-info.java b/src/tutorial/distancefunction/package-info.java
index ba64b6bd..c9fb987d 100644
--- a/src/tutorial/distancefunction/package-info.java
+++ b/src/tutorial/distancefunction/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/tutorial/outlier/DistanceStddevOutlier.java b/src/tutorial/outlier/DistanceStddevOutlier.java
index 61859f88..571e1906 100644
--- a/src/tutorial/outlier/DistanceStddevOutlier.java
+++ b/src/tutorial/outlier/DistanceStddevOutlier.java
@@ -1,4 +1,26 @@
package tutorial.outlier;
+/*
+ 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.algorithm.AbstractDistanceBasedAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
@@ -11,13 +33,13 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.math.MeanVariance;
@@ -36,9 +58,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class DistanceStddevOutlier<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
+public class DistanceStddevOutlier<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
* Class logger
*/
@@ -55,7 +76,7 @@ public class DistanceStddevOutlier<O, D extends NumberDistance<D, ?>> extends Ab
* @param distanceFunction Distance function to use
* @param k Number of neighbors to use
*/
- public DistanceStddevOutlier(DistanceFunction<? super O, D> distanceFunction, int k) {
+ public DistanceStddevOutlier(DistanceFunction<? super O> distanceFunction, int k) {
super(distanceFunction);
this.k = k;
}
@@ -69,7 +90,7 @@ public class DistanceStddevOutlier<O, D extends NumberDistance<D, ?>> extends Ab
*/
public OutlierResult run(Database database, Relation<O> relation) {
// Get a nearest neighbor query on the relation.
- KNNQuery<O, D> knnq = QueryUtil.getKNNQuery(relation, getDistanceFunction(), k);
+ KNNQuery<O> knnq = QueryUtil.getKNNQuery(relation, getDistanceFunction(), k);
// Output data storage
WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_DB);
// Track minimum and maximum scores
@@ -77,15 +98,15 @@ public class DistanceStddevOutlier<O, D extends NumberDistance<D, ?>> extends Ab
// Iterate over all objects
for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
- KNNList<D> neighbors = knnq.getKNNForDBID(iter, k);
+ KNNList neighbors = knnq.getKNNForDBID(iter, k);
// Aggregate distances
MeanVariance mv = new MeanVariance();
- for(DistanceDBIDListIter<D> neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ for(DoubleDBIDListIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
// Skip the object itself. The 0 is not very informative.
if(DBIDUtil.equal(iter, neighbor)) {
continue;
}
- mv.put(neighbor.getDistance().doubleValue());
+ mv.put(neighbor.doubleValue());
}
// Store score
scores.putDouble(iter, mv.getSampleStddev());
@@ -94,7 +115,7 @@ public class DistanceStddevOutlier<O, D extends NumberDistance<D, ?>> extends Ab
// Wrap the result in the standard containers
// Actual min-max, theoretical min-max!
OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0, Double.POSITIVE_INFINITY);
- Relation<Double> rel = new MaterializedRelation<>(database, TypeUtil.DOUBLE, relation.getDBIDs(), "stddev-outlier", scores);
+ DoubleRelation rel = new MaterializedDoubleRelation(database, relation.getDBIDs(), "stddev-outlier", scores);
return new OutlierResult(meta, rel);
}
@@ -116,9 +137,8 @@ public class DistanceStddevOutlier<O, D extends NumberDistance<D, ?>> extends Ab
* @apiviz.exclude
*
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Option ID for parameterization.
*/
@@ -141,7 +161,7 @@ public class DistanceStddevOutlier<O, D extends NumberDistance<D, ?>> extends Ab
}
@Override
- protected DistanceStddevOutlier<O, D> makeInstance() {
+ protected DistanceStddevOutlier<O> makeInstance() {
return new DistanceStddevOutlier<>(distanceFunction, k);
}
}
diff --git a/src/tutorial/outlier/ODIN.java b/src/tutorial/outlier/ODIN.java
index 04f8ee90..b97be33b 100644
--- a/src/tutorial/outlier/ODIN.java
+++ b/src/tutorial/outlier/ODIN.java
@@ -4,7 +4,7 @@ package tutorial.outlier;
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
@@ -33,13 +33,13 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
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.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
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.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
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.Distance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.result.outlier.InvertedOutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
@@ -66,10 +66,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* @author Erich Schubert
*
* @param <O> Object type
- * @param <D> Distance type
*/
@Reference(authors = "V. Hautamäki and I. Kärkkäinen and P Fränti", title = "Outlier detection using k-nearest neighbour graph", booktitle = "Proc. 17th Int. Conf. Pattern Recognition, ICPR 2004", url = "http://dx.doi.org/10.1109/ICPR.2004.1334558")
-public class ODIN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm<O, D, OutlierResult> implements OutlierAlgorithm {
+public class ODIN<O> extends AbstractDistanceBasedAlgorithm<O, OutlierResult> implements OutlierAlgorithm {
/**
* Class logger.
*/
@@ -86,7 +85,7 @@ public class ODIN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorit
* @param distanceFunction Distance function
* @param k k parameter
*/
- public ODIN(DistanceFunction<? super O, D> distanceFunction, int k) {
+ public ODIN(DistanceFunction<? super O> distanceFunction, int k) {
super(distanceFunction);
this.k = k;
}
@@ -105,8 +104,8 @@ public class ODIN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorit
*/
public OutlierResult run(Database database, Relation<O> relation) {
// Get the query functions:
- DistanceQuery<O, D> dq = database.getDistanceQuery(relation, getDistanceFunction());
- KNNQuery<O, D> knnq = database.getKNNQuery(dq, k);
+ DistanceQuery<O> dq = database.getDistanceQuery(relation, getDistanceFunction());
+ KNNQuery<O> knnq = database.getKNNQuery(dq, k);
// Get the objects to process, and a data storage for counting and output:
DBIDs ids = relation.getDBIDs();
@@ -115,7 +114,7 @@ public class ODIN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorit
// Process all objects
for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
// Find the nearest neighbors (using an index, if available!)
- KNNList<D> neighbors = knnq.getKNNForDBID(iter, k);
+ KNNList neighbors = knnq.getKNNForDBID(iter, k);
// For each neighbor, except ourselves, increase the in-degree:
for (DBIDIter nei = neighbors.iter(); nei.valid(); nei.advance()) {
if (DBIDUtil.equal(iter, nei)) {
@@ -135,7 +134,7 @@ public class ODIN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorit
// By actually specifying theoretical min, max and baseline, we get a better
// visualization (try it out - or see the screenshots in the tutorial)!
OutlierScoreMeta meta = new InvertedOutlierScoreMeta(min, max, 0., ids.size() - 1, k);
- Relation<Double> rel = new MaterializedRelation<>("ODIN In-Degree", "odin", TypeUtil.DOUBLE, scores, ids);
+ DoubleRelation rel = new MaterializedDoubleRelation("ODIN In-Degree", "odin", scores, ids);
return new OutlierResult(meta, rel);
}
@@ -157,9 +156,8 @@ public class ODIN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorit
* @apiviz.exclude
*
* @param <O> Object type
- * @param <D> Distance type
*/
- public static class Parameterizer<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* Parameter for the number of nearest neighbors:
*
@@ -189,7 +187,7 @@ public class ODIN<O, D extends Distance<D>> extends AbstractDistanceBasedAlgorit
}
@Override
- protected ODIN<O, D> makeInstance() {
+ protected ODIN<O> makeInstance() {
return new ODIN<>(distanceFunction, k);
}
}
diff --git a/src/tutorial/outlier/SimpleScoreDumper.java b/src/tutorial/outlier/SimpleScoreDumper.java
index 49c1de0b..6984cccd 100644
--- a/src/tutorial/outlier/SimpleScoreDumper.java
+++ b/src/tutorial/outlier/SimpleScoreDumper.java
@@ -4,7 +4,7 @@ package tutorial.outlier;
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 java.util.ArrayList;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultHandler;
@@ -44,9 +44,9 @@ public class SimpleScoreDumper implements ResultHandler {
// Get all new outlier results
ArrayList<OutlierResult> ors = ResultUtil.filterResults(newResult, OutlierResult.class);
for (OutlierResult o : ors) {
- Relation<Double> scores = o.getScores();
+ DoubleRelation scores = o.getScores();
for (DBIDIter iter = scores.iterDBIDs(); iter.valid(); iter.advance()) {
- System.out.println(DBIDUtil.toString(iter) + " " + scores.get(iter));
+ System.out.println(DBIDUtil.toString(iter) + " " + scores.doubleValue(iter));
}
}
}
diff --git a/src/tutorial/package-info.java b/src/tutorial/package-info.java
index e37e53f2..33067053 100644
--- a/src/tutorial/package-info.java
+++ b/src/tutorial/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/test/de/lmu/ifi/dbs/elki/AllTests.java b/test/de/lmu/ifi/dbs/elki/AllTests.java
deleted file mode 100644
index 84f8e407..00000000
--- a/test/de/lmu/ifi/dbs/elki/AllTests.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package de.lmu.ifi.dbs.elki;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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.List;
-
-import junit.framework.JUnit4TestAdapter;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-import de.lmu.ifi.dbs.elki.utilities.InspectionUtil;
-
-/**
- * Build a test suite with all tests included with ELKI
- *
- * @author Erich Schubert
- */
-public class AllTests extends TestSuite {
- /**
- * Build a test suite with all tests included in ELKI.
- *
- * @return Test suite
- */
- public static Test suite() {
- TestSuite suite = new TestSuite();
- List<Class<?>> tests = InspectionUtil.findAllImplementations(TestCase.class, false);
- tests.addAll(InspectionUtil.findAllImplementations(JUnit4Test.class, false));
- for(Class<?> cls : tests) {
- if(cls == AllTests.class) {
- continue;
- }
- Test test = new JUnit4TestAdapter(cls);
- if(test != null) {
- suite.addTest(test);
- }
- }
- return suite;
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/AbstractSimpleAlgorithmTest.java b/test/de/lmu/ifi/dbs/elki/algorithm/AbstractSimpleAlgorithmTest.java
deleted file mode 100644
index 3e260e8e..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/AbstractSimpleAlgorithmTest.java
+++ /dev/null
@@ -1,242 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import de.lmu.ifi.dbs.elki.algorithm.clustering.trivial.ByLabelClustering;
-import de.lmu.ifi.dbs.elki.data.Cluster;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.model.Model;
-import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.StaticArrayDatabase;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.datasource.FileBasedDatabaseConnection;
-import de.lmu.ifi.dbs.elki.datasource.filter.FixedDBIDsFilter;
-import de.lmu.ifi.dbs.elki.evaluation.clustering.ClusterContingencyTable;
-import de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierROCCurve;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.result.Result;
-import de.lmu.ifi.dbs.elki.result.ResultUtil;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Abstract base class useful for testing various algorithms.
- *
- * @author Erich Schubert
- */
-public abstract class AbstractSimpleAlgorithmTest {
- /**
- * Base path for unit test files.
- */
- public final static String UNITTEST = "data/testdata/unittests/";
-
- /**
- * Notice: this is okay for tests - don't use this for frequently used
- * objects, use a static instance instead!
- */
- protected Logging logger = Logging.getLogger(this.getClass());
-
- /**
- * Validate that parameterization succeeded: no parameters left, no
- * parameterization errors.
- *
- * @param config Parameterization to test
- */
- protected void testParameterizationOk(ListParameterization config) {
- if (config.hasUnusedParameters()) {
- fail("Unused parameters: " + config.getRemainingParameters());
- }
- if (config.hasErrors()) {
- config.logAndClearReportedErrors();
- fail("Parameterization errors.");
- }
- }
-
- /**
- * Generate a simple DoubleVector database from a file.
- *
- * @param filename File to load
- * @param expectedSize Expected size in records
- * @param params Extra parameters
- * @return Database
- */
- protected <T> Database makeSimpleDatabase(String filename, int expectedSize, ListParameterization params, Class<?>[] filters) {
- org.junit.Assert.assertTrue("Test data set not found: " + filename, (new File(filename)).exists());
- params.addParameter(FileBasedDatabaseConnection.Parameterizer.INPUT_ID, filename);
-
- List<Class<?>> filterlist = new ArrayList<>();
- filterlist.add(FixedDBIDsFilter.class);
- if (filters != null) {
- for (Class<?> filter : filters) {
- filterlist.add(filter);
- }
- }
- params.addParameter(FileBasedDatabaseConnection.Parameterizer.FILTERS_ID, filterlist);
- params.addParameter(FixedDBIDsFilter.Parameterizer.IDSTART_ID, 1);
- Database db = ClassGenericsUtil.parameterizeOrAbort(StaticArrayDatabase.class, params);
-
- testParameterizationOk(params);
-
- db.initialize();
- Relation<?> rel = db.getRelation(TypeUtil.ANY);
- org.junit.Assert.assertEquals("Database size does not match.", expectedSize, rel.size());
- return db;
- }
-
- /**
- * Generate a simple DoubleVector database from a file.
- *
- * @param filename File to load
- * @param expectedSize Expected size in records
- * @return Database
- */
- protected <T> Database makeSimpleDatabase(String filename, int expectedSize) {
- return makeSimpleDatabase(filename, expectedSize, new ListParameterization(), null);
- }
-
- /**
- * Find a clustering result, fail if there is more than one or none.
- *
- * @param result Base result
- * @return Clustering
- */
- protected Clustering<?> findSingleClustering(Result result) {
- List<Clustering<? extends Model>> clusterresults = ResultUtil.getClusteringResults(result);
- assertTrue("No unique clustering found in result.", clusterresults.size() == 1);
- Clustering<? extends Model> clustering = clusterresults.get(0);
- return clustering;
- }
-
- /**
- * Test the clustering result by comparing the score with an expected value.
- *
- * @param database Database to test
- * @param clustering Clustering result
- * @param expected Expected score
- */
- protected <O> void testFMeasure(Database database, Clustering<?> clustering, double expected) {
- // Run by-label as reference
- ByLabelClustering bylabel = new ByLabelClustering();
- Clustering<Model> rbl = bylabel.run(database);
-
- ClusterContingencyTable ct = new ClusterContingencyTable(true, false);
- ct.process(clustering, rbl);
- double score = ct.getPaircount().f1Measure();
- if (logger.isVerbose()) {
- logger.verbose(this.getClass().getSimpleName() + " score: " + score + " expect: " + expected);
- }
- org.junit.Assert.assertEquals(this.getClass().getSimpleName() + ": Score does not match.", expected, score, 0.0001);
- }
-
- /**
- * Validate the cluster sizes with an expected result.
- *
- * @param clustering Clustering to test
- * @param expected Expected cluster sizes
- */
- protected void testClusterSizes(Clustering<?> clustering, int[] expected) {
- List<Integer> sizes = new java.util.ArrayList<>();
- for (Cluster<?> cl : clustering.getAllClusters()) {
- sizes.add(cl.size());
- }
- // Sort both
- Collections.sort(sizes);
- Arrays.sort(expected);
- // Report
- // if(logger.isVerbose()) {
- StringBuilder buf = new StringBuilder();
- buf.append("Cluster sizes: [");
- for (int i = 0; i < sizes.size(); i++) {
- if (i > 0) {
- buf.append(", ");
- }
- buf.append(sizes.get(i));
- }
- buf.append("]");
- // }
- // Test
- org.junit.Assert.assertEquals("Number of clusters does not match expectations. " + buf.toString(), expected.length, sizes.size());
- for (int i = 0; i < expected.length; i++) {
- org.junit.Assert.assertEquals("Cluster size does not match at position " + i + " in " + buf.toString(), expected[i], (int) sizes.get(i));
- }
- }
-
- /**
- * Test the AUC value for an outlier result.
- *
- * @param db Database
- * @param positive Positive class name
- * @param result Outlier result to process
- * @param expected Expected AUC value
- */
- protected void testAUC(Database db, String positive, OutlierResult result, double expected) {
- ListParameterization params = new ListParameterization();
- params.addParameter(OutlierROCCurve.POSITIVE_CLASS_NAME_ID, positive);
- OutlierROCCurve rocCurve = ClassGenericsUtil.parameterizeOrAbort(OutlierROCCurve.class, params);
-
- // Ensure the result has been added to the hierarchy:
- if (db.getHierarchy().numParents(result) < 1) {
- db.getHierarchy().add(db, result);
- }
-
- // Compute ROC and AUC:
- rocCurve.processNewResult(db, result);
- // Find the ROC results
- Collection<OutlierROCCurve.ROCResult> rocs = ResultUtil.filterResults(result, OutlierROCCurve.ROCResult.class);
- org.junit.Assert.assertTrue("No ROC result found.", !rocs.isEmpty());
- double auc = rocs.iterator().next().getAUC();
- org.junit.Assert.assertFalse("More than one ROC result found.", rocs.size() > 1);
- org.junit.Assert.assertEquals("ROC value does not match.", expected, auc, 0.0001);
- }
-
- /**
- * Test the outlier score of a single object.
- *
- * @param result Result object to use
- * @param id Object ID
- * @param expected expected value
- */
- protected void testSingleScore(OutlierResult result, int id, double expected) {
- org.junit.Assert.assertNotNull("No outlier result", result);
- org.junit.Assert.assertNotNull("No score result.", result.getScores());
- final DBID dbid = DBIDUtil.importInteger(id);
- org.junit.Assert.assertNotNull("No result for ID " + id, result.getScores().get(dbid));
- double actual = result.getScores().get(dbid);
- org.junit.Assert.assertEquals("Outlier score of object " + id + " doesn't match.", expected, actual, 0.0001);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/TestKNNJoin.java b/test/de/lmu/ifi/dbs/elki/algorithm/TestKNNJoin.java
deleted file mode 100644
index 19509350..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/TestKNNJoin.java
+++ /dev/null
@@ -1,215 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 java.util.List;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.QueryUtil;
-import de.lmu.ifi.dbs.elki.database.StaticArrayDatabase;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStore;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-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.datasource.FileBasedDatabaseConnection;
-import de.lmu.ifi.dbs.elki.datasource.filter.FixedDBIDsFilter;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.ManhattanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluTree;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluTreeFactory;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTree;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTreeFactory;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTreeNode;
-import de.lmu.ifi.dbs.elki.math.MeanVariance;
-import de.lmu.ifi.dbs.elki.persistent.AbstractPageFileFactory;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-public class TestKNNJoin implements JUnit4Test {
- // the following values depend on the data set used!
- String dataset = "data/testdata/unittests/uebungsblatt-2d-mini.csv";
-
- // size of the data set
- int shoulds = 20;
-
- // mean number of 2NN
- double mean2nnEuclid = 2.85;
-
- // variance
- double var2nnEuclid = 0.87105;
-
- // mean number of 2NN
- double mean2nnManhattan = 2.9;
-
- // variance
- double var2nnManhattan = 0.83157894;
-
- @Test
- public void testLinearScan() {
- ListParameterization inputparams = new ListParameterization();
- inputparams.addParameter(FileBasedDatabaseConnection.Parameterizer.INPUT_ID, dataset);
- List<Class<?>> filters = Arrays.asList(new Class<?>[] { FixedDBIDsFilter.class });
- inputparams.addParameter(FileBasedDatabaseConnection.Parameterizer.FILTERS_ID, filters);
- inputparams.addParameter(FixedDBIDsFilter.Parameterizer.IDSTART_ID, 1);
-
- // get database
- Database db = ClassGenericsUtil.parameterizeOrAbort(StaticArrayDatabase.class, inputparams);
- inputparams.failOnErrors();
-
- db.initialize();
- Relation<NumberVector<?>> relation = db.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
- // verify data set size.
- org.junit.Assert.assertEquals("Database size does not match.", shoulds, relation.size());
-
- // Euclidean
- {
- DistanceQuery<NumberVector<?>, DoubleDistance> dq = db.getDistanceQuery(relation, EuclideanDistanceFunction.STATIC);
- KNNQuery<NumberVector<?>, DoubleDistance> knnq = QueryUtil.getLinearScanKNNQuery(dq);
-
- MeanVariance meansize = new MeanVariance();
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- KNNList<DoubleDistance> knnlist = knnq.getKNNForDBID(iditer, 2);
- meansize.put(knnlist.size());
- }
- org.junit.Assert.assertEquals("Euclidean mean 2NN", mean2nnEuclid, meansize.getMean(), 0.00001);
- org.junit.Assert.assertEquals("Euclidean variance 2NN", var2nnEuclid, meansize.getSampleVariance(), 0.00001);
- }
- // Manhattan
- {
- DistanceQuery<NumberVector<?>, DoubleDistance> dq = db.getDistanceQuery(relation, ManhattanDistanceFunction.STATIC);
- KNNQuery<NumberVector<?>, DoubleDistance> knnq = QueryUtil.getLinearScanKNNQuery(dq);
-
- MeanVariance meansize = new MeanVariance();
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- KNNList<DoubleDistance> knnlist = knnq.getKNNForDBID(iditer, 2);
- meansize.put(knnlist.size());
- }
- org.junit.Assert.assertEquals("Manhattan mean 2NN", mean2nnManhattan, meansize.getMean(), 0.00001);
- org.junit.Assert.assertEquals("Manhattan variance 2NN", var2nnManhattan, meansize.getSampleVariance(), 0.00001);
- }
- }
-
- /**
- * Test {@link RStarTree} using a file based database connection.
- *
- * @throws ParameterException on errors.
- */
- @Test
- public void testKNNJoinRtreeMini() {
- ListParameterization spatparams = new ListParameterization();
- spatparams.addParameter(StaticArrayDatabase.Parameterizer.INDEX_ID, RStarTreeFactory.class);
- spatparams.addParameter(AbstractPageFileFactory.Parameterizer.PAGE_SIZE_ID, 200);
-
- doKNNJoin(spatparams);
- }
-
- /**
- * Test {@link RStarTree} using a file based database connection.
- *
- * @throws ParameterException on errors.
- */
- @Test
- public void testKNNJoinRtreeMaxi() {
- ListParameterization spatparams = new ListParameterization();
- spatparams.addParameter(StaticArrayDatabase.Parameterizer.INDEX_ID, RStarTreeFactory.class);
- spatparams.addParameter(AbstractPageFileFactory.Parameterizer.PAGE_SIZE_ID, 2000);
-
- doKNNJoin(spatparams);
- }
-
- /**
- * Test {@link DeLiCluTree} using a file based database connection.
- *
- * @throws ParameterException on errors.
- */
- @Test
- public void testKNNJoinDeLiCluTreeMini() {
- ListParameterization spatparams = new ListParameterization();
- spatparams.addParameter(StaticArrayDatabase.Parameterizer.INDEX_ID, DeLiCluTreeFactory.class);
- spatparams.addParameter(AbstractPageFileFactory.Parameterizer.PAGE_SIZE_ID, 200);
-
- doKNNJoin(spatparams);
- }
-
- /**
- * Actual test routine.
- *
- * @param inputparams
- * @throws ParameterException
- */
- void doKNNJoin(ListParameterization inputparams) {
- inputparams.addParameter(FileBasedDatabaseConnection.Parameterizer.INPUT_ID, dataset);
- List<Class<?>> filters = Arrays.asList(new Class<?>[] { FixedDBIDsFilter.class });
- inputparams.addParameter(FileBasedDatabaseConnection.Parameterizer.FILTERS_ID, filters);
- inputparams.addParameter(FixedDBIDsFilter.Parameterizer.IDSTART_ID, 1);
-
- // get database
- Database db = ClassGenericsUtil.parameterizeOrAbort(StaticArrayDatabase.class, inputparams);
- inputparams.failOnErrors();
-
- db.initialize();
- Relation<NumberVector<?>> relation = db.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
- // verify data set size.
- org.junit.Assert.assertEquals("Database size does not match.", shoulds, relation.size());
-
- // Euclidean
- {
- KNNJoin<DoubleVector, DoubleDistance, ?, ?> knnjoin = new KNNJoin<DoubleVector, DoubleDistance, RStarTreeNode, SpatialEntry>(EuclideanDistanceFunction.STATIC, 2);
- DataStore<KNNList<DoubleDistance>> result = knnjoin.run(db);
-
- MeanVariance meansize = new MeanVariance();
- for(DBIDIter id = relation.getDBIDs().iter(); id.valid(); id.advance()) {
- KNNList<DoubleDistance> knnlist = result.get(id);
- meansize.put(knnlist.size());
- }
- org.junit.Assert.assertEquals("Euclidean mean 2NN set size", mean2nnEuclid, meansize.getMean(), 0.00001);
- org.junit.Assert.assertEquals("Euclidean variance 2NN", var2nnEuclid, meansize.getSampleVariance(), 0.00001);
- }
- // Manhattan
- {
- KNNJoin<DoubleVector, DoubleDistance, ?, ?> knnjoin = new KNNJoin<DoubleVector, DoubleDistance, RStarTreeNode, SpatialEntry>(ManhattanDistanceFunction.STATIC, 2);
- DataStore<KNNList<DoubleDistance>> result = knnjoin.run(db);
-
- MeanVariance meansize = new MeanVariance();
- for(DBIDIter id = relation.getDBIDs().iter(); id.valid(); id.advance()) {
- KNNList<DoubleDistance> knnlist = result.get(id);
- meansize.put(knnlist.size());
- }
- org.junit.Assert.assertEquals("Manhattan mean 2NN", mean2nnManhattan, meansize.getMean(), 0.00001);
- org.junit.Assert.assertEquals("Manhattan variance 2NN", var2nnManhattan, meansize.getSampleVariance(), 0.00001);
- }
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestDBSCANResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestDBSCANResults.java
deleted file mode 100644
index 34dd2e3d..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestDBSCANResults.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.GeneralizedDBSCAN;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.Model;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Performs a full DBSCAN run, and compares the result with a clustering derived
- * from the data set labels. This test ensures that DBSCAN performance doesn't
- * unexpectedly drop on this data set (and also ensures that the algorithms
- * work, as a side effect).
- *
- * @author Elke Achtert
- * @author Erich Schubert
- * @author Katharina Rausch
- */
-public class TestDBSCANResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run DBSCAN with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testDBSCANResults() {
- Database db = makeSimpleDatabase(UNITTEST + "3clusters-and-noise-2d.csv", 330);
-
- // setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(DBSCAN.Parameterizer.EPSILON_ID, 0.04);
- params.addParameter(DBSCAN.Parameterizer.MINPTS_ID, 20);
- DBSCAN<DoubleVector, DoubleDistance> dbscan = ClassGenericsUtil.parameterizeOrAbort(DBSCAN.class, params);
- testParameterizationOk(params);
-
- // run DBSCAN on database
- Clustering<Model> result = dbscan.run(db);
-
- testFMeasure(db, result, 0.996413);
- testClusterSizes(result, new int[] { 29, 50, 101, 150 });
- }
-
- /**
- * Run DBSCAN with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testDBSCANOnSingleLinkDataset() {
- Database db = makeSimpleDatabase(UNITTEST + "single-link-effect.ascii", 638);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(DBSCAN.Parameterizer.EPSILON_ID, 11.5);
- params.addParameter(DBSCAN.Parameterizer.MINPTS_ID, 120);
- DBSCAN<DoubleVector, DoubleDistance> dbscan = ClassGenericsUtil.parameterizeOrAbort(DBSCAN.class, params);
- testParameterizationOk(params);
-
- // run DBSCAN on database
- Clustering<Model> result = dbscan.run(db);
- testFMeasure(db, result, 0.954382);
- testClusterSizes(result, new int[] { 11, 200, 203, 224 });
- }
-
- /**
- * Run DBSCAN with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testGDBSCANResults() {
- Database db = makeSimpleDatabase(UNITTEST + "3clusters-and-noise-2d.csv", 330);
-
- // setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(DBSCAN.Parameterizer.EPSILON_ID, 0.04);
- params.addParameter(DBSCAN.Parameterizer.MINPTS_ID, 20);
- GeneralizedDBSCAN dbscan = ClassGenericsUtil.parameterizeOrAbort(GeneralizedDBSCAN.class, params);
- testParameterizationOk(params);
-
- // run DBSCAN on database
- Clustering<Model> result = dbscan.run(db);
-
- testClusterSizes(result, new int[] { 29, 50, 101, 150 });
- testFMeasure(db, result, 0.996413);
- }
-
- /**
- * Run DBSCAN with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testGDBSCANOnSingleLinkDataset() {
- Database db = makeSimpleDatabase(UNITTEST + "single-link-effect.ascii", 638);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(DBSCAN.Parameterizer.EPSILON_ID, 11.5);
- params.addParameter(DBSCAN.Parameterizer.MINPTS_ID, 120);
- GeneralizedDBSCAN dbscan = ClassGenericsUtil.parameterizeOrAbort(GeneralizedDBSCAN.class, params);
- testParameterizationOk(params);
-
- // run DBSCAN on database
- Clustering<Model> result = dbscan.run(db);
- testClusterSizes(result, new int[] { 11, 200, 203, 224 });
- testFMeasure(db, result, 0.954382);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestDeLiCluResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestDeLiCluResults.java
deleted file mode 100644
index b70c0f67..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestDeLiCluResults.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.trivial.ByLabelClustering;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.model.Model;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.StaticArrayDatabase;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.evaluation.clustering.ClusterContingencyTable;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluTreeFactory;
-import de.lmu.ifi.dbs.elki.persistent.AbstractPageFileFactory;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Performs a full DeLiClu run, and compares the result with a clustering
- * derived from the data set labels. This test ensures that DeLiClu's
- * performance doesn't unexpectedly drop on this data set (and also ensures that
- * the algorithms work, as a side effect).
- *
- * @author Katharina Rausch
- * @author Erich Schubert
- */
-public class TestDeLiCluResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run DeLiClu with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testDeLiCluResults() {
- ListParameterization indexparams = new ListParameterization();
- // We need a special index for this algorithm:
- indexparams.addParameter(StaticArrayDatabase.Parameterizer.INDEX_ID, DeLiCluTreeFactory.class);
- indexparams.addParameter(AbstractPageFileFactory.Parameterizer.PAGE_SIZE_ID, 1000);
- Database db = makeSimpleDatabase(UNITTEST + "hierarchical-2d.ascii", 710, indexparams, null);
-
- // Setup actual algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(DeLiClu.MINPTS_ID, 18);
- params.addParameter(OPTICSXi.XI_ID, 0.038);
- params.addParameter(OPTICSXi.XIALG_ID, DeLiClu.class);
- OPTICSXi<DoubleDistance> opticsxi = ClassGenericsUtil.parameterizeOrAbort(OPTICSXi.class, params);
- testParameterizationOk(params);
-
- // run DeLiClu on database
- Clustering<?> clustering = opticsxi.run(db);
-
- // Test F-Measure
- ByLabelClustering bylabel = new ByLabelClustering();
- Clustering<Model> rbl = bylabel.run(db);
- ClusterContingencyTable ct = new ClusterContingencyTable(true, false);
- ct.process(clustering, rbl);
- double score = ct.getPaircount().f1Measure();
- // We cannot test exactly - due to Hashing, DeLiClu sequence is not
- // identical each time, the results will vary slightly.
- assertEquals(this.getClass().getSimpleName() + ": Score does not match: " + score, score, 0.807415, 1E-5);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestEMResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestEMResults.java
deleted file mode 100644
index 065307be..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestEMResults.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeans;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.EMModel;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Performs a full EM run, and compares the result with a clustering derived
- * from the data set labels. This test ensures that EM's performance doesn't
- * unexpectedly drop on this data set (and also ensures that the algorithms
- * work, as a side effect).
- *
- * @author Katharina Rausch
- * @author Erich Schubert
- */
-public class TestEMResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run EM with fixed parameters and compare the result to a golden standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testEMResults() {
- Database db = makeSimpleDatabase(UNITTEST + "hierarchical-2d.ascii", 710);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(KMeans.SEED_ID, 0);
- params.addParameter(EM.Parameterizer.K_ID, 6);
- EM<DoubleVector> em = ClassGenericsUtil.parameterizeOrAbort(EM.class, params);
- testParameterizationOk(params);
-
- // run EM on database
- Clustering<EMModel<DoubleVector>> result = em.run(db);
- testFMeasure(db, result, 0.7551098);
- testClusterSizes(result, new int[] { 50, 99, 102, 120, 141, 198 });
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestOPTICSResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestOPTICSResults.java
deleted file mode 100644
index dde81a0f..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestOPTICSResults.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Performs a full OPTICS run, and compares the result with a clustering derived
- * from the data set labels. This test ensures that OPTICS's performance doesn't
- * unexpectedly drop on this data set (and also ensures that the algorithms
- * work, as a side effect).
- *
- * @author Katharina Rausch
- * @author Erich Schubert
- */
-public class TestOPTICSResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run OPTICS with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testOPTICSResults() {
- Database db = makeSimpleDatabase(UNITTEST + "hierarchical-2d.ascii", 710);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(OPTICS.MINPTS_ID, 18);
- params.addParameter(OPTICSXi.XI_ID, 0.038);
- params.addParameter(OPTICSXi.XIALG_ID, OPTICS.class);
- OPTICSXi<DoubleDistance> opticsxi = ClassGenericsUtil.parameterizeOrAbort(OPTICSXi.class, params);
- testParameterizationOk(params);
-
- // run OPTICS on database
- Clustering<?> clustering = opticsxi.run(db);
-
- testFMeasure(db, clustering, 0.874062);
- testClusterSizes(clustering, new int[] { 109, 121, 210, 270 });
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestSNNClusteringResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestSNNClusteringResults.java
deleted file mode 100644
index 302d5c0b..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/TestSNNClusteringResults.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.Model;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborPreprocessor;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Performs a full SNNClustering run, and compares the result with a clustering
- * derived from the data set labels. This test ensures that SNNClustering's
- * performance doesn't unexpectedly drop on this data set (and also ensures that
- * the algorithms work, as a side effect).
- *
- * @author Katharina Rausch
- * @author Erich Schubert
- */
-public class TestSNNClusteringResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run SNNClustering with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testSNNClusteringResults() {
- Database db = makeSimpleDatabase(UNITTEST + "different-densities-2d.ascii", 1200);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(SNNClustering.EPSILON_ID, 77);
- params.addParameter(SNNClustering.MINPTS_ID, 28);
- params.addParameter(SharedNearestNeighborPreprocessor.Factory.NUMBER_OF_NEIGHBORS_ID, 100);
- SNNClustering<DoubleVector> snn = ClassGenericsUtil.parameterizeOrAbort(SNNClustering.class, params);
- testParameterizationOk(params);
-
- // run SNN on database
- Clustering<Model> result = snn.run(db);
- testFMeasure(db, result, 0.832371422);
- testClusterSizes(result, new int[] { 73, 228, 213, 219, 231, 236 });
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestCASHResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestCASHResults.java
deleted file mode 100644
index 62791b68..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestCASHResults.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.correlation;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.Model;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Perform a full CASH run, and compare the result with a clustering derived
- * from the data set labels. This test ensures that CASH performance doesn't
- * unexpectedly drop on this data set (and also ensures that the algorithms
- * work, as a side effect).
- *
- * @author Erich Schubert
- * @author Katharina Rausch
- */
-public class TestCASHResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run CASH with fixed parameters and compare the result to a golden standard.
- */
- @Test
- public void testCASHResults() {
- // Input
- Database db = makeSimpleDatabase(UNITTEST + "hierarchical-3d2d1d.csv", 600, new ListParameterization(), null);
-
- // CASH parameters
- ListParameterization params = new ListParameterization();
- params.addParameter(CASH.JITTER_ID, 0.7);
- params.addParameter(CASH.MINPTS_ID, 50);
- params.addParameter(CASH.MAXLEVEL_ID, 25);
- params.addFlag(CASH.ADJUST_ID);
-
- // setup algorithm
- CASH<DoubleVector> cash = ClassGenericsUtil.parameterizeOrAbort(CASH.class, params);
- testParameterizationOk(params);
-
- // run CASH on database
- Clustering<Model> result = cash.run(db);
-
- testFMeasure(db, result, 0.490551); // with hierarchical pairs: 0.64102
- testClusterSizes(result, new int[] { 37, 71, 76, 442 });
- }
-
- /**
- * Run CASH with fixed parameters and compare the result to a golden standard.
- */
- @Test
- public void testCASHEmbedded() {
- // CASH input
- Database db = makeSimpleDatabase(UNITTEST + "correlation-embedded-2-4d.ascii", 600, new ListParameterization(), null);
-
- // CASH parameters
- ListParameterization params = new ListParameterization();
- params.addParameter(CASH.JITTER_ID, 0.7);
- params.addParameter(CASH.MINPTS_ID, 160);
- params.addParameter(CASH.MAXLEVEL_ID, 40);
-
- // setup algorithm
- CASH<DoubleVector> cash = ClassGenericsUtil.parameterizeOrAbort(CASH.class, params);
- testParameterizationOk(params);
-
- // run CASH on database
- Clustering<Model> result = cash.run(db);
- testFMeasure(db, result, 0.443246);
- testClusterSizes(result, new int[] { 169, 196, 235 });
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestCOPACResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestCOPACResults.java
deleted file mode 100644
index 94c59557..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestCOPACResults.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.correlation;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.Model;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.localpca.KNNQueryFilteredPCAIndex;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredRunner;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCARunner;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PercentageEigenPairFilter;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.WeightedCovarianceMatrixBuilder;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions.ErfcWeight;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Perform a full COPAC run, and compare the result with a clustering derived
- * from the data set labels. This test ensures that COPAC performance doesn't
- * unexpectedly drop on this data set (and also ensures that the algorithms
- * work, as a side effect).
- *
- * @author Erich Schubert
- * @author Katharina Rausch
- */
-public class TestCOPACResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run COPAC with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException on errors.
- */
- @Test
- public void testCOPACResults() {
- Database db = makeSimpleDatabase(UNITTEST + "correlation-hierarchy.csv", 450);
-
- // these parameters are not picked too smartly - room for improvement.
- ListParameterization params = new ListParameterization();
- params.addParameter(COPAC.PARTITION_ALGORITHM_ID, DBSCAN.class);
- params.addParameter(DBSCAN.Parameterizer.EPSILON_ID, 0.02);
- params.addParameter(DBSCAN.Parameterizer.MINPTS_ID, 50);
- params.addParameter(COPAC.PREPROCESSOR_ID, KNNQueryFilteredPCAIndex.Factory.class);
- params.addParameter(KNNQueryFilteredPCAIndex.Factory.K_ID, 15);
-
- COPAC<DoubleVector, DoubleDistance> copac = ClassGenericsUtil.parameterizeOrAbort(COPAC.class, params);
- testParameterizationOk(params);
-
- // run COPAC on database
- Clustering<Model> result = copac.run(db);
-
- testFMeasure(db, result, 0.842521);
- testClusterSizes(result, new int[] { 6, 16, 32, 196, 200 });
- }
-
- /**
- * Run COPAC with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException on errors.
- */
- @Test
- public void testCOPACOverlap() {
- Database db = makeSimpleDatabase(UNITTEST + "correlation-overlap-3-5d.ascii", 650);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(COPAC.PARTITION_ALGORITHM_ID, DBSCAN.class);
- params.addParameter(DBSCAN.Parameterizer.EPSILON_ID, 0.5);
- params.addParameter(DBSCAN.Parameterizer.MINPTS_ID, 20);
- params.addParameter(COPAC.PREPROCESSOR_ID, KNNQueryFilteredPCAIndex.Factory.class);
- params.addParameter(KNNQueryFilteredPCAIndex.Factory.K_ID, 45);
- // PCA
- params.addParameter(PCARunner.PCA_COVARIANCE_MATRIX, WeightedCovarianceMatrixBuilder.class);
- params.addParameter(WeightedCovarianceMatrixBuilder.WEIGHT_ID, ErfcWeight.class);
- params.addParameter(PCAFilteredRunner.PCA_EIGENPAIR_FILTER, PercentageEigenPairFilter.class);
- params.addParameter(PercentageEigenPairFilter.ALPHA_ID, 0.8);
-
- COPAC<DoubleVector, DoubleDistance> copac = ClassGenericsUtil.parameterizeOrAbort(COPAC.class, params);
- testParameterizationOk(params);
-
- Clustering<Model> result = copac.run(db);
- testFMeasure(db, result, 0.84687864);
- testClusterSizes(result, new int[] { 1, 22, 22, 29, 34, 158, 182, 202 });
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestERiCResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestERiCResults.java
deleted file mode 100644
index 76e8cca2..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestERiCResults.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.correlation;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.CorrelationModel;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.correlation.ERiCDistanceFunction;
-import de.lmu.ifi.dbs.elki.index.preprocessed.localpca.KNNQueryFilteredPCAIndex;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCAFilteredRunner;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PCARunner;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.PercentageEigenPairFilter;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.RelativeEigenPairFilter;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.WeightedCovarianceMatrixBuilder;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions.ErfcWeight;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Perform a full ERiC run, and compare the result with a clustering derived
- * from the data set labels. This test ensures that ERiC performance doesn't
- * unexpectedly drop on this data set (and also ensures that the algorithms
- * work, as a side effect).
- *
- * @author Erich Schubert
- * @author Katharina Rausch
- */
-public class TestERiCResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run ERiC with fixed parameters and compare the result to a golden standard.
- *
- * @throws ParameterException on errors.
- */
- @Test
- public void testERiCResults() {
- Database db = makeSimpleDatabase(UNITTEST + "hierarchical-3d2d1d.csv", 600);
-
- // ERiC
- ListParameterization params = new ListParameterization();
- params.addParameter(COPAC.PARTITION_ALGORITHM_ID, DBSCAN.class);
- params.addParameter(DBSCAN.Parameterizer.MINPTS_ID, 30);
- params.addParameter(DBSCAN.Parameterizer.EPSILON_ID, 0);
- // ERiC Distance function in DBSCAN:
- params.addParameter(COPAC.PARTITION_DISTANCE_ID, ERiCDistanceFunction.class);
- params.addParameter(ERiCDistanceFunction.DELTA_ID, 0.20);
- params.addParameter(ERiCDistanceFunction.TAU_ID, 0.04);
- // Preprocessing via Local PCA:
- params.addParameter(COPAC.PREPROCESSOR_ID, KNNQueryFilteredPCAIndex.Factory.class);
- params.addParameter(KNNQueryFilteredPCAIndex.Factory.K_ID, 50);
- // PCA
- params.addParameter(PCARunner.PCA_COVARIANCE_MATRIX, WeightedCovarianceMatrixBuilder.class);
- params.addParameter(WeightedCovarianceMatrixBuilder.WEIGHT_ID, ErfcWeight.class);
- params.addParameter(PCAFilteredRunner.PCA_EIGENPAIR_FILTER, RelativeEigenPairFilter.class);
- params.addParameter(RelativeEigenPairFilter.EIGENPAIR_FILTER_RALPHA, 1.60);
-
- ERiC<DoubleVector> eric = ClassGenericsUtil.parameterizeOrAbort(ERiC.class, params);
- testParameterizationOk(params);
-
- // run ERiC on database
- Clustering<CorrelationModel<DoubleVector>> result = eric.run(db);
-
- testFMeasure(db, result, 0.714207); // Hierarchical pairs scored: 0.9204825
- testClusterSizes(result, new int[] { 109, 184, 307 });
- }
-
- /**
- * Run ERiC with fixed parameters and compare the result to a golden standard.
- *
- * @throws ParameterException on errors.
- */
- @Test
- public void testERiCOverlap() {
- Database db = makeSimpleDatabase(UNITTEST + "correlation-overlap-3-5d.ascii", 650);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- // ERiC
- params.addParameter(COPAC.PARTITION_ALGORITHM_ID, DBSCAN.class);
- params.addParameter(DBSCAN.Parameterizer.MINPTS_ID, 15);
- params.addParameter(DBSCAN.Parameterizer.EPSILON_ID, 0);
- // ERiC Distance function in DBSCAN:
- params.addParameter(COPAC.PARTITION_DISTANCE_ID, ERiCDistanceFunction.class);
- params.addParameter(ERiCDistanceFunction.DELTA_ID, 1.0);
- params.addParameter(ERiCDistanceFunction.TAU_ID, 1.0);
- // Preprocessing via Local PCA:
- params.addParameter(COPAC.PREPROCESSOR_ID, KNNQueryFilteredPCAIndex.Factory.class);
- params.addParameter(KNNQueryFilteredPCAIndex.Factory.K_ID, 45);
- // PCA
- params.addParameter(PCARunner.PCA_COVARIANCE_MATRIX, WeightedCovarianceMatrixBuilder.class);
- params.addParameter(WeightedCovarianceMatrixBuilder.WEIGHT_ID, ErfcWeight.class);
- params.addParameter(PCAFilteredRunner.PCA_EIGENPAIR_FILTER, PercentageEigenPairFilter.class);
- params.addParameter(PercentageEigenPairFilter.ALPHA_ID, 0.6);
-
- ERiC<DoubleVector> eric = ClassGenericsUtil.parameterizeOrAbort(ERiC.class, params);
- testParameterizationOk(params);
-
- // run ERiC on database
- Clustering<CorrelationModel<DoubleVector>> result = eric.run(db);
- testFMeasure(db, result, 0.831136946);
- testClusterSizes(result, new int[] { 29, 189, 207, 225 });
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestFourCResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestFourCResults.java
deleted file mode 100644
index 8604a5f0..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestFourCResults.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.correlation;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.AbstractProjectedDBSCAN;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.Model;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Perform a full 4C run, and compare the result with a clustering derived from
- * the data set labels. This test ensures that 4C performance doesn't
- * unexpectedly drop on this data set (and also ensures that the algorithms
- * work, as a side effect).
- *
- * @author Erich Schubert
- * @author Katharina Rausch
- */
-public class TestFourCResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run 4F with fixed parameters and compare the result to a golden standard.
- *
- * @throws ParameterException on errors.
- */
- @Test
- public void testFourCResults() {
- Database db = makeSimpleDatabase(UNITTEST + "hierarchical-3d2d1d.csv", 600);
-
- // Setup 4C
- ListParameterization params = new ListParameterization();
- params.addParameter(AbstractProjectedDBSCAN.EPSILON_ID, 0.30);
- params.addParameter(AbstractProjectedDBSCAN.MINPTS_ID, 20);
- params.addParameter(AbstractProjectedDBSCAN.LAMBDA_ID, 5);
-
- FourC<DoubleVector> fourc = ClassGenericsUtil.parameterizeOrAbort(FourC.class, params);
- testParameterizationOk(params);
-
- // run 4C on database
- Clustering<Model> result = fourc.run(db);
-
- testFMeasure(db, result, 0.498048); // Hierarchical pairs scored: 0.79467
- testClusterSizes(result, new int[] { 5, 595 });
- }
-
- /**
- * Run ERiC with fixed parameters and compare the result to a golden standard.
- *
- * @throws ParameterException on errors.
- */
- @Test
- public void testFourCOverlap() {
- Database db = makeSimpleDatabase(UNITTEST + "correlation-overlap-3-5d.ascii", 650);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- // 4C
- params.addParameter(AbstractProjectedDBSCAN.EPSILON_ID, 1.2);
- params.addParameter(AbstractProjectedDBSCAN.MINPTS_ID, 5);
- params.addParameter(AbstractProjectedDBSCAN.LAMBDA_ID, 3);
-
- FourC<DoubleVector> fourc = ClassGenericsUtil.parameterizeOrAbort(FourC.class, params);
- testParameterizationOk(params);
-
- // run 4C on database
- Clustering<Model> result = fourc.run(db);
- testFMeasure(db, result, 0.48305405);
- testClusterSizes(result, new int[] { 65, 70, 515 });
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestORCLUSResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestORCLUSResults.java
deleted file mode 100644
index 5cdb09c9..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/correlation/TestORCLUSResults.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.correlation;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.Model;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Performs a full ORCLUS run, and compares the result with a clustering derived
- * from the data set labels. This test ensures that ORCLUS performance doesn't
- * unexpectedly drop on this data set (and also ensures that the algorithms
- * work, as a side effect).
- *
- * @author Elke Achtert
- * @author Katharina Rausch
- */
-public class TestORCLUSResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run ORCLUS with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException on errors.
- */
- @Test
- public void testORCLUSResults() {
- Database db = makeSimpleDatabase(UNITTEST + "correlation-hierarchy.csv", 450);
-
- ListParameterization params = new ListParameterization();
- params.addParameter(ORCLUS.Parameterizer.K_ID, 3);
- params.addParameter(ORCLUS.Parameterizer.L_ID, 1);
- params.addParameter(ORCLUS.Parameterizer.SEED_ID, 2);
-
- // setup algorithm
- ORCLUS<DoubleVector> orclus = ClassGenericsUtil.parameterizeOrAbort(ORCLUS.class, params);
- testParameterizationOk(params);
-
- // run ORCLUS on database
- Clustering<Model> result = orclus.run(db);
-
- testFMeasure(db, result, 0.6361108); // Hierarchical pairs scored: 0.789113
- testClusterSizes(result, new int[] { 19, 33, 398 });
- }
-
- /**
- * Run ORCLUS with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException on errors.
- */
- @Test
- public void testORCLUSSkewedDisjoint() {
- Database db = makeSimpleDatabase(UNITTEST + "correlation-skewed-disjoint-3-5d.ascii", 601);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(ORCLUS.Parameterizer.K_ID, 3);
- params.addParameter(ORCLUS.Parameterizer.L_ID, 4);
- params.addParameter(ORCLUS.Parameterizer.SEED_ID, 9);
-
- ORCLUS<DoubleVector> orclus = ClassGenericsUtil.parameterizeOrAbort(ORCLUS.class, params);
- testParameterizationOk(params);
-
- // run ORCLUS on database
- Clustering<Model> result = orclus.run(db);
- testFMeasure(db, result, 0.8687866);
- testClusterSizes(result, new int[] { 170, 200, 231 });
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/TestNaiveAgglomerativeHierarchicalClustering.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/TestNaiveAgglomerativeHierarchicalClustering.java
deleted file mode 100644
index 8ed18823..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/TestNaiveAgglomerativeHierarchicalClustering.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.result.Result;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-import de.lmu.ifi.dbs.elki.workflow.AlgorithmStep;
-
-/**
- * Perform agglomerative hierarchical clustering, using the naive algorithm.
- *
- * @author Erich Schubert
- */
-public class TestNaiveAgglomerativeHierarchicalClustering extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- // TODO: add more data sets.
-
- /**
- * Run agglomerative hierarchical clustering with fixed parameters and compare
- * the result to a golden standard.
- */
- @Test
- public void testSingleLink() {
- Database db = makeSimpleDatabase(UNITTEST + "single-link-effect.ascii", 638);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(ExtractFlatClusteringFromHierarchy.Parameterizer.OUTPUTMODE_ID, ExtractFlatClusteringFromHierarchy.OutputMode.STRICT_PARTITIONS);
- params.addParameter(ExtractFlatClusteringFromHierarchy.Parameterizer.MINCLUSTERS_ID, 3);
- params.addParameter(AlgorithmStep.Parameterizer.ALGORITHM_ID, NaiveAgglomerativeHierarchicalClustering.class);
- params.addParameter(NaiveAgglomerativeHierarchicalClustering.Parameterizer.LINKAGE_ID, SingleLinkageMethod.class);
- ExtractFlatClusteringFromHierarchy<DoubleDistance> c = ClassGenericsUtil.parameterizeOrAbort(ExtractFlatClusteringFromHierarchy.class, params);
- testParameterizationOk(params);
-
- // run clustering algorithm on database
- Result result = c.run(db);
- Clustering<?> clustering = findSingleClustering(result);
- testFMeasure(db, clustering, 0.6829722);
- testClusterSizes(clustering, new int[] { 9, 200, 429 });
- }
-
- /**
- * Run agglomerative hierarchical clustering with fixed parameters and compare
- * the result to a golden standard.
- */
- @Test
- public void testWard() {
- Database db = makeSimpleDatabase(UNITTEST + "single-link-effect.ascii", 638);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(ExtractFlatClusteringFromHierarchy.Parameterizer.OUTPUTMODE_ID, ExtractFlatClusteringFromHierarchy.OutputMode.STRICT_PARTITIONS);
- params.addParameter(ExtractFlatClusteringFromHierarchy.Parameterizer.MINCLUSTERS_ID, 3);
- params.addParameter(AlgorithmStep.Parameterizer.ALGORITHM_ID, NaiveAgglomerativeHierarchicalClustering.class);
- ExtractFlatClusteringFromHierarchy<DoubleDistance> c = ClassGenericsUtil.parameterizeOrAbort(ExtractFlatClusteringFromHierarchy.class, params);
- testParameterizationOk(params);
-
- // run clustering algorithm on database
- Result result = c.run(db);
- Clustering<?> clustering = findSingleClustering(result);
- testFMeasure(db, clustering, 0.93866265);
- testClusterSizes(clustering, new int[] { 200, 211, 227 });
- }
-
- /**
- * Run agglomerative hierarchical clustering with fixed parameters and compare
- * the result to a golden standard.
- */
- @Test
- public void testGroupAverage() {
- Database db = makeSimpleDatabase(UNITTEST + "single-link-effect.ascii", 638);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(ExtractFlatClusteringFromHierarchy.Parameterizer.OUTPUTMODE_ID, ExtractFlatClusteringFromHierarchy.OutputMode.STRICT_PARTITIONS);
- params.addParameter(ExtractFlatClusteringFromHierarchy.Parameterizer.MINCLUSTERS_ID, 3);
- params.addParameter(AlgorithmStep.Parameterizer.ALGORITHM_ID, NaiveAgglomerativeHierarchicalClustering.class);
- params.addParameter(NaiveAgglomerativeHierarchicalClustering.Parameterizer.LINKAGE_ID, GroupAverageLinkageMethod.class);
- ExtractFlatClusteringFromHierarchy<DoubleDistance> c = ClassGenericsUtil.parameterizeOrAbort(ExtractFlatClusteringFromHierarchy.class, params);
- testParameterizationOk(params);
-
- // run clustering algorithm on database
- Result result = c.run(db);
- Clustering<?> clustering = findSingleClustering(result);
- testFMeasure(db, clustering, 0.93866265);
- testClusterSizes(clustering, new int[] { 200, 211, 227 });
- }
-
- /**
- * Run agglomerative hierarchical clustering with fixed parameters and compare
- * the result to a golden standard.
- */
- @Test
- public void testCompleteLink() {
- Database db = makeSimpleDatabase(UNITTEST + "single-link-effect.ascii", 638);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(ExtractFlatClusteringFromHierarchy.Parameterizer.OUTPUTMODE_ID, ExtractFlatClusteringFromHierarchy.OutputMode.STRICT_PARTITIONS);
- params.addParameter(ExtractFlatClusteringFromHierarchy.Parameterizer.MINCLUSTERS_ID, 3);
- params.addParameter(AlgorithmStep.Parameterizer.ALGORITHM_ID, NaiveAgglomerativeHierarchicalClustering.class);
- params.addParameter(NaiveAgglomerativeHierarchicalClustering.Parameterizer.LINKAGE_ID, CompleteLinkageMethod.class);
- ExtractFlatClusteringFromHierarchy<DoubleDistance> c = ClassGenericsUtil.parameterizeOrAbort(ExtractFlatClusteringFromHierarchy.class, params);
- testParameterizationOk(params);
-
- // run clustering algorithm on database
- Result result = c.run(db);
- Clustering<?> clustering = findSingleClustering(result);
- testFMeasure(db, clustering, 0.938167802);
- testClusterSizes(clustering, new int[] { 200, 217, 221 });
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/TestSLINKResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/TestSLINKResults.java
deleted file mode 100644
index 8b25cf9c..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/hierarchical/TestSLINKResults.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.hierarchical;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.result.Result;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-import de.lmu.ifi.dbs.elki.workflow.AlgorithmStep;
-
-/**
- * Performs a full SLINK run, and compares the result with a clustering derived
- * from the data set labels. This test ensures that SLINK's performance doesn't
- * unexpectedly drop on this data set (and also ensures that the algorithms
- * work, as a side effect).
- *
- * @author Katharina Rausch
- * @author Erich Schubert
- */
-public class TestSLINKResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- // TODO: add a test for a non-single-link dataset?
-
- /**
- * Run SLINK with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testSLINKResults() {
- Database db = makeSimpleDatabase(UNITTEST + "single-link-effect.ascii", 638);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(ExtractFlatClusteringFromHierarchy.Parameterizer.OUTPUTMODE_ID, ExtractFlatClusteringFromHierarchy.OutputMode.STRICT_PARTITIONS);
- params.addParameter(ExtractFlatClusteringFromHierarchy.Parameterizer.MINCLUSTERS_ID, 3);
- params.addParameter(AlgorithmStep.Parameterizer.ALGORITHM_ID, SLINK.class);
- ExtractFlatClusteringFromHierarchy<DoubleDistance> slink = ClassGenericsUtil.parameterizeOrAbort(ExtractFlatClusteringFromHierarchy.class, params);
- testParameterizationOk(params);
-
- // run SLINK on database
- Result result = slink.run(db);
- Clustering<?> clustering = findSingleClustering(result);
- testFMeasure(db, clustering, 0.6829722);
- testClusterSizes(clustering, new int[] { 9, 200, 429 });
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/TestKMeansBisecting.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/TestKMeansBisecting.java
deleted file mode 100644
index d678981d..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/TestKMeansBisecting.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
-
-/*
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.WithinClusterVarianceQualityMeasure;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.MeanModel;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the KMeansBisecting
- *
- * @author Stephan Baier
- */
-public class TestKMeansBisecting extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run KMeansBisecting with fixed parameters and compare cluster size to
- * expected value.
- */
- @Test
- public void testKMeansBisectingClusterSize() {
- Database db = makeSimpleDatabase(UNITTEST + "bisecting-test.csv", 300);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(KMeans.K_ID, 3);
- params.addParameter(BestOfMultipleKMeans.Parameterizer.TRIALS_ID, 5);
- params.addParameter(BestOfMultipleKMeans.Parameterizer.KMEANS_ID, KMeansLloyd.class);
- params.addParameter(BestOfMultipleKMeans.Parameterizer.QUALITYMEASURE_ID, WithinClusterVarianceQualityMeasure.class);
-
- KMeansBisecting<DoubleVector, DoubleDistance, MeanModel<DoubleVector>> kmeans = ClassGenericsUtil.parameterizeOrAbort(KMeansBisecting.class, params);
- testParameterizationOk(params);
-
- // run KMedians on database
- Clustering<MeanModel<DoubleVector>> result = kmeans.run(db);
- testClusterSizes(result, new int[] { 103, 97, 100 });
- }
-
- /**
- * Run KMeansBisecting with fixed parameters (k = 2) and compare f-measure to
- * golden standard.
- */
- @Test
- public void testKMeansBisectingFMeasure() {
- Database db = makeSimpleDatabase(UNITTEST + "bisecting-test.csv", 300);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(KMeans.K_ID, 2);
- params.addParameter(BestOfMultipleKMeans.Parameterizer.TRIALS_ID, 5);
- params.addParameter(BestOfMultipleKMeans.Parameterizer.KMEANS_ID, KMeansLloyd.class);
- params.addParameter(BestOfMultipleKMeans.Parameterizer.QUALITYMEASURE_ID, WithinClusterVarianceQualityMeasure.class);
-
- KMeansBisecting<DoubleVector, DoubleDistance, MeanModel<DoubleVector>> kmeans = ClassGenericsUtil.parameterizeOrAbort(KMeansBisecting.class, params);
- testParameterizationOk(params);
-
- // run KMedians on database
- Clustering<MeanModel<DoubleVector>> result = kmeans.run(db);
- testFMeasure(db, result, 0.7408);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/TestKMeansQualityMeasure.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/TestKMeansQualityMeasure.java
deleted file mode 100644
index 44603617..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/TestKMeansQualityMeasure.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
-
-/*
- 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 static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.KMeansQualityMeasure;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.WithinClusterMeanDistanceQualityMeasure;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.quality.WithinClusterVarianceQualityMeasure;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.model.MeanModel;
-import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
-import de.lmu.ifi.dbs.elki.database.Database;
-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.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Test cluster quality measure computations.
- *
- * @author Stephan Baier
- */
-public class TestKMeansQualityMeasure extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Test cluster variance.
- */
- @Test
- public void testVariance() {
- Database db = makeSimpleDatabase(UNITTEST + "quality-measure-test.csv", 7);
- Relation<DoubleVector> rel = db.getRelation(TypeUtil.DOUBLE_VECTOR_FIELD);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params = new ListParameterization();
- params.addParameter(KMeans.K_ID, 2);
- params.addParameter(KMeans.INIT_ID, FirstKInitialMeans.class);
- AbstractKMeans<DoubleVector, DoubleDistance, ?> kmeans = ClassGenericsUtil.parameterizeOrAbort(KMeansLloyd.class, params);
- testParameterizationOk(params);
-
- // run KMeans on database
- @SuppressWarnings("unchecked")
- Clustering<MeanModel<DoubleVector>> result2 = (Clustering<MeanModel<DoubleVector>>) kmeans.run(db);
-
- // Test Cluster Variance
- KMeansQualityMeasure<? super DoubleVector, ? super DoubleDistance> variance = new WithinClusterVarianceQualityMeasure();
- @SuppressWarnings("unchecked")
- final PrimitiveDoubleDistanceFunction<NumberVector<?>> dist = (PrimitiveDoubleDistanceFunction<NumberVector<?>>) kmeans.getDistanceFunction();
-
- final double quality = variance.calculateCost(result2, dist, rel);
- assertEquals("Within cluster variance incorrect", 3.16666666666, quality, 1e-10);
- }
-
- /**
- * Test cluster average overall distance.
- */
- @Test
- public void testOverallDistance() {
-
- Database db = makeSimpleDatabase(UNITTEST + "quality-measure-test.csv", 7);
- Relation<DoubleVector> rel = db.getRelation(TypeUtil.DOUBLE_VECTOR_FIELD);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params = new ListParameterization();
- params.addParameter(KMeans.K_ID, 2);
- params.addParameter(KMeans.INIT_ID, FirstKInitialMeans.class);
- AbstractKMeans<DoubleVector, DoubleDistance, ?> kmeans = ClassGenericsUtil.parameterizeOrAbort(KMeansLloyd.class, params);
- testParameterizationOk(params);
-
- // run KMeans on database
- @SuppressWarnings("unchecked")
- Clustering<MeanModel<DoubleVector>> result = (Clustering<MeanModel<DoubleVector>>) kmeans.run(db);
- @SuppressWarnings("unchecked")
- final PrimitiveDoubleDistanceFunction<NumberVector<?>> dist = (PrimitiveDoubleDistanceFunction<NumberVector<?>>) kmeans.getDistanceFunction();
-
- // Test Cluster Average Overall Distance
- KMeansQualityMeasure<? super DoubleVector, ? super DoubleDistance> overall = new WithinClusterMeanDistanceQualityMeasure();
- final double quality = overall.calculateCost(result, dist, rel);
-
- assertEquals("Avarage overall distance not as expected.", 0.8888888888888888, quality, 1e-10);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/TestKMeansResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/TestKMeansResults.java
deleted file mode 100644
index 3601b977..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/kmeans/TestKMeansResults.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansLloyd;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.MeanModel;
-import de.lmu.ifi.dbs.elki.data.model.MedoidModel;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Performs a full KMeans run, and compares the result with a clustering derived
- * from the data set labels. This test ensures that KMeans's performance doesn't
- * unexpectedly drop on this data set (and also ensures that the algorithms
- * work, as a side effect).
- *
- * @author Katharina Rausch
- * @author Erich Schubert
- */
-public class TestKMeansResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run KMeans with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testKMeansLloyd() {
- Database db = makeSimpleDatabase(UNITTEST + "different-densities-2d-no-noise.ascii", 1000);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(KMeans.K_ID, 5);
- params.addParameter(KMeans.SEED_ID, 2);
- AbstractKMeans<DoubleVector, DoubleDistance, ?> kmeans = ClassGenericsUtil.parameterizeOrAbort(KMeansLloyd.class, params);
- testParameterizationOk(params);
-
- // run KMeans on database
- Clustering<? extends MeanModel<DoubleVector>> result = kmeans.run(db);
- testFMeasure(db, result, 0.998005);
- testClusterSizes(result, new int[] { 199, 200, 200, 200, 201 });
- }
-
- /**
- * Run KMeans with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testKMeansMacQueen() {
- Database db = makeSimpleDatabase(UNITTEST + "different-densities-2d-no-noise.ascii", 1000);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(KMeans.K_ID, 5);
- params.addParameter(KMeans.SEED_ID, 2);
- AbstractKMeans<DoubleVector, DoubleDistance, ?> kmeans = ClassGenericsUtil.parameterizeOrAbort(KMeansMacQueen.class, params);
- testParameterizationOk(params);
-
- // run KMeans on database
- Clustering<? extends MeanModel<DoubleVector>> result = kmeans.run(db);
- testFMeasure(db, result, 0.998005);
- testClusterSizes(result, new int[] { 199, 200, 200, 200, 201 });
- }
-
- /**
- * Run KMedians with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testKMediansLloyd() {
- Database db = makeSimpleDatabase(UNITTEST + "different-densities-2d-no-noise.ascii", 1000);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(KMeans.K_ID, 5);
- params.addParameter(KMeans.SEED_ID, 2);
- AbstractKMeans<DoubleVector, DoubleDistance, ?> kmedians = ClassGenericsUtil.parameterizeOrAbort(KMediansLloyd.class, params);
- testParameterizationOk(params);
-
- // run KMedians on database
- Clustering<? extends MeanModel<DoubleVector>> result = kmedians.run(db);
- testFMeasure(db, result, 0.998005);
- testClusterSizes(result, new int[] { 199, 200, 200, 200, 201 });
- }
-
- /**
- * Run KMedians PAM with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testKMedoidsPAM() {
- Database db = makeSimpleDatabase(UNITTEST + "different-densities-2d-no-noise.ascii", 1000);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(KMeans.K_ID, 5);
- KMedoidsPAM<DoubleVector, DoubleDistance> kmedians = ClassGenericsUtil.parameterizeOrAbort(KMedoidsPAM.class, params);
- testParameterizationOk(params);
-
- // run KMedians on database
- Clustering<MedoidModel> result = kmedians.run(db);
- testFMeasure(db, result, 0.998005);
- testClusterSizes(result, new int[] { 199, 200, 200, 200, 201 });
- }
-
- /**
- * Run KMedoidsEM with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testKMedoidsEM() {
- Database db = makeSimpleDatabase(UNITTEST + "different-densities-2d-no-noise.ascii", 1000);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(KMeans.K_ID, 5);
- KMedoidsEM<DoubleVector, DoubleDistance> kmedians = ClassGenericsUtil.parameterizeOrAbort(KMedoidsEM.class, params);
- testParameterizationOk(params);
-
- // run KMedians on database
- Clustering<MedoidModel> result = kmedians.run(db);
- testFMeasure(db, result, 0.998005);
- testClusterSizes(result, new int[] { 199, 200, 200, 200, 201 });
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestCLIQUEResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestCLIQUEResults.java
deleted file mode 100644
index 726efd76..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestCLIQUEResults.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.SubspaceModel;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Performs a full CLIQUE run, and compares the result with a clustering derived
- * from the data set labels. This test ensures that CLIQUE performance doesn't
- * unexpectedly drop on this data set (and also ensures that the algorithms
- * work, as a side effect).
- *
- * @author Elke Achtert
- * @author Katharina Rausch
- * @author Erich Schubert
- */
-public class TestCLIQUEResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run CLIQUE with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testCLIQUEResults() {
- Database db = makeSimpleDatabase(UNITTEST + "subspace-simple.csv", 600);
-
- ListParameterization params = new ListParameterization();
- params.addParameter(CLIQUE.TAU_ID, "0.1");
- params.addParameter(CLIQUE.XSI_ID, 20);
-
- // setup algorithm
- CLIQUE<DoubleVector> clique = ClassGenericsUtil.parameterizeOrAbort(CLIQUE.class, params);
- testParameterizationOk(params);
-
- // run CLIQUE on database
- Clustering<SubspaceModel<DoubleVector>> result = clique.run(db);
-
- // PairCounting is not appropriate here: overlapping clusterings!
- // testFMeasure(db, result, 0.9882);
- testClusterSizes(result, new int[] { 200, 200, 216, 400 });
- }
-
- /**
- * Run CLIQUE with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testCLIQUESubspaceOverlapping() {
- Database db = makeSimpleDatabase(UNITTEST + "subspace-overlapping-3-4d.ascii", 850);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(CLIQUE.TAU_ID, 0.2);
- params.addParameter(CLIQUE.XSI_ID, 6);
- CLIQUE<DoubleVector> clique = ClassGenericsUtil.parameterizeOrAbort(CLIQUE.class, params);
- testParameterizationOk(params);
-
- // run CLIQUE on database
- Clustering<SubspaceModel<DoubleVector>> result = clique.run(db);
- // PairCounting is not appropriate here: overlapping clusterings!
- // testFMeasure(db, result, 0.433661);
- testClusterSizes(result, new int[] { 255, 409, 458, 458, 480 });
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestDiSHResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestDiSHResults.java
deleted file mode 100644
index c7be9747..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestDiSHResults.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.SubspaceModel;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Performs a full DiSH run, and compares the result with a clustering derived
- * from the data set labels. This test ensures that DiSH performance doesn't
- * unexpectedly drop on this data set (and also ensures that the algorithms
- * work, as a side effect).
- *
- * @author Elke Achtert
- * @author Katharina Rausch
- * @author Erich Schubert
- */
-public class TestDiSHResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run DiSH with fixed parameters and compare the result to a golden standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testDiSHResults() {
- Database db = makeSimpleDatabase(UNITTEST + "subspace-hierarchy.csv", 450);
-
- ListParameterization params = new ListParameterization();
- params.addParameter(DiSH.EPSILON_ID, 0.005);
- params.addParameter(DiSH.MU_ID, 50);
-
- // setup algorithm
- DiSH<DoubleVector> dish = ClassGenericsUtil.parameterizeOrAbort(DiSH.class, params);
- testParameterizationOk(params);
-
- // run DiSH on database
- Clustering<SubspaceModel<DoubleVector>> result = dish.run(db);
-
- testFMeasure(db, result, 0.996976); // Hierarchical pairs scored: 0.9991258
- testClusterSizes(result, new int[] { 51, 199, 200 });
- }
-
- /**
- * Run DiSH with fixed parameters and compare the result to a golden standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testDiSHSubspaceOverlapping() {
- Database db = makeSimpleDatabase(UNITTEST + "subspace-overlapping-4-5d.ascii", 1100);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(DiSH.EPSILON_ID, 0.1);
- params.addParameter(DiSH.MU_ID, 30);
- DiSH<DoubleVector> dish = ClassGenericsUtil.parameterizeOrAbort(DiSH.class, params);
- testParameterizationOk(params);
-
- // run DiSH on database
- Clustering<SubspaceModel<DoubleVector>> result = dish.run(db);
- testFMeasure(db, result, 0.6376870);
- testClusterSizes(result, new int[] { 33, 52, 72, 109, 172, 314, 348 });
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestP3C.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestP3C.java
deleted file mode 100644
index 4d02351f..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestP3C.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.SubspaceModel;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Test P3C on a simple test data set.
- *
- * Note: both data sets are really beneficial for P3C, and with reasonably
- * chosen parameters, it works perfectly.
- *
- * @author Erich Schubert
- */
-public class TestP3C extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run P3C with fixed parameters and compare the result to a golden standard.
- */
- @Test
- public void testP3CSimple() {
- Database db = makeSimpleDatabase(UNITTEST + "subspace-simple.csv", 600);
-
- ListParameterization params = new ListParameterization();
-
- // setup algorithm
- P3C<DoubleVector> p3c = ClassGenericsUtil.parameterizeOrAbort(P3C.class, params);
- testParameterizationOk(params);
-
- // run P3C on database
- Clustering<SubspaceModel<DoubleVector>> result = p3c.run(db);
-
- testFMeasure(db, result, 1.0);
- testClusterSizes(result, new int[] { 200, 400 });
- }
-
- /**
- * Run P3C with fixed parameters and compare the result to a golden standard.
- */
- @Test
- public void testP3COverlapping() {
- Database db = makeSimpleDatabase(UNITTEST + "subspace-overlapping-3-4d.ascii", 850);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(P3C.Parameterizer.ALPHA_THRESHOLD_ID, 0.01);
- P3C<DoubleVector> p3c = ClassGenericsUtil.parameterizeOrAbort(P3C.class, params);
- testParameterizationOk(params);
-
- // run P3C on database
- Clustering<SubspaceModel<DoubleVector>> result = p3c.run(db);
- testFMeasure(db, result, 1.0);
- testClusterSizes(result, new int[] { 150, 300, 400 });
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestPROCLUSResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestPROCLUSResults.java
deleted file mode 100644
index bfb94ee3..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestPROCLUSResults.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Performs a full PROCLUS run, and compares the result with a clustering
- * derived from the data set labels. This test ensures that PROCLUS performance
- * doesn't unexpectedly drop on this data set (and also ensures that the
- * algorithms work, as a side effect).
- *
- * @author Elke Achtert
- * @author Katharina Rausch
- * @author Erich Schubert
- */
-public class TestPROCLUSResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run PROCLUS with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testPROCLUSResults() {
- Database db = makeSimpleDatabase(UNITTEST + "subspace-simple.csv", 600);
-
- ListParameterization params = new ListParameterization();
- params.addParameter(PROCLUS.Parameterizer.L_ID, 1);
- params.addParameter(PROCLUS.Parameterizer.K_ID, 4);
- // NOTE: PROCLUS quality heavily depends on random...
- params.addParameter(PROCLUS.Parameterizer.SEED_ID, 0);
-
- // setup algorithm
- PROCLUS<DoubleVector> proclus = ClassGenericsUtil.parameterizeOrAbort(PROCLUS.class, params);
- testParameterizationOk(params);
-
- // run PROCLUS on database
- Clustering<?> result = proclus.run(db);
-
- testFMeasure(db, result, 0.6946958);
- testClusterSizes(result, new int[] { 45, 151, 200, 204 });
- }
-
- /**
- * Run PROCLUS with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testPROCLUSSubspaceOverlapping() {
- Database db = makeSimpleDatabase(UNITTEST + "subspace-overlapping-3-4d.ascii", 850);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(PROCLUS.Parameterizer.L_ID, 2);
- params.addParameter(PROCLUS.Parameterizer.K_ID, 3);
- // NOTE: PROCLUS quality heavily depends on random...
- params.addParameter(PROCLUS.Parameterizer.SEED_ID, 1);
- PROCLUS<DoubleVector> proclus = ClassGenericsUtil.parameterizeOrAbort(PROCLUS.class, params);
- testParameterizationOk(params);
-
- // run PROCLUS on database
- Clustering<?> result = proclus.run(db);
- testFMeasure(db, result, 0.7812455);
- testClusterSizes(result, new int[] { 111, 269, 470 });
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestPreDeConResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestPreDeConResults.java
deleted file mode 100644
index d00a703f..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestPreDeConResults.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.AbstractProjectedDBSCAN;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.Model;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.datasource.filter.ClassLabelFilter;
-import de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj.PreDeConSubspaceIndex.Factory;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Perform a full PreDeCon run, and compare the result with a clustering derived
- * from the data set labels. This test ensures that PreDeCon performance doesn't
- * unexpectedly drop on this data set (and also ensures that the algorithms
- * work, as a side effect).
- *
- * @author Erich Schubert
- * @author Katharina Rausch
- */
-public class TestPreDeConResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run PreDeCon with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testPreDeConResults() {
- // Additional input parameters
- ListParameterization inp = new ListParameterization();
- inp.addParameter(ClassLabelFilter.Parameterizer.CLASS_LABEL_INDEX_ID, 1);
- Class<?>[] filters = new Class<?>[] { ClassLabelFilter.class };
- Database db = makeSimpleDatabase(UNITTEST + "axis-parallel-subspace-clusters-6d.csv.gz", 2500, inp, filters);
-
- ListParameterization params = new ListParameterization();
- // PreDeCon
- // FIXME: These parameters do NOT work...
- params.addParameter(AbstractProjectedDBSCAN.EPSILON_ID, 50);
- params.addParameter(AbstractProjectedDBSCAN.MINPTS_ID, 50);
- params.addParameter(AbstractProjectedDBSCAN.LAMBDA_ID, 2);
-
- // setup algorithm
- PreDeCon<DoubleVector> predecon = ClassGenericsUtil.parameterizeOrAbort(PreDeCon.class, params);
- testParameterizationOk(params);
-
- // run PredeCon on database
- Clustering<Model> result = predecon.run(db);
-
- // FIXME: find working parameters...
- testFMeasure(db, result, 0.40153);
- testClusterSizes(result, new int[] { 2500 });
- }
-
- /**
- * Run PreDeCon with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testPreDeConSubspaceOverlapping() {
- Database db = makeSimpleDatabase(UNITTEST + "subspace-overlapping-3-4d.ascii", 850);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- // PreDeCon
- params.addParameter(AbstractProjectedDBSCAN.EPSILON_ID, 2.0);
- params.addParameter(AbstractProjectedDBSCAN.MINPTS_ID, 7);
- params.addParameter(AbstractProjectedDBSCAN.LAMBDA_ID, 4);
- params.addParameter(Factory.DELTA_ID, 0.04);
- PreDeCon<DoubleVector> predecon = ClassGenericsUtil.parameterizeOrAbort(PreDeCon.class, params);
- testParameterizationOk(params);
-
- // run PredeCon on database
- Clustering<Model> result = predecon.run(db);
- testFMeasure(db, result, 0.6470817);
- testClusterSizes(result, new int[] { 7, 10, 10, 13, 15, 16, 16, 18, 28, 131, 586 });
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestSUBCLUResults.java b/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestSUBCLUResults.java
deleted file mode 100644
index 817687c5..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/clustering/subspace/TestSUBCLUResults.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.clustering.subspace;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.model.SubspaceModel;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Performs a full SUBCLU run, and compares the result with a clustering derived
- * from the data set labels. This test ensures that SUBCLU performance doesn't
- * unexpectedly drop on this data set (and also ensures that the algorithms
- * work, as a side effect).
- *
- * @author Elke Achtert
- * @author Katharina Rausch
- * @author Erich Schubert
- */
-public class TestSUBCLUResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- /**
- * Run SUBCLU with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testSUBCLUResults() {
- Database db = makeSimpleDatabase(UNITTEST + "subspace-simple.csv", 600);
-
- ListParameterization params = new ListParameterization();
- params.addParameter(SUBCLU.EPSILON_ID, 0.001);
- params.addParameter(SUBCLU.MINPTS_ID, 100);
-
- // setup algorithm
- SUBCLU<DoubleVector> subclu = ClassGenericsUtil.parameterizeOrAbort(SUBCLU.class, params);
- testParameterizationOk(params);
-
- // run SUBCLU on database
- Clustering<SubspaceModel<DoubleVector>> result = subclu.run(db);
-
- // PairCounting is not appropriate here: overlapping clusterings!
- // testFMeasure(db, result, 0.9090);
- testClusterSizes(result, new int[] { 191, 194, 395 });
- }
-
- /**
- * Run SUBCLU with fixed parameters and compare the result to a golden
- * standard.
- *
- * @throws ParameterException
- */
- @Test
- public void testSUBCLUSubspaceOverlapping() {
- Database db = makeSimpleDatabase(UNITTEST + "subspace-overlapping-3-4d.ascii", 850);
-
- // Setup algorithm
- ListParameterization params = new ListParameterization();
- params.addParameter(SUBCLU.EPSILON_ID, 0.04);
- params.addParameter(SUBCLU.MINPTS_ID, 70);
- SUBCLU<DoubleVector> subclu = ClassGenericsUtil.parameterizeOrAbort(SUBCLU.class, params);
- testParameterizationOk(params);
-
- // run SUBCLU on database
- Clustering<SubspaceModel<DoubleVector>> result = subclu.run(db);
- // PairCounting is not appropriate here: overlapping clusterings!
- // testFMeasure(db, result, 0.49279033);
- testClusterSizes(result, new int[] { 99, 247, 303, 323, 437, 459 });
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestABOD.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestABOD.java
deleted file mode 100644
index e213b54e..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestABOD.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the ABOD algorithm.
- *
- * Note: we don't implement JUnit4Test, as this test is slow.
- *
- * @author Lucia Cichella
- */
-public class TestABOD extends AbstractSimpleAlgorithmTest {
- @Test
- public void testABOD() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-3d-3clusters.ascii", 960);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
-
- // setup Algorithm
- ABOD<DoubleVector> abod = ClassGenericsUtil.parameterizeOrAbort(ABOD.class, params);
- testParameterizationOk(params);
-
- // run ABOD on database
- OutlierResult result = abod.run(db);
-
- testAUC(db, "Noise", result, 0.94887037037037);
- testSingleScore(result, 945, 1.88108120738508E-4);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestAggarwalYuEvolutionary.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestAggarwalYuEvolutionary.java
deleted file mode 100644
index cabd315a..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestAggarwalYuEvolutionary.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the AggarwalYuEvolutionary algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestAggarwalYuEvolutionary extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testAggarwalYuEvolutionary() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-3d-3clusters.ascii", 960);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(AggarwalYuEvolutionary.Parameterizer.K_ID, 2);
- params.addParameter(AggarwalYuEvolutionary.Parameterizer.PHI_ID, 8);
- params.addParameter(AggarwalYuEvolutionary.Parameterizer.M_ID, 5);
- params.addParameter(AggarwalYuEvolutionary.Parameterizer.SEED_ID, 0);
-
- // setup Algorithm
- AggarwalYuEvolutionary<DoubleVector> aggarwalYuEvolutionary = ClassGenericsUtil.parameterizeOrAbort(AggarwalYuEvolutionary.class, params);
- testParameterizationOk(params);
-
- // run AggarwalYuEvolutionary on database
- OutlierResult result = aggarwalYuEvolutionary.run(db);
-
- testSingleScore(result, 945, 16.6553612449883);
- testAUC(db, "Noise", result, 0.5799537037037);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestAggarwalYuNaive.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestAggarwalYuNaive.java
deleted file mode 100644
index 016fe5e5..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestAggarwalYuNaive.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the AggarwalYuNaive algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestAggarwalYuNaive extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testAggarwalYuNaive() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-3d-3clusters.ascii", 960);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(AggarwalYuNaive.Parameterizer.K_ID, 2);
- params.addParameter(AggarwalYuNaive.Parameterizer.PHI_ID, 8);
-
- // setup Algorithm
- AggarwalYuNaive<DoubleVector> aggarwalYuNaive = ClassGenericsUtil.parameterizeOrAbort(AggarwalYuNaive.class, params);
- testParameterizationOk(params);
-
- // run AggarwalYuNaive on database
- OutlierResult result = aggarwalYuNaive.run(db);
-
- testSingleScore(result, 945, -2.3421601750764798);
- testAUC(db, "Noise", result, 0.8652037037037);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestDBOutlierDetection.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestDBOutlierDetection.java
deleted file mode 100644
index 0d6fc7f6..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestDBOutlierDetection.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the DBOutlierDetection algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestDBOutlierDetection extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testDBOutlierDetection() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-fire.ascii", 1025);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(DBOutlierDetection.D_ID, 0.175);
- params.addParameter(DBOutlierDetection.P_ID, 0.98);
-
- // setup Algorithm
- DBOutlierDetection<DoubleVector, DoubleDistance> dbOutlierDetection = ClassGenericsUtil.parameterizeOrAbort(DBOutlierDetection.class, params);
- testParameterizationOk(params);
-
- // run DBOutlierDetection on database
- OutlierResult result = dbOutlierDetection.run(db);
-
- testSingleScore(result, 1025, 0.0);
- testAUC(db, "Noise", result, 0.97487179);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestDBOutlierScore.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestDBOutlierScore.java
deleted file mode 100644
index b34c071e..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestDBOutlierScore.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the DBOutlierScore algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestDBOutlierScore extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testDBOutlierScore() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-fire.ascii", 1025);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(DBOutlierScore.D_ID, 0.175);
-
- // setup Algorithm
- DBOutlierScore<DoubleVector, DoubleDistance> dbOutlierScore = ClassGenericsUtil.parameterizeOrAbort(DBOutlierScore.class, params);
- testParameterizationOk(params);
-
- // run DBOutlierScore on database
- OutlierResult result = dbOutlierScore.run(db);
-
- testSingleScore(result, 1025, 0.688780487804878);
- testAUC(db, "Noise", result, 0.992565641);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestFastABOD.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestFastABOD.java
deleted file mode 100644
index 11977af6..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestFastABOD.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the ABOD algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestFastABOD extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testFastABOD() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-3d-3clusters.ascii", 960);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(FastABOD.Parameterizer.K_ID, 5);
-
- // setup Algorithm
- FastABOD<DoubleVector> abod = ClassGenericsUtil.parameterizeOrAbort(FastABOD.class, params);
- testParameterizationOk(params);
-
- // run ABOD on database
- OutlierResult result = abod.run(db);
-
- testAUC(db, "Noise", result, 0.963259259259);
- testSingleScore(result, 945, 0.68723169783);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestGaussianModel.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestGaussianModel.java
deleted file mode 100644
index e18c2f46..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestGaussianModel.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the GaussianModel algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestGaussianModel extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testGaussianModel() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-fire.ascii", 1025);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
-
- // setup Algorithm
- GaussianModel<DoubleVector> gaussianModel = ClassGenericsUtil.parameterizeOrAbort(GaussianModel.class, params);
- testParameterizationOk(params);
-
- // run GaussianModel on database
- OutlierResult result = gaussianModel.run(db);
-
- testSingleScore(result, 1025, 2.8312466458765426);
- testAUC(db, "Noise", result, 0.9937641025641025);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestGaussianUniformMixture.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestGaussianUniformMixture.java
deleted file mode 100644
index c02da8a5..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestGaussianUniformMixture.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the GaussianUniformMixture algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestGaussianUniformMixture extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testGaussianUniformMixture() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-fire.ascii", 1025);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
-
- // setup Algorithm
- GaussianUniformMixture<DoubleVector> gaussianUniformMixture = ClassGenericsUtil.parameterizeOrAbort(GaussianUniformMixture.class, params);
- testParameterizationOk(params);
-
- // run GaussianUniformMixture on database
- OutlierResult result = gaussianUniformMixture.run(db);
-
- testSingleScore(result, 1025, -20.2862041);
- testAUC(db, "Noise", result, 0.94404102);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestKNNOutlier.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestKNNOutlier.java
deleted file mode 100644
index 7d0457df..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestKNNOutlier.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the KNNOutlier algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestKNNOutlier extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testKNNOutlier() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-3d-3clusters.ascii", 960);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(KNNOutlier.K_ID, 2);
-
- // setup Algorithm
- KNNOutlier<DoubleVector, DoubleDistance> knnOutlier = ClassGenericsUtil.parameterizeOrAbort(KNNOutlier.class, params);
- testParameterizationOk(params);
-
- // run KNNOutlier on database
- OutlierResult result = knnOutlier.run(db);
-
- testSingleScore(result, 945, 0.4793554700168577);
- testAUC(db, "Noise", result, 0.991462962962963);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestKNNWeightOutlier.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestKNNWeightOutlier.java
deleted file mode 100644
index bbb1bdfb..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestKNNWeightOutlier.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the KNNWeightOutlier algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestKNNWeightOutlier extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testKNNWeightOutlier() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-3d-3clusters.ascii", 960);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(KNNWeightOutlier.K_ID, 5);
-
- // setup Algorithm
- KNNWeightOutlier<DoubleVector, DoubleDistance> knnWeightOutlier = ClassGenericsUtil.parameterizeOrAbort(KNNWeightOutlier.class, params);
- testParameterizationOk(params);
-
- // run KNNWeightOutlier on database
- OutlierResult result = knnWeightOutlier.run(db);
-
- testSingleScore(result, 945, 2.384117261027324);
- testAUC(db, "Noise", result, 0.9912777777777778);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestLBABOD.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestLBABOD.java
deleted file mode 100644
index 5a1f56f2..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestLBABOD.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the LB-ABOD algorithm.
- *
- * Note: we don't implement JUnit4Test, as this test is slow.
- *
- * @author Lucia Cichella
- */
-public class TestLBABOD extends AbstractSimpleAlgorithmTest {
- @Test
- public void testLBABOD() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-3d-3clusters.ascii", 960);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(FastABOD.Parameterizer.K_ID, 150);
- params.addParameter(LBABOD.Parameterizer.L_ID, 10);
-
- // setup Algorithm
- LBABOD<DoubleVector> abod = ClassGenericsUtil.parameterizeOrAbort(LBABOD.class, params);
- testParameterizationOk(params);
-
- // run ABOD on database
- OutlierResult result = abod.run(db);
-
- testAUC(db, "Noise", result, 0.928999999999);
- testSingleScore(result, 945, 1.88108120738508E-4);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestOPTICSOF.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestOPTICSOF.java
deleted file mode 100644
index ed9e1533..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestOPTICSOF.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICS;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the OPTICS-OF algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestOPTICSOF extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testOPTICSOF() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-parabolic.ascii", 530);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(OPTICS.MINPTS_ID, 22);
-
- // setup Algorithm
- OPTICSOF<DoubleVector, DoubleDistance> opticsof = ClassGenericsUtil.parameterizeOrAbort(OPTICSOF.class, params);
- testParameterizationOk(params);
-
- // run OPTICSOF on database
- OutlierResult result = opticsof.run(db);
-
- testSingleScore(result, 416, 1.6108343626651815);
- testAUC(db, "Noise", result, 0.9058);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestReferenceBasedOutlierDetection.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestReferenceBasedOutlierDetection.java
deleted file mode 100644
index 5b6d3bde..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/TestReferenceBasedOutlierDetection.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-import de.lmu.ifi.dbs.elki.utilities.referencepoints.GridBasedReferencePoints;
-
-/**
- * Tests the ReferenceBasedOutlierDetection algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestReferenceBasedOutlierDetection extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testReferenceBasedOutlierDetection() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-3d-3clusters.ascii", 960);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(ReferenceBasedOutlierDetection.K_ID, 11);
- params.addParameter(GridBasedReferencePoints.GRID_ID, 11);
-
- // setup Algorithm
- ReferenceBasedOutlierDetection<DoubleVector, DoubleDistance> referenceBasedOutlierDetection = ClassGenericsUtil.parameterizeOrAbort(ReferenceBasedOutlierDetection.class, params);
- testParameterizationOk(params);
-
- // run ReferenceBasedOutlierDetection on database
- OutlierResult result = referenceBasedOutlierDetection.run(db);
-
- testSingleScore(result, 945, 0.9260829537195538);
- testAUC(db, "Noise", result, 0.9892407407407409);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestINFLO.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestINFLO.java
deleted file mode 100644
index 99b97d92..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestINFLO.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.INFLO;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the INFLO algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestINFLO extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testINFLO() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-3d-3clusters.ascii", 960);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(INFLO.K_ID, 29);
-
- // setup Algorithm
- INFLO<DoubleVector, DoubleDistance> inflo = ClassGenericsUtil.parameterizeOrAbort(INFLO.class, params);
- testParameterizationOk(params);
-
- // run INFLO on database
- OutlierResult result = inflo.run(db);
-
- testSingleScore(result, 945, 1.215459716);
- testAUC(db, "Noise", result, 0.9389259259259);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLDOF.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLDOF.java
deleted file mode 100644
index 370054ea..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLDOF.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LDOF;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the LDOF algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestLDOF extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testLDOF() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-fire.ascii", 1025);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(LDOF.K_ID, 25);
-
- // setup Algorithm
- LDOF<DoubleVector, DoubleDistance> ldof = ClassGenericsUtil.parameterizeOrAbort(LDOF.class, params);
- testParameterizationOk(params);
-
- // run LDOF on database
- OutlierResult result = ldof.run(db);
-
- testAUC(db, "Noise", result, 0.9637948717948718);
- testSingleScore(result, 1025, 0.8976268846182947);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLOCI.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLOCI.java
deleted file mode 100644
index 05206f55..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLOCI.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOCI;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the LOCI algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestLOCI extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testLOCI() {
- Database db = makeSimpleDatabase(UNITTEST + "3clusters-and-noise-2d.csv", 330);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(LOCI.RMAX_ID, 0.5);
-
- // setup Algorithm
- LOCI<DoubleVector, DoubleDistance> loci = ClassGenericsUtil.parameterizeOrAbort(LOCI.class, params);
- testParameterizationOk(params);
-
- // run LOCI on database
- OutlierResult result = loci.run(db);
-
- testAUC(db, "Noise", result, 0.96222222);
- testSingleScore(result, 146, 3.8054382);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLOF.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLOF.java
deleted file mode 100644
index 2c7bbd1d..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLOF.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOF;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the LOF algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestLOF extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testLOF() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-axis-subspaces-6d.ascii", 1345);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(LOF.Parameterizer.K_ID, 10);
-
- // setup Algorithm
- LOF<DoubleVector, DoubleDistance> lof = ClassGenericsUtil.parameterizeOrAbort(LOF.class, params);
- testParameterizationOk(params);
-
- // run LOF on database
- OutlierResult result = lof.run(db);
-
- testSingleScore(result, 1293, 1.1945314199156365);
- testAUC(db, "Noise", result, 0.8921680672268908);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLoOP.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLoOP.java
deleted file mode 100644
index e6670eb7..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestLoOP.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LoOP;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the LoOP algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestLoOP extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testLoOP() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-3d-3clusters.ascii", 960);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(LoOP.KCOMP_ID, 15);
-
- // setup Algorithm
- LoOP<DoubleVector, DoubleDistance> loop = ClassGenericsUtil.parameterizeOrAbort(LoOP.class, params);
- testParameterizationOk(params);
-
- // run LoOP on database
- OutlierResult result = loop.run(db);
-
- testAUC(db, "Noise", result, 0.9443796296296296);
- testSingleScore(result, 945, 0.39805457858293325);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestOnlineLOF.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestOnlineLOF.java
deleted file mode 100644
index 889cddce..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/TestOnlineLOF.java
+++ /dev/null
@@ -1,168 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.Random;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.FlexibleLOF;
-import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOF;
-import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.OnlineLOF;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-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.database.HashmapDatabase;
-import de.lmu.ifi.dbs.elki.database.UpdatableDatabase;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-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.database.relation.RelationUtil;
-import de.lmu.ifi.dbs.elki.datasource.FileBasedDatabaseConnection;
-import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.CosineDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the OnlineLOF algorithm. Compares the result of the static LOF
- * algorithm to the result of the OnlineLOF algorithm, where some insertions and
- * deletions (of the previously inserted objects) have been applied to the
- * database.
- *
- * @author Elke Achtert
- *
- */
-public class TestOnlineLOF implements JUnit4Test {
- // the following values depend on the data set used!
- static String dataset = "data/testdata/unittests/3clusters-and-noise-2d.csv";
-
- // parameter k for LOF and OnlineLOF
- static int k = 5;
-
- // neighborhood distance function for LOF and OnlineLOF
- @SuppressWarnings("rawtypes")
- static DistanceFunction neighborhoodDistanceFunction = EuclideanDistanceFunction.STATIC;
-
- // reachability distance function for LOF and OnlineLOF
- @SuppressWarnings("rawtypes")
- static DistanceFunction reachabilityDistanceFunction = CosineDistanceFunction.STATIC;
-
- // seed for the generator
- static int seed = 5;
-
- // size of the data set
- static int size = 50;
-
- /**
- * First, run the {@link LOF} algorithm on the database. Second, run the
- * {@link OnlineLOF} algorithm on the database, insert new objects and
- * afterwards delete them. Then, compare the two results for equality.
- *
- * @throws UnableToComplyException
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testOnlineLOF() throws UnableToComplyException {
- UpdatableDatabase db = getDatabase();
-
- // 1. Run LOF
- FlexibleLOF<DoubleVector, DoubleDistance> lof = new FlexibleLOF<>(k, k, neighborhoodDistanceFunction, reachabilityDistanceFunction);
- OutlierResult result1 = lof.run(db);
-
- // 2. Run OnlineLOF (with insertions and removals) on database
- OutlierResult result2 = runOnlineLOF(db);
-
- // 3. Compare results
- Relation<Double> scores1 = result1.getScores();
- Relation<Double> scores2 = result2.getScores();
-
- for(DBIDIter id = scores1.getDBIDs().iter(); id.valid(); id.advance()) {
- Double lof1 = scores1.get(id);
- Double lof2 = scores2.get(id);
- assertTrue("lof(" + DBIDUtil.toString(id) + ") != lof(" + DBIDUtil.toString(id) + "): " + lof1 + " != " + lof2, lof1.equals(lof2));
- }
- }
-
- /**
- * Run OnlineLOF (with insertions and removals) on database.
- */
- @SuppressWarnings("unchecked")
- private static OutlierResult runOnlineLOF(UpdatableDatabase db) throws UnableToComplyException {
- Relation<DoubleVector> rep = db.getRelation(TypeUtil.DOUBLE_VECTOR_FIELD);
-
- // setup algorithm
- OnlineLOF<DoubleVector, DoubleDistance> lof = new OnlineLOF<>(k, k, neighborhoodDistanceFunction, reachabilityDistanceFunction);
-
- // run OnlineLOF on database
- OutlierResult result = lof.run(db);
-
- // insert new objects
- ArrayList<DoubleVector> insertions = new ArrayList<>();
- NumberVector.Factory<DoubleVector, ?> o = RelationUtil.getNumberVectorFactory(rep);
- int dim = RelationUtil.dimensionality(rep);
- Random random = new Random(seed);
- for(int i = 0; i < size; i++) {
- DoubleVector obj = VectorUtil.randomVector(o, dim, random);
- insertions.add(obj);
- }
- DBIDs deletions = db.insert(MultipleObjectsBundle.makeSimple(rep.getDataTypeInformation(), insertions));
-
- // delete objects
- db.delete(deletions);
-
- return result;
- }
-
- /**
- * Returns the database.
- */
- private static UpdatableDatabase getDatabase() {
- ListParameterization params = new ListParameterization();
- params.addParameter(FileBasedDatabaseConnection.Parameterizer.INPUT_ID, dataset);
-
- UpdatableDatabase db = ClassGenericsUtil.parameterizeOrAbort(HashmapDatabase.class, params);
- params.failOnErrors();
- if(params.hasUnusedParameters()) {
- fail("Unused parameters: " + params.getRemainingParameters());
- }
-
- // get database
- db.initialize();
- return db;
- }
-
-}
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/TestFeatureBagging.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/TestFeatureBagging.java
deleted file mode 100644
index c3d9f7a0..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/TestFeatureBagging.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier.meta;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOF;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the Feature Bagging algorithm.
- *
- * @author Erich Schubert
- */
-public class TestFeatureBagging extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testFeatureBaggingSum() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-axis-subspaces-6d.ascii", 1345);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(LOF.Parameterizer.K_ID, 10);
- params.addParameter(FeatureBagging.Parameterizer.NUM_ID, 10);
- params.addParameter(FeatureBagging.Parameterizer.SEED_ID, 1);
-
- // setup Algorithm
- FeatureBagging fb = ClassGenericsUtil.parameterizeOrAbort(FeatureBagging.class, params);
- testParameterizationOk(params);
-
- // run AggarwalYuEvolutionary on database
- OutlierResult result = fb.run(db);
-
- testSingleScore(result, 1293, 11.8295414);
- testAUC(db, "Noise", result, 0.9066106);
- }
-
- @Test
- public void testFeatureBaggingBreadth() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-axis-subspaces-6d.ascii", 1345);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(LOF.Parameterizer.K_ID, 10);
- params.addParameter(FeatureBagging.Parameterizer.NUM_ID, 10);
- params.addParameter(FeatureBagging.Parameterizer.SEED_ID, 5);
- params.addFlag(FeatureBagging.Parameterizer.BREADTH_ID);
-
- // setup Algorithm
- FeatureBagging fb = ClassGenericsUtil.parameterizeOrAbort(FeatureBagging.class, params);
- testParameterizationOk(params);
-
- // run AggarwalYuEvolutionary on database
- OutlierResult result = fb.run(db);
-
- testSingleScore(result, 1293, 1.321709879);
- testAUC(db, "Noise", result, 0.884212);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/TestHiCS.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/TestHiCS.java
deleted file mode 100644
index e1ed1f37..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/meta/TestHiCS.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier.meta;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.algorithm.outlier.lof.LOF;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.math.statistics.tests.KolmogorovSmirnovTest;
-import de.lmu.ifi.dbs.elki.math.statistics.tests.WelchTTest;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the HiCS algorithm.
- *
- * @author Erich Schubert
- */
-public class TestHiCS extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testHiCSKS() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-axis-subspaces-6d.ascii", 1345);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(LOF.Parameterizer.K_ID, 10);
- params.addParameter(HiCS.Parameterizer.LIMIT_ID, 10);
- params.addParameter(HiCS.Parameterizer.SEED_ID, 0);
- params.addParameter(HiCS.Parameterizer.TEST_ID, KolmogorovSmirnovTest.STATIC);
-
- // setup Algorithm
- HiCS<DoubleVector> fb = ClassGenericsUtil.parameterizeOrAbort(HiCS.class, params);
- testParameterizationOk(params);
-
- // run HiCS on database
- OutlierResult result = fb.run(db);
-
- testAUC(db, "Noise", result, 0.85340056);
- testSingleScore(result, 1293, 4.935802);
- }
-
- @Test
- public void testHiCSWelch() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-axis-subspaces-6d.ascii", 1345);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(LOF.Parameterizer.K_ID, 10);
- params.addParameter(HiCS.Parameterizer.LIMIT_ID, 10);
- params.addParameter(HiCS.Parameterizer.SEED_ID, 0);
- params.addParameter(HiCS.Parameterizer.TEST_ID, WelchTTest.STATIC);
-
- // setup Algorithm
- HiCS<DoubleVector> fb = ClassGenericsUtil.parameterizeOrAbort(HiCS.class, params);
- testParameterizationOk(params);
-
- // run HiCS on database
- OutlierResult result = fb.run(db);
-
- testAUC(db, "Noise", result, 0.6255238);
- testSingleScore(result, 1293, 2.542272);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/TestSOD.java b/test/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/TestSOD.java
deleted file mode 100644
index f8f47886..00000000
--- a/test/de/lmu/ifi/dbs/elki/algorithm/outlier/subspace/TestSOD.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package de.lmu.ifi.dbs.elki.algorithm.outlier.subspace;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborPreprocessor;
-import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Tests the SOD algorithm.
- *
- * @author Lucia Cichella
- */
-public class TestSOD extends AbstractSimpleAlgorithmTest implements JUnit4Test {
- @Test
- public void testSOD() {
- Database db = makeSimpleDatabase(UNITTEST + "outlier-axis-subspaces-6d.ascii", 1345);
-
- // Parameterization
- ListParameterization params = new ListParameterization();
- params.addParameter(SOD.Parameterizer.KNN_ID, 25);
- params.addParameter(SharedNearestNeighborPreprocessor.Factory.NUMBER_OF_NEIGHBORS_ID, 19);
-
- // setup Algorithm
- SOD<DoubleVector, DoubleDistance> sod = ClassGenericsUtil.parameterizeOrAbort(SOD.class, params);
- testParameterizationOk(params);
-
- // run SOD on database
- OutlierResult result = sod.run(db);
-
- testSingleScore(result, 1293, 1.5167500);
- testAUC(db, "Noise", result, 0.949131652);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/data/spatial/TestPolygon.java b/test/de/lmu/ifi/dbs/elki/data/spatial/TestPolygon.java
deleted file mode 100644
index 9403946a..00000000
--- a/test/de/lmu/ifi/dbs/elki/data/spatial/TestPolygon.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package de.lmu.ifi.dbs.elki.data.spatial;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.*;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-
-public class TestPolygon implements JUnit4Test {
- @Test
- public void testPolygonContainment() {
- final Polygon p1, p2, p3;
- {
- List<Vector> v1 = new ArrayList<>();
- v1.add(new Vector(0, 0));
- v1.add(new Vector(.9, 0));
- v1.add(new Vector(0, .9));
- p1 = new Polygon(v1);
- }
- {
- List<Vector> v2 = new ArrayList<>();
- v2.add(new Vector(1, 1));
- v2.add(new Vector(1, .1));
- v2.add(new Vector(.1, 1));
- p2 = new Polygon(v2);
- }
- {
- List<Vector> v3 = new ArrayList<>();
- v3.add(new Vector(.1, .1));
- v3.add(new Vector(.1, .9));
- v3.add(new Vector(.9, .9));
- v3.add(new Vector(.9, .1));
- p3 = new Polygon(v3);
- }
- Vector pou = new Vector(-1, -1);
- Vector p22 = new Vector(.2, .2);
- assertFalse("P2 not in p1", p1.containsPoint2D(pou));
- assertFalse("P2 not in p2", p2.containsPoint2D(pou));
- assertFalse("P2 not in p3", p3.containsPoint2D(pou));
- assertTrue("P2 not in p1", p1.containsPoint2D(p22));
- assertFalse("P2 in p2", p2.containsPoint2D(p22));
- assertTrue("P2 not in p3", p3.containsPoint2D(p22));
- assertFalse("Polygons p1 and p2 must not intersect.", p1.intersects2DIncomplete(p2));
- assertTrue("Polygons p1 and p3 must intersect.", p1.intersects2DIncomplete(p3));
- assertTrue("Polygons p2 and p3 must intersect.", p2.intersects2DIncomplete(p3));
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/database/TestRelationSorting.java b/test/de/lmu/ifi/dbs/elki/database/TestRelationSorting.java
deleted file mode 100644
index 2b77f2f5..00000000
--- a/test/de/lmu/ifi/dbs/elki/database/TestRelationSorting.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package de.lmu.ifi.dbs.elki.database;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.VectorUtil;
-import de.lmu.ifi.dbs.elki.data.VectorUtil.SortDBIDsBySingleDimension;
-import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
-import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
-import de.lmu.ifi.dbs.elki.datasource.FileBasedDatabaseConnection;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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/>.
- */
-
-/**
- * Unit test that loads a data file and sorts it. This tests some key parts of
- * the database and ID layers.
- *
- * @author Erich Schubert
- *
- */
-public class TestRelationSorting implements JUnit4Test {
- public static final String filename = "data/testdata/unittests/hierarchical-3d2d1d.csv";
-
- @Test
- public void testSorting() {
- ListParameterization params = new ListParameterization();
- params.addParameter(FileBasedDatabaseConnection.Parameterizer.INPUT_ID, filename);
- Database db = ClassGenericsUtil.parameterizeOrAbort(StaticArrayDatabase.class, params);
- if (params.hasUnusedParameters()) {
- fail("Unused parameters: " + params.getRemainingParameters());
- }
- if (params.hasErrors()) {
- params.logAndClearReportedErrors();
- fail("Parameterization errors.");
- }
- db.initialize();
- Relation<? extends NumberVector<?>> rel = db.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
-
- ArrayModifiableDBIDs ids = DBIDUtil.newArray(rel.getDBIDs());
- final int size = rel.size();
-
- int dims = RelationUtil.dimensionality(rel);
- SortDBIDsBySingleDimension sorter = new VectorUtil.SortDBIDsBySingleDimension(rel);
-
- for (int d = 0; d < dims; d++) {
- sorter.setDimension(d);
- ids.sort(sorter);
- assertEquals("Lost some DBID during sorting?!?", size, DBIDUtil.newHashSet(ids).size());
-
- DBIDArrayIter it = ids.iter();
- double prev = rel.get(it).doubleValue(d);
- for (it.advance(); it.valid(); it.advance()) {
- double next = rel.get(it).doubleValue(d);
- assertTrue("Not correctly sorted: " + prev + " > " + next + " at pos " + it.getOffset(), prev <= next);
- prev = next;
- }
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/datasource/parser/TestTermFrequencyParser.java b/test/de/lmu/ifi/dbs/elki/datasource/parser/TestTermFrequencyParser.java
deleted file mode 100644
index 2bf288f7..00000000
--- a/test/de/lmu/ifi/dbs/elki/datasource/parser/TestTermFrequencyParser.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package de.lmu.ifi.dbs.elki.datasource.parser;
-
-/*
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.data.SparseNumberVector;
-import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.StaticArrayDatabase;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.datasource.AbstractDatabaseConnection;
-import de.lmu.ifi.dbs.elki.datasource.FileBasedDatabaseConnection;
-import de.lmu.ifi.dbs.elki.datasource.filter.SparseVectorFieldFilter;
-import de.lmu.ifi.dbs.elki.datasource.filter.normalization.TFIDFNormalization;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.ArcCosineDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SparseEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Unit test the term frequency parser by loading an example data set derived
- * from DBLP.
- *
- * TODO: maybe also run an example algorithm?
- *
- * @author Erich Schubert
- */
-public class TestTermFrequencyParser implements JUnit4Test {
- /** Test data set to use. */
- public static String DBLP_DATA = "data/testdata/parsing/termfreq-dblp.ascii.gz";
-
- @Test
- public void testDBLPData() {
- ListParameterization config = new ListParameterization();
- config.addParameter(AbstractDatabaseConnection.Parameterizer.PARSER_ID, TermFrequencyParser.class);
- config.addParameter(FileBasedDatabaseConnection.Parameterizer.INPUT_ID, DBLP_DATA);
-
- ArrayList<Object> filters = new ArrayList<>();
- filters.add(TFIDFNormalization.class);
- // Note: this filter is needed for the non-sparse Euclidean distance below.
- filters.add(SparseVectorFieldFilter.class);
- config.addParameter(AbstractDatabaseConnection.Parameterizer.FILTERS_ID, filters);
-
- Database db = ClassGenericsUtil.parameterizeOrAbort(StaticArrayDatabase.class, config);
-
- if (config.hasUnusedParameters()) {
- fail("Unused parameters: " + config.getRemainingParameters());
- }
- if (config.hasErrors()) {
- config.logAndClearReportedErrors();
- fail("Parameterization errors.");
- }
-
- db.initialize();
-
- Relation<SparseNumberVector<?>> rel = db.getRelation(TypeUtil.SPARSE_VECTOR_FIELD);
-
- // Get first three objects:
- DBIDIter iter = rel.iterDBIDs();
- SparseNumberVector<?> v1 = rel.get(iter);
- iter.advance();
- SparseNumberVector<?> v2 = rel.get(iter);
- iter.advance();
- SparseNumberVector<?> v3 = rel.get(iter);
-
- // "Dense" euclidean distance:
- double euclid1_12 = EuclideanDistanceFunction.STATIC.doubleDistance(v1, v2);
- double euclid1_13 = EuclideanDistanceFunction.STATIC.doubleDistance(v1, v3);
- double euclid1_23 = EuclideanDistanceFunction.STATIC.doubleDistance(v2, v3);
- double euclid1_21 = EuclideanDistanceFunction.STATIC.doubleDistance(v2, v1);
- // Sparse euclidean distance:
- double euclid2_12 = SparseEuclideanDistanceFunction.STATIC.doubleDistance(v1, v2);
- double euclid2_13 = SparseEuclideanDistanceFunction.STATIC.doubleDistance(v1, v3);
- double euclid2_23 = SparseEuclideanDistanceFunction.STATIC.doubleDistance(v2, v3);
- double euclid2_21 = SparseEuclideanDistanceFunction.STATIC.doubleDistance(v2, v1);
- // (Auto-switching) angular distance:
- double arccos_12 = ArcCosineDistanceFunction.STATIC.doubleDistance(v1, v2);
- double arccos_13 = ArcCosineDistanceFunction.STATIC.doubleDistance(v1, v3);
- double arccos_23 = ArcCosineDistanceFunction.STATIC.doubleDistance(v2, v3);
- double arccos_21 = ArcCosineDistanceFunction.STATIC.doubleDistance(v2, v1);
-
- assertEquals("Euclidean self-distance is not 0.", 0., EuclideanDistanceFunction.STATIC.doubleDistance(v1, v1), Double.MIN_VALUE);
- assertEquals("Sparse Euclidean self-distance is not 0.", 0., SparseEuclideanDistanceFunction.STATIC.doubleDistance(v1, v1), Double.MIN_VALUE);
- assertEquals("Arccos self-distance is not 0.", 0., ArcCosineDistanceFunction.STATIC.doubleDistance(v1, v1), Double.MIN_VALUE);
- assertEquals("Euclidean distance not symmetric.", euclid1_12, euclid1_21, Double.MIN_VALUE);
- assertEquals("Sparse Euclidean distance not symmetric.", euclid2_12, euclid2_21, Double.MIN_VALUE);
- assertEquals("Arccos distance not symmetric.", arccos_12, arccos_21, Double.MIN_VALUE);
-
- assertEquals("Euclidean distance 1-2 not as expected.", 684.4165398352088, euclid1_12, 1e-20);
- assertEquals("Sparse Euclidean distance 1-2 not as expected.", 684.4165398352088, euclid2_12, 1e-20);
- assertEquals("Arccos distance 1-2 not as expected.", 0.1901934493141418, arccos_12, 1e-20);
- assertEquals("Euclidean distance 1-3 not as expected.", 654.9862593978594, euclid1_13, 1e-20);
- assertEquals("Sparse Euclidean distance 1-3 not as expected.", 654.9862593978594, euclid2_13, 1e-20);
- assertEquals("Arccos distance 1-3 not as expected.", 0.18654347641726107, arccos_13, 1e-20);
- assertEquals("Euclidean distance 2-3 not as expected.", 231.78653972998518, euclid1_23, 1e-20);
- assertEquals("Sparse Euclidean distance 2-3 not as expected.", 231.78653972998518, euclid2_23, 1e-20);
- assertEquals("Arccos distance 2-3 not as expected.", 0.11138352337990769, arccos_23, 1e-20);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/datasource/parser/TestTokenizer.java b/test/de/lmu/ifi/dbs/elki/datasource/parser/TestTokenizer.java
deleted file mode 100644
index 34ccdc04..00000000
--- a/test/de/lmu/ifi/dbs/elki/datasource/parser/TestTokenizer.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package de.lmu.ifi.dbs.elki.datasource.parser;
-
-/*
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.regex.Pattern;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Simple unit test for testing the new tokenizer
- *
- * TODO: add more test cases, refactor into input, expected-output pattern.
- *
- * @author Erich Schubert
- */
-public class TestTokenizer implements JUnit4Test {
- Tokenizer t = new Tokenizer(Pattern.compile("\\s"), "\"'");
-
- @Test
- public void testSimple() {
- final String input = "1 -234 3.1415 - banana";
- final Object[] expect = { 1L, -234L, 3.1415, "-", "banana" };
- t.initialize(input, 0, input.length());
- tokenizerTest(expect);
- }
-
- @Test
- public void testQuotes() {
- final String input = "'this is' \"a test\" '123' '123 456' \"bana' na\"";
- final Object[] expect = { "this is", "a test", 123L, "123 456", "bana' na" };
- t.initialize(input, 0, input.length());
- tokenizerTest(expect);
- }
-
- @Test
- public void testSpecials() {
- final String input = "nan inf -∞ NaN infinity NA";
- final Object[] expect = { Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NaN, Double.POSITIVE_INFINITY, Double.NaN };
- t.initialize(input, 0, input.length());
- tokenizerTest(expect);
- }
-
- @Test
- public void testEmpty() {
- final String input = "";
- final Object[] expect = {};
- t.initialize(input, 0, input.length());
- tokenizerTest(expect);
- }
-
- @Test
- public void testLineEnd() {
- final String input = "1 ";
- final Object[] expect = { 1L };
- t.initialize(input, 0, input.length());
- tokenizerTest(expect);
- }
-
- @Test
- public void testPartial() {
- final String input = "abc1def";
- final Object[] expect = { 1L };
- t.initialize(input, 3, 4);
- tokenizerTest(expect);
- }
-
- private void tokenizerTest(Object[] expect) {
- for(int i = 0; i < expect.length; i++, t.advance()) {
- assertTrue("Tokenizer stopped early.", t.valid());
- Object e = expect[i];
- // Negative tests first:
- if(e instanceof String || e instanceof Double) {
- try {
- long val = t.getLongBase10();
- fail("The value " + t.getSubstring() + " was expected to be not parseable as long integer, but returned: " + val);
- }
- catch(Exception ex) {
- // pass. this is expected to fail.
- }
- }
- if(e instanceof String) {
- try {
- double val = t.getDouble();
- fail("The value " + t.getSubstring() + " was expected to be not parseable as double, but returned: " + val);
- }
- catch(Exception ex) {
- // pass. this is expected to fail.
- }
- }
- // Positive tests:
- if(e instanceof Long) {
- assertEquals("Long parsing failed.", (long) e, t.getLongBase10());
- }
- if(e instanceof Double) {
- // Note: this also works for NaNs, they are treated special.
- assertEquals("Double parsing failed.", (double) e, t.getDouble(), Double.MIN_VALUE);
- }
- if(e instanceof String) {
- assertEquals("String parsing failed.", (String) e, t.getSubstring());
- }
- }
- if(t.valid()) {
- assertTrue("Spurous data after expected end: " + t.getSubstring(), !t.valid());
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDistanceFunctionTest.java b/test/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDistanceFunctionTest.java
deleted file mode 100644
index 81512abd..00000000
--- a/test/de/lmu/ifi/dbs/elki/distance/distancefunction/SpatialPrimitiveDistanceFunctionTest.java
+++ /dev/null
@@ -1,154 +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) 2012
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox;
-import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.colorhistogram.HistogramIntersectionDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.ManhattanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.MaximumDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.MinimumDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-
-/**
- * Validate spatial distance functions by ensuring that mindist <= distance for
- * random objects.
- *
- * @author Erich Schubert
- *
- */
-public class SpatialPrimitiveDistanceFunctionTest implements JUnit4Test {
- @Test
- public void testSpatialDistanceConsistency() {
- final Random rnd = new Random(0);
- final int dim = 7;
- final int iters = 10000;
-
- List<SpatialPrimitiveDistanceFunction<? super NumberVector<?>, ?>> dists = new ArrayList<>();
- dists.add(EuclideanDistanceFunction.STATIC);
- dists.add(ManhattanDistanceFunction.STATIC);
- dists.add(MaximumDistanceFunction.STATIC);
- dists.add(MinimumDistanceFunction.STATIC);
- dists.add(new LPNormDistanceFunction(3));
- dists.add(new LPNormDistanceFunction(.5));
- dists.add(CanberraDistanceFunction.STATIC);
- // Histogram intersection distance isn't proper for negative values
- // dists.add(HistogramIntersectionDistanceFunction.STATIC);
- dists.add(SquaredEuclideanDistanceFunction.STATIC);
- dists.add(ArcCosineDistanceFunction.STATIC);
- dists.add(CosineDistanceFunction.STATIC);
-
- double[] d1 = new double[dim];
- double[] d2 = new double[dim];
- double[] d3 = new double[dim];
- double[] d4 = new double[dim];
- Vector v1 = new Vector(d1);
- ModifiableHyperBoundingBox mbr = new ModifiableHyperBoundingBox(d2, d3);
- Vector v2 = new Vector(d4);
- for(int i = 0; i < iters; i++) {
- for(int d = 0; d < dim; d++) {
- d1[d] = (rnd.nextDouble() - .5) * 2E4;
- d2[d] = (rnd.nextDouble() - .5) * 2E4;
- d3[d] = (rnd.nextDouble() - .5) * 2E4;
- if(d2[d] > d3[d]) {
- double t = d2[d];
- d2[d] = d3[d];
- d3[d] = t;
- }
- double m = rnd.nextDouble();
- d4[d] = m * d2[d] + (1 - m) * d3[d];
- }
- for(SpatialPrimitiveDistanceFunction<? super NumberVector<?>, ?> dis : dists) {
- compareDistances(v1, mbr, v2, dis);
- }
- }
- }
-
- @Test
- public void testSpatialDistanceConsistencyPositive() {
- final Random rnd = new Random(1);
- final int dim = 7;
- final int iters = 10000;
-
- List<SpatialPrimitiveDistanceFunction<? super NumberVector<?>, ?>> dists = new ArrayList<>();
- dists.add(EuclideanDistanceFunction.STATIC);
- dists.add(ManhattanDistanceFunction.STATIC);
- dists.add(MaximumDistanceFunction.STATIC);
- dists.add(MinimumDistanceFunction.STATIC);
- dists.add(new LPNormDistanceFunction(3));
- dists.add(new LPNormDistanceFunction(.5));
- dists.add(CanberraDistanceFunction.STATIC);
- dists.add(HistogramIntersectionDistanceFunction.STATIC);
- dists.add(SquaredEuclideanDistanceFunction.STATIC);
- dists.add(ArcCosineDistanceFunction.STATIC);
- dists.add(CosineDistanceFunction.STATIC);
-
- double[] d1 = new double[dim];
- double[] d2 = new double[dim];
- double[] d3 = new double[dim];
- double[] d4 = new double[dim];
- Vector v1 = new Vector(d1);
- ModifiableHyperBoundingBox mbr = new ModifiableHyperBoundingBox(d2, d3);
- Vector v2 = new Vector(d4);
- for(int i = 0; i < iters; i++) {
- for(int d = 0; d < dim; d++) {
- d1[d] = rnd.nextDouble() * 2E4;
- d2[d] = rnd.nextDouble() * 2E4;
- d3[d] = rnd.nextDouble() * 2E4;
- if(d2[d] > d3[d]) {
- double t = d2[d];
- d2[d] = d3[d];
- d3[d] = t;
- }
- double m = rnd.nextDouble();
- d4[d] = m * d2[d] + (1 - m) * d3[d];
- }
- for(SpatialPrimitiveDistanceFunction<? super NumberVector<?>, ?> dis : dists) {
- compareDistances(v1, mbr, v2, dis);
- }
- }
- }
-
- protected <D extends Distance<D>> void compareDistances(Vector v1, ModifiableHyperBoundingBox mbr, Vector v2, SpatialPrimitiveDistanceFunction<? super NumberVector<?>, D> dist) {
- D exact = dist.distance(v1, v2);
- D mind = dist.minDist(v1, v2);
- D mbrd = dist.minDist(v1, mbr);
- assertEquals("Not same: " + dist.toString(), exact, mind);
- assertTrue("Not smaller:" + dist.toString() + " " + mbrd + " > " + exact + " " + mbr + " " + v1, mbrd.compareTo(exact) <= 0);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/LevenshteinDistanceFunctionTest.java b/test/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/LevenshteinDistanceFunctionTest.java
deleted file mode 100644
index 7aa8208a..00000000
--- a/test/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/LevenshteinDistanceFunctionTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-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
- 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 static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for Levenshtein distance.
- *
- * @author Erich Schubert
- */
-public class LevenshteinDistanceFunctionTest implements JUnit4Test {
- /**
- * Some test strings, from the Wikipedia article.
- */
- final String[][] TESTS = { //
- { "kitten", "sitting" }, //
- { "Saturday", "Sunday" }, //
- { "tier", "tor" }, //
- { "abcz", "zabc" }, //
- { "zabc", "abcz" }, //
- };
-
- /**
- * The associated scores.
- */
- final int[] SCORES = { //
- 3, // kitten <-> sitting
- 3, // Saturday <-> Sunday
- 2, // Tier <-> Tor
- 2, // abcz <-> zabc
- 2, // zabc <-> abcz
- };
-
- @Test
- public void testStringLevenshtein() {
- LevenshteinDistanceFunction f = LevenshteinDistanceFunction.STATIC_SENSITIVE;
- for (int i = 0; i < TESTS.length; i++) {
- assertEquals("Distance does not agree: " + TESTS[i][0] + " <-> " + TESTS[i][1], SCORES[i], f.distance(TESTS[i][0], TESTS[i][1]).intValue());
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/NormalizedLevenshteinDistanceFunctionTest.java b/test/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/NormalizedLevenshteinDistanceFunctionTest.java
deleted file mode 100644
index 57260e76..00000000
--- a/test/de/lmu/ifi/dbs/elki/distance/distancefunction/strings/NormalizedLevenshteinDistanceFunctionTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-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
- 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 static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for Levenshtein distance.
- *
- * @author Erich Schubert
- */
-public class NormalizedLevenshteinDistanceFunctionTest implements JUnit4Test {
- /**
- * Some test strings, from the Wikipedia article.
- */
- final String[][] TESTS = { //
- { "kitten", "sitting" }, //
- { "Saturday", "Sunday" }, //
- { "tier", "tor" }, //
- { "abcz", "zabc" }, //
- { "zabc", "abcz" }, //
- };
-
- /**
- * The associated scores.
- */
- final double[] SCORES = { //
- 3. / 6.5, // kitten <-> sitting
- 3. / 7., // Saturday <-> Sunday
- 2. / 3.5, // tier <-> tor
- 2. / 4., // abcz <-> zabc
- 2. / 4., // zabc <-> abcz
- };
-
- @Test
- public void testStringLevenshtein() {
- NormalizedLevenshteinDistanceFunction f = NormalizedLevenshteinDistanceFunction.STATIC_SENSITIVE;
- for (int i = 0; i < TESTS.length; i++) {
- assertEquals("Distance does not agree: " + TESTS[i][0] + " <-> " + TESTS[i][1], SCORES[i], f.distance(TESTS[i][0], TESTS[i][1]).doubleValue(), 1E-10);
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/evaluation/paircounting/TestClusterContingencyTable.java b/test/de/lmu/ifi/dbs/elki/evaluation/paircounting/TestClusterContingencyTable.java
deleted file mode 100644
index bc83e534..00000000
--- a/test/de/lmu/ifi/dbs/elki/evaluation/paircounting/TestClusterContingencyTable.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package de.lmu.ifi.dbs.elki.evaluation.paircounting;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.trivial.ByLabelClustering;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.trivial.TrivialAllInOne;
-import de.lmu.ifi.dbs.elki.algorithm.clustering.trivial.TrivialAllNoise;
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.model.Model;
-import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.StaticArrayDatabase;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.datasource.FileBasedDatabaseConnection;
-import de.lmu.ifi.dbs.elki.evaluation.clustering.ClusterContingencyTable;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Validate {@link ClusterContingencyTable} with respect to its ability to compare
- * data clusterings.
- *
- * @author Erich Schubert
- */
-public class TestClusterContingencyTable implements JUnit4Test {
- // the following values depend on the data set used!
- String dataset = "data/testdata/unittests/hierarchical-3d2d1d.csv";
-
- // size of the data set
- int shoulds = 600;
-
- /**
- * Validate {@link ClusterContingencyTable} with respect to its ability to
- * compare data clusterings.
- *
- * @throws ParameterException on errors.
- */
- @Test
- public void testCompareDatabases() {
- ListParameterization params = new ListParameterization();
- // Input
- params.addParameter(FileBasedDatabaseConnection.Parameterizer.INPUT_ID, dataset);
-
- // get database
- Database db = ClassGenericsUtil.parameterizeOrAbort(StaticArrayDatabase.class, params);
- db.initialize();
-
- // verify data set size.
- Relation<?> rel = db.getRelation(TypeUtil.ANY);
- assertTrue(rel.size() == shoulds);
-
- // run all-in-one
- TrivialAllInOne allinone = new TrivialAllInOne();
- Clustering<Model> rai = allinone.run(db);
-
- // run all-in-noise
- TrivialAllNoise allinnoise = new TrivialAllNoise();
- Clustering<Model> ran = allinnoise.run(db);
-
- // run by-label
- ByLabelClustering bylabel = new ByLabelClustering();
- Clustering<?> rbl = bylabel.run(db);
-
- assertEquals(1.0, computeFMeasure(rai, rai, false), Double.MIN_VALUE);
- assertEquals(1.0, computeFMeasure(ran, ran, false), Double.MIN_VALUE);
- assertEquals(1.0, computeFMeasure(rbl, rbl, false), Double.MIN_VALUE);
-
- assertEquals(0.009950248756218905, computeFMeasure(ran, rbl, true), Double.MIN_VALUE);
- assertEquals(0.0033277870216306157, computeFMeasure(rai, ran, true), Double.MIN_VALUE);
-
- assertEquals(0.5 /* 0.3834296724470135 */, computeFMeasure(rai, rbl, false), Double.MIN_VALUE);
- }
-
- private double computeFMeasure(Clustering<?> c1, Clustering<?> c2, boolean noise) {
- ClusterContingencyTable ct = new ClusterContingencyTable(true, noise);
- ct.process(c1, c2);
- return ct.getPaircount().f1Measure();
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/evaluation/roc/TestComputeROC.java b/test/de/lmu/ifi/dbs/elki/evaluation/roc/TestComputeROC.java
deleted file mode 100644
index 1988f060..00000000
--- a/test/de/lmu/ifi/dbs/elki/evaluation/roc/TestComputeROC.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package de.lmu.ifi.dbs.elki.evaluation.roc;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 junit.framework.Assert;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPairList;
-import de.lmu.ifi.dbs.elki.math.geometry.XYCurve;
-
-/**
- * Test to validate ROC curve computation.
- *
- * @author Erich Schubert
- */
-public class TestComputeROC implements JUnit4Test {
- /**
- * Test ROC curve generation, including curve simplification
- */
- @Test
- public void testROCCurve() {
- HashSetModifiableDBIDs positive = DBIDUtil.newHashSet();
- positive.add(DBIDUtil.importInteger(1));
- positive.add(DBIDUtil.importInteger(2));
- positive.add(DBIDUtil.importInteger(3));
- positive.add(DBIDUtil.importInteger(4));
- positive.add(DBIDUtil.importInteger(5));
-
- final DoubleDistanceDBIDPairList distances = new DoubleDistanceDBIDPairList();
- // Starting point: ................................ 0.0,0. ++
- distances.add(0.0, DBIDUtil.importInteger(1)); // + 0.0,.2 -- redundant
- distances.add(1.0, DBIDUtil.importInteger(2)); // + 0.0,.4 ++
- distances.add(2.0, DBIDUtil.importInteger(6)); // - .25,.4 ++
- distances.add(3.0, DBIDUtil.importInteger(7)); // -
- distances.add(3.0, DBIDUtil.importInteger(3)); // + .50,.6 -- redundant
- distances.add(4.0, DBIDUtil.importInteger(8)); // -
- distances.add(4.0, DBIDUtil.importInteger(4)); // + .75,.8 ++
- distances.add(5.0, DBIDUtil.importInteger(9)); // - 1.0,.8 ++
- distances.add(6.0, DBIDUtil.importInteger(5)); // + 1.0,1. ++
-
- XYCurve roccurve = ROC.materializeROC(new ROC.DBIDsTest(positive), new ROC.DistanceResultAdapter<>(distances.iter()));
- // System.err.println(roccurve);
- Assert.assertEquals("ROC curve too complex", 6, roccurve.size());
-
- double auc = XYCurve.areaUnderCurve(roccurve);
- Assert.assertEquals("ROC AUC not right.", 0.6, auc, 0.0001);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/index/TestIndexStructures.java b/test/de/lmu/ifi/dbs/elki/index/TestIndexStructures.java
deleted file mode 100644
index b412e409..00000000
--- a/test/de/lmu/ifi/dbs/elki/index/TestIndexStructures.java
+++ /dev/null
@@ -1,233 +0,0 @@
-package de.lmu.ifi.dbs.elki.index;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.StaticArrayDatabase;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
-import de.lmu.ifi.dbs.elki.database.query.knn.DoubleOptimizedDistanceKNNQuery;
-import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
-import de.lmu.ifi.dbs.elki.database.query.range.DoubleOptimizedDistanceRangeQuery;
-import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.datasource.FileBasedDatabaseConnection;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mtree.MTree;
-import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mtree.MTreeFactory;
-import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.DoubleDistanceMetricalIndexKNNQuery;
-import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.DoubleDistanceMetricalIndexRangeQuery;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeFactory;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query.DoubleDistanceRStarTreeKNNQuery;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query.DoubleDistanceRStarTreeRangeQuery;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTree;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTreeFactory;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert.ApproximativeLeastOverlapInsertionStrategy;
-import de.lmu.ifi.dbs.elki.index.vafile.PartialVAFile;
-import de.lmu.ifi.dbs.elki.index.vafile.VAFile;
-import de.lmu.ifi.dbs.elki.persistent.AbstractPageFileFactory;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Test case to validate some index structures for accuracy. For a known data
- * set and query point, the top 10 nearest neighbors are queried and verified.
- *
- * Note that the internal operation of the index structure is not tested this
- * way, only whether the database object with the index still returns reasonable
- * results.
- *
- * @author Erich Schubert
- */
-public class TestIndexStructures implements JUnit4Test {
- // the following values depend on the data set used!
- String dataset = "data/testdata/unittests/hierarchical-3d2d1d.csv";
-
- // size of the data set
- int shoulds = 600;
-
- // query point
- double[] querypoint = new double[] { 0.5, 0.5, 0.5 };
-
- // number of kNN to query
- int k = 10;
-
- // the 10 next neighbors of the query point
- double[][] shouldc = new double[][] { { 0.45000428746088883, 0.484504234161508, 0.5538595167151342 }, { 0.4111050036231091, 0.429204794352013, 0.4689430202460606 }, { 0.4758477631164003, 0.6021538103067177, 0.5556807408692025 }, { 0.4163288957164025, 0.49604545242979536, 0.4054361013566713 }, { 0.5819940640461848, 0.48586944418231115, 0.6289592025558619 }, { 0.4373568207802466, 0.3468650110814596, 0.49566951629699485 }, { 0.40283109564192643, 0.6301433694690401, 0.44313571161129883 }, { 0.6545840114867083, 0.4919617658889418, 0.5905461546078652 }, { 0.6011097673869055, 0.6562921241634017, 0.44830647520493694 }, { 0.5127485678175534, 0.29708449200895504, 0.561722374659424 }, };
-
- // and their distances
- double[] shouldd = new double[] { 0.07510351238126374, 0.11780839322826206, 0.11882371989803064, 0.1263282354232315, 0.15347043712184602, 0.1655090505771259, 0.17208323533934652, 0.17933052146586306, 0.19319066655063877, 0.21247795391113142 };
-
- DoubleDistance eps = new DoubleDistance(0.21247795391113142);
-
- /**
- * Test exact query, also to validate the test is correct.
- */
- @Test
- public void testExact() {
- ListParameterization params = new ListParameterization();
- testFileBasedDatabaseConnection(params, DoubleOptimizedDistanceKNNQuery.class, DoubleOptimizedDistanceRangeQuery.class);
- }
-
- /**
- * Test {@link MTree} using a file based database connection.
- */
- @Test
- public void testMetrical() {
- ListParameterization metparams = new ListParameterization();
- metparams.addParameter(StaticArrayDatabase.Parameterizer.INDEX_ID, MTreeFactory.class);
- metparams.addParameter(AbstractPageFileFactory.Parameterizer.PAGE_SIZE_ID, 300);
- testFileBasedDatabaseConnection(metparams, DoubleDistanceMetricalIndexKNNQuery.class, DoubleDistanceMetricalIndexRangeQuery.class);
- }
-
- /**
- * Test {@link RStarTree} using a file based database connection.
- */
- @Test
- public void testRStarTree() {
- ListParameterization spatparams = new ListParameterization();
- spatparams.addParameter(StaticArrayDatabase.Parameterizer.INDEX_ID, RStarTreeFactory.class);
- spatparams.addParameter(AbstractPageFileFactory.Parameterizer.PAGE_SIZE_ID, 300);
- testFileBasedDatabaseConnection(spatparams, DoubleDistanceRStarTreeKNNQuery.class, DoubleDistanceRStarTreeRangeQuery.class);
- }
-
- /**
- * Test {@link VAFile} using a file based database connection.
- */
- @Test
- public void testVAFile() {
- ListParameterization spatparams = new ListParameterization();
- spatparams.addParameter(StaticArrayDatabase.Parameterizer.INDEX_ID, VAFile.Factory.class);
- spatparams.addParameter(VAFile.Factory.PARTITIONS_ID, 4);
- testFileBasedDatabaseConnection(spatparams, VAFile.VAFileKNNQuery.class, VAFile.VAFileRangeQuery.class);
- }
-
- /**
- * Test {@link PartialVAFile} using a file based database connection.
- */
- @Test
- public void testPartialVAFile() {
- ListParameterization spatparams = new ListParameterization();
- spatparams.addParameter(StaticArrayDatabase.Parameterizer.INDEX_ID, PartialVAFile.Factory.class);
- spatparams.addParameter(PartialVAFile.Factory.PARTITIONS_ID, 4);
- testFileBasedDatabaseConnection(spatparams, PartialVAFile.PartialVAFileKNNQuery.class, PartialVAFile.PartialVAFileRangeQuery.class);
- }
-
- /**
- * Test {@link RStarTree} using a file based database connection. With "fast"
- * mode enabled on an extreme level (since this should only reduce
- * performance, not correctness!)
- */
- @Test
- public void testRStarTreeFast() {
- ListParameterization spatparams = new ListParameterization();
- spatparams.addParameter(StaticArrayDatabase.Parameterizer.INDEX_ID, RStarTreeFactory.class);
- spatparams.addParameter(AbstractRStarTreeFactory.Parameterizer.INSERTION_STRATEGY_ID, ApproximativeLeastOverlapInsertionStrategy.class);
- spatparams.addParameter(ApproximativeLeastOverlapInsertionStrategy.Parameterizer.INSERTION_CANDIDATES_ID, 1);
- spatparams.addParameter(AbstractPageFileFactory.Parameterizer.PAGE_SIZE_ID, 300);
- testFileBasedDatabaseConnection(spatparams, DoubleDistanceRStarTreeKNNQuery.class, DoubleDistanceRStarTreeRangeQuery.class);
- }
-
- /**
- * Test {@link XTree} using a file based database connection.
- */
- // @Test
- // public void testXTree() {
- // ListParameterization xtreeparams = new ListParameterization();
- // xtreeparams.addParameter(StaticArrayDatabase.INDEX_ID,
- // experimentalcode.shared.index.xtree.XTreeFactory.class);
- // xtreeparams.addParameter(TreeIndexFactory.PAGE_SIZE_ID, 300);
- // testFileBasedDatabaseConnection(xtreeparams,
- // DoubleDistanceRStarTreeKNNQuery.class,
- // DoubleDistanceRStarTreeRangeQuery.class);
- // }
-
- /**
- * Actual test routine.
- *
- * @param inputparams
- */
- void testFileBasedDatabaseConnection(ListParameterization inputparams, Class<?> expectKNNQuery, Class<?> expectRangeQuery) {
- inputparams.addParameter(FileBasedDatabaseConnection.Parameterizer.INPUT_ID, dataset);
-
- // get database
- Database db = ClassGenericsUtil.parameterizeOrAbort(StaticArrayDatabase.class, inputparams);
- db.initialize();
- Relation<DoubleVector> rep = db.getRelation(TypeUtil.DOUBLE_VECTOR_FIELD);
- DistanceQuery<DoubleVector, DoubleDistance> dist = db.getDistanceQuery(rep, EuclideanDistanceFunction.STATIC);
-
- // verify data set size.
- assertTrue(rep.size() == shoulds);
-
- {
- // get the 10 next neighbors
- DoubleVector dv = new DoubleVector(querypoint);
- KNNQuery<DoubleVector, DoubleDistance> knnq = db.getKNNQuery(dist, k);
- assertTrue("Returned knn query is not of expected class: expected " + expectKNNQuery + " got " + knnq.getClass(), expectKNNQuery.isAssignableFrom(knnq.getClass()));
- KNNList<DoubleDistance> ids = knnq.getKNNForObject(dv, k);
- assertEquals("Result size does not match expectation!", shouldd.length, ids.size());
-
- // verify that the neighbors match.
- int i = 0;
- for(DistanceDBIDListIter<DoubleDistance> res = ids.iter(); res.valid(); res.advance(), i++) {
- // Verify distance
- assertEquals("Expected distance doesn't match.", shouldd[i], res.getDistance().doubleValue());
- // verify vector
- DoubleVector c = rep.get(res);
- DoubleVector c2 = new DoubleVector(shouldc[i]);
- assertEquals("Expected vector doesn't match: " + c.toString(), 0.0, dist.distance(c, c2).doubleValue(), 0.00001);
- }
- }
- {
- // Do a range query
- DoubleVector dv = new DoubleVector(querypoint);
- RangeQuery<DoubleVector, DoubleDistance> rangeq = db.getRangeQuery(dist, eps);
- assertTrue("Returned range query is not of expected class: expected " + expectRangeQuery + " got " + rangeq.getClass(), expectRangeQuery.isAssignableFrom(rangeq.getClass()));
- DistanceDBIDList<DoubleDistance> ids = rangeq.getRangeForObject(dv, eps);
- assertEquals("Result size does not match expectation!", shouldd.length, ids.size());
-
- // verify that the neighbors match.
- int i = 0;
- for(DistanceDBIDListIter<DoubleDistance> res = ids.iter(); res.valid(); res.advance(), i++) {
- // Verify distance
- assertEquals("Expected distance doesn't match.", shouldd[i], res.getDistance().doubleValue());
- // verify vector
- DoubleVector c = rep.get(res);
- DoubleVector c2 = new DoubleVector(shouldc[i]);
- assertEquals("Expected vector doesn't match: " + c.toString(), 0.0, dist.distance(c, c2).doubleValue(), 0.00001);
- }
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/index/preprocessed/TestMaterializedKNNAndRKNNPreprocessor.java b/test/de/lmu/ifi/dbs/elki/index/preprocessed/TestMaterializedKNNAndRKNNPreprocessor.java
deleted file mode 100644
index 10bd8a1e..00000000
--- a/test/de/lmu/ifi/dbs/elki/index/preprocessed/TestMaterializedKNNAndRKNNPreprocessor.java
+++ /dev/null
@@ -1,213 +0,0 @@
-package de.lmu.ifi.dbs.elki.index.preprocessed;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-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.database.HashmapDatabase;
-import de.lmu.ifi.dbs.elki.database.UpdatableDatabase;
-import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
-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.distance.DistanceDBIDList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
-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.query.knn.LinearScanDistanceKNNQuery;
-import de.lmu.ifi.dbs.elki.database.query.rknn.LinearScanRKNNQuery;
-import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.database.relation.RelationUtil;
-import de.lmu.ifi.dbs.elki.datasource.FileBasedDatabaseConnection;
-import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNAndRKNNPreprocessor;
-import de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNPreprocessor;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * Test case to validate the dynamic updates of materialized kNN and RkNN
- * preprocessors.
- *
- *
- * some index structures for accuracy. For a known data set and query point, the
- * top 10 nearest neighbors are queried and verified.
- *
- *
- * @author Elke Achtert
- */
-public class TestMaterializedKNNAndRKNNPreprocessor implements JUnit4Test {
- // the following values depend on the data set used!
- static String dataset = "data/testdata/unittests/3clusters-and-noise-2d.csv";
-
- // number of kNN to query
- int k = 10;
-
- // the size of objects inserted and deleted
- int updatesize = 12;
-
- int seed = 5;
-
- // size of the data set
- int shoulds = 330;
-
- /**
- * Actual test routine.
- *
- * @throws ParameterException
- * @throws UnableToComplyException
- */
- @Test
- public void testPreprocessor() throws ParameterException, UnableToComplyException {
- ListParameterization params = new ListParameterization();
- params.addParameter(FileBasedDatabaseConnection.Parameterizer.INPUT_ID, dataset);
-
- // get database
- UpdatableDatabase db = ClassGenericsUtil.parameterizeOrAbort(HashmapDatabase.class, params);
- db.initialize();
- Relation<DoubleVector> rep = db.getRelation(TypeUtil.DOUBLE_VECTOR_FIELD);
- DistanceQuery<DoubleVector, DoubleDistance> distanceQuery = db.getDistanceQuery(rep, EuclideanDistanceFunction.STATIC);
-
- // verify data set size.
- assertEquals("Data set size doesn't match parameters.", shoulds, rep.size());
-
- // get linear queries
- LinearScanDistanceKNNQuery<DoubleVector, DoubleDistance> lin_knn_query = new LinearScanDistanceKNNQuery<>(distanceQuery);
- LinearScanRKNNQuery<DoubleVector, DoubleDistance> lin_rknn_query = new LinearScanRKNNQuery<>(distanceQuery, lin_knn_query, k);
-
- // get preprocessed queries
- ListParameterization config = new ListParameterization();
- config.addParameter(MaterializeKNNPreprocessor.Factory.DISTANCE_FUNCTION_ID, distanceQuery.getDistanceFunction());
- config.addParameter(MaterializeKNNPreprocessor.Factory.K_ID, k);
- MaterializeKNNAndRKNNPreprocessor<DoubleVector, DoubleDistance> preproc = new MaterializeKNNAndRKNNPreprocessor<>(rep, distanceQuery.getDistanceFunction(), k);
- KNNQuery<DoubleVector, DoubleDistance> preproc_knn_query = preproc.getKNNQuery(distanceQuery, k);
- RKNNQuery<DoubleVector, DoubleDistance> preproc_rknn_query = preproc.getRKNNQuery(distanceQuery);
- // add as index
- db.addIndex(preproc);
- assertTrue("Preprocessor knn query class incorrect.", !(preproc_knn_query instanceof LinearScanDistanceKNNQuery));
- assertTrue("Preprocessor rknn query class incorrect.", !(preproc_rknn_query instanceof LinearScanDistanceKNNQuery));
-
- // test queries
- testKNNQueries(rep, lin_knn_query, preproc_knn_query, k);
- testRKNNQueries(rep, lin_rknn_query, preproc_rknn_query, k);
- // also test partial queries, forward only
- testKNNQueries(rep, lin_knn_query, preproc_knn_query, k / 2);
-
- // insert new objects
- List<DoubleVector> insertions = new ArrayList<>();
- NumberVector.Factory<DoubleVector, ?> o = RelationUtil.getNumberVectorFactory(rep);
- int dim = RelationUtil.dimensionality(rep);
- Random random = new Random(seed);
- for(int i = 0; i < updatesize; i++) {
- DoubleVector obj = VectorUtil.randomVector(o, dim, random);
- insertions.add(obj);
- }
- System.out.println("Insert " + insertions);
- System.out.println();
- DBIDs deletions = db.insert(MultipleObjectsBundle.makeSimple(rep.getDataTypeInformation(), insertions));
-
- // test queries
- testKNNQueries(rep, lin_knn_query, preproc_knn_query, k);
- testRKNNQueries(rep, lin_rknn_query, preproc_rknn_query, k);
-
- // delete objects
- System.out.println("Delete " + deletions);
- db.delete(deletions);
-
- // test queries
- testKNNQueries(rep, lin_knn_query, preproc_knn_query, k);
- testRKNNQueries(rep, lin_rknn_query, preproc_rknn_query, k);
- }
-
- private void testKNNQueries(Relation<DoubleVector> rep, KNNQuery<DoubleVector, DoubleDistance> lin_knn_query, KNNQuery<DoubleVector, DoubleDistance> preproc_knn_query, int k) {
- ArrayDBIDs sample = DBIDUtil.ensureArray(rep.getDBIDs());
- List<? extends KNNList<DoubleDistance>> lin_knn_ids = lin_knn_query.getKNNForBulkDBIDs(sample, k);
- List<? extends KNNList<DoubleDistance>> preproc_knn_ids = preproc_knn_query.getKNNForBulkDBIDs(sample, k);
- for(int i = 0; i < rep.size(); i++) {
- KNNList<DoubleDistance> lin_knn = lin_knn_ids.get(i);
- KNNList<DoubleDistance> pre_knn = preproc_knn_ids.get(i);
- DistanceDBIDListIter<DoubleDistance> lin = lin_knn.iter(), pre = pre_knn.iter();
- for(; lin.valid() && pre.valid(); lin.advance(), pre.advance(), i++) {
- if(!DBIDUtil.equal(lin, pre) && lin.getDistance().compareTo(pre.getDistance()) != 0) {
- System.out.print("LIN kNN #" + i + " " + lin.getDistancePair());
- System.out.print(" <=> ");
- System.out.print("PRE kNN #" + i + " " + pre.getDistancePair());
- System.out.println();
- break;
- }
- }
- assertEquals("kNN sizes do not agree.", lin_knn.size(), pre_knn.size());
- for(int j = 0; j < lin_knn.size(); j++) {
- assertTrue("kNNs of linear scan and preprocessor do not match!", DBIDUtil.equal(lin_knn.get(j), pre_knn.get(j)));
- assertTrue("kNNs of linear scan and preprocessor do not match!", lin_knn.get(j).getDistance().equals(pre_knn.get(j).getDistance()));
- }
- }
- System.out.println("knns ok");
- }
-
- private void testRKNNQueries(Relation<DoubleVector> rep, RKNNQuery<DoubleVector, DoubleDistance> lin_rknn_query, RKNNQuery<DoubleVector, DoubleDistance> preproc_rknn_query, int k) {
- ArrayDBIDs sample = DBIDUtil.ensureArray(rep.getDBIDs());
- List<? extends DistanceDBIDList<DoubleDistance>> lin_rknn_ids = lin_rknn_query.getRKNNForBulkDBIDs(sample, k);
- List<? extends DistanceDBIDList<DoubleDistance>> preproc_rknn_ids = preproc_rknn_query.getRKNNForBulkDBIDs(sample, k);
- for(int i = 0; i < rep.size(); i++) {
- DistanceDBIDList<DoubleDistance> lin_rknn = lin_rknn_ids.get(i);
- DistanceDBIDList<DoubleDistance> pre_rknn = preproc_rknn_ids.get(i);
-
- DistanceDBIDListIter<DoubleDistance> lin = lin_rknn.iter(), pre = pre_rknn.iter();
- for(; lin.valid() && pre.valid(); lin.advance(), pre.advance(), i++) {
- if(!DBIDUtil.equal(lin, pre) || lin.getDistance().compareTo(pre.getDistance()) != 0) {
- System.out.print("LIN RkNN #" + i + " " + lin);
- System.out.print(" <=> ");
- System.out.print("PRE RkNN #" + i + " " + pre);
- System.out.println();
- break;
- }
- }
- assertEquals("rkNN sizes do not agree for k=" + k, lin_rknn.size(), pre_rknn.size());
- for(int j = 0; j < lin_rknn.size(); j++) {
- assertTrue("rkNNs of linear scan and preprocessor do not match!", DBIDUtil.equal(lin_rknn.get(j), pre_rknn.get(j)));
- assertTrue("rkNNs of linear scan and preprocessor do not match!", lin_rknn.get(j).getDistance().equals(pre_rknn.get(j).getDistance()));
- }
- }
- System.out.println("rknns ok");
- System.out.println();
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/logging/TestOutputStreamLogger.java b/test/de/lmu/ifi/dbs/elki/logging/TestOutputStreamLogger.java
deleted file mode 100644
index 5742cb2d..00000000
--- a/test/de/lmu/ifi/dbs/elki/logging/TestOutputStreamLogger.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package de.lmu.ifi.dbs.elki.logging;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.Writer;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Small experiment to assert the console output logger works as expected.
- *
- * @author Erich Schubert
- *
- */
-public class TestOutputStreamLogger implements JUnit4Test {
- /**
- * Write a couple of messages to the console output writer and compare the
- * resulting characters.
- *
- * @throws IOException on errors.
- */
- @Test
- public final void testWriteString() throws IOException {
- ByteArrayOutputStream buf = new ByteArrayOutputStream();
- Writer wri = new OutputStreamLogger(buf);
- wri.write("Test." + OutputStreamLogger.NEWLINE);
- wri.write("\r123");
- wri.write("\r23");
- wri.write("\r3");
- wri.write("Test.");
- String should = "Test." + OutputStreamLogger.NEWLINE + "\r123\r \r23\r \r3" + OutputStreamLogger.NEWLINE + "Test.";
- assertEquals("Output doesn't match requirements.", should, buf.toString());
- wri.close();
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/TestAffineTransformation.java b/test/de/lmu/ifi/dbs/elki/math/TestAffineTransformation.java
deleted file mode 100644
index 926c111c..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/TestAffineTransformation.java
+++ /dev/null
@@ -1,242 +0,0 @@
-package de.lmu.ifi.dbs.elki.math;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.AffineTransformation;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-
-/**
- * JUnit Test for the class {@link AffineTransformation}
- *
- * @author Erich Schubert
- *
- */
-public class TestAffineTransformation implements JUnit4Test {
- /**
- * Test identity transform
- */
- @Test
- public void testIdentityTransform() {
- int testdim = 5;
- AffineTransformation t = new AffineTransformation(testdim);
- assertTrue(t.getDimensionality() == testdim);
- Matrix tm = t.getTransformation();
- assertEquals("initial transformation matrix should be unity", tm, Matrix.unitMatrix(testdim + 1));
-
- // test application to a vector
- double[] dv = new double[testdim];
- for(int i = 0; i < testdim; i++) {
- dv[i] = i * i + testdim;
- }
- Vector v1 = new Vector(dv.clone());
- Vector v2 = new Vector(dv.clone());
-
- Vector v3 = t.apply(v1);
- assertEquals("identity transformation wasn't identical", v2, v3);
-
- Vector v4 = t.applyInverse(v2);
- assertEquals("inverse of identity wasn't identity", v1, v4);
- }
-
- /**
- * Test adding translation vectors
- */
- @Test
- public void testTranslation() {
- int testdim = 5;
- AffineTransformation t = new AffineTransformation(testdim);
- assertTrue(t.getDimensionality() == testdim);
- Matrix tm = t.getTransformation();
- assertNotSame("getTransformation is expected to return a new copy", tm, t.getTransformation());
- assertEquals("initial transformation matrix should be unity", tm, Matrix.unitMatrix(testdim + 1));
-
- // translation vector
- double[] tv = new double[testdim];
- for(int i = 0; i < testdim; i++) {
- tv[i] = i + testdim;
- }
- t.addTranslation(new Vector(tv));
-
- Matrix tm2 = t.getTransformation();
- // Manually do the same changes to the matrix tm
- for(int i = 0; i < testdim; i++) {
- tm.set(i, testdim, i + testdim);
- }
- // Compare the results
- assertEquals("Translation wasn't added correctly to matrix.", tm, tm2);
-
- // test application to a vector
- double[] dv1 = new double[testdim];
- double[] dv2 = new double[testdim];
- for(int i = 0; i < testdim; i++) {
- dv1[i] = i * i + testdim;
- dv2[i] = i * i + i + 2 * testdim;
- }
- Vector v1 = new Vector(dv1);
- Vector v2t = new Vector(dv2);
-
- Vector v1t = t.apply(v1);
- assertEquals("Vector wasn't translated properly forward.", v2t, v1t);
- Vector v2b = t.applyInverse(v2t);
- assertEquals("Vector wasn't translated properly backwards.", v1, v2b);
- Vector v1b = t.applyInverse(v1t);
- assertEquals("Vector wasn't translated properly back and forward.", v1, v1b);
-
- // Translation
- Vector vd = v1.minus(v2b);
- Vector vtd = v1t.minus(v2t);
- assertEquals("Translation changed vector difference.", vd, vtd);
-
- // Translation shouldn't change relative vectors.
- assertEquals("Relative vectors weren't left unchanged by translation!", v1, t.applyRelative(v1));
- assertEquals("Relative vectors weren't left unchanged by translation!", v2t, t.applyRelative(v2t));
- assertEquals("Relative vectors weren't left unchanged by translation!", v1t, t.applyRelative(v1t));
- assertEquals("Relative vectors weren't left unchanged by translation!", v2b, t.applyRelative(v2b));
- }
-
- /**
- * Test direct inclusion of matrices
- */
- @Test
- public void testMatrix() {
- int testdim = 5;
- int axis1 = 1;
- int axis2 = 3;
-
- assert (axis1 < testdim);
- assert (axis2 < testdim);
- // don't change the angle; we'll be using that executing the rotation
- // three times will be identity (approximately)
- double angle = Math.toRadians(360 / 3);
- AffineTransformation t = new AffineTransformation(testdim);
- assertTrue(t.getDimensionality() == testdim);
- Matrix tm = t.getTransformation();
- assertNotSame("getTransformation is expected to return a new copy", tm, t.getTransformation());
- assertEquals("initial transformation matrix should be unity", tm, Matrix.unitMatrix(testdim + 1));
-
- // rotation matrix
- double[][] rm = new double[testdim][testdim];
- for(int i = 0; i < testdim; i++) {
- rm[i][i] = 1;
- }
- // add the rotation
- rm[axis1][axis1] = +Math.cos(angle);
- rm[axis1][axis2] = -Math.sin(angle);
- rm[axis2][axis1] = +Math.sin(angle);
- rm[axis2][axis2] = +Math.cos(angle);
- t.addMatrix(new Matrix(rm));
- Matrix tm2 = t.getTransformation();
-
- // We know that we didn't do any translations and tm is the unity matrix
- // so we can manually do the rotation on it, too.
- tm.set(axis1, axis1, +Math.cos(angle));
- tm.set(axis1, axis2, -Math.sin(angle));
- tm.set(axis2, axis1, +Math.sin(angle));
- tm.set(axis2, axis2, +Math.cos(angle));
-
- // Compare the results
- assertEquals("Rotation wasn't added correctly to matrix.", tm, tm2);
-
- // test application to a vector
- double[] dv = new double[testdim];
- for(int i = 0; i < testdim; i++) {
- dv[i] = i * i + testdim;
- }
- Vector v1 = new Vector(dv);
- Vector v2 = t.apply(v1);
- Vector v3 = t.applyInverse(v2);
- assertTrue("Forward-Backward didn't work correctly.", v1.minus(v3).euclideanLength() < 0.0001);
- Vector v4 = t.apply(t.apply(t.apply(v1)));
- assertTrue("Triple-Rotation by 120 degree didn't work", v1.minus(v4).euclideanLength() < 0.0001);
-
- // Rotation shouldn't disagree for relative vectors.
- // (they just are not affected by translation!)
- assertEquals("Relative vectors were affected differently by pure rotation!", v2, t.applyRelative(v1));
-
- // should do the same as built-in rotation!
- AffineTransformation t2 = new AffineTransformation(testdim);
- t2.addRotation(axis1, axis2, angle);
- Vector t2v2 = t2.apply(v1);
- assertTrue("Manual rotation and AffineTransformation.addRotation disagree.", v2.minus(t2v2).euclideanLength() < 0.0001);
- }
-
- /**
- * Test {@link AffineTransformation#reorderAxesTransformation}
- */
- @Test
- public void testReorder() {
- Vector v = new Vector(new double[] { 3, 5, 7 });
- // all permutations
- Vector p1 = new Vector(new double[] { 3, 5, 7 });
- Vector p2 = new Vector(new double[] { 3, 7, 5 });
- Vector p3 = new Vector(new double[] { 5, 3, 7 });
- Vector p4 = new Vector(new double[] { 5, 7, 3 });
- Vector p5 = new Vector(new double[] { 7, 3, 5 });
- Vector p6 = new Vector(new double[] { 7, 5, 3 });
- Vector[] ps = new Vector[] {
- // with no arguments.
- p1,
- // with just one argument.
- p1, p3, p5,
- // with two arguments.
- p1, p2, p3, p4, p5, p6, };
-
- // index in reference array
- int idx = 0;
- // with 0 arguments
- {
- AffineTransformation aff = AffineTransformation.reorderAxesTransformation(v.getDimensionality(), new int[] {});
- Vector n = aff.apply(v).minus(ps[idx]);
- assertEquals("Permutation " + idx + " doesn't match.", n.euclideanLength(), 0.0, 0.001);
- idx++;
- }
- // with one argument
- for(int d1 = 1; d1 <= 3; d1++) {
- AffineTransformation aff = AffineTransformation.reorderAxesTransformation(v.getDimensionality(), new int[] { d1 });
- Vector n = aff.apply(v).minus(ps[idx]);
- assertEquals("Permutation " + idx + " doesn't match.", n.euclideanLength(), 0.0, 0.001);
- idx++;
- }
- // with two arguments
- for(int d1 = 1; d1 <= 3; d1++) {
- for(int d2 = 1; d2 <= 3; d2++) {
- if(d1 == d2) {
- continue;
- }
- AffineTransformation aff = AffineTransformation.reorderAxesTransformation(v.getDimensionality(), new int[] { d1, d2 });
- Vector n = aff.apply(v).minus(ps[idx]);
- assertEquals("Permutation " + idx + " doesn't match.", n.euclideanLength(), 0.0, 0.001);
- idx++;
- }
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/TestKernelDensityFitting.java b/test/de/lmu/ifi/dbs/elki/math/TestKernelDensityFitting.java
deleted file mode 100644
index 57129241..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/TestKernelDensityFitting.java
+++ /dev/null
@@ -1,166 +0,0 @@
-package de.lmu.ifi.dbs.elki.math;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-
-import java.util.Arrays;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.data.DoubleVector;
-import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
-import de.lmu.ifi.dbs.elki.database.Database;
-import de.lmu.ifi.dbs.elki.database.StaticArrayDatabase;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.relation.Relation;
-import de.lmu.ifi.dbs.elki.datasource.FileBasedDatabaseConnection;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.fitting.FittingFunction;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.fitting.GaussianFittingFunction;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.fitting.LevenbergMarquardtMethod;
-import de.lmu.ifi.dbs.elki.math.statistics.KernelDensityEstimator;
-import de.lmu.ifi.dbs.elki.math.statistics.distribution.NormalDistribution;
-import de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions.GaussianKernelDensityFunction;
-import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
-
-/**
- * JUnit test that does a complete Kernel and Levenberg-Marquadt fitting.
- *
- * @author Erich Schubert
- */
-public class TestKernelDensityFitting implements JUnit4Test {
- // the following values depend on the data set used!
- String dataset = "data/testdata/unittests/gaussian-1d-for-fitting.csv";
-
- // data set size for verification.
- int realsize = 100;
-
- double realmean = 0.5;
-
- double realstdd = 1.5;
-
- /**
- * The test will load the given data set and perform a Levenberq-Marquadt
- * fitting on a kernelized density estimation. The test evaluates the fitting
- * quality to ensure that the results remain stable and significantly better
- * than traditional estimation.
- *
- * @throws ParameterException on errors.
- */
- @Test
- public final void testFitDoubleArray() {
- ListParameterization config = new ListParameterization();
- // Input
- config.addParameter(FileBasedDatabaseConnection.Parameterizer.INPUT_ID, dataset);
- // This data was generated with a mean of 0.0 and stddev 1.23,
-
- // get database
- Database db = ClassGenericsUtil.parameterizeOrAbort(StaticArrayDatabase.class, config);
- db.initialize();
- Relation<DoubleVector> rep = db.getRelation(TypeUtil.DOUBLE_VECTOR_FIELD);
-
- // verify data set size.
- assertEquals("Data set size doesn't match parameters.", realsize, rep.size());
-
- double splitval = 0.5;
-
- double[] fulldata = new double[rep.size()];
- // transform into double array
- {
- int i = 0;
- for(DBIDIter iditer = rep.iterDBIDs(); iditer.valid(); iditer.advance()) {
- fulldata[i] = rep.get(iditer).doubleValue(0);
- i++;
- }
- }
- Arrays.sort(fulldata);
-
- // Check that the initial parameters match what we were expecting from the
- // data.
- double[] fullparams = estimateInitialParameters(fulldata);
- assertEquals("Full Mean before fitting", 0.4446105, fullparams[0], 0.0001);
- assertEquals("Full Stddev before fitting", 1.4012001, fullparams[1], 0.0001);
-
- // Do a fit using only part of the data and check the results are right.
- double[] fullfit = run(fulldata, fullparams);
- assertEquals("Full Mean after fitting", 0.64505, fullfit[0], 0.01);
- assertEquals("Full Stddev after fitting", 1.5227889, fullfit[1], 0.01);
-
- int splitpoint = 0;
- while(fulldata[splitpoint] < splitval && splitpoint < fulldata.length) {
- splitpoint++;
- }
- double[] halfdata = Arrays.copyOf(fulldata, splitpoint);
-
- // Check that the initial parameters match what we were expecting from the
- // data.
- double[] params = estimateInitialParameters(halfdata);
- assertEquals("Mean before fitting", -0.65723044, params[0], 0.0001);
- assertEquals("Stddev before fitting", 1.0112391, params[1], 0.0001);
-
- // Do a fit using only part of the data and check the results are right.
- double[] ps = run(halfdata, params);
- assertEquals("Mean after fitting", 0.45980, ps[0], 0.01);
- assertEquals("Stddev after fitting", 1.320427, ps[1], 0.01);
- }
-
- private double[] estimateInitialParameters(double[] data) {
- double[] params = new double[3];
- // compute averages
- MeanVariance mv = new MeanVariance();
- for(double d : data) {
- mv.put(d);
- }
-
- params[0] = mv.getMean();
- params[1] = mv.getSampleStddev();
- // guess initial amplitude for an gaussian distribution.
- double c1 = NormalDistribution.erf(Math.abs(data[0] - params[0]) / (params[1] * Math.sqrt(2)));
- double c2 = NormalDistribution.erf(Math.abs(data[data.length - 1] - params[0]) / (params[1] * Math.sqrt(2)));
- params[2] = 1.0 / Math.min(c1, c2);
- // System.out.println("Mean: " + params[0] + " Stddev: " + params[1] +
- // " Amp: " + params[2]);
- return params;
- }
-
- private double[] run(double[] data, double[] params) {
- FittingFunction func = GaussianFittingFunction.STATIC;
- boolean[] dofit = { true, true, true };
- KernelDensityEstimator de = new KernelDensityEstimator(data, GaussianKernelDensityFunction.KERNEL, 1e-10);
- LevenbergMarquardtMethod fit = new LevenbergMarquardtMethod(func, params, dofit, data, de.getDensity(), de.getVariance());
- // for(int i = 0; i < 100; i++) {
- // fit.iterate();
- // double[] ps = fit.getParams();
- // System.out.println("Mean: " + ps[0] + " Stddev: " + ps[1] + " Amp: " +
- // ps[2]+" Chi: "+fit.getChiSq());
- // }
- fit.run();
- // double[] ps = fit.getParams();
- // System.out.println("Result: "+ps[0]+" "+ps[1]+" "+ps[2]+" Chi: "+fit.getChiSq()+" Iter: "+fit.maxruns);
- return fit.getParams();
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/math/TestLevenbergMarquardtGaussianFitting.java b/test/de/lmu/ifi/dbs/elki/math/TestLevenbergMarquardtGaussianFitting.java
deleted file mode 100644
index 039b7179..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/TestLevenbergMarquardtGaussianFitting.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package de.lmu.ifi.dbs.elki.math;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.fitting.GaussianFittingFunction;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.fitting.LevenbergMarquardtMethod;
-
-/**
- * Test to evaluate Levenberg-Marquardt fitting on a given Gaussian
- * distribution.
- *
- * @author Erich Schubert
- *
- */
-public class TestLevenbergMarquardtGaussianFitting implements JUnit4Test {
- /**
- * Evaluate on a symmetric Gaussian distribution. Traditional estimation
- * already has the mean quite good, but is far off on the stddev. The improved
- * fitting is much better on the stddev.
- */
- // these points were generated with mean 0.12345 and stddev 0.98765
- @Test
- public void testSymmetric() {
- double[] testx = { -0.787791050195, -0.738026373791, -0.688261697386, -0.638497020982, -0.588732344578, -0.538967668174, -0.489202991769, -0.439438315365, -0.389673638961, -0.339908962556, -0.290144286152, -0.240379609748, -0.190614933344, -0.140850256939, -0.0910855805352, -0.0413209041309, 0.00844377227332, 0.0582084486776, 0.107973125082, 0.157737801486, 0.20750247789, 0.257267154295, 0.307031830699, 0.356796507103, 0.406561183507, 0.456325859912, 0.506090536316, 0.55585521272, 0.605619889124, 0.655384565529, 0.705149241933, 0.754913918337, 0.804678594741, 0.854443271146, 0.90420794755, 0.953972623954, 1.00373730036, 1.05350197676, 1.10326665317 };
- double[] testy = { 0.25319163934, 0.210993032783, 0.26122946916, 0.301418618261, 0.309456448082, 0.319503735357, 0.327541565177, 0.285342958621, 0.371749629189, 0.345626682273, 0.357683427004, 0.343617224818, 0.365721256824, 0.363711799369, 0.39586311865, 0.389834746285, 0.456146842302, 0.434042810296, 0.39586311865, 0.40390094847, 0.442080640117, 0.375768544099, 0.355673969549, 0.373759086644, 0.39586311865, 0.371749629189, 0.345626682273, 0.361702341914, 0.381796916465, 0.357683427004, 0.405910405925, 0.353664512093, 0.349645597183, 0.267257841525, 0.263238926615, 0.313475362992, 0.243144352064, 0.25721055425, 0.221040320058 };
- double mean = 0.122895805963;
- double stddev = 0.542856090502;
- double[] s = new double[testx.length];
- for(int i = 0; i < testx.length; i++) {
- s[i] = 1.0;
- }
- double[] params = { mean, stddev, 1 };
- boolean[] dofit = { true, true, false };
- LevenbergMarquardtMethod fit = new LevenbergMarquardtMethod(GaussianFittingFunction.STATIC, params, dofit, testx, testy, s);
- for(int i = 0; i < 50; i++) {
- fit.iterate();
- }
- double[] ps = fit.getParams();
- // compare results.
- double[] should = { 0.1503920, 0.9788814, 1 };
- assertEquals("Mean doesn't match.", should[0], ps[0], 0.0001);
- assertEquals("Stddev doesn't match.", should[1], ps[1], 0.0001);
- assertEquals("Scaling doesn't match.", should[2], ps[2], 0.0001);
- }
-
- /**
- * Same experiment, but only with one leg of the distribution. This results in
- * the traditional mean being far off.
- */
- @Test
- public void testAsymmetric() {
- double[] testx = { 0.157737801486, 0.20750247789, 0.257267154295, 0.307031830699, 0.356796507103, 0.406561183507, 0.456325859912, 0.506090536316, 0.55585521272, 0.605619889124, 0.655384565529, 0.705149241933, 0.754913918337, 0.804678594741, 0.854443271146, 0.90420794755, 0.953972623954, 1.00373730036, 1.05350197676, 1.10326665317, 1.15303132957, 1.20279600598, 1.25256068238, 1.30232535878, 1.35209003519, 1.40185471159, 1.451619388, 1.5013840644, 1.55114874081, 1.60091341721, 1.65067809361, 1.70044277002, 1.75020744642, 1.79997212283, 1.84973679923, 1.89950147564, 1.94926615204, 1.99903082844, 2.04879550485, 2.09856018125, 2.14832485766, 2.19808953406, 2.24785421046, 2.29761888687, 2.34738356327, 2.39714823968, 2.44691291608, 2.49667759249, 2.54644226889, 2.59620694529, 2.6459716217, 2.6957362981, 2.74550097451, 2.79526565091, 2.84503032732, 2.89479500372, 2.94455968012, 2.99432435653, 3.04408903293, 3.09385370934 };
- double[] testy = { 0.40390094847, 0.442080640117, 0.375768544099, 0.355673969549, 0.373759086644, 0.39586311865, 0.371749629189, 0.345626682273, 0.361702341914, 0.381796916465, 0.357683427004, 0.405910405925, 0.353664512093, 0.349645597183, 0.267257841525, 0.263238926615, 0.313475362992, 0.243144352064, 0.25721055425, 0.221040320058, 0.247163266974, 0.219030862603, 0.267257841525, 0.186879543322, 0.184870085867, 0.160756596406, 0.202955202963, 0.132624192035, 0.150709309131, 0.158747138951, 0.100472872754, 0.124586362215, 0.116548532394, 0.132624192035, 0.078368840748, 0.0843972131132, 0.0582742661972, 0.0763593832929, 0.100472872754, 0.052245893832, 0.0562648087421, 0.0462175214668, 0.0321513192812, 0.0421986065566, 0.026122946916, 0.0321513192812, 0.0140662021855, 0.0120567447305, 0.0241134894609, 0.0140662021855, 0.0160756596406, 0.0140662021855, 0.00803782982031, 0.00602837236523, 0.0120567447305, 0.00803782982031, 0.00803782982031, 0.00602837236523, 0.0100472872754, 0.00200945745508 };
- double mean = 0.951868470698;
- double stddev = 0.571932920001;
- double[] s = new double[testx.length];
- for(int i = 0; i < testx.length; i++) {
- s[i] = 1.0;
- }
- double[] params = { mean, stddev, 1 };
- boolean[] dofit = { true, true, false };
- LevenbergMarquardtMethod fit = new LevenbergMarquardtMethod(GaussianFittingFunction.STATIC, params, dofit, testx, testy, s);
- for(int i = 0; i < 50; i++) {
- fit.iterate();
- }
- double[] ps = fit.getParams();
- // compare results.
- double[] should = { 0.132165, 1.027699, 1 };
- assertEquals("Mean doesn't match.", should[0], ps[0], 0.0001);
- assertEquals("Stddev doesn't match.", should[1], ps[1], 0.0001);
- assertEquals("Scaling doesn't match.", should[2], ps[2], 0.0001);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/math/TestMathUtil.java b/test/de/lmu/ifi/dbs/elki/math/TestMathUtil.java
deleted file mode 100644
index 90112694..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/TestMathUtil.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package de.lmu.ifi.dbs.elki.math;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Random;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for some basic math functions.
- *
- * @author Erich Schubert
- */
-public class TestMathUtil implements JUnit4Test {
- @Test
- public void testPearsonCorrelation() {
- final int size = 1000;
- final long seed = 1;
- double[] data1 = new double[size];
- double[] data2 = new double[size];
- double[] weight1 = new double[size];
- double[] weight2 = new double[size];
-
- Random r = new Random(seed);
- for (int i = 0; i < size; i++) {
- data1[i] = r.nextDouble();
- data2[i] = r.nextDouble();
- weight1[i] = 1.0;
- weight2[i] = 0.1;
- }
-
- double pear = MathUtil.pearsonCorrelationCoefficient(data1, data2);
- double wpear1 = MathUtil.weightedPearsonCorrelationCoefficient(data1, data2, weight1);
- double wpear2 = MathUtil.weightedPearsonCorrelationCoefficient(data1, data2, weight2);
- assertEquals("Pearson and weighted pearson should be the same with constant weights.", pear, wpear1, 1E-10);
- assertEquals("Weighted pearsons should be the same with constant weights.", wpear1, wpear2, 1E-10);
- }
-
- @Test
- public void testBitMath() {
- assertEquals("Bit math issues", 1024, MathUtil.nextPow2Int(912));
- assertEquals("Bit math issues", 8, MathUtil.nextPow2Int(5));
- assertEquals("Bit math issues", 4, MathUtil.nextPow2Int(4));
- assertEquals("Bit math issues", 4, MathUtil.nextPow2Int(3));
- assertEquals("Bit math issues", 2, MathUtil.nextPow2Int(2));
- assertEquals("Bit math issues", 1, MathUtil.nextPow2Int(1));
- assertEquals("Bit math issues", 0, MathUtil.nextPow2Int(0));
- assertEquals("Bit math issues", 1024L, MathUtil.nextPow2Long(912L));
- assertEquals("Bit math issues", 0, MathUtil.nextPow2Int(-1));
- assertEquals("Bit math issues", 0, MathUtil.nextPow2Int(-2));
- assertEquals("Bit math issues", 0, MathUtil.nextPow2Int(-99));
- assertEquals("Bit math issues", 15, MathUtil.nextAllOnesInt(8));
- assertEquals("Bit math issues", 7, MathUtil.nextAllOnesInt(4));
- assertEquals("Bit math issues", 3, MathUtil.nextAllOnesInt(3));
- assertEquals("Bit math issues", 3, MathUtil.nextAllOnesInt(2));
- assertEquals("Bit math issues", 1, MathUtil.nextAllOnesInt(1));
- assertEquals("Bit math issues", 0, MathUtil.nextAllOnesInt(0));
- assertEquals("Bit math issues", -1, MathUtil.nextAllOnesInt(-1));
- assertEquals("Bit math issues", 0, 0 >>> 1);
- }
-
- @Test
- public void testFloatToDouble() {
- Random r = new Random(1l);
- for (int i = 0; i < 10000; i++) {
- final double dbl = Double.longBitsToDouble(r.nextLong());
- final float flt = (float) dbl;
- final double uppd = MathUtil.floatToDoubleUpper(flt);
- final float uppf = (float) uppd;
- final double lowd = MathUtil.floatToDoubleLower(flt);
- final float lowf = (float) lowd;
- assertTrue("Expected value to become larger, but " + uppd + " < " + dbl, uppd >= dbl || Double.isNaN(dbl));
- assertTrue("Expected value to round to the same float.", flt == uppf || Double.isNaN(flt));
- assertTrue("Expected value to become smaller, but " + lowd + " > " + dbl, lowd <= dbl || Double.isNaN(dbl));
- assertTrue("Expected value to round to the same float.", flt == lowf || Double.isNaN(flt));
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/TestMatrix.java b/test/de/lmu/ifi/dbs/elki/math/TestMatrix.java
deleted file mode 100644
index 55c266d8..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/TestMatrix.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package de.lmu.ifi.dbs.elki.math;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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.Random;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
-
-public class TestMatrix implements JUnit4Test {
-
- @Test
- public void testTransposedOperations() {
- for(int i = 0; i < 100; i++) {
- randomizedTransposedTest();
- randomizedTestAsymmetric();
- }
- }
-
- private void randomizedTransposedTest() {
- Random r = new Random();
- int dim = r.nextInt(30) + 10;
- Matrix A = new Matrix(dim, dim);
- Matrix B = new Matrix(dim, dim);
- for(int i = 0; i < dim; i++) {
- for(int j = 0; j < dim; j++) {
- A.set(i, j, (r.nextDouble() - .5) * 10);
- B.set(i, j, (r.nextDouble() - .5) * 10);
- }
- }
-
- Matrix AT_B = A.transpose().times(B);
- org.junit.Assert.assertTrue("A.transposeTimes(B) does not equal A.transpose.times(B)", A.transposeTimes(B).almostEquals(AT_B));
- Matrix A_BT = A.times(B.transpose());
- org.junit.Assert.assertTrue("A.timesTranspose(B) does not equal A.times(B.transpose)", A.timesTranspose(B).almostEquals(A_BT));
- org.junit.Assert.assertTrue("Usually (!) AT_B != A_BT!", !AT_B.almostEquals(A_BT));
- Matrix AT_BT = A.transpose().times(B.transpose());
- org.junit.Assert.assertTrue("A.transposeTimesTranspose(B) does not equal (B.times(A)).transpose", B.times(A).transpose().almostEquals(AT_BT));
- org.junit.Assert.assertTrue("A.transposeTimesTranspose(B) does not equal A.transpose.times(B.transpose)", A.transposeTimesTranspose(B).almostEquals(AT_BT));
- }
-
- private void randomizedTestAsymmetric() {
- Random r = new Random();
- int dim1 = r.nextInt(30) + 10;
- int dim2 = r.nextInt(30) + 10;
- int dim3 = r.nextInt(30) + 10;
- Matrix A = new Matrix(dim1, dim2);
- Matrix B = new Matrix(dim2, dim3);
- for(int i = 0; i < dim1; i++) {
- for(int j = 0; j < dim2; j++) {
- A.set(i, j, (r.nextDouble() - .5) * 10);
- }
- }
- for(int i = 0; i < dim2; i++) {
- for(int j = 0; j < dim3; j++) {
- B.set(i, j, (r.nextDouble() - .5) * 10);
- }
- }
-
- Matrix A_B = A.times(B);
- Matrix BT_AT = B.transpose().times(A.transpose());
- Matrix BT_AT2 = B.transposeTimesTranspose(A);
- org.junit.Assert.assertTrue("B.transposeTimesTranspose(A) does not equal (A.times(B)).transpose", A_B.transpose().almostEquals(BT_AT));
- org.junit.Assert.assertTrue("B.transposeTimesTranspose(A) does not equal B.transpose.times(A.transpose)", BT_AT2.almostEquals(BT_AT));
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/math/TestSinCosTable.java b/test/de/lmu/ifi/dbs/elki/math/TestSinCosTable.java
deleted file mode 100644
index 8e91a404..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/TestSinCosTable.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package de.lmu.ifi.dbs.elki.math;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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/>.
- */
-
-public class TestSinCosTable implements JUnit4Test {
-
- @Test
- public void testSinCosTable() {
- doTestSinCosTable(360);
- doTestSinCosTable(142); // Divisible by two
- doTestSinCosTable(17);
- doTestSinCosTable(131); // Prime.
- }
-
- protected void doTestSinCosTable(int steps) {
- SinCosTable table = SinCosTable.make(steps);
- for (int i = -steps; i < 2 * steps; i++) {
- double angle = Math.toRadians(360. * i / steps);
- assertEquals("Cosine does not match at i=" + i + " a=" + angle, Math.cos(angle), table.cos(i), 1E-10);
- assertEquals("Sine does not match at i=" + i + " a=" + angle, Math.sin(angle), table.sin(i), 1E-10);
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/TestSlidingVariance.java b/test/de/lmu/ifi/dbs/elki/math/TestSlidingVariance.java
deleted file mode 100644
index 58824142..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/TestSlidingVariance.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package de.lmu.ifi.dbs.elki.math;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Random;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test {@link MeanVariance} with negative weights.
- *
- * @author Erich Schubert
- */
-public class TestSlidingVariance implements JUnit4Test {
- /**
- * Size of test data set.
- */
- private static final int SIZE = 100000;
-
- /**
- * Sliding window size.
- */
- private static final int WINDOWSIZE = 100;
-
- @Test
- public void testSlidingWindowVariance() {
- MeanVariance mv = new MeanVariance();
- MeanVariance mc = new MeanVariance();
-
- Random r = new Random(0);
- double[] data = new double[SIZE];
- for(int i = 0; i < data.length; i++) {
- data[i] = r.nextDouble();
- }
- // Arrays.sort(data);
-
- // Pre-roll:
- for(int i = 0; i < WINDOWSIZE; i++) {
- mv.put(data[i]);
- }
- // Compare to window approach
- for(int i = WINDOWSIZE; i < data.length; i++) {
- mv.put(data[i - WINDOWSIZE], -1.); // Remove
- mv.put(data[i]);
-
- mc.reset(); // Reset statistics
- for(int j = i + 1 - WINDOWSIZE; j <= i; j++) {
- mc.put(data[j]);
- }
- // Fully manual statistics, exact two-pass algorithm:
- double mean = 0.0;
- for(int j = i + 1 - WINDOWSIZE; j <= i; j++) {
- mean += data[j];
- }
- mean /= WINDOWSIZE;
- double var = 0.0;
- for(int j = i + 1 - WINDOWSIZE; j <= i; j++) {
- double v = data[j] - mean;
- var += v * v;
- }
- var /= (WINDOWSIZE - 1);
- assertEquals("Variance does not agree at i=" + i, mv.getSampleVariance(), mc.getSampleVariance(), 1e-14);
- assertEquals("Variance does not agree at i=" + i, mv.getSampleVariance(), var, 1e-14);
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/TestStatisticalMoments.java b/test/de/lmu/ifi/dbs/elki/math/TestStatisticalMoments.java
deleted file mode 100644
index fe63b707..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/TestStatisticalMoments.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package de.lmu.ifi.dbs.elki.math;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test to check our statistical moments class for correctness.
- *
- * @author Erich Schubert
- */
-public class TestStatisticalMoments implements JUnit4Test {
- @Test
- public void testTiny() {
- double[] data = new double[] { 222, 1122, 45444 };
- StatisticalMoments m = new StatisticalMoments();
- for (double d : data) {
- m.put(d);
- }
- // Validated with R package "e1071" and scipy.
- // Looks as we might be closer to scipys result!
- // skewness(c(222,1122,45444), type = 1) = 0.70614285367114104
- // scipy.stats.skew([222, 1122, 45444], bias=True) = 0.7061428536711412
- assertEquals("Naive skewness does not match.", 0.70614285367114104, m.getNaiveSkewness(), 1e-15);
- // skewness(c(222,1122,45444), type = 2) = 1.7296896770071024
- // scipy.stats.skew([222, 1122, 45444], bias=False) = 1.7296896770071026
- assertEquals("Sample skewness does not match.", 1.7296896770071024, m.getSampleSkewness(), 1e-15);
- // Type 3 skewness is not in ELKI.
-
- // kurtosis(c(222,1122,45444), type = 1) = -1.5
- assertEquals("Naive kurtosis does not match.", -1.5, m.getNaiveExcessKurtosis(), 1e-15);
- assertEquals("Naive kurtosis does not match.", -1.5 + 3.0, m.getNaiveKurtosis(), 1e-15);
- // type = 2 needs 4 observations - so do we!
- }
-
- @Test
- public void testGamma() {
- double[] data = new double[] { // 100 Gamma(5,5) distributed random values.
- 0.6388530607016163, 0.9782442336324599, 0.8882176966052615, 0.7849646645745156, 2.0633275427120497, //
- 0.9545195282320902, 1.092390620469477, 0.7258265676258062, 1.378026049091643, 0.8310918468931533,//
- 0.9495339766440013, 0.7126363476416752, 0.5608700366395489, 0.31408795273142415, 1.4909322345449254, //
- 0.46625313007571856, 1.1870054487101156, 0.7640843133327799, 2.235582041645692, 1.5812487824715005, //
- 1.512895069952923, 0.606517358771931, 1.1961880366469766, 0.7854465499137, 0.8084781536051177, //
- 0.7615405607968533, 1.6614435713861262, 1.4869842072109933, 0.43465864880894045, 2.007341464773332, //
- 0.33478515273215137, 1.9093706181977907, 0.3539177300096471, 0.44888559667524086, 1.0249621186169293, //
- 0.38784905783431306, 0.7632290555534638, 0.9941038353388855, 0.6358745449186729, 0.5750658437507069, //
- 0.9565742499910938, 1.2221328658541637, 0.9389920544737386, 1.21461175894598, 1.5713316877580166, //
- 0.3470088915002977, 0.4419291224056868, 2.343465732285217, 1.0612049261527454, 0.9960347794653911, //
- 0.5433216826433932, 1.006345176861023, 1.034059277904943, 0.7199916430119295, 1.218878192200847, //
- 1.0023101563986212, 1.093784991451296, 0.9748868952634213, 1.81732410812918, 0.5259404003069172, //
- 1.5179842038671814, 0.7461497981977685, 0.47530253061596, 0.810558795121139, 0.9383514512691828, //
- 0.42371144806092004, 0.8698616597894346, 0.4541860955288436, 0.3136304450065802, 0.8799371863836344, //
- 0.9854734113277808, 0.8651302802119106, 0.7981146204118504, 0.5255964404563404, 0.8570668629471919, //
- 1.0294303406520284, 1.4592029352371467, 1.1034285928922425, 1.0042662401564635, 0.6443339212869743, //
- 1.4096313764251664, 0.9328112988095885, 2.0874718257265483, 1.063702918067901, 0.5885221900074733, //
- 1.216856018361022, 0.5572986786142953, 0.6620626132872955, 0.7357210048560157, 1.5174141129183254, //
- 1.2293542801457167, 1.490026433254134, 1.4307462549666328, 1.381520418446136, 0.48400651328811123, //
- 0.8448303085270435, 1.1514319532981445, 0.8944580168473978, 0.5003052782124537, 1.1457096934062219 };
- StatisticalMoments m = new StatisticalMoments();
- for (double d : data) {
- m.put(d);
- }
- // Validated with R package "e1071" and scipy:
- // Looks as we might be closer to scipys result!
- // skewness(data, type = 1) = 0.8553563631726689
- // scipy.stats.skew(data, bias=True) = 0.8553563631726712
- assertEquals("Naive skewness does not match.", 0.8553563631726689, m.getNaiveSkewness(), 1e-14);
- // skewness(data, type = 2) = 0.868437587353074
- // scipy.stats.skew(data, bias=False) = 0.868437587353077
- assertEquals("Sample skewness does not match.", 0.868437587353074, m.getSampleSkewness(), 1e-14);
- // Type 3 skewness is not in ELKI.
-
- // kurtosis(data, type = 1) = 0.4778717586207377
- // scipy.stats.kurtosis(data, fisher=True) = 0.4778717586207377
- assertEquals("Naive kurtosis does not match.", 0.4778717586207377, m.getNaiveExcessKurtosis(), 1e-14);
- assertEquals("Naive kurtosis does not match.", 0.4778717586207377 + 3.0, m.getNaiveKurtosis(), 1e-14);
- // kurtosis(data, type = 2) = 0.565141985530060675
- // scipy.stats.kurtosis(data, fisher=True, bias=False) = 0.5651419855300603
- // scipy.stats.kurtosis(data, fisher=True, bias=False) = 0.5651419855300603
- // scipy.stats.kurtosis(data, fisher=False, bias=False) = 3.5651419855300603
- assertEquals("Sample kurtosis does not match.", 0.565141985530060675, m.getSampleExcessKurtosis(), 1e-14);
- assertEquals("Sample kurtosis does not match.", 3.565141985530060675, m.getSampleKurtosis(), 1e-14);
-
- // numpy.array(data).mean() = 0.98342960290360215
- assertEquals("Mean does not match.", 0.98342960290360215, m.getMean(), 1e-15);
- // numpy.array(data).std() = 0.44953213330440578
- assertEquals("Naive stddev does not match.", 0.44953213330440578, m.getNaiveStddev(), 1e-15);
- // numpy.array(data).std(ddof=1) = 0.45179679314507293
- assertEquals("Sample stddev does not match.", 0.45179679314507293, m.getSampleStddev(), 1e-15);
- // numpy.array(data).min() = 0.31363044500658022
- assertEquals("Min does not match.", 0.31363044500658022, m.getMin(), 1e-16);
- // numpy.array(data).max() = 2.343465732285217
- assertEquals("Max does not match.", 2.343465732285217, m.getMax(), 1e-16);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/TestWeightFunctions.java b/test/de/lmu/ifi/dbs/elki/math/TestWeightFunctions.java
deleted file mode 100644
index d2a71615..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/TestWeightFunctions.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package de.lmu.ifi.dbs.elki.math;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions.ConstantWeight;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions.ErfcStddevWeight;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions.ErfcWeight;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions.ExponentialWeight;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions.GaussStddevWeight;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions.GaussWeight;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions.LinearWeight;
-import de.lmu.ifi.dbs.elki.math.linearalgebra.pca.weightfunctions.WeightFunction;
-
-/**
- * JUnit test to assert consistency of a couple of Weight functions
- *
- * @author Erich Schubert
- *
- */
-public class TestWeightFunctions implements JUnit4Test {
- /**
- * Just a 'boring' value test for completeness.
- */
- @Test
- public void testGetWeight() {
- WeightFunction[] wf = { new ConstantWeight(), new ErfcWeight(), new ErfcStddevWeight(), new GaussWeight(), new GaussStddevWeight(), new LinearWeight(), new ExponentialWeight() };
- double[] at0 = { 1.0, 1.0, 1.0, 1.0, 0.3989422804014327, 1.0, 1.0 };
- double[] at01 = { 1.0, 0.8693490686884612, 0.920344325445942, 0.9772372209558107, 0.3969525474770118, 0.91, 0.7943282347242815 };
- double[] at09 = { 1.0, 0.13877499454059491, 0.36812025069351895, 0.15488166189124816, 0.2660852498987548, 0.18999999999999995, 0.12589254117941673 };
- double[] at10 = { 1.0, 0.10000000000000016, 0.31731050786291404, 0.10000000000000002, 0.24197072451914337, 0.09999999999999998, 0.10000000000000002 };
-
- assert (wf.length == at0.length);
- assert (wf.length == at01.length);
- assert (wf.length == at09.length);
- assert (wf.length == at10.length);
-
- for(int i = 0; i < wf.length; i++) {
- double val0 = wf[i].getWeight(0, 1, 1);
- double val01 = wf[i].getWeight(0.1, 1, 1);
- double val09 = wf[i].getWeight(0.9, 1, 1);
- double val10 = wf[i].getWeight(1.0, 1, 1);
- assertEquals(wf[i].getClass().getSimpleName() + " at 0.0", at0[i], val0, 1e-15);
- assertEquals(wf[i].getClass().getSimpleName() + " at 0.1", at01[i], val01, 1e-15);
- assertEquals(wf[i].getClass().getSimpleName() + " at 0.9", at09[i], val09, 1e-15);
- assertEquals(wf[i].getClass().getSimpleName() + " at 1.0", at10[i], val10, 1e-15);
- }
- }
-
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/geodesy/TestEarthModels.java b/test/de/lmu/ifi/dbs/elki/math/geodesy/TestEarthModels.java
deleted file mode 100644
index 62628512..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/geodesy/TestEarthModels.java
+++ /dev/null
@@ -1,385 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.geodesy;
-
-/*
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test that cross-validates some distance computations with different
- * implementations. Note that it is common to see some difference in these
- * computations, unfortunately - even within R: "sp", "SDMTools" and "geosphere"
- * give different values. But in the end, it's always just an approximation.
- *
- * @author Erich Schubert
- */
-public class TestEarthModels implements JUnit4Test {
- // New York City
- final double[] NEW_YORK = new double[] { 40.67, -73.94 };
-
- // Munich City
- final double[] MUNICH = new double[] { 48.133333, 11.566667 };
-
- // Close to Munich city.
- final double[] MUNICH_AIRPORT = new double[] { 48.353889, 11.786111 };
-
- // Beijing
- final double[] BEIJING = new double[] { 39.913889, 116.391667 };
-
- // Sydney
- final double[] SYDNEY = new double[] { -33.859972, 151.211111 };
-
- // South pole
- final double[] SOUTH = new double[] { -90., 123. };
-
- // North pole
- final double[] NORTH = new double[] { 90., -11. };
-
- // Null
- final double[] NULL = new double[] { 0., 0. };
-
- // Antipodal of New York
- final double[] ANEW_YORK = new double[] { -40.67, 180. + -73.94 };
-
- // The full data set
- final double[][] DATA = new double[][] { NEW_YORK, MUNICH, MUNICH_AIRPORT, BEIJING, SYDNEY, SOUTH, NORTH, ANEW_YORK, NULL };
-
- // Names, for reporting
- final String[] NAMES = new String[] { "New York", "Munich", "Munich Airport", "Beijing", "Sydney", "South Pole", "North Pole", "AnitpodalNY", "Null" };
-
- // Distance matrix, as computed by R "sp" package.
- final double[][] R_SP_WGS84 = new double[][] { //
- { 0.00000000e+00, 6.50366148e+06, 6.50686263e+06, //
- 1.10191059e+07, 1.59817953e+07, 1.44857385e+07, //
- 5.49643716e+06, 2.00089752e+07, 8.65713703e+06, //
- }, //
- { 6.50366148e+06, 0.00000000e+00, 2.94317181e+04, //
- 7.77130051e+06, 1.63129394e+07, 1.53127242e+07, //
- 4.66770838e+06, 1.34974501e+07, 5.44172321e+06, //
- }, //
- { 6.50686263e+06, 2.94317181e+04, 0.00000000e+00, //
- 7.74340170e+06, 1.62922795e+07, 1.53371802e+07, //
- 4.64319863e+06, 1.34940877e+07, 5.46970119e+06, //
- }, //
- { 1.10191059e+07, 7.77130051e+06, 7.74340170e+06, //
- 0.00000000e+00, 8.90595105e+06, 1.44020175e+07, //
- 5.58032509e+06, 8.97021429e+06, 1.22298940e+07, //
- }, //
- { 1.59817953e+07, 1.63129394e+07, 1.62922795e+07, //
- 8.90595105e+06, 0.00000000e+00, 6.25152406e+06, //
- 1.37320772e+07, 4.03034506e+06, 1.52087327e+07, //
- }, //
- { 1.44857385e+07, 1.53127242e+07, 1.53371802e+07, //
- 1.44020175e+07, 6.25152406e+06, 0.00000000e+00, //
- 1.99703264e+07, 5.49643716e+06, 9.99356093e+06, //
- }, //
- { 5.49643716e+06, 4.66770838e+06, 4.64319863e+06, //
- 5.58032509e+06, 1.37320772e+07, 1.99703264e+07, //
- 0.00000000e+00, 1.44857385e+07, 9.99356093e+06, //
- }, //
- { 2.00089752e+07, 1.34974501e+07, 1.34940877e+07, //
- 8.97021429e+06, 4.03034506e+06, 5.49643716e+06, //
- 1.44857385e+07, 0.00000000e+00, 1.13581966e+07, //
- }, //
- { 8.65713703e+06, 5.44172321e+06, 5.46970119e+06, //
- 1.22298940e+07, 1.52087327e+07, 9.99356093e+06, //
- 9.99356093e+06, 1.13581966e+07, 0.00000000e+00, //
- }, //
- };
-
- // Distance matrix, as computed by R "SDMTools" with avoiding segfaults
- final double[][] SDM_WGS84 = new double[][] { //
- { 0.00000000e+00, 6.49607649e+06, 6.49934560e+06, //
- 1.10186899e+07, 1.59618991e+07, 1.45058923e+07, //
- 5.49803918e+06, 1.99845542e+07, 8.64487707e+06, //
- }, //
- { 6.49607649e+06, 0.00000000e+00, 2.94333400e+04, //
- 7.76413413e+06, 1.63019586e+07, 1.53352188e+07, //
- 4.66871262e+06, 1.34959988e+07, 5.44849943e+06, //
- }, //
- { 6.49934560e+06, 2.94333400e+04, 0.00000000e+00, //
- 7.73629144e+06, 1.62815962e+07, 1.53597436e+07, //
- 4.64418788e+06, 1.34928316e+07, 5.47647977e+06, //
- }, //
- { 1.10186899e+07, 7.76413413e+06, 7.73629144e+06, //
- 0.00000000e+00, 8.91481946e+06, 1.44219335e+07, //
- 5.58199793e+06, 8.98486478e+06, 1.22110932e+07, //
- }, //
- { 1.59618991e+07, 1.63019586e+07, 1.62815962e+07, //
- 8.91481946e+06, 0.00000000e+00, 6.25383635e+06, //
- 1.37500951e+07, 4.02274801e+06, 1.51936337e+07, //
- }, //
- { 1.45058923e+07, 1.53352188e+07, 1.53597436e+07, //
- 1.44219335e+07, 6.25383635e+06, 0.00000000e+00, //
- 2.00039315e+07, 5.49803918e+06, 1.00019657e+07, //
- }, //
- { 5.49803918e+06, 4.66871262e+06, 4.64418788e+06, //
- 5.58199793e+06, 1.37500951e+07, 2.00039315e+07, //
- 0.00000000e+00, 1.45058923e+07, 1.00019657e+07, //
- }, //
- { 1.99845542e+07, 1.34959988e+07, 1.34928316e+07, //
- 8.98486478e+06, 4.02274801e+06, 5.49803918e+06, //
- 1.45058923e+07, 0.00000000e+00, 1.13403339e+07, //
- }, //
- { 8.64487707e+06, 5.44849943e+06, 5.47647977e+06, //
- 1.22110932e+07, 1.51936337e+07, 1.00019657e+07, //
- 1.00019657e+07, 1.13403339e+07, 0.00000000e+00, //
- }, //
- };
-
- // Distance matrix, cosine distance in "geosphere" package:
- final double[][] GEOSPHERE_COSINE = new double[][] { //
- { 0.000000000000000e+00, 6.486356338365966e+06, 6.489535193201737e+06, //
- 1.099371420315689e+07, 1.599344217645813e+07, 1.452986159024009e+07, //
- 5.485253480114362e+06, 2.001511507035445e+07, 8.660734833379321e+06, //
- }, //
- { 6.486356338365966e+06, 0.000000000000000e+00, 2.941993519886598e+04, //
- 7.750900176348899e+06, 1.632910711431917e+07, 1.535974752803661e+07, //
- 4.655367542317842e+06, 1.352875873198849e+07, 5.467217714777914e+06, //
- }, //
- { 6.489535193201737e+06, 2.941993519886598e+04, 0.000000000000000e+00, //
- 7.723050836613588e+06, 1.630864631433774e+07, 1.538427227092249e+07, //
- 4.630842799431969e+06, 1.352557987715272e+07, 5.495190660363145e+06, //
- }, //
- { 1.099371420315689e+07, 7.750900176348899e+06, 7.723050836613588e+06, //
- 0.000000000000000e+00, 8.948985711203361e+06, 1.444578576429031e+07, //
- 5.569329306064145e+06, 9.021400867197569e+06, 1.222413440358347e+07, //
- }, //
- { 1.599344217645813e+07, 1.632910711431917e+07, 1.630864631433774e+07, //
- 8.948985711203361e+06, 0.000000000000000e+00, 6.242495113738451e+06, //
- 1.377261995661600e+07, 4.021672893896329e+06, 1.520028800598781e+07, //
- }, //
- { 1.452986159024009e+07, 1.535974752803661e+07, 1.538427227092249e+07, //
- 1.444578576429031e+07, 6.242495113738451e+06, 0.000000000000000e+00, //
- 2.001511507035445e+07, 5.485253480114362e+06, 1.000755753517723e+07, //
- }, //
- { 5.485253480114362e+06, 4.655367542317842e+06, 4.630842799431969e+06, //
- 5.569329306064145e+06, 1.377261995661600e+07, 2.001511507035445e+07, //
- 0.000000000000000e+00, 1.452986159024009e+07, 1.000755753517723e+07, //
- }, //
- { 2.001511507035445e+07, 1.352875873198849e+07, 1.352557987715272e+07, //
- 9.021400867197569e+06, 4.021672893896329e+06, 5.485253480114362e+06, //
- 1.452986159024009e+07, 0.000000000000000e+00, 1.135438023697513e+07, //
- }, //
- { 8.660734833379321e+06, 5.467217714777914e+06, 5.495190660363145e+06, //
- 1.222413440358347e+07, 1.520028800598781e+07, 1.000755753517723e+07, //
- 1.000755753517723e+07, 1.135438023697513e+07, 0.000000000000000e+00, //
- }, //
- };
-
- // Distance matrix, cosine distance in "geosphere" package:
- final double[][] GEOSPHERE_HAVERSINE = new double[][] { //
- { 0.000000000000000e+00, 6.486356338365965e+06, 6.489535193201736e+06, //
- 1.099371420315688e+07, 1.599344217645813e+07, 1.452986159024009e+07, //
- 5.485253480114363e+06, 2.001511507035445e+07, 8.660734833379321e+06, //
- }, //
- { 6.486356338365965e+06, 0.000000000000000e+00, 2.941993519893691e+04, //
- 7.750900176348901e+06, 1.632910711431917e+07, 1.535974752803662e+07, //
- 4.655367542317841e+06, 1.352875873198849e+07, 5.467217714777914e+06, //
- }, //
- { 6.489535193201736e+06, 2.941993519893691e+04, 0.000000000000000e+00, //
- 7.723050836613588e+06, 1.630864631433774e+07, 1.538427227092249e+07, //
- 4.630842799431968e+06, 1.352557987715272e+07, 5.495190660363145e+06, //
- }, //
- { 1.099371420315688e+07, 7.750900176348901e+06, 7.723050836613588e+06, //
- 0.000000000000000e+00, 8.948985711203359e+06, 1.444578576429031e+07, //
- 5.569329306064145e+06, 9.021400867197569e+06, 1.222413440358347e+07, //
- }, //
- { 1.599344217645813e+07, 1.632910711431917e+07, 1.630864631433774e+07, //
- 8.948985711203359e+06, 0.000000000000000e+00, 6.242495113738450e+06, //
- 1.377261995661600e+07, 4.021672893896329e+06, 1.520028800598781e+07, //
- }, //
- { 1.452986159024009e+07, 1.535974752803662e+07, 1.538427227092249e+07, //
- 1.444578576429031e+07, 6.242495113738450e+06, 0.000000000000000e+00, //
- 2.001511507035445e+07, 5.485253480114363e+06, 1.000755753517723e+07, //
- }, //
- { 5.485253480114363e+06, 4.655367542317841e+06, 4.630842799431968e+06, //
- 5.569329306064145e+06, 1.377261995661600e+07, 2.001511507035445e+07, //
- 0.000000000000000e+00, 1.452986159024009e+07, 1.000755753517723e+07, //
- }, //
- { 2.001511507035445e+07, 1.352875873198849e+07, 1.352557987715272e+07, //
- 9.021400867197569e+06, 4.021672893896329e+06, 5.485253480114363e+06, //
- 1.452986159024009e+07, 0.000000000000000e+00, 1.135438023697513e+07, //
- }, //
- { 8.660734833379321e+06, 5.467217714777914e+06, 5.495190660363145e+06, //
- 1.222413440358347e+07, 1.520028800598781e+07, 1.000755753517723e+07, //
- 1.000755753517723e+07, 1.135438023697513e+07, 0.000000000000000e+00, //
- }, //
- };
-
- // Distance matrix, cosine distance in "geosphere" package:
- final double[][] GEOSPHERE_VINCENTY_SPHERE = new double[][] { //
- { 0.000000000000000e+00, 6.486356338365965e+06, 6.489535193201737e+06, //
- 1.099371420315689e+07, 1.599344217645813e+07, 1.452986159024009e+07, //
- 5.485253480114362e+06, 2.001511507035445e+07, 8.660734833379321e+06, //
- }, //
- { 6.486356338365966e+06, 0.000000000000000e+00, 2.941993519893652e+04, //
- 7.750900176348899e+06, 1.632910711431917e+07, 1.535974752803661e+07, //
- 4.655367542317842e+06, 1.352875873198849e+07, 5.467217714777914e+06, //
- }, //
- { 6.489535193201737e+06, 2.941993519893681e+04, 0.000000000000000e+00, //
- 7.723050836613588e+06, 1.630864631433774e+07, 1.538427227092249e+07, //
- 4.630842799431969e+06, 1.352557987715272e+07, 5.495190660363145e+06, //
- }, //
- { 1.099371420315689e+07, 7.750900176348899e+06, 7.723050836613588e+06, //
- 0.000000000000000e+00, 8.948985711203361e+06, 1.444578576429031e+07, //
- 5.569329306064145e+06, 9.021400867197569e+06, 1.222413440358347e+07, //
- }, //
- { 1.599344217645813e+07, 1.632910711431917e+07, 1.630864631433774e+07, //
- 8.948985711203361e+06, 0.000000000000000e+00, 6.242495113738451e+06, //
- 1.377261995661600e+07, 4.021672893896329e+06, 1.520028800598781e+07, //
- }, //
- { 1.452986159024009e+07, 1.535974752803661e+07, 1.538427227092249e+07, //
- 1.444578576429031e+07, 6.242495113738451e+06, 0.000000000000000e+00, //
- 2.001511507035445e+07, 5.485253480114362e+06, 1.000755753517723e+07, //
- }, //
- { 5.485253480114362e+06, 4.655367542317842e+06, 4.630842799431969e+06, //
- 5.569329306064145e+06, 1.377261995661600e+07, 2.001511507035445e+07, //
- 0.000000000000000e+00, 1.452986159024009e+07, 1.000755753517723e+07, //
- }, //
- { 2.001511507035445e+07, 1.352875873198849e+07, 1.352557987715272e+07, //
- 9.021400867197569e+06, 4.021672893896328e+06, 5.485253480114362e+06, //
- 1.452986159024009e+07, 0.000000000000000e+00, 1.135438023697513e+07, //
- }, //
- { 8.660734833379321e+06, 5.467217714777914e+06, 5.495190660363145e+06, //
- 1.222413440358347e+07, 1.520028800598781e+07, 1.000755753517723e+07, //
- 1.000755753517723e+07, 1.135438023697513e+07, 0.000000000000000e+00, //
- }, //
- };
-
- // Distance matrix, cosine distance in "geosphere" package:
- final double[][] GEOSPHERE_VINCENTY_WGS84 = new double[][] { //
- { 0.000000000000000e+00, 6.503767848090770e+06, 6.506974602807214e+06, //
- 1.101910369872154e+07, 1.599270764104164e+07, 1.450589228275554e+07, //
- 5.498039175797141e+06, Double.NaN, 8.661075093360968e+06, //
- }, //
- { 6.503767848090770e+06, 0.000000000000000e+00, 2.944678565227988e+04, //
- 7.771413604903577e+06, 1.632562828361734e+07, 1.533521883690098e+07, //
- 4.668712621651703e+06, 1.351202375815323e+07, 5.449076622477260e+06, //
- }, //
- { 6.506974602807214e+06, 2.944678565227961e+04, 0.000000000000000e+00, //
- 7.743520548885130e+06, 1.630501450760304e+07, 1.535974357438163e+07, //
- 4.644187884171052e+06, 1.350871506702908e+07, 5.477072159975932e+06, //
- }, //
- { 1.101910369872154e+07, 7.771413604903577e+06, 7.743520548885130e+06, //
- 0.000000000000000e+00, 8.918923554119145e+06, 1.442193352759095e+07, //
- 5.581997930961725e+06, 8.985204289439090e+06, 1.223306246456788e+07, //
- }, //
- { 1.599270764104165e+07, 1.632562828361734e+07, 1.630501450760304e+07, //
- 8.918923554119145e+06, 0.000000000000000e+00, 6.253836350029638e+06, //
- 1.375009510852304e+07, 4.030502513001381e+06, 1.521100587039189e+07, //
- }, //
- { 1.450589228275554e+07, 1.533521883690098e+07, 1.535974357438163e+07, //
- 1.442193352759095e+07, 6.253836350029638e+06, 0.000000000000000e+00, //
- 2.000393145855268e+07, 5.498039175797141e+06, 1.000196572927634e+07, //
- }, //
- { 5.498039175797141e+06, 4.668712621651703e+06, 4.644187884171051e+06, //
- 5.581997930961725e+06, 1.375009510852304e+07, 2.000393145855268e+07, //
- 0.000000000000000e+00, 1.450589228275554e+07, 1.000196572927634e+07, //
- }, //
- { Double.NaN, 1.351202375815323e+07, 1.350871506702908e+07, //
- 8.985204289439090e+06, 4.030502513001381e+06, 5.498039175797141e+06, //
- 1.450589228275554e+07, 0.000000000000000e+00, 1.136156548644650e+07, //
- }, //
- { 8.661075093360968e+06, 5.449076622477260e+06, 5.477072159975932e+06, //
- 1.223306246456788e+07, 1.521100587039189e+07, 1.000196572927634e+07, //
- 1.000196572927634e+07, 1.136156548644650e+07, 0.000000000000000e+00, //
- }, //
- };
-
- @Test
- public void testWGS84SpheroidEarth() {
- // WGS84 Vincenty to WGS84 Haversine: .3% error on test set.
- testEarthModel(WGS84SpheroidEarthModel.STATIC, R_SP_WGS84, .00316, 1e-12);
- // WGS84 Vincenty to WGS84 Vincenty: also .2% error on test set.
- testEarthModel(WGS84SpheroidEarthModel.STATIC, SDM_WGS84, .001936, 1e-12);
- // WGS84 Vincenty to WGS84 Vincenty: with "geosphere" we have a high
- // agreement.
- testEarthModel(WGS84SpheroidEarthModel.STATIC, GEOSPHERE_VINCENTY_WGS84, 6.1763e-12, 1e-12);
- }
-
- @Test
- public void testHaversineEarth() {
- // Spherical Haversine to WGS84 Haversine: .6% error on test set.
- testEarthModel(SphericalHaversineEarthModel.STATIC, R_SP_WGS84, .005674, 1e-12);
- // Spherical Haversine to WGS84 Vincenty: .4% error on test set.
- testEarthModel(SphericalHaversineEarthModel.STATIC, SDM_WGS84, .00405, 1e-12);
- // WGS84 Vincenty to WGS84 Vincenty: with "geosphere" we have a high
- // agreement.
- testEarthModel(SphericalHaversineEarthModel.STATIC, GEOSPHERE_HAVERSINE, 6.662e-16, 1e-12);
- }
-
- @Test
- public void testCosineEarth() {
- // Spherical Cosine to WGS84 Haversine: 0% error on test set.
- testEarthModel(SphericalCosineEarthModel.STATIC, R_SP_WGS84, .005674, 0.0);
- // Spherical Cosine to WGS84 Vincenty: 0% error on test set.
- testEarthModel(SphericalCosineEarthModel.STATIC, SDM_WGS84, .00405, 0.0);
- // Spherical Cosine to Cosine: with "geosphere" we have a high agreement.
- testEarthModel(SphericalCosineEarthModel.STATIC, GEOSPHERE_COSINE, 4.4409e-16, 1e-12);
- }
-
- @Test
- public void testSphericalEarth() {
- // Spherical Vincenty to WGS84 Haversine: .6% error on test set.
- testEarthModel(SphericalVincentyEarthModel.STATIC, R_SP_WGS84, .005674, 1e-12);
- // Spherical Vincenty to WGS84 Vincenty: .4% error on test set.
- testEarthModel(SphericalVincentyEarthModel.STATIC, SDM_WGS84, .00405, 1e-12);
- // Spherical Vincenty to Spherical Vincenty: with "geosphere" we have a high
- // agreement.
- testEarthModel(SphericalVincentyEarthModel.STATIC, GEOSPHERE_VINCENTY_SPHERE, 4.441e-16, 1e-12);
- }
-
- protected void testEarthModel(EarthModel model, final double[][] ref, final double relerror, final double abserror) {
- double maxrel = 0.0, maxabs = 0.0;
- for (int i = 0; i < DATA.length; i++) {
- for (int j = i; j < DATA.length; j++) {
- if (Double.isNaN(ref[i][j])) {
- continue;
- }
- double d = model.distanceDeg(DATA[i][0], DATA[i][1], DATA[j][0], DATA[j][1]);
- assertFalse("NaN in distance " + NAMES[i] + " to " + NAMES[j], Double.isNaN(d));
- double test = (d > 0) ? (ref[i][j] / d) : (ref[i][j] - d + 1.0);
- if (Math.abs(d - ref[i][j]) > abserror) {
- if (Math.abs(test - 1.0) > relerror) {
- assertEquals("Distances do not agree for " + NAMES[i] + " to " + NAMES[j] + " " + Math.abs(test - 1.0), ref[i][j], d, abserror);
- }
- if (Math.abs(test - 1.0) > maxrel) {
- maxrel = Math.abs(test - 1.0);
- }
- } else {
- if (Math.abs(ref[i][j] - d) > maxabs) {
- maxabs = Math.abs(ref[i][j] - d);
- }
- }
- }
- }
- assertEquals("Relative error bound not tight.", maxrel, relerror, 1e-3 * relerror + 1e-12);
- assertEquals("Absolute error bound not tight.", maxabs, abserror, 1e-3 * abserror + 1e-12);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/geometry/TestPrimsMinimumSpanningTree.java b/test/de/lmu/ifi/dbs/elki/math/geometry/TestPrimsMinimumSpanningTree.java
deleted file mode 100644
index c8252a26..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/geometry/TestPrimsMinimumSpanningTree.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.geometry;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Test class for Prim's minmum spanning tree algorithm.
- *
- * @author Erich Schubert
- */
-public class TestPrimsMinimumSpanningTree implements JUnit4Test {
- @Test
- public void testSimple() {
- // A simple test.
- final double inf = Double.POSITIVE_INFINITY;
- double[][] mat = new double[][] {//
- { 0.0, 7.0, inf, 5.0, inf, inf, inf }, //
- { 7.0, 0.0, 8.0, 9.0, 7.0, inf, inf }, //
- { inf, 8.0, 0.0, inf, 5.0, inf, inf }, //
- { 5.0, 9.0, inf, 0.0, 15., 6.0, inf }, //
- { inf, 7.0, 5.0, 15., 0.0, 8.0, 9.0 }, //
- { inf, inf, inf, 6.0, 8.0, 0.0, 11. }, //
- { inf, inf, inf, inf, 9.0, 11., 0.0 }, //
- };
- int[] ret = PrimsMinimumSpanningTree.processDense(mat);
- // "correct" edges (ignore order and direction!)
- int[] correct = new int[] { 0, 1, 0, 3, 1, 4, 2, 4, 4, 6, 3, 5 };
- assertEquals("Graph size does not match expected size.", correct.length, ret.length);
-
- // Flags so we find edges only once.
- int[] flags = new int[correct.length];
- for (int i = 0; i < ret.length; i += 2) {
- boolean found = false;
- for (int j = 0; j < correct.length; j += 2) {
- if (flags[j] == 1) {
- continue;
- }
- if ((correct[j] == ret[i] && correct[j + 1] == ret[i + 1]) || (correct[j] == ret[i + 1] && correct[j + 1] == ret[i])) {
- found = true;
- flags[j] = 1;
- break;
- }
- }
- assertTrue("Edge not found: " + (char) ('A' + ret[i]) + " -> " + (char) ('A' + ret[i + 1]), found);
- }
- }
- // We could also check that every even flag is set. But as we checked the
- // length and found all edges, all must have been used...
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/scales/TestLinearScale.java b/test/de/lmu/ifi/dbs/elki/math/scales/TestLinearScale.java
deleted file mode 100644
index f593902c..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/scales/TestLinearScale.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.scales;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.math.scales.LinearScale;
-
-/**
- * Test class to test rounding of the linear scale.
- *
- * @author Erich Schubert
- *
- */
-public class TestLinearScale implements JUnit4Test {
-
- /**
- * Produces a simple linear scale and verifies the tick lines are placed as
- * expected.
- */
- @Test
- public final void testLinearScale() {
- LinearScale a = new LinearScale(3, 97);
- assertEquals("Minimum for scale 3-97 not as expected.", 0.0, a.getMin(), Double.MIN_VALUE);
- assertEquals("Maximum for scale 3-97 not as expected.", 100.0, a.getMax(), Double.MIN_VALUE);
-
- LinearScale b = new LinearScale(-97, -3);
- assertEquals("Minimum for scale -97 : -3 not as expected.", -100.0, b.getMin(), Double.MIN_VALUE);
- assertEquals("Maximum for scale -97 : -3 not as expected.", 0.0, b.getMax(), Double.MIN_VALUE);
-
- LinearScale c = new LinearScale(-3, 37);
- assertEquals("Minimum for scale -3 : 37 not as expected.", -10.0, c.getMin(), Double.MIN_VALUE);
- assertEquals("Maximum for scale -3 : 37 not as expected.", 40.0, c.getMax(), Double.MIN_VALUE);
-
- LinearScale d = new LinearScale(-37, 3);
- assertEquals("Minimum for scale -37 : 3 not as expected.", -40.0, d.getMin(), Double.MIN_VALUE);
- assertEquals("Maximum for scale -37 : 3 not as expected.", 10.0, d.getMax(), Double.MIN_VALUE);
- }
-
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistributionTest.java b/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistributionTest.java
deleted file mode 100644
index 63a19072..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistributionTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Abstract base class for distribution unit testing.
- *
- * @author Erich Schubert
- */
-public class AbstractDistributionTest {
- public void checkPDF(Distribution d, double[] x, double[] expected, double err) {
- int maxerrlev = -15;
- for(int i = 0; i < x.length; i++) {
- double val = d.pdf(x[i]);
- if(val == expected[i]) {
- continue;
- }
- double diff = Math.abs(val - expected[i]);
- final int errlev = (int) Math.ceil(Math.log10(diff / expected[i]));
- maxerrlev = Math.max(errlev, maxerrlev);
- if(diff < err || diff / expected[i] < err) {
- continue;
- }
- assertEquals("Error magnitude: 1e" + errlev + " at " + x[i], expected[i], val, err);
- }
- int given = (int) Math.floor(Math.log10(err * 1.1));
- assertTrue("Error magnitude is not tight: measured " + maxerrlev + " specified " + given, given <= maxerrlev);
- }
-
- public void checkCDF(Distribution d, double[] x, double[] expected, double err) {
- int maxerrlev = -15;
- for(int i = 0; i < x.length; i++) {
- double val = d.cdf(x[i]);
- if(val == expected[i]) {
- continue;
- }
- double diff = Math.abs(val - expected[i]);
- final int errlev = (int) Math.ceil(Math.log10(diff / expected[i]));
- maxerrlev = Math.max(errlev, maxerrlev);
- if(diff < err || diff / expected[i] < err) {
- continue;
- }
- assertEquals("Error magnitude: 1e" + errlev + " at " + x[i], expected[i], val, err);
- }
- int given = (int) Math.floor(Math.log10(err * 1.1));
- assertTrue("Error magnitude is not tight: measured " + maxerrlev + " specified " + given, given <= maxerrlev);
- }
-
- public void checkQuantile(Distribution d, double[] x, double[] expected, double err) {
- int maxerrlev = -15;
- for(int i = 0; i < x.length; i++) {
- if(Double.isNaN(expected[i])) {
- continue;
- }
- double val = d.quantile(x[i]);
- if(val == expected[i]) {
- continue;
- }
- double diff = Math.abs(val - expected[i]);
- final int errlev = (int) Math.ceil(Math.log10(diff / expected[i]));
- maxerrlev = Math.max(errlev, maxerrlev);
- if(diff < err || diff / expected[i] < err) {
- continue;
- }
- assertEquals("Error magnitude: 1e" + errlev + " at " + x[i], expected[i], val, err);
- }
- int given = (int) Math.floor(Math.log10(err * 1.1));
- assertTrue("Error magnitude is not tight: measured " + maxerrlev + " specified " + given, given <= maxerrlev);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestBetaDistribution.java b/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestBetaDistribution.java
deleted file mode 100644
index 8746ea8b..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestBetaDistribution.java
+++ /dev/null
@@ -1,3939 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for the Beta distribution in ELKI.
- *
- * The reference values were computed using GNU R and SciPy.
- *
- * @author Erich Schubert
- */
-public class TestBetaDistribution extends AbstractDistributionTest implements JUnit4Test {
- public static final double[] P_CDFPDF = { //
- 1e-10, 1e-05, 0.1, 0.1234567, 0.2, 0.271828182846, 0.3, 0.314159265359, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.71828182846, 3.14159265359 //
- };
-
- public static final double[] SCIPY_BETA_CDF_01_01 = { //
- 5.07237274393781481518495013460778864100575447082520e-02, // 0.000000
- 1.60402641359773445728365004470106214284896850585938e-01, // 0.000010
- 4.06385093936275976211902616341831162571907043457031e-01, // 0.100000
- 4.15927737016427878646851468147360719740390777587891e-01, // 0.123457
- 4.39709190223345591785886199431843124330043792724609e-01, // 0.200000
- 4.56830072616762117299060719233239069581031799316406e-01, // 0.271828
- 4.62804186115552074198831178364343941211700439453125e-01, // 0.300000
- 4.65695944978432807559443062928039580583572387695312e-01, // 0.314159
- 4.82120045609327974034385988488793373107910156250000e-01, // 0.400000
- 4.99999999999999888977697537484345957636833190917969e-01, // 0.500000
- 5.17879954390672025965614011511206626892089843750000e-01, // 0.600000
- 5.37195813884447925801168821635656058788299560546875e-01, // 0.700000
- 5.60290809776654241680660106794675812125205993652344e-01, // 0.800000
- 5.93614906063723468676585071079898625612258911132812e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_01_01 = { //
- 5.07237274435283020138740539550781250000000000000000e+07, // 0.000000
- 1.60403953757008639513514935970306396484375000000000e+03, // 0.000010
- 4.42988958666523380269808285447652451694011688232422e-01, // 0.100000
- 3.75276980422167505402342158049577847123146057128906e-01, // 0.123457
- 2.63938762316794750528714530446450226008892059326172e-01, // 0.200000
- 2.17939347824759516170090023479133378714323043823242e-01, // 0.271828
- 2.06639715373252902397283037316810805350542068481445e-01, // 0.300000
- 2.01918135102394286084503960410074796527624130249023e-01, // 0.314159
- 1.83240320487424945827825695232604630291461944580078e-01, // 0.400000
- 1.76630277977873700878674867453810293227434158325195e-01, // 0.500000
- 1.83240320487424945827825695232604630291461944580078e-01, // 0.600000
- 2.06639715373252874641707421687897294759750366210938e-01, // 0.700000
- 2.63938762316794861551016992962104268372058868408203e-01, // 0.800000
- 4.42988958666523491292110747963306494057178497314453e-01, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_01_01 = { //
- 5.07237274393781412129555974388495087623596191406250e-02, // 0.000000
- 1.60402641359773390217213773212279193103313446044922e-01, // 0.000010
- 4.06385093936275865189600153826177120208740234375000e-01, // 0.100000
- 4.15927737016427712113397774373879656195640563964844e-01, // 0.123457
- 4.39709190223345480763583736916189081966876983642578e-01, // 0.200000
- 4.56830072616782767447318747144890949130058288574219e-01, // 0.271828
- 4.62804186115551741131923790817381814122200012207031e-01, // 0.300000
- 4.65695944978436748851180482233758084475994110107422e-01, // 0.314159
- 4.82120045609327474434024907168350182473659515380859e-01, // 0.400000
- 4.99999999999999500399638918679556809365749359130859e-01, // 0.500000
- 5.17879954390672470054823861573822796344757080078125e-01, // 0.600000
- 5.37195813884448258868076209182618185877799987792969e-01, // 0.700000
- 5.60290809776654574747567494341637939214706420898438e-01, // 0.800000
- 5.93614906063724134810399846173822879791259765625000e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_01_01 = { //
- 5.07237274435282945632934570312500000000000000000000e+07, // 0.000000
- 1.60403953757008684988250024616718292236328125000000e+03, // 0.000010
- 4.42988958666523380269808285447652451694011688232422e-01, // 0.100000
- 3.75276980422167782958098314338712953031063079833984e-01, // 0.123457
- 2.63938762316794861551016992962104268372058868408203e-01, // 0.200000
- 2.17939347824716384005583336147537920624017715454102e-01, // 0.271828
- 2.06639715373252930152858652945724315941333770751953e-01, // 0.300000
- 2.01918135102387819035385518873226828873157501220703e-01, // 0.314159
- 1.83240320487424973583401310861518140882253646850586e-01, // 0.400000
- 1.76630277977873756389826098711637314409017562866211e-01, // 0.500000
- 1.83240320487424973583401310861518140882253646850586e-01, // 0.600000
- 2.06639715373252930152858652945724315941333770751953e-01, // 0.700000
- 2.63938762316794917062168224219931289553642272949219e-01, // 0.800000
- 4.42988958666523602314413210478960536420345306396484e-01, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_01_05 = { //
- 8.83151389893383070850418903319223318248987197875977e-02, // 0.000000
- 2.79277118023966042237304918671725317835807800292969e-01, // 0.000010
- 7.04833622051221020399225380970165133476257324218750e-01, // 0.100000
- 7.20681507439501545242421798320719972252845764160156e-01, // 0.123457
- 7.59304219445318007153389316954417154192924499511719e-01, // 0.200000
- 7.86085328767555213680395809205947443842887878417969e-01, // 0.271828
- 7.95176530367367906393383236718364059925079345703125e-01, // 0.300000
- 7.99524278991131209792797562840860337018966674804688e-01, // 0.314159
- 8.23494838536657169925092603079974651336669921875000e-01, // 0.400000
- 8.48001712399770513073349320620764046907424926757812e-01, // 0.500000
- 8.70603436980005307432861627603415399789810180664062e-01, // 0.600000
- 8.92658587836405614801549290859838947653770446777344e-01, // 0.700000
- 9.15640640375003589390701108641223981976509094238281e-01, // 0.800000
- 9.42366288315789946139489074994344264268875122070312e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_01_05 = { //
- 8.83151389933526813983917236328125000000000000000000e+07, // 0.000000
- 2.79278387474808914703316986560821533203125000000000e+03, // 0.000010
- 7.39458664410644117559456844901433214545249938964844e-01, // 0.100000
- 6.19848096459823749704298734286567196249961853027344e-01, // 0.123457
- 4.20303655461324865427741315215826034545898437500000e-01, // 0.200000
- 3.34235972869352193637126902103773318231105804443359e-01, // 0.271828
- 3.11944266317603025040483544216840527951717376708984e-01, // 0.300000
- 3.02335144044583059574904382316162809729576110839844e-01, // 0.314159
- 2.60079151351645165846093732398003339767456054687500e-01, // 0.400000
- 2.33065049073819779978933297570620197802782058715820e-01, // 0.500000
- 2.21140881157234348020068637197255156934261322021484e-01, // 0.600000
- 2.22272786172716479979882819861813914030790328979492e-01, // 0.700000
- 2.41401058813832225524720342946238815784454345703125e-01, // 0.800000
- 3.07055512274369113434602240886306390166282653808594e-01, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_01_05 = { //
- 8.83151389893382793294662747030088212341070175170898e-02, // 0.000000
- 2.79277118023966042237304918671725317835807800292969e-01, // 0.000010
- 7.04833622051220909376922918454511091113090515136719e-01, // 0.100000
- 7.20681507439501323197816873289411887526512145996094e-01, // 0.123457
- 7.59304219445317896131086854438763111829757690429688e-01, // 0.200000
- 7.86085328767586744014295163651695474982261657714844e-01, // 0.271828
- 7.95176530367367462304173386655747890472412109375000e-01, // 0.300000
- 7.99524278991137093974828076170524582266807556152344e-01, // 0.314159
- 8.23494838536657169925092603079974651336669921875000e-01, // 0.400000
- 8.48001712399770513073349320620764046907424926757812e-01, // 0.500000
- 8.70603436980005307432861627603415399789810180664062e-01, // 0.600000
- 8.92658587836405725823851753375492990016937255859375e-01, // 0.700000
- 9.15640640375003700413003571156878024339675903320312e-01, // 0.800000
- 9.42366288315790390228698925056960433721542358398438e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_01_05 = { //
- 8.83151389933526664972305297851562500000000000000000e+07, // 0.000000
- 2.79278387474808823753846809267997741699218750000000e+03, // 0.000010
- 7.39458664410643895514851919870125129818916320800781e-01, // 0.100000
- 6.19848096459823971748903659317875280976295471191406e-01, // 0.123457
- 4.20303655461324865427741315215826034545898437500000e-01, // 0.200000
- 3.34235972869268427309918934042798355221748352050781e-01, // 0.271828
- 3.11944266317603025040483544216840527951717376708984e-01, // 0.300000
- 3.02335144044569681387457649179850704967975616455078e-01, // 0.314159
- 2.60079151351645221357244963655830360949039459228516e-01, // 0.400000
- 2.33065049073819752223357681941706687211990356445312e-01, // 0.500000
- 2.21140881157234375775644252826168667525053024291992e-01, // 0.600000
- 2.22272786172716479979882819861813914030790328979492e-01, // 0.700000
- 2.41401058813832253280295958575152326375246047973633e-01, // 0.800000
- 3.07055512274369168945753472144133411347866058349609e-01, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_01_1 = { //
- 1.00000000000000019428902930940239457413554191589355e-01, // 0.000000
- 3.16227766016837996687627310166135430335998535156250e-01, // 0.000010
- 7.94328234724281712075821815233211964368820190429688e-01, // 0.100000
- 8.11243941442105320760447284555993974208831787109375e-01, // 0.123457
- 8.51339922520784830872742077190196141600608825683594e-01, // 0.200000
- 8.77868464423642858029950275522423908114433288574219e-01, // 0.271828
- 8.86568150565213541902664928784361109137535095214844e-01, // 0.300000
- 8.90666232270154401007289379776921123266220092773438e-01, // 0.314159
- 9.12443536555481049532545512192882597446441650390625e-01, // 0.400000
- 9.33032991536807632115824162610806524753570556640625e-01, // 0.500000
- 9.50200216505676653611089932383038103580474853515625e-01, // 0.600000
- 9.64961095119817868770439872605493292212486267089844e-01, // 0.700000
- 9.77932768542928765320709771913243457674980163574219e-01, // 0.800000
- 9.89519258206214669115752258221618831157684326171875e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_01_1 = { //
- 1.00000000000000059604644775390625000000000000000000e+08, // 0.000000
- 3.16227766016838040741276927292346954345703125000000e+03, // 0.000010
- 7.94328234724281601053519352717557922005653381347656e-01, // 0.100000
- 6.57108072256997965965297225920949131250381469726562e-01, // 0.123457
- 4.25669961260392415436371038595098070800304412841797e-01, // 0.200000
- 3.22949760114201955829571488720830529928207397460938e-01, // 0.271828
- 2.95522716855071199137938720014062710106372833251953e-01, // 0.300000
- 2.83507867021658532813432884722715243697166442871094e-01, // 0.314159
- 2.28110884138870234627560762419307138770818710327148e-01, // 0.400000
- 1.86606598307361509769819463144813198596239089965820e-01, // 0.500000
- 1.58366702750946081179606039768259506672620773315430e-01, // 0.600000
- 1.37851585017116834430694893853797111660242080688477e-01, // 0.700000
- 1.22241596067866081787300913674698676913976669311523e-01, // 0.800000
- 1.09946584245134940105437237889418611302971839904785e-01, // 0.900000
- 1.00000000000000019428902930940239457413554191589355e-01, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_01_1 = { //
- 9.99999999999999777955395074968691915273666381835938e-02, // 0.000000
- 3.16227766016837885665324847650481387972831726074219e-01, // 0.000010
- 7.94328234724281379008914427686249837279319763183594e-01, // 0.100000
- 8.11243941442104987693539897009031847119331359863281e-01, // 0.123457
- 8.51339922520784497805834689643234014511108398437500e-01, // 0.200000
- 8.77868464423673389163127467327285557985305786132812e-01, // 0.271828
- 8.86568150565213208835757541237398982048034667968750e-01, // 0.300000
- 8.90666232270159952122412505559623241424560546875000e-01, // 0.314159
- 9.12443536555480938510243049677228555083274841308594e-01, // 0.400000
- 9.33032991536807410071219237579498440027236938476562e-01, // 0.500000
- 9.50200216505676431566485007351730018854141235351562e-01, // 0.600000
- 9.64961095119817535703532485058531165122985839843750e-01, // 0.700000
- 9.77932768542928543276104846881935372948646545410156e-01, // 0.800000
- 9.89519258206214447071147333190310746431350708007812e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_01_1 = { //
- 9.99999999999998211860656738281250000000000000000000e+07, // 0.000000
- 3.16227766016838040741276927292346954345703125000000e+03, // 0.000010
- 7.94328234724281601053519352717557922005653381347656e-01, // 0.100000
- 6.57108072256998076987599688436603173613548278808594e-01, // 0.123457
- 4.25669961260392415436371038595098070800304412841797e-01, // 0.200000
- 3.22949760114099870822457205576938576996326446533203e-01, // 0.271828
- 2.95522716855071199137938720014062710106372833251953e-01, // 0.300000
- 2.83507867021641657423458582343300804495811462402344e-01, // 0.314159
- 2.28110884138870234627560762419307138770818710327148e-01, // 0.400000
- 1.86606598307361537525395078773726709187030792236328e-01, // 0.500000
- 1.58366702750946108935181655397173017263412475585938e-01, // 0.600000
- 1.37851585017116834430694893853797111660242080688477e-01, // 0.700000
- 1.22241596067866095665088721489155432209372520446777e-01, // 0.800000
- 1.09946584245134940105437237889418611302971839904785e-01, // 0.900000
- 1.00000000000000005551115123125782702118158340454102e-01, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_01_2 = { //
- 1.09999999998999994921256018187705194577574729919434e-01, // 0.000000
- 3.47850226390755745686789168757968582212924957275391e-01, // 0.000010
- 8.65817775849466841897594804322579875588417053222656e-01, // 0.100000
- 8.82352985595772132398906251182779669761657714843750e-01, // 0.123457
- 9.19447116322447466352230094344122335314750671386719e-01, // 0.200000
- 9.41792371919806692304177886398974806070327758789062e-01, // 0.271828
- 9.48627921104778337735297100152820348739624023437500e-01, // 0.300000
- 9.51751750576165678197071429167408496141433715820312e-01, // 0.314159
- 9.67190148748809930268066636926960200071334838867188e-01, // 0.400000
- 9.79684641113647836085931430716300383210182189941406e-01, // 0.500000
- 9.88208225165903453302007619640789926052093505859375e-01, // 0.600000
- 9.93909927973412155033372528123436495661735534667969e-01, // 0.700000
- 9.97491423913787089716720402066130191087722778320312e-01, // 0.800000
- 9.99414450788276509385354984260629862546920776367188e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_01_2 = { //
- 1.09999999989000067114830017089843750000000000000000e+08, // 0.000000
- 3.47847064113095666471053846180438995361328125000000e+03, // 0.000010
- 7.86384952377038759507854592811781913042068481445312e-01, // 0.100000
- 6.33582045924066195041746141214389353990554809570312e-01, // 0.123457
- 3.74589565909145327804452563213999383151531219482422e-01, // 0.200000
- 2.58679205039021475887039969165925867855548858642578e-01, // 0.271828
- 2.27552491978404769490396120090736076235771179199219e-01, // 0.300000
- 2.13885368174107387551075021292490419000387191772461e-01, // 0.314159
- 1.50553183531654338755956246131972875446081161499023e-01, // 0.400000
- 1.02633629069048826210064362385310232639312744140625e-01, // 0.500000
- 6.96813492104162851559223668118647765368223190307617e-02, // 0.600000
- 4.54910230556485536967947780340182362124323844909668e-02, // 0.700000
- 2.68931511349305325808689559607955743558704853057861e-02, // 0.800000
- 1.20941242669648403584847784486555610783398151397705e-02, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_01_2 = { //
- 1.09999999998999994921256018187705194577574729919434e-01, // 0.000000
- 3.47850226390755745686789168757968582212924957275391e-01, // 0.000010
- 8.65817775849466841897594804322579875588417053222656e-01, // 0.100000
- 8.82352985595771910354301326151471585035324096679688e-01, // 0.123457
- 9.19447116322447355329927631828468292951583862304688e-01, // 0.200000
- 9.41792371919831339255324564874172210693359375000000e-01, // 0.271828
- 9.48627921104778337735297100152820348739624023437500e-01, // 0.300000
- 9.51751750576169897044565004762262105941772460937500e-01, // 0.314159
- 9.67190148748809708223461711895652115345001220703125e-01, // 0.400000
- 9.79684641113647725063628968200646340847015380859375e-01, // 0.500000
- 9.88208225165903453302007619640789926052093505859375e-01, // 0.600000
- 9.93909927973412155033372528123436495661735534667969e-01, // 0.700000
- 9.97491423913787089716720402066130191087722778320312e-01, // 0.800000
- 9.99414450788276509385354984260629862546920776367188e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_01_2 = { //
- 1.09999999989000082015991210937500000000000000000000e+08, // 0.000000
- 3.47847064113095257198438048362731933593750000000000e+03, // 0.000010
- 7.86384952377038648485552130296127870678901672363281e-01, // 0.100000
- 6.33582045924066306064048603730043396353721618652344e-01, // 0.123457
- 3.74589565909145272293301331956172361969947814941406e-01, // 0.200000
- 2.58679205038905735136722796596586704254150390625000e-01, // 0.271828
- 2.27552491978404825001547351348563097417354583740234e-01, // 0.300000
- 2.13885368174088180692749006084341090172529220581055e-01, // 0.314159
- 1.50553183531654338755956246131972875446081161499023e-01, // 0.400000
- 1.02633629069048826210064362385310232639312744140625e-01, // 0.500000
- 6.96813492104162851559223668118647765368223190307617e-02, // 0.600000
- 4.54910230556485675745825858484749915078282356262207e-02, // 0.700000
- 2.68931511349305360503159079144097631797194480895996e-02, // 0.800000
- 1.20941242669648386237613024718484666664153337478638e-02, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_01_4 = { //
- 1.19349999996744948749238801610772497951984405517578e-01, // 0.000000
- 3.77416809425109245346163788781268522143363952636719e-01, // 0.000010
- 9.23499112106322184168050171138020232319831848144531e-01, // 0.100000
- 9.37669077635512548951624012261163443326950073242188e-01, // 0.123457
- 9.66195894147908407312286271917400881648063659667969e-01, // 0.200000
- 9.80442982290223752350755148654570803046226501464844e-01, // 0.271828
- 9.84228508474799701488677783345337957143783569335938e-01, // 0.300000
- 9.85856268655784573340383758477400988340377807617188e-01, // 0.314159
- 9.92844411222603584477042204525787383317947387695312e-01, // 0.400000
- 9.97004066019049783875516368425451219081878662109375e-01, // 0.500000
- 9.98911280404623402873198756424244493246078491210938e-01, // 0.600000
- 9.99689562452632296540855350031051784753799438476562e-01, // 0.700000
- 9.99944079297292787167350525123765692114830017089844e-01, // 0.800000
- 9.99996782871730882646943427971564233303070068359375e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_01_4 = { //
- 1.19349999964195013046264648437500000000000000000000e+08, // 0.000000
- 3.77406516319158845362835563719272613525390625000000e+03, // 0.000010
- 6.91114415396560266557912655116524547338485717773438e-01, // 0.100000
- 5.28176834178893939153454084589611738920211791992188e-01, // 0.123457
- 2.60114994567310409134819337850785814225673675537109e-01, // 0.200000
- 1.48819207734607078519317724385473411530256271362305e-01, // 0.271828
- 1.20978282360318822874489796959096565842628479003906e-01, // 0.300000
- 1.09158451358456268232011154850624734535813331604004e-01, // 0.314159
- 5.88060734874641527492045156577660236507654190063477e-02, // 0.400000
- 2.78393718849794802316921504825586453080177307128906e-02, // 0.500000
- 1.20966822229282636169678255555481882765889167785645e-02, // 0.600000
- 4.44219840138408098711986227158377005252987146377563e-03, // 0.700000
- 1.16716275925598405617533703804156175465323030948639e-03, // 0.800000
- 1.31221248296568387655194887209120224724756553769112e-04, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_01_4 = { //
- 1.19349999996745004260390032868599519133567810058594e-01, // 0.000000
- 3.77416809425109411879617482554749585688114166259766e-01, // 0.000010
- 9.23499112106322628257260021200636401772499084472656e-01, // 0.100000
- 9.37669077635512770996228937292471528053283691406250e-01, // 0.123457
- 9.66195894147908740379193659464363008737564086914062e-01, // 0.200000
- 9.80442982290238074227772813173942267894744873046875e-01, // 0.271828
- 9.84228508474799701488677783345337957143783569335938e-01, // 0.300000
- 9.85856268655786793786433008790481835603713989257812e-01, // 0.314159
- 9.92844411222603584477042204525787383317947387695312e-01, // 0.400000
- 9.97004066019049783875516368425451219081878662109375e-01, // 0.500000
- 9.98911280404623402873198756424244493246078491210938e-01, // 0.600000
- 9.99689562452632296540855350031051784753799438476562e-01, // 0.700000
- 9.99944079297292676145048062608111649751663208007812e-01, // 0.800000
- 9.99996782871730882646943427971564233303070068359375e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_01_4 = { //
- 1.19349999964195147156715393066406250000000000000000e+08, // 0.000000
- 3.77406516319158572514425031840801239013671875000000e+03, // 0.000010
- 6.91114415396560155535610192600870504975318908691406e-01, // 0.100000
- 5.28176834178893939153454084589611738920211791992188e-01, // 0.123457
- 2.60114994567310353623668106592958793044090270996094e-01, // 0.200000
- 1.48819207734501468554100256369565613567829132080078e-01, // 0.271828
- 1.20978282360318920019004451660293852910399436950684e-01, // 0.300000
- 1.09158451358439906320185741606110241264104843139648e-01, // 0.314159
- 5.88060734874641596880984195649944012984633445739746e-02, // 0.400000
- 2.78393718849794941094799582970154006034135818481445e-02, // 0.500000
- 1.20966822229282670864147775091623771004378795623779e-02, // 0.600000
- 4.44219840138408185448160025998731725849211215972900e-03, // 0.700000
- 1.16716275925598514037750952354599576210603117942810e-03, // 0.800000
- 1.31221248296568414760249199346731074911076575517654e-04, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_05_01 = { //
- 1.76630277983172680022875850741614911498800211120397e-06, // 0.000000
- 5.58555657830258874343987152144563879119232296943665e-04, // 0.000010
- 5.76337116842095750768315554068976780399680137634277e-02, // 0.100000
- 6.45370774761398202645779065278475172817707061767578e-02, // 0.123457
- 8.43593596249963134647842366575787309557199478149414e-02, // 0.200000
- 1.01039482858121226760417243895062711089849472045898e-01, // 0.271828
- 1.07341412163594357442875093511247541755437850952148e-01, // 0.300000
- 1.10480921737836620954986699416622286662459373474121e-01, // 0.314159
- 1.29396563019994831345016450541152153164148330688477e-01, // 0.400000
- 1.51998287600229570193377526265976484864950180053711e-01, // 0.500000
- 1.76505161463342941097209859435679391026496887207031e-01, // 0.600000
- 2.04823469632632232384494841426203493028879165649414e-01, // 0.700000
- 2.40695780554681937335459451787755824625492095947266e-01, // 0.800000
- 2.95166377948778924089623387772007845342159271240234e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_05_01 = { //
- 8.83151389968852345191407948732376098632812500000000e+03, // 0.000000
- 2.79279504596178647091164748417213559150695800781250e+01, // 0.000010
- 3.07055512274369002412299778370652347803115844726562e-01, // 0.100000
- 2.82996971327952206998190831654937937855720520019531e-01, // 0.123457
- 2.41401058813832225524720342946238815784454345703125e-01, // 0.200000
- 2.25360312523454175970272217455203644931316375732422e-01, // 0.271828
- 2.22272786172716479979882819861813914030790328979492e-01, // 0.300000
- 2.21237769900911845910584929697506595402956008911133e-01, // 0.314159
- 2.21140881157234348020068637197255156934261322021484e-01, // 0.400000
- 2.33065049073819779978933297570620197802782058715820e-01, // 0.500000
- 2.60079151351645165846093732398003339767456054687500e-01, // 0.600000
- 3.11944266317603025040483544216840527951717376708984e-01, // 0.700000
- 4.20303655461324976450043777731480076909065246582031e-01, // 0.800000
- 7.39458664410644339604061769932741299271583557128906e-01, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_05_01 = { //
- 1.76630277983172658847052169384106434790737694129348e-06, // 0.000000
- 5.58555657830258765923769903594120478373952209949493e-04, // 0.000010
- 5.76337116842095611990437475924409227445721626281738e-02, // 0.100000
- 6.45370774761398063867900987133907619863748550415039e-02, // 0.123457
- 8.43593596249962857092086210286652203649282455444336e-02, // 0.200000
- 1.01039482858142709575943740674119908362627029418945e-01, // 0.271828
- 1.07341412163594315809511670067877275869250297546387e-01, // 0.300000
- 1.10480921737841158991599854743981268256902694702148e-01, // 0.314159
- 1.29396563019994748078289603654411621391773223876953e-01, // 0.400000
- 1.51998287600229459171075063750322442501783370971680e-01, // 0.500000
- 1.76505161463342774563756165662198327481746673583984e-01, // 0.600000
- 2.04823469632632537695826613344252109527587890625000e-01, // 0.700000
- 2.40695780554682103868913145561236888170242309570312e-01, // 0.800000
- 2.95166377948779090623077081545488908886909484863281e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_05_01 = { //
- 8.83151389968851799494586884975433349609375000000000e+03, // 0.000000
- 2.79279504596178611564027960412204265594482421875000e+01, // 0.000010
- 3.07055512274369057923451009628479368984699249267578e-01, // 0.100000
- 2.82996971327952262509342062912764959037303924560547e-01, // 0.123457
- 2.41401058813832197769144727317325305193662643432617e-01, // 0.200000
- 2.25360312523441158605308487494767177850008010864258e-01, // 0.271828
- 2.22272786172716479979882819861813914030790328979492e-01, // 0.300000
- 2.21237769900910513642955379509658087044954299926758e-01, // 0.314159
- 2.21140881157234375775644252826168667525053024291992e-01, // 0.400000
- 2.33065049073819752223357681941706687211990356445312e-01, // 0.500000
- 2.60079151351645221357244963655830360949039459228516e-01, // 0.600000
- 3.11944266317603025040483544216840527951717376708984e-01, // 0.700000
- 4.20303655461324976450043777731480076909065246582031e-01, // 0.800000
- 7.39458664410644228581759307417087256908416748046875e-01, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_05_05 = { //
- 6.36619772378191858851811252284491615682782139629126e-06, // 0.000000
- 2.01317183947538743890581791617933049565181136131287e-03, // 0.000010
- 2.04832764699133501595795792127319145947694778442383e-01, // 0.100000
- 2.28564106667586530718949688889551907777786254882812e-01, // 0.123457
- 2.95167235300866637182082286017248407006263732910156e-01, // 0.200000
- 3.49158781117712757602333795148297213017940521240234e-01, // 0.271828
- 3.69010119565545413600204938120441511273384094238281e-01, // 0.300000
- 3.78781359553035823495292788720689713954925537109375e-01, // 0.314159
- 4.35905783151025183475013591305469162762165069580078e-01, // 0.400000
- 5.00000000000000111022302462515654042363166809082031e-01, // 0.500000
- 5.64094216848975094080742564983665943145751953125000e-01, // 0.600000
- 6.30989880434454586399795061879558488726615905761719e-01, // 0.700000
- 7.04832764699133362817917713982751592993736267089844e-01, // 0.800000
- 7.95167235300866193092872435954632237553596496582031e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_05_05 = { //
- 3.18309886199706197658088058233261108398437500000000e+04, // 0.000000
- 1.00658927504869836866419063881039619445800781250000e+02, // 0.000010
- 1.06103295394596908174378313560737296938896179199219e+00, // 0.100000
- 9.67622833349070621267173919477500021457672119140625e-01, // 0.123457
- 7.95774715459476977841291045479010790586471557617188e-01, // 0.200000
- 7.15460980314251537848235784622374922037124633789062e-01, // 0.271828
- 6.94609118042856854557953738549258559942245483398438e-01, // 0.300000
- 6.85746426302663469876108592870878055691719055175781e-01, // 0.314159
- 6.49747334361396755575412953476188704371452331542969e-01, // 0.400000
- 6.36619772367581604477493328886339440941810607910156e-01, // 0.500000
- 6.49747334361396755575412953476188704371452331542969e-01, // 0.600000
- 6.94609118042856854557953738549258559942245483398438e-01, // 0.700000
- 7.95774715459476977841291045479010790586471557617188e-01, // 0.800000
- 1.06103295394596930378838806063868105411529541015625e+00, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_05_05 = { //
- 6.36619772378191689445221801424423802018282003700733e-06, // 0.000000
- 2.01317183947538700522494892197755689267069101333618e-03, // 0.000010
- 2.04832764699133446084644560869492124766111373901367e-01, // 0.100000
- 2.28564106667586419696647226373897865414619445800781e-01, // 0.123457
- 2.95167235300866415137477360985940322279930114746094e-01, // 0.200000
- 3.49158781117780925296045779759879224002361297607422e-01, // 0.271828
- 3.69010119565545247066751244346960447728633880615234e-01, // 0.300000
- 3.78781359553049756794251834435272030532360076904297e-01, // 0.314159
- 4.35905783151024850408106203758507035672664642333984e-01, // 0.400000
- 4.99999999999999555910790149937383830547332763671875e-01, // 0.500000
- 5.64094216848975094080742564983665943145751953125000e-01, // 0.600000
- 6.30989880434454697422097524395212531089782714843750e-01, // 0.700000
- 7.04832764699133584862522639014059677720069885253906e-01, // 0.800000
- 7.95167235300866637182082286017248407006263732910156e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_05_05 = { //
- 3.18309886199705724720843136310577392578125000000000e+04, // 0.000000
- 1.00658927504869879498983209487050771713256835937500e+02, // 0.000010
- 1.06103295394596863765457328554475679993629455566406e+00, // 0.100000
- 9.67622833349070399222568994446191936731338500976562e-01, // 0.123457
- 7.95774715459476422729778732900740578770637512207031e-01, // 0.200000
- 7.15460980314172489968882473476696759462356567382812e-01, // 0.271828
- 6.94609118042856410468743888486642390489578247070312e-01, // 0.300000
- 6.85746426302651035378232791117625311017036437988281e-01, // 0.314159
- 6.49747334361396533530808028444880619645118713378906e-01, // 0.400000
- 6.36619772367581160388283478823723271489143371582031e-01, // 0.500000
- 6.49747334361396533530808028444880619645118713378906e-01, // 0.600000
- 6.94609118042856410468743888486642390489578247070312e-01, // 0.700000
- 7.95774715459476533752081195416394621133804321289062e-01, // 0.800000
- 1.06103295394596885969917821057606488466262817382812e+00, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_05_1 = { //
- 1.00000000000000008180305391403130954586231382563710e-05, // 0.000000
- 3.16227766016837939441752602931501314742490649223328e-03, // 0.000010
- 3.16227766016837941176476078908308409154415130615234e-01, // 0.100000
- 3.51364056215202502642114268383011221885681152343750e-01, // 0.123457
- 4.47213595499957927703604809721582569181919097900391e-01, // 0.200000
- 5.21371444217943791343827797390986233949661254882812e-01, // 0.271828
- 5.47722557505166074420799304789397865533828735351562e-01, // 0.300000
- 5.60499121639792874383090293122222647070884704589844e-01, // 0.314159
- 6.32455532033675882352952157816616818308830261230469e-01, // 0.400000
- 7.07106781186547572737310929369414225220680236816406e-01, // 0.500000
- 7.74596669241483404277914814883843064308166503906250e-01, // 0.600000
- 8.36660026534075562665293546160683035850524902343750e-01, // 0.700000
- 8.94427190999915855407209619443165138363838195800781e-01, // 0.800000
- 9.48683298050513768018277005467098206281661987304688e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_05_1 = { //
- 5.00000000000000072759576141834259033203125000000000e+04, // 0.000000
- 1.58113883008418980580245261080563068389892578125000e+02, // 0.000010
- 1.58113883008418976139353162579936906695365905761719e+00, // 0.100000
- 1.42302546648016092767363716120598837733268737792969e+00, // 0.123457
- 1.11803398874989512457034379622200503945350646972656e+00, // 0.200000
- 9.59009177708225135638997471687616780400276184082031e-01, // 0.271828
- 9.12870929175277012745937099680304527282714843750000e-01, // 0.300000
- 8.92062058076385722138468281627865508198738098144531e-01, // 0.314159
- 7.90569415042094880696765812899684533476829528808594e-01, // 0.400000
- 7.07106781186547683759613391885068267583847045898438e-01, // 0.500000
- 6.45497224367902910913130654080305248498916625976562e-01, // 0.600000
- 5.97614304667197004938827831210801377892494201660156e-01, // 0.700000
- 5.59016994374947562285171898111002519726753234863281e-01, // 0.800000
- 5.27046276694730031486813004448777064681053161621094e-01, // 0.900000
- 5.00000000000000111022302462515654042363166809082031e-01, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_05_1 = { //
- 1.00000000000000008180305391403130954586231382563710e-05, // 0.000000
- 3.16227766016837939441752602931501314742490649223328e-03, // 0.000010
- 3.16227766016837941176476078908308409154415130615234e-01, // 0.100000
- 3.51364056215202502642114268383011221885681152343750e-01, // 0.123457
- 4.47213595499957927703604809721582569181919097900391e-01, // 0.200000
- 5.21371444218035384743359372805571183562278747558594e-01, // 0.271828
- 5.47722557505166074420799304789397865533828735351562e-01, // 0.300000
- 5.60499121639811304085299070720793679356575012207031e-01, // 0.314159
- 6.32455532033675882352952157816616818308830261230469e-01, // 0.400000
- 7.07106781186547572737310929369414225220680236816406e-01, // 0.500000
- 7.74596669241483404277914814883843064308166503906250e-01, // 0.600000
- 8.36660026534075562665293546160683035850524902343750e-01, // 0.700000
- 8.94427190999915966429512081958819180727005004882812e-01, // 0.800000
- 9.48683298050513768018277005467098206281661987304688e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_05_1 = { //
- 5.00000000000000072759576141834259033203125000000000e+04, // 0.000000
- 1.58113883008418980580245261080563068389892578125000e+02, // 0.000010
- 1.58113883008418953934892670076806098222732543945312e+00, // 0.100000
- 1.42302546648016092767363716120598837733268737792969e+00, // 0.123457
- 1.11803398874989490252573887119069695472717285156250e+00, // 0.200000
- 9.59009177708056492761556910409126430749893188476562e-01, // 0.271828
- 9.12870929175276901723634637164650484919548034667969e-01, // 0.300000
- 8.92062058076356190206013252463890239596366882324219e-01, // 0.314159
- 7.90569415042094769674463350384030491113662719726562e-01, // 0.400000
- 7.07106781186547572737310929369414225220680236816406e-01, // 0.500000
- 6.45497224367902799890828191564651206135749816894531e-01, // 0.600000
- 5.97614304667196893916525368695147335529327392578125e-01, // 0.700000
- 5.59016994374947451262869435595348477363586425781250e-01, // 0.800000
- 5.27046276694729920464510541933123022317886352539062e-01, // 0.900000
- 5.00000000000000000000000000000000000000000000000000e-01, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_05_2 = { //
- 1.49999999995000036075122260004199858940410194918513e-05, // 0.000000
- 4.74340067886426866583526873455411987379193305969238e-03, // 0.000010
- 4.58530260724415050788138614734634757041931152343750e-01, // 0.100000
- 5.05356960883332151368563245341647416353225708007812e-01, // 0.123457
- 6.26099033699941132091737472364911809563636779785156e-01, // 0.200000
- 7.11195440192161520975844268832588568329811096191406e-01, // 0.271828
- 7.39425452631974344797072262736037373542785644531250e-01, // 0.300000
- 7.52705686315334188130066195299150422215461730957031e-01, // 0.314159
- 8.22192191643778769183370513928821310400962829589844e-01, // 0.400000
- 8.83883476483184660210667971114162355661392211914062e-01, // 0.500000
- 9.29516003089779996315655807848088443279266357421875e-01, // 0.600000
- 9.62159030514186830451706100575393065810203552246094e-01, // 0.700000
- 9.83869910099907429845700335135916247963905334472656e-01, // 0.800000
- 9.96117462953039489725881594495149329304695129394531e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_05_2 = { //
- 7.49999999925000010989606380462646484375000000000000e+04, // 0.000000
- 2.37168452804383292686907225288450717926025390625000e+02, // 0.000010
- 2.13453742061365581150766956852748990058898925781250e+00, // 0.100000
- 1.87101515755883918146196265297476202249526977539062e+00, // 0.123457
- 1.34164078649987406066657058545388281345367431640625e+00, // 0.200000
- 1.04748518339887985995062535948818549513816833496094e+00, // 0.271828
- 9.58514475634040685747550014639273285865783691406250e-01, // 0.300000
- 9.17718745884733677620204161939909681677818298339844e-01, // 0.314159
- 7.11512473537885270502556522842496633529663085937500e-01, // 0.400000
- 5.30330085889910707308558812655974179506301879882812e-01, // 0.500000
- 3.87298334620741757650108638699748553335666656494141e-01, // 0.600000
- 2.68926437100238668875817893422208726406097412109375e-01, // 0.700000
- 1.67705098312484202072170091923908330500125885009766e-01, // 0.800000
- 7.90569415042094714163312119126203469932079315185547e-02, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_05_2 = { //
- 1.49999999994999815846555973886111701176560018211603e-05, // 0.000000
- 4.74340067886426779847353074615057266782969236373901e-03, // 0.000010
- 4.58530260724415050788138614734634757041931152343750e-01, // 0.100000
- 5.05356960883331929323958320310339331626892089843750e-01, // 0.123457
- 6.26099033699941021069435009849257767200469970703125e-01, // 0.200000
- 7.11195440192261552070362995436880737543106079101562e-01, // 0.271828
- 7.39425452631974677863979650282999500632286071777344e-01, // 0.300000
- 7.52705686315353283966089747991645708680152893066406e-01, // 0.314159
- 8.22192191643778880205672976444475352764129638671875e-01, // 0.400000
- 8.83883476483184438166063046082854270935058593750000e-01, // 0.500000
- 9.29516003089779996315655807848088443279266357421875e-01, // 0.600000
- 9.62159030514186941474008563091047108173370361328125e-01, // 0.700000
- 9.83869910099907540868002797651570290327072143554688e-01, // 0.800000
- 9.96117462953039489725881594495149329304695129394531e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_05_2 = { //
- 7.49999999924999574432149529457092285156250000000000e+04, // 0.000000
- 2.37168452804383349530326086096465587615966796875000e+02, // 0.000010
- 2.13453742061365536741845971846487373113632202148438e+00, // 0.100000
- 1.87101515755883918146196265297476202249526977539062e+00, // 0.123457
- 1.34164078649987361657736073539126664400100708007812e+00, // 0.200000
- 1.04748518339855811731808898912277072668075561523438e+00, // 0.271828
- 9.58514475634040685747550014639273285865783691406250e-01, // 0.300000
- 9.17718745884675612956016266252845525741577148437500e-01, // 0.314159
- 7.11512473537885270502556522842496633529663085937500e-01, // 0.400000
- 5.30330085889910596286256350140320137143135070800781e-01, // 0.500000
- 3.87298334620741702138957407441921532154083251953125e-01, // 0.600000
- 2.68926437100238557853515430906554684042930603027344e-01, // 0.700000
- 1.67705098312484174316594476294994819909334182739258e-01, // 0.800000
- 7.90569415042094297829677884692500811070203781127930e-02, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_05_4 = { //
- 2.18749999978125033101364338428140854375669732689857e-05, // 0.000000
- 6.91741320720956186923755737439023505430668592453003e-03, // 0.000010
- 6.26625082597740412637676854501478374004364013671875e-01, // 0.100000
- 6.80541225384169945478163299412699416279792785644531e-01, // 0.123457
- 8.04984471899924280968718903750414028763771057128906e-01, // 0.200000
- 8.77770786854125240061819113179808482527732849121094e-01, // 0.271828
- 8.98778484206133598810595231043407693505287170410156e-01, // 0.300000
- 9.08079033661920775877263167785713449120521545410156e-01, // 0.314159
- 9.50264436880598029055988718027947470545768737792969e-01, // 0.400000
- 9.77796095859522762516746752226026728749275207519531e-01, // 0.500000
- 9.91483736629098721948594175046309828758239746093750e-01, // 0.600000
- 9.97455625383593225130596238159341737627983093261719e-01, // 0.700000
- 9.99522385942405944270205964130582287907600402832031e-01, // 0.800000
- 9.99971488851369660899592872738139703869819641113281e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_05_4 = { //
- 1.09374999967187526635825634002685546875000000000000e+05, // 0.000000
- 3.45863742961106026996276341378688812255859375000000e+02, // 0.000010
- 2.52142232809988131592149329662788659334182739257812e+00, // 0.100000
- 2.09643237315321817604285570268984884023666381835938e+00, // 0.123457
- 1.25219806739988270827268479479243978857994079589844e+00, // 0.200000
- 8.09976508987270138462122304190415889024734497070312e-01, // 0.271828
- 6.84938469046824982555676797346677631139755249023438e-01, // 0.300000
- 6.29524964821042476437185086979297921061515808105469e-01, // 0.314159
- 3.73544048607389767013842174492310732603073120117188e-01, // 0.400000
- 1.93349510480696623604401906959537882357835769653320e-01, // 0.500000
- 9.03696114115064286220757594492170028388500213623047e-02, // 0.600000
- 3.52965948694063461066328102333500282838940620422363e-02, // 0.700000
- 9.78279740156157671948644605208755820058286190032959e-03, // 0.800000
- 1.15291373026972119794630877720464923186227679252625e-03, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_05_4 = { //
- 2.18749999978125100864000118772167979841469787061214e-05, // 0.000000
- 6.91741320720955839979060542077604623045772314071655e-03, // 0.000010
- 6.26625082597740301615374391985824331641197204589844e-01, // 0.100000
- 6.80541225384170056500465761928353458642959594726562e-01, // 0.123457
- 8.04984471899924280968718903750414028763771057128906e-01, // 0.200000
- 8.77770786854202622606635486590676009654998779296875e-01, // 0.271828
- 8.98778484206133709832897693559061735868453979492188e-01, // 0.300000
- 9.08079033661933876508953744632890447974205017089844e-01, // 0.314159
- 9.50264436880598029055988718027947470545768737792969e-01, // 0.400000
- 9.77796095859522762516746752226026728749275207519531e-01, // 0.500000
- 9.91483736629098721948594175046309828758239746093750e-01, // 0.600000
- 9.97455625383593114108293775643687695264816284179688e-01, // 0.700000
- 9.99522385942406055292508426646236330270767211914062e-01, // 0.800000
- 9.99971488851369771921895335253793746232986450195312e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_05_4 = { //
- 1.09374999967187599395401775836944580078125000000000e+05, // 0.000000
- 3.45863742961106026996276341378688812255859375000000e+02, // 0.000010
- 2.52142232809988087183228344656527042388916015625000e+00, // 0.100000
- 2.09643237315321773195364585262723267078399658203125e+00, // 0.123457
- 1.25219806739988204213887001969851553440093994140625e+00, // 0.200000
- 8.09976508986808951817693014163523912429809570312500e-01, // 0.271828
- 6.84938469046825204600281722377985715866088867187500e-01, // 0.300000
- 6.29524964820964538780856400990160182118415832519531e-01, // 0.314159
- 3.73544048607389822524993405750137753784656524658203e-01, // 0.400000
- 1.93349510480696651359977522588451392948627471923828e-01, // 0.500000
- 9.03696114115064008665001438203034922480583190917969e-02, // 0.600000
- 3.52965948694063183510571946044365176931023597717285e-02, // 0.700000
- 9.78279740156157845420992202889465261250734329223633e-03, // 0.800000
- 1.15291373026972098110587428010376243037171661853790e-03, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_1_01 = { //
- 1.00000000004500018040698788008499304624104864203105e-11, // 0.000000
- 1.00000450002850051417838117551184495823690667748451e-06, // 0.000010
- 1.04807417937856101747273740443233691621571779251099e-02, // 0.100000
- 1.30904819719778343217742033743888896424323320388794e-02, // 0.123457
- 2.20672314570714948878116246078207041136920452117920e-02, // 0.200000
- 3.12239657447760353414789591397493495605885982513428e-02, // 0.271828
- 3.50389048801823949075284758691850584000349044799805e-02, // 0.300000
- 3.70087797866922516010212973469606367871165275573730e-02, // 0.314159
- 4.97997834943236170057723199988686246797442436218262e-02, // 0.400000
- 6.69670084631925899287807624205015599727630615234375e-02, // 0.500000
- 8.75564634445191447564837972095119766891002655029297e-02, // 0.600000
- 1.13431849434786694019727804061403730884194374084473e-01, // 0.700000
- 1.48660077479215418927438463470025453716516494750977e-01, // 0.800000
- 2.05671765275718482213207494169182609766721725463867e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_1_01 = { //
- 1.00000000009000014622451146806270116940140724182129e-01, // 0.000000
- 1.00000900008550108744032058893935754895210266113281e-01, // 0.000010
- 1.09946584245134940105437237889418611302971839904785e-01, // 0.100000
- 1.12591074283269546030261665237048873677849769592285e-01, // 0.123457
- 1.22241596067866081787300913674698676913976669311523e-01, // 0.200000
- 1.33042231439480740373682010613265447318553924560547e-01, // 0.271828
- 1.37851585017116834430694893853797111660242080688477e-01, // 0.300000
- 1.40410327292290693090848208157694898545742034912109e-01, // 0.314159
- 1.58366702750946081179606039768259506672620773315430e-01, // 0.400000
- 1.86606598307361509769819463144813198596239089965820e-01, // 0.500000
- 2.28110884138870234627560762419307138770818710327148e-01, // 0.600000
- 2.95522716855071143626787488756235688924789428710938e-01, // 0.700000
- 4.25669961260392526458673501110752113163471221923828e-01, // 0.800000
- 7.94328234724281823098124277748866006731986999511719e-01, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_1_01 = { //
- 1.00000000004500001884827449082177529791903847211643e-11, // 0.000000
- 1.00000450002850030242014436193676019115628150757402e-06, // 0.000010
- 1.04807417937856067052804220907091803383082151412964e-02, // 0.100000
- 1.30904819719778325870507273975817952305078506469727e-02, // 0.123457
- 2.20672314570714879489177207005923264659941196441650e-02, // 0.200000
- 3.12239657447887335173231093676804448477923870086670e-02, // 0.271828
- 3.50389048801823740908467641474999254569411277770996e-02, // 0.300000
- 3.70087797866951451197792266611941158771514892578125e-02, // 0.314159
- 4.97997834943235961890906082771834917366504669189453e-02, // 0.400000
- 6.69670084631925344176295311626745387911796569824219e-02, // 0.500000
- 8.75564634445190614897569503227714449167251586914062e-02, // 0.600000
- 1.13431849434786791164242458762601017951965332031250e-01, // 0.700000
- 1.48660077479215502194165310356765985488891601562500e-01, // 0.800000
- 2.05671765275718620991085572313750162720680236816406e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_1_01 = { //
- 1.00000000009000028500238954620726872235536575317383e-01, // 0.000000
- 1.00000900008550108744032058893935754895210266113281e-01, // 0.000010
- 1.09946584245134940105437237889418611302971839904785e-01, // 0.100000
- 1.12591074283269559908049473051505628973245620727539e-01, // 0.123457
- 1.22241596067866095665088721489155432209372520446777e-01, // 0.200000
- 1.33042231439496422273904840949398931115865707397461e-01, // 0.271828
- 1.37851585017116834430694893853797111660242080688477e-01, // 0.300000
- 1.40410327292294495604707549318845849484205245971680e-01, // 0.314159
- 1.58366702750946108935181655397173017263412475585938e-01, // 0.400000
- 1.86606598307361537525395078773726709187030792236328e-01, // 0.500000
- 2.28110884138870234627560762419307138770818710327148e-01, // 0.600000
- 2.95522716855071199137938720014062710106372833251953e-01, // 0.700000
- 4.25669961260392470947522269852925091981887817382812e-01, // 0.800000
- 7.94328234724281934120426740264520049095153808593750e-01, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_1_05 = { //
- 5.00000000012500009741482020021919761496032030834158e-11, // 0.000000
- 5.00001250006250130353616101253066972276428714394569e-06, // 0.000010
- 5.13167019494862042261473789039882831275463104248047e-02, // 0.100000
- 6.37610881831496972838024817065161187201738357543945e-02, // 0.123457
- 1.05572809000084130715002572742378106340765953063965e-01, // 0.200000
- 1.46670159226752749859201685467269271612167358398438e-01, // 0.271828
- 1.63339973465924465090282069468230474740266799926758e-01, // 0.300000
- 1.71844981515525241366759701122646220028400421142578e-01, // 0.314159
- 2.25403330758516595722085185116156935691833496093750e-01, // 0.400000
- 2.92893218813452427262689070630585774779319763183594e-01, // 0.500000
- 3.67544467966324062135896610925556160509586334228516e-01, // 0.600000
- 4.52277442494833814556898232694948092103004455566406e-01, // 0.700000
- 5.52786404500041905762941496504936367273330688476562e-01, // 0.800000
- 6.83772233983161559223162839771248400211334228515625e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_1_05 = { //
- 5.00000000025000113090811737492913380265235900878906e-01, // 0.000000
- 5.00002500018750239973996940534561872482299804687500e-01, // 0.000010
- 5.27046276694730031486813004448777064681053161621094e-01, // 0.100000
- 5.34051718732463376326791149040218442678451538085938e-01, // 0.123457
- 5.59016994374947562285171898111002519726753234863281e-01, // 0.200000
- 5.85939898160509287095010222401469945907592773437500e-01, // 0.271828
- 5.97614304667197004938827831210801377892494201660156e-01, // 0.300000
- 6.03751699669707986295463797432603314518928527832031e-01, // 0.314159
- 6.45497224367902910913130654080305248498916625976562e-01, // 0.400000
- 7.07106781186547683759613391885068267583847045898438e-01, // 0.500000
- 7.90569415042094880696765812899684533476829528808594e-01, // 0.600000
- 9.12870929175276901723634637164650484919548034667969e-01, // 0.700000
- 1.11803398874989512457034379622200503945350646972656e+00, // 0.800000
- 1.58113883008418998343813655083067715167999267578125e+00, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_1_05 = { //
- 5.00000000012500009741482020021919761496032030834158e-11, // 0.000000
- 5.00001250006250130353616101253066972276428714394569e-06, // 0.000010
- 5.13167019494862042261473789039882831275463104248047e-02, // 0.100000
- 6.37610881831496972838024817065161187201738357543945e-02, // 0.123457
- 1.05572809000084130715002572742378106340765953063965e-01, // 0.200000
- 1.46670159226808705099642793356906622648239135742188e-01, // 0.271828
- 1.63339973465924409579130838210403453558683395385742e-01, // 0.300000
- 1.71844981515537759131362349762639496475458145141602e-01, // 0.314159
- 2.25403330758516567966509569487243425101041793823242e-01, // 0.400000
- 2.92893218813452260729235376857104711234569549560547e-01, // 0.500000
- 3.67544467966324117647047842183383181691169738769531e-01, // 0.600000
- 4.52277442494833814556898232694948092103004455566406e-01, // 0.700000
- 5.52786404500042127807546421536244451999664306640625e-01, // 0.800000
- 6.83772233983162114334675152349518612027168273925781e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_1_05 = { //
- 5.00000000025000002068509274977259337902069091796875e-01, // 0.000000
- 5.00002500018750128951694478018907830119132995605469e-01, // 0.000010
- 5.27046276694729920464510541933123022317886352539062e-01, // 0.100000
- 5.34051718732463265304488686524564400315284729003906e-01, // 0.123457
- 5.59016994374947451262869435595348477363586425781250e-01, // 0.200000
- 5.85939898160547589789359790302114561200141906738281e-01, // 0.271828
- 5.97614304667196782894222906179493293166160583496094e-01, // 0.300000
- 6.03751699669717090124265723716234788298606872558594e-01, // 0.314159
- 6.45497224367902799890828191564651206135749816894531e-01, // 0.400000
- 7.07106781186547572737310929369414225220680236816406e-01, // 0.500000
- 7.90569415042094769674463350384030491113662719726562e-01, // 0.600000
- 9.12870929175276790701332174648996442556381225585938e-01, // 0.700000
- 1.11803398874989490252573887119069695472717285156250e+00, // 0.800000
- 1.58113883008418998343813655083067715167999267578125e+00, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_1_1 = { //
- 1.00000000000000003643219731549774157916554706559964e-10, // 0.000000
- 1.00000000000000008180305391403130954586231382563710e-05, // 0.000010
- 1.00000000000000005551115123125782702118158340454102e-01, // 0.100000
- 1.23456700000000002548361521803599316626787185668945e-01, // 0.123457
- 2.00000000000000011102230246251565404236316680908203e-01, // 0.200000
- 2.71828182845904486875099337339634075760841369628906e-01, // 0.271828
- 2.99999999999999988897769753748434595763683319091797e-01, // 0.300000
- 3.14159265358979311599796346854418516159057617187500e-01, // 0.314159
- 4.00000000000000022204460492503130808472633361816406e-01, // 0.400000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 5.99999999999999977795539507496869191527366638183594e-01, // 0.600000
- 6.99999999999999955591079014993738383054733276367188e-01, // 0.700000
- 8.00000000000000044408920985006261616945266723632812e-01, // 0.800000
- 9.00000000000000022204460492503130808472633361816406e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_1_1 = { //
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.000010
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.123457
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.271828
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.314159
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_1_1 = { //
- 9.99999999999999648691285181266018983192722657804552e-11, // 0.000000
- 9.99999999999999742989875012311173918533313553780317e-06, // 0.000010
- 1.00000000000000019428902930940239457413554191589355e-01, // 0.100000
- 1.23456699999999974792785906174685806035995483398438e-01, // 0.123457
- 2.00000000000000011102230246251565404236316680908203e-01, // 0.200000
- 2.71828182846000021566368332059937529265880584716797e-01, // 0.271828
- 2.99999999999999988897769753748434595763683319091797e-01, // 0.300000
- 3.14159265359000017259205606023897416889667510986328e-01, // 0.314159
- 4.00000000000000022204460492503130808472633361816406e-01, // 0.400000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 5.99999999999999977795539507496869191527366638183594e-01, // 0.600000
- 6.99999999999999955591079014993738383054733276367188e-01, // 0.700000
- 8.00000000000000044408920985006261616945266723632812e-01, // 0.800000
- 9.00000000000000022204460492503130808472633361816406e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_1_1 = { //
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.000010
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.123457
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.271828
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.314159
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_1_2 = { //
- 1.99999999990000014066132773281109138302502614692457e-10, // 0.000000
- 1.99999000000000014167899492489866020150657277554274e-05, // 0.000010
- 1.90000000000000002220446049250313080847263336181641e-01, // 0.100000
- 2.31671843225110002384425911259313579648733139038086e-01, // 0.123457
- 3.60000000000000042188474935755948536098003387451172e-01, // 0.200000
- 4.69765804702502509648809336795238777995109558105469e-01, // 0.271828
- 5.10000000000000008881784197001252323389053344726562e-01, // 0.300000
- 5.29622486707065021072082799946656450629234313964844e-01, // 0.314159
- 6.40000000000000124344978758017532527446746826171875e-01, // 0.400000
- 7.50000000000000000000000000000000000000000000000000e-01, // 0.500000
- 8.39999999999999968913755310495616868138313293457031e-01, // 0.600000
- 9.09999999999999920063942226988729089498519897460938e-01, // 0.700000
- 9.59999999999999964472863211994990706443786621093750e-01, // 0.800000
- 9.89999999999999991118215802998747676610946655273438e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_1_2 = { //
- 1.99999999979999998345192580018192529678344726562500e+00, // 0.000000
- 1.99998000000000009102052445086883381009101867675781e+00, // 0.000010
- 1.80000000000000004440892098500626161694526672363281e+00, // 0.100000
- 1.75308660000000005041442818765062838792800903320312e+00, // 0.123457
- 1.60000000000000008881784197001252323389053344726562e+00, // 0.200000
- 1.45634363430819102624980132532073184847831726074219e+00, // 0.271828
- 1.39999999999999991118215802998747676610946655273438e+00, // 0.300000
- 1.37168146928204137680040730629116296768188476562500e+00, // 0.314159
- 1.19999999999999995559107901499373838305473327636719e+00, // 0.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 8.00000000000000044408920985006261616945266723632812e-01, // 0.600000
- 6.00000000000000088817841970012523233890533447265625e-01, // 0.700000
- 3.99999999999999911182158029987476766109466552734375e-01, // 0.800000
- 1.99999999999999955591079014993738383054733276367188e-01, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_1_2 = { //
- 1.99999999989999600475826496767271702598156579711031e-10, // 0.000000
- 1.99998999999999980286581602317852457417757250368595e-05, // 0.000010
- 1.89999999999999502620084967929869890213012695312500e-01, // 0.100000
- 2.31671843225110141162303989403881132602691650390625e-01, // 0.123457
- 3.59999999999999764632718779466813430190086364746094e-01, // 0.200000
- 4.69765804702641842638399793941061943769454956054688e-01, // 0.271828
- 5.10000000000000008881784197001252323389053344726562e-01, // 0.300000
- 5.29622486707093331759210741438437253236770629882812e-01, // 0.314159
- 6.40000000000000013322676295501878485083580017089844e-01, // 0.400000
- 7.50000000000000000000000000000000000000000000000000e-01, // 0.500000
- 8.39999999999999968913755310495616868138313293457031e-01, // 0.600000
- 9.09999999999999920063942226988729089498519897460938e-01, // 0.700000
- 9.59999999999999964472863211994990706443786621093750e-01, // 0.800000
- 9.89999999999999991118215802998747676610946655273438e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_1_2 = { //
- 1.99999999979999998345192580018192529678344726562500e+00, // 0.000000
- 1.99998000000000009102052445086883381009101867675781e+00, // 0.000010
- 1.79999999999999982236431605997495353221893310546875e+00, // 0.100000
- 1.75308660000000005041442818765062838792800903320312e+00, // 0.123457
- 1.59999999999999986677323704498121514916419982910156e+00, // 0.200000
- 1.45634363430799984584496087336447089910507202148438e+00, // 0.271828
- 1.40000000000000013322676295501878485083580017089844e+00, // 0.300000
- 1.37168146928199985445928632543655112385749816894531e+00, // 0.314159
- 1.19999999999999995559107901499373838305473327636719e+00, // 0.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 8.00000000000000044408920985006261616945266723632812e-01, // 0.600000
- 6.00000000000000088817841970012523233890533447265625e-01, // 0.700000
- 3.99999999999999966693309261245303787291049957275391e-01, // 0.800000
- 1.99999999999999983346654630622651893645524978637695e-01, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_1_4 = { //
- 3.99999999940000003552250502724231887019534781302355e-10, // 0.000000
- 3.99994000039999964652912001206175318657187744975090e-05, // 0.000010
- 3.43900000000000038991032624835497699677944183349609e-01, // 0.100000
- 4.09671843506900057452213559372466988861560821533203e-01, // 0.123457
- 5.90400000000000035882408155885059386491775512695312e-01, // 0.200000
- 7.18851698137215278094913628592621535062789916992188e-01, // 0.271828
- 7.59900000000000019895196601282805204391479492187500e-01, // 0.300000
- 7.78744994988354810594444188609486445784568786621094e-01, // 0.314159
- 8.70400000000000062527760746888816356658935546875000e-01, // 0.400000
- 9.37500000000000000000000000000000000000000000000000e-01, // 0.500000
- 9.74400000000000043876013933186186477541923522949219e-01, // 0.600000
- 9.91900000000000003907985046680551022291183471679688e-01, // 0.700000
- 9.98399999999999954169993543473538011312484741210938e-01, // 0.800000
- 9.99900000000000011013412404281552881002426147460938e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_1_4 = { //
- 3.99999999879999990071155480109155178070068359375000e+00, // 0.000000
- 3.99988000119999664860870325355790555477142333984375e+00, // 0.000010
- 2.91600000000000036948222259525209665298461914062500e+00, // 0.100000
- 2.69389159208951811663723674428183585405349731445312e+00, // 0.123457
- 2.04800000000000048672177399566862732172012329101562e+00, // 0.200000
- 1.54440639002807333923783517093397676944732666015625e+00, // 0.271828
- 1.37199999999999966426855735335266217589378356933594e+00, // 0.300000
- 1.29041623710177200123894181160721927881240844726562e+00, // 0.314159
- 8.63999999999999879207734920782968401908874511718750e-01, // 0.400000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 2.56000000000000060840221749458578415215015411376953e-01, // 0.600000
- 1.08000000000000054289905904170154826715588569641113e-01, // 0.700000
- 3.19999999999999798494521030534087913110852241516113e-02, // 0.800000
- 3.99999999999999748118151288167609891388565301895142e-03, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_1_4 = { //
- 3.99999999939999900154673933595772528093448272556998e-10, // 0.000000
- 3.99994000039999896890276220862148193191387690603733e-05, // 0.000010
- 3.43899999999999872457578931062016636133193969726562e-01, // 0.100000
- 4.09671843506900223985667253145948052406311035156250e-01, // 0.123457
- 5.90399999999999813837803230853751301765441894531250e-01, // 0.200000
- 7.18851698137362937757188774412497878074645996093750e-01, // 0.271828
- 7.59900000000000019895196601282805204391479492187500e-01, // 0.300000
- 7.78744994988381455947035192366456612944602966308594e-01, // 0.314159
- 8.70400000000000062527760746888816356658935546875000e-01, // 0.400000
- 9.37500000000000000000000000000000000000000000000000e-01, // 0.500000
- 9.74399999999999932853711470670532435178756713867188e-01, // 0.600000
- 9.91900000000000003907985046680551022291183471679688e-01, // 0.700000
- 9.98399999999999954169993543473538011312484741210938e-01, // 0.800000
- 9.99900000000000011013412404281552881002426147460938e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_1_4 = { //
- 3.99999999879999990071155480109155178070068359375000e+00, // 0.000000
- 3.99988000119999531634107370337005704641342163085938e+00, // 0.000010
- 2.91600000000000036948222259525209665298461914062500e+00, // 0.100000
- 2.69389159208951767254802689421921968460083007812500e+00, // 0.123457
- 2.04799999999999959854335429554339498281478881835938e+00, // 0.200000
- 1.54440639002746538110955043521244078874588012695312e+00, // 0.271828
- 1.37200000000000033040237212844658643007278442382812e+00, // 0.300000
- 1.29041623710165476168754139507655054330825805664062e+00, // 0.314159
- 8.63999999999999879207734920782968401908874511718750e-01, // 0.400000
- 5.00000000000000111022302462515654042363166809082031e-01, // 0.500000
- 2.56000000000000060840221749458578415215015411376953e-01, // 0.600000
- 1.08000000000000054289905904170154826715588569641113e-01, // 0.700000
- 3.19999999999999937272399108678655466064810752868652e-02, // 0.800000
- 3.99999999999999834854325087007964611984789371490479e-03, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_2_01 = { //
- 5.50000000033000091061882744625813924005303568789147e-22, // 0.000000
- 5.50003300023512856945298627756354276335110098372638e-12, // 0.000010
- 5.85549211723463618010920850309730667504481971263885e-04, // 0.100000
- 9.06422742544821247179243073333054780960083007812500e-04, // 0.123457
- 2.50857608621292025793958480051060178084298968315125e-03, // 0.200000
- 4.88990284715010506411125845716014737263321876525879e-03, // 0.271828
- 6.09007202658786231386223164463444845750927925109863e-03, // 0.300000
- 6.75551835775626500352197822962807549629360437393188e-03, // 0.314159
- 1.17917748340965571063332362200526404194533824920654e-02, // 0.400000
- 2.03153588863522159557728485879124491475522518157959e-02, // 0.500000
- 3.28098512511902778987504802898911293596029281616211e-02, // 0.600000
- 5.13720788952217247147480350122350500896573066711426e-02, // 0.700000
- 8.05528836775526307922845603570749517530202865600586e-02, // 0.800000
- 1.34182224150533185857980811306333635002374649047852e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_2_01 = { //
- 1.10000000009900018879889436430572250639331466359749e-11, // 0.000000
- 1.10000990009405111972099443329309309547170414589345e-06, // 0.000010
- 1.20941242669648438279317304022697499021887779235840e-02, // 0.100000
- 1.52901347285140567361372276877773401793092489242554e-02, // 0.123457
- 2.68931511349305395197628598680239520035684108734131e-02, // 0.200000
- 3.97810908153541434306710300461418228223919868469238e-02, // 0.271828
- 4.54910230556485536967947780340182362124323844909668e-02, // 0.300000
- 4.85223257980558694835160338243440492078661918640137e-02, // 0.314159
- 6.96813492104162851559223668118647765368223190307617e-02, // 0.400000
- 1.02633629069048826210064362385310232639312744140625e-01, // 0.500000
- 1.50553183531654338755956246131972875446081161499023e-01, // 0.600000
- 2.27552491978404769490396120090736076235771179199219e-01, // 0.700000
- 3.74589565909145438826755025729653425514698028564453e-01, // 0.800000
- 7.86384952377038870530157055327435955405235290527344e-01, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_2_01 = { //
- 5.50000000033000185101430810408814561504226546568802e-22, // 0.000000
- 5.50003300023513099283368711651180898818125353244568e-12, // 0.000010
- 5.85549211723463618010920850309730667504481971263885e-04, // 0.100000
- 9.06422742544820921918591327681724578724242746829987e-04, // 0.123457
- 2.50857608621292025793958480051060178084298968315125e-03, // 0.200000
- 4.88990284715390410852364766469690948724746704101562e-03, // 0.271828
- 6.09007202658786057913875566782735404558479785919189e-03, // 0.300000
- 6.75551835775727114313804477774283441249281167984009e-03, // 0.314159
- 1.17917748340965536368862842664384515956044197082520e-02, // 0.400000
- 2.03153588863522090168789446806840714998543262481689e-02, // 0.500000
- 3.28098512511902501431748646609776187688112258911133e-02, // 0.600000
- 5.13720788952216692035968037544080289080739021301270e-02, // 0.700000
- 8.05528836775526863034357916149019729346036911010742e-02, // 0.800000
- 1.34182224150533130346829580048506613820791244506836e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_2_01 = { //
- 1.10000000009900018879889436430572250639331466359749e-11, // 0.000000
- 1.10000990009405090796275761971800832839107897598296e-06, // 0.000010
- 1.20941242669648507668256343094981275498867034912109e-02, // 0.100000
- 1.52901347285140602055841796413915290031582117080688e-02, // 0.123457
- 2.68931511349305464586567637752523296512663364410400e-02, // 0.200000
- 3.97810908153728159941664443977060727775096893310547e-02, // 0.271828
- 4.54910230556485467579008741267898585647344589233398e-02, // 0.300000
- 4.85223257980603936423413813372462755069136619567871e-02, // 0.314159
- 6.96813492104162851559223668118647765368223190307617e-02, // 0.400000
- 1.02633629069048826210064362385310232639312744140625e-01, // 0.500000
- 1.50553183531654338755956246131972875446081161499023e-01, // 0.600000
- 2.27552491978404769490396120090736076235771179199219e-01, // 0.700000
- 3.74589565909145383315603794471826404333114624023438e-01, // 0.800000
- 7.86384952377038981552459517843089997768402099609375e-01, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_2_05 = { //
- 3.75000000012500073511663321748728148736677675747611e-21, // 0.000000
- 3.75001250007031431176997547885672810996648962600375e-11, // 0.000010
- 3.88253704696051200884188148165776510722935199737549e-03, // 0.100000
- 5.96860495090002600437895097229556995443999767303467e-03, // 0.123457
- 1.61300899000925389292770972815560526214540004730225e-02, // 0.200000
- 3.06906092339643381261549137661859276704490184783936e-02, // 0.271828
- 3.78409694858131209760365720740082906559109687805176e-02, // 0.300000
- 4.17586954103080082445487164477526675909757614135742e-02, // 0.314159
- 7.04839969102199759287685765229980461299419403076172e-02, // 0.400000
- 1.16116523516815603467300377360515994951128959655762e-01, // 0.500000
- 1.77807808356221369594507564215746242552995681762695e-01, // 0.600000
- 2.60574547368025710714078968521789647638797760009766e-01, // 0.700000
- 3.73900966300058923419413758892915211617946624755859e-01, // 0.800000
- 5.41469739275584838189558922749711200594902038574219e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_2_05 = { //
- 7.50000000037500098835526107000383749107141895251516e-11, // 0.000000
- 7.50003750028125248017121101673509997453948017209768e-06, // 0.000010
- 7.90569415042094991719068275415338575839996337890625e-02, // 0.100000
- 9.88983942360571466334562273914343677461147308349609e-02, // 0.123457
- 1.67705098312484257583321323181735351681709289550781e-01, // 0.200000
- 2.38912466660828326503462903929175809025764465332031e-01, // 0.271828
- 2.68926437100238613364666662164381705224514007568359e-01, // 0.300000
- 2.84511285641205868834902048547519370913505554199219e-01, // 0.314159
- 3.87298334620741757650108638699748553335666656494141e-01, // 0.400000
- 5.30330085889910707308558812655974179506301879882812e-01, // 0.500000
- 7.11512473537885270502556522842496633529663085937500e-01, // 0.600000
- 9.58514475634040685747550014639273285865783691406250e-01, // 0.700000
- 1.34164078649987406066657058545388281345367431640625e+00, // 0.800000
- 2.13453742061365625559687941859010607004165649414062e+00, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_2_05 = { //
- 3.75000000012498794573809627099919478751325177944313e-21, // 0.000000
- 3.75001250007031495800482903590959910325453030566223e-11, // 0.000010
- 3.88253704696051200884188148165776510722935199737549e-03, // 0.100000
- 5.96860495090002253493199901868138113059103488922119e-03, // 0.123457
- 1.61300899000925389292770972815560526214540004730225e-02, // 0.200000
- 3.06906092339871497398640087794774444773793220520020e-02, // 0.271828
- 3.78409694858131001593548603523231577128171920776367e-02, // 0.300000
- 4.17586954103138993654731336846452904865145683288574e-02, // 0.314159
- 7.04839969102199342954051530796277802437543869018555e-02, // 0.400000
- 1.16116523516815506322785722659318707883358001708984e-01, // 0.500000
- 1.77807808356221147549902639184438157826662063598633e-01, // 0.600000
- 2.60574547368025322136020349717000499367713928222656e-01, // 0.700000
- 3.73900966300058978930564990150742232799530029296875e-01, // 0.800000
- 5.41469739275584949211861385265365242958068847656250e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_2_05 = { //
- 7.50000000037501132811291798284977338368006982705083e-11, // 0.000000
- 7.50003750028124570390763298233238742795947473496199e-06, // 0.000010
- 7.90569415042094991719068275415338575839996337890625e-02, // 0.100000
- 9.88983942360571466334562273914343677461147308349609e-02, // 0.123457
- 1.67705098312484229827745707552821841090917587280273e-01, // 0.200000
- 2.38912466660927941264347396099765319377183914184570e-01, // 0.271828
- 2.68926437100238502342364199648727662861347198486328e-01, // 0.300000
- 2.84511285641228850451511789287906140089035034179688e-01, // 0.314159
- 3.87298334620741702138957407441921532154083251953125e-01, // 0.400000
- 5.30330085889910596286256350140320137143135070800781e-01, // 0.500000
- 7.11512473537885270502556522842496633529663085937500e-01, // 0.600000
- 9.58514475634040463702945089607965201139450073242188e-01, // 0.700000
- 1.34164078649987383862196566042257472872734069824219e+00, // 0.800000
- 2.13453742061365581150766956852748990058898925781250e+00, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_2_1 = { //
- 1.00000000000000009561654835946237267172778046723484e-20, // 0.000000
- 1.00000000000000016567916802690831577782315520153134e-10, // 0.000010
- 1.00000000000000019428902930940239457413554191589355e-02, // 0.100000
- 1.52415567748900009775736563710779591929167509078979e-02, // 0.123457
- 4.00000000000000077715611723760957829654216766357422e-02, // 0.200000
- 7.38905609893064779791771456984861288219690322875977e-02, // 0.271828
- 8.99999999999999966693309261245303787291049957275391e-02, // 0.300000
- 9.86960440108935743719342781332670710980892181396484e-02, // 0.314159
- 1.60000000000000031086244689504383131861686706542969e-01, // 0.400000
- 2.50000000000000000000000000000000000000000000000000e-01, // 0.500000
- 3.59999999999999986677323704498121514916419982910156e-01, // 0.600000
- 4.89999999999999935607064571740920655429363250732422e-01, // 0.700000
- 6.40000000000000124344978758017532527446746826171875e-01, // 0.800000
- 8.10000000000000053290705182007513940334320068359375e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_2_1 = { //
- 2.00000000000000007286439463099548315833109413119928e-10, // 0.000000
- 2.00000000000000016360610782806261909172462765127420e-05, // 0.000010
- 2.00000000000000011102230246251565404236316680908203e-01, // 0.100000
- 2.46913400000000005096723043607198633253574371337891e-01, // 0.123457
- 4.00000000000000022204460492503130808472633361816406e-01, // 0.200000
- 5.43656365691808973750198674679268151521682739257812e-01, // 0.271828
- 5.99999999999999977795539507496869191527366638183594e-01, // 0.300000
- 6.28318530717958623199592693708837032318115234375000e-01, // 0.314159
- 8.00000000000000044408920985006261616945266723632812e-01, // 0.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.19999999999999995559107901499373838305473327636719e+00, // 0.600000
- 1.39999999999999991118215802998747676610946655273438e+00, // 0.700000
- 1.60000000000000008881784197001252323389053344726562e+00, // 0.800000
- 1.80000000000000004440892098500626161694526672363281e+00, // 0.900000
- 2.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_2_1 = { //
- 1.00000000000000114885948669623197981171571781836697e-20, // 0.000000
- 9.99999999999997968480665932928554400643816890692506e-11, // 0.000010
- 1.00000000000000054123372450476381345652043819427490e-02, // 0.100000
- 1.52415567748899975081267044174637703690677881240845e-02, // 0.123457
- 4.00000000000000077715611723760957829654216766357422e-02, // 0.200000
- 7.38905609893584225389417952101211994886398315429688e-02, // 0.271828
- 8.99999999999999827915431183100736234337091445922852e-02, // 0.300000
- 9.86960440109066056146858159081602934747934341430664e-02, // 0.314159
- 1.60000000000000003330669073875469621270895004272461e-01, // 0.400000
- 2.50000000000000000000000000000000000000000000000000e-01, // 0.500000
- 3.59999999999999986677323704498121514916419982910156e-01, // 0.600000
- 4.89999999999999935607064571740920655429363250732422e-01, // 0.700000
- 6.40000000000000235367281220533186569809913635253906e-01, // 0.800000
- 8.10000000000000053290705182007513940334320068359375e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_2_1 = { //
- 1.99999999999999593696133186585710880128763378138501e-10, // 0.000000
- 1.99999999999999982479292892634248346439562737941742e-05, // 0.000010
- 2.00000000000000066613381477509392425417900085449219e-01, // 0.100000
- 2.46913399999999977341147427978285122662782669067383e-01, // 0.123457
- 4.00000000000000022204460492503130808472633361816406e-01, // 0.200000
- 5.43656365692000043132736664119875058531761169433594e-01, // 0.271828
- 5.99999999999999866773237044981215149164199829101562e-01, // 0.300000
- 6.28318530718000034518411212047794833779335021972656e-01, // 0.314159
- 8.00000000000000044408920985006261616945266723632812e-01, // 0.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.19999999999999995559107901499373838305473327636719e+00, // 0.600000
- 1.39999999999999991118215802998747676610946655273438e+00, // 0.700000
- 1.60000000000000008881784197001252323389053344726562e+00, // 0.800000
- 1.80000000000000004440892098500626161694526672363281e+00, // 0.900000
- 2.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_2_2 = { //
- 2.99999999980000028621542970819290774575628845094157e-20, // 0.000000
- 2.99998000000000032546659169620955655288785379752881e-10, // 0.000010
- 2.80000000000000040523140398818213725462555885314941e-02, // 0.100000
- 4.19613257200888781217607004236924694851040840148926e-02, // 0.123457
- 1.04000000000000022981616609740740386769175529479980e-01, // 0.200000
- 1.81500609121544087543043133337050676345825195312500e-01, // 0.271828
- 2.16000000000000025313084961453569121658802032470703e-01, // 0.300000
- 2.34075578672081091591294921272492501884698867797852e-01, // 0.314159
- 3.52000000000000090594198809412773698568344116210938e-01, // 0.400000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 6.47999999999999909405801190587226301431655883789062e-01, // 0.600000
- 7.83999999999999919175763807288603857159614562988281e-01, // 0.700000
- 8.96000000000000018651746813702629879117012023925781e-01, // 0.800000
- 9.71999999999999975131004248396493494510650634765625e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_2_2 = { //
- 5.99999999940000036688084108105895042584165821608622e-10, // 0.000000
- 5.99994000000000069806882496692423956119455397129059e-05, // 0.000010
- 5.40000000000000146549439250520663335919380187988281e-01, // 0.100000
- 6.49290859350659999016386336734285578131675720214844e-01, // 0.123457
- 9.60000000000000186517468137026298791170120239257812e-01, // 0.200000
- 1.18762573113958813664225999673362821340560913085938e+00, // 0.271828
- 1.26000000000000000888178419700125232338905334472656e+00, // 0.300000
- 1.29277932808851447887832364358473569154739379882812e+00, // 0.314159
- 1.43999999999999994670929481799248605966567993164062e+00, // 0.400000
- 1.50000000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.43999999999999994670929481799248605966567993164062e+00, // 0.600000
- 1.26000000000000023092638912203256040811538696289062e+00, // 0.700000
- 9.59999999999999853450560749479336664080619812011719e-01, // 0.800000
- 5.39999999999999924504834325489355251193046569824219e-01, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_2_2 = { //
- 2.99999999979999607324367636111447918580453904641306e-20, // 0.000000
- 2.99997999999999722353929462235577578510525853516810e-10, // 0.000010
- 2.80000000000000109912079437890497501939535140991211e-02, // 0.100000
- 4.19613257200888642439728926092357141897082328796387e-02, // 0.123457
- 1.04000000000000022981616609740740386769175529479980e-01, // 0.200000
- 1.81500609121657580091735439964395482093095779418945e-01, // 0.271828
- 2.15999999999999942046358114566828589886426925659180e-01, // 0.300000
- 2.34075578672107875721764003174030221998691558837891e-01, // 0.314159
- 3.52000000000000035083047578154946677386760711669922e-01, // 0.400000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 6.47999999999999909405801190587226301431655883789062e-01, // 0.600000
- 7.84000000000000030198066269804257899522781372070312e-01, // 0.700000
- 8.96000000000000018651746813702629879117012023925781e-01, // 0.800000
- 9.71999999999999975131004248396493494510650634765625e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_2_2 = { //
- 5.99999999940000553675966953748191837214598365335405e-10, // 0.000000
- 5.99993999999999459943160473596179826927254907786846e-05, // 0.000010
- 5.40000000000000035527136788005009293556213378906250e-01, // 0.100000
- 6.49290859350659776971781411702977493405342102050781e-01, // 0.123457
- 9.60000000000000075495165674510644748806953430175781e-01, // 0.200000
- 1.18762573113984970518686168361455202102661132812500e+00, // 0.271828
- 1.26000000000000000888178419700125232338905334472656e+00, // 0.300000
- 1.29277932808856044211154312506550922989845275878906e+00, // 0.314159
- 1.44000000000000016875389974302379414439201354980469e+00, // 0.400000
- 1.50000000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.44000000000000016875389974302379414439201354980469e+00, // 0.600000
- 1.26000000000000000888178419700125232338905334472656e+00, // 0.700000
- 9.59999999999999853450560749479336664080619812011719e-01, // 0.800000
- 5.39999999999999813482531862973701208829879760742188e-01, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_2_4 = { //
- 9.99999999800000094982332989268162402300727516471889e-20, // 0.000000
- 9.99980000149999789015279420541053301274558862132835e-10, // 0.000010
- 8.14600000000000185051973744521092157810926437377930e-02, // 0.100000
- 1.18151979036013266011195810278877615928649902343750e-01, // 0.123457
- 2.62720000000000009077183449335279874503612518310547e-01, // 0.200000
- 4.13155570114924819424828683622763492166996002197266e-01, // 0.271828
- 4.71779999999999921644899814054952003061771392822266e-01, // 0.300000
- 5.00707755662531783791280304285464808344841003417969e-01, // 0.314159
- 6.63040000000000073754335971898399293422698974609375e-01, // 0.400000
- 8.12500000000000000000000000000000000000000000000000e-01, // 0.500000
- 9.12959999999999993747223925311118364334106445312500e-01, // 0.600000
- 9.69219999999999970441422192379832267761230468750000e-01, // 0.700000
- 9.93280000000000051763038300123298540711402893066406e-01, // 0.800000
- 9.99539999999999984048315582185750827193260192871094e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_2_4 = { //
- 1.99999999939999970416416897342568731454903740996087e-09, // 0.000000
- 1.99994000059999853073644526801899701240472495555878e-04, // 0.000010
- 1.45799999999999996269650637259474024176597595214844e+00, // 0.100000
- 1.66289483058558995587361550860805436968803405761719e+00, // 0.123457
- 2.04800000000000048672177399566862732172012329101562e+00, // 0.200000
- 2.09906591288467181399823857645969837903976440429688e+00, // 0.271828
- 2.05799999999999938538053356751333922147750854492188e+00, // 0.300000
- 2.02698108527595532990517313010059297084808349609375e+00, // 0.314159
- 1.72799999999999975841546984156593680381774902343750e+00, // 0.400000
- 1.25000000000000000000000000000000000000000000000000e+00, // 0.500000
- 7.68000000000000127009514017117908224463462829589844e-01, // 0.600000
- 3.78000000000000113686837721616029739379882812500000e-01, // 0.700000
- 1.27999999999999919397808412213635165244340896606445e-01, // 0.800000
- 1.79999999999999882316359389733406715095043182373047e-02, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_2_4 = { //
- 9.99999999799998650534874698841272610317270577776400e-20, // 0.000000
- 9.99980000149998548244360590999540994161520757188555e-10, // 0.000010
- 8.14600000000000601385607978954794816672801971435547e-02, // 0.100000
- 1.18151979036013293766771425907791126519441604614258e-01, // 0.123457
- 2.62720000000000064588334680593106895685195922851562e-01, // 0.200000
- 4.13155570115125381214227218151791021227836608886719e-01, // 0.271828
- 4.71779999999999810622597351539297960698604583740234e-01, // 0.300000
- 5.00707755662573861243913597718346863985061645507812e-01, // 0.314159
- 6.63040000000000073754335971898399293422698974609375e-01, // 0.400000
- 8.12500000000000000000000000000000000000000000000000e-01, // 0.500000
- 9.12959999999999993747223925311118364334106445312500e-01, // 0.600000
- 9.69219999999999970441422192379832267761230468750000e-01, // 0.700000
- 9.93279999999999940740735837607644498348236083984375e-01, // 0.800000
- 9.99539999999999984048315582185750827193260192871094e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_2_4 = { //
- 1.99999999940000135852539407948103705736642154988658e-09, // 0.000000
- 1.99994000059999527812992781150569499004632234573364e-04, // 0.000010
- 1.45799999999999996269650637259474024176597595214844e+00, // 0.100000
- 1.66289483058558951178440565854543820023536682128906e+00, // 0.123457
- 2.04799999999999959854335429554339498281478881835938e+00, // 0.200000
- 2.09906591288458299615626856393646448850631713867188e+00, // 0.271828
- 2.05799999999999938538053356751333922147750854492188e+00, // 0.300000
- 2.02698108527590559191366992308758199214935302734375e+00, // 0.314159
- 1.72799999999999998046007476659724488854408264160156e+00, // 0.400000
- 1.25000000000000000000000000000000000000000000000000e+00, // 0.500000
- 7.67999999999999904964909092086600139737129211425781e-01, // 0.600000
- 3.78000000000000002664535259100375697016716003417969e-01, // 0.700000
- 1.27999999999999947153384027842548675835132598876953e-01, // 0.800000
- 1.79999999999999847621889870197264826856553554534912e-02, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_4_01 = { //
- 2.98375000021482896530143510253419751265415869320405e-42, // 0.000000
- 2.98377148317007480476821711655106704510022866858290e-22, // 0.000010
- 3.21712826910625692496299710132490190517273731529713e-06, // 0.100000
- 7.61463101593263861873502745813979686317907180637121e-06, // 0.123457
- 5.59207027072549877851938282535826374441967345774174e-05, // 0.200000
- 2.03667699680023080383364786349886799143860116600990e-04, // 0.271828
- 3.10437547367714518006809321093442122219130396842957e-04, // 0.300000
- 3.78567315617660054768989219553532166173681616783142e-04, // 0.314159
- 1.08871959537661425719556884672556407167576253414154e-03, // 0.400000
- 2.99593398095022393073927347018070577178150415420532e-03, // 0.500000
- 7.15558877739638343057348990328137006144970655441284e-03, // 0.600000
- 1.57714915252002985113222166546620428562164306640625e-02, // 0.700000
- 3.38041058520913012541697639790072571486234664916992e-02, // 0.800000
- 7.65008878936773301093765553559933323413133621215820e-02, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_4_01 = { //
- 1.19350000010741456808122504902637373369716469559713e-31, // 0.000000
- 1.19351074160204525818413908323422939743433979524131e-16, // 0.000010
- 1.31221248296568523180466447897174475656356662511826e-04, // 0.100000
- 2.52854320367995155215828928518817519943695515394211e-04, // 0.123457
- 1.16716275925598492353707502644510896061547100543976e-03, // 0.200000
- 3.18930012206767362487047634544978791382163763046265e-03, // 0.271828
- 4.44219840138407838503464830637312843464314937591553e-03, // 0.300000
- 5.19602333868628314672566403942255419678986072540283e-03, // 0.314159
- 1.20966822229282636169678255555481882765889167785645e-02, // 0.400000
- 2.78393718849794802316921504825586453080177307128906e-02, // 0.500000
- 5.88060734874641527492045156577660236507654190063477e-02, // 0.600000
- 1.20978282360318822874489796959096565842628479003906e-01, // 0.700000
- 2.60114994567310464645970569108612835407257080078125e-01, // 0.800000
- 6.91114415396560488602517580147832632064819335937500e-01, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_4_01 = { //
- 2.98375000021482960253819955551510832420631780028878e-42, // 0.000000
- 2.98377148317007715575691876112608298257330311307425e-22, // 0.000010
- 3.21712826910625988957831249137608864430148969404399e-06, // 0.100000
- 7.61463101593263438357029118663810152156656840816140e-06, // 0.123457
- 5.59207027072550148902481403911934876305167563259602e-05, // 0.200000
- 2.03667699680327795403941837371064593753544613718987e-04, // 0.271828
- 3.10437547367714355376483448267777021101210266351700e-04, // 0.300000
- 3.78567315617767824464934278694272506982088088989258e-04, // 0.314159
- 1.08871959537661447403600334382645087316632270812988e-03, // 0.400000
- 2.99593398095022523178188045278602658072486519813538e-03, // 0.500000
- 7.15558877739638603265870386849201167933642864227295e-03, // 0.600000
- 1.57714915252002915724283127474336652085185050964355e-02, // 0.700000
- 3.38041058520913290097453796079207677394151687622070e-02, // 0.800000
- 7.65008878936773439871643631704500876367092132568359e-02, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_4_01 = { //
- 1.19350000010741500598699515053170839736265947369592e-31, // 0.000000
- 1.19351074160204328603187603070471586811292658827574e-16, // 0.000010
- 1.31221248296568631600683696447617876401636749505997e-04, // 0.100000
- 2.52854320367994938375394431417930718453135341405869e-04, // 0.123457
- 1.16716275925598514037750952354599576210603117942810e-03, // 0.200000
- 3.18930012207141325500381334734356642002239823341370e-03, // 0.271828
- 4.44219840138407751767291031796958122868090867996216e-03, // 0.300000
- 5.19602333868745148298673441900064062792807817459106e-03, // 0.314159
- 1.20966822229282670864147775091623771004378795623779e-02, // 0.400000
- 2.78393718849794941094799582970154006034135818481445e-02, // 0.500000
- 5.88060734874641596880984195649944012984633445739746e-02, // 0.600000
- 1.20978282360318822874489796959096565842628479003906e-01, // 0.700000
- 2.60114994567310464645970569108612835407257080078125e-01, // 0.800000
- 6.91114415396560599624820042663486674427986145019531e-01, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_4_05 = { //
- 2.73437500010937531608195608847323954680264550128516e-41, // 0.000000
- 2.73438593756836093040429464081171992743562950508136e-21, // 0.000010
- 2.85111486302981175650073097926906484644860029220581e-05, // 0.100000
- 6.69233684394836031601727643902677300502546131610870e-05, // 0.123457
- 4.77614057594005748073884287663304348825477063655853e-04, // 0.200000
- 1.68960523493624824656333949235431646229699254035950e-03, // 0.271828
- 2.54437461640680739546893640579128259560093283653259e-03, // 0.300000
- 3.08346021657933443485544167117495817365124821662903e-03, // 0.314159
- 8.51626337090127978612930093049726565368473529815674e-03, // 0.400000
- 2.22039041404772513610410555884300265461206436157227e-02, // 0.500000
- 4.97355631194020056384808015081944176927208900451660e-02, // 0.600000
- 1.01221515793866442822768192399962572380900382995605e-01, // 0.700000
- 1.95015528100075691275705480620672460645437240600586e-01, // 0.800000
- 3.73374917402259476340020682982867583632469177246094e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_4_05 = { //
- 1.09375000005468786566718251296557641016341269128500e-30, // 0.000000
- 1.09375546879101630526115027849392190014539904489160e-15, // 0.000010
- 1.15291373026972206530804676560819643782451748847961e-03, // 0.100000
- 2.19824134059588231077109199418373464141041040420532e-03, // 0.123457
- 9.78279740156158365838034995931593584828078746795654e-03, // 0.200000
- 2.57445069421568979717296343778798473067581653594971e-02, // 0.271828
- 3.52965948694063183510571946044365176931023597717285e-02, // 0.300000
- 4.09502017884755334375945778901950689032673835754395e-02, // 0.314159
- 9.03696114115064286220757594492170028388500213623047e-02, // 0.400000
- 1.93349510480696623604401906959537882357835769653320e-01, // 0.500000
- 3.73544048607389767013842174492310732603073120117188e-01, // 0.600000
- 6.84938469046824871533374334831023588776588439941406e-01, // 0.700000
- 1.25219806739988270827268479479243978857994079589844e+00, // 0.800000
- 2.52142232809988220409991299675311893224716186523438e+00, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_4_05 = { //
- 2.73437500010936715945137109031758115893500893060072e-41, // 0.000000
- 2.73438593756835415955683390443567402751317510494625e-21, // 0.000010
- 2.85111486302981480581934109475028549240960273891687e-05, // 0.100000
- 6.69233684394835353975369840462406045844545587897301e-05, // 0.123457
- 4.77614057594005693863775663388082648452837020158768e-04, // 0.200000
- 1.68960523493870678340966762220887176226824522018433e-03, // 0.271828
- 2.54437461640680566074546042898418818367645144462585e-03, // 0.300000
- 3.08346021658018184727345634144057839876040816307068e-03, // 0.314159
- 8.51626337090127805140582495369017124176025390625000e-03, // 0.400000
- 2.22039041404772374832532477739732712507247924804688e-02, // 0.500000
- 4.97355631194019570662234741575957741588354110717773e-02, // 0.600000
- 1.01221515793866317922677922069851774722337722778320e-01, // 0.700000
- 1.95015528100075719031281096249585971236228942871094e-01, // 0.800000
- 3.73374917402259698384625608014175668358802795410156e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_4_05 = { //
- 1.09375000005468611404410210694423775550143357888984e-30, // 0.000000
- 1.09375546879101808019818702577048407653467093116062e-15, // 0.000010
- 1.15291373026972206530804676560819643782451748847961e-03, // 0.100000
- 2.19824134059588057604761601737664022948592901229858e-03, // 0.123457
- 9.78279740156158712782730191293012467212975025177002e-03, // 0.200000
- 2.57445069421857186675595130509464070200920104980469e-02, // 0.271828
- 3.52965948694062836565876750682946294546127319335938e-02, // 0.300000
- 4.09502017884842486883378853690373944118618965148926e-02, // 0.314159
- 9.03696114115064008665001438203034922480583190917969e-02, // 0.400000
- 1.93349510480696651359977522588451392948627471923828e-01, // 0.500000
- 3.73544048607389822524993405750137753784656524658203e-01, // 0.600000
- 6.84938469046824760511071872315369546413421630859375e-01, // 0.700000
- 1.25219806739988248622807986976113170385360717773438e+00, // 0.800000
- 2.52142232809988176001070314669050276279449462890625e+00, // 0.900000
- Double.POSITIVE_INFINITY, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_4_1 = { //
- 1.00000000000000013320864402483403646202733603332908e-40, // 0.000000
- 1.00000000000000039654310216996797471172433399612973e-20, // 0.000010
- 1.00000000000000018344700758454735023406101390719414e-04, // 0.100000
- 2.32305052922195277983682948352850416995352134108543e-04, // 0.123457
- 1.60000000000000029351521213527576037449762225151062e-03, // 0.200000
- 5.45981500331442059364972507751190278213471174240112e-03, // 0.271828
- 8.09999999999999956146190527306316653266549110412598e-03, // 0.300000
- 9.74090910340024221381050040236004861071705818176270e-03, // 0.314159
- 2.56000000000000046962433941644121659919619560241699e-02, // 0.400000
- 6.25000000000000000000000000000000000000000000000000e-02, // 0.500000
- 1.29599999999999992983390484369010664522647857666016e-01, // 0.600000
- 2.40099999999999952349227783088281285017728805541992e-01, // 0.700000
- 4.09600000000000075139894306630594655871391296386719e-01, // 0.800000
- 6.56100000000000016520118606422329321503639221191406e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_4_1 = { //
- 4.00000000000000033334568243034394140372534410747462e-30, // 0.000000
- 4.00000000000000109968250472765612236495730768756629e-15, // 0.000010
- 4.00000000000000095062846483529028773773461580276489e-03, // 0.100000
- 7.52668920916224962192053737908281618729233741760254e-03, // 0.123457
- 3.20000000000000076050277186823223019018769264221191e-02, // 0.200000
- 8.03421476927506372778253762589883990585803985595703e-02, // 0.271828
- 1.07999999999999984900966865097871050238609313964844e-01, // 0.300000
- 1.24025106721199263049015826254617422819137573242188e-01, // 0.314159
- 2.56000000000000060840221749458578415215015411376953e-01, // 0.400000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 8.63999999999999879207734920782968401908874511718750e-01, // 0.600000
- 1.37199999999999966426855735335266217589378356933594e+00, // 0.700000
- 2.04800000000000048672177399566862732172012329101562e+00, // 0.800000
- 2.91600000000000036948222259525209665298461914062500e+00, // 0.900000
- 4.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_4_1 = { //
- 1.00000000000000217236629027437295105899424517600020e-40, // 0.000000
- 9.99999999999995882644795012383944111776031062706330e-21, // 0.000010
- 1.00000000000000113212390850936372999058221466839314e-04, // 0.100000
- 2.32305052922195169563465699802407016250072047114372e-04, // 0.123457
- 1.60000000000000094403651562657842077896930277347565e-03, // 0.200000
- 5.45981500332209674503092244890467554796487092971802e-03, // 0.271828
- 8.09999999999999782673842929625607212074100971221924e-03, // 0.300000
- 9.74090910340281480872537400728106149472296237945557e-03, // 0.314159
- 2.56000000000000012267964422107979771681129932403564e-02, // 0.400000
- 6.25000000000000000000000000000000000000000000000000e-02, // 0.500000
- 1.29599999999999965227814868740097153931856155395508e-01, // 0.600000
- 2.40099999999999924593652167459367774426937103271484e-01, // 0.700000
- 4.09600000000000130651045537888421677052974700927734e-01, // 0.800000
- 6.56100000000000127542421068937983363866806030273438e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_4_1 = { //
- 4.00000000000002415541957595223414710712826003604885e-30, // 0.000000
- 3.99999999999999084449073685450265201248595901134530e-15, // 0.000010
- 4.00000000000000181799020282369383494369685649871826e-03, // 0.100000
- 7.52668920916224701983532341387217456940561532974243e-03, // 0.123457
- 3.20000000000000214828155264967790571972727775573730e-02, // 0.200000
- 8.03421476928353334168164678885659668594598770141602e-02, // 0.271828
- 1.07999999999999957145391249468957539647817611694336e-01, // 0.300000
- 1.24025106721223812855647850028617540374398231506348e-01, // 0.314159
- 2.56000000000000060840221749458578415215015411376953e-01, // 0.400000
- 5.00000000000000111022302462515654042363166809082031e-01, // 0.500000
- 8.63999999999999879207734920782968401908874511718750e-01, // 0.600000
- 1.37199999999999966426855735335266217589378356933594e+00, // 0.700000
- 2.04800000000000004263256414560601115226745605468750e+00, // 0.800000
- 2.91600000000000036948222259525209665298461914062500e+00, // 0.900000
- 4.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_4_2 = { //
- 4.99999999960000092956526294536008149911609020135072e-40, // 0.000000
- 4.99996000000000182972062623064444698658055305533981e-20, // 0.000010
- 4.60000000000000122332699525884436297928914427757263e-04, // 0.100000
- 1.04680680370257796554800400201656884746626019477844e-03, // 0.123457
- 6.72000000000000114602771716931783885229378938674927e-03, // 0.200000
- 2.13625486524690426370920448562173987738788127899170e-02, // 0.271828
- 3.07799999999999983335552400376400328241288661956787e-02, // 0.300000
- 3.64637581255899539955933619239658582955598831176758e-02, // 0.314159
- 8.70400000000000062527760746888816356658935546875000e-02, // 0.400000
- 1.87500000000000000000000000000000000000000000000000e-01, // 0.500000
- 3.36959999999999981756815259359427727758884429931641e-01, // 0.600000
- 5.28219999999999911821646492171566933393478393554688e-01, // 0.700000
- 7.37280000000000157456270244438201189041137695312500e-01, // 0.800000
- 9.18540000000000023128166048991261050105094909667969e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_4_2 = { //
- 1.99999999980000012361177456368779558183353543188356e-29, // 0.000000
- 1.99998000000000044302004307985331939009172267512904e-14, // 0.000010
- 1.80000000000000021094237467877974268049001693725586e-02, // 0.100000
- 3.29873449873673424415088106798066291958093643188477e-02, // 0.123457
- 1.28000000000000030420110874729289207607507705688477e-01, // 0.200000
- 2.92514438397464715535534196533262729644775390625000e-01, // 0.271828
- 3.77999999999999891642232796584721654653549194335938e-01, // 0.300000
- 4.25307351537991429335505699782515875995159149169922e-01, // 0.314159
- 7.68000000000000127009514017117908224463462829589844e-01, // 0.400000
- 1.25000000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.72799999999999975841546984156593680381774902343750e+00, // 0.600000
- 2.05799999999999982946974341757595539093017578125000e+00, // 0.700000
- 2.04800000000000004263256414560601115226745605468750e+00, // 0.800000
- 1.45799999999999974065190144756343215703964233398438e+00, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_4_2 = { //
- 4.99999999960002458379395944001149082393223625633561e-40, // 0.000000
- 4.99995999999999340377711953648758986667705424628279e-20, // 0.000010
- 4.60000000000000501803459895810988200537394732236862e-04, // 0.100000
- 1.04680680370257774870756950491568204597570002079010e-03, // 0.123457
- 6.72000000000000461547466912293202767614275217056274e-03, // 0.200000
- 2.13625486524969925017369831721225637011229991912842e-02, // 0.271828
- 3.07799999999999948641082880840258440002799034118652e-02, // 0.300000
- 3.64637581255987802686391319184622261673212051391602e-02, // 0.314159
- 8.70400000000000062527760746888816356658935546875000e-02, // 0.400000
- 1.87499999999999972244424384371086489409208297729492e-01, // 0.500000
- 3.36959999999999926245664028101600706577301025390625e-01, // 0.600000
- 5.28220000000000022843948954687220975756645202636719e-01, // 0.700000
- 7.37280000000000046433967781922547146677970886230469e-01, // 0.800000
- 9.18540000000000023128166048991261050105094909667969e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_4_2 = { //
- 1.99999999980001413659641781185850481912936833104487e-29, // 0.000000
- 1.99998000000000801608473320156665134268594938987684e-14, // 0.000010
- 1.80000000000000159872115546022541821002960205078125e-02, // 0.100000
- 3.29873449873673146859331950508931186050176620483398e-02, // 0.123457
- 1.28000000000000058175686490358202718198299407958984e-01, // 0.200000
- 2.92514438397734666263971803346066735684871673583984e-01, // 0.271828
- 3.77999999999999669597627871553413569927215576171875e-01, // 0.300000
- 4.25307351538062705653686634832411073148250579833984e-01, // 0.314159
- 7.67999999999999904964909092086600139737129211425781e-01, // 0.400000
- 1.25000000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.72799999999999998046007476659724488854408264160156e+00, // 0.600000
- 2.05799999999999938538053356751333922147750854492188e+00, // 0.700000
- 2.04799999999999959854335429554339498281478881835938e+00, // 0.800000
- 1.45799999999999929656269159750081598758697509765625e+00, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_CDF_4_4 = { //
- 3.49999999916000016318033258661157178322633534961105e-39, // 0.000000
- 3.49991600069999950401327387562812102476143042072235e-19, // 0.000010
- 2.72800000000000038985481509712371916975826025009155e-03, // 0.100000
- 5.96069507924967562778606477991161227691918611526489e-03, // 0.123457
- 3.33440000000000055790927433463366469368338584899902e-02, // 0.200000
- 9.24732206974749615380204659231822006404399871826172e-02, // 0.271828
- 1.26036000000000009135803225035488139837980270385742e-01, // 0.300000
- 1.45131940494089783921793923582299612462520599365234e-01, // 0.314159
- 2.89791999999999994042099160651559941470623016357422e-01, // 0.400000
- 4.99999999999999888977697537484345957636833190917969e-01, // 0.500000
- 7.10207999999999950446749608090613037347793579101562e-01, // 0.600000
- 8.73963999999999963108621159335598349571228027343750e-01, // 0.700000
- 9.66656000000000070748740199633175507187843322753906e-01, // 0.800000
- 9.97272000000000047315040774265071377158164978027344e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_BETA_PDF_4_4 = { //
- 1.39999999958000002624274888250361173924268353172324e-28, // 0.000000
- 1.39995800041999896773103113821248488557241404506293e-13, // 0.000010
- 1.02060000000000025699442574023123597726225852966309e-01, // 0.100000
- 1.77415741797289500114587212920014280825853347778320e-01, // 0.123457
- 5.73440000000000171809233506792224943637847900390625e-01, // 0.200000
- 1.08570810499605374666032275854377076029777526855469e+00, // 0.271828
- 1.29653999999999935965888653299771249294281005859375e+00, // 0.300000
- 1.40038510081151179598180078755831345915794372558594e+00, // 0.314159
- 1.93535999999999996923349954158766195178031921386719e+00, // 0.400000
- 2.18750000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.93535999999999996923349954158766195178031921386719e+00, // 0.600000
- 1.29654000000000024783730623312294483184814453125000e+00, // 0.700000
- 5.73439999999999727720023656729608774185180664062500e-01, // 0.800000
- 1.02059999999999942432715727136383065953850746154785e-01, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_CDF_4_4 = { //
- 3.49999999915999951064988578675911911219692442395630e-39, // 0.000000
- 3.49991600069999998549575997243708428875591606695418e-19, // 0.000010
- 2.72800000000000125721655308552726637572050094604492e-03, // 0.100000
- 5.96069507924966868889216087268323462922126054763794e-03, // 0.123457
- 3.33440000000000194568805511607934022322297096252441e-02, // 0.200000
- 9.24732206975786980018838789874280337244272232055664e-02, // 0.271828
- 1.26035999999999953624651993777661118656396865844727e-01, // 0.300000
- 1.45131940494118955031765949570399243384599685668945e-01, // 0.314159
- 2.89792000000000049553250391909386962652206420898438e-01, // 0.400000
- 4.99999999999999944488848768742172978818416595458984e-01, // 0.500000
- 7.10207999999999950446749608090613037347793579101562e-01, // 0.600000
- 8.73963999999999963108621159335598349571228027343750e-01, // 0.700000
- 9.66655999999999959726437737117521464824676513671875e-01, // 0.800000
- 9.97271999999999936292738311749417334794998168945312e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_BETA_PDF_4_4 = { //
- 1.39999999957999778416520596279629826127535026785743e-28, // 0.000000
- 1.39995800042000149208592784545026220310382294997886e-13, // 0.000010
- 1.02060000000000108966169420909864129498600959777832e-01, // 0.100000
- 1.77415741797289527870162828548927791416645050048828e-01, // 0.123457
- 5.73439999999999949764628581760916858911514282226562e-01, // 0.200000
- 1.08570810499677206095725523482542484998703002929688e+00, // 0.271828
- 1.29653999999999958170349145802902057766914367675781e+00, // 0.300000
- 1.40038510081166234222393995878519490361213684082031e+00, // 0.314159
- 1.93536000000000041332270939165027812123298645019531e+00, // 0.400000
- 2.18750000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.93536000000000041332270939165027812123298645019531e+00, // 0.600000
- 1.29653999999999958170349145802902057766914367675781e+00, // 0.700000
- 5.73439999999999505675418731698300689458847045898438e-01, // 0.800000
- 1.02060000000000011821654766208666842430830001831055e-01, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] P_QUANT = { //
- 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99, 0.999, 0.9999 //
- };
-
- public static final double[] SCIPY_BETA_QUANT_01_01 = { //
- 8.86928065555026613565596956864396236737615274357892e-38, // 0.000100
- 8.86928065555024393294670900210330809197198311562804e-28, // 0.001000
- 8.86928065555025006242057470083821192914616784639358e-18, // 0.010000
- 8.86928001193459112153072432249700796091929078102112e-08, // 0.100000
- 8.45255532847129752160864057941580540500581264495850e-04, // 0.250000
- 5.00000000000000777156117237609578296542167663574219e-01, // 0.500000
- 9.99154744467152911013840821397025138139724731445312e-01, // 0.750000
- 9.99999911307199895738051509397337213158607482910156e-01, // 0.900000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.990000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.999000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_01_01 = { //
- 8.86928065555028388448412252463067501937612992138827e-38, // 0.000100
- 8.86928065555027263153925837435692060995384889311041e-28, // 0.001000
- 8.86928065555026392911617428893635393218735445787027e-18, // 0.010000
- 8.86928001193460965037644551031692508047399314818904e-08, // 0.100000
- 8.45255532847132245825860774601778757642023265361786e-04, // 0.250000
- 4.99999999999999500399638918679556809365749359130859e-01, // 0.500000
- 9.99154744467152911013840821397025138139724731445312e-01, // 0.750000
- 9.99999911307199895738051509397337213158607482910156e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.990000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.999000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_01_05 = { //
- 3.46456275607431455261002811459588941188867309477607e-40, // 0.000100
- 3.46456275607431613825500469117221110902093083941640e-30, // 0.001000
- 3.46456275607430439357088457229084493496058065920175e-20, // 0.010000
- 3.46456275552870422056197107589232790647582049814446e-10, // 0.100000
- 3.30405955584976185706561242760859187228561495430768e-06, // 0.250000
- 3.37816430372528137687782034959127486217767000198364e-03, // 0.500000
- 1.78799793029011389045024316146736964583396911621094e-01, // 0.750000
- 7.32777808689458409752148781990399584174156188964844e-01, // 0.900000
- 9.96800847460084904483323953172657638788223266601562e-01, // 0.990000
- 9.99967947541768209518409094016533344984054565429688e-01, // 0.999000
- 9.99999679469315005952978481218451634049415588378906e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_01_05 = { //
- 3.46456275607432760321896411164494283247689160787118e-40, // 0.000100
- 3.46456275607431613825500469117221110902093083941640e-30, // 0.001000
- 3.46456275607431342136749888745890613485718652604856e-20, // 0.010000
- 3.46456275552870783947715099538840546888884830423194e-10, // 0.100000
- 3.30405955584976524519740144480994814557561767287552e-06, // 0.250000
- 3.37816430372529221889954520463561493670567870140076e-03, // 0.500000
- 1.78799793029011944156536628725007176399230957031250e-01, // 0.750000
- 7.32777808689457965662938931927783414721488952636719e-01, // 0.900000
- 9.96800847460084904483323953172657638788223266601562e-01, // 0.990000
- 9.99967947541768209518409094016533344984054565429688e-01, // 0.999000
- 9.99999679469315005952978481218451634049415588378906e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_01_1 = { //
- 1.00000000000000298802934877418851689778100883306864e-40, // 0.000100
- 1.00000000000000218528411709481159173652571096174285e-30, // 0.001000
- 1.00000000000000084793293288572637777171916428947207e-20, // 0.010000
- 9.99999999999999131703402335623722188562290114077769e-11, // 0.100000
- 9.53674316406248835329697525337033781056561565492302e-07, // 0.250000
- 9.76562499999998590537175768844235790311358869075775e-04, // 0.500000
- 5.63135147094726076777426726494013564661145210266113e-02, // 0.750000
- 3.48678440099999320533896707274834625422954559326172e-01, // 0.900000
- 9.04382075008804409144147484767017886042594909667969e-01, // 0.990000
- 9.90044880209748234811684142187004908919334411621094e-01, // 0.999000
- 9.99000449880021124116069586307276040315628051757812e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_01_1 = { //
- 1.00000000000000665851311202335856317232144528987664e-40, // 0.000100
- 1.00000000000000673950412615046707223864685665397028e-30, // 0.001000
- 1.00000000000000445905157861179360225167780663621080e-20, // 0.010000
- 1.00000000000000313835949438935152234694814232796034e-10, // 0.100000
- 9.53674316406252541098841762901017204967502038925886e-07, // 0.250000
- 9.76562500000002385244779468109754816396161913871765e-04, // 0.500000
- 5.63135147094727672723024625156540423631668090820312e-02, // 0.750000
- 3.48678440100000486268072563689202070236206054687500e-01, // 0.900000
- 9.04382075008804409144147484767017886042594909667969e-01, // 0.990000
- 9.90044880209748234811684142187004908919334411621094e-01, // 0.999000
- 9.99000449880021124116069586307276040315628051757812e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_01_2 = { //
- 3.85543289429533451133658448963742592666926086214652e-41, // 0.000100
- 3.85543289429532603687340095433216245505652506485049e-31, // 0.001000
- 3.85543289429532404962034705548650193823057760610265e-21, // 0.010000
- 3.85543289443045237890743375235041599455310112887219e-11, // 0.100000
- 3.67682855892327505770053293690513562808064307319000e-07, // 0.250000
- 3.76636057551797004145505143313243934244383126497269e-04, // 0.500000
- 2.21534346953469116203727651281951693817973136901855e-02, // 0.750000
- 1.54915841004560961291502962922095321118831634521484e-01, // 0.900000
- 6.27148329248184310813485353719443082809448242187500e-01, // 0.990000
- 8.70585822529799657765181564172962680459022521972656e-01, // 0.999000
- 9.57904427593739837831776640086900442838668823242188e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_01_2 = { //
- 3.85543289429538701964597541526447679856717128592763e-41, // 0.000100
- 3.85543289429535537655999775518958492064467519746949e-31, // 0.001000
- 3.85543289429532931583503873933453763817026436176329e-21, // 0.010000
- 3.85543289443044591655889818182170606167269433228739e-11, // 0.100000
- 3.67682855892327611649171700478055946348376892274246e-07, // 0.250000
- 3.76636057551797437826374137515017537225503474473953e-04, // 0.500000
- 2.21534346953469185592666690354235470294952392578125e-02, // 0.750000
- 1.54915841004561238847259119211230427026748657226562e-01, // 0.900000
- 6.27148329248184310813485353719443082809448242187500e-01, // 0.990000
- 8.70585822529799657765181564172962680459022521972656e-01, // 0.999000
- 9.57904427593739837831776640086900442838668823242188e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_01_4 = { //
- 1.70520173780031775915342203870768816354885853037205e-41, // 0.000100
- 1.70520173780031788553917314540519037060879260315405e-31, // 0.001000
- 1.70520173780031400068231169360407429564207370948071e-21, // 0.010000
- 1.70520173787961264841636790620568427459535776335997e-11, // 0.100000
- 1.62620782287267823496376044703493057852483616443351e-07, // 0.250000
- 1.66599281457928790261754925516868297563632950186729e-04, // 0.500000
- 9.86339324158605999792737151210531010292470455169678e-03, // 0.750000
- 7.19532648151699621985599719664605800062417984008789e-02, // 0.900000
- 3.58513695489701578189567499066470190882682800292969e-01, // 0.990000
- 6.07588693735668705642183340387418866157531738281250e-01, // 0.999000
- 7.70239957250841489333481604262487962841987609863281e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_01_4 = { //
- 1.70520173780032387662636078732443195444958595838538e-41, // 0.000100
- 1.70520173780031000323531131830916642462988659737581e-31, // 0.001000
- 1.70520173780030873446762000975603859570238695382007e-21, // 0.010000
- 1.70520173787960327801099132893905487191876790831202e-11, // 0.100000
- 1.62620782287266764705191976828069222449357766890898e-07, // 0.250000
- 1.66599281457928193950560058489429593464592471718788e-04, // 0.500000
- 9.86339324158602703818132795277051627635955810546875e-03, // 0.750000
- 7.19532648151695042315623140893876552581787109375000e-02, // 0.900000
- 3.58513695489701134100357649003854021430015563964844e-01, // 0.990000
- 6.07588693735668594619880877871764823794364929199219e-01, // 0.999000
- 7.70239957250841489333481604262487962841987609863281e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_05_01 = { //
- 3.20530684976785390026245365149848431940426962682977e-07, // 0.000100
- 3.20524582318020690016244222952934705972438678145409e-05, // 0.001000
- 3.19915253991507426631346611145545466570183634757996e-03, // 0.010000
- 2.67222191310541978825909836814389564096927642822266e-01, // 0.100000
- 8.21200206970988388910370758821954950690269470214844e-01, // 0.250000
- 9.96621835696274716021036965685198083519935607910156e-01, // 0.500000
- 9.99996695940444157990611984132556244730949401855469e-01, // 0.750000
- 9.99999999653543691913171187479747459292411804199219e-01, // 0.900000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.990000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.999000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_05_01 = { //
- 3.20530684976785442965804568543619623710583255160600e-07, // 0.000100
- 3.20524582318020825541515783640988956904038786888123e-05, // 0.001000
- 3.19915253991507513367520409985900187166407704353333e-03, // 0.010000
- 2.67222191310542089848212299330043606460094451904297e-01, // 0.100000
- 8.21200206970988055843463371274992823600769042968750e-01, // 0.250000
- 9.96621835696274716021036965685198083519935607910156e-01, // 0.500000
- 9.99996695940444157990611984132556244730949401855469e-01, // 0.750000
- 9.99999999653543691913171187479747459292411804199219e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.990000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.999000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_05_05 = { //
- 2.46740107997877850811582013451292438865891654131701e-08, // 0.000100
- 2.46739907091694248724746130196905369302839972078800e-06, // 0.001000
- 2.46719817134221513794251068318885700136888772249222e-04, // 0.010000
- 2.44717418524231997145612638178135966882109642028809e-02, // 0.100000
- 1.46446609406726185875768919686379376798868179321289e-01, // 0.250000
- 4.99999999999999666933092612453037872910499572753906e-01, // 0.500000
- 8.53553390593273841879806695942534133791923522949219e-01, // 0.750000
- 9.75528258147576821102120447903871536254882812500000e-01, // 0.900000
- 9.99753280182865800007618872768944129347801208496094e-01, // 0.990000
- 9.99997532600929051049831741693196818232536315917969e-01, // 0.999000
- 9.99999975325989165497730937204323709011077880859375e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_05_05 = { //
- 2.46740107997877950073255519814613423434934702527244e-08, // 0.000100
- 2.46739907091694375779688218341956229551215074025095e-06, // 0.001000
- 2.46719817134221622214468316869329100882168859243393e-04, // 0.010000
- 2.44717418524232274701368794467271072790026664733887e-02, // 0.100000
- 1.46446609406726185875768919686379376798868179321289e-01, // 0.250000
- 4.99999999999999167332731531132594682276248931884766e-01, // 0.500000
- 8.53553390593273841879806695942534133791923522949219e-01, // 0.750000
- 9.75528258147576821102120447903871536254882812500000e-01, // 0.900000
- 9.99753280182865800007618872768944129347801208496094e-01, // 0.990000
- 9.99997532600929051049831741693196818232536315917969e-01, // 0.999000
- 9.99999975325989165497730937204323709011077880859375e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_05_1 = { //
- 1.00000000000000018635868334073400764960837250328041e-08, // 0.000100
- 1.00000000000000016650634863946134345269456389360130e-06, // 0.001000
- 1.00000000000000004792173602385929598312941379845142e-04, // 0.010000
- 1.00000000000000002081668171172168513294309377670288e-02, // 0.100000
- 6.25000000000000000000000000000000000000000000000000e-02, // 0.250000
- 2.50000000000000000000000000000000000000000000000000e-01, // 0.500000
- 5.62500000000000000000000000000000000000000000000000e-01, // 0.750000
- 8.10000000000000053290705182007513940334320068359375e-01, // 0.900000
- 9.80099999999999971223019201715942472219467163085938e-01, // 0.990000
- 9.98001000000000026979307676811004057526588439941406e-01, // 0.999000
- 9.99800010000000072274417561857262626290321350097656e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_05_1 = { //
- 1.00000000000000018635868334073400764960837250328041e-08, // 0.000100
- 1.00000000000000037826458545303642821977518906351179e-06, // 0.001000
- 1.00000000000000086107336538798762148871901445090771e-04, // 0.010000
- 1.00000000000000036776137690708310401532799005508423e-02, // 0.100000
- 6.25000000000000277555756156289135105907917022705078e-02, // 0.250000
- 2.50000000000000000000000000000000000000000000000000e-01, // 0.500000
- 5.62499999999999777955395074968691915273666381835938e-01, // 0.750000
- 8.10000000000000053290705182007513940334320068359375e-01, // 0.900000
- 9.80099999999999971223019201715942472219467163085938e-01, // 0.990000
- 9.98001000000000026979307676811004057526588439941406e-01, // 0.999000
- 9.99800010000000072274417561857262626290321350097656e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_05_2 = { //
- 4.44444445761316705817644639965255382030306918750284e-09, // 0.000100
- 4.44444576131755449727476570478956752197063906351104e-07, // 0.001000
- 4.44457613851590344110700780966283218731405213475227e-05, // 0.010000
- 4.45768188762137376746075290157023118808865547180176e-03, // 0.100000
- 2.83095437186913906346674707492638844996690750122070e-02, // 0.250000
- 1.20614758428183241334430420010903617367148399353027e-01, // 0.500000
- 3.11224179038489423554381119174649938941001892089844e-01, // 0.750000
- 5.31877433473580407685687987395795062184333801269531e-01, // 0.900000
- 8.41255287053071842962026494205929338932037353515625e-01, // 0.990000
- 9.48808055284168672116607012867461889982223510742188e-01, // 0.999000
- 9.83714619081483720997027830890147015452384948730469e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_05_2 = { //
- 4.44444445761315465046725810423743074917268813806004e-09, // 0.000100
- 4.44444576131755290908798960297643176886595028918236e-07, // 0.001000
- 4.44457613851590750686515463030445971526205539703369e-05, // 0.010000
- 4.45768188762137550218422887837732560001313686370850e-03, // 0.100000
- 2.83095437186913941041144227028780733235180377960205e-02, // 0.250000
- 1.20614758428183130312127957495249575003981590270996e-01, // 0.500000
- 3.11224179038489201509776194143341854214668273925781e-01, // 0.750000
- 5.31877433473580518707990449911449104547500610351562e-01, // 0.900000
- 8.41255287053071842962026494205929338932037353515625e-01, // 0.990000
- 9.48808055284168672116607012867461889982223510742188e-01, // 0.999000
- 9.83714619081483720997027830890147015452384948730469e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_05_4 = { //
- 2.08979592710184102207603484900426404902162857979420e-09, // 0.000100
- 2.08979679181727248935671503900224355021464361925609e-07, // 0.001000
- 2.08988326860078756129837640465041204151930287480354e-05, // 0.010000
- 2.09858372142358862166844346575089730322360992431641e-03, // 0.100000
- 1.34159346080160047504081788360963400918990373611450e-02, // 0.250000
- 5.87108013397836248081773646845249459147453308105469e-02, // 0.500000
- 1.61283978400102917527547674581001047044992446899414e-01, // 0.750000
- 3.01792928793774728468690682348096743226051330566406e-01, // 0.900000
- 5.84601685951977589894568154704757034778594970703125e-01, // 0.990000
- 7.60584846730546160209485151426633819937705993652344e-01, // 0.999000
- 8.63700924381154200304422374756541103124618530273438e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_05_4 = { //
- 2.08979592710183854053419718992123943479555236990564e-09, // 0.000100
- 2.08979679181727301875230707293995546791620654403232e-07, // 0.001000
- 2.08988326860079027180380761841149706015130504965782e-05, // 0.010000
- 2.09858372142358948903018145415444450918585062026978e-03, // 0.100000
- 1.34159346080160134240255587201318121515214443206787e-02, // 0.250000
- 5.87108013397836039914956529628398129716515541076660e-02, // 0.500000
- 1.61283978400102778749669596436433494091033935546875e-01, // 0.750000
- 3.01792928793774506424085757316788658499717712402344e-01, // 0.900000
- 5.84601685951977145805358304642140865325927734375000e-01, // 0.990000
- 7.60584846730546049187182688910979777574539184570312e-01, // 0.999000
- 8.63700924381154200304422374756541103124618530273438e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_1_01 = { //
- 9.99550119979002518744159999641851754859089851379395e-04, // 0.000100
- 9.95511979025178947444452148829441284760832786560059e-03, // 0.001000
- 9.56179249911954937113378605317848268896341323852539e-02, // 0.010000
- 6.51321559899999957821137286373414099216461181640625e-01, // 0.100000
- 9.43686485290527454772302462515654042363166809082031e-01, // 0.250000
- 9.99023437500000000000000000000000000000000000000000e-01, // 0.500000
- 9.99999046325683593750000000000000000000000000000000e-01, // 0.750000
- 9.99999999899999991725962900090962648391723632812500e-01, // 0.900000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.990000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.999000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_1_01 = { //
- 9.99550119979002735584594496742738556349650025367737e-04, // 0.000100
- 9.95511979025179120916799746510150725953280925750732e-03, // 0.001000
- 9.56179249911955353447012839751550927758216857910156e-02, // 0.010000
- 6.51321559899999735776532361342106014490127563476562e-01, // 0.100000
- 9.43686485290527232727697537484345957636833190917969e-01, // 0.250000
- 9.99023437500000000000000000000000000000000000000000e-01, // 0.500000
- 9.99999046325683593750000000000000000000000000000000e-01, // 0.750000
- 9.99999999899999991725962900090962648391723632812500e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.990000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.999000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_1_05 = { //
- 1.99989999999999987657234301607900306407827883958817e-04, // 0.000100
- 1.99899999999999990890620082950590585824102163314819e-03, // 0.001000
- 1.99000000000000010214051826551440171897411346435547e-02, // 0.010000
- 1.90000000000000002220446049250313080847263336181641e-01, // 0.100000
- 4.37500000000000055511151231257827021181583404541016e-01, // 0.250000
- 7.50000000000000111022302462515654042363166809082031e-01, // 0.500000
- 9.37500000000000000000000000000000000000000000000000e-01, // 0.750000
- 9.89999999999999991118215802998747676610946655273438e-01, // 0.900000
- 9.99900000000000011013412404281552881002426147460938e-01, // 0.990000
- 9.99998999999999971244335483788745477795600891113281e-01, // 0.999000
- 9.99999989999999949752407246705843135714530944824219e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_1_05 = { //
- 1.99989999999999987657234301607900306407827883958817e-04, // 0.000100
- 1.99899999999999990890620082950590585824102163314819e-03, // 0.001000
- 1.99000000000000010214051826551440171897411346435547e-02, // 0.010000
- 1.90000000000000057731597280508140102028846740722656e-01, // 0.100000
- 4.37500000000000166533453693773481063544750213623047e-01, // 0.250000
- 7.50000000000000000000000000000000000000000000000000e-01, // 0.500000
- 9.37500000000000000000000000000000000000000000000000e-01, // 0.750000
- 9.89999999999999991118215802998747676610946655273438e-01, // 0.900000
- 9.99900000000000011013412404281552881002426147460938e-01, // 0.990000
- 9.99998999999999971244335483788745477795600891113281e-01, // 0.999000
- 9.99999989999999949752407246705843135714530944824219e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_1_1 = { //
- 1.00000000000000004792173602385929598312941379845142e-04, // 0.000100
- 1.00000000000000002081668171172168513294309377670288e-03, // 0.001000
- 1.00000000000000002081668171172168513294309377670288e-02, // 0.010000
- 1.00000000000000005551115123125782702118158340454102e-01, // 0.100000
- 2.50000000000000000000000000000000000000000000000000e-01, // 0.250000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 7.50000000000000000000000000000000000000000000000000e-01, // 0.750000
- 9.00000000000000022204460492503130808472633361816406e-01, // 0.900000
- 9.89999999999999991118215802998747676610946655273438e-01, // 0.990000
- 9.98999999999999999111821580299874767661094665527344e-01, // 0.999000
- 9.99900000000000011013412404281552881002426147460938e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_1_1 = { //
- 1.00000000000000086107336538798762148871901445090771e-04, // 0.000100
- 1.00000000000000023765711620882257193443365395069122e-03, // 0.001000
- 1.00000000000000036776137690708310401532799005508423e-02, // 0.010000
- 1.00000000000000019428902930940239457413554191589355e-01, // 0.100000
- 2.50000000000000000000000000000000000000000000000000e-01, // 0.250000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 7.50000000000000000000000000000000000000000000000000e-01, // 0.750000
- 9.00000000000000022204460492503130808472633361816406e-01, // 0.900000
- 9.89999999999999991118215802998747676610946655273438e-01, // 0.990000
- 9.98999999999999999111821580299874767661094665527344e-01, // 0.999000
- 9.99900000000000011013412404281552881002426147460938e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_1_2 = { //
- 5.00012500625039114031909759372496182550094090402126e-05, // 0.000100
- 5.00125062539089927649005318244235240854322910308838e-04, // 0.001000
- 5.01256289338004520916847184253128943964838981628418e-03, // 0.010000
- 5.13167019494862042261473789039882831275463104248047e-02, // 0.100000
- 1.33974596215561375656122322652663569897413253784180e-01, // 0.250000
- 2.92893218813452482773840301888412795960903167724609e-01, // 0.500000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.750000
- 6.83772233983162003312372689833864569664001464843750e-01, // 0.900000
- 8.99999999999999911182158029987476766109466552734375e-01, // 0.990000
- 9.68377223398316222535697761486517265439033508300781e-01, // 0.999000
- 9.90000000000000546229728115577017888426780700683594e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_1_2 = { //
- 5.00012500625039249557181320060550433481694199144840e-05, // 0.000100
- 5.00125062539089710808570821143348439363762736320496e-04, // 0.001000
- 5.01256289338004520916847184253128943964838981628418e-03, // 0.010000
- 5.13167019494862042261473789039882831275463104248047e-02, // 0.100000
- 1.33974596215561375656122322652663569897413253784180e-01, // 0.250000
- 2.92893218813452371751537839372758753597736358642578e-01, // 0.500000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.750000
- 6.83772233983162114334675152349518612027168273925781e-01, // 0.900000
- 8.99999999999999911182158029987476766109466552734375e-01, // 0.990000
- 9.68377223398316222535697761486517265439033508300781e-01, // 0.999000
- 9.90000000000000546229728115577017888426780700683594e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_1_4 = { //
- 2.50009375546912596263108424787802164246386382728815e-05, // 0.000100
- 2.50093804725125897110704631387534391251392662525177e-04, // 0.001000
- 2.50943006631889524785106182491745130391791462898254e-03, // 0.010000
- 2.59962535747032368049769246454161475412547588348389e-02, // 0.100000
- 6.93951408979004008559243743547995109111070632934570e-02, // 0.250000
- 1.59103584746285470208349011045356746762990951538086e-01, // 0.500000
- 2.92893218813452482773840301888412795960903167724609e-01, // 0.750000
- 4.37658674809650927173265699821058660745620727539062e-01, // 0.900000
- 6.83772233983162003312372689833864569664001464843750e-01, // 0.990000
- 8.22172058996107679718079452868551015853881835937500e-01, // 0.999000
- 9.00000000000002797762022055394481867551803588867188e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_1_4 = { //
- 2.50009375546912697907062095303842852445086464285851e-05, // 0.000100
- 2.50093804725125951320813255662756091624032706022263e-04, // 0.001000
- 2.50943006631889611521279981332099850988015532493591e-03, // 0.010000
- 2.59962535747032368049769246454161475412547588348389e-02, // 0.100000
- 6.93951408979004286114999899837130215018987655639648e-02, // 0.250000
- 1.59103584746285470208349011045356746762990951538086e-01, // 0.500000
- 2.92893218813452427262689070630585774779319763183594e-01, // 0.750000
- 4.37658674809650927173265699821058660745620727539062e-01, // 0.900000
- 6.83772233983162003312372689833864569664001464843750e-01, // 0.990000
- 8.22172058996107679718079452868551015853881835937500e-01, // 0.999000
- 9.00000000000002686739719592878827825188636779785156e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_2_01 = { //
- 4.20955724062624797587872649273776914924383163452148e-02, // 0.000100
- 1.29414177470200258968091588940296787768602371215820e-01, // 0.001000
- 3.72851670751815522653060952507075853645801544189453e-01, // 0.010000
- 8.45084158995438761152740880788769572973251342773438e-01, // 0.100000
- 9.77846565304653081440733330964576452970504760742188e-01, // 0.250000
- 9.99623363942448217578373714786721393465995788574219e-01, // 0.500000
- 9.99999632317144060422720031056087464094161987304688e-01, // 0.750000
- 9.99999999961445618090749576367670670151710510253906e-01, // 0.900000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.990000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.999000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_2_01 = { //
- 4.20955724062624728198933610201493138447403907775879e-02, // 0.000100
- 1.29414177470200231212515973311383277177810668945312e-01, // 0.001000
- 3.72851670751815578164212183764902874827384948730469e-01, // 0.010000
- 8.45084158995438761152740880788769572973251342773438e-01, // 0.100000
- 9.77846565304653081440733330964576452970504760742188e-01, // 0.250000
- 9.99623363942448217578373714786721393465995788574219e-01, // 0.500000
- 9.99999632317144060422720031056087464094161987304688e-01, // 0.750000
- 9.99999999961445618090749576367670670151710510253906e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.990000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.999000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_2_05 = { //
- 1.62853809185172157536491965856839669868350028991699e-02, // 0.000100
- 5.11919447158312862500295636891678441315889358520508e-02, // 0.001000
- 1.58744712946928157037973505794070661067962646484375e-01, // 0.010000
- 4.68122566526419536803160781346377916634082794189453e-01, // 0.100000
- 6.88775820961510354401013955794041976332664489746094e-01, // 0.250000
- 8.79385241571816744787781772174639627337455749511719e-01, // 0.500000
- 9.71690456281308567731969105807365849614143371582031e-01, // 0.750000
- 9.95542318112378588068622775608673691749572753906250e-01, // 0.900000
- 9.99955554238614818807207029749406501650810241699219e-01, // 0.990000
- 9.99999555555423857988728286727564409375190734863281e-01, // 0.999000
- 9.99999995555555520887480724923079833388328552246094e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_2_05 = { //
- 1.62853809185172088147552926784555893391370773315430e-02, // 0.000100
- 5.11919447158312793111356597819394664838910102844238e-02, // 0.001000
- 1.58744712946928129282397890165157150477170944213867e-01, // 0.010000
- 4.68122566526419647825463243862031958997249603271484e-01, // 0.100000
- 6.88775820961510798490223805856658145785331726074219e-01, // 0.250000
- 8.79385241571817299899294084752909839153289794921875e-01, // 0.500000
- 9.71690456281308567731969105807365849614143371582031e-01, // 0.750000
- 9.95542318112378588068622775608673691749572753906250e-01, // 0.900000
- 9.99955554238614818807207029749406501650810241699219e-01, // 0.990000
- 9.99999555555423857988728286727564409375190734863281e-01, // 0.999000
- 9.99999995555555520887480724923079833388328552246094e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_2_1 = { //
- 1.00000000000000002081668171172168513294309377670288e-02, // 0.000100
- 3.16227766016837913420900463279394898563623428344727e-02, // 0.001000
- 9.99999999999999916733273153113259468227624893188477e-02, // 0.010000
- 3.16227766016837941176476078908308409154415130615234e-01, // 0.100000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.250000
- 7.07106781186547461715008466853760182857513427734375e-01, // 0.500000
- 8.66025403784438596588302061718422919511795043945312e-01, // 0.750000
- 9.48683298050513768018277005467098206281661987304688e-01, // 0.900000
- 9.94987437106619965199172384018311277031898498535156e-01, // 0.990000
- 9.99499874937460952573076156113529577851295471191406e-01, // 0.999000
- 9.99949998749937507547258519480237737298011779785156e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_2_1 = { //
- 9.99999999999999500399638918679556809365749359130859e-03, // 0.000100
- 3.16227766016837982809839502351678675040602684020996e-02, // 0.001000
- 1.00000000000000019428902930940239457413554191589355e-01, // 0.010000
- 3.16227766016837885665324847650481387972831726074219e-01, // 0.100000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.250000
- 7.07106781186547572737310929369414225220680236816406e-01, // 0.500000
- 8.66025403784438596588302061718422919511795043945312e-01, // 0.750000
- 9.48683298050513768018277005467098206281661987304688e-01, // 0.900000
- 9.94987437106619965199172384018311277031898498535156e-01, // 0.990000
- 9.99499874937460952573076156113529577851295471191406e-01, // 0.999000
- 9.99949998749937507547258519480237737298011779785156e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_2_2 = { //
- 5.78466759288776954245347994287840265315026044845581e-03, // 0.000100
- 1.83702538588116116857751336510773398913443088531494e-02, // 0.001000
- 5.89031357781952535912495250158826820552349090576172e-02, // 0.010000
- 1.95800105659091727705600760600646026432514190673828e-01, // 0.100000
- 3.26351822333069641057790022387052886188030242919922e-01, // 0.250000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 6.73648177666930303431058746355120092630386352539062e-01, // 0.750000
- 8.04199894340908327805550470657180994749069213867188e-01, // 0.900000
- 9.41096864221804718653174859355203807353973388671875e-01, // 0.990000
- 9.81629746141188364028096202673623338341712951660156e-01, // 0.999000
- 9.94215332407112573065433025476522743701934814453125e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_2_2 = { //
- 5.78466759288776954245347994287840265315026044845581e-03, // 0.000100
- 1.83702538588116116857751336510773398913443088531494e-02, // 0.001000
- 5.89031357781952674690373328303394373506307601928711e-02, // 0.010000
- 1.95800105659091699950025144971732515841722488403320e-01, // 0.100000
- 3.26351822333069696568941253644879907369613647460938e-01, // 0.250000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 6.73648177666930303431058746355120092630386352539062e-01, // 0.750000
- 8.04199894340908327805550470657180994749069213867188e-01, // 0.900000
- 9.41096864221804718653174859355203807353973388671875e-01, // 0.990000
- 9.81629746141188364028096202673623338341712951660156e-01, // 0.999000
- 9.94215332407112573065433025476522743701934814453125e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_2_4 = { //
- 3.17233337277439495643927003243334183935075998306274e-03, // 0.000100
- 1.01017878837377523409957191802277520764619112014771e-02, // 0.001000
- 3.26821122006028808026911747219855897128582000732422e-02, // 0.010000
- 1.12234958545858548584206459963752422481775283813477e-01, // 0.100000
- 1.93763609553971150045725835298071615397930145263672e-01, // 0.250000
- 3.13810170455697423630425646479125134646892547607422e-01, // 0.500000
- 4.54180564773615791374083983100717887282371520996094e-01, // 0.750000
- 5.83890374619528973454407605458982288837432861328125e-01, // 0.900000
- 7.77927716615001818567520786018576472997665405273438e-01, // 0.990000
- 8.77986170388521558471950356761226430535316467285156e-01, // 0.999000
- 9.32186920845740840668725013529183343052864074707031e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_2_4 = { //
- 3.17233337277439452275840103823156823636963963508606e-03, // 0.000100
- 1.01017878837377488715487672266135632526129484176636e-02, // 0.001000
- 3.26821122006028738637972708147572120651602745056152e-02, // 0.010000
- 1.12234958545858534706418652149295667186379432678223e-01, // 0.100000
- 1.93763609553971177801301450926985125988721847534180e-01, // 0.250000
- 3.13810170455697368119274415221298113465309143066406e-01, // 0.500000
- 4.54180564773615680351781520585063844919204711914062e-01, // 0.750000
- 5.83890374619528973454407605458982288837432861328125e-01, // 0.900000
- 7.77927716615001929589823248534230515360832214355469e-01, // 0.990000
- 8.77986170388521558471950356761226430535316467285156e-01, // 0.999000
- 9.32186920845740840668725013529183343052864074707031e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_4_01 = { //
- 2.29760042749164533626426987211743835359811782836914e-01, // 0.000100
- 3.92411306264331405380119122128235176205635070800781e-01, // 0.001000
- 6.41486304510298754877339888480491936206817626953125e-01, // 0.010000
- 9.28046735184830051679227835847996175289154052734375e-01, // 0.100000
- 9.90136606758413972961818672047229483723640441894531e-01, // 0.250000
- 9.99833400718542097962426851154305040836334228515625e-01, // 0.500000
- 9.99999837379217715316315207019215449690818786621094e-01, // 0.750000
- 9.99999999982947973542479758179979398846626281738281e-01, // 0.900000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.990000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.999000
- 9.99999999999999888977697537484345957636833190917969e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_4_01 = { //
- 2.29760042749164533626426987211743835359811782836914e-01, // 0.000100
- 3.92411306264331349868967890870408155024051666259766e-01, // 0.001000
- 6.41486304510298754877339888480491936206817626953125e-01, // 0.010000
- 9.28046735184830495768437685910612344741821289062500e-01, // 0.100000
- 9.90136606758413972961818672047229483723640441894531e-01, // 0.250000
- 9.99833400718542097962426851154305040836334228515625e-01, // 0.500000
- 9.99999837379217715316315207019215449690818786621094e-01, // 0.750000
- 9.99999999982947973542479758179979398846626281738281e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.990000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.999000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_4_05 = { //
- 1.36299075618849435675983272631128784269094467163086e-01, // 0.000100
- 2.39415153269453812034939232944452669471502304077148e-01, // 0.001000
- 4.15398314048022576638885539068724028766155242919922e-01, // 0.010000
- 6.98207071206225382553611780167557299137115478515625e-01, // 0.100000
- 8.38716021599897110228027941047912463545799255371094e-01, // 0.250000
- 9.41289198660216319680671404057648032903671264648438e-01, // 0.500000
- 9.86584065391983955350951873697340488433837890625000e-01, // 0.750000
- 9.97901416278576425256119364348705857992172241210938e-01, // 0.900000
- 9.99979101167314032849731120222713798284530639648438e-01, // 0.990000
- 9.99999791020320771828266970260301604866981506347656e-01, // 0.999000
- 9.99999997910204108109155640704557299613952636718750e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_4_05 = { //
- 1.36299075618849463431558888260042294859886169433594e-01, // 0.000100
- 2.39415153269453950812817311089020222425460815429688e-01, // 0.001000
- 4.15398314048022687661188001584378071129322052001953e-01, // 0.010000
- 6.98207071206225493575914242683211341500282287597656e-01, // 0.100000
- 8.38716021599897221250330403563566505908966064453125e-01, // 0.250000
- 9.41289198660216541725276329088956117630004882812500e-01, // 0.500000
- 9.86584065391983955350951873697340488433837890625000e-01, // 0.750000
- 9.97901416278576425256119364348705857992172241210938e-01, // 0.900000
- 9.99979101167314032849731120222713798284530639648438e-01, // 0.990000
- 9.99999791020320771828266970260301604866981506347656e-01, // 0.999000
- 9.99999997910204108109155640704557299613952636718750e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_4_1 = { //
- 1.00000000000000005551115123125782702118158340454102e-01, // 0.000100
- 1.77827941003892292526344931502535473555326461791992e-01, // 0.001000
- 3.16227766016837941176476078908308409154415130615234e-01, // 0.010000
- 5.62341325190349072826734300178941339254379272460938e-01, // 0.100000
- 7.07106781186547572737310929369414225220680236816406e-01, // 0.250000
- 8.40896415253714613058377835841383785009384155273438e-01, // 0.500000
- 9.30604859102099557510712202201830223202705383300781e-01, // 0.750000
- 9.74003746425296745847788315586512908339500427246094e-01, // 0.900000
- 9.97490569933681126002511518890969455242156982421875e-01, // 0.990000
- 9.99749906195274928855099005886586382985115051269531e-01, // 0.999000
- 9.99974999062445357722594962979201227426528930664062e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_4_1 = { //
- 1.00000000000000019428902930940239457413554191589355e-01, // 0.000100
- 1.77827941003892264770769315873621962964534759521484e-01, // 0.001000
- 3.16227766016837941176476078908308409154415130615234e-01, // 0.010000
- 5.62341325190349072826734300178941339254379272460938e-01, // 0.100000
- 7.07106781186547572737310929369414225220680236816406e-01, // 0.250000
- 8.40896415253714502036075373325729742646217346191406e-01, // 0.500000
- 9.30604859102099557510712202201830223202705383300781e-01, // 0.750000
- 9.74003746425296745847788315586512908339500427246094e-01, // 0.900000
- 9.97490569933681126002511518890969455242156982421875e-01, // 0.990000
- 9.99749906195274928855099005886586382985115051269531e-01, // 0.999000
- 9.99974999062445357722594962979201227426528930664062e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_4_2 = { //
- 6.78130791542610467104168492369353771209716796875000e-02, // 0.000100
- 1.22013829611478455405837451053230324760079383850098e-01, // 0.001000
- 2.22072283384998070410176751465769484639167785644531e-01, // 0.010000
- 4.16109625380471082056743625798844732344150543212891e-01, // 0.100000
- 5.45819435226384208625916016899282112717628479003906e-01, // 0.250000
- 6.86189829544302631880725584778701886534690856933594e-01, // 0.500000
- 8.06236390446028794443122933444101363420486450195312e-01, // 0.750000
- 8.87765041454141479171369155665161088109016418457031e-01, // 0.900000
- 9.67317887799397091441733209649100899696350097656250e-01, // 0.990000
- 9.89898212116262277149303372425492852926254272460938e-01, // 0.999000
- 9.96827666627225772444376161729451268911361694335938e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_4_2 = { //
- 6.78130791542610883437802726803056430071592330932617e-02, // 0.000100
- 1.22013829611478469283625258867687080055475234985352e-01, // 0.001000
- 2.22072283384998042654601135836855974048376083374023e-01, // 0.010000
- 4.16109625380471026545592394541017711162567138671875e-01, // 0.100000
- 5.45819435226384319648218479414936155080795288085938e-01, // 0.250000
- 6.86189829544302631880725584778701886534690856933594e-01, // 0.500000
- 8.06236390446028794443122933444101363420486450195312e-01, // 0.750000
- 8.87765041454141479171369155665161088109016418457031e-01, // 0.900000
- 9.67317887799397091441733209649100899696350097656250e-01, // 0.990000
- 9.89898212116262277149303372425492852926254272460938e-01, // 0.999000
- 9.96827666627225772444376161729451268911361694335938e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_4_4 = { //
- 4.21840560047029092261006155695213237777352333068848e-02, // 0.000100
- 7.66545428268873701993513236629951279610395431518555e-02, // 0.001000
- 1.42270377006857268176176489760109689086675643920898e-01, // 0.010000
- 2.78602048581713057640030228867544792592525482177734e-01, // 0.100000
- 3.78848440641707306930641152575844898819923400878906e-01, // 0.250000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 6.21151559358292693069358847424155101180076599121094e-01, // 0.750000
- 7.21397951418286886848818539874628186225891113281250e-01, // 0.900000
- 8.57729622993142704068247894610976800322532653808594e-01, // 0.990000
- 9.23345457173112560411709637264721095561981201171875e-01, // 0.999000
- 9.57815943995298235691393529123160988092422485351562e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_4_4 = { //
- 4.21840560047029092261006155695213237777352333068848e-02, // 0.000100
- 7.66545428268873701993513236629951279610395431518555e-02, // 0.001000
- 1.42270377006857268176176489760109689086675643920898e-01, // 0.010000
- 2.78602048581713057640030228867544792592525482177734e-01, // 0.100000
- 3.78848440641707306930641152575844898819923400878906e-01, // 0.250000
- 5.00000000000000111022302462515654042363166809082031e-01, // 0.500000
- 6.21151559358292693069358847424155101180076599121094e-01, // 0.750000
- 7.21397951418286886848818539874628186225891113281250e-01, // 0.900000
- 8.57729622993142704068247894610976800322532653808594e-01, // 0.990000
- 9.23345457173112560411709637264721095561981201171875e-01, // 0.999000
- 9.57815943995298235691393529123160988092422485351562e-01, // 0.999900
- };
-
- public static final double[] SCIPY_BETA_QUANT_5000_10000 = { //
- 3.19116827168564931582750432426109910011291503906250e-01, // 0.000100
- 3.21504012263543914595942396772443316876888275146484e-01, // 0.001000
- 3.24412567280382702072927258996060118079185485839844e-01, // 0.010000
- 3.28405475125335688524330635118531063199043273925781e-01, // 0.100000
- 3.30733175792180755792060153908096253871917724609375e-01, // 0.250000
- 3.33325925743107376320040202699601650238037109375000e-01, // 0.500000
- 3.35925416008591048999676331732189282774925231933594e-01, // 0.750000
- 3.38270709107204470278418284578947350382804870605469e-01, // 0.900000
- 3.42319458459627412594272755086421966552734375000000e-01, // 0.990000
- 3.45289298443524073078947367321234196424484252929688e-01, // 0.999000
- 3.47739889112688382866167557949665933847427368164062e-01, // 0.999900
- };
-
- public static final double[] GNUR_BETA_QUANT_5000_10000 = { //
- 3.19116827168544670012551023319247178733348846435547e-01, // 0.000100
- 3.21504012263524707737616381564293988049030303955078e-01, // 0.001000
- 3.24412567280357388987965805426938459277153015136719e-01, // 0.010000
- 3.28405475125304435746187436961918137967586517333984e-01, // 0.100000
- 3.30733175792131905978976647020317614078521728515625e-01, // 0.250000
- 3.33325925743034268133868636141414754092693328857422e-01, // 0.500000
- 3.35925416008648558552351914840983226895332336425781e-01, // 0.750000
- 3.38270709107251876801569778763223439455032348632812e-01, // 0.900000
- 3.42319458459653502835351446265121921896934509277344e-01, // 0.990000
- 3.45289298443550274342328521015588194131851196289062e-01, // 0.999000
- 3.47739889112697708739574409264605492353439331054688e-01, // 0.999900
- };
-
- @Test
- public void testPDF() {
- checkPDF(new BetaDistribution(1., 1.), P_CDFPDF, SCIPY_BETA_PDF_1_1, 1e-15);
- checkPDF(new BetaDistribution(2., 1.), P_CDFPDF, SCIPY_BETA_PDF_2_1, 1e-12);
- checkPDF(new BetaDistribution(4., 1.), P_CDFPDF, SCIPY_BETA_PDF_4_1, 1e-11);
- checkPDF(new BetaDistribution(.1, 1.), P_CDFPDF, SCIPY_BETA_PDF_01_1, 1e-12);
- checkPDF(new BetaDistribution(.5, 1.), P_CDFPDF, SCIPY_BETA_PDF_05_1, 1e-12);
- checkPDF(new BetaDistribution(1., 2.), P_CDFPDF, SCIPY_BETA_PDF_1_2, 1e-12);
- checkPDF(new BetaDistribution(2., 2.), P_CDFPDF, SCIPY_BETA_PDF_2_2, 1e-12);
- checkPDF(new BetaDistribution(4., 2.), P_CDFPDF, SCIPY_BETA_PDF_4_2, 1e-12);
- checkPDF(new BetaDistribution(.1, 2.), P_CDFPDF, SCIPY_BETA_PDF_01_2, 1e-12);
- checkPDF(new BetaDistribution(.5, 2.), P_CDFPDF, SCIPY_BETA_PDF_05_2, 1e-12);
- checkPDF(new BetaDistribution(1., 4.), P_CDFPDF, SCIPY_BETA_PDF_1_4, 1e-12);
- checkPDF(new BetaDistribution(2., 4.), P_CDFPDF, SCIPY_BETA_PDF_2_4, 1e-13);
- checkPDF(new BetaDistribution(4., 4.), P_CDFPDF, SCIPY_BETA_PDF_4_4, 1e-12);
- checkPDF(new BetaDistribution(.1, 4.), P_CDFPDF, SCIPY_BETA_PDF_01_4, 1e-12);
- checkPDF(new BetaDistribution(.5, 4.), P_CDFPDF, SCIPY_BETA_PDF_05_4, 1e-12);
- checkPDF(new BetaDistribution(1., .1), P_CDFPDF, SCIPY_BETA_PDF_1_01, 1e-12);
- checkPDF(new BetaDistribution(2., .1), P_CDFPDF, SCIPY_BETA_PDF_2_01, 1e-12);
- checkPDF(new BetaDistribution(4., .1), P_CDFPDF, SCIPY_BETA_PDF_4_01, 1e-11);
- checkPDF(new BetaDistribution(.1, .1), P_CDFPDF, SCIPY_BETA_PDF_01_01, 1e-12);
- checkPDF(new BetaDistribution(.5, .1), P_CDFPDF, SCIPY_BETA_PDF_05_01, 1e-13);
- checkPDF(new BetaDistribution(1., .5), P_CDFPDF, SCIPY_BETA_PDF_1_05, 1e-13);
- checkPDF(new BetaDistribution(2., .5), P_CDFPDF, SCIPY_BETA_PDF_2_05, 1e-12);
- checkPDF(new BetaDistribution(4., .5), P_CDFPDF, SCIPY_BETA_PDF_4_05, 1e-11);
- checkPDF(new BetaDistribution(.1, .5), P_CDFPDF, SCIPY_BETA_PDF_01_05, 1e-12);
- checkPDF(new BetaDistribution(.5, .5), P_CDFPDF, SCIPY_BETA_PDF_05_05, 1e-12);
-
- checkPDF(new BetaDistribution(1., 1.), P_CDFPDF, GNUR_BETA_PDF_1_1, 1e-15);
- checkPDF(new BetaDistribution(2., 1.), P_CDFPDF, GNUR_BETA_PDF_2_1, 1e-14);
- checkPDF(new BetaDistribution(4., 1.), P_CDFPDF, GNUR_BETA_PDF_4_1, 1e-14);
- checkPDF(new BetaDistribution(.1, 1.), P_CDFPDF, GNUR_BETA_PDF_01_1, 1e-14);
- checkPDF(new BetaDistribution(.5, 1.), P_CDFPDF, GNUR_BETA_PDF_05_1, 1e-14);
- checkPDF(new BetaDistribution(1., 2.), P_CDFPDF, GNUR_BETA_PDF_1_2, 1e-15);
- checkPDF(new BetaDistribution(2., 2.), P_CDFPDF, GNUR_BETA_PDF_2_2, 1e-15);
- checkPDF(new BetaDistribution(4., 2.), P_CDFPDF, GNUR_BETA_PDF_4_2, 1e-13);
- checkPDF(new BetaDistribution(.1, 2.), P_CDFPDF, GNUR_BETA_PDF_01_2, 1e-15);
- checkPDF(new BetaDistribution(.5, 2.), P_CDFPDF, GNUR_BETA_PDF_05_2, 1e-14);
- checkPDF(new BetaDistribution(1., 4.), P_CDFPDF, GNUR_BETA_PDF_1_4, 1e-15);
- checkPDF(new BetaDistribution(2., 4.), P_CDFPDF, GNUR_BETA_PDF_2_4, 1e-15);
- checkPDF(new BetaDistribution(4., 4.), P_CDFPDF, GNUR_BETA_PDF_4_4, 1e-14);
- checkPDF(new BetaDistribution(.1, 4.), P_CDFPDF, GNUR_BETA_PDF_01_4, 1e-14);
- checkPDF(new BetaDistribution(.5, 4.), P_CDFPDF, GNUR_BETA_PDF_05_4, 1e-15);
- checkPDF(new BetaDistribution(1., .1), P_CDFPDF, GNUR_BETA_PDF_1_01, 1e-15);
- checkPDF(new BetaDistribution(2., .1), P_CDFPDF, GNUR_BETA_PDF_2_01, 1e-15);
- checkPDF(new BetaDistribution(4., .1), P_CDFPDF, GNUR_BETA_PDF_4_01, 1e-14);
- checkPDF(new BetaDistribution(.1, .1), P_CDFPDF, GNUR_BETA_PDF_01_01, 1e-14);
- checkPDF(new BetaDistribution(.5, .1), P_CDFPDF, GNUR_BETA_PDF_05_01, 1e-15);
- checkPDF(new BetaDistribution(1., .5), P_CDFPDF, GNUR_BETA_PDF_1_05, 1e-14);
- checkPDF(new BetaDistribution(2., .5), P_CDFPDF, GNUR_BETA_PDF_2_05, 1e-14);
- checkPDF(new BetaDistribution(4., .5), P_CDFPDF, GNUR_BETA_PDF_4_05, 1e-15);
- checkPDF(new BetaDistribution(.1, .5), P_CDFPDF, GNUR_BETA_PDF_01_05, 1e-15);
- checkPDF(new BetaDistribution(.5, .5), P_CDFPDF, GNUR_BETA_PDF_05_05, 1e-14);
- }
-
- @Test
- public void testCDF() {
- checkCDF(new BetaDistribution(1., 1.), P_CDFPDF, SCIPY_BETA_CDF_1_1, 1e-12);
- checkCDF(new BetaDistribution(2., 1.), P_CDFPDF, SCIPY_BETA_CDF_2_1, 1e-12);
- checkCDF(new BetaDistribution(4., 1.), P_CDFPDF, SCIPY_BETA_CDF_4_1, 1e-11);
- checkCDF(new BetaDistribution(.1, 1.), P_CDFPDF, SCIPY_BETA_CDF_01_1, 1e-13);
- checkCDF(new BetaDistribution(.5, 1.), P_CDFPDF, SCIPY_BETA_CDF_05_1, 1e-12);
- checkCDF(new BetaDistribution(1., 2.), P_CDFPDF, SCIPY_BETA_CDF_1_2, 1e-12);
- checkCDF(new BetaDistribution(2., 2.), P_CDFPDF, SCIPY_BETA_CDF_2_2, 1e-12);
- checkCDF(new BetaDistribution(4., 2.), P_CDFPDF, SCIPY_BETA_CDF_4_2, 1e-11);
- checkCDF(new BetaDistribution(.1, 2.), P_CDFPDF, SCIPY_BETA_CDF_01_2, 1e-13);
- checkCDF(new BetaDistribution(.5, 2.), P_CDFPDF, SCIPY_BETA_CDF_05_2, 1e-12);
- checkCDF(new BetaDistribution(1., 4.), P_CDFPDF, SCIPY_BETA_CDF_1_4, 1e-12);
- checkCDF(new BetaDistribution(2., 4.), P_CDFPDF, SCIPY_BETA_CDF_2_4, 1e-12);
- checkCDF(new BetaDistribution(4., 4.), P_CDFPDF, SCIPY_BETA_CDF_4_4, 1e-11);
- checkCDF(new BetaDistribution(.1, 4.), P_CDFPDF, SCIPY_BETA_CDF_01_4, 1e-13);
- checkCDF(new BetaDistribution(.5, 4.), P_CDFPDF, SCIPY_BETA_CDF_05_4, 1e-13);
- checkCDF(new BetaDistribution(1., .1), P_CDFPDF, SCIPY_BETA_CDF_1_01, 1e-12);
- checkCDF(new BetaDistribution(2., .1), P_CDFPDF, SCIPY_BETA_CDF_2_01, 1e-12);
- checkCDF(new BetaDistribution(4., .1), P_CDFPDF, SCIPY_BETA_CDF_4_01, 1e-11);
- checkCDF(new BetaDistribution(.1, .1), P_CDFPDF, SCIPY_BETA_CDF_01_01, 1e-13);
- checkCDF(new BetaDistribution(.5, .1), P_CDFPDF, SCIPY_BETA_CDF_05_01, 1e-12);
- checkCDF(new BetaDistribution(1., .5), P_CDFPDF, SCIPY_BETA_CDF_1_05, 1e-12);
- checkCDF(new BetaDistribution(2., .5), P_CDFPDF, SCIPY_BETA_CDF_2_05, 1e-12);
- checkCDF(new BetaDistribution(4., .5), P_CDFPDF, SCIPY_BETA_CDF_4_05, 1e-11);
- checkCDF(new BetaDistribution(.1, .5), P_CDFPDF, SCIPY_BETA_CDF_01_05, 1e-13);
- checkCDF(new BetaDistribution(.5, .5), P_CDFPDF, SCIPY_BETA_CDF_05_05, 1e-12);
-
- checkCDF(new BetaDistribution(1., 1.), P_CDFPDF, GNUR_BETA_CDF_1_1, 1e-14);
- checkCDF(new BetaDistribution(2., 1.), P_CDFPDF, GNUR_BETA_CDF_2_1, 1e-14);
- checkCDF(new BetaDistribution(4., 1.), P_CDFPDF, GNUR_BETA_CDF_4_1, 1e-13);
- checkCDF(new BetaDistribution(.1, 1.), P_CDFPDF, GNUR_BETA_CDF_01_1, 1e-15);
- checkCDF(new BetaDistribution(.5, 1.), P_CDFPDF, GNUR_BETA_CDF_05_1, 1e-14);
- checkCDF(new BetaDistribution(1., 2.), P_CDFPDF, GNUR_BETA_CDF_1_2, 1e-14);
- checkCDF(new BetaDistribution(2., 2.), P_CDFPDF, GNUR_BETA_CDF_2_2, 1e-14);
- checkCDF(new BetaDistribution(4., 2.), P_CDFPDF, GNUR_BETA_CDF_4_2, 1e-14);
- checkCDF(new BetaDistribution(.1, 2.), P_CDFPDF, GNUR_BETA_CDF_01_2, 1e-15);
- checkCDF(new BetaDistribution(.5, 2.), P_CDFPDF, GNUR_BETA_CDF_05_2, 1e-14);
- checkCDF(new BetaDistribution(1., 4.), P_CDFPDF, GNUR_BETA_CDF_1_4, 1e-14);
- checkCDF(new BetaDistribution(2., 4.), P_CDFPDF, GNUR_BETA_CDF_2_4, 1e-14);
- checkCDF(new BetaDistribution(4., 4.), P_CDFPDF, GNUR_BETA_CDF_4_4, 1e-14);
- checkCDF(new BetaDistribution(.1, 4.), P_CDFPDF, GNUR_BETA_CDF_01_4, 1e-15);
- checkCDF(new BetaDistribution(.5, 4.), P_CDFPDF, GNUR_BETA_CDF_05_4, 1e-15);
- checkCDF(new BetaDistribution(1., .1), P_CDFPDF, GNUR_BETA_CDF_1_01, 1e-14);
- checkCDF(new BetaDistribution(2., .1), P_CDFPDF, GNUR_BETA_CDF_2_01, 1e-14);
- checkCDF(new BetaDistribution(4., .1), P_CDFPDF, GNUR_BETA_CDF_4_01, 1e-14);
- checkCDF(new BetaDistribution(.1, .1), P_CDFPDF, GNUR_BETA_CDF_01_01, 1e-14);
- checkCDF(new BetaDistribution(.5, .1), P_CDFPDF, GNUR_BETA_CDF_05_01, 1e-14);
- checkCDF(new BetaDistribution(1., .5), P_CDFPDF, GNUR_BETA_CDF_1_05, 1e-14);
- checkCDF(new BetaDistribution(2., .5), P_CDFPDF, GNUR_BETA_CDF_2_05, 1e-14);
- checkCDF(new BetaDistribution(4., .5), P_CDFPDF, GNUR_BETA_CDF_4_05, 1e-13);
- checkCDF(new BetaDistribution(.1, .5), P_CDFPDF, GNUR_BETA_CDF_01_05, 1e-14);
- checkCDF(new BetaDistribution(.5, .5), P_CDFPDF, GNUR_BETA_CDF_05_05, 1e-14);
- }
-
- @Test
- public void testQuantile() {
- checkQuantile(new BetaDistribution(1., 1.), P_QUANT, SCIPY_BETA_QUANT_1_1, 1e-15);
- checkQuantile(new BetaDistribution(2., 1.), P_QUANT, SCIPY_BETA_QUANT_2_1, 1e-15);
- checkQuantile(new BetaDistribution(4., 1.), P_QUANT, SCIPY_BETA_QUANT_4_1, 1e-15);
- checkQuantile(new BetaDistribution(.1, 1.), P_QUANT, SCIPY_BETA_QUANT_01_1, 1e-14);
- checkQuantile(new BetaDistribution(.5, 1.), P_QUANT, SCIPY_BETA_QUANT_05_1, 1e-14);
- checkQuantile(new BetaDistribution(1., 2.), P_QUANT, SCIPY_BETA_QUANT_1_2, 1e-14);
- checkQuantile(new BetaDistribution(2., 2.), P_QUANT, SCIPY_BETA_QUANT_2_2, 1e-15);
- checkQuantile(new BetaDistribution(4., 2.), P_QUANT, SCIPY_BETA_QUANT_4_2, 1e-15);
- checkQuantile(new BetaDistribution(.1, 2.), P_QUANT, SCIPY_BETA_QUANT_01_2, 1e-13);
- checkQuantile(new BetaDistribution(.5, 2.), P_QUANT, SCIPY_BETA_QUANT_05_2, 1e-14);
- checkQuantile(new BetaDistribution(1., 4.), P_QUANT, SCIPY_BETA_QUANT_1_4, 1e-14);
- checkQuantile(new BetaDistribution(2., 4.), P_QUANT, SCIPY_BETA_QUANT_2_4, 1e-15);
- checkQuantile(new BetaDistribution(4., 4.), P_QUANT, SCIPY_BETA_QUANT_4_4, 1e-15);
- checkQuantile(new BetaDistribution(.1, 4.), P_QUANT, SCIPY_BETA_QUANT_01_4, 1e-13);
- checkQuantile(new BetaDistribution(.5, 4.), P_QUANT, SCIPY_BETA_QUANT_05_4, 1e-14);
- checkQuantile(new BetaDistribution(1., .1), P_QUANT, SCIPY_BETA_QUANT_1_01, 1e-14);
- checkQuantile(new BetaDistribution(2., .1), P_QUANT, SCIPY_BETA_QUANT_2_01, 1e-15);
- checkQuantile(new BetaDistribution(4., .1), P_QUANT, SCIPY_BETA_QUANT_4_01, 1e-15);
- checkQuantile(new BetaDistribution(.1, .1), P_QUANT, SCIPY_BETA_QUANT_01_01, 1e-13);
- checkQuantile(new BetaDistribution(.5, .1), P_QUANT, SCIPY_BETA_QUANT_05_01, 1e-14);
- checkQuantile(new BetaDistribution(1., .5), P_QUANT, SCIPY_BETA_QUANT_1_05, 1e-14);
- checkQuantile(new BetaDistribution(2., .5), P_QUANT, SCIPY_BETA_QUANT_2_05, 1e-15);
- checkQuantile(new BetaDistribution(4., .5), P_QUANT, SCIPY_BETA_QUANT_4_05, 1e-15);
- checkQuantile(new BetaDistribution(.1, .5), P_QUANT, SCIPY_BETA_QUANT_01_05, 1e-14);
- checkQuantile(new BetaDistribution(.5, .5), P_QUANT, SCIPY_BETA_QUANT_05_05, 1e-14);
- checkQuantile(new BetaDistribution(5000, 10000), P_QUANT, SCIPY_BETA_QUANT_5000_10000, 1e-13);
-
- checkQuantile(new BetaDistribution(1., 1.), P_QUANT, GNUR_BETA_QUANT_1_1, 1e-15);
- checkQuantile(new BetaDistribution(2., 1.), P_QUANT, GNUR_BETA_QUANT_2_1, 1e-15);
- checkQuantile(new BetaDistribution(4., 1.), P_QUANT, GNUR_BETA_QUANT_4_1, 1e-15);
- checkQuantile(new BetaDistribution(.1, 1.), P_QUANT, GNUR_BETA_QUANT_01_1, 1e-13);
- checkQuantile(new BetaDistribution(.5, 1.), P_QUANT, GNUR_BETA_QUANT_05_1, 1e-14);
- checkQuantile(new BetaDistribution(1., 2.), P_QUANT, GNUR_BETA_QUANT_1_2, 1e-14);
- checkQuantile(new BetaDistribution(2., 2.), P_QUANT, GNUR_BETA_QUANT_2_2, 1e-15);
- checkQuantile(new BetaDistribution(4., 2.), P_QUANT, GNUR_BETA_QUANT_4_2, 1e-15);
- checkQuantile(new BetaDistribution(.1, 2.), P_QUANT, GNUR_BETA_QUANT_01_2, 1e-14);
- checkQuantile(new BetaDistribution(.5, 2.), P_QUANT, GNUR_BETA_QUANT_05_2, 1e-14);
- checkQuantile(new BetaDistribution(1., 4.), P_QUANT, GNUR_BETA_QUANT_1_4, 1e-14);
- checkQuantile(new BetaDistribution(2., 4.), P_QUANT, GNUR_BETA_QUANT_2_4, 1e-15);
- checkQuantile(new BetaDistribution(4., 4.), P_QUANT, GNUR_BETA_QUANT_4_4, 1e-15);
- checkQuantile(new BetaDistribution(.1, 4.), P_QUANT, GNUR_BETA_QUANT_01_4, 1e-13);
- checkQuantile(new BetaDistribution(.5, 4.), P_QUANT, GNUR_BETA_QUANT_05_4, 1e-14);
- checkQuantile(new BetaDistribution(1., .1), P_QUANT, GNUR_BETA_QUANT_1_01, 1e-14);
- checkQuantile(new BetaDistribution(2., .1), P_QUANT, GNUR_BETA_QUANT_2_01, 1e-15);
- checkQuantile(new BetaDistribution(4., .1), P_QUANT, GNUR_BETA_QUANT_4_01, 1e-15);
- checkQuantile(new BetaDistribution(.1, .1), P_QUANT, GNUR_BETA_QUANT_01_01, 1e-13);
- checkQuantile(new BetaDistribution(.5, .1), P_QUANT, GNUR_BETA_QUANT_05_01, 1e-14);
- checkQuantile(new BetaDistribution(1., .5), P_QUANT, GNUR_BETA_QUANT_1_05, 1e-14);
- checkQuantile(new BetaDistribution(2., .5), P_QUANT, GNUR_BETA_QUANT_2_05, 1e-15);
- checkQuantile(new BetaDistribution(4., .5), P_QUANT, GNUR_BETA_QUANT_4_05, 1e-15);
- checkQuantile(new BetaDistribution(.1, .5), P_QUANT, GNUR_BETA_QUANT_01_05, 1e-14);
- checkQuantile(new BetaDistribution(.5, .5), P_QUANT, GNUR_BETA_QUANT_05_05, 1e-14);
- checkQuantile(new BetaDistribution(5000, 10000), P_QUANT, GNUR_BETA_QUANT_5000_10000, 1e-13);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestChiSquaredDistribution.java b/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestChiSquaredDistribution.java
deleted file mode 100644
index 4bfb52fd..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestChiSquaredDistribution.java
+++ /dev/null
@@ -1,826 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for the Chi Squared distribution in ELKI.
- *
- * The reference values were computed using GNU R and SciPy.
- *
- * @author Erich Schubert
- */
-public class TestChiSquaredDistribution extends AbstractDistributionTest implements JUnit4Test {
- public static final double[] P_CDFPDF = { //
- 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 1e-05, 1e-10, 0.1234567, 3.14159265359, 2.71828182846, 0.314159265359, 0.271828182846 //
- };
-
- public static final double[] SCIPY_CHISQ_CDF_01 = { //
- 8.82243563885668047319654760940466076135635375976562e-01, // 0.100000
- 9.11257625237519408578634738660184666514396667480469e-01, // 0.200000
- 9.27832443365792181033668839518213644623756408691406e-01, // 0.300000
- 9.39209088699221039675535394053440541028976440429688e-01, // 0.400000
- 9.47708820173318144952645525336265563964843750000000e-01, // 0.500000
- 9.54381121874345095257297089119674637913703918457031e-01, // 0.600000
- 9.59792062842079185536192653671605512499809265136719e-01, // 0.700000
- 9.64282450147988190458647750347154214978218078613281e-01, // 0.800000
- 9.68073590190356547680039511760696768760681152343750e-01, // 0.900000
- 9.71317371244163729748777313943719491362571716308594e-01, // 1.000000
- 9.74122543962944176243468064058106392621994018554688e-01, // 1.100000
- 9.76569616477515944907850098388735204935073852539062e-01, // 1.200000
- 9.78719820077030289162678400316508486866950988769531e-01, // 1.300000
- 9.80620773380832644328108926856657490134239196777344e-01, // 1.400000
- 9.82310206057613877206335928349290043115615844726562e-01, // 1.500000
- 9.83818489875346147144341557577718049287796020507812e-01, // 1.600000
- 9.85170408569036260004736504924949258565902709960938e-01, // 1.700000
- 9.86386426034563057463344648567726835608482360839844e-01, // 1.800000
- 9.87483614564462985896398095064796507358551025390625e-01, // 1.900000
- 9.88476347051459813819462851824937388300895690917969e-01, // 2.000000
- 5.57969600280356692323380229936446994543075561523438e-01, // 0.000010
- 3.13769439143751660559189531340962275862693786621094e-01, // 0.000000
- 8.91102932913000800319025529461214318871498107910156e-01, // 0.123457
- 9.95185831509797558247498727723723277449607849121094e-01, // 3.141593
- 9.93427663775691249803401206008857116103172302246094e-01, // 2.718282
- 9.29682286188087236844523886247770860791206359863281e-01, // 0.314159
- 9.23848956395416420761534936900716274976730346679688e-01, // 0.271828
- };
-
- public static final double[] SCIPY_CHISQ_PDF_01 = { //
- 4.20596758859699160204570489440811797976493835449219e-01, // 0.100000
- 2.07096472560618249936226220597745850682258605957031e-01, // 0.200000
- 1.34020514700378817751769133792549837380647659301758e-01, // 0.300000
- 9.69984417734248427489518462607520632445812225341797e-02, // 0.400000
- 7.46423873161204676218716258517815731465816497802734e-02, // 0.500000
- 5.97102120258812332775910647342243464663624763488770e-02, // 0.600000
- 4.90607789226714316455080222567630698904395103454590e-02, // 0.700000
- 4.11080963115560762966005370344646507874131202697754e-02, // 0.800000
- 3.49637289621889876811700048619968583807349205017090e-02, // 0.900000
- 3.00907771823936791288911507535885903052985668182373e-02, // 1.000000
- 2.61454204266986685312179616857974906452000141143799e-02, // 1.100000
- 2.28971681180981344316816006312365061603486537933350e-02, // 1.200000
- 2.01856643669713550770516974353085970506072044372559e-02, // 1.300000
- 1.78958724006224693947597614851474645547568798065186e-02, // 1.400000
- 1.59431116775097907189984169917806866578757762908936e-02, // 1.500000
- 1.42636632388964210843562696595654415432363748550415e-02, // 1.600000
- 1.28086648126372482786594630965737451333552598953247e-02, // 1.700000
- 1.15400245359752948171028208435018314048647880554199e-02, // 1.800000
- 1.04276144940537648930778402700525475665926933288574e-02, // 1.900000
- 9.44729915895063145081511635225979262031614780426025e-03, // 2.000000
- 2.78983471644215933338273316621780395507812500000000e+03, // 0.000010
- 1.56884719564404964447021484375000000000000000000000e+08, // 0.000000
- 3.40277656462092736866509312676498666405677795410156e-01, // 0.123457
- 3.47616265678607179803738524981326918350532650947571e-03, // 3.141593
- 4.92871253406783164929816365429360303096473217010498e-03, // 2.718282
- 1.27370674605358003006472245033364742994308471679688e-01, // 0.314159
- 1.49270555162829721140838046267163008451461791992188e-01, // 0.271828
- };
-
- public static final double[] GNUR_CHISQ_CDF_01 = { //
- 8.82243563885668047319654760940466076135635375976562e-01, // 0.100000
- 9.11257625237519630623239663691492751240730285644531e-01, // 0.200000
- 9.27832443365792847167483614612137898802757263183594e-01, // 0.300000
- 9.39209088699221039675535394053440541028976440429688e-01, // 0.400000
- 9.47708820173318589041855375398881733417510986328125e-01, // 0.500000
- 9.54381121874345650368809401697944849729537963867188e-01, // 0.600000
- 9.59792062842079629625402503734221681952476501464844e-01, // 0.700000
- 9.64282450147988301480950212862808257341384887695312e-01, // 0.800000
- 9.68073590190356436657737049245042726397514343261719e-01, // 0.900000
- 9.71317371244163951793382238975027576088905334472656e-01, // 1.000000
- 9.74122543962944731354980376636376604437828063964844e-01, // 1.100000
- 9.76569616477516500019362410967005416750907897949219e-01, // 1.200000
- 9.78719820077030733251888250379124656319618225097656e-01, // 1.300000
- 9.80620773380832866372713851887965574860572814941406e-01, // 1.400000
- 9.82310206057613877206335928349290043115615844726562e-01, // 1.500000
- 9.83818489875346147144341557577718049287796020507812e-01, // 1.600000
- 9.85170408569036704093946354987565428018569946289062e-01, // 1.700000
- 9.86386426034563279507949573599034920334815979003906e-01, // 1.800000
- 9.87483614564463429985607945127412676811218261718750e-01, // 1.900000
- 9.88476347051460035864067776856245473027229309082031e-01, // 2.000000
- 5.57969600280356914367985154967755079269409179687500e-01, // 0.000010
- 3.13769439143751827092643225114443339407444000244141e-01, // 0.000000
- 8.91102932913001466452840304555138573050498962402344e-01, // 0.123457
- 9.95185831509798335403615965333301573991775512695312e-01, // 3.141593
- 9.93427663775695912740104631666326895356178283691406e-01, // 2.718282
- 9.29682286188089901379782986623467877507209777832031e-01, // 0.314159
- 9.23848956395430742638552601420087739825248718261719e-01, // 0.271828
- };
-
- public static final double[] GNUR_CHISQ_PDF_01 = { //
- 4.20596758859699271226872951956465840339660644531250e-01, // 0.100000
- 2.07096472560618277691801836226659361273050308227539e-01, // 0.200000
- 1.34020514700378845507344749421463347971439361572266e-01, // 0.300000
- 9.69984417734248705045274618896655738353729248046875e-02, // 0.400000
- 7.46423873161204814996594336662383284419775009155273e-02, // 0.500000
- 5.97102120258812332775910647342243464663624763488770e-02, // 0.600000
- 4.90607789226714316455080222567630698904395103454590e-02, // 0.700000
- 4.11080963115560832354944409416930284351110458374023e-02, // 0.800000
- 3.49637289621889876811700048619968583807349205017090e-02, // 0.900000
- 3.00907771823936825983381027072027791291475296020508e-02, // 1.000000
- 2.61454204266986720006649136394116794690489768981934e-02, // 1.100000
- 2.28971681180981309622346486776223173364996910095215e-02, // 1.200000
- 2.01856643669713516076047454816944082267582416534424e-02, // 1.300000
- 1.78958724006224659253128095315332757309079170227051e-02, // 1.400000
- 1.59431116775097872495514650381664978340268135070801e-02, // 1.500000
- 1.42636632388964228190797456363725359551608562469482e-02, // 1.600000
- 1.28086648126372430744890351661524618975818157196045e-02, // 1.700000
- 1.15400245359752878782089169362734537571668624877930e-02, // 1.800000
- 1.04276144940537579541839363628241699188947677612305e-02, // 1.900000
- 9.44729915895062624664468842183850938454270362854004e-03, // 2.000000
- 2.78983471644215978813008405268192291259765625000000e+03, // 0.000010
- 1.56884719564405262470245361328125000000000000000000e+08, // 0.000000
- 3.40277656462092847888811775192152708768844604492188e-01, // 0.123457
- 3.47616265678549370143901597884905640967190265655518e-03, // 3.141593
- 4.92871253406383397904777510234453075099736452102661e-03, // 2.718282
- 1.27370674605348788155367856234079226851463317871094e-01, // 0.314159
- 1.49270555162772794455250391365552786737680435180664e-01, // 0.271828
- };
-
- public static final double[] SCIPY_CHISQ_CDF_1 = { //
- 2.48170365954150762277663488930556923151016235351562e-01, // 0.100000
- 3.45279153981423170272080369613831862807273864746094e-01, // 0.200000
- 4.16117579229634992898922973836306482553482055664062e-01, // 0.300000
- 4.72910743134461963865788902694475837051868438720703e-01, // 0.400000
- 5.20499877813046629704274437244748696684837341308594e-01, // 0.500000
- 5.61421973919000283359537206706590950489044189453125e-01, // 0.600000
- 5.97216305753524356880745926900999620556831359863281e-01, // 0.700000
- 6.28906630477302552861829099128954112529754638671875e-01, // 0.800000
- 6.57218288852088661222694554453482851386070251464844e-01, // 0.900000
- 6.82689492137085962575326902879169210791587829589844e-01, // 1.000000
- 7.05733895695037305451080555940279737114906311035156e-01, // 1.100000
- 7.26678321707701857512518017756519839167594909667969e-01, // 1.200000
- 7.45786776396035855363209066126728430390357971191406e-01, // 1.300000
- 7.63276429362142794232681808352936059236526489257812e-01, // 1.400000
- 7.79328638080153068834476925985654816031455993652344e-01, // 1.500000
- 7.94096789267931812972278748929966241121292114257812e-01, // 1.600000
- 8.07712022888480207782890829548705369234085083007812e-01, // 1.700000
- 8.20287505121000126706576338619925081729888916015625e-01, // 1.800000
- 8.31921680965029608501026814337819814682006835937500e-01, // 1.900000
- 8.42700792949715116186837349232519045472145080566406e-01, // 2.000000
- 2.52312831680559686298170873897106503136456012725830e-03, // 0.000010
- 7.97884560789568197394176080061711786584055516868830e-06, // 0.000000
- 2.74684755560843596455811166379135102033615112304688e-01, // 0.123457
- 9.23680750542945294689900492812739685177803039550781e-01, // 3.141593
- 9.00795249588885127423054655082523822784423828125000e-01, // 2.718282
- 4.24860961379973645080099231563508510589599609375000e-01, // 0.314159
- 3.97891959928843685911914462849381379783153533935547e-01, // 0.271828
- };
-
- public static final double[] SCIPY_CHISQ_PDF_1 = { //
- 1.20003894843013592108604825625661760568618774414062e+00, // 0.100000
- 8.07171129357680983140710395673522725701332092285156e-01, // 0.200000
- 6.26910099227520833942151057271985337138175964355469e-01, // 0.300000
- 5.16441547467278438965365694457432255148887634277344e-01, // 0.400000
- 4.39391289467722434558538679993944242596626281738281e-01, // 0.500000
- 3.81545289384093044837698016635840758681297302246094e-01, // 0.600000
- 3.36014467726770404976122108564595691859722137451172e-01, // 0.700000
- 2.98983539918204976881810353006585501134395599365234e-01, // 0.800000
- 2.68136721052083026872736581935896538197994232177734e-01, // 0.900000
- 2.41970724519143365327522587904240936040878295898438e-01, // 1.000000
- 2.19458172413343671758312325437145773321390151977539e-01, // 1.100000
- 1.99867763901733275222483143807039596140384674072266e-01, // 1.200000
- 1.82661481795109131853749317997426260262727737426758e-01, // 1.300000
- 1.67432557345083526945117569084686692804098129272461e-01, // 1.400000
- 1.53866322805455257860529627578216604888439178466797e-01, // 1.500000
- 1.41714565306223921892225803276232909411191940307617e-01, // 1.600000
- 1.30778181923888126014787758322199806571006774902344e-01, // 1.700000
- 1.20895122473204871815788408184744184836745262145996e-01, // 1.800000
- 1.11931805086169955387731533846817910671234130859375e-01, // 1.900000
- 1.03776874355148679418547885688894893974065780639648e-01, // 2.000000
- 1.26155995319454547143322997726500034332275390625000e+02, // 0.000010
- 3.98942280381486198166385293006896972656250000000000e+04, // 0.000000
- 1.06744240620741748237776391761144623160362243652344e+00, // 0.123457
- 4.67893435961044684701093387957371305674314498901367e-02, // 3.141593
- 6.21577700803671237550496186941018095239996910095215e-02, // 2.718282
- 6.08297892453185884420463480637408792972564697265625e-01, // 0.314159
- 6.67937897133326075049808423500508069992065429687500e-01, // 0.271828
- };
-
- public static final double[] GNUR_CHISQ_CDF_1 = { //
- 2.48170365954150706766512257672729901969432830810547e-01, // 0.100000
- 3.45279153981422948227475444582523778080940246582031e-01, // 0.200000
- 4.16117579229634826365469280062825419008731842041016e-01, // 0.300000
- 4.72910743134461908354637671436648815870285034179688e-01, // 0.400000
- 5.20499877813046518681971974729094654321670532226562e-01, // 0.500000
- 5.61421973919000061314932281675282865762710571289062e-01, // 0.600000
- 5.97216305753524356880745926900999620556831359863281e-01, // 0.700000
- 6.28906630477302330817224174097646027803421020507812e-01, // 0.800000
- 6.57218288852088550200392091937828809022903442382812e-01, // 0.900000
- 6.82689492137085962575326902879169210791587829589844e-01, // 1.000000
- 7.05733895695037083406475630908971652388572692871094e-01, // 1.100000
- 7.26678321707701857512518017756519839167594909667969e-01, // 1.200000
- 7.45786776396035633318604141095420345664024353027344e-01, // 1.300000
- 7.63276429362142572188076883321627974510192871093750e-01, // 1.400000
- 7.79328638080153179856779388501308858394622802734375e-01, // 1.500000
- 7.94096789267931590927673823898658156394958496093750e-01, // 1.600000
- 8.07712022888480207782890829548705369234085083007812e-01, // 1.700000
- 8.20287505121000237728878801135579124093055725097656e-01, // 1.800000
- 8.31921680965029608501026814337819814682006835937500e-01, // 1.900000
- 8.42700792949715449253744736779481172561645507812500e-01, // 2.000000
- 2.52312831680559773034344672737461223732680082321167e-03, // 0.000010
- 7.97884560789567350361228825761372718261554837226868e-06, // 0.000000
- 2.74684755560843485433508703863481059670448303222656e-01, // 0.123457
- 9.23680750542954953630214731674641370773315429687500e-01, // 3.141593
- 9.00795249588944302310267175926128402352333068847656e-01, // 2.718282
- 4.24860961379986301622579958348069339990615844726562e-01, // 0.314159
- 3.97891959928907357202376715576974675059318542480469e-01, // 0.271828
- };
-
- public static final double[] GNUR_CHISQ_PDF_1 = { //
- 1.20003894843013592108604825625661760568618774414062e+00, // 0.100000
- 8.07171129357681094163012858189176768064498901367188e-01, // 0.200000
- 6.26910099227520833942151057271985337138175964355469e-01, // 0.300000
- 5.16441547467278327943063231941778212785720825195312e-01, // 0.400000
- 4.39391289467722434558538679993944242596626281738281e-01, // 0.500000
- 3.81545289384093044837698016635840758681297302246094e-01, // 0.600000
- 3.36014467726770404976122108564595691859722137451172e-01, // 0.700000
- 2.98983539918204921370659121748758479952812194824219e-01, // 0.800000
- 2.68136721052082971361585350678069517016410827636719e-01, // 0.900000
- 2.41970724519143365327522587904240936040878295898438e-01, // 1.000000
- 2.19458172413343699513887941066059283912181854248047e-01, // 1.100000
- 1.99867763901733275222483143807039596140384674072266e-01, // 1.200000
- 1.82661481795109104098173702368512749671936035156250e-01, // 1.300000
- 1.67432557345083526945117569084686692804098129272461e-01, // 1.400000
- 1.53866322805455257860529627578216604888439178466797e-01, // 1.500000
- 1.41714565306223921892225803276232909411191940307617e-01, // 1.600000
- 1.30778181923888126014787758322199806571006774902344e-01, // 1.700000
- 1.20895122473204871815788408184744184836745262145996e-01, // 1.800000
- 1.11931805086169955387731533846817910671234130859375e-01, // 1.900000
- 1.03776874355148693296335693503351649269461631774902e-01, // 2.000000
- 1.26155995319454461878194706514477729797363281250000e+02, // 0.000010
- 3.98942280381485470570623874664306640625000000000000e+04, // 0.000000
- 1.06744240620741726033315899258013814687728881835938e+00, // 0.123457
- 4.67893435960980846877177441456296946853399276733398e-02, // 3.141593
- 6.21577700803265520423934731297777034342288970947266e-02, // 2.718282
- 6.08297892453159572134779864427400752902030944824219e-01, // 0.314159
- 6.67937897133176639030693877430167049169540405273438e-01, // 0.271828
- };
-
- public static final double[] SCIPY_CHISQ_CDF_2 = { //
- 4.87705754992859910612601481716410489752888679504395e-02, // 0.100000
- 9.51625819640404407850908796717703808099031448364258e-02, // 0.200000
- 1.39292023574942191999070928432047367095947265625000e-01, // 0.300000
- 1.81269246922018151257915974383649881929159164428711e-01, // 0.400000
- 2.21199216928595121522960198490181937813758850097656e-01, // 0.500000
- 2.59181779318282068391710026844521053135395050048828e-01, // 0.600000
- 2.95311910281286504886821830950793810188770294189453e-01, // 0.700000
- 3.29679953964360561435853469447465613484382629394531e-01, // 0.800000
- 3.62371848378226779630040255142375826835632324218750e-01, // 0.900000
- 3.93469340287366520225731392201851122081279754638672e-01, // 1.000000
- 4.23050189619513239414061445131665095686912536621094e-01, // 1.100000
- 4.51188363905973610634703163668746128678321838378906e-01, // 1.200000
- 4.77954223238983844090910224622348323464393615722656e-01, // 1.300000
- 5.03414696208590473069932613725541159510612487792969e-01, // 1.400000
- 5.27633447258985310845957883429946377873420715332031e-01, // 1.500000
- 5.50671035882778325820652298716595396399497985839844e-01, // 1.600000
- 5.72585068051273293754377391451271250844001770019531e-01, // 1.700000
- 5.93430340259400890268182138242991641163825988769531e-01, // 1.800000
- 6.13258976545498768473407835699617862701416015625000e-01, // 1.900000
- 6.32120558828557776998025019565830007195472717285156e-01, // 2.000000
- 4.99998750002083230991115070374064544012071564793587e-06, // 0.000010
- 4.99999999987500220561171362591683115655927238663025e-11, // 0.000000
- 5.98617593408454426451292818001093110069632530212402e-02, // 0.123457
- 7.92120423649238181162957062042551115155220031738281e-01, // 3.141593
- 7.43118634686529722088721428008284419775009155273438e-01, // 2.718282
- 1.45364000846766538987964167972677387297153472900391e-01, // 0.314159
- 1.27082379621731661467620710936898831278085708618164e-01, // 0.271828
- };
-
- public static final double[] SCIPY_CHISQ_PDF_2 = { //
- 4.75614712250357007938816877867793664336204528808594e-01, // 0.100000
- 4.52418709017979814301924079700256697833538055419922e-01, // 0.200000
- 4.30353988212528904000464535783976316452026367187500e-01, // 0.300000
- 4.09365376538990910493254204993718303740024566650391e-01, // 0.400000
- 3.89400391535702439238519900754909031093120574951172e-01, // 0.500000
- 3.70409110340858993559720602206652984023094177246094e-01, // 0.600000
- 3.52344044859356719801013468895689584314823150634766e-01, // 0.700000
- 3.35160023017819663770922034018440172076225280761719e-01, // 0.800000
- 3.18814075810886610184979872428812086582183837890625e-01, // 0.900000
- 3.03265329856316712131558688270160928368568420410156e-01, // 1.000000
- 2.88474905190243380292969277434167452156543731689453e-01, // 1.100000
- 2.74405818047013250193799649423453956842422485351562e-01, // 1.200000
- 2.61022888380508022443393656430998817086219787597656e-01, // 1.300000
- 2.48292651895704791220609308766142930835485458374023e-01, // 1.400000
- 2.36183276370507344577021058285026811063289642333984e-01, // 1.500000
- 2.24664482058610809334098235012788791209459304809570e-01, // 1.600000
- 2.13707465974363353122811304274364374577999114990234e-01, // 1.700000
- 2.03284829870299554865908930878504179418087005615234e-01, // 1.800000
- 1.93370511727250643518871697779104579240083694458008e-01, // 1.900000
- 1.83939720585721139256563105845998506993055343627930e-01, // 2.000000
- 4.99997500006249984139117259474005550146102905273438e-01, // 0.000010
- 4.99999999974999997931490725022740662097930908203125e-01, // 0.000000
- 4.70069120329577316841351830589701421558856964111328e-01, // 0.123457
- 1.03939788175380951051884892422094708308577537536621e-01, // 3.141593
- 1.28440682656735138955639285995857790112495422363281e-01, // 2.718282
- 4.27317999576616702750442300384747795760631561279297e-01, // 0.314159
- 4.36458810189134183143977452346007339656352996826172e-01, // 0.271828
- };
-
- public static final double[] GNUR_CHISQ_CDF_2 = { //
- 4.87705754992859910612601481716410489752888679504395e-02, // 0.100000
- 9.51625819640404269073030718573136255145072937011719e-02, // 0.200000
- 1.39292023574942191999070928432047367095947265625000e-01, // 0.300000
- 1.81269246922018151257915974383649881929159164428711e-01, // 0.400000
- 2.21199216928595121522960198490181937813758850097656e-01, // 0.500000
- 2.59181779318282123902861258102348074316978454589844e-01, // 0.600000
- 2.95311910281286560397973062208620831370353698730469e-01, // 0.700000
- 3.29679953964360727969307163220946677029132843017578e-01, // 0.800000
- 3.62371848378226724118889023884548805654048919677734e-01, // 0.900000
- 3.93469340287366575736882623459678143262863159179688e-01, // 1.000000
- 4.23050189619513350436363907647319138050079345703125e-01, // 1.100000
- 4.51188363905973610634703163668746128678321838378906e-01, // 1.200000
- 4.77954223238983955113212687138002365827560424804688e-01, // 1.300000
- 5.03414696208590473069932613725541159510612487792969e-01, // 1.400000
- 5.27633447258985310845957883429946377873420715332031e-01, // 1.500000
- 5.50671035882778325820652298716595396399497985839844e-01, // 1.600000
- 5.72585068051273404776679853966925293207168579101562e-01, // 1.700000
- 5.93430340259400890268182138242991641163825988769531e-01, // 1.800000
- 6.13258976545498657451105373183963820338249206542969e-01, // 1.900000
- 6.32120558828557665975722557050175964832305908203125e-01, // 2.000000
- 4.99998750002083400397704521234132357676571700721979e-06, // 0.000010
- 4.99999999987500026690715295475821817669515034765482e-11, // 0.000000
- 5.98617593408454426451292818001093110069632530212402e-02, // 0.123457
- 7.92120423649259608467332327563781291246414184570312e-01, // 3.141593
- 7.43118634686652401732942507806001231074333190917969e-01, // 2.718282
- 1.45364000846775420772161169225000776350498199462891e-01, // 0.314159
- 1.27082379621773322586619769936078228056430816650391e-01, // 0.271828
- };
-
- public static final double[] GNUR_CHISQ_PDF_2 = { //
- 4.75614712250357007938816877867793664336204528808594e-01, // 0.100000
- 4.52418709017979758790772848442429676651954650878906e-01, // 0.200000
- 4.30353988212528904000464535783976316452026367187500e-01, // 0.300000
- 4.09365376538990910493254204993718303740024566650391e-01, // 0.400000
- 3.89400391535702439238519900754909031093120574951172e-01, // 0.500000
- 3.70409110340858938048569370948825962841510772705078e-01, // 0.600000
- 3.52344044859356719801013468895689584314823150634766e-01, // 0.700000
- 3.35160023017819663770922034018440172076225280761719e-01, // 0.800000
- 3.18814075810886665696131103686639107763767242431641e-01, // 0.900000
- 3.03265329856316712131558688270160928368568420410156e-01, // 1.000000
- 2.88474905190243324781818046176340430974960327148438e-01, // 1.100000
- 2.74405818047013194682648418165626935660839080810547e-01, // 1.200000
- 2.61022888380508022443393656430998817086219787597656e-01, // 1.300000
- 2.48292651895704763465033693137229420244693756103516e-01, // 1.400000
- 2.36183276370507344577021058285026811063289642333984e-01, // 1.500000
- 2.24664482058610781578522619383875280618667602539062e-01, // 1.600000
- 2.13707465974363353122811304274364374577999114990234e-01, // 1.700000
- 2.03284829870299554865908930878504179418087005615234e-01, // 1.800000
- 1.93370511727250615763296082150191068649291992187500e-01, // 1.900000
- 1.83939720585721167012138721474912017583847045898438e-01, // 2.000000
- 4.99997500006249984139117259474005550146102905273438e-01, // 0.000010
- 4.99999999974999997931490725022740662097930908203125e-01, // 0.000000
- 4.70069120329577261330200599331874400377273559570312e-01, // 0.123457
- 1.03939788175370209644121644032566109672188758850098e-01, // 3.141593
- 1.28440682656673799133528746096999384462833404541016e-01, // 2.718282
- 4.27317999576612317369495031016413122415542602539062e-01, // 0.314159
- 4.36458810189113310951114499403047375380992889404297e-01, // 0.271828
- };
-
- public static final double[] SCIPY_CHISQ_CDF_4 = { //
- 1.20910427425029100463593767500469766673631966114044e-03, // 0.100000
- 4.67884016044447376136972138738201465457677841186523e-03, // 0.200000
- 1.01858271111835239214338244551072421018034219741821e-02, // 0.300000
- 1.75230963064217717950477037902601296082139015197754e-02, // 0.400000
- 2.64990211607439123120411039735699887387454509735107e-02, // 0.500000
- 3.69363131137667791148437856918462784960865974426270e-02, // 0.600000
- 4.86710788797368384961394838228443404659628868103027e-02, // 0.700000
- 6.15519355501049983403483167876402148976922035217285e-02, // 0.800000
- 7.54391801484287222168134690036822576075792312622070e-02, // 0.900000
- 9.02040104310498636053239351895172148942947387695312e-02, // 1.000000
- 1.05727793910245615460752333092386834323406219482422e-01, // 1.100000
- 1.21901382249557641013204545288317603990435600280762e-01, // 1.200000
- 1.38624468344323514834570687526138499379158020019531e-01, // 1.300000
- 1.55804983554603787565540073956071864813566207885742e-01, // 1.400000
- 1.73358532703224266224850680373492650687694549560547e-01, // 1.500000
- 1.91207864589001103050591723331308458000421524047852e-01, // 1.600000
- 2.09282375894855626752288912939548026770353317260742e-01, // 1.700000
- 2.27517646492861713714006555164814926683902740478516e-01, // 1.800000
- 2.45855004263722698443217495878343470394611358642578e-01, // 1.900000
- 2.64241117657115276440293882842524908483028411865234e-01, // 2.000000
- 1.24999583334114298362906795536861261509270493164081e-11, // 0.000010
- 1.24999999995833552159194802776351939183872839712033e-21, // 0.000000
- 1.82857697305291249344205706250932053080759942531586e-03, // 0.123457
- 4.65583948701781880075145636510569602251052856445312e-01, // 3.141593
- 3.93980660985851938171720121317775920033454895019531e-01, // 2.718282
- 1.11180920251080228577933439737535081803798675537109e-02, // 0.314159
- 8.44057436093374746644002470929990522563457489013672e-03, // 0.271828
- };
-
- public static final double[] SCIPY_CHISQ_PDF_4 = { //
- 2.37807356125178670502862132707377895712852478027344e-02, // 0.100000
- 4.52418709017979800424136271885799942538142204284668e-02, // 0.200000
- 6.45530982318793383756272419304877985268831253051758e-02, // 0.300000
- 8.18730753077981932008810872503090649843215942382812e-02, // 0.400000
- 9.73500978839256236874177830031840130686759948730469e-02, // 0.500000
- 1.11122733102257703619031303787778597325086593627930e-01, // 0.600000
- 1.23320415700774871359257645053730811923742294311523e-01, // 0.700000
- 1.34064009207127854406138567355810664594173431396484e-01, // 0.800000
- 1.43466334114899007889931681347661651670932769775391e-01, // 0.900000
- 1.51632664928158356065779344135080464184284210205078e-01, // 1.000000
- 1.58661197854633867487805787277466151863336563110352e-01, // 1.100000
- 1.64643490828207922360704174025158863514661788940430e-01, // 1.200000
- 1.69664877447330247894896615434845443814992904663086e-01, // 1.300000
- 1.73804856326993356629984077699191402643918991088867e-01, // 1.400000
- 1.77137457277880522310553601528226863592863082885742e-01, // 1.500000
- 1.79731585646888653018393711136013735085725784301758e-01, // 1.600000
- 1.81651346078208847378832047070318367332220077514648e-01, // 1.700000
- 1.82956346883269588277087791539088357239961624145508e-01, // 1.800000
- 1.83701986140888090526246401168464217334985733032227e-01, // 1.900000
- 1.83939720585721139256563105845998506993055343627930e-01, // 2.000000
- 2.49998750003124934010532293138240333973953966051340e-06, // 0.000010
- 2.49999999987499629841753832369663826905303860570484e-11, // 0.000000
- 2.90165911838962502222738493173892493359744548797607e-02, // 0.123457
- 1.63268237473728039521603250250336714088916778564453e-01, // 3.141593
- 1.74568986850338975225227500231994781643152236938477e-01, // 2.718282
- 6.71229544108292858206610276283754501491785049438477e-02, // 0.314159
- 5.93209026303989431228025352993427077308297157287598e-02, // 0.271828
- };
-
- public static final double[] GNUR_CHISQ_CDF_4 = { //
- 1.20910427425029057095506868080292406375519931316376e-03, // 0.100000
- 4.67884016044447115928450742217137303669005632400513e-03, // 0.200000
- 1.01858271111835187172633965246859588660299777984619e-02, // 0.300000
- 1.75230963064217613867068479294175631366670131683350e-02, // 0.400000
- 2.64990211607439261898289117880267440341413021087646e-02, // 0.500000
- 3.69363131137667860537376895990746561437845230102539e-02, // 0.600000
- 4.86710788797368662517150994517578510567545890808105e-02, // 0.700000
- 6.15519355501050191570300285093253478407859802246094e-02, // 0.800000
- 7.54391801484287360946012768181390129029750823974609e-02, // 0.900000
- 9.02040104310498774831117430039739701896905899047852e-02, // 1.000000
- 1.05727793910245615460752333092386834323406219482422e-01, // 1.100000
- 1.21901382249557682646567968731687869876623153686523e-01, // 1.200000
- 1.38624468344323542590146303155052009969949722290039e-01, // 1.300000
- 1.55804983554603898587842536471725907176733016967773e-01, // 1.400000
- 1.73358532703224266224850680373492650687694549560547e-01, // 1.500000
- 1.91207864589001158561742954589135479182004928588867e-01, // 1.600000
- 2.09282375894855654507864528568461537361145019531250e-01, // 1.700000
- 2.27517646492861658202855323906987905502319335937500e-01, // 1.800000
- 2.45855004263722753954368727136170491576194763183594e-01, // 1.900000
- 2.64241117657115276440293882842524908483028411865234e-01, // 2.000000
- 1.24999583334114362986392151242148360838074561129929e-11, // 0.000010
- 1.24999999995832724611171823885946329193350635251076e-21, // 0.000000
- 1.82857697305291162608031907410577332484535872936249e-03, // 0.123457
- 4.65583948701815852899699166300706565380096435546875e-01, // 3.141593
- 3.93980660986018471625413894798839464783668518066406e-01, // 2.718282
- 1.11180920251094158407445533498503209557384252548218e-02, // 0.314159
- 8.44057436093940786914213703084897133521735668182373e-03, // 0.271828
- };
-
- public static final double[] GNUR_CHISQ_PDF_4 = { //
- 2.37807356125178601113923093635094119235873222351074e-02, // 0.100000
- 4.52418709017979661646258193741232389584183692932129e-02, // 0.200000
- 6.45530982318793522534150497449445538222789764404297e-02, // 0.300000
- 8.18730753077982070786688950647658202797174453735352e-02, // 0.400000
- 9.73500978839256236874177830031840130686759948730469e-02, // 0.500000
- 1.11122733102257675863455688158865086734294891357422e-01, // 0.600000
- 1.23320415700774885237045452868187567219138145446777e-01, // 0.700000
- 1.34064009207127882161714182984724175184965133666992e-01, // 0.800000
- 1.43466334114899007889931681347661651670932769775391e-01, // 0.900000
- 1.51632664928158356065779344135080464184284210205078e-01, // 1.000000
- 1.58661197854633839732230171648552641272544860839844e-01, // 1.100000
- 1.64643490828207977871855405282985884696245193481445e-01, // 1.200000
- 1.69664877447330220139320999805931933224201202392578e-01, // 1.300000
- 1.73804856326993328874408462070277892053127288818359e-01, // 1.400000
- 1.77137457277880550066129217157140374183654785156250e-01, // 1.500000
- 1.79731585646888653018393711136013735085725784301758e-01, // 1.600000
- 1.81651346078208847378832047070318367332220077514648e-01, // 1.700000
- 1.82956346883269616032663407168001867830753326416016e-01, // 1.800000
- 1.83701986140888090526246401168464217334985733032227e-01, // 1.900000
- 1.83939720585721167012138721474912017583847045898438e-01, // 2.000000
- 2.49998750003124891658884930423223380557828932069242e-06, // 0.000010
- 2.49999999987500469947063456538396118179756744126507e-11, // 0.000000
- 2.90165911838962536917208012710034381598234176635742e-02, // 0.123457
- 1.63268237473721905539392196260450873523950576782227e-01, // 3.141593
- 1.74568986850316937298188690874667372554540634155273e-01, // 2.718282
- 6.71229544108329911900057140883291140198707580566406e-02, // 0.314159
- 5.93209026304169703691648862786678364500403404235840e-02, // 0.271828
- };
-
- public static final double[] SCIPY_CHISQ_CDF_10 = { //
- 2.49795133600650746949935939182803334990268240289879e-09, // 0.100000
- 7.66780168618932654114059375288769970779867435339838e-08, // 0.200000
- 5.58580784810275424538130676493929982484587526414543e-07, // 0.300000
- 2.25819055295782344450553069670206696173409000039101e-06, // 0.400000
- 6.61171056103424409242054135549260251991654513403773e-06, // 0.500000
- 1.57850405416599700160560498796158412915247026830912e-05, // 0.600000
- 3.27361747531325168996535479593035233847331255674362e-05, // 0.700000
- 6.12433271023337950488690806238878394651692360639572e-05, // 0.800000
- 1.05904769283482884140341895307102504375507123768330e-04, // 0.900000
- 1.72115629955840721259513470542401591956149786710739e-04, // 1.000000
- 2.66026240432705039958005688305320290965028107166290e-04, // 1.100000
- 3.94486018340255682485678834225950595282483845949173e-04, // 1.200000
- 5.64976348978787402434209585777580286958254873752594e-04, // 1.300000
- 7.85535448953023811638485263131315150531008839607239e-04, // 1.400000
- 1.06467777278579280725301359211698581930249929428101e-03, // 1.500000
- 1.41131014588673502248294955307983400416560471057892e-03, // 1.600000
- 1.83464647201952166591376602866603207075968384742737e-03, // 1.700000
- 2.34412256627762561819738884594244154868647456169128e-03, // 1.800000
- 2.94931240186648664300395061843573785154148936271667e-03, // 1.900000
- 3.65984682734371308959753221756727725733071565628052e-03, // 2.000000
- 2.60415581599546609733287774064553218283559941928103e-29, // 0.000010
- 2.60416666655820244729903965275602508551632679775379e-54, // 0.000000
- 7.09444350487475695446226334845915562077323102130322e-09, // 0.123457
- 2.21073482327962915483521300075153703801333904266357e-02, // 3.141593
- 1.27010572812203369197359137388048111461102962493896e-02, // 2.718282
- 6.99320669493774398455519271389224655877114855684340e-07, // 0.314159
- 3.45169511596339609613224696377242750600089493673295e-07, // 0.271828
- };
-
- public static final double[] SCIPY_CHISQ_PDF_10 = { //
- 1.23857997981863822630169027876056997428122485871427e-07, // 0.100000
- 1.88507795424158187552754212951144907606249034870416e-06, // 0.200000
- 9.07777943885801461183782112840390254859812557697296e-06, // 0.300000
- 2.72910251025994052959371821698297821967571508139372e-05, // 0.400000
- 6.33789699765140417814235362925501249264925718307495e-05, // 0.500000
- 1.25013074740039885346387649178723222576081752777100e-04, // 0.600000
- 2.20306784298780056327235477020565213024383410811424e-04, // 0.700000
- 3.57504024552340871068167871271725744009017944335938e-04, // 0.800000
- 5.44723737342507358799581496100472577381879091262817e-04, // 0.900000
- 7.89753463167491365562455918336581817129626870155334e-04, // 1.000000
- 1.09988569971103010078361528201185137731954455375671e-03, // 1.100000
- 1.48179141745387061429584107941082038450986146926880e-03, // 1.200000
- 1.94142570704054513025527128888825245667248964309692e-03, // 1.300000
- 2.48396107167327909875931268857129907701164484024048e-03, // 1.400000
- 3.11374436621274317676943965693681093398481607437134e-03, // 1.500000
- 3.83427382713362290000969068159974995069205760955811e-03, // 1.600000
- 4.64819303792833159877373461199567827861756086349487e-03, // 1.700000
- 5.55729903657931241511835906976557453162968158721924e-03, // 1.800000
- 6.56256209864766217043641205464155063964426517486572e-03, // 1.900000
- 7.66415502440504978198809737932606367394328117370605e-03, // 2.000000
- 1.30207682293293247342964777423805818639678689634258e-23, // 0.000010
- 1.30208333326823731527652024476599117068802519713176e-43, // 0.000000
- 2.84373520508469333784316900384792070610728842439130e-07, // 0.123457
- 2.63663549177880519869265896204524324275553226470947e-02, // 3.141593
- 1.82620407865934676616692655670703970827162265777588e-02, // 2.718282
- 1.08397546669860501598013635682349331545992754399776e-05, // 0.314159
- 6.20568843801925594646975298251945218908076640218496e-06, // 0.271828
- };
-
- public static final double[] GNUR_CHISQ_CDF_10 = { //
- 2.49795133600649837051262130852360976440706963330740e-09, // 0.100000
- 7.66780168618931198276181281960062197100569392205216e-08, // 0.200000
- 5.58580784810275424538130676493929982484587526414543e-07, // 0.300000
- 2.25819055295782302098905706955189742757283966057003e-06, // 0.400000
- 6.61171056103425340978296115279633227146405261009932e-06, // 0.500000
- 1.57850405416599598516606828280117724716546945273876e-05, // 0.600000
- 3.27361747531325507809714381313170861176331527531147e-05, // 0.700000
- 6.12433271023336866286518320734444387198891490697861e-05, // 0.800000
- 1.05904769283483060323194924201573030586587265133858e-04, // 0.900000
- 1.72115629955840395998861724891071389720309525728226e-04, // 1.000000
- 2.66026240432705039958005688305320290965028107166290e-04, // 1.100000
- 3.94486018340255411435135712849842093419283628463745e-04, // 1.200000
- 5.64976348978787619274644082878467088448815047740936e-04, // 1.300000
- 7.85535448953025112681092245736635959474369883537292e-04, // 1.400000
- 1.06467777278579280725301359211698581930249929428101e-03, // 1.500000
- 1.41131014588673415512121156467628679820336401462555e-03, // 1.600000
- 1.83464647201952231643506951996869247523136436939240e-03, // 1.700000
- 2.34412256627762518451651985174066794570535421371460e-03, // 1.800000
- 2.94931240186649314821698553146234189625829458236694e-03, // 1.900000
- 3.65984682734371439064013920017259806627407670021057e-03, // 2.000000
- 2.60415581599546665785226347057236055232743273524748e-29, // 0.000010
- 2.60416666655812826317602590432831045081109584496352e-54, // 0.000000
- 7.09444350487472965750204909854588486428639271252905e-09, // 0.123457
- 2.21073482328017455189606010890202014707028865814209e-02, // 3.141593
- 1.27010572812377743601164326037178398109972476959229e-02, // 2.718282
- 6.99320669493999391582133694916789679041357885580510e-07, // 0.314159
- 3.45169511596932850313657926977217726971502997912467e-07, // 0.271828
- };
-
- public static final double[] GNUR_CHISQ_PDF_10 = { //
- 1.23857997981864007918626239754256168623669509543106e-07, // 0.100000
- 1.88507795424158484014285751956263581519124272745103e-06, // 0.200000
- 9.07777943885802816436497719720932764175813645124435e-06, // 0.300000
- 2.72910251025994493416504393934474137495271861553192e-05, // 0.400000
- 6.33789699765140824390050044989664002059726044535637e-05, // 0.500000
- 1.25013074740039749821116088490668971644481644034386e-04, // 0.600000
- 2.20306784298780218957561349846230314142303541302681e-04, // 0.700000
- 3.57504024552340437387298877069952141027897596359253e-04, // 0.800000
- 5.44723737342507684060233241751802779617719352245331e-04, // 0.900000
- 7.89753463167491907663542161088798820856027305126190e-04, // 1.000000
- 1.09988569971102879974100829940653056837618350982666e-03, // 1.100000
- 1.48179141745387169849801356491525439196266233921051e-03, // 1.200000
- 1.94142570704054556393614028309002605965360999107361e-03, // 1.300000
- 2.48396107167327953244018168277307267999276518821716e-03, // 1.400000
- 3.11374436621274404413117764534035813994705677032471e-03, // 1.500000
- 3.83427382713362723681838062361748598050326108932495e-03, // 1.600000
- 4.64819303792833680294416254241696151439100503921509e-03, // 1.700000
- 5.55729903657931414984183504657266894355416297912598e-03, // 1.800000
- 6.56256209864766303779815004304509784560650587081909e-03, // 1.900000
- 7.66415502440505238407331134453670529183000326156616e-03, // 2.000000
- 1.30207682293293908558537114960529051053980877147452e-23, // 0.000010
- 1.30208333326823472650216465453104099875737882460008e-43, // 0.000000
- 2.84373520508469280844757696991020878840572549961507e-07, // 0.123457
- 2.63663549177922673649732132616918534040451049804688e-02, // 3.141593
- 1.82620407866104020322417511579260462895035743713379e-02, // 2.718282
- 1.08397546669888199575388851303436865691764978691936e-05, // 0.314159
- 6.20568843802768815945966954239487733957503223791718e-06, // 0.271828
- };
-
- public static final double[] P_QUANT = { //
- 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99, 0.999, 0.9999 //
- };
-
- public static final double[] SCIPY_CHISQ_QUANT_01 = { //
- 1.16892641156733644781219710813445996321826192936318e-80, // 0.000100
- 1.16892641146821240352815603348024825656653422803765e-60, // 0.001000
- 1.16892641145814869325987350586058419394529211182657e-40, // 0.010000
- 1.16892641145721739436487227654675467673153240504758e-20, // 0.100000
- 1.06313237798343417157777858600350238808297798076552e-12, // 0.250000
- 1.11477568814925462586246096563513674482237547636032e-06, // 0.500000
- 3.71347136769252343657665704768078285269439220428467e-03, // 0.750000
- 1.52634227818377987695441788673633709549903869628906e-01, // 0.900000
- 2.17525480018361871970000720466487109661102294921875e+00, // 0.990000
- 5.47291719745734983604279477731324732303619384765625e+00, // 0.999000
- 9.24820164420099821711573895299807190895080566406250e+00, // 0.999900
- };
-
- public static final double[] GNUR_CHISQ_QUANT_01 = { //
- 1.16892641145733484384707827779994069422035569294114e-80, // 0.000100
- 1.16892641145731079523768921414073055688308402765104e-60, // 0.001000
- 1.16892641145731997959243769324569198659341653028700e-40, // 0.010000
- 1.16892641145730436213892351266574423573550225567180e-20, // 0.100000
- 1.06313237798339660917691558230537590321561347561641e-12, // 0.250000
- 1.11477568814925102597243513485869570445174758788198e-06, // 0.500000
- 3.71347136769249915044799337238146108575165271759033e-03, // 0.750000
- 1.52634227818377238294900166692968923598527908325195e-01, // 0.900000
- 2.17525480018361827561079735460225492715835571289062e+00, // 0.990000
- 5.47291719745735161239963417756371200084686279296875e+00, // 0.999000
- 9.24820164420099821711573895299807190895080566406250e+00, // 0.999900
- };
-
- public static final double[] SCIPY_CHISQ_QUANT_1 = { //
- 1.57079633500628175845386844643181145642074625357054e-08, // 0.000100
- 1.57079714926323284399762268692679612058782367967069e-06, // 0.001000
- 1.57087857909697853949632095904576090106274932622910e-04, // 0.010000
- 1.57907740934312285085994176370149943977594375610352e-02, // 0.100000
- 1.01531044267621481380636794256133725866675376892090e-01, // 0.250000
- 4.54936423119572663775755927417776547372341156005859e-01, // 0.500000
- 1.32330369693146554510576606844551861286163330078125e+00, // 0.750000
- 2.70554345409541641132022959936875849962234497070312e+00, // 0.900000
- 6.63489660102121447948775312397629022598266601562500e+00, // 0.990000
- 1.08275661706627310820749698905274271965026855468750e+01, // 0.999000
- 1.51367052266236044033576035872101783752441406250000e+01, // 0.999900
- };
-
- public static final double[] GNUR_CHISQ_QUANT_1 = { //
- 1.57079633501956727170820513452345612570582034095423e-08, // 0.000100
- 1.57079714926249020786111747910451796883535280358046e-06, // 0.001000
- 1.57087857909702001022941852959036168613238260149956e-04, // 0.010000
- 1.57907740934312285085994176370149943977594375610352e-02, // 0.100000
- 1.01531044267621550769575833328417502343654632568359e-01, // 0.250000
- 4.54936423119572830309209621191257610917091369628906e-01, // 0.500000
- 1.32330369693146598919497591850813478231430053710938e+00, // 0.750000
- 2.70554345409541507905260004918090999126434326171875e+00, // 0.900000
- 6.63489660102121181495249402360059320926666259765625e+00, // 0.990000
- 1.08275661706627310820749698905274271965026855468750e+01, // 0.999000
- 1.51367052266236044033576035872101783752441406250000e+01, // 0.999900
- };
-
- public static final double[] SCIPY_CHISQ_QUANT_2 = { //
- 2.00010000666460950081992908877737136208452284336090e-04, // 0.000100
- 2.00100066716752279100122180466314603108912706375122e-03, // 0.001000
- 2.01006717070028942395687465705123031511902809143066e-02, // 0.010000
- 2.10721031315652534976479159922746475785970687866211e-01, // 0.100000
- 5.75364144903561913757528145652031525969505310058594e-01, // 0.250000
- 1.38629436111989057245352796599036082625389099121094e+00, // 0.500000
- 2.77258872223978158899626578204333782196044921875000e+00, // 0.750000
- 4.60517018598809180218722758581861853599548339843750e+00, // 0.900000
- 9.21034037197618005166077637113630771636962890625000e+00, // 0.990000
- 1.38155105579642718538480039569549262523651123046875e+01, // 0.999000
- 1.84206807439525839242833171738311648368835449218750e+01, // 0.999900
- };
-
- public static final double[] GNUR_CHISQ_QUANT_2 = { //
- 2.00010000666716686269427927236108644137857481837273e-04, // 0.000100
- 2.00100066716706699240790889859908929793164134025574e-03, // 0.001000
- 2.01006717070028838312278907096697366796433925628662e-02, // 0.010000
- 2.10721031315652618243206006809487007558345794677734e-01, // 0.100000
- 5.75364144903561802735225683136377483606338500976562e-01, // 0.250000
- 1.38629436111989057245352796599036082625389099121094e+00, // 0.500000
- 2.77258872223978114490705593198072165250778198242188e+00, // 0.750000
- 4.60517018598809180218722758581861853599548339843750e+00, // 0.900000
- 9.21034037197618005166077637113630771636962890625000e+00, // 0.990000
- 1.38155105579642718538480039569549262523651123046875e+01, // 0.999000
- 1.84206807439525839242833171738311648368835449218750e+01, // 0.999900
- };
-
- public static final double[] SCIPY_CHISQ_QUANT_4 = { //
- 2.84184752435540088910670419863890856504440307617188e-02, // 0.000100
- 9.08040355389811981723369171959348022937774658203125e-02, // 0.001000
- 2.97109480506531686838656014515436254441738128662109e-01, // 0.010000
- 1.06362321677922411211625330906827002763748168945312e+00, // 0.100000
- 1.92255752622955422559414273564470931887626647949219e+00, // 0.250000
- 3.35669398003332153379574265272822231054306030273438e+00, // 0.500000
- 5.38526905777939113306729268515482544898986816406250e+00, // 0.750000
- 7.77944033973485904454037154209800064563751220703125e+00, // 0.900000
- 1.32767041359876234452030985266901552677154541015625e+01, // 0.990000
- 1.84668269529031690012743638362735509872436523437500e+01, // 0.999000
- 2.35127424449910797932261630194261670112609863281250e+01, // 0.999900
- };
-
- public static final double[] GNUR_CHISQ_QUANT_4 = { //
- 2.84184752435549976834483487664329004473984241485596e-02, // 0.000100
- 9.08040355389791442597413606563350185751914978027344e-02, // 0.001000
- 2.97109480506531964394412170804571360349655151367188e-01, // 0.010000
- 1.06362321677922389007164838403696194291114807128906e+00, // 0.100000
- 1.92255752622955400354953781061340123414993286132812e+00, // 0.250000
- 3.35669398003332108970653280266560614109039306640625e+00, // 0.500000
- 5.38526905777939202124571238528005778789520263671875e+00, // 0.750000
- 7.77944033973485904454037154209800064563751220703125e+00, // 0.900000
- 1.32767041359876216688462591264396905899047851562500e+01, // 0.990000
- 1.84668269529031690012743638362735509872436523437500e+01, // 0.999000
- 2.35127424449910762405124842189252376556396484375000e+01, // 0.999900
- };
-
- public static final double[] SCIPY_CHISQ_QUANT_10 = { //
- 8.88920357912773129172023800492752343416213989257812e-01, // 0.000100
- 1.47874346383567578655515717400703579187393188476562e+00, // 0.001000
- 2.55821216018720765106309045222587883472442626953125e+00, // 0.010000
- 4.86518205192532882108480407623574137687683105468750e+00, // 0.100000
- 6.73720077195464384089973464142531156539916992187500e+00, // 0.250000
- 9.34181776559196919151872862130403518676757812500000e+00, // 0.500000
- 1.25488613968893769623491607489995658397674560546875e+01, // 0.750000
- 1.59871791721052627366361775784753262996673583984375e+01, // 0.900000
- 2.32092511589543590844186837784945964813232421875000e+01, // 0.990000
- 2.95882984450744146442957571707665920257568359375000e+01, // 0.999000
- 3.55640139419523890751406725030392408370971679687500e+01, // 0.999900
- };
-
- public static final double[] GNUR_CHISQ_QUANT_10 = { //
- 8.88920357912895919838547342806123197078704833984375e-01, // 0.000100
- 1.47874346383566490636951584747293964028358459472656e+00, // 0.001000
- 2.55821216018720631879546090203803032636642456054688e+00, // 0.010000
- 4.86518205192532882108480407623574137687683105468750e+00, // 0.100000
- 6.73720077195464206454289524117484688758850097656250e+00, // 0.250000
- 9.34181776559196741516188922105357050895690917968750e+00, // 0.500000
- 1.25488613968893769623491607489995658397674560546875e+01, // 0.750000
- 1.59871791721052591839224987779743969440460205078125e+01, // 0.900000
- 2.32092511589543590844186837784945964813232421875000e+01, // 0.990000
- 2.95882984450744181970094359712675213813781738281250e+01, // 0.999000
- 3.55640139419523890751406725030392408370971679687500e+01, // 0.999900
- };
-
- @Test
- public void testPDF() {
- checkPDF(new ChiSquaredDistribution(1.), P_CDFPDF, SCIPY_CHISQ_PDF_1, 1e-12);
- checkPDF(new ChiSquaredDistribution(2.), P_CDFPDF, SCIPY_CHISQ_PDF_2, 1e-12);
- checkPDF(new ChiSquaredDistribution(4.), P_CDFPDF, SCIPY_CHISQ_PDF_4, 1e-12);
- checkPDF(new ChiSquaredDistribution(10), P_CDFPDF, SCIPY_CHISQ_PDF_10, 1e-12);
- checkPDF(new ChiSquaredDistribution(.1), P_CDFPDF, SCIPY_CHISQ_PDF_01, 1e-12);
- checkPDF(new ChiSquaredDistribution(1.), P_CDFPDF, GNUR_CHISQ_PDF_1, 1e-14);
- checkPDF(new ChiSquaredDistribution(2.), P_CDFPDF, GNUR_CHISQ_PDF_2, 1e-15);
- checkPDF(new ChiSquaredDistribution(4.), P_CDFPDF, GNUR_CHISQ_PDF_4, 1e-15);
- checkPDF(new ChiSquaredDistribution(10), P_CDFPDF, GNUR_CHISQ_PDF_10, 1e-15);
- checkPDF(new ChiSquaredDistribution(.1), P_CDFPDF, GNUR_CHISQ_PDF_01, 1e-14);
- }
-
- @Test
- public void testCDF() {
- checkCDF(new ChiSquaredDistribution(1.), P_CDFPDF, SCIPY_CHISQ_CDF_1, 1e-12);
- checkCDF(new ChiSquaredDistribution(2.), P_CDFPDF, SCIPY_CHISQ_CDF_2, 1e-12);
- checkCDF(new ChiSquaredDistribution(4.), P_CDFPDF, SCIPY_CHISQ_CDF_4, 1e-12);
- checkCDF(new ChiSquaredDistribution(10), P_CDFPDF, SCIPY_CHISQ_CDF_10, 1e-11);
- checkCDF(new ChiSquaredDistribution(.1), P_CDFPDF, SCIPY_CHISQ_CDF_01, 1e-13);
- checkCDF(new ChiSquaredDistribution(1.), P_CDFPDF, GNUR_CHISQ_CDF_1, 1e-15);
- checkCDF(new ChiSquaredDistribution(2.), P_CDFPDF, GNUR_CHISQ_CDF_2, 1e-15);
- checkCDF(new ChiSquaredDistribution(4.), P_CDFPDF, GNUR_CHISQ_CDF_4, 1e-15);
- checkCDF(new ChiSquaredDistribution(10), P_CDFPDF, GNUR_CHISQ_CDF_10, 1e-15);
- checkCDF(new ChiSquaredDistribution(.1), P_CDFPDF, GNUR_CHISQ_CDF_01, 1e-14);
- }
-
- @Test
- public void testQuantile() {
- checkQuantile(new ChiSquaredDistribution(1.), P_QUANT, SCIPY_CHISQ_QUANT_1, 1e-13);
- checkQuantile(new ChiSquaredDistribution(2.), P_QUANT, SCIPY_CHISQ_QUANT_2, 1e-13);
- checkQuantile(new ChiSquaredDistribution(4.), P_QUANT, SCIPY_CHISQ_QUANT_4, 1e-13);
- checkQuantile(new ChiSquaredDistribution(10), P_QUANT, SCIPY_CHISQ_QUANT_10, 1e-12);
- checkQuantile(new ChiSquaredDistribution(.1), P_QUANT, SCIPY_CHISQ_QUANT_01, 1e-13);
- checkQuantile(new ChiSquaredDistribution(1.), P_QUANT, GNUR_CHISQ_QUANT_1, 1e-13);
- checkQuantile(new ChiSquaredDistribution(2.), P_QUANT, GNUR_CHISQ_QUANT_2, 1e-14);
- checkQuantile(new ChiSquaredDistribution(4.), P_QUANT, GNUR_CHISQ_QUANT_4, 1e-13);
- checkQuantile(new ChiSquaredDistribution(10), P_QUANT, GNUR_CHISQ_QUANT_10, 1e-13);
- checkQuantile(new ChiSquaredDistribution(.1), P_QUANT, GNUR_CHISQ_QUANT_01, 1e-13);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestExponentialDistribution.java b/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestExponentialDistribution.java
deleted file mode 100644
index 8aa5a04a..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestExponentialDistribution.java
+++ /dev/null
@@ -1,826 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for the exponential distribution in ELKI.
- *
- * The reference values were computed using GNU R and SciPy.
- *
- * @author Erich Schubert
- */
-public class TestExponentialDistribution extends AbstractDistributionTest implements JUnit4Test {
- public static final double[] P_CDFPDF = { //
- 1e-10, 1e-05, 0.1, 0.1234567, 0.2, 0.271828182846, 0.3, 0.314159265359, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.71828182846, 3.14159265359 //
- };
-
- public static final double[] SCIPY_EXP_CDF_01 = { //
- 9.99999999995000020434998363876935860601602445996150e-12, // 0.000000
- 9.99999500000166912315989475867894498151144944131374e-07, // 0.000010
- 9.95016625083194709844303105228391359560191631317139e-03, // 0.100000
- 1.22697748626232703422767045253749529365450143814087e-02, // 0.123457
- 1.98013266932446987955707129458460258319973945617676e-02, // 0.200000
- 2.68166904430214188270742425856951740570366382598877e-02, // 0.271828
- 2.95544664514918210829197420252967276610434055328369e-02, // 0.300000
- 3.09275736951893608084329656549016362987458705902100e-02, // 0.314159
- 3.92105608476767883430191830029798438772559165954590e-02, // 0.400000
- 4.87705754992859910612601481716410489752888679504395e-02, // 0.500000
- 5.82354664157512871835997714242694200947880744934082e-02, // 0.600000
- 6.76061800940517682034780477806634735316038131713867e-02, // 0.700000
- 7.68836536133642167722967997178784571588039398193359e-02, // 0.800000
- 8.60688147287718141598134025116451084613800048828125e-02, // 0.900000
- 9.51625819640404269073030718573136255145072937011719e-02, // 1.000000
- 1.04165864703471763852427045549120521172881126403809e-01, // 1.100000
- 1.13079563282842479599032969872496323660016059875488e-01, // 1.200000
- 1.21904569079438682144278516261692857369780540466309e-01, // 1.300000
- 1.30641764601194171335762916896783281117677688598633e-01, // 1.400000
- 1.39292023574942191999070928432047367095947265625000e-01, // 1.500000
- 1.47856211033788653708143101539462804794311523437500e-01, // 1.600000
- 1.56335183403616295727545093541266396641731262207031e-01, // 1.700000
- 1.64729788588727971143654826846614014357328414916992e-01, // 1.800000
- 1.73040866056637682168783953784441109746694564819336e-01, // 1.900000
- 1.81269246922018151257915974383649881929159164428711e-01, // 2.000000
- 2.38014828033141334628908225568011403083801269531250e-01, // 2.718282
- 2.69597308951354364126018481329083442687988281250000e-01, // 3.141593
- };
-
- public static final double[] SCIPY_EXP_PDF_01 = { //
- 9.99999999989999999172596290009096264839172363281250e-02, // 0.000000
- 9.99999000000500043450202269923465792089700698852539e-02, // 0.000010
- 9.90049833749168106677984724228736013174057006835938e-02, // 0.100000
- 9.87730225137376793842491906616487540304660797119141e-02, // 0.123457
- 9.80198673306755252632171959703555330634117126464844e-02, // 0.200000
- 9.73183309556978626275736132811289280652999877929688e-02, // 0.271828
- 9.70445533548508210142102825557230971753597259521484e-02, // 0.300000
- 9.69072426304810607966544466762570664286613464355469e-02, // 0.314159
- 9.60789439152323204718086913089791778475046157836914e-02, // 0.400000
- 9.51229424500713988122058140106673818081617355346680e-02, // 0.500000
- 9.41764533584248664244142901225131936371326446533203e-02, // 0.600000
- 9.32393819905948245674309760033793281763792037963867e-02, // 0.700000
- 9.23116346386635699960976353395381011068820953369141e-02, // 0.800000
- 9.13931185271228130329035366230527870357036590576172e-02, // 0.900000
- 9.04837418035959462070394465627032332122325897216797e-02, // 1.000000
- 8.95834135296528222269785146636422723531723022460938e-02, // 1.100000
- 8.86920436717157506523179222313046921044588088989258e-02, // 1.200000
- 8.78095430920561303977933675923850387334823608398438e-02, // 1.300000
- 8.69358235398805800908661467474303208291530609130859e-02, // 1.400000
- 8.60707976425057752489777840310125611722469329833984e-02, // 1.500000
- 8.52143788966211318536281282831623684614896774291992e-02, // 1.600000
- 8.43664816596383648761303675200906582176685333251953e-02, // 1.700000
- 8.35270211411272001100769557524472475051879882812500e-02, // 1.800000
- 8.26959133943362262320064814957731869071722030639648e-02, // 1.900000
- 8.18730753077981793230932794358523096889257431030273e-02, // 2.000000
- 7.61985171966858693126667390060902107506990432739258e-02, // 2.718282
- 7.30402691048645663629557134299830067902803421020508e-02, // 3.141593
- };
-
- public static final double[] GNUR_EXP_CDF_01 = { //
- 9.99999999995000020434998363876935860601602445996150e-12, // 0.000000
- 9.99999500000166912315989475867894498151144944131374e-07, // 0.000010
- 9.95016625083194709844303105228391359560191631317139e-03, // 0.100000
- 1.22697748626232703422767045253749529365450143814087e-02, // 0.123457
- 1.98013266932446987955707129458460258319973945617676e-02, // 0.200000
- 2.68166904430307134754585263181070331484079360961914e-02, // 0.271828
- 2.95544664514918210829197420252967276610434055328369e-02, // 0.300000
- 3.09275736951913661487711948439027764834463596343994e-02, // 0.314159
- 3.92105608476767883430191830029798438772559165954590e-02, // 0.400000
- 4.87705754992859910612601481716410489752888679504395e-02, // 0.500000
- 5.82354664157512871835997714242694200947880744934082e-02, // 0.600000
- 6.76061800940517682034780477806634735316038131713867e-02, // 0.700000
- 7.68836536133642167722967997178784571588039398193359e-02, // 0.800000
- 8.60688147287718141598134025116451084613800048828125e-02, // 0.900000
- 9.51625819640404269073030718573136255145072937011719e-02, // 1.000000
- 1.04165864703471763852427045549120521172881126403809e-01, // 1.100000
- 1.13079563282842479599032969872496323660016059875488e-01, // 1.200000
- 1.21904569079438682144278516261692857369780540466309e-01, // 1.300000
- 1.30641764601194171335762916896783281117677688598633e-01, // 1.400000
- 1.39292023574942191999070928432047367095947265625000e-01, // 1.500000
- 1.47856211033788653708143101539462804794311523437500e-01, // 1.600000
- 1.56335183403616295727545093541266396641731262207031e-01, // 1.700000
- 1.64729788588727971143654826846614014357328414916992e-01, // 1.800000
- 1.73040866056637682168783953784441109746694564819336e-01, // 1.900000
- 1.81269246922018151257915974383649881929159164428711e-01, // 2.000000
- 2.38014828033214109748172404579236172139644622802734e-01, // 2.718282
- 2.69597308951369518670304614715860225260257720947266e-01, // 3.141593
- };
-
- public static final double[] GNUR_EXP_PDF_01 = { //
- 9.99999999989999999172596290009096264839172363281250e-02, // 0.000000
- 9.99999000000500043450202269923465792089700698852539e-02, // 0.000010
- 9.90049833749168106677984724228736013174057006835938e-02, // 0.100000
- 9.87730225137376793842491906616487540304660797119141e-02, // 0.123457
- 9.80198673306755252632171959703555330634117126464844e-02, // 0.200000
- 9.73183309556969328157904897125263232737779617309570e-02, // 0.271828
- 9.70445533548508210142102825557230971753597259521484e-02, // 0.300000
- 9.69072426304808665076251372738624922931194305419922e-02, // 0.314159
- 9.60789439152323204718086913089791778475046157836914e-02, // 0.400000
- 9.51229424500713988122058140106673818081617355346680e-02, // 0.500000
- 9.41764533584248664244142901225131936371326446533203e-02, // 0.600000
- 9.32393819905948245674309760033793281763792037963867e-02, // 0.700000
- 9.23116346386635699960976353395381011068820953369141e-02, // 0.800000
- 9.13931185271228130329035366230527870357036590576172e-02, // 0.900000
- 9.04837418035959462070394465627032332122325897216797e-02, // 1.000000
- 8.95834135296528222269785146636422723531723022460938e-02, // 1.100000
- 8.86920436717157506523179222313046921044588088989258e-02, // 1.200000
- 8.78095430920561303977933675923850387334823608398438e-02, // 1.300000
- 8.69358235398805800908661467474303208291530609130859e-02, // 1.400000
- 8.60707976425057752489777840310125611722469329833984e-02, // 1.500000
- 8.52143788966211318536281282831623684614896774291992e-02, // 1.600000
- 8.43664816596383648761303675200906582176685333251953e-02, // 1.700000
- 8.35270211411272001100769557524472475051879882812500e-02, // 1.800000
- 8.26959133943362262320064814957731869071722030639648e-02, // 1.900000
- 8.18730753077981793230932794358523096889257431030273e-02, // 2.000000
- 7.61985171966785973518554442307504359632730484008789e-02, // 2.718282
- 7.30402691048630536840846616541966795921325683593750e-02, // 3.141593
- };
-
- public static final double[] SCIPY_EXP_CDF_05 = { //
- 4.99999999987500026690715295475821817669515034765482e-11, // 0.000000
- 4.99998750002083400397704521234132357676571700721979e-06, // 0.000010
- 4.87705754992859910612601481716410489752888679504395e-02, // 0.100000
- 5.98617593408454357062353778928809333592653274536133e-02, // 0.123457
- 9.51625819640404269073030718573136255145072937011719e-02, // 0.200000
- 1.27082379621731633712045095307985320687294006347656e-01, // 0.271828
- 1.39292023574942191999070928432047367095947265625000e-01, // 0.300000
- 1.45364000846766566743539783601590897887945175170898e-01, // 0.314159
- 1.81269246922018151257915974383649881929159164428711e-01, // 0.400000
- 2.21199216928595121522960198490181937813758850097656e-01, // 0.500000
- 2.59181779318282123902861258102348074316978454589844e-01, // 0.600000
- 2.95311910281286560397973062208620831370353698730469e-01, // 0.700000
- 3.29679953964360727969307163220946677029132843017578e-01, // 0.800000
- 3.62371848378226724118889023884548805654048919677734e-01, // 0.900000
- 3.93469340287366575736882623459678143262863159179688e-01, // 1.000000
- 4.23050189619513350436363907647319138050079345703125e-01, // 1.100000
- 4.51188363905973555123551932410919107496738433837891e-01, // 1.200000
- 4.77954223238983955113212687138002365827560424804688e-01, // 1.300000
- 5.03414696208590473069932613725541159510612487792969e-01, // 1.400000
- 5.27633447258985310845957883429946377873420715332031e-01, // 1.500000
- 5.50671035882778436842954761232249438762664794921875e-01, // 1.600000
- 5.72585068051273293754377391451271250844001770019531e-01, // 1.700000
- 5.93430340259400890268182138242991641163825988769531e-01, // 1.800000
- 6.13258976545498768473407835699617862701416015625000e-01, // 1.900000
- 6.32120558828557665975722557050175964832305908203125e-01, // 2.000000
- 7.43118634686529722088721428008284419775009155273438e-01, // 2.718282
- 7.92120423649238070140654599526897072792053222656250e-01, // 3.141593
- };
-
- public static final double[] SCIPY_EXP_PDF_05 = { //
- 4.99999999974999997931490725022740662097930908203125e-01, // 0.000000
- 4.99997500006249984139117259474005550146102905273438e-01, // 0.000010
- 4.75614712250357007938816877867793664336204528808594e-01, // 0.100000
- 4.70069120329577261330200599331874400377273559570312e-01, // 0.123457
- 4.52418709017979758790772848442429676651954650878906e-01, // 0.200000
- 4.36458810189134183143977452346007339656352996826172e-01, // 0.271828
- 4.30353988212528904000464535783976316452026367187500e-01, // 0.300000
- 4.27317999576616702750442300384747795760631561279297e-01, // 0.314159
- 4.09365376538990910493254204993718303740024566650391e-01, // 0.400000
- 3.89400391535702439238519900754909031093120574951172e-01, // 0.500000
- 3.70409110340858938048569370948825962841510772705078e-01, // 0.600000
- 3.52344044859356719801013468895689584314823150634766e-01, // 0.700000
- 3.35160023017819663770922034018440172076225280761719e-01, // 0.800000
- 3.18814075810886665696131103686639107763767242431641e-01, // 0.900000
- 3.03265329856316712131558688270160928368568420410156e-01, // 1.000000
- 2.88474905190243324781818046176340430974960327148438e-01, // 1.100000
- 2.74405818047013194682648418165626935660839080810547e-01, // 1.200000
- 2.61022888380508022443393656430998817086219787597656e-01, // 1.300000
- 2.48292651895704763465033693137229420244693756103516e-01, // 1.400000
- 2.36183276370507344577021058285026811063289642333984e-01, // 1.500000
- 2.24664482058610781578522619383875280618667602539062e-01, // 1.600000
- 2.13707465974363353122811304274364374577999114990234e-01, // 1.700000
- 2.03284829870299554865908930878504179418087005615234e-01, // 1.800000
- 1.93370511727250615763296082150191068649291992187500e-01, // 1.900000
- 1.83939720585721167012138721474912017583847045898438e-01, // 2.000000
- 1.28440682656735111200063670366944279521703720092773e-01, // 2.718282
- 1.03939788175380964929672700236551463603973388671875e-01, // 3.141593
- };
-
- public static final double[] GNUR_EXP_CDF_05 = { //
- 4.99999999987500026690715295475821817669515034765482e-11, // 0.000000
- 4.99998750002083400397704521234132357676571700721979e-06, // 0.000010
- 4.87705754992859910612601481716410489752888679504395e-02, // 0.100000
- 5.98617593408454357062353778928809333592653274536133e-02, // 0.123457
- 9.51625819640404269073030718573136255145072937011719e-02, // 0.200000
- 1.27082379621773322586619769936078228056430816650391e-01, // 0.271828
- 1.39292023574942191999070928432047367095947265625000e-01, // 0.300000
- 1.45364000846775420772161169225000776350498199462891e-01, // 0.314159
- 1.81269246922018151257915974383649881929159164428711e-01, // 0.400000
- 2.21199216928595121522960198490181937813758850097656e-01, // 0.500000
- 2.59181779318282123902861258102348074316978454589844e-01, // 0.600000
- 2.95311910281286560397973062208620831370353698730469e-01, // 0.700000
- 3.29679953964360727969307163220946677029132843017578e-01, // 0.800000
- 3.62371848378226724118889023884548805654048919677734e-01, // 0.900000
- 3.93469340287366575736882623459678143262863159179688e-01, // 1.000000
- 4.23050189619513350436363907647319138050079345703125e-01, // 1.100000
- 4.51188363905973555123551932410919107496738433837891e-01, // 1.200000
- 4.77954223238983955113212687138002365827560424804688e-01, // 1.300000
- 5.03414696208590473069932613725541159510612487792969e-01, // 1.400000
- 5.27633447258985310845957883429946377873420715332031e-01, // 1.500000
- 5.50671035882778436842954761232249438762664794921875e-01, // 1.600000
- 5.72585068051273293754377391451271250844001770019531e-01, // 1.700000
- 5.93430340259400890268182138242991641163825988769531e-01, // 1.800000
- 6.13258976545498768473407835699617862701416015625000e-01, // 1.900000
- 6.32120558828557665975722557050175964832305908203125e-01, // 2.000000
- 7.43118634686652401732942507806001231074333190917969e-01, // 2.718282
- 7.92120423649259608467332327563781291246414184570312e-01, // 3.141593
- };
-
- public static final double[] GNUR_EXP_PDF_05 = { //
- 4.99999999974999997931490725022740662097930908203125e-01, // 0.000000
- 4.99997500006249984139117259474005550146102905273438e-01, // 0.000010
- 4.75614712250357007938816877867793664336204528808594e-01, // 0.100000
- 4.70069120329577261330200599331874400377273559570312e-01, // 0.123457
- 4.52418709017979758790772848442429676651954650878906e-01, // 0.200000
- 4.36458810189113310951114499403047375380992889404297e-01, // 0.271828
- 4.30353988212528904000464535783976316452026367187500e-01, // 0.300000
- 4.27317999576612317369495031016413122415542602539062e-01, // 0.314159
- 4.09365376538990910493254204993718303740024566650391e-01, // 0.400000
- 3.89400391535702439238519900754909031093120574951172e-01, // 0.500000
- 3.70409110340858938048569370948825962841510772705078e-01, // 0.600000
- 3.52344044859356719801013468895689584314823150634766e-01, // 0.700000
- 3.35160023017819663770922034018440172076225280761719e-01, // 0.800000
- 3.18814075810886665696131103686639107763767242431641e-01, // 0.900000
- 3.03265329856316712131558688270160928368568420410156e-01, // 1.000000
- 2.88474905190243324781818046176340430974960327148438e-01, // 1.100000
- 2.74405818047013194682648418165626935660839080810547e-01, // 1.200000
- 2.61022888380508022443393656430998817086219787597656e-01, // 1.300000
- 2.48292651895704763465033693137229420244693756103516e-01, // 1.400000
- 2.36183276370507344577021058285026811063289642333984e-01, // 1.500000
- 2.24664482058610781578522619383875280618667602539062e-01, // 1.600000
- 2.13707465974363353122811304274364374577999114990234e-01, // 1.700000
- 2.03284829870299554865908930878504179418087005615234e-01, // 1.800000
- 1.93370511727250615763296082150191068649291992187500e-01, // 1.900000
- 1.83939720585721167012138721474912017583847045898438e-01, // 2.000000
- 1.28440682656673799133528746096999384462833404541016e-01, // 2.718282
- 1.03939788175370209644121644032566109672188758850098e-01, // 3.141593
- };
-
- public static final double[] SCIPY_EXP_CDF_1 = { //
- 9.99999999950000070330663866405545691512513073462287e-11, // 0.000000
- 9.99995000016666629922851977640974041605659294873476e-06, // 0.000010
- 9.51625819640404269073030718573136255145072937011719e-02, // 0.100000
- 1.16140088450309583723019102308171568438410758972168e-01, // 0.123457
- 1.81269246922018151257915974383649881929159164428711e-01, // 0.200000
- 2.38014828033141334628908225568011403083801269531250e-01, // 0.271828
- 2.59181779318282123902861258102348074316978454589844e-01, // 0.300000
- 2.69597308951354364126018481329083442687988281250000e-01, // 0.314159
- 3.29679953964360727969307163220946677029132843017578e-01, // 0.400000
- 3.93469340287366575736882623459678143262863159179688e-01, // 0.500000
- 4.51188363905973555123551932410919107496738433837891e-01, // 0.600000
- 5.03414696208590473069932613725541159510612487792969e-01, // 0.700000
- 5.50671035882778436842954761232249438762664794921875e-01, // 0.800000
- 5.93430340259400890268182138242991641163825988769531e-01, // 0.900000
- 6.32120558828557665975722557050175964832305908203125e-01, // 1.000000
- 6.67128916301920504849931603530421853065490722656250e-01, // 1.100000
- 6.98805788087797918883836700842948630452156066894531e-01, // 1.200000
- 7.27468206965987462808698182925581932067871093750000e-01, // 1.300000
- 7.53403036058393538176858328370144590735435485839844e-01, // 1.400000
- 7.76869839851570209710018843907164409756660461425781e-01, // 1.500000
- 7.98103482005344644356625849468400701880455017089844e-01, // 1.600000
- 8.17316475947265308477085454796906560659408569335938e-01, // 1.700000
- 8.34701111778413440411839019361650571227073669433594e-01, // 1.800000
- 8.50431380777364909206994525447953492403030395507812e-01, // 1.900000
- 8.64664716763387297682186272140825167298316955566406e-01, // 2.000000
- 9.34011964154687457373427150741918012499809265136719e-01, // 2.718282
- 9.56786081736227700389463279861956834793090820312500e-01, // 3.141593
- };
-
- public static final double[] SCIPY_EXP_PDF_1 = { //
- 9.99999999899999991725962900090962648391723632812500e-01, // 0.000000
- 9.99990000049999827602675850357627496123313903808594e-01, // 0.000010
- 9.04837418035959517581545696884859353303909301757812e-01, // 0.100000
- 8.83859911549690457910344321135198697447776794433594e-01, // 0.123457
- 8.18730753077981820986508409987436607480049133300781e-01, // 0.200000
- 7.61985171966858665371091774431988596916198730468750e-01, // 0.271828
- 7.40818220681717876097138741897651925683021545410156e-01, // 0.300000
- 7.30402691048645635873981518670916557312011718750000e-01, // 0.314159
- 6.70320046035639327541844068036880344152450561523438e-01, // 0.400000
- 6.06530659712633424263117376540321856737136840820312e-01, // 0.500000
- 5.48811636094026389365296836331253871321678161621094e-01, // 0.600000
- 4.96585303791409526930067386274458840489387512207031e-01, // 0.700000
- 4.49328964117221563157045238767750561237335205078125e-01, // 0.800000
- 4.06569659740599109731817861757008358836174011230469e-01, // 0.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 1.000000
- 3.32871083698079550661219627727405168116092681884766e-01, // 1.100000
- 3.01194211912202136627314530414878390729427337646484e-01, // 1.200000
- 2.72531793034012592702453048332245089113712310791016e-01, // 1.300000
- 2.46596963941606489578717287258768919855356216430664e-01, // 1.400000
- 2.23130160148429818045556771721749100834131240844727e-01, // 1.500000
- 2.01896517994655383398949766160512808710336685180664e-01, // 1.600000
- 1.82683524052734663767338929574179928749799728393555e-01, // 1.700000
- 1.65298888221586531832585365009435918182134628295898e-01, // 1.800000
- 1.49568619222635063037429858923132997006177902221680e-01, // 1.900000
- 1.35335283236612702317813727859174832701683044433594e-01, // 2.000000
- 6.59880358453125426265728492580819875001907348632812e-02, // 2.718282
- 4.32139182637722579771732966946728993207216262817383e-02, // 3.141593
- };
-
- public static final double[] GNUR_EXP_CDF_1 = { //
- 9.99999999950000070330663866405545691512513073462287e-11, // 0.000000
- 9.99995000016666629922851977640974041605659294873476e-06, // 0.000010
- 9.51625819640404269073030718573136255145072937011719e-02, // 0.100000
- 1.16140088450309583723019102308171568438410758972168e-01, // 0.123457
- 1.81269246922018151257915974383649881929159164428711e-01, // 0.200000
- 2.38014828033214137503748020208149682730436325073242e-01, // 0.271828
- 2.59181779318282123902861258102348074316978454589844e-01, // 0.300000
- 2.69597308951369518670304614715860225260257720947266e-01, // 0.314159
- 3.29679953964360727969307163220946677029132843017578e-01, // 0.400000
- 3.93469340287366575736882623459678143262863159179688e-01, // 0.500000
- 4.51188363905973555123551932410919107496738433837891e-01, // 0.600000
- 5.03414696208590473069932613725541159510612487792969e-01, // 0.700000
- 5.50671035882778436842954761232249438762664794921875e-01, // 0.800000
- 5.93430340259400890268182138242991641163825988769531e-01, // 0.900000
- 6.32120558828557665975722557050175964832305908203125e-01, // 1.000000
- 6.67128916301920504849931603530421853065490722656250e-01, // 1.100000
- 6.98805788087797918883836700842948630452156066894531e-01, // 1.200000
- 7.27468206965987462808698182925581932067871093750000e-01, // 1.300000
- 7.53403036058393538176858328370144590735435485839844e-01, // 1.400000
- 7.76869839851570209710018843907164409756660461425781e-01, // 1.500000
- 7.98103482005344644356625849468400701880455017089844e-01, // 1.600000
- 8.17316475947265308477085454796906560659408569335938e-01, // 1.700000
- 8.34701111778413440411839019361650571227073669433594e-01, // 1.800000
- 8.50431380777364909206994525447953492403030395507812e-01, // 1.900000
- 8.64664716763387297682186272140825167298316955566406e-01, // 2.000000
- 9.34011964154750407018923397117760032415390014648438e-01, // 2.718282
- 9.56786081736236693195962743629934266209602355957031e-01, // 3.141593
- };
-
- public static final double[] GNUR_EXP_PDF_1 = { //
- 9.99999999899999991725962900090962648391723632812500e-01, // 0.000000
- 9.99990000049999827602675850357627496123313903808594e-01, // 0.000010
- 9.04837418035959517581545696884859353303909301757812e-01, // 0.100000
- 8.83859911549690457910344321135198697447776794433594e-01, // 0.123457
- 8.18730753077981820986508409987436607480049133300781e-01, // 0.200000
- 7.61985171966785834740676364162936806678771972656250e-01, // 0.271828
- 7.40818220681717876097138741897651925683021545410156e-01, // 0.300000
- 7.30402691048630536840846616541966795921325683593750e-01, // 0.314159
- 6.70320046035639327541844068036880344152450561523438e-01, // 0.400000
- 6.06530659712633424263117376540321856737136840820312e-01, // 0.500000
- 5.48811636094026389365296836331253871321678161621094e-01, // 0.600000
- 4.96585303791409526930067386274458840489387512207031e-01, // 0.700000
- 4.49328964117221563157045238767750561237335205078125e-01, // 0.800000
- 4.06569659740599109731817861757008358836174011230469e-01, // 0.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 1.000000
- 3.32871083698079550661219627727405168116092681884766e-01, // 1.100000
- 3.01194211912202136627314530414878390729427337646484e-01, // 1.200000
- 2.72531793034012592702453048332245089113712310791016e-01, // 1.300000
- 2.46596963941606489578717287258768919855356216430664e-01, // 1.400000
- 2.23130160148429818045556771721749100834131240844727e-01, // 1.500000
- 2.01896517994655383398949766160512808710336685180664e-01, // 1.600000
- 1.82683524052734663767338929574179928749799728393555e-01, // 1.700000
- 1.65298888221586531832585365009435918182134628295898e-01, // 1.800000
- 1.49568619222635063037429858923132997006177902221680e-01, // 1.900000
- 1.35335283236612702317813727859174832701683044433594e-01, // 2.000000
- 6.59880358452495374699253716244129464030265808105469e-02, // 2.718282
- 4.32139182637633137429311602772941114380955696105957e-02, // 3.141593
- };
-
- public static final double[] SCIPY_EXP_CDF_2 = { //
- 1.99999999979999994996431941180555121040374189078648e-10, // 0.000000
- 1.99998000013333293123189704498798846543650142848492e-05, // 0.000010
- 1.81269246922018151257915974383649881929159164428711e-01, // 0.100000
- 2.18791656755373431497702085835044272243976593017578e-01, // 0.123457
- 3.29679953964360727969307163220946677029132843017578e-01, // 0.200000
- 4.19378597702636857214031351759331300854682922363281e-01, // 0.271828
- 4.51188363905973555123551932410919107496738433837891e-01, // 0.300000
- 4.66511908908896710812541641644202172756195068359375e-01, // 0.314159
- 5.50671035882778436842954761232249438762664794921875e-01, // 0.400000
- 6.32120558828557665975722557050175964832305908203125e-01, // 0.500000
- 6.98805788087797918883836700842948630452156066894531e-01, // 0.600000
- 7.53403036058393538176858328370144590735435485839844e-01, // 0.700000
- 7.98103482005344644356625849468400701880455017089844e-01, // 0.800000
- 8.34701111778413440411839019361650571227073669433594e-01, // 0.900000
- 8.64664716763387297682186272140825167298316955566406e-01, // 1.000000
- 8.89196841637666102187154137936886399984359741210938e-01, // 1.100000
- 9.09282046710587543714154890039935708045959472656250e-01, // 1.200000
- 9.25726421785666109265378054260509088635444641113281e-01, // 1.300000
- 9.39189937374782068957301817135885357856750488281250e-01, // 1.400000
- 9.50212931632136048598624711303273215889930725097656e-01, // 1.500000
- 9.59237796021633837284525725408457219600677490234375e-01, // 1.600000
- 9.66626730039673920380494109849678352475166320800781e-01, // 1.700000
- 9.72676277552707468920800693013006821274757385253906e-01, // 1.800000
- 9.77629228143834350106544661684893071651458740234375e-01, // 1.900000
- 9.81684361111265779697987454710528254508972167968750e-01, // 2.000000
- 9.95645579125277735421661873260745778679847717285156e-01, // 2.718282
- 9.98132557268291975560714490711688995361328125000000e-01, // 3.141593
- };
-
- public static final double[] SCIPY_EXP_PDF_2 = { //
- 1.99999999959999996690385160036385059356689453125000e+00, // 0.000000
- 1.99996000039999732855733327596681192517280578613281e+00, // 0.000010
- 1.63746150615596364197301681997487321496009826660156e+00, // 0.100000
- 1.56241668648925324802689829084556549787521362304688e+00, // 0.123457
- 1.34064009207127865508368813607376068830490112304688e+00, // 0.200000
- 1.16124280459472628557193729648133739829063415527344e+00, // 0.271828
- 1.09762327218805277873059367266250774264335632324219e+00, // 0.300000
- 1.06697618218220657837491671671159565448760986328125e+00, // 0.314159
- 8.98657928234443126314090477535501122474670410156250e-01, // 0.400000
- 7.35758882342884668048554885899648070335388183593750e-01, // 0.500000
- 6.02388423824404273254629060829756781458854675292969e-01, // 0.600000
- 4.93193927883212979157434574517537839710712432861328e-01, // 0.700000
- 4.03793035989310766797899532321025617420673370361328e-01, // 0.800000
- 3.30597776443173063665170730018871836364269256591797e-01, // 0.900000
- 2.70670566473225404635627455718349665403366088867188e-01, // 1.000000
- 2.21606316724667740114540492868400178849697113037109e-01, // 1.100000
- 1.81435906578825023593992682435782626271247863769531e-01, // 1.200000
- 1.48547156428667753713668275850068312138319015502930e-01, // 1.300000
- 1.21620125250435945352123212614969816058874130249023e-01, // 1.400000
- 9.95741367357278889249627695789968129247426986694336e-02, // 1.500000
- 8.15244079567324225754632038842828478664159774780273e-02, // 1.600000
- 6.67465399206521592390117803006432950496673583984375e-02, // 1.700000
- 5.46474448945851176695498452318133786320686340332031e-02, // 1.800000
- 4.47415437123312026423960219290165696293115615844727e-02, // 1.900000
- 3.66312777774683573372982436922029592096805572509766e-02, // 2.000000
- 8.70884174944450660527106578001621528528630733489990e-03, // 2.718282
- 3.73488546341597862227024151593468559440225362777710e-03, // 3.141593
- };
-
- public static final double[] GNUR_EXP_CDF_2 = { //
- 1.99999999979999994996431941180555121040374189078648e-10, // 0.000000
- 1.99998000013333293123189704498798846543650142848492e-05, // 0.000010
- 1.81269246922018151257915974383649881929159164428711e-01, // 0.100000
- 2.18791656755373431497702085835044272243976593017578e-01, // 0.123457
- 3.29679953964360727969307163220946677029132843017578e-01, // 0.200000
- 4.19378597702747768494191404897719621658325195312500e-01, // 0.271828
- 4.51188363905973555123551932410919107496738433837891e-01, // 0.300000
- 4.66511908908918804250731682259356603026390075683594e-01, // 0.314159
- 5.50671035882778436842954761232249438762664794921875e-01, // 0.400000
- 6.32120558828557665975722557050175964832305908203125e-01, // 0.500000
- 6.98805788087797918883836700842948630452156066894531e-01, // 0.600000
- 7.53403036058393538176858328370144590735435485839844e-01, // 0.700000
- 7.98103482005344644356625849468400701880455017089844e-01, // 0.800000
- 8.34701111778413440411839019361650571227073669433594e-01, // 0.900000
- 8.64664716763387297682186272140825167298316955566406e-01, // 1.000000
- 8.89196841637666102187154137936886399984359741210938e-01, // 1.100000
- 9.09282046710587543714154890039935708045959472656250e-01, // 1.200000
- 9.25726421785666109265378054260509088635444641113281e-01, // 1.300000
- 9.39189937374782068957301817135885357856750488281250e-01, // 1.400000
- 9.50212931632136048598624711303273215889930725097656e-01, // 1.500000
- 9.59237796021633837284525725408457219600677490234375e-01, // 1.600000
- 9.66626730039673920380494109849678352475166320800781e-01, // 1.700000
- 9.72676277552707468920800693013006821274757385253906e-01, // 1.800000
- 9.77629228143834350106544661684893071651458740234375e-01, // 1.900000
- 9.81684361111265779697987454710528254508972167968750e-01, // 2.000000
- 9.95645579125286062094346561934798955917358398437500e-01, // 2.718282
- 9.98132557268292752716831728321267291903495788574219e-01, // 3.141593
- };
-
- public static final double[] GNUR_EXP_PDF_2 = { //
- 1.99999999959999996690385160036385059356689453125000e+00, // 0.000000
- 1.99996000039999732855733327596681192517280578613281e+00, // 0.000010
- 1.63746150615596364197301681997487321496009826660156e+00, // 0.100000
- 1.56241668648925324802689829084556549787521362304688e+00, // 0.123457
- 1.34064009207127865508368813607376068830490112304688e+00, // 0.200000
- 1.16124280459450446301161719020456075668334960937500e+00, // 0.271828
- 1.09762327218805277873059367266250774264335632324219e+00, // 0.300000
- 1.06697618218216239149853663548128679394721984863281e+00, // 0.314159
- 8.98657928234443126314090477535501122474670410156250e-01, // 0.400000
- 7.35758882342884668048554885899648070335388183593750e-01, // 0.500000
- 6.02388423824404273254629060829756781458854675292969e-01, // 0.600000
- 4.93193927883212979157434574517537839710712432861328e-01, // 0.700000
- 4.03793035989310766797899532321025617420673370361328e-01, // 0.800000
- 3.30597776443173063665170730018871836364269256591797e-01, // 0.900000
- 2.70670566473225404635627455718349665403366088867188e-01, // 1.000000
- 2.21606316724667740114540492868400178849697113037109e-01, // 1.100000
- 1.81435906578825023593992682435782626271247863769531e-01, // 1.200000
- 1.48547156428667753713668275850068312138319015502930e-01, // 1.300000
- 1.21620125250435945352123212614969816058874130249023e-01, // 1.400000
- 9.95741367357278889249627695789968129247426986694336e-02, // 1.500000
- 8.15244079567324225754632038842828478664159774780273e-02, // 1.600000
- 6.67465399206521592390117803006432950496673583984375e-02, // 1.700000
- 5.46474448945851176695498452318133786320686340332031e-02, // 1.800000
- 4.47415437123312026423960219290165696293115615844727e-02, // 1.900000
- 3.66312777774683573372982436922029592096805572509766e-02, // 2.000000
- 8.70884174942787754603035210720918257720768451690674e-03, // 2.718282
- 3.73488546341443254997227718661179096670821309089661e-03, // 3.141593
- };
-
- public static final double[] SCIPY_EXP_CDF_4 = { //
- 3.99999999920000017111637123087353531958321184447414e-10, // 0.000000
- 3.99992000106665654499821238587742300296667963266373e-05, // 0.000010
- 3.29679953964360727969307163220946677029132843017578e-01, // 0.100000
- 3.89713524444985692785081710098893381655216217041016e-01, // 0.123457
- 5.50671035882778436842954761232249438762664794921875e-01, // 0.200000
- 6.62878787194243646041513784439302980899810791015625e-01, // 0.271828
- 6.98805788087797918883836700842948630452156066894531e-01, // 0.300000
- 7.15390456663970719652922980458242818713188171386719e-01, // 0.314159
- 7.98103482005344644356625849468400701880455017089844e-01, // 0.400000
- 8.64664716763387297682186272140825167298316955566406e-01, // 0.500000
- 9.09282046710587543714154890039935708045959472656250e-01, // 0.600000
- 9.39189937374782068957301817135885357856750488281250e-01, // 0.700000
- 9.59237796021633837284525725408457219600677490234375e-01, // 0.800000
- 9.72676277552707468920800693013006821274757385253906e-01, // 0.900000
- 9.81684361111265779697987454710528254508972167968750e-01, // 1.000000
- 9.87722660096931548423526692204177379608154296875000e-01, // 1.100000
- 9.91770252950979980255397094879299402236938476562500e-01, // 1.200000
- 9.94483435579239238855109306314261630177497863769531e-01, // 1.300000
- 9.96302136283517048020996753621147945523262023925781e-01, // 1.400000
- 9.97521247823333623294672634074231609702110290527344e-01, // 1.500000
- 9.98338442726826036377474338223692029714584350585938e-01, // 1.600000
- 9.98886224852155168996148404403356835246086120605469e-01, // 1.700000
- 9.99253414191623279272391755512217059731483459472656e-01, // 1.800000
- 9.99499548566559425921695947181433439254760742187500e-01, // 1.900000
- 9.99664537372097483647337412548949941992759704589844e-01, // 2.000000
- 9.99981039018845829779991163377417251467704772949219e-01, // 2.718282
- 9.99996512657643776833538140635937452316284179687500e-01, // 3.141593
- };
-
- public static final double[] SCIPY_EXP_PDF_4 = { //
- 3.99999999839999986761540640145540237426757812500000e+00, // 0.000000
- 3.99984000319995747219081749790348112583160400390625e+00, // 0.000010
- 2.68128018414255731016737627214752137660980224609375e+00, // 0.100000
- 2.44114590222005700681506823457311838865280151367188e+00, // 0.123457
- 1.79731585646888625262818095507100224494934082031250e+00, // 0.200000
- 1.34848485122302563787854978727409616112709045410156e+00, // 0.271828
- 1.20477684764880854650925812165951356291770935058594e+00, // 0.300000
- 1.13843817334411712138830807816702872514724731445312e+00, // 0.314159
- 8.07586071978621533595799064642051234841346740722656e-01, // 0.400000
- 5.41341132946450809271254911436699330806732177734375e-01, // 0.500000
- 3.62871813157650047187985364871565252542495727539062e-01, // 0.600000
- 2.43240250500871890704246425229939632117748260498047e-01, // 0.700000
- 1.63048815913464845150926407768565695732831954956055e-01, // 0.800000
- 1.09294889789170235339099690463626757264137268066406e-01, // 0.900000
- 7.32625555549367146745964873844059184193611145019531e-02, // 1.000000
- 4.91093596122737438558480960182350827381014823913574e-02, // 1.100000
- 3.29189881960801206117750439261726569384336471557617e-02, // 1.200000
- 2.20662576830430862129261981863237451761960983276367e-02, // 1.300000
- 1.47914548659317281187330905822818749584257602691650e-02, // 1.400000
- 9.91500870666543396292347267717559589073061943054199e-03, // 1.500000
- 6.64622909269573566154454269394591392483562231063843e-03, // 1.600000
- 4.45510059137921299310391987091861665248870849609375e-03, // 1.700000
- 2.98634323350671681066015317185247113229706883430481e-03, // 1.800000
- 2.00180573376244333103080030866749439155682921409607e-03, // 1.900000
- 1.34185051161004741289428654482662750524468719959259e-03, // 2.000000
- 7.58439246168676609646114306073627631121780723333359e-05, // 2.718282
- 1.39493694248359891788707765059029952681157737970352e-05, // 3.141593
- };
-
- public static final double[] GNUR_EXP_CDF_4 = { //
- 3.99999999920000017111637123087353531958321184447414e-10, // 0.000000
- 3.99992000106665654499821238587742300296667963266373e-05, // 0.000010
- 3.29679953964360727969307163220946677029132843017578e-01, // 0.100000
- 3.89713524444985692785081710098893381655216217041016e-01, // 0.123457
- 5.50671035882778436842954761232249438762664794921875e-01, // 0.200000
- 6.62878787194372431912370302597992122173309326171875e-01, // 0.271828
- 6.98805788087797918883836700842948630452156066894531e-01, // 0.300000
- 7.15390456663994256381045033776899799704551696777344e-01, // 0.314159
- 7.98103482005344644356625849468400701880455017089844e-01, // 0.400000
- 8.64664716763387297682186272140825167298316955566406e-01, // 0.500000
- 9.09282046710587543714154890039935708045959472656250e-01, // 0.600000
- 9.39189937374782068957301817135885357856750488281250e-01, // 0.700000
- 9.59237796021633837284525725408457219600677490234375e-01, // 0.800000
- 9.72676277552707468920800693013006821274757385253906e-01, // 0.900000
- 9.81684361111265779697987454710528254508972167968750e-01, // 1.000000
- 9.87722660096931548423526692204177379608154296875000e-01, // 1.100000
- 9.91770252950979980255397094879299402236938476562500e-01, // 1.200000
- 9.94483435579239238855109306314261630177497863769531e-01, // 1.300000
- 9.96302136283517048020996753621147945523262023925781e-01, // 1.400000
- 9.97521247823333623294672634074231609702110290527344e-01, // 1.500000
- 9.98338442726826036377474338223692029714584350585938e-01, // 1.600000
- 9.98886224852155168996148404403356835246086120605469e-01, // 1.700000
- 9.99253414191623279272391755512217059731483459472656e-01, // 1.800000
- 9.99499548566559425921695947181433439254760742187500e-01, // 1.900000
- 9.99664537372097483647337412548949941992759704589844e-01, // 2.000000
- 9.99981039018845829779991163377417251467704772949219e-01, // 2.718282
- 9.99996512657643776833538140635937452316284179687500e-01, // 3.141593
- };
-
- public static final double[] GNUR_EXP_PDF_4 = { //
- 3.99999999839999986761540640145540237426757812500000e+00, // 0.000000
- 3.99984000319995747219081749790348112583160400390625e+00, // 0.000010
- 2.68128018414255731016737627214752137660980224609375e+00, // 0.100000
- 2.44114590222005700681506823457311838865280151367188e+00, // 0.123457
- 1.79731585646888625262818095507100224494934082031250e+00, // 0.200000
- 1.34848485122251049439512371463933959603309631347656e+00, // 0.271828
- 1.20477684764880854650925812165951356291770935058594e+00, // 0.300000
- 1.13843817334402297447581986489240080118179321289062e+00, // 0.314159
- 8.07586071978621533595799064642051234841346740722656e-01, // 0.400000
- 5.41341132946450809271254911436699330806732177734375e-01, // 0.500000
- 3.62871813157650047187985364871565252542495727539062e-01, // 0.600000
- 2.43240250500871890704246425229939632117748260498047e-01, // 0.700000
- 1.63048815913464845150926407768565695732831954956055e-01, // 0.800000
- 1.09294889789170235339099690463626757264137268066406e-01, // 0.900000
- 7.32625555549367146745964873844059184193611145019531e-02, // 1.000000
- 4.91093596122737438558480960182350827381014823913574e-02, // 1.100000
- 3.29189881960801206117750439261726569384336471557617e-02, // 1.200000
- 2.20662576830430862129261981863237451761960983276367e-02, // 1.300000
- 1.47914548659317281187330905822818749584257602691650e-02, // 1.400000
- 9.91500870666543396292347267717559589073061943054199e-03, // 1.500000
- 6.64622909269573566154454269394591392483562231063843e-03, // 1.600000
- 4.45510059137921299310391987091861665248870849609375e-03, // 1.700000
- 2.98634323350671681066015317185247113229706883430481e-03, // 1.800000
- 2.00180573376244333103080030866749439155682921409607e-03, // 1.900000
- 1.34185051161004741289428654482662750524468719959259e-03, // 2.000000
- 7.58439246165780028017047720290122470032656565308571e-05, // 2.718282
- 1.39493694248244424257338058836808158957865089178085e-05, // 3.141593
- };
-
- public static final double[] P_QUANT = { //
- 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99, 0.999, 0.9999 //
- };
-
- public static final double[] SCIPY_EXP_QUANT_01 = { //
- 1.00005000333358335003197669976771067013032734394073e-03, // 0.000100
- 1.00050033358353353957204134871972200926393270492554e-02, // 0.001000
- 1.00503358535014422625586405501962872222065925598145e-01, // 0.010000
- 1.05360515657826314672718126530526205897331237792969e+00, // 0.100000
- 2.87682072451780879163152349065057933330535888671875e+00, // 0.250000
- 6.93147180559945308431224475498311221599578857421875e+00, // 0.500000
- 1.38629436111989061686244895099662244319915771484375e+01, // 0.750000
- 2.30258509299404607872929773293435573577880859375000e+01, // 0.900000
- 4.60517018598809002583038818556815385818481445312500e+01, // 0.990000
- 6.90775527898213539401695015840232372283935546875000e+01, // 0.999000
- 9.21034037197629373849849798716604709625244140625000e+01, // 0.999900
- };
-
- public static final double[] GNUR_EXP_QUANT_01 = { //
- 1.00005000333358335003197669976771067013032734394073e-03, // 0.000100
- 1.00050033358353353957204134871972200926393270492554e-02, // 0.001000
- 1.00503358535014422625586405501962872222065925598145e-01, // 0.010000
- 1.05360515657826314672718126530526205897331237792969e+00, // 0.100000
- 2.87682072451780879163152349065057933330535888671875e+00, // 0.250000
- 6.93147180559945308431224475498311221599578857421875e+00, // 0.500000
- 1.38629436111989061686244895099662244319915771484375e+01, // 0.750000
- 2.30258509299404607872929773293435573577880859375000e+01, // 0.900000
- 4.60517018598809002583038818556815385818481445312500e+01, // 0.990000
- 6.90775527898213539401695015840232372283935546875000e+01, // 0.999000
- 9.21034037197629373849849798716604709625244140625000e+01, // 0.999900
- };
-
- public static final double[] SCIPY_EXP_QUANT_05 = { //
- 2.00010000666716686269427927236108644137857481837273e-04, // 0.000100
- 2.00100066716706699240790889859908929793164134025574e-03, // 0.001000
- 2.01006717070028838312278907096697366796433925628662e-02, // 0.010000
- 2.10721031315652618243206006809487007558345794677734e-01, // 0.100000
- 5.75364144903561802735225683136377483606338500976562e-01, // 0.250000
- 1.38629436111989057245352796599036082625389099121094e+00, // 0.500000
- 2.77258872223978114490705593198072165250778198242188e+00, // 0.750000
- 4.60517018598809180218722758581861853599548339843750e+00, // 0.900000
- 9.21034037197618005166077637113630771636962890625000e+00, // 0.990000
- 1.38155105579642718538480039569549262523651123046875e+01, // 0.999000
- 1.84206807439525874769969959743320941925048828125000e+01, // 0.999900
- };
-
- public static final double[] GNUR_EXP_QUANT_05 = { //
- 2.00010000666716686269427927236108644137857481837273e-04, // 0.000100
- 2.00100066716706699240790889859908929793164134025574e-03, // 0.001000
- 2.01006717070028838312278907096697366796433925628662e-02, // 0.010000
- 2.10721031315652618243206006809487007558345794677734e-01, // 0.100000
- 5.75364144903561802735225683136377483606338500976562e-01, // 0.250000
- 1.38629436111989057245352796599036082625389099121094e+00, // 0.500000
- 2.77258872223978114490705593198072165250778198242188e+00, // 0.750000
- 4.60517018598809180218722758581861853599548339843750e+00, // 0.900000
- 9.21034037197618005166077637113630771636962890625000e+00, // 0.990000
- 1.38155105579642718538480039569549262523651123046875e+01, // 0.999000
- 1.84206807439525874769969959743320941925048828125000e+01, // 0.999900
- };
-
- public static final double[] SCIPY_EXP_QUANT_1 = { //
- 1.00005000333358343134713963618054322068928740918636e-04, // 0.000100
- 1.00050033358353349620395444929954464896582067012787e-03, // 0.001000
- 1.00503358535014419156139453548348683398216962814331e-02, // 0.010000
- 1.05360515657826309121603003404743503779172897338867e-01, // 0.100000
- 2.87682072451780901367612841568188741803169250488281e-01, // 0.250000
- 6.93147180559945286226763982995180413126945495605469e-01, // 0.500000
- 1.38629436111989057245352796599036082625389099121094e+00, // 0.750000
- 2.30258509299404590109361379290930926799774169921875e+00, // 0.900000
- 4.60517018598809002583038818556815385818481445312500e+00, // 0.990000
- 6.90775527898213592692400197847746312618255615234375e+00, // 0.999000
- 9.21034037197629373849849798716604709625244140625000e+00, // 0.999900
- };
-
- public static final double[] GNUR_EXP_QUANT_1 = { //
- 1.00005000333358343134713963618054322068928740918636e-04, // 0.000100
- 1.00050033358353349620395444929954464896582067012787e-03, // 0.001000
- 1.00503358535014419156139453548348683398216962814331e-02, // 0.010000
- 1.05360515657826309121603003404743503779172897338867e-01, // 0.100000
- 2.87682072451780901367612841568188741803169250488281e-01, // 0.250000
- 6.93147180559945286226763982995180413126945495605469e-01, // 0.500000
- 1.38629436111989057245352796599036082625389099121094e+00, // 0.750000
- 2.30258509299404590109361379290930926799774169921875e+00, // 0.900000
- 4.60517018598809002583038818556815385818481445312500e+00, // 0.990000
- 6.90775527898213592692400197847746312618255615234375e+00, // 0.999000
- 9.21034037197629373849849798716604709625244140625000e+00, // 0.999900
- };
-
- public static final double[] SCIPY_EXP_QUANT_2 = { //
- 5.00025001666791715673569818090271610344643704593182e-05, // 0.000100
- 5.00250166791766748101977224649772324482910335063934e-04, // 0.001000
- 5.02516792675072095780697267741743416991084814071655e-03, // 0.010000
- 5.26802578289131545608015017023717518895864486694336e-02, // 0.100000
- 1.43841036225890450683806420784094370901584625244141e-01, // 0.250000
- 3.46573590279972643113381991497590206563472747802734e-01, // 0.500000
- 6.93147180559945286226763982995180413126945495605469e-01, // 0.750000
- 1.15129254649702295054680689645465463399887084960938e+00, // 0.900000
- 2.30258509299404501291519409278407692909240722656250e+00, // 0.990000
- 3.45387763949106796346200098923873156309127807617188e+00, // 0.999000
- 4.60517018598814686924924899358302354812622070312500e+00, // 0.999900
- };
-
- public static final double[] GNUR_EXP_QUANT_2 = { //
- 5.00025001666791715673569818090271610344643704593182e-05, // 0.000100
- 5.00250166791766748101977224649772324482910335063934e-04, // 0.001000
- 5.02516792675072095780697267741743416991084814071655e-03, // 0.010000
- 5.26802578289131545608015017023717518895864486694336e-02, // 0.100000
- 1.43841036225890450683806420784094370901584625244141e-01, // 0.250000
- 3.46573590279972643113381991497590206563472747802734e-01, // 0.500000
- 6.93147180559945286226763982995180413126945495605469e-01, // 0.750000
- 1.15129254649702295054680689645465463399887084960938e+00, // 0.900000
- 2.30258509299404501291519409278407692909240722656250e+00, // 0.990000
- 3.45387763949106796346200098923873156309127807617188e+00, // 0.999000
- 4.60517018598814686924924899358302354812622070312500e+00, // 0.999900
- };
-
- public static final double[] SCIPY_EXP_QUANT_4 = { //
- 2.50012500833395857836784909045135805172321852296591e-05, // 0.000100
- 2.50125083395883374050988612324886162241455167531967e-04, // 0.001000
- 2.51258396337536047890348633870871708495542407035828e-03, // 0.010000
- 2.63401289144565772804007508511858759447932243347168e-02, // 0.100000
- 7.19205181129452253419032103920471854507923126220703e-02, // 0.250000
- 1.73286795139986321556690995748795103281736373901367e-01, // 0.500000
- 3.46573590279972643113381991497590206563472747802734e-01, // 0.750000
- 5.75646273248511475273403448227327316999435424804688e-01, // 0.900000
- 1.15129254649702250645759704639203846454620361328125e+00, // 0.990000
- 1.72693881974553398173100049461936578154563903808594e+00, // 0.999000
- 2.30258509299407343462462449679151177406311035156250e+00, // 0.999900
- };
-
- public static final double[] GNUR_EXP_QUANT_4 = { //
- 2.50012500833395857836784909045135805172321852296591e-05, // 0.000100
- 2.50125083395883374050988612324886162241455167531967e-04, // 0.001000
- 2.51258396337536047890348633870871708495542407035828e-03, // 0.010000
- 2.63401289144565772804007508511858759447932243347168e-02, // 0.100000
- 7.19205181129452253419032103920471854507923126220703e-02, // 0.250000
- 1.73286795139986321556690995748795103281736373901367e-01, // 0.500000
- 3.46573590279972643113381991497590206563472747802734e-01, // 0.750000
- 5.75646273248511475273403448227327316999435424804688e-01, // 0.900000
- 1.15129254649702250645759704639203846454620361328125e+00, // 0.990000
- 1.72693881974553398173100049461936578154563903808594e+00, // 0.999000
- 2.30258509299407343462462449679151177406311035156250e+00, // 0.999900
- };
-
- @Test
- public void testPDF() {
- checkPDF(new ExponentialDistribution(.1), P_CDFPDF, SCIPY_EXP_PDF_01, 1e-13);
- checkPDF(new ExponentialDistribution(.5), P_CDFPDF, SCIPY_EXP_PDF_05, 1e-13);
- checkPDF(new ExponentialDistribution(1.), P_CDFPDF, SCIPY_EXP_PDF_1, 1e-13);
- checkPDF(new ExponentialDistribution(2.), P_CDFPDF, SCIPY_EXP_PDF_2, 1e-12);
- checkPDF(new ExponentialDistribution(4.), P_CDFPDF, SCIPY_EXP_PDF_4, 1e-12);
- checkPDF(new ExponentialDistribution(.1), P_CDFPDF, GNUR_EXP_PDF_01, 1e-15);
- checkPDF(new ExponentialDistribution(.5), P_CDFPDF, GNUR_EXP_PDF_05, 1e-15);
- checkPDF(new ExponentialDistribution(1.), P_CDFPDF, GNUR_EXP_PDF_1, 1e-15);
- checkPDF(new ExponentialDistribution(2.), P_CDFPDF, GNUR_EXP_PDF_2, 1e-15);
- checkPDF(new ExponentialDistribution(4.), P_CDFPDF, GNUR_EXP_PDF_4, 1e-15);
- }
-
- @Test
- public void testCDF() {
- checkCDF(new ExponentialDistribution(.1), P_CDFPDF, SCIPY_EXP_CDF_01, 1e-12);
- checkCDF(new ExponentialDistribution(.5), P_CDFPDF, SCIPY_EXP_CDF_05, 1e-12);
- checkCDF(new ExponentialDistribution(1.), P_CDFPDF, SCIPY_EXP_CDF_1, 1e-12);
- checkCDF(new ExponentialDistribution(2.), P_CDFPDF, SCIPY_EXP_CDF_2, 1e-12);
- checkCDF(new ExponentialDistribution(4.), P_CDFPDF, SCIPY_EXP_CDF_4, 1e-12);
- checkCDF(new ExponentialDistribution(.1), P_CDFPDF, GNUR_EXP_CDF_01, 1e-15);
- checkCDF(new ExponentialDistribution(.5), P_CDFPDF, GNUR_EXP_CDF_05, 1e-15);
- checkCDF(new ExponentialDistribution(1.), P_CDFPDF, GNUR_EXP_CDF_1, 1e-15);
- checkCDF(new ExponentialDistribution(2.), P_CDFPDF, GNUR_EXP_CDF_2, 1e-15);
- checkCDF(new ExponentialDistribution(4.), P_CDFPDF, GNUR_EXP_CDF_4, 1e-15);
- }
-
- @Test
- public void testProbit() {
- checkQuantile(new ExponentialDistribution(.1), P_QUANT, GNUR_EXP_QUANT_01, 1e-15);
- checkQuantile(new ExponentialDistribution(.5), P_QUANT, GNUR_EXP_QUANT_05, 1e-15);
- checkQuantile(new ExponentialDistribution(1.), P_QUANT, GNUR_EXP_QUANT_1, 1e-15);
- checkQuantile(new ExponentialDistribution(2.), P_QUANT, GNUR_EXP_QUANT_2, 1e-15);
- checkQuantile(new ExponentialDistribution(4.), P_QUANT, GNUR_EXP_QUANT_4, 1e-15);
- checkQuantile(new ExponentialDistribution(.1), P_QUANT, SCIPY_EXP_QUANT_01, 1e-15);
- checkQuantile(new ExponentialDistribution(.5), P_QUANT, SCIPY_EXP_QUANT_05, 1e-15);
- checkQuantile(new ExponentialDistribution(1.), P_QUANT, SCIPY_EXP_QUANT_1, 1e-15);
- checkQuantile(new ExponentialDistribution(2.), P_QUANT, SCIPY_EXP_QUANT_2, 1e-15);
- checkQuantile(new ExponentialDistribution(4.), P_QUANT, SCIPY_EXP_QUANT_4, 1e-15);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestExponentiallyModifiedGaussianDistribution.java b/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestExponentiallyModifiedGaussianDistribution.java
deleted file mode 100644
index b50f1b07..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestExponentiallyModifiedGaussianDistribution.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for the Normal distribution in ELKI.
- *
- * The reference values were computed using GNU R and SciPy.
- *
- * @author Erich Schubert
- */
-public class TestExponentiallyModifiedGaussianDistribution extends AbstractDistributionTest implements JUnit4Test {
- public static final double[] P_CDFPDF = { //
- 1e-10, 1e-05, 0.1, 0.1234567, 0.2, 0.2718281828459045, 0.3, 0.3141592653589793, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.718281828459045, 3.141592653589793 //
- };
-
- public static final double[] GNUR_EXGAUSS_PDF_1_3_05 = { //
- 8.47499457587128773861e-02, // 0.000000
- 8.47501509788143592150e-02, // 0.000010
- 8.67850439453969474402e-02, // 0.100000
- 8.72571793172293719287e-02, // 0.123457
- 8.87828480833198901978e-02, // 0.200000
- 9.01922765508967883008e-02, // 0.271828
- 9.07388117440050406826e-02, // 0.300000
- 9.10121196636441698313e-02, // 0.314159
- 9.26484294233294591869e-02, // 0.400000
- 9.45072549271919470915e-02, // 0.500000
- 9.63109197365605573804e-02, // 0.600000
- 9.80551512388879997761e-02, // 0.700000
- 9.97357907145074162880e-02, // 0.800000
- 1.01348810967098704183e-01, // 0.900000
- 1.02890333488697346964e-01, // 1.000000
- 1.04356645052008520369e-01, // 1.100000
- 1.05744213625967600767e-01, // 1.200000
- 1.07049703514534744198e-01, // 1.300000
- 1.08269989623592619021e-01, // 1.400000
- 1.09402170766494374887e-01, // 1.500000
- 1.10443581925230030483e-01, // 1.600000
- 1.11391805391289122618e-01, // 1.700000
- 1.12244680718037018186e-01, // 1.800000
- 1.13000313424705317589e-01, // 1.900000
- 1.13657082400870648731e-01, // 2.000000
- 1.15388290567157214550e-01, // 2.718282
- 1.13959589524871160449e-01, // 3.141593
- };
-
- public static final double[] GNUR_EXGAUSS_CDF_1_3_05 = { //
- 1.99941448676917293836e-01, // 0.000000
- 1.99942296168926059163e-01, // 0.000010
- 2.08518489920253430325e-01, // 0.100000
- 2.10559722098245583055e-01, // 0.123457
- 2.17297214297385354875e-01, // 0.200000
- 2.23725077521963966465e-01, // 0.271828
- 2.26273664808885194288e-01, // 0.300000
- 2.27560395746384258597e-01, // 0.314159
- 2.35443431714238121666e-01, // 0.400000
- 2.44801657534712419073e-01, // 0.500000
- 2.54343043903264842687e-01, // 0.600000
- 2.64061860245194957031e-01, // 0.700000
- 2.73951954270620134935e-01, // 0.800000
- 2.84006764248710408260e-01, // 0.900000
- 2.94219333022605278316e-01, // 1.000000
- 3.04582323713075031613e-01, // 1.100000
- 3.15088037048429803200e-01, // 1.200000
- 3.25728430247959499511e-01, // 1.300000
- 3.36495137376428721243e-01, // 1.400000
- 3.47379491077914881458e-01, // 1.500000
- 3.58372545588643010017e-01, // 1.600000
- 3.69465100920526368089e-01, // 1.700000
- 3.80647728099900828358e-01, // 1.800000
- 3.91910795339542039617e-01, // 1.900000
- 4.03244495016495063666e-01, // 2.000000
- 4.85820022244521587673e-01, // 2.718282
- 5.34425248272120123616e-01, // 3.141593
- };
-
- @Test
- public void testPDF() {
- checkPDF(new ExponentiallyModifiedGaussianDistribution(1., 3., .5), P_CDFPDF, GNUR_EXGAUSS_PDF_1_3_05, 1e-13);
- }
-
- @Test
- public void testCDF() {
- checkCDF(new ExponentiallyModifiedGaussianDistribution(1., 3., .5), P_CDFPDF, GNUR_EXGAUSS_CDF_1_3_05, 1e-12);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGammaDistribution.java b/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGammaDistribution.java
deleted file mode 100644
index a0895298..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGammaDistribution.java
+++ /dev/null
@@ -1,1317 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-
-import java.util.Random;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.GammaChoiWetteEstimator;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;
-
-/**
- * Unit test for the Gamma distribution in ELKI.
- *
- * The reference values were computed using GNU R and SciPy.
- *
- * @author Erich Schubert
- */
-public class TestGammaDistribution extends AbstractDistributionTest implements JUnit4Test {
- public static final double[] P_CDFPDF = { //
- 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 1e-05, 1e-10, 0.1234567, 3.14159265359, 2.71828182846, 0.314159265359, 0.271828182846 //
- };
-
- public static final double[] SCIPY_GAMMA_CDF_1_1 = { //
- 9.51625819640404407850908796717703808099031448364258e-02, // 0.100000
- 1.81269246922018151257915974383649881929159164428711e-01, // 0.200000
- 2.59181779318282068391710026844521053135395050048828e-01, // 0.300000
- 3.29679953964360561435853469447465613484382629394531e-01, // 0.400000
- 3.93469340287366520225731392201851122081279754638672e-01, // 0.500000
- 4.51188363905973610634703163668746128678321838378906e-01, // 0.600000
- 5.03414696208590473069932613725541159510612487792969e-01, // 0.700000
- 5.50671035882778325820652298716595396399497985839844e-01, // 0.800000
- 5.93430340259400890268182138242991641163825988769531e-01, // 0.900000
- 6.32120558828557776998025019565830007195472717285156e-01, // 1.000000
- 6.67128916301920504849931603530421853065490722656250e-01, // 1.100000
- 6.98805788087797807861534238327294588088989257812500e-01, // 1.200000
- 7.27468206965987351786395720409927889704704284667969e-01, // 1.300000
- 7.53403036058393538176858328370144590735435485839844e-01, // 1.400000
- 7.76869839851570209710018843907164409756660461425781e-01, // 1.500000
- 7.98103482005344533334323386952746659517288208007812e-01, // 1.600000
- 8.17316475947265308477085454796906560659408569335938e-01, // 1.700000
- 8.34701111778413440411839019361650571227073669433594e-01, // 1.800000
- 8.50431380777364909206994525447953492403030395507812e-01, // 1.900000
- 8.64664716763387297682186272140825167298316955566406e-01, // 2.000000
- 9.99995000016666799329441428501041855270159430801868e-06, // 0.000010
- 9.99999999950001362800370980511287678088594432779246e-11, // 0.000000
- 1.16140088450309555967443486679258057847619056701660e-01, // 0.123457
- 9.56786081736227700389463279861956834793090820312500e-01, // 3.141593
- 9.34011964154687457373427150741918012499809265136719e-01, // 2.718282
- 2.69597308951354475148320943844737485051155090332031e-01, // 0.314159
- 2.38014828033141445651210688083665445446968078613281e-01, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_PDF_1_1 = { //
- 9.04837418035959517581545696884859353303909301757812e-01, // 0.100000
- 8.18730753077981820986508409987436607480049133300781e-01, // 0.200000
- 7.40818220681717876097138741897651925683021545410156e-01, // 0.300000
- 6.70320046035639327541844068036880344152450561523438e-01, // 0.400000
- 6.06530659712633424263117376540321856737136840820312e-01, // 0.500000
- 5.48811636094026389365296836331253871321678161621094e-01, // 0.600000
- 4.96585303791409526930067386274458840489387512207031e-01, // 0.700000
- 4.49328964117221563157045238767750561237335205078125e-01, // 0.800000
- 4.06569659740599109731817861757008358836174011230469e-01, // 0.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 1.000000
- 3.32871083698079550661219627727405168116092681884766e-01, // 1.100000
- 3.01194211912202136627314530414878390729427337646484e-01, // 1.200000
- 2.72531793034012592702453048332245089113712310791016e-01, // 1.300000
- 2.46596963941606489578717287258768919855356216430664e-01, // 1.400000
- 2.23130160148429818045556771721749100834131240844727e-01, // 1.500000
- 2.01896517994655383398949766160512808710336685180664e-01, // 1.600000
- 1.82683524052734663767338929574179928749799728393555e-01, // 1.700000
- 1.65298888221586531832585365009435918182134628295898e-01, // 1.800000
- 1.49568619222635063037429858923132997006177902221680e-01, // 1.900000
- 1.35335283236612702317813727859174832701683044433594e-01, // 2.000000
- 9.99990000049999827602675850357627496123313903808594e-01, // 0.000010
- 9.99999999899999991725962900090962648391723632812500e-01, // 0.000000
- 8.83859911549690457910344321135198697447776794433594e-01, // 0.123457
- 4.32139182637722579771732966946728993207216262817383e-02, // 3.141593
- 6.59880358453125426265728492580819875001907348632812e-02, // 2.718282
- 7.30402691048645635873981518670916557312011718750000e-01, // 0.314159
- 7.61985171966858665371091774431988596916198730468750e-01, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_CDF_1_1 = { //
- 9.51625819640404269073030718573136255145072937011719e-02, // 0.100000
- 1.81269246922018151257915974383649881929159164428711e-01, // 0.200000
- 2.59181779318282123902861258102348074316978454589844e-01, // 0.300000
- 3.29679953964360727969307163220946677029132843017578e-01, // 0.400000
- 3.93469340287366575736882623459678143262863159179688e-01, // 0.500000
- 4.51188363905973610634703163668746128678321838378906e-01, // 0.600000
- 5.03414696208590473069932613725541159510612487792969e-01, // 0.700000
- 5.50671035882778325820652298716595396399497985839844e-01, // 0.800000
- 5.93430340259400890268182138242991641163825988769531e-01, // 0.900000
- 6.32120558828557665975722557050175964832305908203125e-01, // 1.000000
- 6.67128916301920504849931603530421853065490722656250e-01, // 1.100000
- 6.98805788087797807861534238327294588088989257812500e-01, // 1.200000
- 7.27468206965987462808698182925581932067871093750000e-01, // 1.300000
- 7.53403036058393538176858328370144590735435485839844e-01, // 1.400000
- 7.76869839851570209710018843907164409756660461425781e-01, // 1.500000
- 7.98103482005344644356625849468400701880455017089844e-01, // 1.600000
- 8.17316475947265308477085454796906560659408569335938e-01, // 1.700000
- 8.34701111778413440411839019361650571227073669433594e-01, // 1.800000
- 8.50431380777364909206994525447953492403030395507812e-01, // 1.900000
- 8.64664716763387297682186272140825167298316955566406e-01, // 2.000000
- 9.99995000016666799329441428501041855270159430801868e-06, // 0.000010
- 9.99999999950000070330663866405545691512513073462287e-11, // 0.000000
- 1.16140088450309583723019102308171568438410758972168e-01, // 0.123457
- 9.56786081736236693195962743629934266209602355957031e-01, // 3.141593
- 9.34011964154750407018923397117760032415390014648438e-01, // 2.718282
- 2.69597308951369518670304614715860225260257720947266e-01, // 0.314159
- 2.38014828033214137503748020208149682730436325073242e-01, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_PDF_1_1 = { //
- 9.04837418035959517581545696884859353303909301757812e-01, // 0.100000
- 8.18730753077981820986508409987436607480049133300781e-01, // 0.200000
- 7.40818220681717876097138741897651925683021545410156e-01, // 0.300000
- 6.70320046035639327541844068036880344152450561523438e-01, // 0.400000
- 6.06530659712633424263117376540321856737136840820312e-01, // 0.500000
- 5.48811636094026389365296836331253871321678161621094e-01, // 0.600000
- 4.96585303791409526930067386274458840489387512207031e-01, // 0.700000
- 4.49328964117221563157045238767750561237335205078125e-01, // 0.800000
- 4.06569659740599109731817861757008358836174011230469e-01, // 0.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 1.000000
- 3.32871083698079550661219627727405168116092681884766e-01, // 1.100000
- 3.01194211912202136627314530414878390729427337646484e-01, // 1.200000
- 2.72531793034012592702453048332245089113712310791016e-01, // 1.300000
- 2.46596963941606489578717287258768919855356216430664e-01, // 1.400000
- 2.23130160148429818045556771721749100834131240844727e-01, // 1.500000
- 2.01896517994655383398949766160512808710336685180664e-01, // 1.600000
- 1.82683524052734663767338929574179928749799728393555e-01, // 1.700000
- 1.65298888221586531832585365009435918182134628295898e-01, // 1.800000
- 1.49568619222635063037429858923132997006177902221680e-01, // 1.900000
- 1.35335283236612702317813727859174832701683044433594e-01, // 2.000000
- 9.99990000049999827602675850357627496123313903808594e-01, // 0.000010
- 9.99999999899999991725962900090962648391723632812500e-01, // 0.000000
- 8.83859911549690457910344321135198697447776794433594e-01, // 0.123457
- 4.32139182637633137429311602772941114380955696105957e-02, // 3.141593
- 6.59880358452495374699253716244129464030265808105469e-02, // 2.718282
- 7.30402691048630536840846616541966795921325683593750e-01, // 0.314159
- 7.61985171966785834740676364162936806678771972656250e-01, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_CDF_2_1 = { //
- 4.67884016044447376136972138738201465457677841186523e-03, // 0.100000
- 1.75230963064217717950477037902601296082139015197754e-02, // 0.200000
- 3.69363131137667791148437856918462784960865974426270e-02, // 0.300000
- 6.15519355501049983403483167876402148976922035217285e-02, // 0.400000
- 9.02040104310498636053239351895172148942947387695312e-02, // 0.500000
- 1.21901382249557641013204545288317603990435600280762e-01, // 0.600000
- 1.55804983554603787565540073956071864813566207885742e-01, // 0.700000
- 1.91207864589001103050591723331308458000421524047852e-01, // 0.800000
- 2.27517646492861713714006555164814926683902740478516e-01, // 0.900000
- 2.64241117657115276440293882842524908483028411865234e-01, // 1.000000
- 3.00970724234032926958093412395101040601730346679688e-01, // 1.100000
- 3.37372733793155299419908033087267540395259857177734e-01, // 1.200000
- 3.73176876021771020131012619458488188683986663818359e-01, // 1.300000
- 4.08167286540144502726690234339912422001361846923828e-01, // 1.400000
- 4.42174599628925357741593415994429960846900939941406e-01, // 1.500000
- 4.75069053213895919896003761095926165580749511718750e-01, // 1.600000
- 5.06754485057616443910433190467301756143569946289062e-01, // 1.700000
- 5.37163112979557655357609746715752407908439636230469e-01, // 1.800000
- 5.66251004254358369927047078817849978804588317871094e-01, // 1.900000
- 5.93994150290161671001953891391167417168617248535156e-01, // 2.000000
- 4.99996666679166626271834837367592264956162040334675e-11, // 0.000010
- 4.99999999966665360199746137423608777641557195129907e-21, // 0.000000
- 7.02166050809290703815790379849204327911138534545898e-03, // 0.123457
- 8.21025553585930989441976635134778916835784912109375e-01, // 3.141593
- 7.54637885420670229130735151557018980383872985839844e-01, // 2.718282
- 4.01345361152903382095935569395805941894650459289551e-02, // 0.314159
- 3.08857833818661116354054030352926929481327533721924e-02, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_PDF_2_1 = { //
- 9.04837418035959739626150621916167438030242919921875e-02, // 0.100000
- 1.63746150615596386401762174500618129968643188476562e-01, // 0.200000
- 2.22245466204515323971335760688816662877798080444336e-01, // 0.300000
- 2.68128018414255708812277134711621329188346862792969e-01, // 0.400000
- 3.03265329856316712131558688270160928368568420410156e-01, // 0.500000
- 3.29286981656415900232559579308144748210906982421875e-01, // 0.600000
- 3.47609712653986657748816924140555784106254577636719e-01, // 0.700000
- 3.59463171293777250525636191014200448989868164062500e-01, // 0.800000
- 3.65912693766539232065326814336003735661506652832031e-01, // 0.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 1.000000
- 3.66158192067887522380686959877493791282176971435547e-01, // 1.100000
- 3.61433054294642563952777436497854068875312805175781e-01, // 1.200000
- 3.54291330944216387166534332209266722202301025390625e-01, // 1.300000
- 3.45235749518249090961319325288059189915657043457031e-01, // 1.400000
- 3.34695240222644740946122965397080406546592712402344e-01, // 1.500000
- 3.23034428791448668949470857114647515118122100830078e-01, // 1.600000
- 3.10561990889648920077803495587431825697422027587891e-01, // 1.700000
- 2.97537998798855785054229272645898163318634033203125e-01, // 1.800000
- 2.84180376523006650302249909145757555961608886718750e-01, // 1.900000
- 2.70670566473225404635627455718349665403366088867188e-01, // 2.000000
- 9.99990000050000075939183458162418105530377943068743e-06, // 0.000010
- 9.99999999900001396698837531419091790435560440641893e-11, // 0.000000
- 1.09118427942216628112603871159080881625413894653320e-01, // 0.123457
- 1.35760528150296710947486644727177917957305908203125e-01, // 3.141593
- 1.79374078734017200487116383555985521525144577026367e-01, // 2.718282
- 2.29462772836064060610894443925644736737012863159180e-01, // 0.314159
- 2.07129044651275240340737582300789654254913330078125e-01, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_CDF_2_1 = { //
- 4.67884016044447115928450742217137303669005632400513e-03, // 0.100000
- 1.75230963064217613867068479294175631366670131683350e-02, // 0.200000
- 3.69363131137667860537376895990746561437845230102539e-02, // 0.300000
- 6.15519355501050191570300285093253478407859802246094e-02, // 0.400000
- 9.02040104310498774831117430039739701896905899047852e-02, // 0.500000
- 1.21901382249557682646567968731687869876623153686523e-01, // 0.600000
- 1.55804983554603898587842536471725907176733016967773e-01, // 0.700000
- 1.91207864589001158561742954589135479182004928588867e-01, // 0.800000
- 2.27517646492861658202855323906987905502319335937500e-01, // 0.900000
- 2.64241117657115276440293882842524908483028411865234e-01, // 1.000000
- 3.00970724234032926958093412395101040601730346679688e-01, // 1.100000
- 3.37372733793155243908756801829440519213676452636719e-01, // 1.200000
- 3.73176876021770964619861388200661167502403259277344e-01, // 1.300000
- 4.08167286540144225170934078050777316093444824218750e-01, // 1.400000
- 4.42174599628925357741593415994429960846900939941406e-01, // 1.500000
- 4.75069053213895919896003761095926165580749511718750e-01, // 1.600000
- 5.06754485057616221865828265435993671417236328125000e-01, // 1.700000
- 5.37163112979557766379912209231406450271606445312500e-01, // 1.800000
- 5.66251004254358258904744616302195936441421508789062e-01, // 1.900000
- 5.93994150290161893046558816422475501894950866699219e-01, // 2.000000
- 4.99996666679166820142290904483453562942574244232219e-11, // 0.000010
- 4.99999999966665585894661495302810307638972341801077e-21, // 0.000000
- 7.02166050809290617079616581008849607314914464950562e-03, // 0.123457
- 8.21025553585959189106802114110905677080154418945312e-01, // 3.141593
- 7.54637885420841425521132350695552304387092590332031e-01, // 2.718282
- 4.01345361152950913519177333910192828625440597534180e-02, // 0.314159
- 3.08857833818859291163949620795392547734081745147705e-02, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_PDF_2_1 = { //
- 9.04837418035959323292516387482464779168367385864258e-02, // 0.100000
- 1.63746150615596414157337790129531640559434890747070e-01, // 0.200000
- 2.22245466204515351726911376317730173468589782714844e-01, // 0.300000
- 2.68128018414255764323428365969448350369930267333984e-01, // 0.400000
- 3.03265329856316712131558688270160928368568420410156e-01, // 0.500000
- 3.29286981656415955743710810565971769392490386962891e-01, // 0.600000
- 3.47609712653986657748816924140555784106254577636719e-01, // 0.700000
- 3.59463171293777306036787422272027470171451568603516e-01, // 0.800000
- 3.65912693766539232065326814336003735661506652832031e-01, // 0.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 1.000000
- 3.66158192067887522380686959877493791282176971435547e-01, // 1.100000
- 3.61433054294642563952777436497854068875312805175781e-01, // 1.200000
- 3.54291330944216442677685563467093743383884429931641e-01, // 1.300000
- 3.45235749518249146472470556545886211097240447998047e-01, // 1.400000
- 3.34695240222644796457274196654907427728176116943359e-01, // 1.500000
- 3.23034428791448668949470857114647515118122100830078e-01, // 1.600000
- 3.10561990889648975588954726845258846879005432128906e-01, // 1.700000
- 2.97537998798855729543078041388071142137050628662109e-01, // 1.800000
- 2.84180376523006705813401140403584577143192291259766e-01, // 1.900000
- 2.70670566473225404635627455718349665403366088867188e-01, // 2.000000
- 9.99990000049999567719415105582214664536877535283566e-06, // 0.000010
- 9.99999999900002689168544645524833777011641799958852e-11, // 0.000000
- 1.09118427942216628112603871159080881625413894653320e-01, // 0.123457
- 1.35760528150277559600311860776855610311031341552734e-01, // 3.141593
- 1.79374078733908981497791046422207728028297424316406e-01, // 2.718282
- 2.29462772836074496707325920397124718874692916870117e-01, // 0.314159
- 2.07129044651328225734587817896681372076272964477539e-01, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_CDF_4_1 = { //
- 3.84683392534506373979050902756071650401281658560038e-06, // 0.100000
- 5.68402407581566679176977852083751940881484188139439e-05, // 0.200000
- 2.65811190021739791530808183495082630543038249015808e-04, // 0.300000
- 7.76251376207015455870041886754506776924245059490204e-04, // 0.400000
- 1.75162255629082394027540292569256052956916391849518e-03, // 0.500000
- 3.35806885324799794106942485427680367138236761093140e-03, // 0.600000
- 5.75345759229957919023146217796238488517701625823975e-03, // 0.700000
- 9.07985780015398494247058636119618313387036323547363e-03, // 0.800000
- 1.34587206394362543515619279332895530387759208679199e-02, // 0.900000
- 1.89881568761538083167650370342016685754060745239258e-02, // 1.000000
- 2.57418165296708391365232415637365193106234073638916e-02, // 1.100000
- 3.37689681856556886407894069179747020825743675231934e-02, // 1.200000
- 4.30954526920760624952855266656115418300032615661621e-02, // 1.300000
- 5.37252503680754125992002911971212597563862800598145e-02, // 1.400000
- 6.56424543784500796883563111805415246635675430297852e-02, // 1.500000
- 7.88134872297189398304695373553840909153223037719727e-02, // 1.600000
- 9.31894338562339608067475182906491681933403015136719e-02, // 1.700000
- 1.08708394709205430350706933495530392974615097045898e-01, // 1.800000
- 1.25297786682826373105825723541784100234508514404297e-01, // 1.900000
- 1.42876539501452959335381365235662087798118591308594e-01, // 2.000000
- 4.16663333347220766666711883927879838582564067271435e-22, // 0.000010
- 4.16666666633332144820066532191263979309384757370912e-42, // 0.000000
- 8.77087751463964086925343549561162603822594974189997e-06, // 0.123457
- 3.84456296955979215379528568519162945449352264404297e-01, // 3.141593
- 2.89942380984430481127844814182026311755180358886719e-01, // 2.718282
- 3.16096723469245968057839135667563823517411947250366e-04, // 0.314159
- 1.83213919706970028346976198108109201712068170309067e-04, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_PDF_4_1 = { //
- 1.50806236339326763494506078444601371302269399166107e-04, // 0.100000
- 1.09164100410397580526167260472902853507548570632935e-03, // 0.200000
- 3.33368199306773070958453963896772620500996708869934e-03, // 0.300000
- 7.15008049104682522761899932106643973384052515029907e-03, // 0.400000
- 1.26360554106798653184462466469994978979229927062988e-02, // 0.500000
- 1.97572188993849519322854035863201715983450412750244e-02, // 0.600000
- 2.83881265334089138985262934511411003768444061279297e-02, // 0.700000
- 3.83427382713362394084377626768400659784674644470215e-02, // 0.800000
- 4.93982136584827924430385337473126128315925598144531e-02, // 0.900000
- 6.13132401952403913170108751273801317438483238220215e-02, // 1.000000
- 7.38419020670239845127724720441619865596294403076172e-02, // 1.100000
- 8.67439330307142181242241463223763275891542434692383e-02, // 1.200000
- 9.97920582159542851607980651351681444793939590454102e-02, // 1.300000
- 1.12777011509294713964557388408138649538159370422363e-01, // 1.400000
- 1.25510715083491819488159535467275418341159820556641e-01, // 1.500000
- 1.37828022951018119846011700246890541166067123413086e-01, // 1.600000
- 1.49587358945180909364225385616009589284658432006836e-01, // 1.700000
- 1.60670519351382129480398930354567710310220718383789e-01, // 1.800000
- 1.70981859874675595767357094700855668634176254272461e-01, // 1.900000
- 1.80447044315483556831125611097377259284257888793945e-01, // 2.000000
- 1.66665000008333050761503298375805932114390142846638e-16, // 0.000010
- 1.66666666650000169406744350520921226284591055366191e-31, // 0.000000
- 2.77189119111339720303438527437833727162797003984451e-04, // 0.123457
- 2.23317117687730742892071589267288800328969955444336e-01, // 3.141593
- 2.20900855076609420324373900257342029362916946411133e-01, // 2.718282
- 3.77451132111497611454353773297043517231941223144531e-03, // 0.314159
- 2.55081355107697037992720012766767467837780714035034e-03, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_CDF_4_1 = { //
- 3.84683392534506289275756177326037743569031590595841e-06, // 0.100000
- 5.68402407581567289040699875179996070073684677481651e-05, // 0.200000
- 2.65811190021739466270156437843752428307197988033295e-04, // 0.300000
- 7.76251376207014588508303898350959570962004363536835e-04, // 0.400000
- 1.75162255629082459079670641699522093404084444046021e-03, // 0.500000
- 3.35806885324799880843116284268035087734460830688477e-03, // 0.600000
- 5.75345759229958439440189010838366812095046043395996e-03, // 0.700000
- 9.07985780015399361608796624523165519349277019500732e-03, // 0.800000
- 1.34587206394362543515619279332895530387759208679199e-02, // 0.900000
- 1.89881568761538083167650370342016685754060745239258e-02, // 1.000000
- 2.57418165296708252587354337492797640152275562286377e-02, // 1.100000
- 3.37689681856556678241076951962895691394805908203125e-02, // 1.200000
- 4.30954526920761110675428540162101853638887405395508e-02, // 1.300000
- 5.37252503680754125992002911971212597563862800598145e-02, // 1.400000
- 6.56424543784501351995075424383685458451509475708008e-02, // 1.500000
- 7.88134872297189398304695373553840909153223037719727e-02, // 1.600000
- 9.31894338562340163178987495484761893749237060546875e-02, // 1.700000
- 1.08708394709205402595131317866616882383823394775391e-01, // 1.800000
- 1.25297786682826484128128186057438142597675323486328e-01, // 1.900000
- 1.42876539501453014846532596493489108979701995849609e-01, // 2.000000
- 4.16663333347220531567841719470378244835256622822300e-22, // 0.000010
- 4.16666666633328958636244267286709921548589221947301e-42, // 0.000000
- 8.77087751463965272771469705581637299474095925688744e-06, // 0.123457
- 3.84456296956025345146201743773417547345161437988281e-01, // 3.141593
- 2.89942380984641312480221131409052759408950805664062e-01, // 2.718282
- 3.16096723469323813773823594885925558628514409065247e-04, // 0.314159
- 1.83213919707213540154916442403987275611143559217453e-04, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_PDF_4_1 = { //
- 1.50806236339326655074288829894157970556989312171936e-04, // 0.100000
- 1.09164100410397688946384509023346254252828657627106e-03, // 0.200000
- 3.33368199306772810749932567375708458712324500083923e-03, // 0.300000
- 7.15008049104682436025726133266289252787828445434570e-03, // 0.400000
- 1.26360554106798635837227706701924034859985113143921e-02, // 0.500000
- 1.97572188993849727489671153080053045414388179779053e-02, // 0.600000
- 2.83881265334089312457610532192120444960892200469971e-02, // 0.700000
- 3.83427382713362532862255704912968212738633155822754e-02, // 0.800000
- 4.93982136584827855041446298400842351838946342468262e-02, // 0.900000
- 6.13132401952403913170108751273801317438483238220215e-02, // 1.000000
- 7.38419020670239845127724720441619865596294403076172e-02, // 1.100000
- 8.67439330307141764908607228790060617029666900634766e-02, // 1.200000
- 9.97920582159543684275249120219086762517690658569336e-02, // 1.300000
- 1.12777011509294713964557388408138649538159370422363e-01, // 1.400000
- 1.25510715083491819488159535467275418341159820556641e-01, // 1.500000
- 1.37828022951018064334860468989063519984483718872070e-01, // 1.600000
- 1.49587358945180937119801001244923099875450134277344e-01, // 1.700000
- 1.60670519351382129480398930354567710310220718383789e-01, // 1.800000
- 1.70981859874675679034083941587596200406551361083984e-01, // 1.900000
- 1.80447044315483640097852457984117791056632995605469e-01, // 2.000000
- 1.66665000008333075413406586532424851230907807933708e-16, // 0.000010
- 1.66666666649999030851742086607051100754304632309334e-31, // 0.000000
- 2.77189119111339503463004030336946925672236829996109e-04, // 0.123457
- 2.23317117687728605712749185840948484838008880615234e-01, // 3.141593
- 2.20900855076631263962383400212274864315986633300781e-01, // 2.718282
- 3.77451132111564354940091980950001016026362776756287e-03, // 0.314159
- 2.55081355107941764107093440827611630083993077278137e-03, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_CDF_4_10 = { //
- 1.89881568761538083167650370342016685754060745239258e-02, // 0.100000
- 1.42876539501452959335381365235662087798118591308594e-01, // 0.200000
- 3.52768111217768576270970015684724785387516021728516e-01, // 0.300000
- 5.66529879633290933682587819930631667375564575195312e-01, // 0.400000
- 7.34974084702638363886251227086177095770835876464844e-01, // 0.500000
- 8.48796117223352020175752841169014573097229003906250e-01, // 0.600000
- 9.18234583755278332972693533520214259624481201171875e-01, // 0.700000
- 9.57619888008315989225138764595612883567810058593750e-01, // 0.800000
- 9.78773513697091090968172011343995109200477600097656e-01, // 0.900000
- 9.89663949324074310176513336045900359749794006347656e-01, // 1.000000
- 9.95084132734071036274769994633970782160758972167969e-01, // 1.100000
- 9.97708208792208561810355149646056815981864929199219e-01, // 1.200000
- 9.98949700268889517751347284502116963267326354980469e-01, // 1.300000
- 9.99525751453871236229531405115267261862754821777344e-01, // 1.400000
- 9.99788621496533247423599277681205421686172485351562e-01, // 1.500000
- 9.99906858387057395631813960790168493986129760742188e-01, // 1.600000
- 9.99959373411186347446744093758752569556236267089844e-01, // 1.700000
- 9.99982439833354330716019831015728414058685302734375e-01, // 1.800000
- 9.99992471709186814265990506100933998823165893554688e-01, // 1.900000
- 9.99996796280219535368871675018453970551490783691406e-01, // 2.000000
- 4.16633334722182824321055502020601847065999725794631e-18, // 0.000010
- 4.16666666333333208899682539512773183295181978120839e-38, // 0.000000
- 3.68452685531321239009727719349029939621686935424805e-02, // 0.123457
- 9.99999999870692435344210480252513661980628967285156e-01, // 3.141593
- 9.99999994136864356342186965775908902287483215332031e-01, // 2.718282
- 3.84456296955979215379528568519162945449352264404297e-01, // 0.314159
- 2.89942380984430259083239889150718227028846740722656e-01, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_PDF_4_10 = { //
- 6.13132401952403927047896559088258072733879089355469e-01, // 0.100000
- 1.80447044315483551280010487971594557166099548339844e+00, // 0.200000
- 2.24041807655387747999498060380574315786361694335938e+00, // 0.300000
- 1.95366814813164535458156478853197768330574035644531e+00, // 0.400000
- 1.40373895814280502669646466529229655861854553222656e+00, // 0.500000
- 8.92350783599890173825031070009572431445121765136719e-01, // 0.600000
- 5.21292523641998628569638185581425204873085021972656e-01, // 0.700000
- 2.86261442476809790935732280559022910892963409423828e-01, // 0.800000
- 1.49942911965315728295422559313010424375534057617188e-01, // 0.900000
- 7.56665496041414309402739490906242281198501586914062e-02, // 1.000000
- 3.70499395863616506896498492551472736522555351257324e-02, // 1.100000
- 1.76953315775852937363765704503748565912246704101562e-02, // 1.200000
- 8.27657284522896781464584847753940266557037830352783e-03, // 1.300000
- 3.80285800870032181936197801519483618903905153274536e-03, // 1.400000
- 1.72070055282277012062563947836224542697891592979431e-03, // 1.500000
- 7.68240126083475261160871117027681975741870701313019e-04, // 1.600000
- 3.38991900206525934025059143550606677308678627014160e-04, // 1.700000
- 1.48035403118606612247326603792885180155280977487564e-04, // 1.800000
- 6.40493012751137394053535523141817975556477904319763e-05, // 1.900000
- 2.74820482991807852311567234027123163286887574940920e-05, // 2.000000
- 1.66650000833305830210934716499431774874677436582004e-12, // 0.000010
- 1.66666666500001019823879501718183287893096342876298e-27, // 0.000000
- 9.12487883209794348182697376614669337868690490722656e-01, // 0.123457
- 1.17363980155635999975867359517269286617313639453641e-09, // 3.141593
- 5.24063860510259035108958120419836435033289490093011e-08, // 2.718282
- 2.23317117687730748443186712393071502447128295898438e+00, // 0.314159
- 2.20900855076609303750956314615905284881591796875000e+00, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_CDF_4_10 = { //
- 1.89881568761538083167650370342016685754060745239258e-02, // 0.100000
- 1.42876539501453014846532596493489108979701995849609e-01, // 0.200000
- 3.52768111217768742804423709458205848932266235351562e-01, // 0.300000
- 5.66529879633290933682587819930631667375564575195312e-01, // 0.400000
- 7.34974084702638252863948764570523053407669067382812e-01, // 0.500000
- 8.48796117223352020175752841169014573097229003906250e-01, // 0.600000
- 9.18234583755278332972693533520214259624481201171875e-01, // 0.700000
- 9.57619888008315989225138764595612883567810058593750e-01, // 0.800000
- 9.78773513697091090968172011343995109200477600097656e-01, // 0.900000
- 9.89663949324074310176513336045900359749794006347656e-01, // 1.000000
- 9.95084132734071036274769994633970782160758972167969e-01, // 1.100000
- 9.97708208792208561810355149646056815981864929199219e-01, // 1.200000
- 9.98949700268889517751347284502116963267326354980469e-01, // 1.300000
- 9.99525751453871236229531405115267261862754821777344e-01, // 1.400000
- 9.99788621496533247423599277681205421686172485351562e-01, // 1.500000
- 9.99906858387057395631813960790168493986129760742188e-01, // 1.600000
- 9.99959373411186347446744093758752569556236267089844e-01, // 1.700000
- 9.99982439833354330716019831015728414058685302734375e-01, // 1.800000
- 9.99992471709186814265990506100933998823165893554688e-01, // 1.900000
- 9.99996796280219535368871675018453970551490783691406e-01, // 2.000000
- 4.16633334722182670246659951041733602587764319000446e-18, // 0.000010
- 4.16666666333330128955973644209196576036362409030393e-38, // 0.000000
- 3.68452685531321239009727719349029939621686935424805e-02, // 0.123457
- 9.99999999870692435344210480252513661980628967285156e-01, // 3.141593
- 9.99999994136864356342186965775908902287483215332031e-01, // 2.718282
- 3.84456296956025345146201743773417547345161437988281e-01, // 0.314159
- 2.89942380984641312480221131409052759408950805664062e-01, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_PDF_4_10 = { //
- 6.13132401952403927047896559088258072733879089355469e-01, // 0.100000
- 1.80447044315483640097852457984117791056632995605469e+00, // 0.200000
- 2.24041807655387747999498060380574315786361694335938e+00, // 0.300000
- 1.95366814813164602071537956362590193748474121093750e+00, // 0.400000
- 1.40373895814280613691948929044883698225021362304688e+00, // 0.500000
- 8.92350783599889285646611369884340092539787292480469e-01, // 0.600000
- 5.21292523641998628569638185581425204873085021972656e-01, // 0.700000
- 2.86261442476810124002639668105985037982463836669922e-01, // 0.800000
- 1.49942911965315672784271328055183403193950653076172e-01, // 0.900000
- 7.56665496041414725736373725339944940060377120971680e-02, // 1.000000
- 3.70499395863616229340742336262337630614638328552246e-02, // 1.100000
- 1.76953315775852486335661950533904018811881542205811e-02, // 1.200000
- 8.27657284522894699796413675585426972247660160064697e-03, // 1.300000
- 3.80285800870031921727676404998419457115232944488525e-03, // 1.400000
- 1.72070055282276881958303249575692461803555488586426e-03, // 1.500000
- 7.68240126083476779043912596733889586175791919231415e-04, // 1.600000
- 3.38991900206525934025059143550606677308678627014160e-04, // 1.700000
- 1.48035403118606883297869725168993682018481194972992e-04, // 1.800000
- 6.40493012751137529578807083829872226488078013062477e-05, // 1.900000
- 2.74820482991807886192885124199136726019787602126598e-05, // 2.000000
- 1.66650000833305870600613063815236211955179979060659e-12, // 0.000010
- 1.66666666499998652189994178507260255159592416234002e-27, // 0.000000
- 9.12487883209794348182697376614669337868690490722656e-01, // 0.123457
- 1.17363980155416280125657961541131568683482555570663e-09, // 3.141593
- 5.24063860505807479924442746684748462016045778000262e-08, // 2.718282
- 2.23317117687728572406058447086252272129058837890625e+00, // 0.314159
- 2.20900855076631241757922907709144055843353271484375e+00, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_CDF_01_10 = { //
- 9.75872656273672145488262685830704867839813232421875e-01, // 0.100000
- 9.94326176020188468029914474755059927701950073242188e-01, // 0.200000
- 9.98434728252885594912413580459542572498321533203125e-01, // 0.300000
- 9.99535388712767813856885368295479565858840942382812e-01, // 0.400000
- 9.99856061034153253963552288041682913899421691894531e-01, // 0.500000
- 9.99954127338806841862606233917176723480224609375000e-01, // 0.600000
- 9.99985082831851612716889121657004579901695251464844e-01, // 0.700000
- 9.99995075192051996459952079021604731678962707519531e-01, // 0.800000
- 9.99998354830390345782120675721671432256698608398438e-01, // 0.900000
- 9.99999445201428249774266987515147775411605834960938e-01, // 1.000000
- 9.99999811450770770271390119887655600905418395996094e-01, // 1.100000
- 9.99999935505229697874085559305967763066291809082031e-01, // 1.200000
- 9.99999977817657148548846635094378143548965454101562e-01, // 1.300000
- 9.99999992334555942719021004450041800737380981445312e-01, // 1.400000
- 9.99999997340225710296124361775582656264305114746094e-01, // 1.500000
- 9.99999999073787781966871079930569976568222045898438e-01, // 1.600000
- 9.99999999676440931573040415969444438815116882324219e-01, // 1.700000
- 9.99999999886649670877147855208022519946098327636719e-01, // 1.800000
- 9.99999999960190066872200986836105585098266601562500e-01, // 1.900000
- 9.99999999985986431916273886599810793995857238769531e-01, // 2.000000
- 4.18461375237962951434411706941318698227405548095703e-01, // 0.000010
- 1.32330308815105796016453609809104818850755691528320e-01, // 0.000000
- 9.83240178351675986334612389327958226203918457031250e-01, // 0.123457
- 9.99999999999999888977697537484345957636833190917969e-01, // 3.141593
- 9.99999999999991784349617773841600865125656127929688e-01, // 2.718282
- 9.98686603432971331528733571758493781089782714843750e-01, // 0.314159
- 9.97771302397556292262947863491717725992202758789062e-01, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_PDF_01_10 = { //
- 3.86691694403023700221666558718425221741199493408203e-01, // 0.100000
- 7.62330623530854123437450198252918198704719543457031e-02, // 0.200000
- 1.94700358454044236689028934961243066936731338500977e-02, // 0.300000
- 5.52875577773295160538546966222384071443229913711548e-03, // 0.400000
- 1.66384900992015260373646512448431167285889387130737e-03, // 0.500000
- 5.19465021361826249403359501144450405263341963291168e-04, // 0.600000
- 1.66344986720691771688723781252861044777091592550278e-04, // 0.700000
- 5.42653342633515591237128306012493794696638360619545e-05, // 0.800000
- 1.79552199849926109312056587974382182437693700194359e-05, // 0.900000
- 6.00778672619989704319900733486825572526868199929595e-06, // 1.000000
- 2.02846074898835833691911056941847846246673725545406e-06, // 1.100000
- 6.90021180431038364101552478463430517763299576472491e-07, // 1.200000
- 2.36201169837157485606116071215343499289929241058417e-07, // 1.300000
- 8.12870470963516557411429738419506030311367794638500e-08, // 1.400000
- 2.81034711509505172708305416806248699934656087862095e-08, // 1.500000
- 9.75527757384449392403810659207472055776122488168767e-09, // 1.600000
- 3.39820132151311703127167328079318020517263221336179e-09, // 1.700000
- 1.18744471030516355255038446822732009500178662619874e-09, // 1.800000
- 4.16088707178314669861834363610679499156930205572280e-10, // 1.900000
- 1.46164764735815876829497270010841617621233368140565e-10, // 2.000000
- 4.18423334941553275712067261338233947753906250000000e+03, // 0.000010
- 1.32330308694805443286895751953125000000000000000000e+08, // 0.000000
- 2.53005809030332373676941415396868251264095306396484e-01, // 0.123457
- 1.07265707643817319806681139845227667938280975701293e-15, // 3.141593
- 8.42260257482259737446868026839438676448175435940158e-14, // 2.718282
- 1.62124289852739640604983861749133211560547351837158e-02, // 0.314159
- 2.82006743783194402386271804061834700405597686767578e-02, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_CDF_01_10 = { //
- 9.75872656273672256510565148346358910202980041503906e-01, // 0.100000
- 9.94326176020188468029914474755059927701950073242188e-01, // 0.200000
- 9.98434728252885594912413580459542572498321533203125e-01, // 0.300000
- 9.99535388712767813856885368295479565858840942382812e-01, // 0.400000
- 9.99856061034153253963552288041682913899421691894531e-01, // 0.500000
- 9.99954127338806841862606233917176723480224609375000e-01, // 0.600000
- 9.99985082831851612716889121657004579901695251464844e-01, // 0.700000
- 9.99995075192051996459952079021604731678962707519531e-01, // 0.800000
- 9.99998354830390345782120675721671432256698608398438e-01, // 0.900000
- 9.99999445201428249774266987515147775411605834960938e-01, // 1.000000
- 9.99999811450770770271390119887655600905418395996094e-01, // 1.100000
- 9.99999935505229697874085559305967763066291809082031e-01, // 1.200000
- 9.99999977817657148548846635094378143548965454101562e-01, // 1.300000
- 9.99999992334555942719021004450041800737380981445312e-01, // 1.400000
- 9.99999997340225710296124361775582656264305114746094e-01, // 1.500000
- 9.99999999073787781966871079930569976568222045898438e-01, // 1.600000
- 9.99999999676440931573040415969444438815116882324219e-01, // 1.700000
- 9.99999999886649670877147855208022519946098327636719e-01, // 1.800000
- 9.99999999960190066872200986836105585098266601562500e-01, // 1.900000
- 9.99999999985986431916273886599810793995857238769531e-01, // 2.000000
- 4.18461375237963006945562938199145719408988952636719e-01, // 0.000010
- 1.32330308815105768260877994180191308259963989257812e-01, // 0.000000
- 9.83240178351675764290007464296650141477584838867188e-01, // 0.123457
- 9.99999999999999888977697537484345957636833190917969e-01, // 3.141593
- 9.99999999999991784349617773841600865125656127929688e-01, // 2.718282
- 9.98686603432971664595640959305455908179283142089844e-01, // 0.314159
- 9.97771302397558956798206963867414742708206176757812e-01, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_PDF_01_10 = { //
- 3.86691694403023811243969021234079264104366302490234e-01, // 0.100000
- 7.62330623530854400993206354542053304612636566162109e-02, // 0.200000
- 1.94700358454044201994559415425101178698241710662842e-02, // 0.300000
- 5.52875577773295420747068362743448233231902122497559e-03, // 0.400000
- 1.66384900992015282057689962158519847434945404529572e-03, // 0.500000
- 5.19465021361826032562925004043563603772781789302826e-04, // 0.600000
- 1.66344986720691988529158278353747846267651766538620e-04, // 0.700000
- 5.42653342633515862287671427388602296559838578104973e-05, // 0.800000
- 1.79552199849926244837328148662436433369293808937073e-05, // 0.900000
- 6.00778672619989450210016557196723852030117996037006e-06, // 1.000000
- 2.02846074898835876043558419656864799662798759527504e-06, // 1.100000
- 6.90021180431039528771854953126396736706738010980189e-07, // 1.200000
- 2.36201169837157459136336469518457903404851094819605e-07, // 1.300000
- 8.12870470963517086807021772357217948012930719414726e-08, // 1.400000
- 2.81034711509505834452795459228388597061609743832378e-08, // 1.500000
- 9.75527757384449888712178191024076978621337730146479e-09, // 1.600000
- 3.39820132151312695743902391712527866207693705291604e-09, // 1.700000
- 1.18744471030516479332130329776883240211482473114302e-09, // 1.800000
- 4.16088707178313997777586664275693666137367898727462e-10, // 1.900000
- 1.46164764735815825130708985446611938158190113767887e-10, // 2.000000
- 4.18423334941553457611007615923881530761718750000000e+03, // 0.000010
- 1.32330308694805443286895751953125000000000000000000e+08, // 0.000000
- 2.53005809030332484699243877912522293627262115478516e-01, // 0.123457
- 1.07265707643589812321615400040546925420053420152655e-15, // 3.141593
- 8.42260257473954736054446049913952863989448707759955e-14, // 2.718282
- 1.62124289852696411295962519716340466402471065521240e-02, // 0.314159
- 2.82006743782835765654848358963135979138314723968506e-02, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_CDF_01_20 = { //
- 9.94326176020188468029914474755059927701950073242188e-01, // 0.100000
- 9.99535388712767813856885368295479565858840942382812e-01, // 0.200000
- 9.99954127338806841862606233917176723480224609375000e-01, // 0.300000
- 9.99995075192051996459952079021604731678962707519531e-01, // 0.400000
- 9.99999445201428249774266987515147775411605834960938e-01, // 0.500000
- 9.99999935505229697874085559305967763066291809082031e-01, // 0.600000
- 9.99999992334555942719021004450041800737380981445312e-01, // 0.700000
- 9.99999999073787781966871079930569976568222045898438e-01, // 0.800000
- 9.99999999886649670877147855208022519946098327636719e-01, // 0.900000
- 9.99999999985986431916273886599810793995857238769531e-01, // 1.000000
- 9.99999999998253064070752316183643415570259094238281e-01, // 1.100000
- 9.99999999999780730952636531583266332745552062988281e-01, // 1.200000
- 9.99999999999972355446686833602143451571464538574219e-01, // 1.300000
- 9.99999999999996447286321199499070644378662109375000e-01, // 1.400000
- 9.99999999999999555910790149937383830547332763671875e-01, // 1.500000
- 9.99999999999999888977697537484345957636833190917969e-01, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 4.48491720125246684514053185921511612832546234130859e-01, // 0.000010
- 1.41828113264369309876045122109644580632448196411133e-01, // 0.000000
- 9.96936964362935218453287689044373109936714172363281e-01, // 0.123457
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 9.99966686426665196663066126347985118627548217773438e-01, // 0.314159
- 9.99912881838271760948089195153443142771720886230469e-01, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_PDF_01_20 = { //
- 1.52466124706170824687490039650583639740943908691406e-01, // 0.100000
- 1.10575115554659032107709393244476814288645982742310e-02, // 0.200000
- 1.03893004272365249880671900228890081052668392658234e-03, // 0.300000
- 1.08530668526703118247425661202498758939327672123909e-04, // 0.400000
- 1.20155734523997940863980146697365114505373639985919e-05, // 0.500000
- 1.38004236086207672820310495692686103552659915294498e-06, // 0.600000
- 1.62574094192703311482285947683901206062273558927700e-07, // 0.700000
- 1.95105551476889878480762131841494411155224497633753e-08, // 0.800000
- 2.37488942061032710510076893645464019000357325239747e-09, // 0.900000
- 2.92329529471631753658994540021683235242466736281131e-10, // 1.000000
- 3.63103392931038151766683113755789609131130468711035e-11, // 1.100000
- 4.54393006390842164952338174282894757080586423114710e-12, // 1.200000
- 5.72211759915234715705708461587397688436276710355344e-13, // 1.300000
- 7.24438629339447104119041928796962738566333345202608e-14, // 1.400000
- 9.21394754227480053810143174892231491926485650173495e-15, // 1.500000
- 1.17660562505859836487690040130500292983677893422084e-15, // 1.600000
- 1.50780754320226546403459477832592082942578975198605e-16, // 1.700000
- 1.93827646502898085931666826628168232690749572821615e-17, // 1.800000
- 2.49858295196862659910572709810793896012441320426695e-18, // 1.900000
- 3.22891084281901708463501316045877085134772951439524e-19, // 2.000000
- 4.48410183235842850990593433380126953125000000000000e+03, // 0.000010
- 1.41828113006499916315078735351562500000000000000000e+08, // 0.000000
- 7.88983383252931935736285140592372044920921325683594e-02, // 0.123457
- 2.61096087098872756423344011324704568131684902965870e-29, // 3.141593
- 1.41319250269510810248688074925111402327654344402472e-25, // 2.718282
- 7.50887254129001474947657790437460789689794182777405e-04, // 0.314159
- 1.99447085860641592364173035889507445972412824630737e-03, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_CDF_01_20 = { //
- 9.94326176020188468029914474755059927701950073242188e-01, // 0.100000
- 9.99535388712767813856885368295479565858840942382812e-01, // 0.200000
- 9.99954127338806841862606233917176723480224609375000e-01, // 0.300000
- 9.99995075192051996459952079021604731678962707519531e-01, // 0.400000
- 9.99999445201428249774266987515147775411605834960938e-01, // 0.500000
- 9.99999935505229697874085559305967763066291809082031e-01, // 0.600000
- 9.99999992334555942719021004450041800737380981445312e-01, // 0.700000
- 9.99999999073787781966871079930569976568222045898438e-01, // 0.800000
- 9.99999999886649670877147855208022519946098327636719e-01, // 0.900000
- 9.99999999985986431916273886599810793995857238769531e-01, // 1.000000
- 9.99999999998253064070752316183643415570259094238281e-01, // 1.100000
- 9.99999999999780730952636531583266332745552062988281e-01, // 1.200000
- 9.99999999999972355446686833602143451571464538574219e-01, // 1.300000
- 9.99999999999996447286321199499070644378662109375000e-01, // 1.400000
- 9.99999999999999555910790149937383830547332763671875e-01, // 1.500000
- 9.99999999999999888977697537484345957636833190917969e-01, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 4.48491720125246851047506879694992676377296447753906e-01, // 0.000010
- 1.41828113264369393142771968996385112404823303222656e-01, // 0.000000
- 9.96936964362935329475590151560027152299880981445312e-01, // 0.123457
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 9.99966686426665196663066126347985118627548217773438e-01, // 0.314159
- 9.99912881838271982992694120184751227498054504394531e-01, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_PDF_01_20 = { //
- 1.52466124706170880198641270908410660922527313232422e-01, // 0.100000
- 1.10575115554659084149413672548689646646380424499512e-02, // 0.200000
- 1.03893004272365206512585000808712720754556357860565e-03, // 0.300000
- 1.08530668526703172457534285477720459311967715620995e-04, // 0.400000
- 1.20155734523997890042003311439344770406023599207401e-05, // 0.500000
- 1.38004236086207905754370990625279347341347602196038e-06, // 0.600000
- 1.62574094192703417361404354471443589602586143882945e-07, // 0.700000
- 1.95105551476889977742435638204815395724267546029296e-08, // 0.800000
- 2.37488942061032958664260659553766480422964946228603e-09, // 0.900000
- 2.92329529471631650261417970893223876316380227535774e-10, // 1.000000
- 3.63103392931038281013653825166363807788738604642731e-11, // 1.100000
- 4.54393006390842084172981479651285882919581338157400e-12, // 1.200000
- 5.72211759915235624473471276192997522747583916125080e-13, // 1.300000
- 7.24438629339446220594828081263740677430340228482031e-14, // 1.400000
- 9.21394754227482262620677793725286644766468441974938e-15, // 1.500000
- 1.17660562505860112589006867484632187088675742397265e-15, // 1.600000
- 1.50780754320227852954333750133394796118015224813298e-16, // 1.700000
- 1.93827646502899996454171658766134464220868617069515e-17, // 1.800000
- 2.49858295196864470284720433812495768631707350258375e-18, // 1.900000
- 3.22891084281903345503954045196352182716024148627745e-19, // 2.000000
- 4.48410183235842760041123256087303161621093750000000e+03, // 0.000010
- 1.41828113006500124931335449218750000000000000000000e+08, // 0.000000
- 7.88983383252932352069919375026074703782796859741211e-02, // 0.123457
- 2.61096087097776828920364858389876537699185525357919e-29, // 3.141593
- 1.41319250266768533456788338854519414081259096541228e-25, // 2.718282
- 7.50887254128645965055299793533549745916388928890228e-04, // 0.314159
- 1.99447085860197633258583671533870074199512600898743e-03, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_CDF_01_4 = { //
- 9.27573833553704485410662528011016547679901123046875e-01, // 0.100000
- 9.66394653856728291785316287132445722818374633789062e-01, // 0.200000
- 9.82338840734720442071647994453087449073791503906250e-01, // 0.300000
- 9.90161634314574046200618795410264283418655395507812e-01, // 0.400000
- 9.94326176020188468029914474755059927701950073242188e-01, // 0.500000
- 9.96650923670122979025620679749408736824989318847656e-01, // 0.600000
- 9.97989690314743826959897887718398123979568481445312e-01, // 0.700000
- 9.98777830395332189006296630395809188485145568847656e-01, // 0.800000
- 9.99249499182313538625521687208674848079681396484375e-01, // 0.900000
- 9.99535388712767813856885368295479565858840942382812e-01, // 1.000000
- 9.99710441300151630983350514725316315889358520507812e-01, // 1.100000
- 9.99818519608100975126774301315890625119209289550781e-01, // 1.200000
- 9.99885709402319799998792859696550294756889343261719e-01, // 1.300000
- 9.99927723862083506212172778759850189089775085449219e-01, // 1.400000
- 9.99954127338806841862606233917176723480224609375000e-01, // 1.500000
- 9.99970792125264407168572233786107972264289855957031e-01, // 1.600000
- 9.99981350059541806984952927450649440288543701171875e-01, // 1.700000
- 9.99988061331210875692931949743069708347320556640625e-01, // 1.800000
- 9.99992340071521379485375291551463305950164794921875e-01, // 1.900000
- 9.99995075192051996459952079021604731678962707519531e-01, // 2.000000
- 3.81824459744078470446737583188223652541637420654297e-01, // 0.000010
- 1.20743934975320044156177345939795486629009246826172e-01, // 0.000000
- 9.40661616417386547972512289561564102768898010253906e-01, // 0.123457
- 9.99999964784593187161476635083090513944625854492188e-01, // 3.141593
- 9.99999783864769620223000856640283018350601196289062e-01, // 2.718282
- 9.83788069985481405943517074774717912077903747558594e-01, // 0.314159
- 9.78987050620883314522302498517092317342758178710938e-01, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_PDF_01_4 = { //
- 6.42906079231301164078615784092107787728309631347656e-01, // 0.100000
- 2.30941904807187847747940168119384907186031341552734e-01, // 0.200000
- 1.07473852696625640779082289100188063457608222961426e-01, // 0.300000
- 5.56083695858133400524714318180485861375927925109863e-02, // 0.400000
- 3.04932249412341663252767887115624034777283668518066e-02, // 0.500000
- 1.73469227014204988024381748346058884635567665100098e-02, // 0.600000
- 1.01216785315276381479465683810303744394332170486450e-02, // 0.700000
- 6.01647331475561961827702717187094094697386026382446e-03, // 0.800000
- 3.62732886466578426098994469839453813619911670684814e-03, // 0.900000
- 2.21150231109318090236270926141060044756159186363220e-03, // 1.000000
- 1.36055526775470518076327497425381807261146605014801e-03, // 1.100000
- 8.43312796876826494159307134879099976387806236743927e-04, // 1.200000
- 5.25999101373744552823108477923597092740237712860107e-04, // 1.300000
- 3.29838232387005033784815877240248482848983258008957e-04, // 1.400000
- 2.07786008544730114869572568103706089459592476487160e-04, // 1.500000
- 1.31423387335168583012201537485452718101441860198975e-04, // 1.600000
- 8.34178167284065351675878541293229773145867511630058e-05, // 1.700000
- 5.31128738330742547154618427018846205100999213755131e-05, // 1.800000
- 3.39116578546243936046616918034146692662034183740616e-05, // 1.900000
- 2.17061337053406243271114900439400230425235349684954e-05, // 2.000000
- 3.81810575458691437233937904238700866699218750000000e+03, // 0.000010
- 1.20743934931413173675537109375000000000000000000000e+08, // 0.000000
- 4.84212362445597399585039966041222214698791503906250e-01, // 0.123457
- 1.50288248944523529597303750440784320119291805895045e-07, // 3.141593
- 9.30810123491585766181913991212937276031880173832178e-07, // 2.718282
- 9.74271275055620944449685794097604230046272277832031e-02, // 0.314159
- 1.31457803694503660985049009468639269471168518066406e-01, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_CDF_01_4 = { //
- 9.27573833553704485410662528011016547679901123046875e-01, // 0.100000
- 9.66394653856728513829921212163753807544708251953125e-01, // 0.200000
- 9.82338840734720664116252919484395533800125122070312e-01, // 0.300000
- 9.90161634314574046200618795410264283418655395507812e-01, // 0.400000
- 9.94326176020188468029914474755059927701950073242188e-01, // 0.500000
- 9.96650923670122979025620679749408736824989318847656e-01, // 0.600000
- 9.97989690314743826959897887718398123979568481445312e-01, // 0.700000
- 9.98777830395332189006296630395809188485145568847656e-01, // 0.800000
- 9.99249499182313538625521687208674848079681396484375e-01, // 0.900000
- 9.99535388712767813856885368295479565858840942382812e-01, // 1.000000
- 9.99710441300151630983350514725316315889358520507812e-01, // 1.100000
- 9.99818519608100975126774301315890625119209289550781e-01, // 1.200000
- 9.99885709402319799998792859696550294756889343261719e-01, // 1.300000
- 9.99927723862083506212172778759850189089775085449219e-01, // 1.400000
- 9.99954127338806841862606233917176723480224609375000e-01, // 1.500000
- 9.99970792125264407168572233786107972264289855957031e-01, // 1.600000
- 9.99981350059541806984952927450649440288543701171875e-01, // 1.700000
- 9.99988061331210875692931949743069708347320556640625e-01, // 1.800000
- 9.99992340071521379485375291551463305950164794921875e-01, // 1.900000
- 9.99995075192051996459952079021604731678962707519531e-01, // 2.000000
- 3.81824459744078470446737583188223652541637420654297e-01, // 0.000010
- 1.20743934975320044156177345939795486629009246826172e-01, // 0.000000
- 9.40661616417386770017117214592872187495231628417969e-01, // 0.123457
- 9.99999964784593187161476635083090513944625854492188e-01, // 3.141593
- 9.99999783864769620223000856640283018350601196289062e-01, // 2.718282
- 9.83788069985483404344961400056490674614906311035156e-01, // 0.314159
- 9.78987050620895637997875837754691019654273986816406e-01, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_PDF_01_4 = { //
- 6.42906079231301386123220709123415872454643249511719e-01, // 0.100000
- 2.30941904807187903259091399377211928367614746093750e-01, // 0.200000
- 1.07473852696625682412445712543558329343795776367188e-01, // 0.300000
- 5.56083695858133747469409513541904743760824203491211e-02, // 0.400000
- 3.04932249412341767336176445724049699492752552032471e-02, // 0.500000
- 1.73469227014205092107790306954484549351036548614502e-02, // 0.600000
- 1.01216785315276381479465683810303744394332170486450e-02, // 0.700000
- 6.01647331475562135300050314867803535889834165573120e-03, // 0.800000
- 3.62732886466578339362820670999099093023687601089478e-03, // 0.900000
- 2.21150231109318176972444724981414765352383255958557e-03, // 1.000000
- 1.36055526775470539760370947135470487410202622413635e-03, // 1.100000
- 8.43312796876827144680610626181760380859486758708954e-04, // 1.200000
- 5.25999101373743902301804986620936688268557190895081e-04, // 1.300000
- 3.29838232387004816944381380139361681358423084020615e-04, // 1.400000
- 2.07786008544730223289789816654149490204872563481331e-04, // 1.500000
- 1.31423387335168528802092913210231017728801816701889e-04, // 1.600000
- 8.34178167284063996423162934412687263829866424202919e-05, // 1.700000
- 5.31128738330743021493068889427036083361599594354630e-05, // 1.800000
- 3.39116578546244545910338941130390821854234673082829e-05, // 1.900000
- 2.17061337053406344915068570955440918623935431241989e-05, // 2.000000
- 3.81810575458691755557083524763584136962890625000000e+03, // 0.000010
- 1.20743934931413218379020690917968750000000000000000e+08, // 0.000000
- 4.84212362445597510607342428556876257061958312988281e-01, // 0.123457
- 1.50288248944390466015246020196893805831450663390569e-07, // 3.141593
- 9.30810123487737271986064077622380352750042220577598e-07, // 2.718282
- 9.74271275055482721683119962108321487903594970703125e-02, // 0.314159
- 1.31457803694411845540912509022746235132217407226562e-01, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_CDF_01_1 = { //
- 8.27551759585850255085404114652192220091819763183594e-01, // 0.100000
- 8.79419626790056918608229352685157209634780883789062e-01, // 0.200000
- 9.08357989730034232067623634065967053174972534179688e-01, // 0.300000
- 9.27573833553704485410662528011016547679901123046875e-01, // 0.400000
- 9.41402445890133443562319826014572754502296447753906e-01, // 0.500000
- 9.51832144669906954348448380187619477510452270507812e-01, // 0.600000
- 9.59944796430632019124118414765689522027969360351562e-01, // 0.700000
- 9.66394653856728291785316287132445722818374633789062e-01, // 0.800000
- 9.71606904600970766594514316238928586244583129882812e-01, // 0.900000
- 9.75872656273672145488262685830704867839813232421875e-01, // 1.000000
- 9.79399221790659857411753819178557023406028747558594e-01, // 1.100000
- 9.82338840734720442071647994453087449073791503906250e-01, // 1.200000
- 9.84806083916309082937345920072402805089950561523438e-01, // 1.300000
- 9.86888912463439682554167120542842894792556762695312e-01, // 1.400000
- 9.88655983362194623609298105293419212102890014648438e-01, // 1.500000
- 9.90161634314574046200618795410264283418655395507812e-01, // 1.600000
- 9.91449379513895889814989459409844130277633666992188e-01, // 1.700000
- 9.92554419222070327677442946878727525472640991210938e-01, // 1.800000
- 9.93505478144843912069461566716199740767478942871094e-01, // 1.900000
- 9.94326176020188468029914474755059927701950073242188e-01, // 2.000000
- 3.32398405040503219787240141158690676093101501464844e-01, // 0.000010
- 1.05113700610222168818630450459750136360526084899902e-01, // 0.000000
- 8.43459089726093846905996542773209512233734130859375e-01, // 0.123457
- 9.98686603432971331528733571758493781089782714843750e-01, // 3.141593
- 9.97771302397556292262947863491717725992202758789062e-01, // 2.718282
- 9.11526840920496961295782512024743482470512390136719e-01, // 0.314159
- 9.01485773262812539741162254358641803264617919921875e-01, // 0.271828
- };
-
- public static final double[] SCIPY_GAMMA_PDF_01_1 = { //
- 7.55492013825307062724334628001088276505470275878906e-01, // 0.100000
- 3.66330799305670196108764002929092384874820709228516e-01, // 0.200000
- 2.30123967106513782621135533190681599080562591552734e-01, // 0.300000
- 1.60726519807825291019653946023026946932077407836914e-01, // 0.400000
- 1.18970443671299608290325977577595040202140808105469e-01, // 0.500000
- 9.13579848700025454188988760506617836654186248779297e-02, // 0.600000
- 7.19556586194085856522661970302578993141651153564453e-02, // 0.700000
- 5.77354762017969619369850420298462267965078353881836e-02, // 0.800000
- 4.69868178615557574584471467460389249026775360107422e-02, // 0.900000
- 3.86691694403023741855029982161795487627387046813965e-02, // 1.000000
- 3.21130813374652795966213147949019912630319595336914e-02, // 1.100000
- 2.68684631741564101947705722750470158644020557403564e-02, // 1.200000
- 2.26218168783205615668396859518907149322330951690674e-02, // 1.300000
- 1.91483703787232971416099047701209201477468013763428e-02, // 1.400000
- 1.62830392611040195016691711771272821351885795593262e-02, // 1.500000
- 1.39020923964533350131178579545121465343981981277466e-02, // 1.600000
- 1.19111769796363797108140758496119815390557050704956e-02, // 1.700000
- 1.02372663794025164224477109087274584453552961349487e-02, // 1.800000
- 8.82310747761274466460790222299692686647176742553711e-03, // 1.900000
- 7.62330623530854158131919717789060086943209171295166e-03, // 2.000000
- 3.32395383249902215538895688951015472412109375000000e+03, // 0.000010
- 1.05113700600666418671607971191406250000000000000000e+08, // 0.000000
- 6.10491420220252267725413730659056454896926879882812e-01, // 0.123457
- 1.62124289852739653615409931575186419649980962276459e-03, // 3.141593
- 2.82006743783194159524985167308841482736170291900635e-03, // 2.718282
- 2.17664099893520729400719915247464086860418319702148e-01, // 0.314159
- 2.58666872715845264085743338000611402094364166259766e-01, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_CDF_01_1 = { //
- 8.27551759585850477130009039683500304818153381347656e-01, // 0.100000
- 8.79419626790056807585926890169503167271614074707031e-01, // 0.200000
- 9.08357989730034232067623634065967053174972534179688e-01, // 0.300000
- 9.27573833553704485410662528011016547679901123046875e-01, // 0.400000
- 9.41402445890133554584622288530226796865463256835938e-01, // 0.500000
- 9.51832144669907287415355767734581604599952697753906e-01, // 0.600000
- 9.59944796430632130146420877281343564391136169433594e-01, // 0.700000
- 9.66394653856728513829921212163753807544708251953125e-01, // 0.800000
- 9.71606904600970988639119241270236670970916748046875e-01, // 0.900000
- 9.75872656273672256510565148346358910202980041503906e-01, // 1.000000
- 9.79399221790659524344846431631594896316528320312500e-01, // 1.100000
- 9.82338840734720664116252919484395533800125122070312e-01, // 1.200000
- 9.84806083916308971915043457556748762726783752441406e-01, // 1.300000
- 9.86888912463439793576469583058496937155723571777344e-01, // 1.400000
- 9.88655983362194734631600567809073254466056823730469e-01, // 1.500000
- 9.90161634314574046200618795410264283418655395507812e-01, // 1.600000
- 9.91449379513895889814989459409844130277633666992188e-01, // 1.700000
- 9.92554419222070327677442946878727525472640991210938e-01, // 1.800000
- 9.93505478144843912069461566716199740767478942871094e-01, // 1.900000
- 9.94326176020188468029914474755059927701950073242188e-01, // 2.000000
- 3.32398405040503330809542603674344718456268310546875e-01, // 0.000010
- 1.05113700610222196574206066088663646951317787170410e-01, // 0.000000
- 8.43459089726094068950601467804517596960067749023438e-01, // 0.123457
- 9.98686603432971664595640959305455908179283142089844e-01, // 3.141593
- 9.97771302397558956798206963867414742708206176757812e-01, // 2.718282
- 9.11526840920501624232485937682213261723518371582031e-01, // 0.314159
- 9.01485773262837186692308932833839207887649536132812e-01, // 0.271828
- };
-
- public static final double[] GNUR_GAMMA_PDF_01_1 = { //
- 7.55492013825307506813544478063704445958137512207031e-01, // 0.100000
- 3.66330799305670307131066465444746427237987518310547e-01, // 0.200000
- 2.30123967106513865887862380077422130852937698364258e-01, // 0.300000
- 1.60726519807825346530805177280853968113660812377930e-01, // 0.400000
- 1.18970443671299608290325977577595040202140808105469e-01, // 0.500000
- 9.13579848700025592966866838651185389608144760131836e-02, // 0.600000
- 7.19556586194086134078418126591714099049568176269531e-02, // 0.700000
- 5.77354762017969758147728498443029820919036865234375e-02, // 0.800000
- 4.69868178615557713362349545604956801980733871459961e-02, // 0.900000
- 3.86691694403023811243969021234079264104366302490234e-02, // 1.000000
- 3.21130813374652934744091226093587465584278106689453e-02, // 1.100000
- 2.68684631741564206031114281358895823359489440917969e-02, // 1.200000
- 2.26218168783205719751805418127332814037799835205078e-02, // 1.300000
- 1.91483703787233006110568567237351089715957641601562e-02, // 1.400000
- 1.62830392611040264405630750843556597828865051269531e-02, // 1.500000
- 1.39020923964533436867352378385476185940206050872803e-02, // 1.600000
- 1.19111769796363866497079797568403591867536306381226e-02, // 1.700000
- 1.02372663794025233613416148159558360930532217025757e-02, // 1.800000
- 8.82310747761274292988442624618983245454728603363037e-03, // 1.900000
- 7.62330623530854418340441114310124248731881380081177e-03, // 2.000000
- 3.32395383249902442912571132183074951171875000000000e+03, // 0.000010
- 1.05113700600666448473930358886718750000000000000000e+08, // 0.000000
- 6.10491420220252156703111268143402412533760070800781e-01, // 0.123457
- 1.62124289852696415632771209658358202432282269001007e-03, // 3.141593
- 2.82006743782835809022935258383313339436426758766174e-03, // 2.718282
- 2.17664099893503326654808915918692946434020996093750e-01, // 0.314159
- 2.58666872715738793697681785488384775817394256591797e-01, // 0.271828
- };
-
- public static final double[] P_QUANT = { //
- 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99, 0.999, 0.9999 //
- };
-
- public static final double[] SCIPY_GAMMA_QUANT_1_1 = { //
- 1.00005000333358370239768275755665172255248762667179e-04, // 0.000100
- 1.00050033358353349620395444929954464896582067012787e-03, // 0.001000
- 1.00503358535014367114435174244135851040482521057129e-02, // 0.010000
- 1.05360515657826322999390811219200259074568748474121e-01, // 0.100000
- 2.87682072451780956878764072826015762984752655029297e-01, // 0.250000
- 6.93147180559945286226763982995180413126945495605469e-01, // 0.500000
- 1.38629436111989079449813289102166891098022460937500e+00, // 0.750000
- 2.30258509299404590109361379290930926799774169921875e+00, // 0.900000
- 4.60517018598809002583038818556815385818481445312500e+00, // 0.990000
- 6.90775527898213592692400197847746312618255615234375e+00, // 0.999000
- 9.21034037197629196214165858691558241844177246093750e+00, // 0.999900
- };
-
- public static final double[] GNUR_GAMMA_QUANT_1_1 = { //
- 1.00005000333358343134713963618054322068928740918636e-04, // 0.000100
- 1.00050033358353349620395444929954464896582067012787e-03, // 0.001000
- 1.00503358535014419156139453548348683398216962814331e-02, // 0.010000
- 1.05360515657826309121603003404743503779172897338867e-01, // 0.100000
- 2.87682072451780901367612841568188741803169250488281e-01, // 0.250000
- 6.93147180559945286226763982995180413126945495605469e-01, // 0.500000
- 1.38629436111989057245352796599036082625389099121094e+00, // 0.750000
- 2.30258509299404590109361379290930926799774169921875e+00, // 0.900000
- 4.60517018598809002583038818556815385818481445312500e+00, // 0.990000
- 6.90775527898213592692400197847746312618255615234375e+00, // 0.999000
- 9.21034037197629196214165858691558241844177246093750e+00, // 0.999900
- };
-
- public static final double[] SCIPY_GAMMA_QUANT_2_1 = { //
- 1.42092376217775075153415542672519222833216190338135e-02, // 0.000100
- 4.54020177694895513131889686064823763445019721984863e-02, // 0.001000
- 1.48554740253265954441630469773372169584035873413086e-01, // 0.010000
- 5.31811608389612056058126654534135013818740844726562e-01, // 0.100000
- 9.61278763114777112797071367822354659438133239746094e-01, // 0.250000
- 1.67834699001666076689787132636411115527153015136719e+00, // 0.500000
- 2.69263452888969556653364634257741272449493408203125e+00, // 0.750000
- 3.88972016986742952227018577104900032281875610351562e+00, // 0.900000
- 6.63835206799381172260154926334507763385772705078125e+00, // 0.990000
- 9.23341347645158450063718191813677549362182617187500e+00, // 0.999000
- 1.17563712224955398966130815097130835056304931640625e+01, // 0.999900
- };
-
- public static final double[] GNUR_GAMMA_QUANT_2_1 = { //
- 1.42092376217774988417241743832164502236992120742798e-02, // 0.000100
- 4.54020177694895721298706803281675092875957489013672e-02, // 0.001000
- 1.48554740253265982197206085402285680174827575683594e-01, // 0.010000
- 5.31811608389611945035824192018480971455574035644531e-01, // 0.100000
- 9.61278763114777001774768905306700617074966430664062e-01, // 0.250000
- 1.67834699001666054485326640133280307054519653320312e+00, // 0.500000
- 2.69263452888969601062285619264002889394760131835938e+00, // 0.750000
- 3.88972016986742952227018577104900032281875610351562e+00, // 0.900000
- 6.63835206799381083442312956321984529495239257812500e+00, // 0.990000
- 9.23341347645158450063718191813677549362182617187500e+00, // 0.999000
- 1.17563712224955381202562421094626188278198242187500e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GAMMA_QUANT_4_1 = { //
- 2.31796895172818012698101597379718441516160964965820e-01, // 0.000100
- 4.28552413628422945723883685786859132349491119384766e-01, // 0.001000
- 8.23248686345385172202782086969818919897079467773438e-01, // 0.010000
- 1.74476956282491135752366062661167234182357788085938e+00, // 0.100000
- 2.53532021190009304589807470620144158601760864257812e+00, // 0.250000
- 3.67206074885089650550185069732833653688430786132812e+00, // 0.500000
- 5.10942748512337985289377684239298105239868164062500e+00, // 0.750000
- 6.68078306825586487605050933780148625373840332031250e+00, // 0.900000
- 1.00451175148316167451412184163928031921386718750000e+01, // 0.990000
- 1.30622407791880714711396649363450706005096435546875e+01, // 0.999000
- 1.59138140006312944763067207532003521919250488281250e+01, // 0.999900
- };
-
- public static final double[] GNUR_GAMMA_QUANT_4_1 = { //
- 2.31796895172817957186950366121891420334577560424805e-01, // 0.000100
- 4.28552413628423112257337379560340195894241333007812e-01, // 0.001000
- 8.23248686345385172202782086969818919897079467773438e-01, // 0.010000
- 1.74476956282491157956826555164298042654991149902344e+00, // 0.100000
- 2.53532021190009304589807470620144158601760864257812e+00, // 0.250000
- 3.67206074885089650550185069732833653688430786132812e+00, // 0.500000
- 5.10942748512337896471535714226774871349334716796875e+00, // 0.750000
- 6.68078306825586398787208963767625391483306884765625e+00, // 0.900000
- 1.00451175148316149687843790161423385143280029296875e+01, // 0.990000
- 1.30622407791880696947828255360946059226989746093750e+01, // 0.999000
- 1.59138140006312944763067207532003521919250488281250e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GAMMA_QUANT_4_10 = { //
- 2.31796895172818040453677213008631952106952667236328e-02, // 0.000100
- 4.28552413628423001235034917044686153531074523925781e-02, // 0.001000
- 8.23248686345385283225084549485472962260246276855469e-02, // 0.010000
- 1.74476956282491157956826555164298042654991149902344e-01, // 0.100000
- 2.53532021190009337896498209374840371310710906982422e-01, // 0.250000
- 3.67206074885089661652415315984399057924747467041016e-01, // 0.500000
- 5.10942748512338007493838176742428913712501525878906e-01, // 0.750000
- 6.68078306825586554218432411289541050791740417480469e-01, // 0.900000
- 1.00451175148316163010520085663301870226860046386719e+00, // 0.990000
- 1.30622407791880723593180846364703029394149780273438e+00, // 0.999000
- 1.59138140006312944763067207532003521919250488281250e+00, // 0.999900
- };
-
- public static final double[] GNUR_GAMMA_QUANT_4_10 = { //
- 2.31796895172817971064738173936348175629973411560059e-02, // 0.000100
- 4.28552413628423140012912995189253706485033035278320e-02, // 0.001000
- 8.23248686345385283225084549485472962260246276855469e-02, // 0.010000
- 1.74476956282491157956826555164298042654991149902344e-01, // 0.100000
- 2.53532021190009337896498209374840371310710906982422e-01, // 0.250000
- 3.67206074885089661652415315984399057924747467041016e-01, // 0.500000
- 5.10942748512337896471535714226774871349334716796875e-01, // 0.750000
- 6.68078306825586443196129948773887008428573608398438e-01, // 0.900000
- 1.00451175148316163010520085663301870226860046386719e+00, // 0.990000
- 1.30622407791880701388720353861572220921516418457031e+00, // 0.999000
- 1.59138140006312944763067207532003521919250488281250e+00, // 0.999900
- };
-
- public static final double[] SCIPY_GAMMA_QUANT_01_10 = { //
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000100
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.001000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.010000
- 6.07304836274677903746487345757596094421304488975011e-12, // 0.100000
- 5.79171329496954621446304020682127600139210699126124e-08, // 0.250000
- 5.93391104460224945785218331195665086852386593818665e-05, // 0.500000
- 3.53063580735582700775854192443148349411785602569580e-03, // 0.750000
- 2.66154553738837257315097417631477583199739456176758e-02, // 0.900000
- 1.58847781792950559776045338367111980915069580078125e-01, // 0.990000
- 3.36367701171875421728429955692263320088386535644531e-01, // 0.999000
- 5.31624347769055760615231065457919612526893615722656e-01, // 0.999900
- };
-
- public static final double[] GNUR_GAMMA_QUANT_01_10 = { //
- 6.07304836240800246013734290758296395601191608171445e-42, // 0.000100
- 6.07304836240794013868566283512457787341965380549669e-32, // 0.001000
- 6.07304836240792099284182672275736116917595330090291e-22, // 0.010000
- 6.07304836274317627815629288782017336338625579372774e-12, // 0.100000
- 5.79171329496960180100020377028102736005621409276500e-08, // 0.250000
- 5.93391104460226165512662377388153345236787572503090e-05, // 0.500000
- 3.53063580735583307929070784325631393585354089736938e-03, // 0.750000
- 2.66154553738837638954262132529038353823125362396240e-02, // 0.900000
- 1.58847781792950504264894107109284959733486175537109e-01, // 0.990000
- 3.36367701171875477239581186950090341269969940185547e-01, // 0.999000
- 5.31624347769055760615231065457919612526893615722656e-01, // 0.999900
- };
-
- public static final double[] SCIPY_GAMMA_QUANT_01_20 = { //
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000100
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.001000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.010000
- 3.03652418137338951873243672878798047210652244487505e-12, // 0.100000
- 2.89585664748477310723152010341063800069605349563062e-08, // 0.250000
- 2.96695552230112472892609165597832543426193296909332e-05, // 0.500000
- 1.76531790367791350387927096221574174705892801284790e-03, // 0.750000
- 1.33077276869418628657548708815738791599869728088379e-02, // 0.900000
- 7.94238908964752798880226691835559904575347900390625e-02, // 0.990000
- 1.68183850585937710864214977846131660044193267822266e-01, // 0.999000
- 2.65812173884527880307615532728959806263446807861328e-01, // 0.999900
- };
-
- public static final double[] GNUR_GAMMA_QUANT_01_20 = { //
- 3.03652418120400123006867145379148197800595804085722e-42, // 0.000100
- 3.03652418120397006934283141756228893670982690274834e-32, // 0.001000
- 3.03652418120396049642091336137868058458797665045146e-22, // 0.010000
- 3.03652418137158813907814644391008668169312789686387e-12, // 0.100000
- 2.89585664748480090050010188514051368002810704638250e-08, // 0.250000
- 2.96695552230113082756331188694076672618393786251545e-05, // 0.500000
- 1.76531790367791653964535392162815696792677044868469e-03, // 0.750000
- 1.33077276869418819477131066264519176911562681198120e-02, // 0.900000
- 7.94238908964752521324470535546424798667430877685547e-02, // 0.990000
- 1.68183850585937738619790593475045170634984970092773e-01, // 0.999000
- 2.65812173884527880307615532728959806263446807861328e-01, // 0.999900
- };
-
- public static final double[] SCIPY_GAMMA_QUANT_01_4 = { //
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000100
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.001000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.010000
- 1.51826209068669467858686166976238136189225613748022e-11, // 0.100000
- 1.44792832374238655361576005170531900034802674781531e-07, // 0.250000
- 1.48347776115056236446304582798916271713096648454666e-04, // 0.500000
- 8.82658951838956665203461682267516152933239936828613e-03, // 0.750000
- 6.65386384347093073898804505006410181522369384765625e-02, // 0.900000
- 3.97119454482376343928962114659952931106090545654297e-01, // 0.990000
- 8.40919252929688498809923657972831279039382934570312e-01, // 0.999000
- 1.32906086942263934602692643238697201013565063476562e+00, // 0.999900
- };
-
- public static final double[] GNUR_GAMMA_QUANT_01_4 = { //
- 1.51826209060200048758698283629955882669254719901167e-41, // 0.000100
- 1.51826209060198492519497318340481080243853975684947e-31, // 0.001000
- 1.51826209060198020119068264779783997354452683633590e-21, // 0.010000
- 1.51826209068579382720100313806021671836354869356001e-11, // 0.100000
- 1.44792832374240031790115293408582886058866279199719e-07, // 0.250000
- 1.48347776115056534601902016312635623762616887688637e-04, // 0.500000
- 8.82658951838958226454590061393901123665273189544678e-03, // 0.750000
- 6.65386384347094045343951052018383052200078964233398e-02, // 0.900000
- 3.97119454482376232906659652144298888742923736572266e-01, // 0.990000
- 8.40919252929688609832226120488485321402549743652344e-01, // 0.999000
- 1.32906086942263934602692643238697201013565063476562e+00, // 0.999900
- };
-
- public static final double[] SCIPY_GAMMA_QUANT_01_1 = { //
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000100
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.001000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.010000
- 6.07304836274677871434744667904952544756902454992087e-11, // 0.100000
- 5.79171329496954621446304020682127600139210699126124e-07, // 0.250000
- 5.93391104460224945785218331195665086852386593818665e-04, // 0.500000
- 3.53063580735582666081384672907006461173295974731445e-02, // 0.750000
- 2.66154553738837229559521802002564072608947753906250e-01, // 0.900000
- 1.58847781792950537571584845863981172442436218261719e+00, // 0.990000
- 3.36367701171875399523969463189132511615753173828125e+00, // 0.999000
- 5.31624347769055738410770572954788804054260253906250e+00, // 0.999900
- };
-
- public static final double[] GNUR_GAMMA_QUANT_01_1 = { //
- 6.07304836240800195034793134519823530677018879604667e-41, // 0.000100
- 6.07304836240793970077989273361924320975415902739790e-31, // 0.001000
- 6.07304836240792080476273059119135989417810734534360e-21, // 0.010000
- 6.07304836274317530880401255224086687345419477424002e-11, // 0.100000
- 5.79171329496960127160461173634331544235465116798878e-07, // 0.250000
- 5.93391104460226138407608065250542495050467550754547e-04, // 0.500000
- 3.53063580735583290581836024557560449466109275817871e-02, // 0.750000
- 2.66154553738837618137580420807353220880031585693359e-01, // 0.900000
- 1.58847781792950493162663860857719555497169494628906e+00, // 0.990000
- 3.36367701171875443932890448195394128561019897460938e+00, // 0.999000
- 5.31624347769055738410770572954788804054260253906250e+00, // 0.999900
- };
-
- @Test
- public void testPDF() {
- checkPDF(new GammaDistribution(1., 1.), P_CDFPDF, SCIPY_GAMMA_PDF_1_1, 1e-12);
- checkPDF(new GammaDistribution(2., 1.), P_CDFPDF, SCIPY_GAMMA_PDF_2_1, 1e-12);
- checkPDF(new GammaDistribution(4., 1.), P_CDFPDF, SCIPY_GAMMA_PDF_4_1, 1e-12);
- checkPDF(new GammaDistribution(4., 10), P_CDFPDF, SCIPY_GAMMA_PDF_4_10, 1e-13);
- checkPDF(new GammaDistribution(.1, 10), P_CDFPDF, SCIPY_GAMMA_PDF_01_10, 1e-11);
- checkPDF(new GammaDistribution(.1, 20), P_CDFPDF, SCIPY_GAMMA_PDF_01_20, 1e-14);
- checkPDF(new GammaDistribution(.1, 4.), P_CDFPDF, SCIPY_GAMMA_PDF_01_4, 1e-12);
- checkPDF(new GammaDistribution(.1, 1.), P_CDFPDF, SCIPY_GAMMA_PDF_01_1, 1e-12);
- checkPDF(new GammaDistribution(1., 1.), P_CDFPDF, GNUR_GAMMA_PDF_1_1, 1e-15);
- checkPDF(new GammaDistribution(2., 1.), P_CDFPDF, GNUR_GAMMA_PDF_2_1, 1e-16);
- checkPDF(new GammaDistribution(4., 1.), P_CDFPDF, GNUR_GAMMA_PDF_4_1, 1e-14);
- checkPDF(new GammaDistribution(4., 10), P_CDFPDF, GNUR_GAMMA_PDF_4_10, 1e-14);
- checkPDF(new GammaDistribution(.1, 10), P_CDFPDF, GNUR_GAMMA_PDF_01_10, 1e-15);
- checkPDF(new GammaDistribution(.1, 20), P_CDFPDF, GNUR_GAMMA_PDF_01_20, 1e-14);
- checkPDF(new GammaDistribution(.1, 4.), P_CDFPDF, GNUR_GAMMA_PDF_01_4, 1e-15);
- checkPDF(new GammaDistribution(.1, 1.), P_CDFPDF, GNUR_GAMMA_PDF_01_1, 1e-15);
- }
-
- @Test
- public void testCDF() {
- checkCDF(new GammaDistribution(1., 1.), P_CDFPDF, SCIPY_GAMMA_CDF_1_1, 1e-13);
- checkCDF(new GammaDistribution(2., 1.), P_CDFPDF, SCIPY_GAMMA_CDF_2_1, 1e-12);
- checkCDF(new GammaDistribution(4., 1.), P_CDFPDF, SCIPY_GAMMA_CDF_4_1, 1e-12);
- checkCDF(new GammaDistribution(4., 10), P_CDFPDF, SCIPY_GAMMA_CDF_4_10, 1e-12);
- checkCDF(new GammaDistribution(.1, 10), P_CDFPDF, SCIPY_GAMMA_CDF_01_10, 1e-14);
- checkCDF(new GammaDistribution(.1, 20), P_CDFPDF, SCIPY_GAMMA_CDF_01_20, 1e-15);
- checkCDF(new GammaDistribution(.1, 4.), P_CDFPDF, SCIPY_GAMMA_CDF_01_4, 1e-13);
- checkCDF(new GammaDistribution(.1, 1.), P_CDFPDF, SCIPY_GAMMA_CDF_01_1, 1e-13);
- checkCDF(new GammaDistribution(1., 1.), P_CDFPDF, GNUR_GAMMA_CDF_1_1, 1e-15);
- checkCDF(new GammaDistribution(2., 1.), P_CDFPDF, GNUR_GAMMA_CDF_2_1, 1e-15);
- checkCDF(new GammaDistribution(4., 1.), P_CDFPDF, GNUR_GAMMA_CDF_4_1, 1e-14);
- checkCDF(new GammaDistribution(4., 10), P_CDFPDF, GNUR_GAMMA_CDF_4_10, 1e-15);
- checkCDF(new GammaDistribution(.1, 10), P_CDFPDF, GNUR_GAMMA_CDF_01_10, 1e-15);
- checkCDF(new GammaDistribution(.1, 20), P_CDFPDF, GNUR_GAMMA_CDF_01_20, 1e-15);
- checkCDF(new GammaDistribution(.1, 4.), P_CDFPDF, GNUR_GAMMA_CDF_01_4, 1e-15);
- checkCDF(new GammaDistribution(.1, 1.), P_CDFPDF, GNUR_GAMMA_CDF_01_1, 1e-15);
- }
-
- @Test
- public void testProbit() {
- checkQuantile(new GammaDistribution(1., 1.), P_QUANT, SCIPY_GAMMA_QUANT_1_1, 1e-14);
- checkQuantile(new GammaDistribution(2., 1.), P_QUANT, SCIPY_GAMMA_QUANT_2_1, 1e-13);
- checkQuantile(new GammaDistribution(4., 1.), P_QUANT, SCIPY_GAMMA_QUANT_4_1, 1e-13);
- checkQuantile(new GammaDistribution(4., 10), P_QUANT, SCIPY_GAMMA_QUANT_4_10, 1e-13);
- checkQuantile(new GammaDistribution(.1, 10), P_QUANT, SCIPY_GAMMA_QUANT_01_10, 1e-13);
- checkQuantile(new GammaDistribution(.1, 20), P_QUANT, SCIPY_GAMMA_QUANT_01_20, 1e-14);
- checkQuantile(new GammaDistribution(.1, 4.), P_QUANT, SCIPY_GAMMA_QUANT_01_4, 1e-13);
- checkQuantile(new GammaDistribution(.1, 1.), P_QUANT, SCIPY_GAMMA_QUANT_01_1, 1e-13);
- checkQuantile(new GammaDistribution(1., 1.), P_QUANT, GNUR_GAMMA_QUANT_1_1, 1e-14);
- checkQuantile(new GammaDistribution(2., 1.), P_QUANT, GNUR_GAMMA_QUANT_2_1, 1e-13);
- checkQuantile(new GammaDistribution(4., 1.), P_QUANT, GNUR_GAMMA_QUANT_4_1, 1e-13);
- checkQuantile(new GammaDistribution(4., 10), P_QUANT, GNUR_GAMMA_QUANT_4_10, 1e-13);
- checkQuantile(new GammaDistribution(.1, 10), P_QUANT, GNUR_GAMMA_QUANT_01_10, 1e-13);
- checkQuantile(new GammaDistribution(.1, 20), P_QUANT, GNUR_GAMMA_QUANT_01_20, 1e-14);
- checkQuantile(new GammaDistribution(.1, 4.), P_QUANT, GNUR_GAMMA_QUANT_01_4, 1e-13);
- checkQuantile(new GammaDistribution(.1, 1.), P_QUANT, GNUR_GAMMA_QUANT_01_1, 1e-13);
- }
-
- @Test
- public void testRandomAndEstimation() {
- GammaDistribution g = new GammaDistribution(1.2345, 0.12345, new Random(0));
- double[] data = new double[10000];
- for (int i = 0; i < data.length; i++) {
- data[i] = g.nextRandom();
- }
- GammaDistribution g2 = GammaChoiWetteEstimator.STATIC.estimate(data, ArrayLikeUtil.DOUBLEARRAYADAPTER);
- assertEquals("k does not match.", g.getK(), g2.getK(), 1E-2);
- assertEquals("theta does not match.", g.getTheta(), g2.getTheta(), 1E-5);
- }
-
- @Test
- public void extremeValues() {
- // TODO: tested values
- GammaDistribution dist = new GammaDistribution(1.1987906546993674E12, 1.1987905236089673E12);
- assertEquals(0.0, dist.cdf(Double.MIN_VALUE), 1e-50);
- // FIXME: NEITHER OF THESE VALUE IS NOT VERIFIED.
- // THIS IS SOLELY A REGRESSION TEST.
- // assertEquals(0.45430463189141745, dist.cdf(1.0), 1e-15);
- assertEquals(3.6330826914761E-4, dist.cdf(1.0), 1e-15);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGeneralizedExtremeValueDistribution.java b/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGeneralizedExtremeValueDistribution.java
deleted file mode 100644
index 7c66107b..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGeneralizedExtremeValueDistribution.java
+++ /dev/null
@@ -1,1294 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for the Generalized Extreme Value (GEV) distribution in ELKI.
- *
- * The reference values were computed using SciPy.
- *
- * @author Erich Schubert
- */
-public class TestGeneralizedExtremeValueDistribution extends AbstractDistributionTest implements JUnit4Test {
- public static final double[] P_CDFPDF = { //
- 1e-10, 1e-05, 0.1, 0.1234567, 0.2, 0.271828182846, 0.3, 0.314159265359, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.71828182846, 3.14159265359 //
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_1_1 = { //
- 6.59880358632499303128682299757201690226793289184570e-02, // 0.000000
- 6.59898296015106466949617924910853616893291473388672e-02, // 0.000010
- 8.54688658759459179981021748062630649656057357788086e-02, // 0.100000
- 9.04841721928088676962786962576501537114381790161133e-02, // 0.123457
- 1.08008977696591554340521668109431630000472068786621e-01, // 0.200000
- 1.26023050723474722145667215045250486582517623901367e-01, // 0.271828
- 1.33486796658083856081944418292550835758447647094727e-01, // 0.300000
- 1.37320130159857167750914186399313621222972869873047e-01, // 0.314159
- 1.61682814145126474425495644027250818908214569091797e-01, // 0.400000
- 1.92295645547964910715421638087718747556209564208984e-01, // 0.500000
- 2.24961793549918465107140264080953784286975860595703e-01, // 0.600000
- 2.59276865990827554142583721841219812631607055664062e-01, // 0.700000
- 2.94816320729158143354453613937948830425739288330078e-01, // 0.800000
- 3.31154277152908960157873252683202736079692840576172e-01, // 0.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 1.000000
- 4.04607661664131867951255117077380418777465820312500e-01, // 1.100000
- 4.40991025942982617369381159733165986835956573486328e-01, // 1.200000
- 4.76723690714594083850386141421040520071983337402344e-01, // 1.300000
- 5.11544833689041578139722332707606256008148193359375e-01, // 1.400000
- 5.45239211892605046827497972117271274328231811523438e-01, // 1.500000
- 5.77635844258915676086019175272667780518531799316406e-01, // 1.600000
- 6.08605317804406409365469698968809098005294799804688e-01, // 1.700000
- 6.38056166582018691180167024867841973900794982910156e-01, // 1.800000
- 6.65930705440122117089174480497604236006736755371094e-01, // 1.900000
- 6.92200627555346392760782237019157037138938903808594e-01, // 2.000000
- 8.35793188453588298258978284138720482587814331054688e-01, // 2.718282
- 8.89169312582892001906031964608700945973396301269531e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_1_1 = { //
- 1.79374078764838684740823282481869682669639587402344e-01, // 0.000000
- 1.79377160888317427334115450321405660361051559448242e-01, // 0.000010
- 2.10219488415532645975147829631168860942125320434570e-01, // 0.100000
- 2.17395492872112461313349740521516650915145874023438e-01, // 0.123457
- 2.40378400508394624024433028353087138384580612182617e-01, // 0.200000
- 2.61030341003925192566725854703690856695175170898438e-01, // 0.271828
- 2.68809398181777348124654736238881014287471771240234e-01, // 0.300000
- 2.72640929007956611673790803251904435455799102783203e-01, // 0.314159
- 2.94605295353879470532376672053942456841468811035156e-01, // 0.400000
- 3.17041921077942157047857563156867399811744689941406e-01, // 0.500000
- 3.35603559643445015225893257593270391225814819335938e-01, // 0.600000
- 3.49987161158421655748895773285767063498497009277344e-01, // 0.700000
- 3.60089467289227027624320953691494651138782501220703e-01, // 0.800000
- 3.65982076505757814022246066087973304092884063720703e-01, // 0.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 1.000000
- 3.66104151897740148768889412167482078075408935546875e-01, // 1.100000
- 3.61052914770930044596752850338816642761230468750000e-01, // 1.200000
- 3.53165596312007168400270984420785680413246154785156e-01, // 1.300000
- 3.42898756467731824493228032224578782916069030761719e-01, // 1.400000
- 3.30704298890418080247854959452524781227111816406250e-01, // 1.500000
- 3.17013272754289754384871002912404946982860565185547e-01, // 1.600000
- 3.02224456630968474346587981926859356462955474853516e-01, // 1.700000
- 2.86697116378903826827695411338936537504196166992188e-01, // 1.800000
- 2.70747220321607640070027400724939070641994476318359e-01, // 1.900000
- 2.54646380043582531982337968656793236732482910156250e-01, // 2.000000
- 1.49919633191029216812140134607034269720315933227539e-01, // 2.718282
- 1.04448592925595828972973322379402816295623779296875e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_2_1 = { //
- 6.17978989787721657254981888485190211213193833827972e-04, // 0.000000
- 6.18024653604032120531031058163762281765230000019073e-04, // 0.000010
- 1.24839763464425581619698935043061283067800104618073e-03, // 0.100000
- 1.45770722707259806419366476859522663289681077003479e-03, // 0.123457
- 2.35869338329322553171607523836428299546241760253906e-03, // 0.200000
- 3.58731530475635143964674433902928285533562302589417e-03, // 0.271828
- 4.19464154138938540017367273549098172225058078765869e-03, // 0.300000
- 4.53021237372840286650177432647979003377258777618408e-03, // 0.314159
- 7.06196156220941038267335798650492506567388772964478e-03, // 0.400000
- 1.13142863804596271321001310639076109509915113449097e-02, // 0.500000
- 1.73320140087645062354493319389803218655288219451904e-02, // 0.600000
- 2.54943946757241260425708162529190303757786750793457e-02, // 0.700000
- 3.61486049131355194341530534529738361015915870666504e-02, // 0.800000
- 4.95800856955669819181586888134916080161929130554199e-02, // 0.900000
- 6.59880358453125426265728492580819875001907348632812e-02, // 1.000000
- 8.54688658759459596314655982496333308517932891845703e-02, // 1.100000
- 1.08008977696591554340521668109431630000472068786621e-01, // 1.200000
- 1.33486796658083856081944418292550835758447647094727e-01, // 1.300000
- 1.61682814145126418914344412769423797726631164550781e-01, // 1.400000
- 1.92295645547964910715421638087718747556209564208984e-01, // 1.500000
- 2.24961793549918520618291495338780805468559265136719e-01, // 1.600000
- 2.59276865990827554142583721841219812631607055664062e-01, // 1.700000
- 2.94816320729158143354453613937948830425739288330078e-01, // 1.800000
- 3.31154277152908849135570790167548693716526031494141e-01, // 1.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 2.000000
- 6.14105034982032282897534969379194080829620361328125e-01, // 2.718282
- 7.26650204627822926539693071390502154827117919921875e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_2_1 = { //
- 4.56628142304533850281966778084097313694655895233154e-03, // 0.000000
- 4.56657317004234564183917655100231058895587921142578e-03, // 0.000010
- 8.34665480722261536594697162172451498918235301971436e-03, // 0.100000
- 9.52012623739182869964103872462146682664752006530762e-03, // 0.123457
- 1.42692634455674552396153842437342973425984382629395e-02, // 0.200000
- 2.01978449671180448898866188756073825061321258544922e-02, // 0.271828
- 2.29612471247189892098461427849542815238237380981445e-02, // 0.300000
- 2.44494948372630735433652660049119731411337852478027e-02, // 0.314159
- 3.49781245974551888155978929262346355244517326354980e-02, // 0.400000
- 5.07071136099807306951703367303707636892795562744141e-02, // 0.500000
- 7.02847826336932546276159428089158609509468078613281e-02, // 0.600000
- 9.35464974266043414186100335427909158170223236083984e-02, // 0.700000
- 1.20017594905418731321411485168937360867857933044434e-01, // 0.800000
- 1.48946808910974892725675999827217310667037963867188e-01, // 0.900000
- 1.79374078734017200487116383555985521525144577026367e-01, // 1.000000
- 2.10219488415532701486299060888995882123708724975586e-01, // 1.100000
- 2.40378400508394624024433028353087138384580612182617e-01, // 1.200000
- 2.68809398181777348124654736238881014287471771240234e-01, // 1.300000
- 2.94605295353879415021225440796115435659885406494141e-01, // 1.400000
- 3.17041921077942157047857563156867399811744689941406e-01, // 1.500000
- 3.35603559643445015225893257593270391225814819335938e-01, // 1.600000
- 3.49987161158421655748895773285767063498497009277344e-01, // 1.700000
- 3.60089467289227027624320953691494651138782501220703e-01, // 1.800000
- 3.65982076505757758511094834830146282911300659179688e-01, // 1.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 2.000000
- 2.99431043346856384790299898668308742344379425048828e-01, // 2.718282
- 2.32026725020700291812758564446994569152593612670898e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_4_1 = { //
- 1.94233761556120265073609843858010169210640550320133e-24, // 0.000000
- 1.94339836960486498321475838226799834065378487714337e-24, // 0.000010
- 3.50581472625786942134053009067093603336708158078897e-22, // 0.100000
- 1.10204869082170943883948227538294176292737847487482e-21, // 0.123457
- 3.85942175009585124493227078787604613125739296999845e-20, // 0.200000
- 8.55175072212361792537222183911253732406541162804661e-19, // 0.271828
- 2.71618226092945448511767238087193692507249743561641e-18, // 0.300000
- 4.79654546206938212109880845109838654258082904740905e-18, // 0.314159
- 1.27523062451624426541224412921385568571695936319552e-16, // 0.400000
- 4.15089692010904525288672126361021019245556122612140e-15, // 0.500000
- 9.69966408521639154441452223525895873820334286419254e-14, // 0.600000
- 1.67930865740466120726981233244263965733930610291225e-12, // 0.700000
- 2.21644780341866066467927092510455566905236413077773e-11, // 0.800000
- 2.28850701972651310101286108247299871248925384747963e-10, // 0.900000
- 1.89217869483829244811168274588777937772476889222162e-09, // 1.000000
- 1.27958444708893479866928830448492837579266279135481e-08, // 1.100000
- 7.21407495654723266621612446335143342679430134012364e-08, // 1.200000
- 3.44996444807882075559481984891596617615050490712747e-07, // 1.300000
- 1.42158510896623277238609052430806656275308341719210e-06, // 1.400000
- 5.11929429867073290303346178031773661132319830358028e-06, // 1.500000
- 1.63190669761509105832684302095358930273505393415689e-05, // 1.600000
- 4.65873061192628793976758250217073964449809864163399e-05, // 1.700000
- 1.20361180348421196420645451485853527628933079540730e-04, // 1.800000
- 2.84104078721292101477463587499983077577780932188034e-04, // 1.900000
- 6.17978989331093432439689916435554550844244658946991e-04, // 2.000000
- 2.72466505377139643628847665013381629250943660736084e-02, // 2.718282
- 9.44768930014186492094552249909611418843269348144531e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_4_1 = { //
- 1.06048040538825383895657084905076034872528558503039e-22, // 0.000000
- 1.06104894703602011823679422569673096865235426708292e-22, // 0.000010
- 1.73195833587372556877622009550080809725453568188831e-20, // 0.100000
- 5.31816915757311281533262916149991462179401939316581e-20, // 0.123457
- 1.72520723688492552379661823003568327945291845918510e-18, // 0.200000
- 3.55778320603558542628503187787223104575572232312602e-17, // 0.271828
- 1.09862250605229655196224903219933069216592916588111e-16, // 0.300000
- 1.91279689150650823875815251444059610432563375858640e-16, // 0.314159
- 4.66711893658034022812779722242683120807921724748635e-15, // 0.400000
- 1.37458827543354963946170620516550599064667728677058e-13, // 0.500000
- 2.90641705075567549607614189502246106536209602211329e-12, // 0.600000
- 4.55304892645473537813182015220254180570824686924425e-11, // 0.700000
- 5.43750726676849818042246906675497505889715910143423e-10, // 0.800000
- 5.08001673311263319774744418142083113298923535694485e-09, // 0.900000
- 3.80054250404435749527446645589651152974397518846672e-08, // 1.000000
- 2.32553537538727241913236328495206972633013720042072e-07, // 1.100000
- 1.18632914440636535453432297976261722283197741489857e-06, // 1.200000
- 5.13345454477618321902391770872320364560437155887485e-06, // 1.300000
- 1.91398495015806936032053131579999671885161660611629e-05, // 1.400000
- 6.23657718766199291749591226974303026509005576372147e-05, // 1.500000
- 1.79887953645615079585964868336134259152458980679512e-04, // 1.600000
- 4.64670291311834173994532726226225349819287657737732e-04, // 1.700000
- 1.08626127745232634556893369648378211422823369503021e-03, // 1.800000
- 2.32004217969156720582923902895799983525648713111877e-03, // 1.900000
- 4.56628142012791525539139314560088678263127803802490e-03, // 2.000000
- 9.81649050447965243471060148294782266020774841308594e-02, // 2.718282
- 2.22908780675388440428719150077085942029953002929688e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_4_10 = { //
- 2.24961793553274530532704034158086869865655899047852e-01, // 0.000000
- 2.24962129153560647099041602814395446330308914184570e-01, // 0.000010
- 2.28326012057771948748907675508235115557909011840820e-01, // 0.100000
- 2.29117491320003585641984500398393720388412475585938e-01, // 0.123457
- 2.31706315790068034798920848515990655869245529174805e-01, // 0.200000
- 2.34144016800101217867791092430707067251205444335938e-01, // 0.271828
- 2.35102282543562940420045492828649003058671951293945e-01, // 0.300000
- 2.35584367949729117652779564195952843874692916870117e-01, // 0.314159
- 2.38513488532688416876581527503731194883584976196289e-01, // 0.400000
- 2.41939508585804652351924914910341612994670867919922e-01, // 0.500000
- 2.45379916339054454654799997115333098918199539184570e-01, // 0.600000
- 2.48834284427714574894352494993654545396566390991211e-01, // 0.700000
- 2.52302184674948581921682944084750488400459289550781e-01, // 0.800000
- 2.55783188277869832916167069924995303153991699218750e-01, // 0.900000
- 2.59276865990827554142583721841219812631607055664062e-01, // 1.000000
- 2.62782788305835623976491888242890127003192901611328e-01, // 1.100000
- 2.66300525630066620141889188744244165718555450439453e-01, // 1.200000
- 2.69829648460341131599449226996512152254581451416016e-01, // 1.300000
- 2.73369727554544250658352666505379602313041687011719e-01, // 1.400000
- 2.76920334099908960201474883433547802269458770751953e-01, // 1.500000
- 2.80481039878108018292834913154365494847297668457031e-01, // 1.600000
- 2.84051417427103602975080320902634412050247192382812e-01, // 1.700000
- 2.87631040199704479665143708189134486019611358642578e-01, // 1.800000
- 2.91219482718789723918462186702527105808258056640625e-01, // 1.900000
- 2.94816320729158143354453613937948830425739288330078e-01, // 2.000000
- 3.20860670367920819412432820172398351132869720458984e-01, // 2.718282
- 3.36339983908659712064093127992236986756324768066406e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_4_10 = { //
- 3.35603559645095625429966901265288470312952995300293e-02, // 0.000000
- 3.35603724701354494408533923888171557337045669555664e-02, // 0.000010
- 3.37233134553145824652276019151031505316495895385742e-02, // 0.100000
- 3.37609284733200315509193956131639424711465835571289e-02, // 0.123457
- 3.38820574854396400210632123162213247269392013549805e-02, // 0.200000
- 3.39934708099677296289087280456442385911941528320312e-02, // 0.271828
- 3.40365712424673116931472804935765452682971954345703e-02, // 0.300000
- 3.40581064819283629852009198657469823956489562988281e-02, // 0.314159
- 3.41868398883302671009687401237897574901580810546875e-02, // 0.400000
- 3.43328505356715121821231662124773720279335975646973e-02, // 0.500000
- 3.44745922233250789989966733628534711897373199462891e-02, // 0.600000
- 3.46120558908042108559044436333351768553256988525391e-02, // 0.700000
- 3.47452343518489734086607256813294952735304832458496e-02, // 0.800000
- 3.48741222670847020315143538482516305521130561828613e-02, // 0.900000
- 3.49987161158421683504471388914680574089288711547852e-02, // 1.000000
- 3.51190141671897312902750343255320331081748008728027e-02, // 1.100000
- 3.52350164502270857269650150556117296218872070312500e-02, // 1.200000
- 3.53467247236895973361292533354571787640452384948730e-02, // 1.300000
- 3.54541424449113518058140925859333947300910949707031e-02, // 1.400000
- 3.55572747381944151423560640523646725341677665710449e-02, // 1.500000
- 3.56561283626308858640818755247892113402485847473145e-02, // 1.600000
- 3.57507116794234872103608324778178939595818519592285e-02, // 1.700000
- 3.58410346187495246206289323254168266430497169494629e-02, // 1.800000
- 3.59271086462122773985683465980400796979665756225586e-02, // 1.900000
- 3.60089467289226999868745338062581140547990798950195e-02, // 2.000000
- 3.64737821185050284378270646357123041525483131408691e-02, // 2.718282
- 3.66487069582701815995129379643913125619292259216309e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_01_10 = { //
- 3.64200708229312053454407305252971127629280090332031e-01, // 0.000000
- 3.64201076086621500227380465730675496160984039306641e-01, // 0.000010
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.100000
- 3.68742364149354184821305580044281668961048126220703e-01, // 0.123457
- 3.71558174423808174058336817324743606150150299072266e-01, // 0.200000
- 3.74200337049799547362027851704624481499195098876953e-01, // 0.271828
- 3.75236541960806024853525286744115874171257019042969e-01, // 0.300000
- 3.75757321275714095687447979798889718949794769287109e-01, // 0.314159
- 3.78914181510685010856320786842843517661094665527344e-01, // 0.400000
- 3.82590734620523953424253704724833369255065917968750e-01, // 0.500000
- 3.86265846721645655925669871066929772496223449707031e-01, // 0.600000
- 3.89939167191828084391147513088071718811988830566406e-01, // 0.700000
- 3.93610349414351023966673892573453485965728759765625e-01, // 0.800000
- 3.97279050833918845331282909683068282902240753173828e-01, // 0.900000
- 4.00944933009500681375669728367938660085201263427734e-01, // 1.000000
- 4.04607661664131867951255117077380418777465820312500e-01, // 1.100000
- 4.08266906731719725343054960831068456172943115234375e-01, // 1.200000
- 4.11922342400900476366842895004083402454853057861328e-01, // 1.300000
- 4.15573647155991876545044760860037058591842651367188e-01, // 1.400000
- 4.19220503815090905774809471040498465299606323242188e-01, // 1.500000
- 4.22862599565362817788383154038456268608570098876953e-01, // 1.600000
- 4.26499625995571840508802097247098572552204132080078e-01, // 1.700000
- 4.30131279125902432625139226729515939950942993164062e-01, // 1.800000
- 4.33757259435121944601831955878878943622112274169922e-01, // 1.900000
- 4.37377271885135254780863078849506564438343048095703e-01, // 2.000000
- 4.63178277570029439669241355659323744475841522216797e-01, // 2.718282
- 4.78191805551566095910942522095865570008754730224609e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_01_10 = { //
- 3.67860986195510386576046357731684111058712005615234e-02, // 0.000000
- 3.67860989892352038821421444936277111992239952087402e-02, // 0.000010
- 3.67879441171442347902065250764280790463089942932129e-02, // 0.100000
- 3.67878429896495301454351078973559197038412094116211e-02, // 0.123457
- 3.67861108816435675161748974915099097415804862976074e-02, // 0.200000
- 3.67825446794351126889033309907972579821944236755371e-02, // 0.271828
- 3.67806360606196675044898825035488698631525039672852e-02, // 0.300000
- 3.67795687265079010441759521654603304341435432434082e-02, // 0.314159
- 3.67715575045233014628287548930529737845063209533691e-02, // 0.400000
- 3.67589137340928531760830821895069675520062446594238e-02, // 0.500000
- 3.67427439081312035007442773348884657025337219238281e-02, // 0.600000
- 3.67230877916642356462162410934979561716318130493164e-02, // 0.700000
- 3.66999857244961757984924588527064770460128784179688e-02, // 0.800000
- 3.66734785901757648352017326942586805671453475952148e-02, // 0.900000
- 3.66436077853866115638936662435298785567283630371094e-02, // 1.000000
- 3.66104151897740162646677219981938833370804786682129e-02, // 1.100000
- 3.65739431362198524899653762076923158019781112670898e-02, // 1.200000
- 3.65342343815761166903044454556948039680719375610352e-02, // 1.300000
- 3.64913320778669988952991332098463317379355430603027e-02, // 1.400000
- 3.64452797439685782787677226224332116544246673583984e-02, // 1.500000
- 3.63961212377742968082650065753114176914095878601074e-02, // 1.600000
- 3.63439007288538645790154646419978234916925430297852e-02, // 1.700000
- 3.62886626716122442926071300917101325467228889465332e-02, // 1.800000
- 3.62304517789548280459754892035562079399824142456055e-02, // 1.900000
- 3.61693129964641910123468449000938562676310539245605e-02, // 2.000000
- 3.56482034999189151269760600371228065341711044311523e-02, // 2.718282
- 3.52782829415396598227161462091316934674978256225586e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_01_20 = { //
- 3.66040051641140451454958792965044267475605010986328e-01, // 0.000000
- 3.66040235576718830934339621308026835322380065917969e-01, // 0.000010
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.100000
- 3.68310902956942021191366620769258588552474975585938e-01, // 0.123457
- 3.69718830722743807548624772607581689953804016113281e-01, // 0.200000
- 3.71040005167483422088281486139749176800251007080078e-01, // 0.271828
- 3.71558174423808174058336817324743606150150299072266e-01, // 0.300000
- 3.71818605637736554481165285324095748364925384521484e-01, // 0.314159
- 3.73397426637427698459248404105892404913902282714844e-01, // 0.400000
- 3.75236541960806024853525286744115874171257019042969e-01, // 0.500000
- 3.77075475227729051130864945662324316799640655517578e-01, // 0.600000
- 3.78914181510685010856320786842843517661094665527344e-01, // 0.700000
- 3.80752616122933373876691121040494181215763092041016e-01, // 0.800000
- 3.82590734620523953424253704724833369255065917968750e-01, // 0.900000
- 3.84428492804265664606333530173287726938724517822266e-01, // 1.000000
- 3.86265846721645655925669871066929772496223449707031e-01, // 1.100000
- 3.88102752668698702809280121073243208229541778564453e-01, // 1.200000
- 3.89939167191828084391147513088071718811988830566406e-01, // 1.300000
- 3.91775047089576777814556862722383812069892883300781e-01, // 1.400000
- 3.93610349414351023966673892573453485965728759765625e-01, // 1.500000
- 3.95445031474095209933494743381743319332599639892578e-01, // 1.600000
- 3.97279050833918845331282909683068282902240753173828e-01, // 1.700000
- 3.99112365317676576204064531339099630713462829589844e-01, // 1.800000
- 4.00944933009500681375669728367938660085201263427734e-01, // 1.900000
- 4.02776712255286439834378597879549488425254821777344e-01, // 2.000000
- 4.15907192667703928812272806680994108319282531738281e-01, // 2.718282
- 4.23619395109240293173513691726839169859886169433594e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_01_20 = { //
- 1.83937417516764276093077512541640317067503929138184e-02, // 0.000000
- 1.83937417977731651475004071016883244737982749938965e-02, // 0.000010
- 1.83939720585721173951032625382140395231544971466064e-02, // 0.100000
- 1.83939594126808145246876335932029178366065025329590e-02, // 0.123457
- 1.83937425180828485749007228378104628063738346099854e-02, // 0.200000
- 1.83932951601603437985499311935200239531695842742920e-02, // 0.271828
- 1.83930554408217837580874487457549548707902431488037e-02, // 0.300000
- 1.83929213116811943184991662292304681614041328430176e-02, // 0.314159
- 1.83919131598794319271128472337295534089207649230957e-02, // 0.400000
- 1.83903180303098337522449412517744349315762519836426e-02, // 0.500000
- 1.83882724286199075725001250702916877344250679016113e-02, // 0.600000
- 1.83857787522616507314143774465264868922531604766846e-02, // 0.700000
- 1.83828394191271268787168935432418948039412498474121e-02, // 0.800000
- 1.83794568670464265880415410947534837760031223297119e-02, // 0.900000
- 1.83756335532885978212291888667095918208360671997070e-02, // 1.000000
- 1.83713719540656017503721386674442328512668609619141e-02, // 1.100000
- 1.83666745640393841432214117048715706914663314819336e-02, // 1.200000
- 1.83615438958321178231081205467489780858159065246582e-02, // 1.300000
- 1.83559824795396266117197825451512471772730350494385e-02, // 1.400000
- 1.83499928622480878992462294263532385230064392089844e-02, // 1.500000
- 1.83435776075540693530463443039479898288846015930176e-02, // 1.600000
- 1.83367392950878824176008663471293402835726737976074e-02, // 1.700000
- 1.83294805200404052614171490631633787415921688079834e-02, // 1.800000
- 1.83218038926933057819468331217649392783641815185547e-02, // 1.900000
- 1.83137120379528138547353677267892635427415370941162e-02, // 2.000000
- 1.82436263119165158197443332710463437251746654510498e-02, // 2.718282
- 1.81927559990815723711676810125936754047870635986328e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_01_4 = { //
- 3.58683419097346689596861324389465153217315673828125e-01, // 0.000000
- 3.58684338497014365554349524245481006801128387451172e-01, // 0.000010
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.100000
- 3.70036738247086438580168987755314446985721588134766e-01, // 0.123457
- 3.77075475227729051130864945662324316799640655517578e-01, // 0.200000
- 3.83677647968239443621030204667476937174797058105469e-01, // 0.271828
- 3.86265846721645655925669871066929772496223449707031e-01, // 0.300000
- 3.87566357530248317697640914047951810061931610107422e-01, // 0.314159
- 3.95445031474095209933494743381743319332599639892578e-01, // 0.400000
- 4.04607661664131867951255117077380418777465820312500e-01, // 0.500000
- 4.13748531068576341773734839080134406685829162597656e-01, // 0.600000
- 4.22862599565362817788383154038456268608570098876953e-01, // 0.700000
- 4.31944996928375679612344129054690711200237274169922e-01, // 0.800000
- 4.40991025942982672880532390990993008017539978027344e-01, // 0.900000
- 4.49996164872620063590602512704208493232727050781250e-01, // 1.000000
- 4.58956069307663805378894039677106775343418121337891e-01, // 1.100000
- 4.67866573428437237947008497940259985625743865966797e-01, // 1.200000
- 4.76723690714594083850386141421040520071983337402344e-01, // 1.300000
- 4.85523614133279490800987332477234303951263427734375e-01, // 1.400000
- 4.94262715838446498040070764545816928148269653320312e-01, // 1.500000
- 5.02937546413495417674255349993472918868064880371094e-01, // 1.600000
- 5.11544833689041578139722332707606256008148193359375e-01, // 1.700000
- 5.20081481167105397211969375348417088389396667480469e-01, // 1.800000
- 5.28544566082388089789390051009831950068473815917969e-01, // 1.900000
- 5.36931337130553965053536558116320520639419555664062e-01, // 2.000000
- 5.94719607054730259321217999968212097883224487304688e-01, // 2.718282
- 6.26579099505278791504281343804905191063880920410156e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_01_4 = { //
- 9.19408832681790494367746191528567578643560409545898e-02, // 0.000000
- 9.19408890865627964616990652757522184401750564575195e-02, // 0.000010
- 9.19698602928605835060693607374560087919235229492188e-02, // 0.100000
- 9.19682820379929405474328518721449654549360275268555e-02, // 0.123457
- 9.19413621430995309236067214442300610244274139404297e-02, // 0.200000
- 9.18862440991995849115525629713374655693769454956055e-02, // 0.271828
- 9.18568597703280087518606933372211642563343048095703e-02, // 0.300000
- 9.18404563854176708703747067374933976680040359497070e-02, // 0.314159
- 9.17178880377703537041256254269683267921209335327148e-02, // 0.400000
- 9.15260379744350371922223530418705195188522338867188e-02, // 0.500000
- 9.12829492792362195974220639982377178966999053955078e-02, // 0.600000
- 9.09903030944357454901094683918927330523729324340820e-02, // 0.700000
- 9.06498150644146627463726417772704735398292541503906e-02, // 0.800000
- 9.02632286927325111491882125847041606903076171875000e-02, // 0.900000
- 8.98323090075764524309320790962374303489923477172852e-02, // 1.000000
- 8.93588365430456332827446885858080349862575531005859e-02, // 1.100000
- 8.88446016412571676346132676371780689805746078491211e-02, // 1.200000
- 8.82913990780017921000677461051964201033115386962891e-02, // 1.300000
- 8.77010230126132606098821042905910871922969818115234e-02, // 1.400000
- 8.70752622608445409069233278387400787323713302612305e-02, // 1.500000
- 8.64158958878580990559115093674336094409227371215820e-02, // 1.600000
- 8.57246891169329561233070080561446957290172576904297e-02, // 1.700000
- 8.50033895481578094521779576098197139799594879150391e-02, // 1.800000
- 8.42537236802113342903908232983667403459548950195312e-02, // 1.900000
- 8.34773937273183275209476050804369151592254638671875e-02, // 2.000000
- 7.72637758157185411400647012669651303440332412719727e-02, // 2.718282
- 7.32283395263601255553709279411123134195804595947266e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_01_1 = { //
- 3.31154277189507073586582919233478605747222900390625e-01, // 0.000000
- 3.31157936975598421458499842628953047096729278564453e-01, // 0.000010
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.100000
- 3.76507892217193051997981001477455720305442810058594e-01, // 0.123457
- 4.04607661664131867951255117077380418777465820312500e-01, // 0.200000
- 4.30794607123086759070673679161700420081615447998047e-01, // 0.271828
- 4.40991025942982672880532390990993008017539978027344e-01, // 0.300000
- 4.46096575846239407070470406324602663516998291015625e-01, // 0.314159
- 4.76723690714594083850386141421040520071983337402344e-01, // 0.400000
- 5.11544833689041578139722332707606256008148193359375e-01, // 0.500000
- 5.45239211892605046827497972117271274328231811523438e-01, // 0.600000
- 5.77635844258915676086019175272667780518531799316406e-01, // 0.700000
- 6.08605317804406409365469698968809098005294799804688e-01, // 0.800000
- 6.38056166582018691180167024867841973900794982910156e-01, // 0.900000
- 6.65930705440122117089174480497604236006736755371094e-01, // 1.000000
- 6.92200627555346392760782237019157037138938903808594e-01, // 1.100000
- 7.16862603474862081220919662882806733250617980957031e-01, // 1.200000
- 7.39934054783606187655209396325517445802688598632812e-01, // 1.300000
- 7.61449220009415284060594331094762310385704040527344e-01, // 1.400000
- 7.81455584849563456018017859605606645345687866210938e-01, // 1.500000
- 8.00010713004353557487036141537828370928764343261719e-01, // 1.600000
- 8.17179486939028754122205100429710000753402709960938e-01, // 1.700000
- 8.33031748536220639778093755012378096580505371093750e-01, // 1.800000
- 8.47640316515773317718185353442095220088958740234375e-01, // 1.900000
- 8.61079349396833837460007998743094503879547119140625e-01, // 2.000000
- 9.29667709628290483969692559185205027461051940917969e-01, // 2.718282
- 9.53363743354765147408613756851991638541221618652344e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_01_1 = { //
- 3.65982076509606846226319021297967992722988128662109e-01, // 0.000000
- 3.65982461392446445369586172091658227145671844482422e-01, // 0.000010
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.100000
- 3.67779034862618203760575852356851100921630859375000e-01, // 0.123457
- 3.66104151897740148768889412167482078075408935546875e-01, // 0.200000
- 3.62782413998306907387814135290682315826416015625000e-01, // 0.271828
- 3.61052914770930044596752850338816642761230468750000e-01, // 0.300000
- 3.60097994370001339703435405681375414133071899414062e-01, // 0.314159
- 3.53165596312007168400270984420785680413246154785156e-01, // 0.400000
- 3.42898756467731824493228032224578782916069030761719e-01, // 0.500000
- 3.30704298890418080247854959452524781227111816406250e-01, // 0.600000
- 3.17013272754289754384871002912404946982860565185547e-01, // 0.700000
- 3.02224456630968474346587981926859356462955474853516e-01, // 0.800000
- 2.86697116378903826827695411338936537504196166992188e-01, // 0.900000
- 2.70747220321607584558876169467112049460411071777344e-01, // 1.000000
- 2.54646380043582531982337968656793236732482910156250e-01, // 1.100000
- 2.38622831681304076179017670256143901497125625610352e-01, // 1.200000
- 2.22863854497548474764556658556102775037288665771484e-01, // 1.300000
- 2.07519121233516318225653662921104114502668380737305e-01, // 1.400000
- 1.92704574679114809532265439884213265031576156616211e-01, // 1.500000
- 1.78506518513120937541316379792988300323486328125000e-01, // 1.600000
- 1.64985692989648907724742343816615175455808639526367e-01, // 1.700000
- 1.52181175470408269756461550059611909091472625732422e-01, // 1.800000
- 1.40114001931851056559352741714974399656057357788086e-01, // 1.900000
- 1.28790449330409367822980470918992068618535995483398e-01, // 2.000000
- 6.77988607946176241592084465992229524999856948852539e-02, // 2.718282
- 4.55314756659847622022319058032735483720898628234863e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_CDF_1_05_1 = { //
- 2.23130160170742858349868242839875165373086929321289e-01, // 0.000000
- 2.23132391461187878922700633665954228490591049194336e-01, // 0.000010
- 2.46596963941606434067566056000941898673772811889648e-01, // 0.100000
- 2.52449689405203292480450727452989667654037475585938e-01, // 0.123457
- 2.72531793034012592702453048332245089113712310791016e-01, // 0.200000
- 2.92827430712962133441124024102464318275451660156250e-01, // 0.271828
- 3.01194211912202136627314530414878390729427337646484e-01, // 0.300000
- 3.05489236119981799610911821218905970454216003417969e-01, // 0.314159
- 3.32871083698079606172370858985232189297676086425781e-01, // 0.400000
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.500000
- 4.06569659740599109731817861757008358836174011230469e-01, // 0.600000
- 4.49328964117221563157045238767750561237335205078125e-01, // 0.700000
- 4.96585303791409526930067386274458840489387512207031e-01, // 0.800000
- 5.48811636094026389365296836331253871321678161621094e-01, // 0.900000
- 6.06530659712633424263117376540321856737136840820312e-01, // 1.000000
- 6.70320046035639327541844068036880344152450561523438e-01, // 1.100000
- 7.40818220681717876097138741897651925683021545410156e-01, // 1.200000
- 8.18730753077981820986508409987436607480049133300781e-01, // 1.300000
- 9.04837418035959517581545696884859353303909301757812e-01, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_PDF_1_05_1 = { //
- 2.23130160170742858349868242839875165373086929321289e-01, // 0.000000
- 2.23132391461187878922700633665954228490591049194336e-01, // 0.000010
- 2.46596963941606434067566056000941898673772811889648e-01, // 0.100000
- 2.52449689405203292480450727452989667654037475585938e-01, // 0.123457
- 2.72531793034012592702453048332245089113712310791016e-01, // 0.200000
- 2.92827430712962133441124024102464318275451660156250e-01, // 0.271828
- 3.01194211912202136627314530414878390729427337646484e-01, // 0.300000
- 3.05489236119981799610911821218905970454216003417969e-01, // 0.314159
- 3.32871083698079606172370858985232189297676086425781e-01, // 0.400000
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.500000
- 4.06569659740599165242969093014835380017757415771484e-01, // 0.600000
- 4.49328964117221563157045238767750561237335205078125e-01, // 0.700000
- 4.96585303791409526930067386274458840489387512207031e-01, // 0.800000
- 5.48811636094026500387599298846907913684844970703125e-01, // 0.900000
- 6.06530659712633313240814914024667814373970031738281e-01, // 1.000000
- 6.70320046035639327541844068036880344152450561523438e-01, // 1.100000
- 7.40818220681717876097138741897651925683021545410156e-01, // 1.200000
- 8.18730753077981932008810872503090649843215942382812e-01, // 1.300000
- 9.04837418035959517581545696884859353303909301757812e-01, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_CDF_1_05_05 = { //
- 1.35335283263679745369145734912308398634195327758789e-01, // 0.000000
- 1.35337989969344651974836324370699003338813781738281e-01, // 0.000010
- 1.65298888221586531832585365009435918182134628295898e-01, // 0.100000
- 1.73238399726401759437521832296624779701232910156250e-01, // 0.123457
- 2.01896517994655383398949766160512808710336685180664e-01, // 0.200000
- 2.33086969755381512303671343033784069120883941650391e-01, // 0.271828
- 2.46596963941606434067566056000941898673772811889648e-01, // 0.300000
- 2.53680045527954645123713817156385630369186401367188e-01, // 0.314159
- 3.01194211912202136627314530414878390729427337646484e-01, // 0.400000
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.500000
- 4.49328964117221563157045238767750561237335205078125e-01, // 0.600000
- 5.48811636094026389365296836331253871321678161621094e-01, // 0.700000
- 6.70320046035639327541844068036880344152450561523438e-01, // 0.800000
- 8.18730753077981820986508409987436607480049133300781e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_PDF_1_05_05 = { //
- 2.70670566527359490738291469824616797268390655517578e-01, // 0.000000
- 2.70675979938689359460823879999225027859210968017578e-01, // 0.000010
- 3.30597776443173063665170730018871836364269256591797e-01, // 0.100000
- 3.46476799452803518875043664593249559402465820312500e-01, // 0.123457
- 4.03793035989310766797899532321025617420673370361328e-01, // 0.200000
- 4.66173939510763024607342686067568138241767883300781e-01, // 0.271828
- 4.93193927883212868135132112001883797347545623779297e-01, // 0.300000
- 5.07360091055909290247427634312771260738372802734375e-01, // 0.314159
- 6.02388423824404273254629060829756781458854675292969e-01, // 0.400000
- 7.35758882342884668048554885899648070335388183593750e-01, // 0.500000
- 8.98657928234443126314090477535501122474670410156250e-01, // 0.600000
- 1.09762327218805277873059367266250774264335632324219e+00, // 0.700000
- 1.34064009207127865508368813607376068830490112304688e+00, // 0.800000
- 1.63746150615596386401762174500618129968643188476562e+00, // 0.900000
- 2.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_CDF_2_05_05 = { //
- 1.76921206338193331975006117318116594105958938598633e-01, // 0.000000
- 1.76923249246490665864683933250489644706249237060547e-01, // 0.000010
- 1.99398179844168382812696904693439137190580368041992e-01, // 0.100000
- 2.05339665992123637794364299224980641156435012817383e-01, // 0.123457
- 2.26901404464795231064044855884276330471038818359375e-01, // 0.200000
- 2.50825105377308843479511324403574690222740173339844e-01, // 0.271828
- 2.61416388017453427128344856100738979876041412353516e-01, // 0.300000
- 2.67037895731317531655690800107549875974655151367188e-01, // 0.314159
- 3.06292130801829320940754541879869066178798675537109e-01, // 0.400000
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.500000
- 4.60889634482101295809286511939717456698417663574219e-01, // 0.600000
- 6.39407319161896969816893943061586469411849975585938e-01, // 0.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_PDF_2_05_05 = { //
- 2.04291012223037887762799869051377754658460617065430e-01, // 0.000000
- 2.04294733126156702329723202637978829443454742431641e-01, // 0.000010
- 2.47323003145426822957375634359777905046939849853516e-01, // 0.100000
- 2.59416327106311739303379226839751936495304107666016e-01, // 0.123457
- 3.05953791365762839404851547442376613616943359375000e-01, // 0.200000
- 3.62726274623251354611852548259776085615158081054688e-01, // 0.271828
- 3.89696542692991587664153030345914885401725769042969e-01, // 0.300000
- 4.04491116610953882481993559849797748029232025146484e-01, // 0.314159
- 5.17728195074058872293676358822267502546310424804688e-01, // 0.400000
- 7.35758882342884668048554885899648070335388183593750e-01, // 0.500000
- 1.19001191919253446194204570929287001490592956542969e+00, // 0.600000
- 2.85951646191380959294292551930993795394897460937500e+00, // 0.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_CDF_4_05_05 = { //
- 2.24170404679878587650421195576200261712074279785156e-01, // 0.000000
- 2.24171745530291038894787902790994849056005477905273e-01, // 0.000010
- 2.38933711623939531998317420402599964290857315063477e-01, // 0.100000
- 2.42851877427009699150772803477593697607517242431641e-01, // 0.123457
- 2.57198770047239844149800092054647393524646759033203e-01, // 0.200000
- 2.73490194806388475790015490929363295435905456542969e-01, // 0.271828
- 2.80881211900971317074748867526068352162837982177734e-01, // 0.300000
- 2.84858998476642533148606162285432219505310058593750e-01, // 0.314159
- 3.14022014616371969442099043590133078396320343017578e-01, // 0.400000
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.500000
- 5.12353580703692079723055030626710504293441772460938e-01, // 0.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_PDF_4_05_05 = { //
- 1.34085176585659937575911726526101119816303253173828e-01, // 0.000000
- 1.34087587639451499832432546099880710244178771972656e-01, // 0.000010
- 1.62881011401559666618155119977018330246210098266602e-01, // 0.100000
- 1.71325751629594402736245228879852220416069030761719e-01, // 0.123457
- 2.05442218066886145289018372750433627516031265258789e-01, // 0.200000
- 2.50994806945743553772132372614578343927860260009766e-01, // 0.271828
- 2.74361188164238878339773464176687411963939666748047e-01, // 0.300000
- 2.87699431311843278891160480270627886056900024414062e-01, // 0.314159
- 4.04143606154024670473745572962798178195953369140625e-01, // 0.400000
- 7.35758882342884668048554885899648070335388183593750e-01, // 0.500000
- 3.42631489815548651023391357739455997943878173828125e+00, // 0.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_CDF_M1_05_1 = { //
- 1.35335283290746816176053357594355475157499313354492e-01, // 0.000000
- 1.35340696647941433061745897248329129070043563842773e-01, // 0.000010
- 1.88875602837561828994950019477983005344867706298828e-01, // 0.100000
- 2.01098462456466814396449649393616709858179092407227e-01, // 0.123457
- 2.39651036441775794338937544125656131654977798461914e-01, // 0.200000
- 2.73726692426692841397795064040110446512699127197266e-01, // 0.271828
- 2.86504796860190091845055349040194414556026458740234e-01, // 0.300000
- 2.92801343101584787831370704225264489650726318359375e-01, // 0.314159
- 3.29192987807905568242716753957211039960384368896484e-01, // 0.400000
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.500000
- 4.02890321529133010880485699090058915317058563232422e-01, // 0.600000
- 4.34598208507078198614692610135534778237342834472656e-01, // 0.700000
- 4.63369369231175276535594775850768201053142547607422e-01, // 0.800000
- 4.89541659556953112630850455389008857309818267822266e-01, // 0.900000
- 5.13417119032592017546789975313004106283187866210938e-01, // 1.000000
- 5.35261428518990278746514377417042851448059082031250e-01, // 1.100000
- 5.55306373001950515089220061781816184520721435546875e-01, // 1.200000
- 5.73753420737432739962002870015567168593406677246094e-01, // 1.300000
- 5.90777513901231565718319416191661730408668518066406e-01, // 1.400000
- 6.06530659712633424263117376540321856737136840820312e-01, // 1.500000
- 6.21145157615451526389449554699240252375602722167969e-01, // 1.600000
- 6.34736418940281876821529749577166512608528137207031e-01, // 1.700000
- 6.47405392083911013223485042544780299067497253417969e-01, // 1.800000
- 6.59240630200443766817386403999989852309226989746094e-01, // 1.900000
- 6.70320046035639327541844068036880344152450561523438e-01, // 2.000000
- 7.32915541350616539517659475677646696567535400390625e-01, // 2.718282
- 7.59872119711751947690459019213449209928512573242188e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_PDF_M1_05_1 = { //
- 5.41341132946450809271254911436699330806732177734375e-01, // 0.000000
- 5.41341132729920015975721980794332921504974365234375e-01, // 0.000010
- 5.24654452326560716279857388144591823220252990722656e-01, // 0.100000
- 5.17363942213228455990758902771631255745887756347656e-01, // 0.123457
- 4.89083747840358629144219548834371380507946014404297e-01, // 0.200000
- 4.59489810014122646020240381403709761798381805419922e-01, // 0.271828
- 4.47663745094046994221770319200004450976848602294922e-01, // 0.300000
- 4.41727385996091959086129463685210794210433959960938e-01, // 0.314159
- 4.06411096059142717962231472483836114406585693359375e-01, // 0.400000
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.500000
- 3.32967207875316584253511109636747278273105621337891e-01, // 0.600000
- 3.01804311463248764457745210165739990770816802978516e-01, // 0.700000
- 2.74183058716671756993576991590089164674282073974609e-01, // 0.800000
- 2.49766152835180110791668539604870602488517761230469e-01, // 0.900000
- 2.28185386236707560270176031735900323837995529174805e-01, // 1.000000
- 2.09086495515230508246418139606248587369918823242188e-01, // 1.100000
- 1.92147533910709572557706792395038064569234848022461e-01, // 1.200000
- 1.77084389116491575100198474501667078584432601928711e-01, // 1.300000
- 1.63650280859066965533088477968703955411911010742188e-01, // 1.400000
- 1.51632664928158328310203728506166953593492507934570e-01, // 1.500000
- 1.40849242089671561339869754192477557808160781860352e-01, // 1.600000
- 1.31143888210802028737589353113435208797454833984375e-01, // 1.700000
- 1.22382871849510632689117528570932336151599884033203e-01, // 1.800000
- 1.14451498298688142396528633071284275501966476440430e-01, // 1.900000
- 1.07251207365702289076025977010431233793497085571289e-01, // 2.000000
- 7.07629263898439941904427996632875874638557434082031e-02, // 2.718282
- 5.73004168913721634304181407060241326689720153808594e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_CDF_M1_05_05 = { //
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000010
- 6.73794699908546092931294069217074138578027486801147e-03, // 0.100000
- 1.74223231302814106358223256165729253552854061126709e-02, // 0.123457
- 8.20849986238987999742633405730884987860918045043945e-02, // 0.200000
- 1.58913189180960978674761463480535894632339477539062e-01, // 0.271828
- 1.88875602837561828994950019477983005344867706298828e-01, // 0.300000
- 2.03609887745644979606396418603253550827503204345703e-01, // 0.314159
- 2.86504796860190091845055349040194414556026458740234e-01, // 0.400000
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.500000
- 4.34598208507078198614692610135534778237342834472656e-01, // 0.600000
- 4.89541659556953112630850455389008857309818267822266e-01, // 0.700000
- 5.35261428518990278746514377417042851448059082031250e-01, // 0.800000
- 5.73753420737432739962002870015567168593406677246094e-01, // 0.900000
- 6.06530659712633424263117376540321856737136840820312e-01, // 1.000000
- 6.34736418940281876821529749577166512608528137207031e-01, // 1.100000
- 6.59240630200443766817386403999989852309226989746094e-01, // 1.200000
- 6.80712398323385370346727540891151875257492065429688e-01, // 1.300000
- 6.99672537375130243475496172322891652584075927734375e-01, // 1.400000
- 7.16531310573789270712552479380974546074867248535156e-01, // 1.500000
- 7.31615628946641782803794740175362676382064819335938e-01, // 1.600000
- 7.45188817013480497841726446495158597826957702636719e-01, // 1.700000
- 7.57465128396966447255067578225862234830856323242188e-01, // 1.800000
- 7.68620526593735697851172972150379791855812072753906e-01, // 1.900000
- 7.78800783071404878477039801509818062186241149902344e-01, // 2.000000
- 8.31985953941138611789085643977159634232521057128906e-01, // 2.718282
- 8.52864203314464663918670339626260101795196533203125e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_PDF_M1_05_05 = { //
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000010
- 3.36897349954273117589309549657627940177917480468750e-01, // 0.100000
- 5.71540144737188726686838435853132978081703186035156e-01, // 0.123457
- 1.02606248279873502049497346888529136776924133300781e+00, // 0.200000
- 1.07532807339193881013272857671836391091346740722656e+00, // 0.271828
- 1.04930890465312143255971477628918364644050598144531e+00, // 0.300000
- 1.03149974138361355535664642957272008061408996582031e+00, // 0.314159
- 8.95327490188093988443540638400008901953697204589844e-01, // 0.400000
- 7.35758882342884668048554885899648070335388183593750e-01, // 0.500000
- 6.03608622926497528915490420331479981541633605957031e-01, // 0.600000
- 4.99532305670360443627942004241049289703369140625000e-01, // 0.700000
- 4.18172991030461016492836279212497174739837646484375e-01, // 0.800000
- 3.54168778232983150200396949003334157168865203857422e-01, // 0.900000
- 3.03265329856316656620407457012333907186985015869141e-01, // 1.000000
- 2.62287776421604057475178706226870417594909667968750e-01, // 1.100000
- 2.28902996597376284793057266142568551003932952880859e-01, // 1.200000
- 2.01394200687392110893370045232586562633514404296875e-01, // 1.300000
- 1.78487892187533275789590447857335675507783889770508e-01, // 1.400000
- 1.59229180127508751496634431532584130764007568359375e-01, // 1.500000
- 1.42893677528640961060801828352850861847400665283203e-01, // 1.600000
- 1.28925400867384215564115379493159707635641098022461e-01, // 1.700000
- 1.16892766727926894487765707708604168146848678588867e-01, // 1.800000
- 1.06457136647331848666730991226359037682414054870605e-01, // 1.900000
- 9.73500978839256236874177830031840130686759948730469e-02, // 2.000000
- 5.62985273627536753071609609833103604614734649658203e-02, // 2.718282
- 4.32066052830005001283986132420977810397744178771973e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_CDF_M2_05_05 = { //
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000010
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.123457
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.200000
- 3.39033836807548852321225751893507549539208412170410e-02, // 0.271828
- 1.06877925660385744710545452562655555084347724914551e-01, // 0.300000
- 1.38904458384038836937790506453893613070249557495117e-01, // 0.314159
- 2.74997176473929239026716686566942371428012847900391e-01, // 0.400000
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.500000
- 4.29491102067359131755353018888854421675205230712891e-01, // 0.600000
- 4.74565328167800615233318239916115999221801757812500e-01, // 0.700000
- 5.09563978801319317213369686214718967676162719726562e-01, // 0.800000
- 5.37851019311739397821270358690526336431503295898438e-01, // 0.900000
- 5.61383913798928158023215928551508113741874694824219e-01, // 1.000000
- 5.81394271093278680595517471374478191137313842773438e-01, // 1.100000
- 5.98703271909381884441359034099150449037551879882812e-01, // 1.200000
- 6.13883544062845620814528047048952430486679077148438e-01, // 1.300000
- 6.27348918610303951659545873553724959492683410644531e-01, // 1.400000
- 6.39407319161897080839196405577240511775016784667969e-01, // 1.500000
- 6.50293497809677822907303834654157981276512145996094e-01, // 1.600000
- 6.60190136880002498287467460613697767257690429687500e-01, // 1.700000
- 6.69241923627019841269714106601895764470100402832031e-01, // 1.800000
- 6.77565215323516878420662123971851542592048645019531e-01, // 1.900000
- 6.85254845275987456432176259113475680351257324218750e-01, // 2.000000
- 7.27418661477164829598507367336424067616462707519531e-01, // 2.718282
- 7.45249186715569389427571422856999561190605163574219e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_PDF_M2_05_05 = { //
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000010
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.123457
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.200000
- 2.62818951667170752628521768201608210802078247070312e+00, // 0.271828
- 2.38986307070791648143881502619478851556777954101562e+00, // 0.300000
- 2.13681596745114710245161404600366950035095214843750e+00, // 0.314159
- 1.18339942748621074208870140864746645092964172363281e+00, // 0.400000
- 7.35758882342884668048554885899648070335388183593750e-01, // 0.500000
- 5.18551760400383088267517450731247663497924804687500e-01, // 0.600000
- 3.93022345758406721483169121711398474872112274169922e-01, // 0.700000
- 3.12316331294610671776013077760580927133560180664062e-01, // 0.800000
- 2.56585417034103147049250992495217360556125640869141e-01, // 0.900000
- 2.16076769167024562712242641282500699162483215332031e-01, // 1.000000
- 1.85473713825601238536222581387846730649471282958984e-01, // 1.100000
- 1.61646472710941485617652801920485217124223709106445e-01, // 1.200000
- 1.42640237007817916037311078980565071105957031250000e-01, // 1.300000
- 1.27175191967058648367938644696550909429788589477539e-01, // 1.400000
- 1.14380658476552446445317912093742052093148231506348e-01, // 1.500000
- 1.03645098237195559809364908687712159007787704467773e-01, // 1.600000
- 9.45272529515622100815264161610684823244810104370117e-02, // 1.700000
- 8.67012981885665195980195107949839439243078231811523e-02, // 1.800000
- 7.99217885954443957308157564511930104345083236694336e-02, // 1.900000
- 7.40005675633594872664389185956679284572601318359375e-02, // 2.000000
- 4.68956249886947687532945394650596426799893379211426e-02, // 2.718282
- 3.78909810913142866550806786563043715432286262512207e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_CDF_M4_05_05 = { //
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000010
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.123457
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.271828
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.314159
- 2.24170404666470146626267023748368956148624420166016e-01, // 0.400000
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.500000
- 4.21751069637636921694223701706505380570888519287109e-01, // 0.600000
- 4.54975793697936503612311298638815060257911682128906e-01, // 0.700000
- 4.78821231609222464076225378448725678026676177978516e-01, // 0.800000
- 4.97313729450705732659798741224221885204315185546875e-01, // 0.900000
- 5.12353580703692190745357493142364546656608581542969e-01, // 1.000000
- 5.24987194441984716952731560013489797711372375488281e-01, // 1.100000
- 5.35851286369152468580523418495431542396545410156250e-01, // 1.200000
- 5.45361563592452358584239391348091885447502136230469e-01, // 1.300000
- 5.53804088898205759683435189799638465046882629394531e-01, // 1.400000
- 5.61383913798928158023215928551508113741874694824219e-01, // 1.500000
- 5.68252899326986526951088762871222570538520812988281e-01, // 1.600000
- 5.74526561677133451588872503634775057435035705566406e-01, // 1.700000
- 5.80294753258350115565633586811600252985954284667969e-01, // 1.800000
- 5.85628698455619600693466964003164321184158325195312e-01, // 1.900000
- 5.90585779600685034651519345061387866735458374023438e-01, // 2.000000
- 6.18420715153379818573853299312759190797805786132812e-01, // 2.718282
- 6.30625716653393175725739183690166100859642028808594e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GEV_PDF_M4_05_05 = { //
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000010
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.123457
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.271828
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.314159
- 3.35212941403873543322333716787397861480712890625000e+00, // 0.400000
- 7.35758882342884668048554885899648070335388183593750e-01, // 0.500000
- 4.04571752748853263881301245419308543205261230468750e-01, // 0.600000
- 2.75614208099633994919486212893389165401458740234375e-01, // 0.700000
- 2.07421967170040077999004779485403560101985931396484e-01, // 0.800000
- 1.65424119506986211369792272307677194476127624511719e-01, // 0.900000
- 1.37052595926219600297457645865506492555141448974609e-01, // 1.000000
- 1.16652409536449619409381739387754350900650024414062e-01, // 1.100000
- 1.01308142799496639363532324296102160587906837463379e-01, // 1.200000
- 8.93665252759350547950845111699891276657581329345703e-02, // 1.300000
- 7.98213076346705047159346690932579804211854934692383e-02, // 1.400000
- 7.20255897223414931485052647985867224633693695068359e-02, // 1.500000
- 6.55449235573613425698269452368549536913633346557617e-02, // 1.600000
- 6.00769361394048809210666206581663573160767555236816e-02, // 1.700000
- 5.54048234603983710822028285747364861890673637390137e-02, // 1.800000
- 5.13691711403654951983988041774864541366696357727051e-02, // 1.900000
- 4.78502036963653620826875112470588646829128265380859e-02, // 2.000000
- 3.17081485900912798947537396543339127674698829650879e-02, // 2.718282
- 2.62728789480732756456138332623595488257706165313721e-02, // 3.141593
- };
-
- public static final double[] P_QUANT = { //
- 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99, 0.999, 0.9999 //
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_1_1 = { //
- -1.22032680636784629513158506597392261028289794921875e+00, // 0.000100
- -9.32644733916065504786274686921387910842895507812500e-01, // 0.001000
- -5.27179625807901119927123545494396239519119262695312e-01, // 0.010000
- 1.65967554752044277321942900016438215970993041992188e-01, // 0.100000
- 6.73365740021719005881095654331147670745849609375000e-01, // 0.250000
- 1.36651292058166440313016209984198212623596191406250e+00, // 0.500000
- 2.24589932370723843746418424416333436965942382812500e+00, // 0.750000
- 3.25036732731244537575321373878978192806243896484375e+00, // 0.900000
- 5.60014922677657889238389543606899678707122802734375e+00, // 0.990000
- 7.90725507052371590077655127970501780509948730468750e+00, // 0.999000
- 1.02102903698928351161612226860597729682922363281250e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_2_1 = { //
- -2.20326806367846295131585065973922610282897949218750e-01, // 0.000100
- 6.73552660839344952137253130786120891571044921875000e-02, // 0.001000
- 4.72820374192098880072876454505603760480880737304688e-01, // 0.010000
- 1.16596755475204427732194290001643821597099304199219e+00, // 0.100000
- 1.67336574002171900588109565433114767074584960937500e+00, // 0.250000
- 2.36651292058166440313016209984198212623596191406250e+00, // 0.500000
- 3.24589932370723843746418424416333436965942382812500e+00, // 0.750000
- 4.25036732731244537575321373878978192806243896484375e+00, // 0.900000
- 6.60014922677657889238389543606899678707122802734375e+00, // 0.990000
- 8.90725507052371590077655127970501780509948730468750e+00, // 0.999000
- 1.12102903698928351161612226860597729682922363281250e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_4_1 = { //
- 1.77967319363215370486841493402607738971710205078125e+00, // 0.000100
- 2.06735526608393449521372531307861208915710449218750e+00, // 0.001000
- 2.47282037419209910211748137953691184520721435546875e+00, // 0.010000
- 3.16596755475204449936654782504774630069732666015625e+00, // 0.100000
- 3.67336574002171900588109565433114767074584960937500e+00, // 0.250000
- 4.36651292058166440313016209984198212623596191406250e+00, // 0.500000
- 5.24589932370723843746418424416333436965942382812500e+00, // 0.750000
- 6.25036732731244537575321373878978192806243896484375e+00, // 0.900000
- 8.60014922677657978056231513619422912597656250000000e+00, // 0.990000
- 1.09072550705237159007765512797050178050994873046875e+01, // 0.999000
- 1.32102903698928351161612226860597729682922363281250e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_4_10 = { //
- -1.82032680636784647276726900599896907806396484375000e+01, // 0.000100
- -1.53264473391606550478627468692138791084289550781250e+01, // 0.001000
- -1.12717962580790107551820256048813462257385253906250e+01, // 0.010000
- -4.34032445247955678269136114977300167083740234375000e+00, // 0.100000
- 7.33657400217190502900166393374092876911163330078125e-01, // 0.250000
- 7.66512920581664403130162099841982126235961914062500e+00, // 0.500000
- 1.64589932370723843746418424416333436965942382812500e+01, // 0.750000
- 2.65036732731244555338889767881482839584350585937500e+01, // 0.900000
- 5.00014922677657907001957937609404325485229492187500e+01, // 0.990000
- 7.30725507052371625604791915975511074066162109375000e+01, // 0.999000
- 9.61029036989283440561848692595958709716796875000000e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_01_10 = { //
- -2.21032680636784633065872185397893190383911132812500e+01, // 0.000100
- -1.92264473391606536267772753490135073661804199218750e+01, // 0.001000
- -1.51717962580790111104533934849314391613006591796875e+01, // 0.010000
- -8.24032445247955713796272902982309460639953613281250e+00, // 0.100000
- -3.16634259978280940828199163661338388919830322265625e+00, // 0.250000
- 3.76512920581664367603025311836972832679748535156250e+00, // 0.500000
- 1.25589932370723822430136351613327860832214355468750e+01, // 0.750000
- 2.26036732731244569549744483083486557006835937500000e+01, // 0.900000
- 4.61014922677657921212812652811408042907714843750000e+01, // 0.990000
- 6.91725507052371568761373055167496204376220703125000e+01, // 0.999000
- 9.22029036989283383718429831787943840026855468750000e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_01_20 = { //
- -4.43065361273569280342599085997790098190307617187500e+01, // 0.000100
- -3.85528946783213086746400222182273864746093750000000e+01, // 0.001000
- -3.04435925161580200892785796895623207092285156250000e+01, // 0.010000
- -1.65806489049591121442972507793456315994262695312500e+01, // 0.100000
- -6.43268519956561934947103509330190718173980712890625e+00, // 0.250000
- 7.43025841163328681915345441666431725025177001953125e+00, // 0.500000
- 2.50179864741447666176554776029661297798156738281250e+01, // 0.750000
- 4.51073465462489124888634250964969396591186523437500e+01, // 0.900000
- 9.21029845355315757160497014410793781280517578125000e+01, // 0.990000
- 1.38245101410474319436616497114300727844238281250000e+02, // 0.999000
- 1.84305807397856682428027852438390254974365234375000e+02, // 0.999900
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_01_4 = { //
- -8.78130722547138553579770814394578337669372558593750e+00, // 0.000100
- -7.63057893566426237441646662773564457893371582031250e+00, // 0.001000
- -6.00871850323160483497986206202767789363861083984375e+00, // 0.010000
- -3.23612978099182280189438642992172390222549438476562e+00, // 0.100000
- -1.20653703991312366561317048763157799839973449707031e+00, // 0.250000
- 1.56605168232665747929388544434914365410804748535156e+00, // 0.500000
- 5.08359729482895250640694939647801220417022705078125e+00, // 0.750000
- 9.10146930924978114774148707510903477668762207031250e+00, // 0.900000
- 1.85005969071063169906210532644763588905334472656250e+01, // 0.990000
- 2.77290202820948650241916766390204429626464843750000e+01, // 0.999000
- 3.69411614795713418857303622644394636154174804687500e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_01_1 = { //
- -2.12032680636784620631374309596139937639236450195312e+00, // 0.000100
- -1.83264473391606541596843271690886467695236206054688e+00, // 0.001000
- -1.42717962580790103110928157548187300562858581542969e+00, // 0.010000
- -7.34032445247955744882517592486692592501640319824219e-01, // 0.100000
- -2.26634259978280933056637991285242605954408645629883e-01, // 0.250000
- 4.66512920581664380925701607338851317763328552246094e-01, // 0.500000
- 1.34589932370723830423742128914454951882362365722656e+00, // 0.750000
- 2.35036732731244546457105570880230516195297241210938e+00, // 0.900000
- 4.70014922677657853711252755601890385150909423828125e+00, // 0.990000
- 7.00725507052371554550518339965492486953735351562500e+00, // 0.999000
- 9.31029036989283476088985480600968003273010253906250e+00, // 0.999900
- };
-
- public static final double[] SCIPY_GEV_QUANT_1_05_1 = { //
- -7.71034037197618182801761577138677239418029785156250e+00, // 0.000100
- -5.40775527898213681510242167860269546508789062500000e+00, // 0.001000
- -3.10517018598809135809801773575600236654281616210938e+00, // 0.010000
- -8.02585092994045457004403942846693098545074462890625e-01, // 0.100000
- 1.13705638880109427546472034009639173746109008789062e-01, // 0.250000
- 8.06852819440054713773236017004819586873054504394531e-01, // 0.500000
- 1.21231792754821920965468962094746530055999755859375e+00, // 0.750000
- 1.39463948434217366312282138096634298563003540039062e+00, // 0.900000
- 1.48994966414649843144957230833824723958969116210938e+00, // 0.990000
- 1.49899949966641643506193304347107186913490295410156e+00, // 0.999000
- 1.49989999499966675244877478689886629581451416015625e+00, // 0.999900
- };
-
- public static final double[] SCIPY_GEV_QUANT_1_05_05 = { //
- -3.60517018598809091400880788569338619709014892578125e+00, // 0.000100
- -2.45387763949106840755121083930134773254394531250000e+00, // 0.001000
- -1.30258509299404567904900886787800118327140808105469e+00, // 0.010000
- -1.51292546497022728502201971423346549272537231445312e-01, // 0.100000
- 3.06852819440054713773236017004819586873054504394531e-01, // 0.250000
- 6.53426409720027301375466777244582772254943847656250e-01, // 0.500000
- 8.56158963774109604827344810473732650279998779296875e-01, // 0.750000
- 9.47319742171086831561410690483171492815017700195312e-01, // 0.900000
- 9.94974832073249215724786154169123619794845581054688e-01, // 0.990000
- 9.99499749833208217530966521735535934567451477050781e-01, // 0.999000
- 9.99949997499833376224387393449433147907257080078125e-01, // 0.999900
- };
-
- public static final double[] SCIPY_GEV_QUANT_2_05_05 = { //
- -2.04575924419135866116903343936428427696228027343750e+01, // 0.000100
- -1.11792707485763962438340968219563364982604980468750e+01, // 0.001000
- -4.55189811047839842927942299866117537021636962890625e+00, // 0.010000
- -5.75474527619599385275250824633985757827758789062500e-01, // 0.100000
- 2.69546986081798611856186198565410450100898742675781e-01, // 0.250000
- 6.29886746520449625208470934012439101934432983398438e-01, // 0.500000
- 7.29309756297462086216398802207550033926963806152344e-01, // 0.750000
- 7.47224790435079277983732026768848299980163574218750e-01, // 0.900000
- 7.49974747687307985444249425199814140796661376953125e-01, // 0.990000
- 7.49999749749770572293527948204427957534790039062500e-01, // 0.999000
- 7.49999997499749992968531842052470892667770385742188e-01, // 0.999900
- };
-
- public static final double[] SCIPY_GEV_QUANT_4_05_05 = { //
- -8.98898954364620522028417326509952545166015625000000e+02, // 0.000100
- -2.83990001185680910111841512843966484069824218750000e+02, // 0.001000
- -5.55952471477888181539128709118813276290893554687500e+01, // 0.010000
- -2.88876544673679980235192488180473446846008300781250e+00, // 0.100000
- 1.63329802833833193087542667853995226323604583740234e-01, // 0.250000
- 5.96145612677114522526267137436661869287490844726562e-01, // 0.500000
- 6.24143827631059133764779289776924997568130493164062e-01, // 0.750000
- 6.24984596423741489701342288753949105739593505859375e-01, // 0.900000
- 6.24999998724641403491375513112870976328849792480469e-01, // 0.990000
- 6.24999999999874766842822282342240214347839355468750e-01, // 0.999000
- 6.25000000000000000000000000000000000000000000000000e-01, // 0.999900
- };
-
- public static final double[] SCIPY_GEV_QUANT_M1_05_1 = { //
- -3.91426379524187018077441280183847993612289428710938e-01, // 0.000100
- -3.55235172698916024103255040245130658149719238281250e-01, // 0.001000
- -2.82852759048374036154882560367695987224578857421875e-01, // 0.010000
- -6.57055180967481833320675832510460168123245239257812e-02, // 0.100000
- 2.21347520444481749013476701293257065117359161376953e-01, // 0.250000
- 9.42695040888963387004650940070860087871551513671875e-01, // 0.500000
- 2.97605949678220671472672620438970625400543212890625e+00, // 0.750000
- 8.99122158102990454153768951073288917541503906250000e+00, // 0.900000
- 9.89991624734220607706447481177747249603271484375000e+01, // 0.990000
- 9.98999916624973025136569049209356307983398437500000e+02, // 0.999000
- 9.99899999166735688049811869859695434570312500000000e+03, // 0.999900
- };
-
- public static final double[] SCIPY_GEV_QUANT_M1_05_05 = { //
- 5.42868102379064909612793599080760031938552856445312e-02, // 0.000100
- 7.23824136505419879483724798774346709251403808593750e-02, // 0.001000
- 1.08573620475812981922558719816152006387710571289062e-01, // 0.010000
- 2.17147240951625908333966208374476991593837738037109e-01, // 0.100000
- 3.60673760222240846751162735017715021967887878417969e-01, // 0.250000
- 7.21347520444481693502325470035430043935775756835938e-01, // 0.500000
- 1.73802974839110335736336310219485312700271606445312e+00, // 0.750000
- 4.74561079051495227076884475536644458770751953125000e+00, // 0.900000
- 4.97495812367110303853223740588873624801635742187500e+01, // 0.990000
- 4.99749958312486512568284524604678153991699218750000e+02, // 0.999000
- 4.99974999583367844024905934929847717285156250000000e+03, // 0.999900
- };
-
- public static final double[] SCIPY_GEV_QUANT_M2_05_05 = { //
- 2.52947057765806504470162963116308674216270446777344e-01, // 0.000100
- 2.55239213805878162322215985113871283829212188720703e-01, // 0.001000
- 2.61788231063225906858349389949580654501914978027344e-01, // 0.010000
- 2.97152924252903516411095097282668575644493103027344e-01, // 0.100000
- 3.80085561312850483961511827146750874817371368408203e-01, // 0.250000
- 7.70342245251401935846047308587003499269485473632812e-01, // 0.500000
- 3.27074740629244242740014669834636151790618896484375e+00, // 0.750000
- 2.27708217750519459343649941729381680488586425781250e+01, // 0.900000
- 2.47527083322811040488886646926403045654296875000000e+03, // 0.990000
- 2.49750270833332004258409142494201660156250000000000e+05, // 0.999000
- 2.49975002708388678729534149169921875000000000000000e+07, // 0.999900
- };
-
- public static final double[] SCIPY_GEV_QUANT_M4_05_05 = { //
- 3.75017370298949992424297761317575350403785705566406e-01, // 0.000100
- 3.75054898722607388261707228593877516686916351318359e-01, // 0.001000
- 3.75277924783199989811066643596859648823738098144531e-01, // 0.010000
- 3.79446796531200114532822453838889487087726593017578e-01, // 0.100000
- 4.08844506524158768367982474956079386174678802490234e-01, // 0.250000
- 9.16512104386540293887719599297270178794860839843750e-01, // 0.500000
- 1.86248297852450370726273831678554415702819824218750e+01, // 0.750000
- 1.01474982684730787241278449073433876037597656250000e+03, // 0.900000
- 1.22514566248263381421566009521484375000000000000000e+07, // 0.990000
- 1.24750145812874526977539062500000000000000000000000e+11, // 0.999000
- 1.24975001458367900000000000000000000000000000000000e+15, // 0.999900
- };
-
- @Test
- public void testPDF() {
- // Gumbel case:
- checkPDF(new GeneralizedExtremeValueDistribution(1., 1., 0.), P_CDFPDF, SCIPY_GUMBEL_PDF_1_1, 1e-12);
- checkPDF(new GeneralizedExtremeValueDistribution(2., 1., 0.), P_CDFPDF, SCIPY_GUMBEL_PDF_2_1, 1e-12);
- checkPDF(new GeneralizedExtremeValueDistribution(4., 1., 0.), P_CDFPDF, SCIPY_GUMBEL_PDF_4_1, 1e-11);
- checkPDF(new GeneralizedExtremeValueDistribution(4., 10., 0.), P_CDFPDF, SCIPY_GUMBEL_PDF_4_10, 1e-13);
- checkPDF(new GeneralizedExtremeValueDistribution(.1, 1., 0.), P_CDFPDF, SCIPY_GUMBEL_PDF_01_1, 1e-12);
- checkPDF(new GeneralizedExtremeValueDistribution(.1, 4., 0.), P_CDFPDF, SCIPY_GUMBEL_PDF_01_4, 1e-12);
- checkPDF(new GeneralizedExtremeValueDistribution(.1, 10., 0.), P_CDFPDF, SCIPY_GUMBEL_PDF_01_10, 1e-13);
- checkPDF(new GeneralizedExtremeValueDistribution(.1, 20., 0.), P_CDFPDF, SCIPY_GUMBEL_PDF_01_20, 1e-14);
- // Regular:
- checkPDF(new GeneralizedExtremeValueDistribution(.5, 1, -1.), P_CDFPDF, SCIPY_GEV_PDF_1_05_1, 1e-13);
- checkPDF(new GeneralizedExtremeValueDistribution(.5, .5, -1.), P_CDFPDF, SCIPY_GEV_PDF_1_05_05, 1e-12);
- checkPDF(new GeneralizedExtremeValueDistribution(.5, .5, -2.), P_CDFPDF, SCIPY_GEV_PDF_2_05_05, 1e-12);
- checkPDF(new GeneralizedExtremeValueDistribution(.5, .5, -4.), P_CDFPDF, SCIPY_GEV_PDF_4_05_05, 1e-12);
- checkPDF(new GeneralizedExtremeValueDistribution(.5, 1, 1.), P_CDFPDF, SCIPY_GEV_PDF_M1_05_1, 1e-12);
- checkPDF(new GeneralizedExtremeValueDistribution(.5, .5, 1.), P_CDFPDF, SCIPY_GEV_PDF_M1_05_05, 1e-12);
- checkPDF(new GeneralizedExtremeValueDistribution(.5, .5, 2.), P_CDFPDF, SCIPY_GEV_PDF_M2_05_05, 1e-12);
- checkPDF(new GeneralizedExtremeValueDistribution(.5, .5, 4.), P_CDFPDF, SCIPY_GEV_PDF_M4_05_05, 1e-12);
- }
-
- @Test
- public void testCDF() {
- // Gumbel case.
- checkCDF(new GeneralizedExtremeValueDistribution(1., 1., 0.), P_CDFPDF, SCIPY_GUMBEL_CDF_1_1, 1e-12);
- checkCDF(new GeneralizedExtremeValueDistribution(2., 1., 0.), P_CDFPDF, SCIPY_GUMBEL_CDF_2_1, 1e-12);
- checkCDF(new GeneralizedExtremeValueDistribution(4., 1., 0.), P_CDFPDF, SCIPY_GUMBEL_CDF_4_1, 1e-11);
- checkCDF(new GeneralizedExtremeValueDistribution(4., 10., 0.), P_CDFPDF, SCIPY_GUMBEL_CDF_4_10, 1e-12);
- checkCDF(new GeneralizedExtremeValueDistribution(.1, 1., 0.), P_CDFPDF, SCIPY_GUMBEL_CDF_01_1, 1e-13);
- checkCDF(new GeneralizedExtremeValueDistribution(.1, 4., 0.), P_CDFPDF, SCIPY_GUMBEL_CDF_01_4, 1e-13);
- checkCDF(new GeneralizedExtremeValueDistribution(.1, 10., 0.), P_CDFPDF, SCIPY_GUMBEL_CDF_01_10, 1e-13);
- checkCDF(new GeneralizedExtremeValueDistribution(.1, 20., 0.), P_CDFPDF, SCIPY_GUMBEL_CDF_01_20, 1e-13);
- // Regular:
- checkCDF(new GeneralizedExtremeValueDistribution(.5, 1., -1.), P_CDFPDF, SCIPY_GEV_CDF_1_05_1, 1e-13);
- checkCDF(new GeneralizedExtremeValueDistribution(.5, .5, -1.), P_CDFPDF, SCIPY_GEV_CDF_1_05_05, 1e-12);
- checkCDF(new GeneralizedExtremeValueDistribution(.5, .5, -2.), P_CDFPDF, SCIPY_GEV_CDF_2_05_05, 1e-12);
- checkCDF(new GeneralizedExtremeValueDistribution(.5, .5, -4.), P_CDFPDF, SCIPY_GEV_CDF_4_05_05, 1e-13);
- checkCDF(new GeneralizedExtremeValueDistribution(.5, 1., 1.), P_CDFPDF, SCIPY_GEV_CDF_M1_05_1, 1e-12);
- checkCDF(new GeneralizedExtremeValueDistribution(.5, .5, 1.), P_CDFPDF, SCIPY_GEV_CDF_M1_05_05, 1e-12);
- checkCDF(new GeneralizedExtremeValueDistribution(.5, .5, 2.), P_CDFPDF, SCIPY_GEV_CDF_M2_05_05, 1e-12);
- checkCDF(new GeneralizedExtremeValueDistribution(.5, .5, 4.), P_CDFPDF, SCIPY_GEV_CDF_M4_05_05, 1e-13);
- }
-
- @Test
- public void testQuantile() {
- // Gumbel case:
- checkQuantile(new GeneralizedExtremeValueDistribution(1., 1., 0.), P_QUANT, SCIPY_GUMBEL_QUANT_1_1, 1e-13);
- checkQuantile(new GeneralizedExtremeValueDistribution(2., 1., 0.), P_QUANT, SCIPY_GUMBEL_QUANT_2_1, 1e-13);
- checkQuantile(new GeneralizedExtremeValueDistribution(4., 1., 0.), P_QUANT, SCIPY_GUMBEL_QUANT_4_1, 1e-13);
- checkQuantile(new GeneralizedExtremeValueDistribution(4., 10., 0.), P_QUANT, SCIPY_GUMBEL_QUANT_4_10, 1e-13);
- checkQuantile(new GeneralizedExtremeValueDistribution(.1, 1., 0.), P_QUANT, SCIPY_GUMBEL_QUANT_01_1, 1e-13);
- checkQuantile(new GeneralizedExtremeValueDistribution(.1, 4., 0.), P_QUANT, SCIPY_GUMBEL_QUANT_01_4, 1e-13);
- checkQuantile(new GeneralizedExtremeValueDistribution(.1, 10., 0.), P_QUANT, SCIPY_GUMBEL_QUANT_01_10, 1e-13);
- checkQuantile(new GeneralizedExtremeValueDistribution(.1, 20., 0.), P_QUANT, SCIPY_GUMBEL_QUANT_01_20, 1e-13);
- // Regular:
- checkQuantile(new GeneralizedExtremeValueDistribution(.5, 1., -1.), P_QUANT, SCIPY_GEV_QUANT_1_05_1, 1e-13);
- checkQuantile(new GeneralizedExtremeValueDistribution(.5, .5, -1.), P_QUANT, SCIPY_GEV_QUANT_1_05_05, 1e-13);
- checkQuantile(new GeneralizedExtremeValueDistribution(.5, .5, -2.), P_QUANT, SCIPY_GEV_QUANT_2_05_05, 1e-13);
- checkQuantile(new GeneralizedExtremeValueDistribution(.5, .5, -4.), P_QUANT, SCIPY_GEV_QUANT_4_05_05, 1e-13);
- checkQuantile(new GeneralizedExtremeValueDistribution(.5, 1., 1.), P_QUANT, SCIPY_GEV_QUANT_M1_05_1, 1e-13);
- checkQuantile(new GeneralizedExtremeValueDistribution(.5, .5, 1.), P_QUANT, SCIPY_GEV_QUANT_M1_05_05, 1e-15);
- checkQuantile(new GeneralizedExtremeValueDistribution(.5, .5, 2.), P_QUANT, SCIPY_GEV_QUANT_M2_05_05, 1e-14);
- checkQuantile(new GeneralizedExtremeValueDistribution(.5, .5, 4.), P_QUANT, SCIPY_GEV_QUANT_M4_05_05, 1e-14);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGeneralizedLogisticDistribution.java b/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGeneralizedLogisticDistribution.java
deleted file mode 100644
index 3aa83362..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGeneralizedLogisticDistribution.java
+++ /dev/null
@@ -1,364 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for the Generalized Logistic distribution in ELKI.
- *
- * The reference values were computed using GNU R and SciPy.
- *
- * @author Erich Schubert
- */
-public class TestGeneralizedLogisticDistribution extends AbstractDistributionTest implements JUnit4Test {
- public static final double[] P_CDFPDF = { //
- 1e-10, 1e-05, 0.1, 0.1234567, 0.2, 0.271828182846, 0.3, 0.314159265359, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.71828182846, 3.14159265359 //
- };
-
- public static final double[] SCIPY_LOGISTIC_CDF_05 = { //
- 3.77540668821645775121709220911725424230098724365234e-01, // 0.000000
- 3.77543018838145283400109519789111800491809844970703e-01, // 0.000010
- 4.01312339887547997463457249978091567754745483398438e-01, // 0.100000
- 4.06960880864213336849388724658638238906860351562500e-01, // 0.123457
- 4.25557483188341023616629854586790315806865692138672e-01, // 0.200000
- 4.43203246664875705196351418635458685457706451416016e-01, // 0.271828
- 4.50166002687522159853017456043744459748268127441406e-01, // 0.300000
- 4.53673071561317309274841136357281357049942016601562e-01, // 0.314159
- 4.75020812521059987432181515032425522804260253906250e-01, // 0.400000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 5.24979187478939901545516022451920434832572937011719e-01, // 0.600000
- 5.49833997312477840146982543956255540251731872558594e-01, // 0.700000
- 5.74442516811659031894521376671036705374717712402344e-01, // 0.800000
- 5.98687660112452002536542750021908432245254516601562e-01, // 0.900000
- 6.22459331201854593196287623868556693196296691894531e-01, // 1.000000
- 6.45656306225795395548061605950351804494857788085938e-01, // 1.100000
- 6.68187772168166160824398502882104367017745971679688e-01, // 1.200000
- 6.89974481127612504494095446716528385877609252929688e-01, // 1.300000
- 7.10949502625003892930521942616906017065048217773438e-01, // 1.400000
- 7.31058578630004896048433238320285454392433166503906e-01, // 1.500000
- 7.50260105595117687826700603181961923837661743164062e-01, // 1.600000
- 7.68524783499017538623832024313742294907569885253906e-01, // 1.700000
- 7.85834983042558610222272363898809999227523803710938e-01, // 1.800000
- 8.02183888558581692507232219213619828224182128906250e-01, // 1.900000
- 8.17574476193643651100728675373829901218414306640625e-01, // 2.000000
- 9.01879254389253204315934908663621172308921813964844e-01, // 2.718282
- 9.33490913616609740977025921893073245882987976074219e-01, // 3.141593
- };
-
- public static final double[] SCIPY_LOGISTIC_PDF_05 = { //
- 2.35003712207350168306163595843827351927757263183594e-01, // 0.000000
- 2.35004287764725150466915692959446460008621215820312e-01, // 0.000010
- 2.40260745741529169183792191688553430140018463134766e-01, // 0.100000
- 2.41343722310436908928821253539354074746370315551758e-01, // 0.123457
- 2.44458311690745860866869065830542240291833877563477e-01, // 0.200000
- 2.46774128810589049587420618081523571163415908813477e-01, // 0.271828
- 2.47516572711860005640005510940682142972946166992188e-01, // 0.300000
- 2.47853815701437218965708098039613105356693267822266e-01, // 0.314159
- 2.49376040192891945679320997442118823528289794921875e-01, // 0.400000
- 2.50000000000000000000000000000000000000000000000000e-01, // 0.500000
- 2.49376040192891945679320997442118823528289794921875e-01, // 0.600000
- 2.47516572711859950128854279682855121791362762451172e-01, // 0.700000
- 2.44458311690745888622444681459455750882625579833984e-01, // 0.800000
- 2.40260745741529169183792191688553430140018463134766e-01, // 0.900000
- 2.35003712201594494590750628049136139452457427978516e-01, // 1.000000
- 2.28784240456657267381856968313513789325952529907227e-01, // 1.100000
- 2.21712873293109097305730870175466407090425491333008e-01, // 1.200000
- 2.13909696520294428934150232635147403925657272338867e-01, // 1.300000
- 2.05500307342263432985873805591836571693420410156250e-01, // 1.400000
- 1.96611933241481878775758218580449465662240982055664e-01, // 1.500000
- 1.87369879547520601370536041940795257687568664550781e-01, // 1.600000
- 1.77894440646805707118005557276774197816848754882812e-01, // 1.700000
- 1.68298362469060241997098614774586167186498641967773e-01, // 1.800000
- 1.58684897495614651852235965634463354945182800292969e-01, // 1.900000
- 1.49146452070332835582178176991874352097511291503906e-01, // 2.000000
- 8.84930648915379924890345364474342204630374908447266e-02, // 2.718282
- 6.20856278118370533136705091692419955506920814514160e-02, // 3.141593
- };
-
- public static final double[] GNUR_LOGISTIC_CDF_05 = { //
- 3.77540668821645775121709220911725424230098724365234e-01, // 0.000000
- 3.77543018838145283400109519789111800491809844970703e-01, // 0.000010
- 4.01312339887547997463457249978091567754745483398438e-01, // 0.100000
- 4.06960880864213336849388724658638238906860351562500e-01, // 0.123457
- 4.25557483188341023616629854586790315806865692138672e-01, // 0.200000
- 4.43203246664899241924473471954115666449069976806641e-01, // 0.271828
- 4.50166002687522159853017456043744459748268127441406e-01, // 0.300000
- 4.53673071561322416300754412077367305755615234375000e-01, // 0.314159
- 4.75020812521059987432181515032425522804260253906250e-01, // 0.400000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 5.24979187478939901545516022451920434832572937011719e-01, // 0.600000
- 5.49833997312477840146982543956255540251731872558594e-01, // 0.700000
- 5.74442516811659031894521376671036705374717712402344e-01, // 0.800000
- 5.98687660112452002536542750021908432245254516601562e-01, // 0.900000
- 6.22459331201854593196287623868556693196296691894531e-01, // 1.000000
- 6.45656306225795395548061605950351804494857788085938e-01, // 1.100000
- 6.68187772168166160824398502882104367017745971679688e-01, // 1.200000
- 6.89974481127612504494095446716528385877609252929688e-01, // 1.300000
- 7.10949502625003892930521942616906017065048217773438e-01, // 1.400000
- 7.31058578630004896048433238320285454392433166503906e-01, // 1.500000
- 7.50260105595117687826700603181961923837661743164062e-01, // 1.600000
- 7.68524783499017538623832024313742294907569885253906e-01, // 1.700000
- 7.85834983042558610222272363898809999227523803710938e-01, // 1.800000
- 8.02183888558581692507232219213619828224182128906250e-01, // 1.900000
- 8.17574476193643651100728675373829901218414306640625e-01, // 2.000000
- 9.01879254389337470243503958045039325952529907226562e-01, // 2.718282
- 9.33490913616622508541809111193288117647171020507812e-01, // 3.141593
- };
-
- public static final double[] GNUR_LOGISTIC_PDF_05 = { //
- 2.35003712207350168306163595843827351927757263183594e-01, // 0.000000
- 2.35004287764725178222491308588359970599412918090820e-01, // 0.000010
- 2.40260745741529169183792191688553430140018463134766e-01, // 0.100000
- 2.41343722310436908928821253539354074746370315551758e-01, // 0.123457
- 2.44458311690745888622444681459455750882625579833984e-01, // 0.200000
- 2.46774128810591714122679718457220587879419326782227e-01, // 0.271828
- 2.47516572711859977884429895311768632382154464721680e-01, // 0.300000
- 2.47853815701437635299342332473315764218568801879883e-01, // 0.314159
- 2.49376040192891945679320997442118823528289794921875e-01, // 0.400000
- 2.50000000000000000000000000000000000000000000000000e-01, // 0.500000
- 2.49376040192891945679320997442118823528289794921875e-01, // 0.600000
- 2.47516572711859950128854279682855121791362762451172e-01, // 0.700000
- 2.44458311690745888622444681459455750882625579833984e-01, // 0.800000
- 2.40260745741529169183792191688553430140018463134766e-01, // 0.900000
- 2.35003712201594494590750628049136139452457427978516e-01, // 1.000000
- 2.28784240456657267381856968313513789325952529907227e-01, // 1.100000
- 2.21712873293109097305730870175466407090425491333008e-01, // 1.200000
- 2.13909696520294428934150232635147403925657272338867e-01, // 1.300000
- 2.05500307342263432985873805591836571693420410156250e-01, // 1.400000
- 1.96611933241481878775758218580449465662240982055664e-01, // 1.500000
- 1.87369879547520601370536041940795257687568664550781e-01, // 1.600000
- 1.77894440646805707118005557276774197816848754882812e-01, // 1.700000
- 1.68298362469060241997098614774586167186498641967773e-01, // 1.800000
- 1.58684897495614651852235965634463354945182800292969e-01, // 1.900000
- 1.49146452070332835582178176991874352097511291503906e-01, // 2.000000
- 8.84930648914700607177152846816170495003461837768555e-02, // 2.718282
- 6.20856278118259094500608341604674933478236198425293e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GLOGISTIC_CDF_2_05 = { //
- 1.42536956614295634571121240696811582893133163452148e-01, // 0.000000
- 1.42538731073420105177618211200751829892396926879883e-01, // 0.000010
- 1.61051594146018856035240673918451648205518722534180e-01, // 0.100000
- 1.65617158553776427920567471119284164160490036010742e-01, // 0.123457
- 1.81099171497595134994185173127334564924240112304688e-01, // 0.200000
- 1.96429117854286627853355184925021603703498840332031e-01, // 0.271828
- 2.02649429975662181968587560731975827366113662719727e-01, // 0.300000
- 2.05819255859880118064708653946581762284040451049805e-01, // 0.314159
- 2.25644772328168013997284901961393188685178756713867e-01, // 0.400000
- 2.50000000000000000000000000000000000000000000000000e-01, // 0.500000
- 2.75603147286047955866195025009801611304283142089844e-01, // 0.600000
- 3.02317424600617945529279495531227439641952514648438e-01, // 0.700000
- 3.29984205120913143272076695211580954492092132568359e-01, // 0.800000
- 3.58426914370922833352750558333355002105236053466797e-01, // 0.900000
- 3.87455619000260098605536995819420553743839263916016e-01, // 1.000000
- 4.16872065769138100410629022007924504578113555908203e-01, // 1.100000
- 4.46474898875057091274243248335551470518112182617188e-01, // 1.200000
- 4.76064784607318047804369598452467471361160278320312e-01, // 1.300000
- 5.05449195282740459944648137025069445371627807617188e-01, // 1.400000
- 5.34446645388523045028250635368749499320983886718750e-01, // 1.500000
- 5.62890226047597086456164561241166666150093078613281e-01, // 1.600000
- 5.90630342852211831505826467036968097090721130371094e-01, // 1.700000
- 6.17536620573498451491900596010964363813400268554688e-01, // 1.800000
- 6.43498991062967040654996253579156473278999328613281e-01, // 1.900000
- 6.68428024123310704496248035866301506757736206054688e-01, // 2.000000
- 8.13386189497715239582475987845100462436676025390625e-01, // 2.718282
- 8.71405285804772722357824932259973138570785522460938e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GLOGISTIC_PDF_2_05 = { //
- 1.77446917364665113225896675430703908205032348632812e-01, // 0.000000
- 1.77448456485205074972810734834638424217700958251953e-01, // 0.000010
- 1.92839204113320589195623711020743940025568008422852e-01, // 0.100000
- 1.96434907645006984200364286152762360870838165283203e-01, // 0.123457
- 2.08062127735169605236009715554246213287115097045898e-01, // 0.200000
- 2.18742190163498606558789560949662700295448303222656e-01, // 0.271828
- 2.22847092273226854430845378374215215444564819335938e-01, // 0.300000
- 2.24889203734927378697250333061674609780311584472656e-01, // 0.314159
- 2.36917618471424035186956302823091391474008560180664e-01, // 0.400000
- 2.50000000000000000000000000000000000000000000000000e-01, // 0.500000
- 2.61834461914359772904958845174405723810195922851562e-01, // 0.600000
- 2.72186053150493101338014412249322049319744110107422e-01, // 0.700000
- 2.80854495646322144253304031735751777887344360351562e-01, // 0.800000
- 2.87682287369737721416385056727449409663677215576172e-01, // 0.900000
- 2.92560507053915230812890513334423303604125976562500e-01, // 1.000000
- 2.95431975231839061279970337636768817901611328125000e-01, // 1.100000
- 2.96291661733450895077623954421142116189002990722656e-01, // 1.200000
- 2.95184463729510404572664583611185662448406219482422e-01, // 1.300000
- 2.92200682588535265438167698448523879051208496093750e-01, // 1.400000
- 2.87469680914430258944491924921749159693717956542969e-01, // 1.500000
- 2.81152291229334549971241585808456875383853912353516e-01, // 1.600000
- 2.73432572967530318486240048514446243643760681152344e-01, // 1.700000
- 2.64509481633928678068201634232536889612674713134766e-01, // 1.800000
- 2.54588936257104159199826654003118164837360382080078e-01, // 1.900000
- 2.43876664855085467653594832881935872137546539306641e-01, // 2.000000
- 1.59620118766000157473072817992942873388528823852539e-01, // 2.718282
- 1.15912738857065128472711990070820320397615432739258e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GLOGISTIC_CDF_05_05 = { //
- 6.14443381298591106975948150648036971688270568847656e-01, // 0.000000
- 6.14445293608914644423180106969084590673446655273438e-01, // 0.000010
- 6.33492178237070269197772631741827353835105895996094e-01, // 0.100000
- 6.37934856285666040953685751446755602955818176269531e-01, // 0.123457
- 6.52347670485869834955394708231324329972267150878906e-01, // 0.200000
- 6.65735117494094419399175421858672052621841430664062e-01, // 0.271828
- 6.70944112939015346874782608210807666182518005371094e-01, // 0.300000
- 6.73552575202053027680904051521793007850646972656250e-01, // 0.314159
- 6.89217536428854971042312627105275169014930725097656e-01, // 0.400000
- 7.07106781186547572737310929369414225220680236816406e-01, // 0.500000
- 7.24554475163144640070811419718666002154350280761719e-01, // 0.600000
- 7.41507921274262460364923299493966624140739440917969e-01, // 0.700000
- 7.57919861734510202921910604345612227916717529296875e-01, // 0.800000
- 7.73749093771651574868997158773709088563919067382812e-01, // 0.900000
- 7.88960918678393463565612364618573337793350219726562e-01, // 1.000000
- 8.03527414731940226033657381776720285415649414062500e-01, // 1.100000
- 8.17427533282410356818559193925466388463973999023438e-01, // 1.200000
- 8.30647025593670873533369558572303503751754760742188e-01, // 1.300000
- 8.43178215222027627184786524594528600573539733886719e-01, // 1.400000
- 8.55019636400243698837186911987373605370521545410156e-01, // 1.500000
- 8.66175562801859255657177527609746903181076049804688e-01, // 1.600000
- 8.76655453127976325156112125114304944872856140136719e-01, // 1.700000
- 8.86473340288673639086880484683206304907798767089844e-01, // 1.800000
- 8.95647189778755237199447947205044329166412353515625e-01, // 1.900000
- 9.04198250492470045891479912825161591172218322753906e-01, // 2.000000
- 9.49673235586458552859312476357445120811462402343750e-01, // 2.718282
- 9.66173335181948478300739679980324581265449523925781e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GLOGISTIC_PDF_05_05 = { //
- 1.91233008085043759693988363324024248868227005004883e-01, // 0.000000
- 1.91232881274457228171215206202759873121976852416992e-01, // 0.000010
- 1.89631974944145992312272142044093925505876541137695e-01, // 0.100000
- 1.89160162618833033176812818965117912739515304565430e-01, // 0.123457
- 1.87368118835062935634283576291636563837528228759766e-01, // 0.200000
- 1.85339576000944639133649616269394755363464355468750e-01, // 0.271828
- 1.84453941795266723735480240975448396056890487670898e-01, // 0.300000
- 1.83989954776051262141933761995460372418165206909180e-01, // 0.314159
- 1.80912431135328455322763829826726578176021575927734e-01, // 0.400000
- 1.76776695296636865428752116713440045714378356933594e-01, // 0.500000
- 1.72089227753883550198210627968364860862493515014648e-01, // 0.600000
- 1.66900828440584320100370518957788590341806411743164e-01, // 0.700000
- 1.61269234409096795523907985625555738806724548339844e-01, // 0.800000
- 1.55257529653685638626470222334319259971380233764648e-01, // 0.900000
- 1.48932416446719950720023462054086849093437194824219e-01, // 1.000000
- 1.42362436092476424276398461188364308327436447143555e-01, // 1.100000
- 1.35616225454758571045132953258871566504240036010742e-01, // 1.200000
- 1.28760887554741604299479718065413180738687515258789e-01, // 1.300000
- 1.21860541242844275244827656479174038395285606384277e-01, // 1.400000
- 1.14975098156368985002906413228629389777779579162598e-01, // 1.500000
- 1.08159296795112963573970432662463281303644180297852e-01, // 1.600000
- 1.01462005404782576456490517102793091908097267150879e-01, // 1.700000
- 9.49257889776217583799322596860292833298444747924805e-02, // 1.800000
- 8.85867221527336656805573511519469320774078369140625e-02, // 1.900000
- 8.24744197354399105615030407534504774957895278930664e-02, // 2.000000
- 4.65913229811568962990264708423637785017490386962891e-02, // 2.718282
- 3.21296529054722751483907927649852354079484939575195e-02, // 3.141593
- };
-
- public static final double[] P_QUANT = { //
- 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99, 0.999, 0.9999 //
- };
-
- public static final double[] SCIPY_LOGISTIC_QUANT_05 = { //
- -8.71024036697584946864481025841087102890014648437500e+00, // 0.000100
- -6.40675477864855391629816949716769158840179443359375e+00, // 0.001000
- -4.09511985013458978954759004409424960613250732421875e+00, // 0.010000
- -1.69722457733621956421643517387565225362777709960938e+00, // 0.100000
- -5.98612288668109782108217586937826126813888549804688e-01, // 0.250000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 1.59861228866811000415282251196913421154022216796875e+00, // 0.750000
- 2.69722457733621912012722532381303608417510986328125e+00, // 0.900000
- 5.09511985013458357229865214321762323379516601562500e+00, // 0.990000
- 7.40675477864846509845619948464445769786834716796875e+00, // 0.999000
- 9.71024036697667902728881017537787556648254394531250e+00, // 0.999900
- };
-
- public static final double[] GNUR_LOGISTIC_QUANT_05 = { //
- -8.71024036697584946864481025841087102890014648437500e+00, // 0.000100
- -6.40675477864855391629816949716769158840179443359375e+00, // 0.001000
- -4.09511985013458978954759004409424960613250732421875e+00, // 0.010000
- -1.69722457733621912012722532381303608417510986328125e+00, // 0.100000
- -5.98612288668109782108217586937826126813888549804688e-01, // 0.250000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 1.59861228866810978210821758693782612681388854980469e+00, // 0.750000
- 2.69722457733621956421643517387565225362777709960938e+00, // 0.900000
- 5.09511985013458890136917034396901726722717285156250e+00, // 0.990000
- 7.40675477864855302811974979704245924949645996093750e+00, // 0.999000
- 9.71024036697595960276885307393968105316162109375000e+00, // 0.999900
- };
-
- public static final double[] SCIPY_GLOGISTIC_QUANT_2_05 = { //
- -4.09511985013458978954759004409424960613250732421875e+00, // 0.000100
- -2.92174406546798248740515191457234323024749755859375e+00, // 0.001000
- -1.69722457733621956421643517387565225362777709960938e+00, // 0.010000
- -2.71162138430851129555776424240320920944213867187500e-01, // 0.100000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.250000
- 1.38137358701954271467116086569149047136306762695312e+00, // 0.500000
- 2.36626404125887201956857097684405744075775146484375e+00, // 0.750000
- 3.41705874790017549713638800312764942646026611328125e+00, // 0.900000
- 5.79078277119367168523922373424284160137176513671875e+00, // 0.990000
- 8.10015211557315417678637459175661206245422363281250e+00, // 0.999000
- 1.04034125490967461757918499642983078956604003906250e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GLOGISTIC_QUANT_05_05 = { //
- -1.79206807339523663813452003523707389831542968750000e+01, // 0.000100
- -1.33155095579637734459765852079726755619049072265625e+01, // 0.001000
- -8.71024036697584946864481025841087102890014648437500e+00, // 0.010000
- -4.09511985013458978954759004409424960613250732421875e+00, // 0.100000
- -2.20805020110221006390816000930499285459518432617188e+00, // 0.250000
- -5.98612288668109782108217586937826126813888549804688e-01, // 0.500000
- 7.51314428280906221324642046965891495347023010253906e-01, // 0.750000
- 1.95001017550599864414095918618841096758842468261719e+00, // 0.900000
- 4.39693487554469086830977175850421190261840820312500e+00, // 0.990000
- 6.71310722279666993728142188047058880329132080078125e+00, // 0.999000
- 9.01704318266624582633994577918201684951782226562500e+00, // 0.999900
- };
-
- @Test
- public void testPDF() {
- checkPDF(new GeneralizedLogisticDistribution(.5, 1., 1.), P_CDFPDF, SCIPY_LOGISTIC_PDF_05, 1e-12);
- checkPDF(new GeneralizedLogisticDistribution(.5, 1., 1.), P_CDFPDF, GNUR_LOGISTIC_PDF_05, 1e-15);
- checkPDF(new GeneralizedLogisticDistribution(.5, 1., 2.), P_CDFPDF, SCIPY_GLOGISTIC_PDF_2_05, 1e-12);
- checkPDF(new GeneralizedLogisticDistribution(.5, 1., .5), P_CDFPDF, SCIPY_GLOGISTIC_PDF_05_05, 1e-12);
- }
-
- @Test
- public void testCDF() {
- checkCDF(new GeneralizedLogisticDistribution(.5, 1., 1.), P_CDFPDF, SCIPY_LOGISTIC_CDF_05, 1e-13);
- checkCDF(new GeneralizedLogisticDistribution(.5, 1., 1.), P_CDFPDF, GNUR_LOGISTIC_CDF_05, 0.);
- checkCDF(new GeneralizedLogisticDistribution(.5, 1., 2.), P_CDFPDF, SCIPY_GLOGISTIC_CDF_2_05, 1e-12);
- checkCDF(new GeneralizedLogisticDistribution(.5, 1., .5), P_CDFPDF, SCIPY_GLOGISTIC_CDF_05_05, 1e-13);
- }
-
- @Test
- public void testProbit() {
- checkQuantile(new GeneralizedLogisticDistribution(.5, 1., 1.), P_QUANT, SCIPY_LOGISTIC_QUANT_05, 0.);
- checkQuantile(new GeneralizedLogisticDistribution(.5, 1., 1.), P_QUANT, GNUR_LOGISTIC_QUANT_05, 1e-13);
- checkQuantile(new GeneralizedLogisticDistribution(.5, 1., 2.), P_QUANT, SCIPY_GLOGISTIC_QUANT_2_05, 1e-15);
- checkQuantile(new GeneralizedLogisticDistribution(.5, 1., .5), P_QUANT, SCIPY_GLOGISTIC_QUANT_05_05, 0.);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGumbelDistribution.java b/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGumbelDistribution.java
deleted file mode 100644
index 54243d79..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestGumbelDistribution.java
+++ /dev/null
@@ -1,672 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for the Gumbel distribution in ELKI.
- *
- * The reference values were computed using SciPy.
- *
- * @author Erich Schubert
- */
-public class TestGumbelDistribution extends AbstractDistributionTest implements JUnit4Test {
- public static final double[] P_CDFPDF = { //
- 1e-10, 1e-05, 0.1, 0.1234567, 0.2, 0.271828182846, 0.3, 0.314159265359, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.71828182846, 3.14159265359 //
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_1_1 = { //
- 6.59880358632499303128682299757201690226793289184570e-02, // 0.000000
- 6.59898296015106466949617924910853616893291473388672e-02, // 0.000010
- 8.54688658759459179981021748062630649656057357788086e-02, // 0.100000
- 9.04841721928088676962786962576501537114381790161133e-02, // 0.123457
- 1.08008977696591554340521668109431630000472068786621e-01, // 0.200000
- 1.26023050723474722145667215045250486582517623901367e-01, // 0.271828
- 1.33486796658083856081944418292550835758447647094727e-01, // 0.300000
- 1.37320130159857167750914186399313621222972869873047e-01, // 0.314159
- 1.61682814145126474425495644027250818908214569091797e-01, // 0.400000
- 1.92295645547964910715421638087718747556209564208984e-01, // 0.500000
- 2.24961793549918465107140264080953784286975860595703e-01, // 0.600000
- 2.59276865990827554142583721841219812631607055664062e-01, // 0.700000
- 2.94816320729158143354453613937948830425739288330078e-01, // 0.800000
- 3.31154277152908960157873252683202736079692840576172e-01, // 0.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 1.000000
- 4.04607661664131867951255117077380418777465820312500e-01, // 1.100000
- 4.40991025942982617369381159733165986835956573486328e-01, // 1.200000
- 4.76723690714594083850386141421040520071983337402344e-01, // 1.300000
- 5.11544833689041578139722332707606256008148193359375e-01, // 1.400000
- 5.45239211892605046827497972117271274328231811523438e-01, // 1.500000
- 5.77635844258915676086019175272667780518531799316406e-01, // 1.600000
- 6.08605317804406409365469698968809098005294799804688e-01, // 1.700000
- 6.38056166582018691180167024867841973900794982910156e-01, // 1.800000
- 6.65930705440122117089174480497604236006736755371094e-01, // 1.900000
- 6.92200627555346392760782237019157037138938903808594e-01, // 2.000000
- 8.35793188453588298258978284138720482587814331054688e-01, // 2.718282
- 8.89169312582892001906031964608700945973396301269531e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_1_1 = { //
- 1.79374078764838684740823282481869682669639587402344e-01, // 0.000000
- 1.79377160888317427334115450321405660361051559448242e-01, // 0.000010
- 2.10219488415532645975147829631168860942125320434570e-01, // 0.100000
- 2.17395492872112461313349740521516650915145874023438e-01, // 0.123457
- 2.40378400508394624024433028353087138384580612182617e-01, // 0.200000
- 2.61030341003925192566725854703690856695175170898438e-01, // 0.271828
- 2.68809398181777348124654736238881014287471771240234e-01, // 0.300000
- 2.72640929007956611673790803251904435455799102783203e-01, // 0.314159
- 2.94605295353879470532376672053942456841468811035156e-01, // 0.400000
- 3.17041921077942157047857563156867399811744689941406e-01, // 0.500000
- 3.35603559643445015225893257593270391225814819335938e-01, // 0.600000
- 3.49987161158421655748895773285767063498497009277344e-01, // 0.700000
- 3.60089467289227027624320953691494651138782501220703e-01, // 0.800000
- 3.65982076505757814022246066087973304092884063720703e-01, // 0.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 1.000000
- 3.66104151897740148768889412167482078075408935546875e-01, // 1.100000
- 3.61052914770930044596752850338816642761230468750000e-01, // 1.200000
- 3.53165596312007168400270984420785680413246154785156e-01, // 1.300000
- 3.42898756467731824493228032224578782916069030761719e-01, // 1.400000
- 3.30704298890418080247854959452524781227111816406250e-01, // 1.500000
- 3.17013272754289754384871002912404946982860565185547e-01, // 1.600000
- 3.02224456630968474346587981926859356462955474853516e-01, // 1.700000
- 2.86697116378903826827695411338936537504196166992188e-01, // 1.800000
- 2.70747220321607640070027400724939070641994476318359e-01, // 1.900000
- 2.54646380043582531982337968656793236732482910156250e-01, // 2.000000
- 1.49919633191029216812140134607034269720315933227539e-01, // 2.718282
- 1.04448592925595828972973322379402816295623779296875e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_2_1 = { //
- 6.17978989787721657254981888485190211213193833827972e-04, // 0.000000
- 6.18024653604032120531031058163762281765230000019073e-04, // 0.000010
- 1.24839763464425581619698935043061283067800104618073e-03, // 0.100000
- 1.45770722707259806419366476859522663289681077003479e-03, // 0.123457
- 2.35869338329322553171607523836428299546241760253906e-03, // 0.200000
- 3.58731530475635143964674433902928285533562302589417e-03, // 0.271828
- 4.19464154138938540017367273549098172225058078765869e-03, // 0.300000
- 4.53021237372840286650177432647979003377258777618408e-03, // 0.314159
- 7.06196156220941038267335798650492506567388772964478e-03, // 0.400000
- 1.13142863804596271321001310639076109509915113449097e-02, // 0.500000
- 1.73320140087645062354493319389803218655288219451904e-02, // 0.600000
- 2.54943946757241260425708162529190303757786750793457e-02, // 0.700000
- 3.61486049131355194341530534529738361015915870666504e-02, // 0.800000
- 4.95800856955669819181586888134916080161929130554199e-02, // 0.900000
- 6.59880358453125426265728492580819875001907348632812e-02, // 1.000000
- 8.54688658759459596314655982496333308517932891845703e-02, // 1.100000
- 1.08008977696591554340521668109431630000472068786621e-01, // 1.200000
- 1.33486796658083856081944418292550835758447647094727e-01, // 1.300000
- 1.61682814145126418914344412769423797726631164550781e-01, // 1.400000
- 1.92295645547964910715421638087718747556209564208984e-01, // 1.500000
- 2.24961793549918520618291495338780805468559265136719e-01, // 1.600000
- 2.59276865990827554142583721841219812631607055664062e-01, // 1.700000
- 2.94816320729158143354453613937948830425739288330078e-01, // 1.800000
- 3.31154277152908849135570790167548693716526031494141e-01, // 1.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 2.000000
- 6.14105034982032282897534969379194080829620361328125e-01, // 2.718282
- 7.26650204627822926539693071390502154827117919921875e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_2_1 = { //
- 4.56628142304533850281966778084097313694655895233154e-03, // 0.000000
- 4.56657317004234564183917655100231058895587921142578e-03, // 0.000010
- 8.34665480722261536594697162172451498918235301971436e-03, // 0.100000
- 9.52012623739182869964103872462146682664752006530762e-03, // 0.123457
- 1.42692634455674552396153842437342973425984382629395e-02, // 0.200000
- 2.01978449671180448898866188756073825061321258544922e-02, // 0.271828
- 2.29612471247189892098461427849542815238237380981445e-02, // 0.300000
- 2.44494948372630735433652660049119731411337852478027e-02, // 0.314159
- 3.49781245974551888155978929262346355244517326354980e-02, // 0.400000
- 5.07071136099807306951703367303707636892795562744141e-02, // 0.500000
- 7.02847826336932546276159428089158609509468078613281e-02, // 0.600000
- 9.35464974266043414186100335427909158170223236083984e-02, // 0.700000
- 1.20017594905418731321411485168937360867857933044434e-01, // 0.800000
- 1.48946808910974892725675999827217310667037963867188e-01, // 0.900000
- 1.79374078734017200487116383555985521525144577026367e-01, // 1.000000
- 2.10219488415532701486299060888995882123708724975586e-01, // 1.100000
- 2.40378400508394624024433028353087138384580612182617e-01, // 1.200000
- 2.68809398181777348124654736238881014287471771240234e-01, // 1.300000
- 2.94605295353879415021225440796115435659885406494141e-01, // 1.400000
- 3.17041921077942157047857563156867399811744689941406e-01, // 1.500000
- 3.35603559643445015225893257593270391225814819335938e-01, // 1.600000
- 3.49987161158421655748895773285767063498497009277344e-01, // 1.700000
- 3.60089467289227027624320953691494651138782501220703e-01, // 1.800000
- 3.65982076505757758511094834830146282911300659179688e-01, // 1.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 2.000000
- 2.99431043346856384790299898668308742344379425048828e-01, // 2.718282
- 2.32026725020700291812758564446994569152593612670898e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_4_1 = { //
- 1.94233761556120265073609843858010169210640550320133e-24, // 0.000000
- 1.94339836960486498321475838226799834065378487714337e-24, // 0.000010
- 3.50581472625786942134053009067093603336708158078897e-22, // 0.100000
- 1.10204869082170943883948227538294176292737847487482e-21, // 0.123457
- 3.85942175009585124493227078787604613125739296999845e-20, // 0.200000
- 8.55175072212361792537222183911253732406541162804661e-19, // 0.271828
- 2.71618226092945448511767238087193692507249743561641e-18, // 0.300000
- 4.79654546206938212109880845109838654258082904740905e-18, // 0.314159
- 1.27523062451624426541224412921385568571695936319552e-16, // 0.400000
- 4.15089692010904525288672126361021019245556122612140e-15, // 0.500000
- 9.69966408521639154441452223525895873820334286419254e-14, // 0.600000
- 1.67930865740466120726981233244263965733930610291225e-12, // 0.700000
- 2.21644780341866066467927092510455566905236413077773e-11, // 0.800000
- 2.28850701972651310101286108247299871248925384747963e-10, // 0.900000
- 1.89217869483829244811168274588777937772476889222162e-09, // 1.000000
- 1.27958444708893479866928830448492837579266279135481e-08, // 1.100000
- 7.21407495654723266621612446335143342679430134012364e-08, // 1.200000
- 3.44996444807882075559481984891596617615050490712747e-07, // 1.300000
- 1.42158510896623277238609052430806656275308341719210e-06, // 1.400000
- 5.11929429867073290303346178031773661132319830358028e-06, // 1.500000
- 1.63190669761509105832684302095358930273505393415689e-05, // 1.600000
- 4.65873061192628793976758250217073964449809864163399e-05, // 1.700000
- 1.20361180348421196420645451485853527628933079540730e-04, // 1.800000
- 2.84104078721292101477463587499983077577780932188034e-04, // 1.900000
- 6.17978989331093432439689916435554550844244658946991e-04, // 2.000000
- 2.72466505377139643628847665013381629250943660736084e-02, // 2.718282
- 9.44768930014186492094552249909611418843269348144531e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_4_1 = { //
- 1.06048040538825383895657084905076034872528558503039e-22, // 0.000000
- 1.06104894703602011823679422569673096865235426708292e-22, // 0.000010
- 1.73195833587372556877622009550080809725453568188831e-20, // 0.100000
- 5.31816915757311281533262916149991462179401939316581e-20, // 0.123457
- 1.72520723688492552379661823003568327945291845918510e-18, // 0.200000
- 3.55778320603558542628503187787223104575572232312602e-17, // 0.271828
- 1.09862250605229655196224903219933069216592916588111e-16, // 0.300000
- 1.91279689150650823875815251444059610432563375858640e-16, // 0.314159
- 4.66711893658034022812779722242683120807921724748635e-15, // 0.400000
- 1.37458827543354963946170620516550599064667728677058e-13, // 0.500000
- 2.90641705075567549607614189502246106536209602211329e-12, // 0.600000
- 4.55304892645473537813182015220254180570824686924425e-11, // 0.700000
- 5.43750726676849818042246906675497505889715910143423e-10, // 0.800000
- 5.08001673311263319774744418142083113298923535694485e-09, // 0.900000
- 3.80054250404435749527446645589651152974397518846672e-08, // 1.000000
- 2.32553537538727241913236328495206972633013720042072e-07, // 1.100000
- 1.18632914440636535453432297976261722283197741489857e-06, // 1.200000
- 5.13345454477618321902391770872320364560437155887485e-06, // 1.300000
- 1.91398495015806936032053131579999671885161660611629e-05, // 1.400000
- 6.23657718766199291749591226974303026509005576372147e-05, // 1.500000
- 1.79887953645615079585964868336134259152458980679512e-04, // 1.600000
- 4.64670291311834173994532726226225349819287657737732e-04, // 1.700000
- 1.08626127745232634556893369648378211422823369503021e-03, // 1.800000
- 2.32004217969156720582923902895799983525648713111877e-03, // 1.900000
- 4.56628142012791525539139314560088678263127803802490e-03, // 2.000000
- 9.81649050447965243471060148294782266020774841308594e-02, // 2.718282
- 2.22908780675388440428719150077085942029953002929688e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_4_10 = { //
- 2.24961793553274530532704034158086869865655899047852e-01, // 0.000000
- 2.24962129153560647099041602814395446330308914184570e-01, // 0.000010
- 2.28326012057771948748907675508235115557909011840820e-01, // 0.100000
- 2.29117491320003585641984500398393720388412475585938e-01, // 0.123457
- 2.31706315790068034798920848515990655869245529174805e-01, // 0.200000
- 2.34144016800101217867791092430707067251205444335938e-01, // 0.271828
- 2.35102282543562940420045492828649003058671951293945e-01, // 0.300000
- 2.35584367949729117652779564195952843874692916870117e-01, // 0.314159
- 2.38513488532688416876581527503731194883584976196289e-01, // 0.400000
- 2.41939508585804652351924914910341612994670867919922e-01, // 0.500000
- 2.45379916339054454654799997115333098918199539184570e-01, // 0.600000
- 2.48834284427714574894352494993654545396566390991211e-01, // 0.700000
- 2.52302184674948581921682944084750488400459289550781e-01, // 0.800000
- 2.55783188277869832916167069924995303153991699218750e-01, // 0.900000
- 2.59276865990827554142583721841219812631607055664062e-01, // 1.000000
- 2.62782788305835623976491888242890127003192901611328e-01, // 1.100000
- 2.66300525630066620141889188744244165718555450439453e-01, // 1.200000
- 2.69829648460341131599449226996512152254581451416016e-01, // 1.300000
- 2.73369727554544250658352666505379602313041687011719e-01, // 1.400000
- 2.76920334099908960201474883433547802269458770751953e-01, // 1.500000
- 2.80481039878108018292834913154365494847297668457031e-01, // 1.600000
- 2.84051417427103602975080320902634412050247192382812e-01, // 1.700000
- 2.87631040199704479665143708189134486019611358642578e-01, // 1.800000
- 2.91219482718789723918462186702527105808258056640625e-01, // 1.900000
- 2.94816320729158143354453613937948830425739288330078e-01, // 2.000000
- 3.20860670367920819412432820172398351132869720458984e-01, // 2.718282
- 3.36339983908659712064093127992236986756324768066406e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_4_10 = { //
- 3.35603559645095625429966901265288470312952995300293e-02, // 0.000000
- 3.35603724701354494408533923888171557337045669555664e-02, // 0.000010
- 3.37233134553145824652276019151031505316495895385742e-02, // 0.100000
- 3.37609284733200315509193956131639424711465835571289e-02, // 0.123457
- 3.38820574854396400210632123162213247269392013549805e-02, // 0.200000
- 3.39934708099677296289087280456442385911941528320312e-02, // 0.271828
- 3.40365712424673116931472804935765452682971954345703e-02, // 0.300000
- 3.40581064819283629852009198657469823956489562988281e-02, // 0.314159
- 3.41868398883302671009687401237897574901580810546875e-02, // 0.400000
- 3.43328505356715121821231662124773720279335975646973e-02, // 0.500000
- 3.44745922233250789989966733628534711897373199462891e-02, // 0.600000
- 3.46120558908042108559044436333351768553256988525391e-02, // 0.700000
- 3.47452343518489734086607256813294952735304832458496e-02, // 0.800000
- 3.48741222670847020315143538482516305521130561828613e-02, // 0.900000
- 3.49987161158421683504471388914680574089288711547852e-02, // 1.000000
- 3.51190141671897312902750343255320331081748008728027e-02, // 1.100000
- 3.52350164502270857269650150556117296218872070312500e-02, // 1.200000
- 3.53467247236895973361292533354571787640452384948730e-02, // 1.300000
- 3.54541424449113518058140925859333947300910949707031e-02, // 1.400000
- 3.55572747381944151423560640523646725341677665710449e-02, // 1.500000
- 3.56561283626308858640818755247892113402485847473145e-02, // 1.600000
- 3.57507116794234872103608324778178939595818519592285e-02, // 1.700000
- 3.58410346187495246206289323254168266430497169494629e-02, // 1.800000
- 3.59271086462122773985683465980400796979665756225586e-02, // 1.900000
- 3.60089467289226999868745338062581140547990798950195e-02, // 2.000000
- 3.64737821185050284378270646357123041525483131408691e-02, // 2.718282
- 3.66487069582701815995129379643913125619292259216309e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_01_10 = { //
- 3.64200708229312053454407305252971127629280090332031e-01, // 0.000000
- 3.64201076086621500227380465730675496160984039306641e-01, // 0.000010
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.100000
- 3.68742364149354184821305580044281668961048126220703e-01, // 0.123457
- 3.71558174423808174058336817324743606150150299072266e-01, // 0.200000
- 3.74200337049799547362027851704624481499195098876953e-01, // 0.271828
- 3.75236541960806024853525286744115874171257019042969e-01, // 0.300000
- 3.75757321275714095687447979798889718949794769287109e-01, // 0.314159
- 3.78914181510685010856320786842843517661094665527344e-01, // 0.400000
- 3.82590734620523953424253704724833369255065917968750e-01, // 0.500000
- 3.86265846721645655925669871066929772496223449707031e-01, // 0.600000
- 3.89939167191828084391147513088071718811988830566406e-01, // 0.700000
- 3.93610349414351023966673892573453485965728759765625e-01, // 0.800000
- 3.97279050833918845331282909683068282902240753173828e-01, // 0.900000
- 4.00944933009500681375669728367938660085201263427734e-01, // 1.000000
- 4.04607661664131867951255117077380418777465820312500e-01, // 1.100000
- 4.08266906731719725343054960831068456172943115234375e-01, // 1.200000
- 4.11922342400900476366842895004083402454853057861328e-01, // 1.300000
- 4.15573647155991876545044760860037058591842651367188e-01, // 1.400000
- 4.19220503815090905774809471040498465299606323242188e-01, // 1.500000
- 4.22862599565362817788383154038456268608570098876953e-01, // 1.600000
- 4.26499625995571840508802097247098572552204132080078e-01, // 1.700000
- 4.30131279125902432625139226729515939950942993164062e-01, // 1.800000
- 4.33757259435121944601831955878878943622112274169922e-01, // 1.900000
- 4.37377271885135254780863078849506564438343048095703e-01, // 2.000000
- 4.63178277570029439669241355659323744475841522216797e-01, // 2.718282
- 4.78191805551566095910942522095865570008754730224609e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_01_10 = { //
- 3.67860986195510386576046357731684111058712005615234e-02, // 0.000000
- 3.67860989892352038821421444936277111992239952087402e-02, // 0.000010
- 3.67879441171442347902065250764280790463089942932129e-02, // 0.100000
- 3.67878429896495301454351078973559197038412094116211e-02, // 0.123457
- 3.67861108816435675161748974915099097415804862976074e-02, // 0.200000
- 3.67825446794351126889033309907972579821944236755371e-02, // 0.271828
- 3.67806360606196675044898825035488698631525039672852e-02, // 0.300000
- 3.67795687265079010441759521654603304341435432434082e-02, // 0.314159
- 3.67715575045233014628287548930529737845063209533691e-02, // 0.400000
- 3.67589137340928531760830821895069675520062446594238e-02, // 0.500000
- 3.67427439081312035007442773348884657025337219238281e-02, // 0.600000
- 3.67230877916642356462162410934979561716318130493164e-02, // 0.700000
- 3.66999857244961757984924588527064770460128784179688e-02, // 0.800000
- 3.66734785901757648352017326942586805671453475952148e-02, // 0.900000
- 3.66436077853866115638936662435298785567283630371094e-02, // 1.000000
- 3.66104151897740162646677219981938833370804786682129e-02, // 1.100000
- 3.65739431362198524899653762076923158019781112670898e-02, // 1.200000
- 3.65342343815761166903044454556948039680719375610352e-02, // 1.300000
- 3.64913320778669988952991332098463317379355430603027e-02, // 1.400000
- 3.64452797439685782787677226224332116544246673583984e-02, // 1.500000
- 3.63961212377742968082650065753114176914095878601074e-02, // 1.600000
- 3.63439007288538645790154646419978234916925430297852e-02, // 1.700000
- 3.62886626716122442926071300917101325467228889465332e-02, // 1.800000
- 3.62304517789548280459754892035562079399824142456055e-02, // 1.900000
- 3.61693129964641910123468449000938562676310539245605e-02, // 2.000000
- 3.56482034999189151269760600371228065341711044311523e-02, // 2.718282
- 3.52782829415396598227161462091316934674978256225586e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_01_20 = { //
- 3.66040051641140451454958792965044267475605010986328e-01, // 0.000000
- 3.66040235576718830934339621308026835322380065917969e-01, // 0.000010
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.100000
- 3.68310902956942021191366620769258588552474975585938e-01, // 0.123457
- 3.69718830722743807548624772607581689953804016113281e-01, // 0.200000
- 3.71040005167483422088281486139749176800251007080078e-01, // 0.271828
- 3.71558174423808174058336817324743606150150299072266e-01, // 0.300000
- 3.71818605637736554481165285324095748364925384521484e-01, // 0.314159
- 3.73397426637427698459248404105892404913902282714844e-01, // 0.400000
- 3.75236541960806024853525286744115874171257019042969e-01, // 0.500000
- 3.77075475227729051130864945662324316799640655517578e-01, // 0.600000
- 3.78914181510685010856320786842843517661094665527344e-01, // 0.700000
- 3.80752616122933373876691121040494181215763092041016e-01, // 0.800000
- 3.82590734620523953424253704724833369255065917968750e-01, // 0.900000
- 3.84428492804265664606333530173287726938724517822266e-01, // 1.000000
- 3.86265846721645655925669871066929772496223449707031e-01, // 1.100000
- 3.88102752668698702809280121073243208229541778564453e-01, // 1.200000
- 3.89939167191828084391147513088071718811988830566406e-01, // 1.300000
- 3.91775047089576777814556862722383812069892883300781e-01, // 1.400000
- 3.93610349414351023966673892573453485965728759765625e-01, // 1.500000
- 3.95445031474095209933494743381743319332599639892578e-01, // 1.600000
- 3.97279050833918845331282909683068282902240753173828e-01, // 1.700000
- 3.99112365317676576204064531339099630713462829589844e-01, // 1.800000
- 4.00944933009500681375669728367938660085201263427734e-01, // 1.900000
- 4.02776712255286439834378597879549488425254821777344e-01, // 2.000000
- 4.15907192667703928812272806680994108319282531738281e-01, // 2.718282
- 4.23619395109240293173513691726839169859886169433594e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_01_20 = { //
- 1.83937417516764276093077512541640317067503929138184e-02, // 0.000000
- 1.83937417977731651475004071016883244737982749938965e-02, // 0.000010
- 1.83939720585721173951032625382140395231544971466064e-02, // 0.100000
- 1.83939594126808145246876335932029178366065025329590e-02, // 0.123457
- 1.83937425180828485749007228378104628063738346099854e-02, // 0.200000
- 1.83932951601603437985499311935200239531695842742920e-02, // 0.271828
- 1.83930554408217837580874487457549548707902431488037e-02, // 0.300000
- 1.83929213116811943184991662292304681614041328430176e-02, // 0.314159
- 1.83919131598794319271128472337295534089207649230957e-02, // 0.400000
- 1.83903180303098337522449412517744349315762519836426e-02, // 0.500000
- 1.83882724286199075725001250702916877344250679016113e-02, // 0.600000
- 1.83857787522616507314143774465264868922531604766846e-02, // 0.700000
- 1.83828394191271268787168935432418948039412498474121e-02, // 0.800000
- 1.83794568670464265880415410947534837760031223297119e-02, // 0.900000
- 1.83756335532885978212291888667095918208360671997070e-02, // 1.000000
- 1.83713719540656017503721386674442328512668609619141e-02, // 1.100000
- 1.83666745640393841432214117048715706914663314819336e-02, // 1.200000
- 1.83615438958321178231081205467489780858159065246582e-02, // 1.300000
- 1.83559824795396266117197825451512471772730350494385e-02, // 1.400000
- 1.83499928622480878992462294263532385230064392089844e-02, // 1.500000
- 1.83435776075540693530463443039479898288846015930176e-02, // 1.600000
- 1.83367392950878824176008663471293402835726737976074e-02, // 1.700000
- 1.83294805200404052614171490631633787415921688079834e-02, // 1.800000
- 1.83218038926933057819468331217649392783641815185547e-02, // 1.900000
- 1.83137120379528138547353677267892635427415370941162e-02, // 2.000000
- 1.82436263119165158197443332710463437251746654510498e-02, // 2.718282
- 1.81927559990815723711676810125936754047870635986328e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_01_4 = { //
- 3.58683419097346689596861324389465153217315673828125e-01, // 0.000000
- 3.58684338497014365554349524245481006801128387451172e-01, // 0.000010
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.100000
- 3.70036738247086438580168987755314446985721588134766e-01, // 0.123457
- 3.77075475227729051130864945662324316799640655517578e-01, // 0.200000
- 3.83677647968239443621030204667476937174797058105469e-01, // 0.271828
- 3.86265846721645655925669871066929772496223449707031e-01, // 0.300000
- 3.87566357530248317697640914047951810061931610107422e-01, // 0.314159
- 3.95445031474095209933494743381743319332599639892578e-01, // 0.400000
- 4.04607661664131867951255117077380418777465820312500e-01, // 0.500000
- 4.13748531068576341773734839080134406685829162597656e-01, // 0.600000
- 4.22862599565362817788383154038456268608570098876953e-01, // 0.700000
- 4.31944996928375679612344129054690711200237274169922e-01, // 0.800000
- 4.40991025942982672880532390990993008017539978027344e-01, // 0.900000
- 4.49996164872620063590602512704208493232727050781250e-01, // 1.000000
- 4.58956069307663805378894039677106775343418121337891e-01, // 1.100000
- 4.67866573428437237947008497940259985625743865966797e-01, // 1.200000
- 4.76723690714594083850386141421040520071983337402344e-01, // 1.300000
- 4.85523614133279490800987332477234303951263427734375e-01, // 1.400000
- 4.94262715838446498040070764545816928148269653320312e-01, // 1.500000
- 5.02937546413495417674255349993472918868064880371094e-01, // 1.600000
- 5.11544833689041578139722332707606256008148193359375e-01, // 1.700000
- 5.20081481167105397211969375348417088389396667480469e-01, // 1.800000
- 5.28544566082388089789390051009831950068473815917969e-01, // 1.900000
- 5.36931337130553965053536558116320520639419555664062e-01, // 2.000000
- 5.94719607054730259321217999968212097883224487304688e-01, // 2.718282
- 6.26579099505278791504281343804905191063880920410156e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_01_4 = { //
- 9.19408832681790494367746191528567578643560409545898e-02, // 0.000000
- 9.19408890865627964616990652757522184401750564575195e-02, // 0.000010
- 9.19698602928605835060693607374560087919235229492188e-02, // 0.100000
- 9.19682820379929405474328518721449654549360275268555e-02, // 0.123457
- 9.19413621430995309236067214442300610244274139404297e-02, // 0.200000
- 9.18862440991995849115525629713374655693769454956055e-02, // 0.271828
- 9.18568597703280087518606933372211642563343048095703e-02, // 0.300000
- 9.18404563854176708703747067374933976680040359497070e-02, // 0.314159
- 9.17178880377703537041256254269683267921209335327148e-02, // 0.400000
- 9.15260379744350371922223530418705195188522338867188e-02, // 0.500000
- 9.12829492792362195974220639982377178966999053955078e-02, // 0.600000
- 9.09903030944357454901094683918927330523729324340820e-02, // 0.700000
- 9.06498150644146627463726417772704735398292541503906e-02, // 0.800000
- 9.02632286927325111491882125847041606903076171875000e-02, // 0.900000
- 8.98323090075764524309320790962374303489923477172852e-02, // 1.000000
- 8.93588365430456332827446885858080349862575531005859e-02, // 1.100000
- 8.88446016412571676346132676371780689805746078491211e-02, // 1.200000
- 8.82913990780017921000677461051964201033115386962891e-02, // 1.300000
- 8.77010230126132606098821042905910871922969818115234e-02, // 1.400000
- 8.70752622608445409069233278387400787323713302612305e-02, // 1.500000
- 8.64158958878580990559115093674336094409227371215820e-02, // 1.600000
- 8.57246891169329561233070080561446957290172576904297e-02, // 1.700000
- 8.50033895481578094521779576098197139799594879150391e-02, // 1.800000
- 8.42537236802113342903908232983667403459548950195312e-02, // 1.900000
- 8.34773937273183275209476050804369151592254638671875e-02, // 2.000000
- 7.72637758157185411400647012669651303440332412719727e-02, // 2.718282
- 7.32283395263601255553709279411123134195804595947266e-02, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_CDF_01_1 = { //
- 3.31154277189507073586582919233478605747222900390625e-01, // 0.000000
- 3.31157936975598421458499842628953047096729278564453e-01, // 0.000010
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.100000
- 3.76507892217193051997981001477455720305442810058594e-01, // 0.123457
- 4.04607661664131867951255117077380418777465820312500e-01, // 0.200000
- 4.30794607123086759070673679161700420081615447998047e-01, // 0.271828
- 4.40991025942982672880532390990993008017539978027344e-01, // 0.300000
- 4.46096575846239407070470406324602663516998291015625e-01, // 0.314159
- 4.76723690714594083850386141421040520071983337402344e-01, // 0.400000
- 5.11544833689041578139722332707606256008148193359375e-01, // 0.500000
- 5.45239211892605046827497972117271274328231811523438e-01, // 0.600000
- 5.77635844258915676086019175272667780518531799316406e-01, // 0.700000
- 6.08605317804406409365469698968809098005294799804688e-01, // 0.800000
- 6.38056166582018691180167024867841973900794982910156e-01, // 0.900000
- 6.65930705440122117089174480497604236006736755371094e-01, // 1.000000
- 6.92200627555346392760782237019157037138938903808594e-01, // 1.100000
- 7.16862603474862081220919662882806733250617980957031e-01, // 1.200000
- 7.39934054783606187655209396325517445802688598632812e-01, // 1.300000
- 7.61449220009415284060594331094762310385704040527344e-01, // 1.400000
- 7.81455584849563456018017859605606645345687866210938e-01, // 1.500000
- 8.00010713004353557487036141537828370928764343261719e-01, // 1.600000
- 8.17179486939028754122205100429710000753402709960938e-01, // 1.700000
- 8.33031748536220639778093755012378096580505371093750e-01, // 1.800000
- 8.47640316515773317718185353442095220088958740234375e-01, // 1.900000
- 8.61079349396833837460007998743094503879547119140625e-01, // 2.000000
- 9.29667709628290483969692559185205027461051940917969e-01, // 2.718282
- 9.53363743354765147408613756851991638541221618652344e-01, // 3.141593
- };
-
- public static final double[] SCIPY_GUMBEL_PDF_01_1 = { //
- 3.65982076509606846226319021297967992722988128662109e-01, // 0.000000
- 3.65982461392446445369586172091658227145671844482422e-01, // 0.000010
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.100000
- 3.67779034862618203760575852356851100921630859375000e-01, // 0.123457
- 3.66104151897740148768889412167482078075408935546875e-01, // 0.200000
- 3.62782413998306907387814135290682315826416015625000e-01, // 0.271828
- 3.61052914770930044596752850338816642761230468750000e-01, // 0.300000
- 3.60097994370001339703435405681375414133071899414062e-01, // 0.314159
- 3.53165596312007168400270984420785680413246154785156e-01, // 0.400000
- 3.42898756467731824493228032224578782916069030761719e-01, // 0.500000
- 3.30704298890418080247854959452524781227111816406250e-01, // 0.600000
- 3.17013272754289754384871002912404946982860565185547e-01, // 0.700000
- 3.02224456630968474346587981926859356462955474853516e-01, // 0.800000
- 2.86697116378903826827695411338936537504196166992188e-01, // 0.900000
- 2.70747220321607584558876169467112049460411071777344e-01, // 1.000000
- 2.54646380043582531982337968656793236732482910156250e-01, // 1.100000
- 2.38622831681304076179017670256143901497125625610352e-01, // 1.200000
- 2.22863854497548474764556658556102775037288665771484e-01, // 1.300000
- 2.07519121233516318225653662921104114502668380737305e-01, // 1.400000
- 1.92704574679114809532265439884213265031576156616211e-01, // 1.500000
- 1.78506518513120937541316379792988300323486328125000e-01, // 1.600000
- 1.64985692989648907724742343816615175455808639526367e-01, // 1.700000
- 1.52181175470408269756461550059611909091472625732422e-01, // 1.800000
- 1.40114001931851056559352741714974399656057357788086e-01, // 1.900000
- 1.28790449330409367822980470918992068618535995483398e-01, // 2.000000
- 6.77988607946176241592084465992229524999856948852539e-02, // 2.718282
- 4.55314756659847622022319058032735483720898628234863e-02, // 3.141593
- };
-
- public static final double[] P_QUANT = { //
- 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99, 0.999, 0.9999 //
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_1_1 = { //
- -1.22032680636784629513158506597392261028289794921875e+00, // 0.000100
- -9.32644733916065504786274686921387910842895507812500e-01, // 0.001000
- -5.27179625807901119927123545494396239519119262695312e-01, // 0.010000
- 1.65967554752044277321942900016438215970993041992188e-01, // 0.100000
- 6.73365740021719005881095654331147670745849609375000e-01, // 0.250000
- 1.36651292058166440313016209984198212623596191406250e+00, // 0.500000
- 2.24589932370723843746418424416333436965942382812500e+00, // 0.750000
- 3.25036732731244537575321373878978192806243896484375e+00, // 0.900000
- 5.60014922677657889238389543606899678707122802734375e+00, // 0.990000
- 7.90725507052371590077655127970501780509948730468750e+00, // 0.999000
- 1.02102903698928351161612226860597729682922363281250e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_2_1 = { //
- -2.20326806367846295131585065973922610282897949218750e-01, // 0.000100
- 6.73552660839344952137253130786120891571044921875000e-02, // 0.001000
- 4.72820374192098880072876454505603760480880737304688e-01, // 0.010000
- 1.16596755475204427732194290001643821597099304199219e+00, // 0.100000
- 1.67336574002171900588109565433114767074584960937500e+00, // 0.250000
- 2.36651292058166440313016209984198212623596191406250e+00, // 0.500000
- 3.24589932370723843746418424416333436965942382812500e+00, // 0.750000
- 4.25036732731244537575321373878978192806243896484375e+00, // 0.900000
- 6.60014922677657889238389543606899678707122802734375e+00, // 0.990000
- 8.90725507052371590077655127970501780509948730468750e+00, // 0.999000
- 1.12102903698928351161612226860597729682922363281250e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_4_1 = { //
- 1.77967319363215370486841493402607738971710205078125e+00, // 0.000100
- 2.06735526608393449521372531307861208915710449218750e+00, // 0.001000
- 2.47282037419209910211748137953691184520721435546875e+00, // 0.010000
- 3.16596755475204449936654782504774630069732666015625e+00, // 0.100000
- 3.67336574002171900588109565433114767074584960937500e+00, // 0.250000
- 4.36651292058166440313016209984198212623596191406250e+00, // 0.500000
- 5.24589932370723843746418424416333436965942382812500e+00, // 0.750000
- 6.25036732731244537575321373878978192806243896484375e+00, // 0.900000
- 8.60014922677657978056231513619422912597656250000000e+00, // 0.990000
- 1.09072550705237159007765512797050178050994873046875e+01, // 0.999000
- 1.32102903698928351161612226860597729682922363281250e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_4_10 = { //
- -1.82032680636784647276726900599896907806396484375000e+01, // 0.000100
- -1.53264473391606550478627468692138791084289550781250e+01, // 0.001000
- -1.12717962580790107551820256048813462257385253906250e+01, // 0.010000
- -4.34032445247955678269136114977300167083740234375000e+00, // 0.100000
- 7.33657400217190502900166393374092876911163330078125e-01, // 0.250000
- 7.66512920581664403130162099841982126235961914062500e+00, // 0.500000
- 1.64589932370723843746418424416333436965942382812500e+01, // 0.750000
- 2.65036732731244555338889767881482839584350585937500e+01, // 0.900000
- 5.00014922677657907001957937609404325485229492187500e+01, // 0.990000
- 7.30725507052371625604791915975511074066162109375000e+01, // 0.999000
- 9.61029036989283440561848692595958709716796875000000e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_01_10 = { //
- -2.21032680636784633065872185397893190383911132812500e+01, // 0.000100
- -1.92264473391606536267772753490135073661804199218750e+01, // 0.001000
- -1.51717962580790111104533934849314391613006591796875e+01, // 0.010000
- -8.24032445247955713796272902982309460639953613281250e+00, // 0.100000
- -3.16634259978280940828199163661338388919830322265625e+00, // 0.250000
- 3.76512920581664367603025311836972832679748535156250e+00, // 0.500000
- 1.25589932370723822430136351613327860832214355468750e+01, // 0.750000
- 2.26036732731244569549744483083486557006835937500000e+01, // 0.900000
- 4.61014922677657921212812652811408042907714843750000e+01, // 0.990000
- 6.91725507052371568761373055167496204376220703125000e+01, // 0.999000
- 9.22029036989283383718429831787943840026855468750000e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_01_20 = { //
- -4.43065361273569280342599085997790098190307617187500e+01, // 0.000100
- -3.85528946783213086746400222182273864746093750000000e+01, // 0.001000
- -3.04435925161580200892785796895623207092285156250000e+01, // 0.010000
- -1.65806489049591121442972507793456315994262695312500e+01, // 0.100000
- -6.43268519956561934947103509330190718173980712890625e+00, // 0.250000
- 7.43025841163328681915345441666431725025177001953125e+00, // 0.500000
- 2.50179864741447666176554776029661297798156738281250e+01, // 0.750000
- 4.51073465462489124888634250964969396591186523437500e+01, // 0.900000
- 9.21029845355315757160497014410793781280517578125000e+01, // 0.990000
- 1.38245101410474319436616497114300727844238281250000e+02, // 0.999000
- 1.84305807397856682428027852438390254974365234375000e+02, // 0.999900
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_01_4 = { //
- -8.78130722547138553579770814394578337669372558593750e+00, // 0.000100
- -7.63057893566426237441646662773564457893371582031250e+00, // 0.001000
- -6.00871850323160483497986206202767789363861083984375e+00, // 0.010000
- -3.23612978099182280189438642992172390222549438476562e+00, // 0.100000
- -1.20653703991312366561317048763157799839973449707031e+00, // 0.250000
- 1.56605168232665747929388544434914365410804748535156e+00, // 0.500000
- 5.08359729482895250640694939647801220417022705078125e+00, // 0.750000
- 9.10146930924978114774148707510903477668762207031250e+00, // 0.900000
- 1.85005969071063169906210532644763588905334472656250e+01, // 0.990000
- 2.77290202820948650241916766390204429626464843750000e+01, // 0.999000
- 3.69411614795713418857303622644394636154174804687500e+01, // 0.999900
- };
-
- public static final double[] SCIPY_GUMBEL_QUANT_01_1 = { //
- -2.12032680636784620631374309596139937639236450195312e+00, // 0.000100
- -1.83264473391606541596843271690886467695236206054688e+00, // 0.001000
- -1.42717962580790103110928157548187300562858581542969e+00, // 0.010000
- -7.34032445247955744882517592486692592501640319824219e-01, // 0.100000
- -2.26634259978280933056637991285242605954408645629883e-01, // 0.250000
- 4.66512920581664380925701607338851317763328552246094e-01, // 0.500000
- 1.34589932370723830423742128914454951882362365722656e+00, // 0.750000
- 2.35036732731244546457105570880230516195297241210938e+00, // 0.900000
- 4.70014922677657853711252755601890385150909423828125e+00, // 0.990000
- 7.00725507052371554550518339965492486953735351562500e+00, // 0.999000
- 9.31029036989283476088985480600968003273010253906250e+00, // 0.999900
- };
-
- @Test
- public void testPDF() {
- checkPDF(new GumbelDistribution(1., 1.), P_CDFPDF, SCIPY_GUMBEL_PDF_1_1, 1e-12);
- checkPDF(new GumbelDistribution(2., 1.), P_CDFPDF, SCIPY_GUMBEL_PDF_2_1, 1e-12);
- checkPDF(new GumbelDistribution(4., 1.), P_CDFPDF, SCIPY_GUMBEL_PDF_4_1, 1e-11);
- checkPDF(new GumbelDistribution(4., 10.), P_CDFPDF, SCIPY_GUMBEL_PDF_4_10, 1e-13);
- checkPDF(new GumbelDistribution(.1, 1.), P_CDFPDF, SCIPY_GUMBEL_PDF_01_1, 1e-12);
- checkPDF(new GumbelDistribution(.1, 4.), P_CDFPDF, SCIPY_GUMBEL_PDF_01_4, 1e-12);
- checkPDF(new GumbelDistribution(.1, 10.), P_CDFPDF, SCIPY_GUMBEL_PDF_01_10, 1e-13);
- checkPDF(new GumbelDistribution(.1, 20.), P_CDFPDF, SCIPY_GUMBEL_PDF_01_20, 1e-14);
- }
-
- @Test
- public void testCDF() {
- checkCDF(new GumbelDistribution(1., 1.), P_CDFPDF, SCIPY_GUMBEL_CDF_1_1, 1e-12);
- checkCDF(new GumbelDistribution(2., 1.), P_CDFPDF, SCIPY_GUMBEL_CDF_2_1, 1e-12);
- checkCDF(new GumbelDistribution(4., 1.), P_CDFPDF, SCIPY_GUMBEL_CDF_4_1, 1e-11);
- checkCDF(new GumbelDistribution(4., 10.), P_CDFPDF, SCIPY_GUMBEL_CDF_4_10, 1e-12);
- checkCDF(new GumbelDistribution(.1, 1.), P_CDFPDF, SCIPY_GUMBEL_CDF_01_1, 1e-13);
- checkCDF(new GumbelDistribution(.1, 4.), P_CDFPDF, SCIPY_GUMBEL_CDF_01_4, 1e-13);
- checkCDF(new GumbelDistribution(.1, 10.), P_CDFPDF, SCIPY_GUMBEL_CDF_01_10, 1e-13);
- checkCDF(new GumbelDistribution(.1, 20.), P_CDFPDF, SCIPY_GUMBEL_CDF_01_20, 1e-13);
- }
-
- @Test
- public void testQuantile() {
- checkQuantile(new GumbelDistribution(1., 1.), P_QUANT, SCIPY_GUMBEL_QUANT_1_1, 1e-13);
- checkQuantile(new GumbelDistribution(2., 1.), P_QUANT, SCIPY_GUMBEL_QUANT_2_1, 1e-13);
- checkQuantile(new GumbelDistribution(4., 1.), P_QUANT, SCIPY_GUMBEL_QUANT_4_1, 1e-13);
- checkQuantile(new GumbelDistribution(4., 10.), P_QUANT, SCIPY_GUMBEL_QUANT_4_10, 1e-13);
- checkQuantile(new GumbelDistribution(.1, 1.), P_QUANT, SCIPY_GUMBEL_QUANT_01_1, 1e-13);
- checkQuantile(new GumbelDistribution(.1, 4.), P_QUANT, SCIPY_GUMBEL_QUANT_01_4, 1e-13);
- checkQuantile(new GumbelDistribution(.1, 10.), P_QUANT, SCIPY_GUMBEL_QUANT_01_10, 1e-13);
- checkQuantile(new GumbelDistribution(.1, 20.), P_QUANT, SCIPY_GUMBEL_QUANT_01_20, 1e-13);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestLogGammaAlternateDistribution.java b/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestLogGammaAlternateDistribution.java
deleted file mode 100644
index 07f111e5..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestLogGammaAlternateDistribution.java
+++ /dev/null
@@ -1,672 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for the LogGamma distribution in ELKI.
- *
- * The reference values were computed using GNU R and SciPy.
- *
- * @author Erich Schubert
- */
-public class TestLogGammaAlternateDistribution extends AbstractDistributionTest implements JUnit4Test {
- public static final double[] P_CDFPDF = { //
- 1e-10, 1e-05, 0.1, 0.1234567, 0.2, 0.271828182846, 0.3, 0.314159265359, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.71828182846, 3.14159265359 //
- };
-
- public static final double[] SCIPY_LOGGAMMA_CDF_1_1 = { //
- 6.32120558865345572030491894111037254333496093750000e-01, // 0.000000
- 6.32124237622968987437843679799698293209075927734375e-01, // 0.000010
- 6.68845722847090984330975516058970242738723754882812e-01, // 0.100000
- 6.77419000750269617583398940041661262512207031250000e-01, // 0.123457
- 7.05183679270841912156697617319878190755844116210938e-01, // 0.200000
- 7.30816370768268552815527527855010703206062316894531e-01, // 0.271828
- 7.40723134009172445857416278158780187368392944335938e-01, // 0.300000
- 7.45666217579490364641969790682196617126464843750000e-01, // 0.314159
- 7.75038206450081590404010967176873236894607543945312e-01, // 0.400000
- 8.07704354452035144795729593170108273625373840332031e-01, // 0.500000
- 8.38317185854873470063353124714922159910202026367188e-01, // 0.600000
- 8.66513203341916171673631197336362674832344055175781e-01, // 0.700000
- 8.91991022303408431781690524076111614704132080078125e-01, // 0.800000
- 9.14531134124054068124110017379280179738998413085938e-01, // 0.900000
- 9.34011964154687457373427150741918012499809265136719e-01, // 1.000000
- 9.50419914304432955631796176021452993154525756835938e-01, // 1.100000
- 9.63851395086864459749165234825341030955314636230469e-01, // 1.200000
- 9.74505605324275880896323087654309347271919250488281e-01, // 1.300000
- 9.82667985991235504172891523921862244606018066406250e-01, // 1.400000
- 9.88685713619540385010964200773742049932479858398438e-01, // 1.500000
- 9.92938038437790604362476187816355377435684204101562e-01, // 1.600000
- 9.95805358458610623273443707148544490337371826171875e-01, // 1.700000
- 9.97641306616706802223859540390549227595329284667969e-01, // 1.800000
- 9.98751602365355761747878204914741218090057373046875e-01, // 1.900000
- 9.99382021010668863958414931403240188956260681152344e-01, // 2.000000
- 9.99999737827261037104165097844088450074195861816406e-01, // 2.718282
- 9.99999999910849313167204854835290461778640747070312e-01, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_PDF_1_1 = { //
- 3.67879441171442334024277442949824035167694091796875e-01, // 0.000000
- 3.67879441153048325485741543161566369235515594482422e-01, // 0.000010
- 3.65982076505757758511094834830146282911300659179688e-01, // 0.100000
- 3.64968469589419641785354997409740462899208068847656e-01, // 0.123457
- 3.60089467289227027624320953691494651138782501220703e-01, // 0.200000
- 3.53266230282285820241128249108442105352878570556641e-01, // 0.271828
- 3.49987161158421655748895773285767063498497009277344e-01, // 0.300000
- 3.48210357844328799448163636043318547308444976806641e-01, // 0.314159
- 3.35603559643444959714742026335443370044231414794922e-01, // 0.400000
- 3.17041921077942157047857563156867399811744689941406e-01, // 0.500000
- 2.94605295353879415021225440796115435659885406494141e-01, // 0.600000
- 2.68809398181777292613503504981053993105888366699219e-01, // 0.700000
- 2.40378400508394596268857412724173627793788909912109e-01, // 0.800000
- 2.10219488415532618219572214002255350351333618164062e-01, // 0.900000
- 1.79374078734017200487116383555985521525144577026367e-01, // 1.000000
- 1.48946808910974892725675999827217310667037963867188e-01, // 1.100000
- 1.20017594905418772954774908612307626754045486450195e-01, // 1.200000
- 9.35464974266043275408222257283341605216264724731445e-02, // 1.300000
- 7.02847826336932546276159428089158609509468078613281e-02, // 1.400000
- 5.07071136099807306951703367303707636892795562744141e-02, // 1.500000
- 3.49781245974551888155978929262346355244517326354980e-02, // 1.600000
- 2.29612471247189892098461427849542815238237380981445e-02, // 1.700000
- 1.42692634455674535048919082669272029306739568710327e-02, // 1.800000
- 8.34665480722261883539392357533870381303131580352783e-03, // 1.900000
- 4.56628142012791525539139314560088678263127803802490e-03, // 2.000000
- 3.97303443855662314872830703782469186080561485141516e-06, // 2.718282
- 2.06300953864877018550080075740774804282651189168973e-09, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_CDF_2_1 = { //
- 2.64241117693903238006214451161213219165802001953125e-01, // 0.000000
- 2.64244796469920995019009524185094051063060760498047e-01, // 0.000010
- 3.02863646341333336842183143744478002190589904785156e-01, // 0.100000
- 3.12450531160849975798043942631920799612998962402344e-01, // 0.123457
- 3.45094211981614884532376663628383539617061614990234e-01, // 0.200000
- 3.77550140485982788085550510004395619034767150878906e-01, // 0.271828
- 3.90735972850750901130822967388667166233062744140625e-01, // 0.300000
- 3.97455859735161454171503692123224027454853057861328e-01, // 0.314159
- 4.39434646806636519666966478325775824487209320068359e-01, // 0.400000
- 4.90662433374092876725569567497586831450462341308594e-01, // 0.500000
- 5.43711890500994221575581377692287787795066833496094e-01, // 0.600000
- 5.97703805160138879060127692355308681726455688476562e-01, // 0.700000
- 6.51612621795013780001681880094110965728759765625000e-01, // 0.800000
- 7.04311645708521449904537803377024829387664794921875e-01, // 0.900000
- 7.54637885420670229130735151557018980383872985839844e-01, // 1.000000
- 8.01473105393458062906120176194235682487487792968750e-01, // 1.100000
- 8.43833800181445714549965941841946914792060852050781e-01, // 1.200000
- 8.80959107897671511722137438482604920864105224609375e-01, // 1.300000
- 9.12383203357542194034124349855119362473487854003906e-01, // 1.400000
- 9.37978600009559682071369479672284796833992004394531e-01, // 1.500000
- 9.57959913840335408607984390982892364263534545898438e-01, // 1.600000
- 9.72844111333891592430234140920219942927360534667969e-01, // 1.700000
- 9.83372043171139353923138060054043307900428771972656e-01, // 1.800000
- 9.90404947558133130769419949501752853393554687500000e-01, // 1.900000
- 9.94815739590541037173920813074801117181777954101562e-01, // 2.000000
- 9.99995764792822483535417177336057648062705993652344e-01, // 2.718282
- 9.99999997847839772191491647390648722648620605468750e-01, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_PDF_2_1 = { //
- 3.67879441208230295590198011268512345850467681884766e-01, // 0.000000
- 3.67883119965853877531003490730654448270797729492188e-01, // 0.000010
- 4.04472747491100181882472952565876767039299011230469e-01, // 0.100000
- 4.12925696504904959915904782974394038319587707519531e-01, // 0.123457
- 4.39814268531488139490903677142341621220111846923828e-01, // 0.200000
- 4.63612998361142059078332522403798066079616546630859e-01, // 0.271828
- 4.72433252028217454121516993836848996579647064208984e-01, // 0.300000
- 4.76737506736729155232268340114387683570384979248047e-01, // 0.314159
- 5.00661678892416417419042318215360864996910095214844e-01, // 0.400000
- 5.22713758984834520049389539053663611412048339843750e-01, // 0.500000
- 5.36805847358902354926613043062388896942138671875000e-01, // 0.600000
- 5.41315653382063444176708344457438215613365173339844e-01, // 0.700000
- 5.34971968656986818224652324715862050652503967285156e-01, // 0.800000
- 5.17056507732666426058187880698824301362037658691406e-01, // 0.900000
- 4.87589298719261043935091493040090426802635192871094e-01, // 1.000000
- 4.47460942705592668033887093770317733287811279296875e-01, // 1.100000
- 3.98472447871620394366232176253106445074081420898438e-01, // 1.200000
- 3.43249851274891548680301411877735517919063568115234e-01, // 1.300000
- 2.85018848205838060128058941700146533548831939697266e-01, // 1.400000
- 2.27253516854241194300456641030905302613973617553711e-01, // 1.500000
- 1.73247785275727900211606424818455707281827926635742e-01, // 1.600000
- 1.25688658809159137241806547535816207528114318847656e-01, // 1.700000
- 8.63240134225174982063322204339783638715744018554688e-02, // 1.800000
- 5.58048529872332277346202999979141168296337127685547e-02, // 1.900000
- 3.37405095768298773917237554087478201836347579956055e-02, // 2.000000
- 6.02084057763153639316298926242865263702697120606899e-05, // 2.718282
- 4.77394696323629441641945875696856349534868968476076e-08, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_CDF_4_1 = { //
- 1.89881568822851329314538304515735944733023643493652e-02, // 0.000000
- 1.89887700177528255529590950345664168708026409149170e-02, // 0.000010
- 2.61253529822300795126821526537241879850625991821289e-02, // 0.100000
- 2.81235909655702942533395116697647608816623687744141e-02, // 0.123457
- 3.56553509387778355677056651984457857906818389892578e-02, // 0.200000
- 4.43389999778885657288896027239388786256313323974609e-02, // 0.271828
- 4.82329824629648754030775137380260275676846504211426e-02, // 0.300000
- 5.03029355298684754949078978825127705931663513183594e-02, // 0.314159
- 6.46205644047200128410324282413057517260313034057617e-02, // 0.400000
- 8.56706717273561235703738248048466630280017852783203e-02, // 0.500000
- 1.12288295716173991412034638415207155048847198486328e-01, // 0.600000
- 1.45366668036726959245541479504026938229799270629883e-01, // 0.700000
- 1.85692968826134785498283008564612828195095062255859e-01, // 0.800000
- 2.33824425998319124220259368485130835324525833129883e-01, // 0.900000
- 2.89942380984430481127844814182026311755180358886719e-01, // 1.000000
- 3.53701473854131198670813773787813261151313781738281e-01, // 1.100000
- 4.24101723341831882141406140362960286438465118408203e-01, // 1.200000
- 4.99419926352932252999750062372186221182346343994141e-01, // 1.300000
- 5.77239041955553089380259734753053635358810424804688e-01, // 1.400000
- 6.54605241135515658612575862207449972629547119140625e-01, // 1.500000
- 7.28319038214917613416332642373163253068923950195312e-01, // 1.600000
- 7.95330930919631029496486007701605558395385742187500e-01, // 1.700000
- 8.53171728306633569971495489880908280611038208007812e-01, // 1.800000
- 9.00318294991257483950164441921515390276908874511719e-01, // 1.900000
- 9.36393731790508887513624358689412474632263183593750e-01, // 2.000000
- 9.99813591594888362301674078480573371052742004394531e-01, // 2.718282
- 9.99999789857372700652149433153681457042694091796875e-01, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_PDF_4_1 = { //
- 6.13132402136343651610772553794959094375371932983398e-02, // 0.000000
- 6.13150796169717390848852289764181477949023246765137e-02, // 0.000010
- 8.23373548977086172628858662392303813248872756958008e-02, // 0.100000
- 8.80955125640966868472148121327336411923170089721680e-02, // 0.123457
- 1.09354298028383978280686505968333221971988677978516e-01, // 0.200000
- 1.33079546765686368425818386640457902103662490844727e-01, // 0.271828
- 1.43471585075040430901083254866534844040870666503906e-01, // 0.300000
- 1.48937253613819708952803466672776266932487487792969e-01, // 0.314159
- 1.85707176283804342720173963243723846971988677978516e-01, // 0.400000
- 2.36813885422332809360668193221499677747488021850586e-01, // 0.500000
- 2.97043029673370651000396946983528323471546173095703e-01, // 0.600000
- 3.65857203274574493967463695298647508025169372558594e-01, // 0.700000
- 4.41622251150090516791379968708497472107410430908203e-01, // 0.800000
- 5.21334931827189818065448889683466404676437377929688e-01, // 0.900000
- 6.00470780245812463249421853106468915939331054687500e-01, // 1.000000
- 6.73056841397915439628718559106346219778060913085938e-01, // 1.100000
- 7.32072012619148004830549325561150908470153808593750e-01, // 1.200000
- 7.70237679686405218859590604552067816257476806640625e-01, // 1.300000
- 7.81172380308322367170603683916851878166198730468750e-01, // 1.400000
- 7.60751483950018791979630350397201254963874816894531e-01, // 1.500000
- 7.08367753976518632619274740136461332440376281738281e-01, // 1.600000
- 6.27691257896798693316497974592493847012519836425781e-01, // 1.700000
- 5.26551080226083545454685008735395967960357666015625e-01, // 1.800000
- 4.15757171500640287931105376628693193197250366210938e-01, // 1.900000
- 3.07028234011749667775603711561416275799274444580078e-01, // 2.000000
- 2.30449342972448420127640211774178169434890151023865e-03, // 2.718282
- 4.26068127121804497963591940035144034482073038816452e-06, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_CDF_4_10 = { //
- 1.89881569374670579330999231615351163782179355621338e-02, // 0.000000
- 1.89942891199536868784836229906431981362402439117432e-02, // 0.000010
- 2.89942380984430481127844814182026311755180358886719e-01, // 0.100000
- 4.49689791586118492450196981735643930733203887939453e-01, // 0.123457
- 9.36393731790508887513624358689412474632263183593750e-01, // 0.200000
- 9.99813591594888362301674078480573371052742004394531e-01, // 0.271828
- 9.99997023008917240716186825011391192674636840820312e-01, // 0.300000
- 9.99999789857372700652149433153681457042694091796875e-01, // 0.314159
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_PDF_4_10 = { //
- 6.13132403791800895120900349866133183240890502929688e-01, // 0.000000
- 6.13316366200022833332639038417255505919456481933594e-01, // 0.000010
- 6.00470780245812463249421853106468915939331054687500e+00, // 0.100000
- 7.47978163723896560810544542619027197360992431640625e+00, // 0.123457
- 3.07028234011749656673373465309850871562957763671875e+00, // 0.200000
- 2.30449342972449608413221255887037841603159904479980e-02, // 0.271828
- 5.13268581343153621615593706906111037824302911758423e-04, // 0.300000
- 4.26068127121804497963591940035144034482073038816452e-05, // 0.314159
- 2.87663777096353381165139848770654588739438492245738e-17, // 0.400000
- 2.83610527480158774910577794815980995977618360070194e-56, // 0.500000
- 2.74168439726173051715348577927730977333274164887227e-165, // 0.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_CDF_01_10 = { //
- 9.75872656312341435480561813164968043565750122070312e-01, // 0.000000
- 9.75876523016603880655850389302941039204597473144531e-01, // 0.000010
- 9.97771302397556292262947863491717725992202758789062e-01, // 0.100000
- 9.99085373345744098827481138869188725948333740234375e-01, // 0.123457
- 9.99990322880914939140950536966556683182716369628906e-01, // 0.200000
- 9.99999997740172674731695678929099813103675842285156e-01, // 0.271828
- 9.99999999987182364158400105225155130028724670410156e-01, // 0.300000
- 9.99999999999465538635945449641440063714981079101562e-01, // 0.314159
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_PDF_01_10 = { //
- 3.86691694055001200513999037866597063839435577392578e-01, // 0.000000
- 3.86656891783232925519087075372226536273956298828125e-01, // 0.000010
- 7.66573807128762413354294835698965471237897872924805e-02, // 0.100000
- 3.82519444836298613821234937404369702562689781188965e-02, // 0.123457
- 7.93399517782126173157108972588957840343937277793884e-04, // 0.200000
- 3.61659882683325373483495179458002688477336050709710e-07, // 0.271828
- 2.68478689210771182002679843229143302751893429558550e-09, // 0.300000
- 1.28298578206074916753204354692176596824948475727979e-10, // 0.314159
- 3.04580319059060921083886090465841494937109628893572e-24, // 0.400000
- 6.07841750487491422247162425697089017615956979567134e-65, // 0.500000
- 1.18942526811122497186251097706497282965193428534428e-175, // 0.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_CDF_01_20 = { //
- 9.75872656351010503428256015467923134565353393554688e-01, // 0.000000
- 9.75880389411505455576900658343220129609107971191406e-01, // 0.000010
- 9.99990322880914939140950536966556683182716369628906e-01, // 0.100000
- 9.99999921146446313358069346577394753694534301757812e-01, // 0.123457
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.271828
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.314159
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_PDF_01_20 = { //
- 7.73383387413957290590360571513883769512176513671875e-01, // 0.000000
- 7.73244176858206899716208226891467347741127014160156e-01, // 0.000010
- 1.58679903556425234631421794517791568068787455558777e-03, // 0.100000
- 1.99500277683705806545944039243067891220562160015106e-05, // 0.123457
- 6.09160638118121842167772180931682989874219257787145e-24, // 0.200000
- 6.64271790906281664176004049075875506156745355852006e-100, // 0.271828
- 2.37885053622244994372502195412994565930386857068856e-175, // 0.300000
- 1.08266349311588655483576215872042725531821155344122e-232, // 0.314159
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_CDF_01_4 = { //
- 9.75872656289139994711945291783194988965988159179688e-01, // 0.000000
- 9.75874203012607965845859325781930238008499145507812e-01, // 0.000010
- 9.88521989554807967159888448804849758744239807128906e-01, // 0.100000
- 9.90682106581839194703320572443772107362747192382812e-01, // 0.123457
- 9.95795137017725928707534421846503391861915588378906e-01, // 0.200000
- 9.98367638432702042550204168946947902441024780273438e-01, // 0.271828
- 9.98945317922235953567167143773986026644706726074219e-01, // 0.300000
- 9.99166739486790800306437176914187148213386535644531e-01, // 0.314159
- 9.99848025621776881344260345940710976719856262207031e-01, // 0.400000
- 9.99990322880914939140950536966556683182716369628906e-01, // 0.500000
- 9.99999816093564919405878299585310742259025573730469e-01, // 0.600000
- 9.99999999419964535896099278033943846821784973144531e-01, // 0.700000
- 9.99999999999873656619797657185699790716171264648438e-01, // 0.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_PDF_01_4 = { //
- 1.54676677705525900119454263403895311057567596435547e-01, // 0.000000
- 1.54671109377300830534096576229785569012165069580078e-01, // 0.000010
- 9.84464052270282996559558341687079519033432006835938e-02, // 0.100000
- 8.58108052000031706896265859541017562150955200195312e-02, // 0.123457
- 4.91952001039043101959791215449513401836156845092773e-02, // 0.200000
- 2.41377289439051283259640712230975623242557048797607e-02, // 0.271828
- 1.71366606385362704734198757705598836764693260192871e-02, // 0.300000
- 1.42024583125499245794820524224633118137717247009277e-02, // 0.314159
- 3.48443031793151504829642028937541908817365765571594e-03, // 0.400000
- 3.17359807112850480104865313890627476212102919816971e-04, // 0.500000
- 8.72258716114687767772921389575202510968665592372417e-06, // 0.600000
- 4.01330737127810106150866157823098312462661851895973e-08, // 0.700000
- 1.28336756744997760816790662079631580184263528465749e-11, // 0.800000
- 7.68518036611483919318729926999253387631177034870593e-17, // 0.900000
- 1.21832127623624368433554436186336597974843851557429e-24, // 1.000000
- 2.76150657747027996328471734486001464284084376015250e-36, // 1.100000
- 1.15047410120420279456129534473030897392716993393999e-53, // 1.200000
- 1.33050980492765102664431323936746771679614454246348e-79, // 1.300000
- 2.64379466050064674479079986745942626514867284146420e-118, // 1.400000
- 4.75770107244327689646329016597701524441576128422297e-176, // 1.500000
- 3.33955712784524322177202771066577131845898338987944e-262, // 1.600000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 0.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 0.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_CDF_01_1 = { //
- 9.75872656277539052283032106061000376939773559570312e-01, // 0.000000
- 9.75873042963626202705995638098102062940597534179688e-01, // 0.000010
- 9.79564498296314867253897773480275645852088928222656e-01, // 0.100000
- 9.80379475959243795735176263406174257397651672363281e-01, // 0.123457
- 9.82903290234357296384359869989566504955291748046875e-01, // 0.200000
- 9.85082822462057028367610200803028419613838195800781e-01, // 0.271828
- 9.85887936645999274354323915758868679404258728027344e-01, // 0.300000
- 9.86282063361266780887603999872226268053054809570312e-01, // 0.314159
- 9.88521989554807967159888448804849758744239807128906e-01, // 0.400000
- 9.90813910099314409940518544317455962300300598144531e-01, // 0.500000
- 9.92777145076669365053589899616781622171401977539062e-01, // 0.600000
- 9.94429979424373611252008231531362980604171752929688e-01, // 0.700000
- 9.95795137017725928707534421846503391861915588378906e-01, // 0.800000
- 9.96899120167219043864292871148791164159774780273438e-01, // 0.900000
- 9.97771302397556292262947863491717725992202758789062e-01, // 1.000000
- 9.98442817593759524008589778532041236758232116699219e-01, // 1.100000
- 9.98945317922235953567167143773986026644706726074219e-01, // 1.200000
- 9.99309698140446789338398048130329698324203491210938e-01, // 1.300000
- 9.99564899282052388151953437045449391007423400878906e-01, // 1.400000
- 9.99736904974793616496242520952364429831504821777344e-01, // 1.500000
- 9.99848025621776881344260345940710976719856262207031e-01, // 1.600000
- 9.99916529849280033559466573933605104684829711914062e-01, // 1.700000
- 9.99956634133785438045549653907073661684989929199219e-01, // 1.800000
- 9.99978809766067122666299837874248623847961425781250e-01, // 1.900000
- 9.99990322880914939140950536966556683182716369628906e-01, // 2.000000
- 9.99999997740172674731695678929099813103675842285156e-01, // 2.718282
- 9.99999999999465538635945449641440063714981079101562e-01, // 3.141593
- };
-
- public static final double[] SCIPY_LOGGAMMA_PDF_01_1 = { //
- 3.86691694368221511313166161016852129250764846801758e-02, // 0.000000
- 3.86688214174100569620051714991859626024961471557617e-02, // 0.000010
- 3.51586863187947004649736015835514990612864494323730e-02, // 0.100000
- 3.43288903336685033429453994813229655846953392028809e-02, // 0.123457
- 3.16152585351597847918014849710743874311447143554688e-02, // 0.200000
- 2.90745711878013547713184294707389199174940586090088e-02, // 0.271828
- 2.80835450574022579828259438272652914747595787048340e-02, // 0.300000
- 2.75871692713388766415860686720407102257013320922852e-02, // 0.314159
- 2.46116013067570749139889585421769879758358001708984e-02, // 0.400000
- 2.12492448134385600311269115536561002954840660095215e-02, // 0.500000
- 1.80459959087036214686605717361089773476123809814453e-02, // 0.600000
- 1.50486745835341825111575175810685323085635900497437e-02, // 0.700000
- 1.22988000259760775489947803862378350459039211273193e-02, // 0.800000
- 9.83000572039229893184231201530565158464014530181885e-03, // 0.900000
- 7.66573807128762517437703394307391135953366756439209e-03, // 1.000000
- 5.81753483010033056038734500248210679274052381515503e-03, // 1.100000
- 4.28416515963406761835496894263997091911733150482178e-03, // 1.200000
- 3.05184388261519690468959176143926015356555581092834e-03, // 1.300000
- 2.09560576678758086338616450916561007034033536911011e-03, // 1.400000
- 1.38175379315578074172765621341341102379374206066132e-03, // 1.500000
- 8.71107579482878762074105072343854772043414413928986e-04, // 1.600000
- 5.22617853061128857447559248328161629615351557731628e-04, // 1.700000
- 2.96827286233691963433789506865423390991054475307465e-04, // 1.800000
- 1.58682200637844659282110759690453960502054542303085e-04, // 1.900000
- 7.93399517782126200262163284726568690530257299542427e-05, // 2.000000
- 3.61659882683322792679984014011657089682216792425606e-08, // 2.718282
- 1.28298578206074919984378622477440951791388679126271e-11, // 3.141593
- };
-
- public static final double[] P_QUANT = { //
- 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99, 0.999, 0.9999 //
- };
-
- public static final double[] SCIPY_LOGGAMMA_QUANT_1_1 = { //
- -9.21029036989272320568034047028049826622009277343750e+00, // 0.000100
- -6.90725507052371678895497097983025014400482177734375e+00, // 0.001000
- -4.60014922677657978056231513619422912597656250000000e+00, // 0.010000
- -2.25036732731244493166400388872716575860977172851562e+00, // 0.100000
- -1.24589932370723799337497439410071820020675659179688e+00, // 0.250000
- -3.66512920581664347619010868584155105054378509521484e-01, // 0.500000
- 3.26634259978281105141206808184506371617317199707031e-01, // 0.750000
- 8.34032445247955944722662025014869868755340576171875e-01, // 0.900000
- 1.52717962580790089788251862046308815479278564453125e+00, // 0.990000
- 1.93264473391606528274166976189007982611656188964844e+00, // 0.999000
- 2.22032680636785828554025101766455918550491333007812e+00, // 0.999900
- };
-
- public static final double[] SCIPY_LOGGAMMA_QUANT_2_1 = { //
- -4.25386298913733185145247261971235275268554687500000e+00, // 0.000100
- -3.09219873066056738508677881327457726001739501953125e+00, // 0.001000
- -1.90680176742938400913374152878532186150550842285156e+00, // 0.010000
- -6.31465971924031865825099885114468634128570556640625e-01, // 0.100000
- -3.94908359938028266644671759877383010461926460266113e-02, // 0.250000
- 5.17809374519952236859410277247661724686622619628906e-01, // 0.500000
- 9.90520093104668930550360528286546468734741210937500e-01, // 0.750000
- 1.35833721927612582902611393365077674388885498046875e+00, // 0.900000
- 1.89286375015490904161197249777615070343017578125000e+00, // 0.990000
- 2.22282880424761364324126589053776115179061889648438e+00, // 0.999000
- 2.46439532533742688968914080760441720485687255859375e+00, // 0.999900
- };
-
- public static final double[] SCIPY_LOGGAMMA_QUANT_4_1 = { //
- -1.46189374258889248636705815442837774753570556640625e+00, // 0.000100
- -8.47342229571847793678784910298418253660202026367188e-01, // 0.001000
- -1.94496953420364770970252266124589368700981140136719e-01, // 0.010000
- 5.56622491246540618270444156223675236105918884277344e-01, // 0.100000
- 9.30319945397308112333689678052905946969985961914062e-01, // 0.250000
- 1.30075301642610718921844181750202551484107971191406e+00, // 0.500000
- 1.63108735980254726527505226840730756521224975585938e+00, // 0.750000
- 1.89923520646495491703831248742062598466873168945312e+00, // 0.900000
- 2.30708669703685576024554393370635807514190673828125e+00, // 0.990000
- 2.56972568487266350700792827410623431205749511718750e+00, // 0.999000
- 2.76718753710466591755334775371011346578598022460938e+00, // 0.999900
- };
-
- public static final double[] SCIPY_LOGGAMMA_QUANT_4_10 = { //
- -1.46189374258889254187820938568620476871728897094727e-01, // 0.000100
- -8.47342229571847876945511757185158785432577133178711e-02, // 0.001000
- -1.94496953420364784848040073939046123996376991271973e-02, // 0.010000
- 5.56622491246540618270444156223675236105918884277344e-02, // 0.100000
- 9.30319945397308223355992140568559989333152770996094e-02, // 0.250000
- 1.30075301642610718921844181750202551484107971191406e-01, // 0.500000
- 1.63108735980254743180850596218078862875699996948242e-01, // 0.750000
- 1.89923520646495508357176618119410704821348190307617e-01, // 0.900000
- 2.30708669703685587126784639622201211750507354736328e-01, // 0.990000
- 2.56972568487266350700792827410623431205749511718750e-01, // 0.999000
- 2.76718753710466613959795267874142155051231384277344e-01, // 0.999900
- };
-
- public static final double[] SCIPY_LOGGAMMA_QUANT_01_10 = { //
- Double.NaN, // 0.000100
- Double.NaN, // 0.001000
- Double.NaN, // 0.010000
- -2.35245753424830494893171817238908261060714721679688e+00, // 0.100000
- -1.43616674972779789776211600837996229529380798339844e+00, // 0.250000
- -7.42965684101831946861693722894415259361267089843750e-01, // 0.500000
- -3.34369221586346410113321780954720452427864074707031e-01, // 0.750000
- -1.32367810983911204925078664018656127154827117919922e-01, // 0.900000
- 4.62776210468462748104379045344103360548615455627441e-02, // 0.990000
- 1.21303472433787085105194591960753314197063446044922e-01, // 0.999000
- 1.67076694072213816077976389351533725857734680175781e-01, // 0.999900
- };
-
- public static final double[] SCIPY_LOGGAMMA_QUANT_01_20 = { //
- Double.NaN, // 0.000100
- Double.NaN, // 0.001000
- Double.NaN, // 0.010000
- -1.17622876712415247446585908619454130530357360839844e+00, // 0.100000
- -7.18083374863898948881058004189981147646903991699219e-01, // 0.250000
- -3.71482842050915973430846861447207629680633544921875e-01, // 0.500000
- -1.67184610793173205056660890477360226213932037353516e-01, // 0.750000
- -6.61839054919556024625393320093280635774135589599609e-02, // 0.900000
- 2.31388105234231374052189522672051680274307727813721e-02, // 0.990000
- 6.06517362168935425525972959803766570985317230224609e-02, // 0.999000
- 8.35383470361069080389881946757668629288673400878906e-02, // 0.999900
- };
-
- public static final double[] SCIPY_LOGGAMMA_QUANT_01_4 = { //
- Double.NaN, // 0.000100
- Double.NaN, // 0.001000
- Double.NaN, // 0.010000
- -5.88114383562076259437390035600401461124420166015625e+00, // 0.100000
- -3.59041687431949441133838263340294361114501953125000e+00, // 0.250000
- -1.85741421025457964510962938220473006367683410644531e+00, // 0.500000
- -8.35923053965865969772153221128974109888076782226562e-01, // 0.750000
- -3.30919527459777984557121044417726807296276092529297e-01, // 0.900000
- 1.15694052617115683556647809382411651313304901123047e-01, // 0.990000
- 3.03258681084467685007410864272969774901866912841797e-01, // 0.999000
- 4.17691735180534484683789742121007293462753295898438e-01, // 0.999900
- };
-
- public static final double[] SCIPY_LOGGAMMA_QUANT_01_1 = { //
- Double.NaN, // 0.000100
- Double.NaN, // 0.001000
- Double.NaN, // 0.010000
- -2.35245753424830503774956014240160584449768066406250e+01, // 0.100000
- -1.43616674972779776453535305336117744445800781250000e+01, // 0.250000
- -7.42965684101831858043851752881892025470733642578125e+00, // 0.500000
- -3.34369221586346387908861288451589643955230712890625e+00, // 0.750000
- -1.32367810983911193822848417767090722918510437011719e+00, // 0.900000
- 4.62776210468462734226591237529646605253219604492188e-01, // 0.990000
- 1.21303472433787074002964345709187909960746765136719e+00, // 0.999000
- 1.67076694072213793873515896848402917385101318359375e+00, // 0.999900
- };
-
- @Test
- public void testPDF() {
- checkPDF(new LogGammaAlternateDistribution(1., 1., 0.), P_CDFPDF, SCIPY_LOGGAMMA_PDF_1_1, 1e-10);
- checkPDF(new LogGammaAlternateDistribution(2., 1., 0.), P_CDFPDF, SCIPY_LOGGAMMA_PDF_2_1, 1e-12);
- checkPDF(new LogGammaAlternateDistribution(4., 1., 0.), P_CDFPDF, SCIPY_LOGGAMMA_PDF_4_1, 1e-12);
- checkPDF(new LogGammaAlternateDistribution(4., 10, 0.), P_CDFPDF, SCIPY_LOGGAMMA_PDF_4_10, 1e-10);
- checkPDF(new LogGammaAlternateDistribution(.1, 10, 0.), P_CDFPDF, SCIPY_LOGGAMMA_PDF_01_10, 1e-11);
- checkPDF(new LogGammaAlternateDistribution(.1, 20, 0.), P_CDFPDF, SCIPY_LOGGAMMA_PDF_01_20, 1e-14);
- checkPDF(new LogGammaAlternateDistribution(.1, 4., 0.), P_CDFPDF, SCIPY_LOGGAMMA_PDF_01_4, 1e-12);
- checkPDF(new LogGammaAlternateDistribution(.1, 1., 0.), P_CDFPDF, SCIPY_LOGGAMMA_PDF_01_1, 1e-12);
- }
-
- @Test
- public void testCDF() {
- checkCDF(new LogGammaAlternateDistribution(1., 1., 0.), P_CDFPDF, SCIPY_LOGGAMMA_CDF_1_1, 1e-13);
- checkCDF(new LogGammaAlternateDistribution(2., 1., 0.), P_CDFPDF, SCIPY_LOGGAMMA_CDF_2_1, 1e-12);
- checkCDF(new LogGammaAlternateDistribution(4., 1., 0.), P_CDFPDF, SCIPY_LOGGAMMA_CDF_4_1, 1e-12);
- checkCDF(new LogGammaAlternateDistribution(4., 10, 0.), P_CDFPDF, SCIPY_LOGGAMMA_CDF_4_10, 1e-14);
- checkCDF(new LogGammaAlternateDistribution(.1, 10, 0.), P_CDFPDF, SCIPY_LOGGAMMA_CDF_01_10, 1e-15);
- checkCDF(new LogGammaAlternateDistribution(.1, 20, 0.), P_CDFPDF, SCIPY_LOGGAMMA_CDF_01_20, 1e-15);
- checkCDF(new LogGammaAlternateDistribution(.1, 4., 0.), P_CDFPDF, SCIPY_LOGGAMMA_CDF_01_4, 1e-14);
- checkCDF(new LogGammaAlternateDistribution(.1, 1., 0.), P_CDFPDF, SCIPY_LOGGAMMA_CDF_01_1, 1e-14);
- }
-
- @Test
- public void testProbit() {
- checkQuantile(new LogGammaAlternateDistribution(1., 1., 0.), P_QUANT, SCIPY_LOGGAMMA_QUANT_1_1, 1e-14);
- checkQuantile(new LogGammaAlternateDistribution(2., 1., 0.), P_QUANT, SCIPY_LOGGAMMA_QUANT_2_1, 1e-13);
- checkQuantile(new LogGammaAlternateDistribution(4., 1., 0.), P_QUANT, SCIPY_LOGGAMMA_QUANT_4_1, 1e-13);
- checkQuantile(new LogGammaAlternateDistribution(4., 10, 0.), P_QUANT, SCIPY_LOGGAMMA_QUANT_4_10, 1e-13);
- checkQuantile(new LogGammaAlternateDistribution(.1, 10, 0.), P_QUANT, SCIPY_LOGGAMMA_QUANT_01_10, 1e-13);
- checkQuantile(new LogGammaAlternateDistribution(.1, 20, 0.), P_QUANT, SCIPY_LOGGAMMA_QUANT_01_20, 1e-14);
- checkQuantile(new LogGammaAlternateDistribution(.1, 4., 0.), P_QUANT, SCIPY_LOGGAMMA_QUANT_01_4, 1e-13);
- checkQuantile(new LogGammaAlternateDistribution(.1, 1., 0.), P_QUANT, SCIPY_LOGGAMMA_QUANT_01_1, 1e-13);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestLogNormalDistribution.java b/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestLogNormalDistribution.java
deleted file mode 100644
index 61ad82b0..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestLogNormalDistribution.java
+++ /dev/null
@@ -1,518 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for the Normal distribution in ELKI.
- *
- * The reference values were computed using GNU R and SciPy.
- *
- * @author Erich Schubert
- */
-public class TestLogNormalDistribution extends AbstractDistributionTest implements JUnit4Test {
- public static final double[] P_CDFPDF = { //
- 1e-10, 1e-05, 0.1, 0.1234567, 0.2, 0.271828182846, 0.3, 0.314159265359, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.71828182846, 3.14159265359 //
- };
-
- public static final double[] SCIPY_LOGNORM_CDF_0_1 = { //
- 1.28417563064343188586946855334205034593745303926717e-117, // 0.000000
- 5.67797929684089614274940495423182419605501044534498e-31, // 0.000010
- 1.06510993417001289390588780747748387511819601058960e-02, // 0.100000
- 1.82253062118146111347805060631799278780817985534668e-02, // 0.123457
- 5.37603104516631360998424327135580824688076972961426e-02, // 0.200000
- 9.63582248817356212811091609182767570018768310546875e-02, // 0.271828
- 1.14300045049151532960962640572688542306423187255859e-01, // 0.300000
- 1.23461564770417142611336203117389231920242309570312e-01, // 0.314159
- 1.79757213895785417090422697583562694489955902099609e-01, // 0.400000
- 2.44108595785582749293496362952282652258872985839844e-01, // 0.500000
- 3.04736582510231668319278242051950655877590179443359e-01, // 0.600000
- 3.60667582622649085521970846457406878471374511718750e-01, // 0.700000
- 4.11711891857454936882731999503448605537414550781250e-01, // 0.800000
- 4.58044872785658863101332372025353834033012390136719e-01, // 0.900000
- 5.00000000000000000000000000000000000000000000000000e-01, // 1.000000
- 5.37965771424616989726530391635606065392494201660156e-01, // 1.100000
- 5.72334808836768349493695495766587555408477783203125e-01, // 1.200000
- 6.03479689632151705680485065386164933443069458007812e-01, // 1.300000
- 6.31742607836675351684618817671434953808784484863281e-01, // 1.400000
- 6.57432169485154149768391107500065118074417114257812e-01, // 1.500000
- 6.80823787674826652605020171904470771551132202148438e-01, // 1.600000
- 7.02161792699145248519698725431226193904876708984375e-01, // 1.700000
- 7.21662252065084608432243840070441365242004394531250e-01, // 1.800000
- 7.39515971034705121844865516322897747159004211425781e-01, // 1.900000
- 7.55891404214417250706503637047717347741127014160156e-01, // 2.000000
- 8.41344746068542925776512220181757584214210510253906e-01, // 2.718282
- 8.73839466286804089634188130730763077735900878906250e-01, // 3.141593
- };
-
- public static final double[] SCIPY_LOGNORM_PDF_0_1 = { //
- 2.96247992534875871443606538046919616608519359260632e-106, // 0.000000
- 6.58561599261676419576702545979628229597991165133025e-25, // 0.000010
- 2.81590189015268332894947889144532382488250732421875e-01, // 0.100000
- 3.62394132775150645819906003453070297837257385253906e-01, // 0.123457
- 5.46267870758180063006648197188042104244232177734375e-01, // 0.200000
- 6.28312639712034104455540273193037137389183044433594e-01, // 0.271828
- 6.44203257359199588094611499400343745946884155273438e-01, // 0.300000
- 6.49600535087859753957673092372715473175048828125000e-01, // 0.314159
- 6.55444168060311471712964248581556603312492370605469e-01, // 0.400000
- 6.27496077115924366651711352460552006959915161132812e-01, // 0.500000
- 5.83573822594503965888179664034396409988403320312500e-01, // 0.600000
- 5.34794832076919912644541454938007518649101257324219e-01, // 0.700000
- 4.86415781111553480187126297096256166696548461914062e-01, // 0.800000
- 4.40815685912026689052822803205344825983047485351562e-01, // 0.900000
- 3.98942280401432702863218082711682654917240142822266e-01, // 1.000000
- 3.61031261229040001392576186844962649047374725341797e-01, // 1.100000
- 3.26972024074255740444527873478364199399948120117188e-01, // 1.200000
- 2.96496370636105011087124694313388317823410034179688e-01, // 1.300000
- 2.69276228949932749934248477075016126036643981933594e-01, // 1.400000
- 2.44973651710509943146831801641383208334445953369141e-01, // 1.500000
- 2.23265447430299024400568441706127487123012542724609e-01, // 1.600000
- 2.03854259497871476147778935228416230529546737670898e-01, // 1.700000
- 1.86472448538908153192750205562333576381206512451172e-01, // 1.800000
- 1.70882238241215372864800770003057550638914108276367e-01, // 1.900000
- 1.56874019278981091662927838115138001739978790283203e-01, // 2.000000
- 8.90160549159514924433267424319637939333915710449219e-02, // 2.718282
- 6.59491245186608343598066994672990404069423675537109e-02, // 3.141593
- };
-
- public static final double[] GNUR_LOGNORM_CDF_0_1 = { //
- 1.28417563064351817736427131462082407099073717791586e-117, // 0.000000
- 5.67797929684099160620728708239478087513287207088142e-31, // 0.000010
- 1.06510993417001341432293060051961219869554042816162e-02, // 0.100000
- 1.82253062118146215431213619240224943496286869049072e-02, // 0.123457
- 5.37603104516631430387363366207864601165056228637695e-02, // 0.200000
- 9.63582248817956288355901506292866542935371398925781e-02, // 0.271828
- 1.14300045049151519083174832758231787011027336120605e-01, // 0.300000
- 1.23461564770430590187721975325985113158822059631348e-01, // 0.314159
- 1.79757213895785389334847081954649183899164199829102e-01, // 0.400000
- 2.44108595785582721537920747323369141668081283569336e-01, // 0.500000
- 3.04736582510231668319278242051950655877590179443359e-01, // 0.600000
- 3.60667582622649085521970846457406878471374511718750e-01, // 0.700000
- 4.11711891857454936882731999503448605537414550781250e-01, // 0.800000
- 4.58044872785658863101332372025353834033012390136719e-01, // 0.900000
- 5.00000000000000000000000000000000000000000000000000e-01, // 1.000000
- 5.37965771424616989726530391635606065392494201660156e-01, // 1.100000
- 5.72334808836768349493695495766587555408477783203125e-01, // 1.200000
- 6.03479689632151705680485065386164933443069458007812e-01, // 1.300000
- 6.31742607836675351684618817671434953808784484863281e-01, // 1.400000
- 6.57432169485154149768391107500065118074417114257812e-01, // 1.500000
- 6.80823787674826763627322634420124813914299011230469e-01, // 1.600000
- 7.02161792699145248519698725431226193904876708984375e-01, // 1.700000
- 7.21662252065084608432243840070441365242004394531250e-01, // 1.800000
- 7.39515971034705121844865516322897747159004211425781e-01, // 1.900000
- 7.55891404214417250706503637047717347741127014160156e-01, // 2.000000
- 8.41344746068627968860198507172754034399986267089844e-01, // 2.718282
- 8.73839466286817856399693482671864330768585205078125e-01, // 3.141593
- };
-
- public static final double[] GNUR_LOGNORM_PDF_0_1 = { //
- 2.96247992534875823036207602430441206383136443181234e-106, // 0.000000
- 6.58561599261676327741206387988416669540449194645082e-25, // 0.000010
- 2.81590189015268332894947889144532382488250732421875e-01, // 0.100000
- 3.62394132775150590308754772195243276655673980712891e-01, // 0.123457
- 5.46267870758180063006648197188042104244232177734375e-01, // 0.200000
- 6.28312639712100828859320245101116597652435302734375e-01, // 0.271828
- 6.44203257359199588094611499400343745946884155273438e-01, // 0.300000
- 6.49600535087866637340425768343266099691390991210938e-01, // 0.314159
- 6.55444168060311471712964248581556603312492370605469e-01, // 0.400000
- 6.27496077115924366651711352460552006959915161132812e-01, // 0.500000
- 5.83573822594503965888179664034396409988403320312500e-01, // 0.600000
- 5.34794832076919912644541454938007518649101257324219e-01, // 0.700000
- 4.86415781111553424675975065838429145514965057373047e-01, // 0.800000
- 4.40815685912026689052822803205344825983047485351562e-01, // 0.900000
- 3.98942280401432702863218082711682654917240142822266e-01, // 1.000000
- 3.61031261229040001392576186844962649047374725341797e-01, // 1.100000
- 3.26972024074255740444527873478364199399948120117188e-01, // 1.200000
- 2.96496370636105011087124694313388317823410034179688e-01, // 1.300000
- 2.69276228949932694423097245817189104855060577392578e-01, // 1.400000
- 2.44973651710509915391256186012469697743654251098633e-01, // 1.500000
- 2.23265447430298996644992826077213976532220840454102e-01, // 1.600000
- 2.03854259497871476147778935228416230529546737670898e-01, // 1.700000
- 1.86472448538908125437174589933420065790414810180664e-01, // 1.800000
- 1.70882238241215372864800770003057550638914108276367e-01, // 1.900000
- 1.56874019278981091662927838115138001739978790283203e-01, // 2.000000
- 8.90160549158889452536769226753676775842905044555664e-02, // 2.718282
- 6.59491245186515084863998481523594819009304046630859e-02, // 3.141593
- };
-
- public static final double[] SCIPY_LOGNORM_CDF_1_3 = { //
- 5.80027942989772828348821244410095933142208312997823e-16, // 0.000000
- 1.51649466283750378246646117741391890376689843833447e-05, // 0.000010
- 1.35478427197421924521592018209048546850681304931641e-01, // 0.100000
- 1.51359152068233360211024773889221251010894775390625e-01, // 0.123457
- 1.92201402041897895234257021002122201025485992431641e-01, // 0.200000
- 2.21383717792045020544833278108853846788406372070312e-01, // 0.271828
- 2.31274023997502686800231685992912389338016510009766e-01, // 0.300000
- 2.35982646811182916746219007109175436198711395263672e-01, // 0.314159
- 2.61488373016912578616910423079389147460460662841797e-01, // 0.400000
- 2.86246959246035603818825165944872424006462097167969e-01, // 0.500000
- 3.07268244645081289867505347501719370484352111816406e-01, // 0.600000
- 3.25553456641869298771041485451860353350639343261719e-01, // 0.700000
- 3.41741639131648788918482750887051224708557128906250e-01, // 0.800000
- 3.56267553868274411410510538189555518329143524169922e-01, // 0.900000
- 3.69441340181763666628000919445184990763664245605469e-01, // 1.000000
- 3.81492504412193622620463884231867268681526184082031e-01, // 1.100000
- 3.92595931185516167083449090569047257304191589355469e-01, // 1.200000
- 4.02888113368478295583940962387714534997940063476562e-01, // 1.300000
- 4.12477728576550517480825419625034555792808532714844e-01, // 1.400000
- 4.21452783486494730880167480790987610816955566406250e-01, // 1.500000
- 4.29885587708867089595798915979685261845588684082031e-01, // 1.600000
- 4.37836307018417136838195347081637009978294372558594e-01, // 1.700000
- 4.45355558873167967082196128103532828390598297119141e-01, // 1.800000
- 4.52486345581900428758359566927538253366947174072266e-01, // 1.900000
- 4.59265519021804791144347746012499555945396423339844e-01, // 2.000000
- 5.00000000000000000000000000000000000000000000000000e-01, // 2.718282
- 5.19238827154144821918180241482332348823547363281250e-01, // 3.141593
- };
-
- public static final double[] SCIPY_LOGNORM_PDF_1_3 = { //
- 1.57184900048158173423151762193583635962568223476410e-05, // 0.000000
- 2.21855874552272958055709750624373555183410644531250e+00, // 0.000010
- 7.25485663598960939246751422615488991141319274902344e-01, // 0.100000
- 6.33321891615805876440958854800555855035781860351562e-01, // 0.123457
- 4.55481616703077685226475068702711723744869232177734e-01, // 0.200000
- 3.64395441271923081760775176007882691919803619384766e-01, // 0.271828
- 3.38429691850187064350308219218277372419834136962891e-01, // 0.300000
- 3.26808430238364144848617343086516484618186950683594e-01, // 0.314159
- 2.71099452010358343834184324805391952395439147949219e-01, // 0.400000
- 2.26804382443861807239215977460844442248344421386719e-01, // 0.500000
- 1.95237994591654751008746870866161771118640899658203e-01, // 0.600000
- 1.71507274769319928431343669217312708497047424316406e-01, // 0.700000
- 1.52968565294889946581946560399956069886684417724609e-01, // 0.800000
- 1.38059669586597599799659974451060406863689422607422e-01, // 0.900000
- 1.25794409230997716875322112173307687044143676757812e-01, // 1.000000
- 1.15517735625617068428994116402463987469673156738281e-01, // 1.100000
- 1.06776574753620304147894159996212692931294441223145e-01, // 1.200000
- 9.92470359816487873727552937452855985611677169799805e-02, // 1.300000
- 9.26911340280602569219325914673390798270702362060547e-02, // 1.400000
- 8.69298985658228523520918429312587250024080276489258e-02, // 1.500000
- 8.18260363727473238881771067099180072546005249023438e-02, // 1.600000
- 7.72723945276378165747388493400649167597293853759766e-02, // 1.700000
- 7.31840719845132658960551452764775604009628295898438e-02, // 1.800000
- 6.94928962728491861344792823729221709072589874267578e-02, // 1.900000
- 6.61434746059730849232494165335083380341529846191406e-02, // 2.000000
- 4.89208877245799755861810353962937369942665100097656e-02, // 2.718282
- 4.22798605814237726807647277382784523069858551025391e-02, // 3.141593
- };
-
- public static final double[] GNUR_LOGNORM_CDF_1_3 = { //
- 5.80027942989774504678244839060182433065409538918561e-16, // 0.000000
- 1.51649466283750666237848184203507173606340074911714e-05, // 0.000010
- 1.35478427197421869010440786951221525669097900390625e-01, // 0.100000
- 1.51359152068233387966600389518134761601686477661133e-01, // 0.123457
- 1.92201402041897867478681405373208690434694290161133e-01, // 0.200000
- 2.21383717792079853792230892395309638231992721557617e-01, // 0.271828
- 2.31274023997502603533504839106171857565641403198242e-01, // 0.300000
- 2.35982646811189716862244836192985530942678451538086e-01, // 0.314159
- 2.61488373016912634128061654337216168642044067382812e-01, // 0.400000
- 2.86246959246035659329976397202699445188045501708984e-01, // 0.500000
- 3.07268244645081289867505347501719370484352111816406e-01, // 0.600000
- 3.25553456641869243259890254194033332169055938720703e-01, // 0.700000
- 3.41741639131648788918482750887051224708557128906250e-01, // 0.800000
- 3.56267553868274355899359306931728497147560119628906e-01, // 0.900000
- 3.69441340181763666628000919445184990763664245605469e-01, // 1.000000
- 3.81492504412193622620463884231867268681526184082031e-01, // 1.100000
- 3.92595931185516167083449090569047257304191589355469e-01, // 1.200000
- 4.02888113368478295583940962387714534997940063476562e-01, // 1.300000
- 4.12477728576550517480825419625034555792808532714844e-01, // 1.400000
- 4.21452783486494730880167480790987610816955566406250e-01, // 1.500000
- 4.29885587708867089595798915979685261845588684082031e-01, // 1.600000
- 4.37836307018417136838195347081637009978294372558594e-01, // 1.700000
- 4.45355558873167967082196128103532828390598297119141e-01, // 1.800000
- 4.52486345581900428758359566927538253366947174072266e-01, // 1.900000
- 4.59265519021804791144347746012499555945396423339844e-01, // 2.000000
- 5.00000000000046740389336719090351834893226623535156e-01, // 2.718282
- 5.19238827154153592680074780219001695513725280761719e-01, // 3.141593
- };
-
- public static final double[] GNUR_LOGNORM_PDF_1_3 = { //
- 1.57184900048159257625324247698017643415369093418121e-05, // 0.000000
- 2.21855874552272913646788765618111938238143920898438e+00, // 0.000010
- 7.25485663598960717202146497584180906414985656738281e-01, // 0.100000
- 6.33321891615805654396353929769247770309448242187500e-01, // 0.123457
- 4.55481616703077685226475068702711723744869232177734e-01, // 0.200000
- 3.64395441271827880136413568834541365504264831542969e-01, // 0.271828
- 3.38429691850187008839156987960450351238250732421875e-01, // 0.300000
- 3.26808430238347880081306584543199278414249420166016e-01, // 0.314159
- 2.71099452010358343834184324805391952395439147949219e-01, // 0.400000
- 2.26804382443861779483640361831930931657552719116211e-01, // 0.500000
- 1.95237994591654723253171255237248260527849197387695e-01, // 0.600000
- 1.71507274769319928431343669217312708497047424316406e-01, // 0.700000
- 1.52968565294889946581946560399956069886684417724609e-01, // 0.800000
- 1.38059669586597572044084358822146896272897720336914e-01, // 0.900000
- 1.25794409230997716875322112173307687044143676757812e-01, // 1.000000
- 1.15517735625617040673418500773550476878881454467773e-01, // 1.100000
- 1.06776574753620290270106352181755937635898590087891e-01, // 1.200000
- 9.92470359816487596171796781163720879703760147094727e-02, // 1.300000
- 9.26911340280602569219325914673390798270702362060547e-02, // 1.400000
- 8.69298985658228384743040351168019697070121765136719e-02, // 1.500000
- 8.18260363727473238881771067099180072546005249023438e-02, // 1.600000
- 7.72723945276378165747388493400649167597293853759766e-02, // 1.700000
- 7.31840719845132658960551452764775604009628295898438e-02, // 1.800000
- 6.94928962728491861344792823729221709072589874267578e-02, // 1.900000
- 6.61434746059730849232494165335083380341529846191406e-02, // 2.000000
- 4.89208877245627948848749610988306812942028045654297e-02, // 2.718282
- 4.22798605814209346731580296818719943985342979431152e-02, // 3.141593
- };
-
- public static final double[] SCIPY_LOGNORM_CDF_01_01 = { //
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000010
- 7.46586729512055156851629424736742001201359883385653e-128, // 0.100000
- 8.62525588462026443966250245228507150042446838603379e-107, // 0.123457
- 8.17136334615500295339422451815302932260019361648268e-66, // 0.200000
- 5.41526143458555017502898041505360963321909770679929e-45, // 0.271828
- 3.63579783587386242094605540612077634804949224374312e-39, // 0.300000
- 1.38530749241422417511125868885806575792955358046047e-36, // 0.314159
- 1.45144331736744006446530515598948213843059576725939e-24, // 0.400000
- 1.08281884688449672381822010295852147196911971320510e-15, // 0.500000
- 5.03627752858171494558555774501791210684409350051283e-10, // 0.600000
- 2.47672755812896728362052650718183599565236363559961e-06, // 0.700000
- 6.15850565794841134717452213465094246203079819679260e-04, // 0.800000
- 2.00069613308373993321165329462019144557416439056396e-02, // 0.900000
- 1.58655253931456963201185317302588373422622680664062e-01, // 1.000000
- 4.81297180574880578696195243537658825516700744628906e-01, // 1.100000
- 7.94807291306340868430879709194414317607879638671875e-01, // 1.200000
- 9.47773950742736737140603509033098816871643066406250e-01, // 1.300000
- 9.90978204147032748494439147179946303367614746093750e-01, // 1.400000
- 9.98873387527683287423485580802662298083305358886719e-01, // 1.500000
- 9.99892215681807416949311573262093588709831237792969e-01, // 1.600000
- 9.99991698949889484815400919615058228373527526855469e-01, // 1.700000
- 9.99999463803087018654025541763985529541969299316406e-01, // 1.800000
- 9.99999969955960299472508268081583082675933837890625e-01, // 1.900000
- 9.99999998498844355765413638437166810035705566406250e-01, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_LOGNORM_PDF_01_01 = { //
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000010
- 1.79683490350738681626883878695903692927320056006734e-124, // 0.100000
- 1.53451240609964396752170892833443226944498342251986e-103, // 0.123457
- 7.00795903038145442928847865311558208490483375898988e-63, // 0.200000
- 2.80824126786686071155513246881328889371784643139373e-42, // 0.271828
- 1.58951508355228437334280261322875927189162769346195e-36, // 0.300000
- 5.58122798783872171035008357202465427911692811792789e-34, // 0.314159
- 3.72276530194518232247109146801702251947511489941735e-22, // 0.400000
- 1.74416764530574268824702660517399569335391176783112e-13, // 0.500000
- 5.25802665152593504051015431063897942465246160281822e-08, // 0.600000
- 1.68718532893121360123969698641133163619088008999825e-04, // 0.700000
- 2.69358375879647123085636195582992513664066791534424e-02, // 0.800000
- 5.38138135622016955394997239636722952127456665039062e-01, // 0.900000
- 2.41970724519143187691838647879194468259811401367188e+00, // 1.000000
- 3.62276178615723765119582822080701589584350585937500e+00, // 1.100000
- 2.36903587207174082251981417357455939054489135742188e+00, // 1.200000
- 8.21334006428800944554780016915174201130867004394531e-01, // 1.300000
- 1.73985796664595016025600671127904206514358520507812e-01, // 1.400000
- 2.50403898972403581024703811408471665345132350921631e-02, // 1.500000
- 2.65452021073224507866084032059461605967953801155090e-03, // 1.600000
- 2.20631598630764908571672000547891911992337554693222e-04, // 1.700000
- 1.50982513130951377124371742821651309895969461649656e-05, // 1.800000
- 8.84282704123672517376785005144279594446743431035429e-07, // 1.900000
- 4.57223083211032647909217801161785299512985147885047e-08, // 2.000000
- 3.78171735691457591044937145833685229912833032037698e-18, // 2.718282
- 2.52927370006418196229588945092783163653520317423423e-24, // 3.141593
- };
-
- public static final double[] GNUR_LOGNORM_CDF_01_01 = { //
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000010
- 7.46586729512139622334915485545022576086084233165236e-128, // 0.100000
- 8.62525588462074367291196505542133273171533757207493e-107, // 0.123457
- 8.17136334615526229146362798902434829752185485895027e-66, // 0.200000
- 5.41526143485395691388299267636695240314190437945746e-45, // 0.271828
- 3.63579783587375997366590782928570699643197691594649e-39, // 0.300000
- 1.38530749242582464214423634101122722133110779968500e-36, // 0.314159
- 1.45144331736743767674240504821798157693450453457286e-24, // 0.400000
- 1.08281884688450796508611950237674858910117499290887e-15, // 0.500000
- 5.03627752858173148919780880557140953501793489976990e-10, // 0.600000
- 2.47672755812898803592773423754014316955363028682768e-06, // 0.700000
- 6.15850565794842218919624698969528253655880689620972e-04, // 0.800000
- 2.00069613308374652516086200648715021088719367980957e-02, // 0.900000
- 1.58655253931457046467912164189328905194997787475586e-01, // 1.000000
- 4.81297180574880967274253862342447973787784576416016e-01, // 1.100000
- 7.94807291306340868430879709194414317607879638671875e-01, // 1.200000
- 9.47773950742736737140603509033098816871643066406250e-01, // 1.300000
- 9.90978204147032748494439147179946303367614746093750e-01, // 1.400000
- 9.98873387527683287423485580802662298083305358886719e-01, // 1.500000
- 9.99892215681807416949311573262093588709831237792969e-01, // 1.600000
- 9.99991698949889484815400919615058228373527526855469e-01, // 1.700000
- 9.99999463803087018654025541763985529541969299316406e-01, // 1.800000
- 9.99999969955960299472508268081583082675933837890625e-01, // 1.900000
- 9.99999998498844355765413638437166810035705566406250e-01, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_LOGNORM_PDF_01_01 = { //
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.000010
- 1.79683490350738660633521042548751343580552590537274e-124, // 0.100000
- 1.53451240609960034664638006561340724714793008505265e-103, // 0.123457
- 7.00795903038125471789064209408362002551800649974979e-63, // 0.200000
- 2.80824126800431268164764045127534069443724460598013e-42, // 0.271828
- 1.58951508355223927043831980742723065033874451220525e-36, // 0.300000
- 5.58122798788467359181540305857831591200353537133688e-34, // 0.314159
- 3.72276530194518138207561081018701614448588512162081e-22, // 0.400000
- 1.74416764530575505758602047063910454925781540191920e-13, // 0.500000
- 5.25802665152591651166443312281906230509775923565030e-08, // 0.600000
- 1.68718532893122579851413744833621422003488987684250e-04, // 0.700000
- 2.69358375879647331252453312799843843095004558563232e-02, // 0.800000
- 5.38138135622017954595719402277609333395957946777344e-01, // 0.900000
- 2.41970724519143365327522587904240936040878295898438e+00, // 1.000000
- 3.62276178615723720710661837074439972639083862304688e+00, // 1.100000
- 2.36903587207174037843060432351194322109222412109375e+00, // 1.200000
- 8.21334006428800944554780016915174201130867004394531e-01, // 1.300000
- 1.73985796664594405402937127291806973516941070556641e-01, // 1.400000
- 2.50403898972401985079105912745944806374609470367432e-02, // 1.500000
- 2.65452021073223987449041239017333282390609383583069e-03, // 1.600000
- 2.20631598630763743054336578630625353980576619505882e-04, // 1.700000
- 1.50982513130949767761771959651007080083218170329928e-05, // 1.800000
- 8.84282704123670929190008903331143841342054656706750e-07, // 1.900000
- 4.57223083211027817174440491480164050486223459301982e-08, // 2.000000
- 3.78171735679367296188854058553106900541344188905750e-18, // 2.718282
- 2.52927370004658260781217201514446220919197886472664e-24, // 3.141593
- };
-
- public static final double[] P_PROBIT = { //
- 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99, 0.999, 0.9999 //
- };
-
- public static final double[] SCIPY_LOGNORM_QUANT_0_1 = { //
- 2.42578140301463428263328836465007043443620204925537e-02, // 0.000100
- 4.54913852476535249258482451750751351937651634216309e-02, // 0.001000
- 9.76517330703359914823025178520765621215105056762695e-02, // 0.010000
- 2.77606241852009827386638107782346196472644805908203e-01, // 0.100000
- 5.09416283863277530308266705105779692530632019042969e-01, // 0.250000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.96303108415825700028278788522584363818168640136719e+00, // 0.750000
- 3.60222447927915734311454798444174230098724365234375e+00, // 0.900000
- 1.02404736563121314674162931623868644237518310546875e+01, // 0.990000
- 2.19821839795828282149159349501132965087890625000000e+01, // 0.999000
- 4.12238299278443065531973843462765216827392578125000e+01, // 0.999900
- };
-
- public static final double[] GNUR_LOGNORM_QUANT_0_1 = { //
- 2.42578140301463567041206914609574596397578716278076e-02, // 0.000100
- 4.54913852476535249258482451750751351937651634216309e-02, // 0.001000
- 9.76517330703359914823025178520765621215105056762695e-02, // 0.010000
- 2.77606241852009716364335645266692154109477996826172e-01, // 0.100000
- 5.09416283863277530308266705105779692530632019042969e-01, // 0.250000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 1.96303108415825700028278788522584363818168640136719e+00, // 0.750000
- 3.60222447927915911947138738469220697879791259765625e+00, // 0.900000
- 1.02404736563121314674162931623868644237518310546875e+01, // 0.990000
- 2.19821839795828282149159349501132965087890625000000e+01, // 0.999000
- 4.12238299278442923423426691442728042602539062500000e+01, // 0.999900
- };
-
- public static final double[] SCIPY_LOGNORM_QUANT_1_3 = { //
- 3.88015852051401416715654957290126958469045348465443e-05, // 0.000100
- 2.55906882854475099201702059659169208316598087549210e-04, // 0.001000
- 2.53124596262631687548783077090774895623326301574707e-03, // 0.010000
- 5.81543441640198222053470544778974726796150207519531e-02, // 0.100000
- 3.59346113463704264212594807759160175919532775878906e-01, // 0.250000
- 2.71828182845904509079559829842764884233474731445312e+00, // 0.500000
- 2.05625045661638417016092716949060559272766113281250e+01, // 0.750000
- 1.27059400379280148740690492559224367141723632812500e+02, // 0.900000
- 2.91913792971113252860959619283676147460937500000000e+03, // 0.990000
- 2.88740029830793428118340671062469482421875000000000e+04, // 0.999000
- 1.90431809934209391940385103225708007812500000000000e+05, // 0.999900
- };
-
- public static final double[] GNUR_LOGNORM_QUANT_1_3 = { //
- 3.88015852051401484478290737634154083934845402836800e-05, // 0.000100
- 2.55906882854475099201702059659169208316598087549210e-04, // 0.001000
- 2.53124596262631687548783077090774895623326301574707e-03, // 0.010000
- 5.81543441640197528164080154056136962026357650756836e-02, // 0.100000
- 3.59346113463704319723746039016987197101116180419922e-01, // 0.250000
- 2.71828182845904509079559829842764884233474731445312e+00, // 0.500000
- 2.05625045661638417016092716949060559272766113281250e+01, // 0.750000
- 1.27059400379280333481801790185272693634033203125000e+02, // 0.900000
- 2.91913792971113298335694707930088043212890625000000e+03, // 0.990000
- 2.88740029830793428118340671062469482421875000000000e+04, // 0.999000
- 1.90431809934209421044215559959411621093750000000000e+05, // 0.999900
- };
-
- public static final double[] SCIPY_LOGNORM_QUANT_01_01 = { //
- 7.61929194249313157527581097383517771959304809570312e-01, // 0.000100
- 8.11376386650571768122119920008117333054542541503906e-01, // 0.001000
- 8.75784881379674473578234028536826372146606445312500e-01, // 0.010000
- 9.72237506076474744531878968700766563415527343750000e-01, // 0.100000
- 1.03308660502291438376687437994405627250671386718750e+00, // 0.250000
- 1.10517091807564771244187795673497021198272705078125e+00, // 0.500000
- 1.18228496257879456265982298646122217178344726562500e+00, // 0.750000
- 1.25628023042354852734092673927079886198043823242188e+00, // 0.900000
- 1.39463786613445961393153993412852287292480468750000e+00, // 0.990000
- 1.50534669021145739442602007329696789383888244628906e+00, // 0.999000
- 1.60303971468576467174216304556466639041900634765625e+00, // 0.999900
- };
-
- public static final double[] GNUR_LOGNORM_QUANT_01_01 = { //
- 7.61929194249313157527581097383517771959304809570312e-01, // 0.000100
- 8.11376386650571768122119920008117333054542541503906e-01, // 0.001000
- 8.75784881379674362555931566021172329783439636230469e-01, // 0.010000
- 9.72237506076474744531878968700766563415527343750000e-01, // 0.100000
- 1.03308660502291416172226945491274818778038024902344e+00, // 0.250000
- 1.10517091807564771244187795673497021198272705078125e+00, // 0.500000
- 1.18228496257879434061521806142991408705711364746094e+00, // 0.750000
- 1.25628023042354852734092673927079886198043823242188e+00, // 0.900000
- 1.39463786613445961393153993412852287292480468750000e+00, // 0.990000
- 1.50534669021145739442602007329696789383888244628906e+00, // 0.999000
- 1.60303971468576444969755812053335830569267272949219e+00, // 0.999900
- };
-
- @Test
- public void testPDF() {
- checkPDF(new LogNormalDistribution(0., 1., 0), P_CDFPDF, GNUR_LOGNORM_PDF_0_1, 1e-15);
- checkPDF(new LogNormalDistribution(1., 3., 0), P_CDFPDF, GNUR_LOGNORM_PDF_1_3, 1e-15);
- checkPDF(new LogNormalDistribution(.1, .1, 0), P_CDFPDF, GNUR_LOGNORM_PDF_01_01, 1e-15);
- checkPDF(new LogNormalDistribution(0., 1., 0), P_CDFPDF, SCIPY_LOGNORM_PDF_0_1, 1e-12);
- checkPDF(new LogNormalDistribution(1., 3., 0), P_CDFPDF, SCIPY_LOGNORM_PDF_1_3, 1e-12);
- checkPDF(new LogNormalDistribution(.1, .1, 0), P_CDFPDF, SCIPY_LOGNORM_PDF_01_01, 1e-14);
- }
-
- @Test
- public void testCDF() {
- checkCDF(new LogNormalDistribution(0., 1., 0), P_CDFPDF, GNUR_LOGNORM_CDF_0_1, 1e-15);
- checkCDF(new LogNormalDistribution(1., 3., 0), P_CDFPDF, GNUR_LOGNORM_CDF_1_3, 1e-15);
- checkCDF(new LogNormalDistribution(.1, .1, 0), P_CDFPDF, GNUR_LOGNORM_CDF_01_01, 1e-15);
- checkCDF(new LogNormalDistribution(0., 1., 0), P_CDFPDF, SCIPY_LOGNORM_CDF_0_1, 1e-12);
- checkCDF(new LogNormalDistribution(1., 3., 0), P_CDFPDF, SCIPY_LOGNORM_CDF_1_3, 1e-12);
- checkCDF(new LogNormalDistribution(.1, .1, 0), P_CDFPDF, SCIPY_LOGNORM_CDF_01_01, 1e-15);
- }
-
- @Test
- public void testProbit() {
- checkQuantile(new LogNormalDistribution(0., 1., 0), P_PROBIT, GNUR_LOGNORM_QUANT_0_1, 1e-8);
- checkQuantile(new LogNormalDistribution(1., 3., 0), P_PROBIT, GNUR_LOGNORM_QUANT_1_3, 1e-8);
- checkQuantile(new LogNormalDistribution(.1, .1, 0), P_PROBIT, GNUR_LOGNORM_QUANT_01_01, 1e-9);
- checkQuantile(new LogNormalDistribution(0., 1., 0), P_PROBIT, SCIPY_LOGNORM_QUANT_0_1, 1e-8);
- checkQuantile(new LogNormalDistribution(1., 3., 0), P_PROBIT, SCIPY_LOGNORM_QUANT_1_3, 1e-8);
- checkQuantile(new LogNormalDistribution(.1, .1, 0), P_PROBIT, SCIPY_LOGNORM_QUANT_01_01, 1e-9);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestLogisticDistribution.java b/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestLogisticDistribution.java
deleted file mode 100644
index 2a16d24b..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestLogisticDistribution.java
+++ /dev/null
@@ -1,210 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for the Logistic distribution in ELKI.
- *
- * The reference values were computed using GNU R and SciPy.
- *
- * @author Erich Schubert
- */
-public class TestLogisticDistribution extends AbstractDistributionTest implements JUnit4Test {
- public static final double[] P_CDFPDF = { //
- 1e-10, 1e-05, 0.1, 0.1234567, 0.2, 0.271828182846, 0.3, 0.314159265359, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.71828182846, 3.14159265359 //
- };
-
- public static final double[] SCIPY_LOGISTIC_CDF_05 = { //
- 3.77540668821645775121709220911725424230098724365234e-01, // 0.000000
- 3.77543018838145283400109519789111800491809844970703e-01, // 0.000010
- 4.01312339887547997463457249978091567754745483398438e-01, // 0.100000
- 4.06960880864213336849388724658638238906860351562500e-01, // 0.123457
- 4.25557483188341023616629854586790315806865692138672e-01, // 0.200000
- 4.43203246664875705196351418635458685457706451416016e-01, // 0.271828
- 4.50166002687522159853017456043744459748268127441406e-01, // 0.300000
- 4.53673071561317309274841136357281357049942016601562e-01, // 0.314159
- 4.75020812521059987432181515032425522804260253906250e-01, // 0.400000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 5.24979187478939901545516022451920434832572937011719e-01, // 0.600000
- 5.49833997312477840146982543956255540251731872558594e-01, // 0.700000
- 5.74442516811659031894521376671036705374717712402344e-01, // 0.800000
- 5.98687660112452002536542750021908432245254516601562e-01, // 0.900000
- 6.22459331201854593196287623868556693196296691894531e-01, // 1.000000
- 6.45656306225795395548061605950351804494857788085938e-01, // 1.100000
- 6.68187772168166160824398502882104367017745971679688e-01, // 1.200000
- 6.89974481127612504494095446716528385877609252929688e-01, // 1.300000
- 7.10949502625003892930521942616906017065048217773438e-01, // 1.400000
- 7.31058578630004896048433238320285454392433166503906e-01, // 1.500000
- 7.50260105595117687826700603181961923837661743164062e-01, // 1.600000
- 7.68524783499017538623832024313742294907569885253906e-01, // 1.700000
- 7.85834983042558610222272363898809999227523803710938e-01, // 1.800000
- 8.02183888558581692507232219213619828224182128906250e-01, // 1.900000
- 8.17574476193643651100728675373829901218414306640625e-01, // 2.000000
- 9.01879254389253204315934908663621172308921813964844e-01, // 2.718282
- 9.33490913616609740977025921893073245882987976074219e-01, // 3.141593
- };
-
- public static final double[] SCIPY_LOGISTIC_PDF_05 = { //
- 2.35003712207350168306163595843827351927757263183594e-01, // 0.000000
- 2.35004287764725150466915692959446460008621215820312e-01, // 0.000010
- 2.40260745741529169183792191688553430140018463134766e-01, // 0.100000
- 2.41343722310436908928821253539354074746370315551758e-01, // 0.123457
- 2.44458311690745860866869065830542240291833877563477e-01, // 0.200000
- 2.46774128810589049587420618081523571163415908813477e-01, // 0.271828
- 2.47516572711860005640005510940682142972946166992188e-01, // 0.300000
- 2.47853815701437218965708098039613105356693267822266e-01, // 0.314159
- 2.49376040192891945679320997442118823528289794921875e-01, // 0.400000
- 2.50000000000000000000000000000000000000000000000000e-01, // 0.500000
- 2.49376040192891945679320997442118823528289794921875e-01, // 0.600000
- 2.47516572711859950128854279682855121791362762451172e-01, // 0.700000
- 2.44458311690745888622444681459455750882625579833984e-01, // 0.800000
- 2.40260745741529169183792191688553430140018463134766e-01, // 0.900000
- 2.35003712201594494590750628049136139452457427978516e-01, // 1.000000
- 2.28784240456657267381856968313513789325952529907227e-01, // 1.100000
- 2.21712873293109097305730870175466407090425491333008e-01, // 1.200000
- 2.13909696520294428934150232635147403925657272338867e-01, // 1.300000
- 2.05500307342263432985873805591836571693420410156250e-01, // 1.400000
- 1.96611933241481878775758218580449465662240982055664e-01, // 1.500000
- 1.87369879547520601370536041940795257687568664550781e-01, // 1.600000
- 1.77894440646805707118005557276774197816848754882812e-01, // 1.700000
- 1.68298362469060241997098614774586167186498641967773e-01, // 1.800000
- 1.58684897495614651852235965634463354945182800292969e-01, // 1.900000
- 1.49146452070332835582178176991874352097511291503906e-01, // 2.000000
- 8.84930648915379924890345364474342204630374908447266e-02, // 2.718282
- 6.20856278118370533136705091692419955506920814514160e-02, // 3.141593
- };
-
- public static final double[] GNUR_LOGISTIC_CDF_05 = { //
- 3.77540668821645775121709220911725424230098724365234e-01, // 0.000000
- 3.77543018838145283400109519789111800491809844970703e-01, // 0.000010
- 4.01312339887547997463457249978091567754745483398438e-01, // 0.100000
- 4.06960880864213336849388724658638238906860351562500e-01, // 0.123457
- 4.25557483188341023616629854586790315806865692138672e-01, // 0.200000
- 4.43203246664899241924473471954115666449069976806641e-01, // 0.271828
- 4.50166002687522159853017456043744459748268127441406e-01, // 0.300000
- 4.53673071561322416300754412077367305755615234375000e-01, // 0.314159
- 4.75020812521059987432181515032425522804260253906250e-01, // 0.400000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 5.24979187478939901545516022451920434832572937011719e-01, // 0.600000
- 5.49833997312477840146982543956255540251731872558594e-01, // 0.700000
- 5.74442516811659031894521376671036705374717712402344e-01, // 0.800000
- 5.98687660112452002536542750021908432245254516601562e-01, // 0.900000
- 6.22459331201854593196287623868556693196296691894531e-01, // 1.000000
- 6.45656306225795395548061605950351804494857788085938e-01, // 1.100000
- 6.68187772168166160824398502882104367017745971679688e-01, // 1.200000
- 6.89974481127612504494095446716528385877609252929688e-01, // 1.300000
- 7.10949502625003892930521942616906017065048217773438e-01, // 1.400000
- 7.31058578630004896048433238320285454392433166503906e-01, // 1.500000
- 7.50260105595117687826700603181961923837661743164062e-01, // 1.600000
- 7.68524783499017538623832024313742294907569885253906e-01, // 1.700000
- 7.85834983042558610222272363898809999227523803710938e-01, // 1.800000
- 8.02183888558581692507232219213619828224182128906250e-01, // 1.900000
- 8.17574476193643651100728675373829901218414306640625e-01, // 2.000000
- 9.01879254389337470243503958045039325952529907226562e-01, // 2.718282
- 9.33490913616622508541809111193288117647171020507812e-01, // 3.141593
- };
-
- public static final double[] GNUR_LOGISTIC_PDF_05 = { //
- 2.35003712207350168306163595843827351927757263183594e-01, // 0.000000
- 2.35004287764725178222491308588359970599412918090820e-01, // 0.000010
- 2.40260745741529169183792191688553430140018463134766e-01, // 0.100000
- 2.41343722310436908928821253539354074746370315551758e-01, // 0.123457
- 2.44458311690745888622444681459455750882625579833984e-01, // 0.200000
- 2.46774128810591714122679718457220587879419326782227e-01, // 0.271828
- 2.47516572711859977884429895311768632382154464721680e-01, // 0.300000
- 2.47853815701437635299342332473315764218568801879883e-01, // 0.314159
- 2.49376040192891945679320997442118823528289794921875e-01, // 0.400000
- 2.50000000000000000000000000000000000000000000000000e-01, // 0.500000
- 2.49376040192891945679320997442118823528289794921875e-01, // 0.600000
- 2.47516572711859950128854279682855121791362762451172e-01, // 0.700000
- 2.44458311690745888622444681459455750882625579833984e-01, // 0.800000
- 2.40260745741529169183792191688553430140018463134766e-01, // 0.900000
- 2.35003712201594494590750628049136139452457427978516e-01, // 1.000000
- 2.28784240456657267381856968313513789325952529907227e-01, // 1.100000
- 2.21712873293109097305730870175466407090425491333008e-01, // 1.200000
- 2.13909696520294428934150232635147403925657272338867e-01, // 1.300000
- 2.05500307342263432985873805591836571693420410156250e-01, // 1.400000
- 1.96611933241481878775758218580449465662240982055664e-01, // 1.500000
- 1.87369879547520601370536041940795257687568664550781e-01, // 1.600000
- 1.77894440646805707118005557276774197816848754882812e-01, // 1.700000
- 1.68298362469060241997098614774586167186498641967773e-01, // 1.800000
- 1.58684897495614651852235965634463354945182800292969e-01, // 1.900000
- 1.49146452070332835582178176991874352097511291503906e-01, // 2.000000
- 8.84930648914700607177152846816170495003461837768555e-02, // 2.718282
- 6.20856278118259094500608341604674933478236198425293e-02, // 3.141593
- };
-
- public static final double[] P_QUANT = { //
- 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99, 0.999, 0.9999 //
- };
-
- public static final double[] SCIPY_LOGISTIC_QUANT_05 = { //
- -8.71024036697584946864481025841087102890014648437500e+00, // 0.000100
- -6.40675477864855391629816949716769158840179443359375e+00, // 0.001000
- -4.09511985013458978954759004409424960613250732421875e+00, // 0.010000
- -1.69722457733621956421643517387565225362777709960938e+00, // 0.100000
- -5.98612288668109782108217586937826126813888549804688e-01, // 0.250000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 1.59861228866811000415282251196913421154022216796875e+00, // 0.750000
- 2.69722457733621912012722532381303608417510986328125e+00, // 0.900000
- 5.09511985013458357229865214321762323379516601562500e+00, // 0.990000
- 7.40675477864846509845619948464445769786834716796875e+00, // 0.999000
- 9.71024036697667902728881017537787556648254394531250e+00, // 0.999900
- };
-
- public static final double[] GNUR_LOGISTIC_QUANT_05 = { //
- -8.71024036697584946864481025841087102890014648437500e+00, // 0.000100
- -6.40675477864855391629816949716769158840179443359375e+00, // 0.001000
- -4.09511985013458978954759004409424960613250732421875e+00, // 0.010000
- -1.69722457733621912012722532381303608417510986328125e+00, // 0.100000
- -5.98612288668109782108217586937826126813888549804688e-01, // 0.250000
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.500000
- 1.59861228866810978210821758693782612681388854980469e+00, // 0.750000
- 2.69722457733621956421643517387565225362777709960938e+00, // 0.900000
- 5.09511985013458890136917034396901726722717285156250e+00, // 0.990000
- 7.40675477864855302811974979704245924949645996093750e+00, // 0.999000
- 9.71024036697595960276885307393968105316162109375000e+00, // 0.999900
- };
-
- @Test
- public void testPDF() {
- checkPDF(new LogisticDistribution(.5, 1.), P_CDFPDF, SCIPY_LOGISTIC_PDF_05, 1e-12);
- checkPDF(new LogisticDistribution(.5, 1.), P_CDFPDF, GNUR_LOGISTIC_PDF_05, 1e-15);
- }
-
- @Test
- public void testCDF() {
- checkCDF(new LogisticDistribution(.5, 1.), P_CDFPDF, SCIPY_LOGISTIC_CDF_05, 1e-13);
- checkCDF(new LogisticDistribution(.5, 1.), P_CDFPDF, GNUR_LOGISTIC_CDF_05, 0.);
- }
-
- @Test
- public void testProbit() {
- checkQuantile(new LogisticDistribution(.5, 1.), P_QUANT, SCIPY_LOGISTIC_QUANT_05, 1e-13);
- checkQuantile(new LogisticDistribution(.5, 1.), P_QUANT, GNUR_LOGISTIC_QUANT_05, 0.);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestNormalDistribution.java b/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestNormalDistribution.java
deleted file mode 100644
index c4924073..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestNormalDistribution.java
+++ /dev/null
@@ -1,519 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for the Normal distribution in ELKI.
- *
- * The reference values were computed using GNU R and SciPy.
- *
- * @author Erich Schubert
- */
-public class TestNormalDistribution extends AbstractDistributionTest implements JUnit4Test {
- public static final double[] P_CDFPDF = { //
- 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 1e-05, 1e-10, 0.1234567, 3.14159265359, 2.71828182846, 0.314159265359, 0.271828182846 //
- };
-
- public static final double[] SCIPY_NORM_CDF_0_1 = { //
- 5.39827837277028987905680423864396288990974426269531e-01, // 0.100000
- 5.79259709439102987715841663884930312633514404296875e-01, // 0.200000
- 6.17911422188952563772090798011049628257751464843750e-01, // 0.300000
- 6.55421741610324182225610911700641736388206481933594e-01, // 0.400000
- 6.91462461274013118206482886307640001177787780761719e-01, // 0.500000
- 7.25746882249926450469956762390211224555969238281250e-01, // 0.600000
- 7.58036347776926966446353617357090115547180175781250e-01, // 0.700000
- 7.88144601416603363119861569430213421583175659179688e-01, // 0.800000
- 8.15939874653240471147341850155498832464218139648438e-01, // 0.900000
- 8.41344746068542925776512220181757584214210510253906e-01, // 1.000000
- 8.64333939053617328340806125197559595108032226562500e-01, // 1.100000
- 8.84930329778291779874166422814596444368362426757812e-01, // 1.200000
- 9.03199515414389697554042868432588875293731689453125e-01, // 1.300000
- 9.19243340766228933524928379483753815293312072753906e-01, // 1.400000
- 9.33192798731141914814202209527138620615005493164062e-01, // 1.500000
- 9.45200708300442005160846292710630223155021667480469e-01, // 1.600000
- 9.55434537241456993683641485404223203659057617187500e-01, // 1.700000
- 9.64069680887074231812050584267126396298408508300781e-01, // 1.800000
- 9.71283440183998147965382941038114950060844421386719e-01, // 1.900000
- 9.77249868051820791414741051994496956467628479003906e-01, // 2.000000
- 5.00003989422803996056643427436938509345054626464844e-01, // 0.000010
- 5.00000000039894199055368062545312568545341491699219e-01, // 0.000000
- 5.49127269841833243191331348498351871967315673828125e-01, // 0.123457
- 9.99159841831736672546071531542111188173294067382812e-01, // 3.141593
- 9.96718904163704344512098032282665371894836425781250e-01, // 2.718282
- 6.23299960463814084477007781970314681529998779296875e-01, // 0.314159
- 6.07122932952487870394975288945715874433517456054688e-01, // 0.271828
- };
-
- public static final double[] SCIPY_NORM_PDF_0_1 = { //
- 3.96952547477011807863789272232679650187492370605469e-01, // 0.100000
- 3.91042693975455879495939370826818048954010009765625e-01, // 0.200000
- 3.81387815460524137733955285511910915374755859375000e-01, // 0.300000
- 3.68270140303323334496354846123722381889820098876953e-01, // 0.400000
- 3.52065326764299524331391921805334277451038360595703e-01, // 0.500000
- 3.33224602891799670523198528826469555497169494628906e-01, // 0.600000
- 3.12253933366761271539502331506810151040554046630859e-01, // 0.700000
- 2.89691552761482729039244077284820377826690673828125e-01, // 0.800000
- 2.66085249898754816477719487011199817061424255371094e-01, // 0.900000
- 2.41970724519143365327522587904240936040878295898438e-01, // 1.000000
- 2.17852177032550553548162497463636100292205810546875e-01, // 1.100000
- 1.94186054983212980085127696838753763586282730102539e-01, // 1.200000
- 1.71368592047807355438493459587334655225276947021484e-01, // 1.300000
- 1.49727465635744877436863475850259419530630111694336e-01, // 1.400000
- 1.29517595665891743772490940500574652105569839477539e-01, // 1.500000
- 1.10920834679455543314574583746434655040502548217773e-01, // 1.600000
- 9.40490773768869470217168782255612313747406005859375e-02, // 1.700000
- 7.89501583008941493213583839860802982002496719360352e-02, // 1.800000
- 6.56158147746765951779934766818769276142120361328125e-02, // 1.900000
- 5.39909665131880628363703067407186608761548995971680e-02, // 2.000000
- 3.98942280381485603335534051439026370644569396972656e-01, // 0.000010
- 3.98942280401432702863218082711682654917240142822266e-01, // 0.000000
- 3.95913584859803491244889528388739563524723052978516e-01, // 0.123457
- 2.86914634635447975477551274536835990147665143013000e-03, // 3.141593
- 9.91737923440347626802271463475335622206330299377441e-03, // 2.718282
- 3.79733132751562452167348737930296920239925384521484e-01, // 0.314159
- 3.84472192557199943241386108638835139572620391845703e-01, // 0.271828
- };
-
- public static final double[] GNUR_NORM_CDF_0_1 = { //
- 5.39827837277028987905680423864396288990974426269531e-01, // 0.100000
- 5.79259709439102987715841663884930312633514404296875e-01, // 0.200000
- 6.17911422188952674794393260526703670620918273925781e-01, // 0.300000
- 6.55421741610324182225610911700641736388206481933594e-01, // 0.400000
- 6.91462461274013007184180423791985958814620971679688e-01, // 0.500000
- 7.25746882249926450469956762390211224555969238281250e-01, // 0.600000
- 7.58036347776926966446353617357090115547180175781250e-01, // 0.700000
- 7.88144601416603363119861569430213421583175659179688e-01, // 0.800000
- 8.15939874653240471147341850155498832464218139648438e-01, // 0.900000
- 8.41344746068542925776512220181757584214210510253906e-01, // 1.000000
- 8.64333939053617328340806125197559595108032226562500e-01, // 1.100000
- 8.84930329778291779874166422814596444368362426757812e-01, // 1.200000
- 9.03199515414389697554042868432588875293731689453125e-01, // 1.300000
- 9.19243340766228933524928379483753815293312072753906e-01, // 1.400000
- 9.33192798731141914814202209527138620615005493164062e-01, // 1.500000
- 9.45200708300442005160846292710630223155021667480469e-01, // 1.600000
- 9.55434537241456993683641485404223203659057617187500e-01, // 1.700000
- 9.64069680887074231812050584267126396298408508300781e-01, // 1.800000
- 9.71283440183998147965382941038114950060844421386719e-01, // 1.900000
- 9.77249868051820791414741051994496956467628479003906e-01, // 2.000000
- 5.00003989422803996056643427436938509345054626464844e-01, // 0.000010
- 5.00000000039894199055368062545312568545341491699219e-01, // 0.000000
- 5.49127269841833243191331348498351871967315673828125e-01, // 0.123457
- 9.99159841831737227657583844120381399989128112792969e-01, // 3.141593
- 9.96718904163713781407807346113258972764015197753906e-01, // 2.718282
- 6.23299960463821967060482620581751689314842224121094e-01, // 0.314159
- 6.07122932952524618777090381627203896641731262207031e-01, // 0.271828
- };
-
- public static final double[] GNUR_NORM_PDF_0_1 = { //
- 3.96952547477011807863789272232679650187492370605469e-01, // 0.100000
- 3.91042693975455879495939370826818048954010009765625e-01, // 0.200000
- 3.81387815460524137733955285511910915374755859375000e-01, // 0.300000
- 3.68270140303323334496354846123722381889820098876953e-01, // 0.400000
- 3.52065326764299524331391921805334277451038360595703e-01, // 0.500000
- 3.33224602891799670523198528826469555497169494628906e-01, // 0.600000
- 3.12253933366761271539502331506810151040554046630859e-01, // 0.700000
- 2.89691552761482729039244077284820377826690673828125e-01, // 0.800000
- 2.66085249898754816477719487011199817061424255371094e-01, // 0.900000
- 2.41970724519143365327522587904240936040878295898438e-01, // 1.000000
- 2.17852177032550525792586881834722589701414108276367e-01, // 1.100000
- 1.94186054983212952329552081209840252995491027832031e-01, // 1.200000
- 1.71368592047807355438493459587334655225276947021484e-01, // 1.300000
- 1.49727465635744877436863475850259419530630111694336e-01, // 1.400000
- 1.29517595665891743772490940500574652105569839477539e-01, // 1.500000
- 1.10920834679455543314574583746434655040502548217773e-01, // 1.600000
- 9.40490773768869470217168782255612313747406005859375e-02, // 1.700000
- 7.89501583008941493213583839860802982002496719360352e-02, // 1.800000
- 6.56158147746765951779934766818769276142120361328125e-02, // 1.900000
- 5.39909665131880628363703067407186608761548995971680e-02, // 2.000000
- 3.98942280381485603335534051439026370644569396972656e-01, // 0.000010
- 3.98942280401432702863218082711682654917240142822266e-01, // 0.000000
- 3.95913584859803435733738297130912542343139648437500e-01, // 0.123457
- 2.86914634635261405967709968933831987669691443443298e-03, // 3.141593
- 9.91737923437773644108617077108647208660840988159180e-03, // 2.718282
- 3.79733132751559954165543331328080967068672180175781e-01, // 0.314159
- 3.84472192557189951234164482229971326887607574462891e-01, // 0.271828
- };
-
- public static final double[] SCIPY_NORM_CDF_1_3 = { //
- 3.82088577811047380716757970731123350560665130615234e-01, // 0.100000
- 3.94862910464025107515340096142608672380447387695312e-01, // 0.200000
- 4.07751288296895331164648723643040284514427185058594e-01, // 0.300000
- 4.20740290560896956773007104857242666184902191162109e-01, // 0.400000
- 4.33816167389096341011622826044913381338119506835938e-01, // 0.500000
- 4.46964883376386012958647597770323045551776885986328e-01, // 0.600000
- 4.60172162722971012094319576135603711009025573730469e-01, // 0.700000
- 4.73423535699634911999567066231975331902503967285156e-01, // 0.800000
- 4.86704386182907899893734793295152485370635986328125e-01, // 0.900000
- 5.00000000000000000000000000000000000000000000000000e-01, // 1.000000
- 5.13295613817092100106265206704847514629364013671875e-01, // 1.100000
- 5.26576464300365088000432933768024668097496032714844e-01, // 1.200000
- 5.39827837277028987905680423864396288990974426269531e-01, // 1.300000
- 5.53035116623614042552503633487503975629806518554688e-01, // 1.400000
- 5.66183832610903658988377173955086618661880493164062e-01, // 1.500000
- 5.79259709439102987715841663884930312633514404296875e-01, // 1.600000
- 5.92248711703104668835351276356959715485572814941406e-01, // 1.700000
- 6.05137089535974892484659903857391327619552612304688e-01, // 1.800000
- 6.17911422188952563772090798011049628257751464843750e-01, // 1.900000
- 6.30558659818236333371999080554815009236335754394531e-01, // 2.000000
- 3.69442598126554777593355538556352257728576660156250e-01, // 0.000010
- 3.69441340194343048608516255626454949378967285156250e-01, // 0.000000
- 3.85074080732704326912596570764435455203056335449219e-01, // 0.123457
- 7.62344427321841155986703597591258585453033447265625e-01, // 3.141593
- 7.16596603378728214117643346980912610888481140136719e-01, // 2.718282
- 4.09584635073669933724715974676655605435371398925781e-01, // 0.314159
- 4.04109630623745164079707592463819310069084167480469e-01, // 0.271828
- };
-
- public static final double[] SCIPY_NORM_PDF_1_3 = { //
- 1.27129271820174721829843633713608141988515853881836e-01, // 0.100000
- 1.28335624865337977196233509857847820967435836791992e-01, // 0.200000
- 1.29409556907848971585295316799602005630731582641602e-01, // 0.300000
- 1.30347564658485293165313123608939349651336669921875e-01, // 0.400000
- 1.31146572033979974536421764241822529584169387817383e-01, // 0.500000
- 1.31803946961939227877635971708514261990785598754883e-01, // 0.600000
- 1.32317515825670611873121629287197720259428024291992e-01, // 0.700000
- 1.32685575437984065727547999813396017998456954956055e-01, // 0.800000
- 1.32906902451659009178897008496278431266546249389648e-01, // 0.900000
- 1.32980760133810910206264566113532055169343948364258e-01, // 1.000000
- 1.32906902451659009178897008496278431266546249389648e-01, // 1.100000
- 1.32685575437984065727547999813396017998456954956055e-01, // 1.200000
- 1.32317515825670611873121629287197720259428024291992e-01, // 1.300000
- 1.31803946961939227877635971708514261990785598754883e-01, // 1.400000
- 1.31146572033979974536421764241822529584169387817383e-01, // 1.500000
- 1.30347564658485293165313123608939349651336669921875e-01, // 1.600000
- 1.29409556907848971585295316799602005630731582641602e-01, // 1.700000
- 1.28335624865337977196233509857847820967435836791992e-01, // 1.800000
- 1.27129271820174721829843633713608141988515853881836e-01, // 1.900000
- 1.25794409230997744630897727802221197634935379028320e-01, // 2.000000
- 1.25794549001942340682447252220299560576677322387695e-01, // 0.000010
- 1.25794409232395459907749568628787528723478317260742e-01, // 0.000000
- 1.27423930053037842702323700905253645032644271850586e-01, // 0.123457
- 1.03069487463836984009191155564622022211551666259766e-01, // 3.141593
- 1.12863271483980939779989682847372023388743400573730e-01, // 2.718282
- 1.29550708126044883394811790822132024914026260375977e-01, // 0.314159
- 1.29120619428010979801157986912585329264402389526367e-01, // 0.271828
- };
-
- public static final double[] GNUR_NORM_CDF_1_3 = { //
- 3.82088577811047325205606739473296329379081726074219e-01, // 0.100000
- 3.94862910464025163026491327400435693562030792236328e-01, // 0.200000
- 4.07751288296895275653497492385213263332843780517578e-01, // 0.300000
- 4.20740290560897012284158336115069687366485595703125e-01, // 0.400000
- 4.33816167389096341011622826044913381338119506835938e-01, // 0.500000
- 4.46964883376386012958647597770323045551776885986328e-01, // 0.600000
- 4.60172162722971012094319576135603711009025573730469e-01, // 0.700000
- 4.73423535699634911999567066231975331902503967285156e-01, // 0.800000
- 4.86704386182907899893734793295152485370635986328125e-01, // 0.900000
- 5.00000000000000000000000000000000000000000000000000e-01, // 1.000000
- 5.13295613817092100106265206704847514629364013671875e-01, // 1.100000
- 5.26576464300365088000432933768024668097496032714844e-01, // 1.200000
- 5.39827837277028987905680423864396288990974426269531e-01, // 1.300000
- 5.53035116623614042552503633487503975629806518554688e-01, // 1.400000
- 5.66183832610903658988377173955086618661880493164062e-01, // 1.500000
- 5.79259709439102987715841663884930312633514404296875e-01, // 1.600000
- 5.92248711703104668835351276356959715485572814941406e-01, // 1.700000
- 6.05137089535974892484659903857391327619552612304688e-01, // 1.800000
- 6.17911422188952674794393260526703670620918273925781e-01, // 1.900000
- 6.30558659818236333371999080554815009236335754394531e-01, // 2.000000
- 3.69442598126554777593355538556352257728576660156250e-01, // 0.000010
- 3.69441340194343048608516255626454949378967285156250e-01, // 0.000000
- 3.85074080732704326912596570764435455203056335449219e-01, // 0.123457
- 7.62344427321862472268776400596834719181060791015625e-01, // 3.141593
- 7.16596603378836016773334449680987745523452758789062e-01, // 2.718282
- 4.09584635073672598259975075052352622151374816894531e-01, // 0.314159
- 4.04109630623757543066432162959245033562183380126953e-01, // 0.271828
- };
-
- public static final double[] GNUR_NORM_PDF_1_3 = { //
- 1.27129271820174721829843633713608141988515853881836e-01, // 0.100000
- 1.28335624865337977196233509857847820967435836791992e-01, // 0.200000
- 1.29409556907848943829719701170688495039939880371094e-01, // 0.300000
- 1.30347564658485293165313123608939349651336669921875e-01, // 0.400000
- 1.31146572033979974536421764241822529584169387817383e-01, // 0.500000
- 1.31803946961939227877635971708514261990785598754883e-01, // 0.600000
- 1.32317515825670611873121629287197720259428024291992e-01, // 0.700000
- 1.32685575437984065727547999813396017998456954956055e-01, // 0.800000
- 1.32906902451659009178897008496278431266546249389648e-01, // 0.900000
- 1.32980760133810910206264566113532055169343948364258e-01, // 1.000000
- 1.32906902451659009178897008496278431266546249389648e-01, // 1.100000
- 1.32685575437984065727547999813396017998456954956055e-01, // 1.200000
- 1.32317515825670611873121629287197720259428024291992e-01, // 1.300000
- 1.31803946961939227877635971708514261990785598754883e-01, // 1.400000
- 1.31146572033979974536421764241822529584169387817383e-01, // 1.500000
- 1.30347564658485293165313123608939349651336669921875e-01, // 1.600000
- 1.29409556907848943829719701170688495039939880371094e-01, // 1.700000
- 1.28335624865337977196233509857847820967435836791992e-01, // 1.800000
- 1.27129271820174721829843633713608141988515853881836e-01, // 1.900000
- 1.25794409230997716875322112173307687044143676757812e-01, // 2.000000
- 1.25794549001942340682447252220299560576677322387695e-01, // 0.000010
- 1.25794409232395459907749568628787528723478317260742e-01, // 0.000000
- 1.27423930053037842702323700905253645032644271850586e-01, // 0.123457
- 1.03069487463831918616641303287906339392066001892090e-01, // 3.141593
- 1.12863271483960359020670694008003920316696166992188e-01, // 2.718282
- 1.29550708126045049928265484595613088458776473999023e-01, // 0.314159
- 1.29120619428011951246304533924558199942111968994141e-01, // 0.271828
- };
-
- public static final double[] SCIPY_NORM_CDF_01_01 = { //
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.100000
- 8.41344746068542925776512220181757584214210510253906e-01, // 0.200000
- 9.77249868051820791414741051994496956467628479003906e-01, // 0.300000
- 9.98650101968369896532351503992686048150062561035156e-01, // 0.400000
- 9.99968328758166880021462930017150938510894775390625e-01, // 0.500000
- 9.99999713348428076464813329948810860514640808105469e-01, // 0.600000
- 9.99999999013412299575520592043176293373107910156250e-01, // 0.700000
- 9.99999999998720134897212119540199637413024902343750e-01, // 0.800000
- 9.99999999999999333866185224906075745820999145507812e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.58679452213762561818555241188732907176017761230469e-01, // 0.000010
- 1.58655254173427739949886472459184005856513977050781e-01, // 0.000000
- 5.92727587424917268243973467178875580430030822753906e-01, // 0.123457
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 9.83886862290707098210873482457827776670455932617188e-01, // 0.314159
- 9.57127388891955366290176243637688457965850830078125e-01, // 0.271828
- };
-
- public static final double[] SCIPY_NORM_PDF_01_01 = { //
- 3.98942280401432691760987836460117250680923461914062e+00, // 0.100000
- 2.41970724519143365327522587904240936040878295898438e+00, // 0.200000
- 5.39909665131880767141581145551754161715507507324219e-01, // 0.300000
- 4.43184841193799972103306572535075247287750244140625e-02, // 0.400000
- 1.33830225764885362219058784205572010250762104988098e-03, // 0.500000
- 1.48671951473429788965346931561839483038056641817093e-05, // 0.600000
- 6.07588284982330709772167754920135784857393446145579e-08, // 0.700000
- 9.13472040836459525705208369548147081390387924670904e-11, // 0.800000
- 5.05227108353689257466156274028694701290357130241127e-14, // 0.900000
- 1.02797735716689157526658972936723696508848598985854e-17, // 1.000000
- 7.69459862670641946739490369438934977209475249356985e-22, // 1.100000
- 2.11881925350939881499454444092795876174188364829642e-26, // 1.200000
- 2.14638373566309106931513939051468388983176710410808e-31, // 1.300000
- 7.99882775700703797498824580100503753079025371215284e-37, // 1.400000
- 1.09660655938900269201836083695141959890318473157378e-42, // 1.500000
- 5.53070954984441600375694607190945207837912395256854e-49, // 1.600000
- 1.02616307279193257019879511994839957950622370045046e-55, // 1.700000
- 7.00418213431858258321746607183141912867315677743039e-63, // 1.800000
- 1.75874954259520391793557171197265931013763303279246e-70, // 1.900000
- 1.62463603677370066317505050197138645763358359341841e-78, // 2.000000
- 2.41994921591514611236561904661357402801513671875000e+00, // 0.000010
- 2.41970724761114075462842265551444143056869506835938e+00, // 0.000000
- 3.88116637682825116328899639484006911516189575195312e+00, // 0.123457
- 5.14979409860350480381150213015443214774639694748316e-201, // 3.141593
- 5.46759448135644106738407952883081851114066212526125e-149, // 2.718282
- 4.02700170728412354392844463291112333536148071289062e-01, // 0.314159
- 9.11558359421968611435715956758940592408180236816406e-01, // 0.271828
- };
-
- public static final double[] GNUR_NORM_CDF_01_01 = { //
- 5.00000000000000000000000000000000000000000000000000e-01, // 0.100000
- 8.41344746068542925776512220181757584214210510253906e-01, // 0.200000
- 9.77249868051820791414741051994496956467628479003906e-01, // 0.300000
- 9.98650101968369896532351503992686048150062561035156e-01, // 0.400000
- 9.99968328758166880021462930017150938510894775390625e-01, // 0.500000
- 9.99999713348428076464813329948810860514640808105469e-01, // 0.600000
- 9.99999999013412299575520592043176293373107910156250e-01, // 0.700000
- 9.99999999998720134897212119540199637413024902343750e-01, // 0.800000
- 9.99999999999999333866185224906075745820999145507812e-01, // 0.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.100000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.200000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.300000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.400000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.500000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.600000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.700000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.800000
- 1.00000000000000000000000000000000000000000000000000e+00, // 1.900000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.000000
- 1.58679452213762561818555241188732907176017761230469e-01, // 0.000010
- 1.58655254173427739949886472459184005856513977050781e-01, // 0.000000
- 5.92727587424917268243973467178875580430030822753906e-01, // 0.123457
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 9.83886862290715424883558171131880953907966613769531e-01, // 0.314159
- 9.57127388892042407775306855910457670688629150390625e-01, // 0.271828
- };
-
- public static final double[] GNUR_NORM_PDF_01_01 = { //
- 3.98942280401432691760987836460117250680923461914062e+00, // 0.100000
- 2.41970724519143365327522587904240936040878295898438e+00, // 0.200000
- 5.39909665131880767141581145551754161715507507324219e-01, // 0.300000
- 4.43184841193799972103306572535075247287750244140625e-02, // 0.400000
- 1.33830225764885362219058784205572010250762104988098e-03, // 0.500000
- 1.48671951473429755084029041389825920305156614631414e-05, // 0.600000
- 6.07588284982330709772167754920135784857393446145579e-08, // 0.700000
- 9.13472040836459267211266946726998684075171652807512e-11, // 0.800000
- 5.05227108353689257466156274028694701290357130241127e-14, // 0.900000
- 1.02797735716689157526658972936723696508848598985854e-17, // 1.000000
- 7.69459862670641946739490369438934977209475249356985e-22, // 1.100000
- 2.11881925350939881499454444092795876174188364829642e-26, // 1.200000
- 2.14638373566309063140936928900934922616627232600929e-31, // 1.300000
- 7.99882775700703797498824580100503753079025371215284e-37, // 1.400000
- 1.09660655938900253270916972370619189601514495480260e-42, // 1.500000
- 5.53070954984441600375694607190945207837912395256854e-49, // 1.600000
- 1.02616307279193257019879511994839957950622370045046e-55, // 1.700000
- 7.00418213431858258321746607183141912867315677743039e-63, // 1.800000
- 1.75874954259520391793557171197265931013763303279246e-70, // 1.900000
- 1.62463603677370042347322114173083210725409360385417e-78, // 2.000000
- 2.41994921591514611236561904661357402801513671875000e+00, // 0.000010
- 2.41970724761114031053921280545182526111602783203125e+00, // 0.000000
- 3.88116637682825116328899639484006911516189575195312e+00, // 0.123457
- 5.14979409827915730787384521426559029430228517673526e-201, // 3.141593
- 5.46759447998955731091850416560450583665483609253997e-149, // 2.718282
- 4.02700170728233830530484738119412213563919067382812e-01, // 0.314159
- 9.11558359420472030798521245742449536919593811035156e-01, // 0.271828
- };
-
- public static final double[] P_PROBIT = { //
- 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99, 0.999, 0.9999 //
- };
-
- public static final double[] SCIPY_NORM_PROBIT_0_1 = { //
- -3.71901648545568042081299608980771154165267944335938e+00, // 0.000100
- -3.09023230616781319213259848766028881072998046875000e+00, // 0.001000
- -2.32634787404084075745913651189766824245452880859375e+00, // 0.010000
- -1.28155156554460036844034220848698168992996215820312e+00, // 0.100000
- -6.74489750196081816469018122006673365831375122070312e-01, // 0.250000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 6.74489750196081816469018122006673365831375122070312e-01, // 0.750000
- 1.28155156554460036844034220848698168992996215820312e+00, // 0.900000
- 2.32634787404084075745913651189766824245452880859375e+00, // 0.990000
- 3.09023230616781319213259848766028881072998046875000e+00, // 0.999000
- 3.71901648545570839843321664375253021717071533203125e+00, // 0.999900
- };
-
- public static final double[] GNUR_NORM_PROBIT_0_1 = { //
- -3.71901648545567997672378623974509537220001220703125e+00, // 0.000100
- -3.09023230616781319213259848766028881072998046875000e+00, // 0.001000
- -2.32634787404084075745913651189766824245452880859375e+00, // 0.010000
- -1.28155156554460036844034220848698168992996215820312e+00, // 0.100000
- -6.74489750196081705446715659491019323468208312988281e-01, // 0.250000
- 0.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 6.74489750196081705446715659491019323468208312988281e-01, // 0.750000
- 1.28155156554460059048494713351828977465629577636719e+00, // 0.900000
- 2.32634787404084075745913651189766824245452880859375e+00, // 0.990000
- 3.09023230616781274804338863759767264127731323242188e+00, // 0.999000
- 3.71901648545570839843321664375253021717071533203125e+00, // 0.999900
- };
-
- public static final double[] SCIPY_NORM_PROBIT_1_3 = { //
- -1.01570494563670408183497784193605184555053710937500e+01, // 0.000100
- -8.27069691850343957639779546298086643218994140625000e+00, // 0.001000
- -5.97904362212252227237740953569300472736358642578125e+00, // 0.010000
- -2.84465469663380110532102662546094506978988647460938e+00, // 0.100000
- -1.02346925058824567145165929105132818222045898437500e+00, // 0.250000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 3.02346925058824567145165929105132818222045898437500e+00, // 0.750000
- 4.84465469663380154941023647552356123924255371093750e+00, // 0.900000
- 7.97904362212252227237740953569300472736358642578125e+00, // 0.990000
- 1.02706969185034395763977954629808664321899414062500e+01, // 0.999000
- 1.21570494563671260834780696313828229904174804687500e+01, // 0.999900
- };
-
- public static final double[] GNUR_NORM_PROBIT_1_3 = { //
- -1.01570494563670408183497784193605184555053710937500e+01, // 0.000100
- -8.27069691850343957639779546298086643218994140625000e+00, // 0.001000
- -5.97904362212252227237740953569300472736358642578125e+00, // 0.010000
- -2.84465469663380110532102662546094506978988647460938e+00, // 0.100000
- -1.02346925058824500531784451595740392804145812988281e+00, // 0.250000
- 1.00000000000000000000000000000000000000000000000000e+00, // 0.500000
- 3.02346925058824522736244944098871201276779174804688e+00, // 0.750000
- 4.84465469663380154941023647552356123924255371093750e+00, // 0.900000
- 7.97904362212252227237740953569300472736358642578125e+00, // 0.990000
- 1.02706969185034395763977954629808664321899414062500e+01, // 0.999000
- 1.21570494563671243071212302311323583126068115234375e+01, // 0.999900
- };
-
- public static final double[] SCIPY_NORM_PROBIT_01_01 = { //
- -2.71901648545568086490220593987032771110534667968750e-01, // 0.000100
- -2.09023230616781324764374971891811583191156387329102e-01, // 0.001000
- -1.32634787404084075745913651189766824245452880859375e-01, // 0.010000
- -2.81551565544600479462644671002635732293128967285156e-02, // 0.100000
- 3.25510249803918211286557493622240144759416580200195e-02, // 0.250000
- 1.00000000000000005551115123125782702118158340454102e-01, // 0.500000
- 1.67448975019608203851362304703798145055770874023438e-01, // 0.750000
- 2.28155156554460059048494713351828977465629577636719e-01, // 0.900000
- 3.32634787404084086848143897441332228481769561767578e-01, // 0.990000
- 4.09023230616781363622180833772290498018264770507812e-01, // 0.999000
- 4.71901648545570817638861171872122213244438171386719e-01, // 0.999900
- };
-
- public static final double[] GNUR_NORM_PROBIT_01_01 = { //
- -2.71901648545568030979069362729205749928951263427734e-01, // 0.000100
- -2.09023230616781324764374971891811583191156387329102e-01, // 0.001000
- -1.32634787404084075745913651189766824245452880859375e-01, // 0.010000
- -2.81551565544600410073705631930351955816149711608887e-02, // 0.100000
- 3.25510249803918350064435571766807697713375091552734e-02, // 0.250000
- 1.00000000000000005551115123125782702118158340454102e-01, // 0.500000
- 1.67448975019608176095786689074884634464979171752930e-01, // 0.750000
- 2.28155156554460059048494713351828977465629577636719e-01, // 0.900000
- 3.32634787404084086848143897441332228481769561767578e-01, // 0.990000
- 4.09023230616781308111029602514463476836681365966797e-01, // 0.999000
- 4.71901648545570873150012403129949234426021575927734e-01, // 0.999900
- };
-
- @Test
- public void testPDF() {
- checkPDF(new NormalDistribution(0., 1.), P_CDFPDF, SCIPY_NORM_PDF_0_1, 1e-11);
- checkPDF(new NormalDistribution(1., 3.), P_CDFPDF, SCIPY_NORM_PDF_1_3, 1e-12);
- checkPDF(new NormalDistribution(.1, .1), P_CDFPDF, SCIPY_NORM_PDF_01_01, 1e-11);
- checkPDF(new NormalDistribution(0., 1.), P_CDFPDF, GNUR_NORM_PDF_0_1, 1e-15);
- checkPDF(new NormalDistribution(1., 3.), P_CDFPDF, GNUR_NORM_PDF_1_3, 1e-15);
- checkPDF(new NormalDistribution(.1, .1), P_CDFPDF, GNUR_NORM_PDF_01_01, 1e-15);
- }
-
- @Test
- public void testCDF() {
- checkCDF(new NormalDistribution(0., 1.), P_CDFPDF, SCIPY_NORM_CDF_0_1, 1e-13);
- checkCDF(new NormalDistribution(1., 3.), P_CDFPDF, SCIPY_NORM_CDF_1_3, 1e-12);
- checkCDF(new NormalDistribution(.1, .1), P_CDFPDF, SCIPY_NORM_CDF_01_01, 1e-13);
- checkCDF(new NormalDistribution(0., 1.), P_CDFPDF, GNUR_NORM_CDF_0_1, 1e-15);
- checkCDF(new NormalDistribution(1., 3.), P_CDFPDF, GNUR_NORM_CDF_1_3, 1e-15);
- checkCDF(new NormalDistribution(.1, .1), P_CDFPDF, GNUR_NORM_CDF_01_01, 1e-15);
- }
-
- @Test
- public void testProbit() {
- // TODO: improve our implementation, to get more significant digits!
- checkQuantile(new NormalDistribution(0., 1.), P_PROBIT, SCIPY_NORM_PROBIT_0_1, 1e-8);
- checkQuantile(new NormalDistribution(1., 3.), P_PROBIT, SCIPY_NORM_PROBIT_1_3, 1e-9);
- checkQuantile(new NormalDistribution(.1, .1), P_PROBIT, SCIPY_NORM_PROBIT_01_01, 1e-9);
- checkQuantile(new NormalDistribution(0., 1.), P_PROBIT, GNUR_NORM_PROBIT_0_1, 1e-8);
- checkQuantile(new NormalDistribution(1., 3.), P_PROBIT, GNUR_NORM_PROBIT_1_3, 1e-9);
- checkQuantile(new NormalDistribution(.1, .1), P_PROBIT, GNUR_NORM_PROBIT_01_01, 1e-9);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestWeibullDistribution.java b/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestWeibullDistribution.java
deleted file mode 100644
index 15d06c40..00000000
--- a/test/de/lmu/ifi/dbs/elki/math/statistics/distribution/TestWeibullDistribution.java
+++ /dev/null
@@ -1,1291 +0,0 @@
-package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Unit test for the Weibull distribution in ELKI.
- *
- * The reference values were computed using GNU R and SciPy.
- *
- * @author Erich Schubert
- */
-public class TestWeibullDistribution extends AbstractDistributionTest implements JUnit4Test {
- public static final double[] P_CDFPDF = { //
- 1e-10, 1e-05, 0.1, 0.1234567, 0.2, 0.271828182846, 0.3, 0.314159265359, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.71828182846, 3.14159265359 //
- };
-
- public static final double[] SCIPY_WEIBULL_CDF_1_1 = { //
- 9.99999999950000070330663866405545691512513073462287e-11, // 0.000000
- 9.99995000016666629922851977640974041605659294873476e-06, // 0.000010
- 9.51625819640404269073030718573136255145072937011719e-02, // 0.100000
- 1.16140088450309583723019102308171568438410758972168e-01, // 0.123457
- 1.81269246922018151257915974383649881929159164428711e-01, // 0.200000
- 2.38014828033141334628908225568011403083801269531250e-01, // 0.271828
- 2.59181779318282123902861258102348074316978454589844e-01, // 0.300000
- 2.69597308951354364126018481329083442687988281250000e-01, // 0.314159
- 3.29679953964360727969307163220946677029132843017578e-01, // 0.400000
- 3.93469340287366575736882623459678143262863159179688e-01, // 0.500000
- 4.51188363905973555123551932410919107496738433837891e-01, // 0.600000
- 5.03414696208590473069932613725541159510612487792969e-01, // 0.700000
- 5.50671035882778436842954761232249438762664794921875e-01, // 0.800000
- 5.93430340259400890268182138242991641163825988769531e-01, // 0.900000
- 6.32120558828557665975722557050175964832305908203125e-01, // 1.000000
- 6.67128916301920504849931603530421853065490722656250e-01, // 1.100000
- 6.98805788087797918883836700842948630452156066894531e-01, // 1.200000
- 7.27468206965987462808698182925581932067871093750000e-01, // 1.300000
- 7.53403036058393538176858328370144590735435485839844e-01, // 1.400000
- 7.76869839851570209710018843907164409756660461425781e-01, // 1.500000
- 7.98103482005344644356625849468400701880455017089844e-01, // 1.600000
- 8.17316475947265308477085454796906560659408569335938e-01, // 1.700000
- 8.34701111778413440411839019361650571227073669433594e-01, // 1.800000
- 8.50431380777364909206994525447953492403030395507812e-01, // 1.900000
- 8.64664716763387297682186272140825167298316955566406e-01, // 2.000000
- 9.34011964154687457373427150741918012499809265136719e-01, // 2.718282
- 9.56786081736227700389463279861956834793090820312500e-01, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_PDF_1_1 = { //
- 9.99999999899999991725962900090962648391723632812500e-01, // 0.000000
- 9.99990000049999827602675850357627496123313903808594e-01, // 0.000010
- 9.04837418035959517581545696884859353303909301757812e-01, // 0.100000
- 8.83859911549690457910344321135198697447776794433594e-01, // 0.123457
- 8.18730753077981820986508409987436607480049133300781e-01, // 0.200000
- 7.61985171966858665371091774431988596916198730468750e-01, // 0.271828
- 7.40818220681717876097138741897651925683021545410156e-01, // 0.300000
- 7.30402691048645635873981518670916557312011718750000e-01, // 0.314159
- 6.70320046035639327541844068036880344152450561523438e-01, // 0.400000
- 6.06530659712633424263117376540321856737136840820312e-01, // 0.500000
- 5.48811636094026389365296836331253871321678161621094e-01, // 0.600000
- 4.96585303791409526930067386274458840489387512207031e-01, // 0.700000
- 4.49328964117221563157045238767750561237335205078125e-01, // 0.800000
- 4.06569659740599109731817861757008358836174011230469e-01, // 0.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 1.000000
- 3.32871083698079550661219627727405168116092681884766e-01, // 1.100000
- 3.01194211912202136627314530414878390729427337646484e-01, // 1.200000
- 2.72531793034012592702453048332245089113712310791016e-01, // 1.300000
- 2.46596963941606489578717287258768919855356216430664e-01, // 1.400000
- 2.23130160148429818045556771721749100834131240844727e-01, // 1.500000
- 2.01896517994655383398949766160512808710336685180664e-01, // 1.600000
- 1.82683524052734663767338929574179928749799728393555e-01, // 1.700000
- 1.65298888221586531832585365009435918182134628295898e-01, // 1.800000
- 1.49568619222635063037429858923132997006177902221680e-01, // 1.900000
- 1.35335283236612702317813727859174832701683044433594e-01, // 2.000000
- 6.59880358453125426265728492580819875001907348632812e-02, // 2.718282
- 4.32139182637722579771732966946728993207216262817383e-02, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_CDF_1_1 = { //
- 9.99999999950000070330663866405545691512513073462287e-11, // 0.000000
- 9.99995000016666629922851977640974041605659294873476e-06, // 0.000010
- 9.51625819640404269073030718573136255145072937011719e-02, // 0.100000
- 1.16140088450309583723019102308171568438410758972168e-01, // 0.123457
- 1.81269246922018151257915974383649881929159164428711e-01, // 0.200000
- 2.38014828033214137503748020208149682730436325073242e-01, // 0.271828
- 2.59181779318282123902861258102348074316978454589844e-01, // 0.300000
- 2.69597308951369518670304614715860225260257720947266e-01, // 0.314159
- 3.29679953964360727969307163220946677029132843017578e-01, // 0.400000
- 3.93469340287366575736882623459678143262863159179688e-01, // 0.500000
- 4.51188363905973555123551932410919107496738433837891e-01, // 0.600000
- 5.03414696208590473069932613725541159510612487792969e-01, // 0.700000
- 5.50671035882778436842954761232249438762664794921875e-01, // 0.800000
- 5.93430340259400890268182138242991641163825988769531e-01, // 0.900000
- 6.32120558828557665975722557050175964832305908203125e-01, // 1.000000
- 6.67128916301920504849931603530421853065490722656250e-01, // 1.100000
- 6.98805788087797918883836700842948630452156066894531e-01, // 1.200000
- 7.27468206965987462808698182925581932067871093750000e-01, // 1.300000
- 7.53403036058393538176858328370144590735435485839844e-01, // 1.400000
- 7.76869839851570209710018843907164409756660461425781e-01, // 1.500000
- 7.98103482005344644356625849468400701880455017089844e-01, // 1.600000
- 8.17316475947265308477085454796906560659408569335938e-01, // 1.700000
- 8.34701111778413440411839019361650571227073669433594e-01, // 1.800000
- 8.50431380777364909206994525447953492403030395507812e-01, // 1.900000
- 8.64664716763387297682186272140825167298316955566406e-01, // 2.000000
- 9.34011964154750407018923397117760032415390014648438e-01, // 2.718282
- 9.56786081736236693195962743629934266209602355957031e-01, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_PDF_1_1 = { //
- 9.99999999899999991725962900090962648391723632812500e-01, // 0.000000
- 9.99990000049999827602675850357627496123313903808594e-01, // 0.000010
- 9.04837418035959517581545696884859353303909301757812e-01, // 0.100000
- 8.83859911549690457910344321135198697447776794433594e-01, // 0.123457
- 8.18730753077981820986508409987436607480049133300781e-01, // 0.200000
- 7.61985171966785834740676364162936806678771972656250e-01, // 0.271828
- 7.40818220681717876097138741897651925683021545410156e-01, // 0.300000
- 7.30402691048630536840846616541966795921325683593750e-01, // 0.314159
- 6.70320046035639327541844068036880344152450561523438e-01, // 0.400000
- 6.06530659712633424263117376540321856737136840820312e-01, // 0.500000
- 5.48811636094026389365296836331253871321678161621094e-01, // 0.600000
- 4.96585303791409526930067386274458840489387512207031e-01, // 0.700000
- 4.49328964117221563157045238767750561237335205078125e-01, // 0.800000
- 4.06569659740599109731817861757008358836174011230469e-01, // 0.900000
- 3.67879441171442334024277442949824035167694091796875e-01, // 1.000000
- 3.32871083698079550661219627727405168116092681884766e-01, // 1.100000
- 3.01194211912202136627314530414878390729427337646484e-01, // 1.200000
- 2.72531793034012592702453048332245089113712310791016e-01, // 1.300000
- 2.46596963941606489578717287258768919855356216430664e-01, // 1.400000
- 2.23130160148429818045556771721749100834131240844727e-01, // 1.500000
- 2.01896517994655383398949766160512808710336685180664e-01, // 1.600000
- 1.82683524052734663767338929574179928749799728393555e-01, // 1.700000
- 1.65298888221586531832585365009435918182134628295898e-01, // 1.800000
- 1.49568619222635063037429858923132997006177902221680e-01, // 1.900000
- 1.35335283236612702317813727859174832701683044433594e-01, // 2.000000
- 6.59880358452495374699253716244129464030265808105469e-02, // 2.718282
- 4.32139182637633137429311602772941114380955696105957e-02, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_CDF_2_1 = { //
- 1.00000000000000009561654835946237267172778046723484e-20, // 0.000000
- 9.99999999950000199577634577816119890170121209393983e-11, // 0.000010
- 9.95016625083194883316650702909100800752639770507812e-03, // 0.100000
- 1.51259921218065002124220086443528998643159866333008e-02, // 0.123457
- 3.92105608476767952819130869102082215249538421630859e-02, // 0.200000
- 7.12266676857742225825731452459876891225576400756836e-02, // 0.271828
- 8.60688147287718141598134025116451084613800048828125e-02, // 0.300000
- 9.39819442110770147946752217649191152304410934448242e-02, // 0.314159
- 1.47856211033788681463718717168376315385103225708008e-01, // 0.400000
- 2.21199216928595121522960198490181937813758850097656e-01, // 0.500000
- 3.02323673928968916779780329306959174573421478271484e-01, // 0.600000
- 3.87373605815583887945763308380264788866043090820312e-01, // 0.700000
- 4.72707575956951508988623800178174860775470733642578e-01, // 0.800000
- 5.55141933777058893539901873737107962369918823242188e-01, // 0.900000
- 6.32120558828557665975722557050175964832305908203125e-01, // 1.000000
- 7.01802720570112725795297592412680387496948242187500e-01, // 1.100000
- 7.63072241317878208199942946521332487463951110839844e-01, // 1.200000
- 8.15480476007010790517881559935631230473518371582031e-01, // 1.300000
- 8.59141579078954942261248106660787016153335571289062e-01, // 1.400000
- 8.94600775438135653594429186341585591435432434082031e-01, // 1.500000
- 9.22695259556700286829311608016723766922950744628906e-01, // 1.600000
- 9.44423787388516955410011632920941337943077087402344e-01, // 1.700000
- 9.60836104901012899581758119893493130803108215332031e-01, // 1.800000
- 9.72948153133649573653940478834556415677070617675781e-01, // 1.900000
- 9.81684361111265779697987454710528254508972167968750e-01, // 2.000000
- 9.99382021010668863958414931403240188956260681152344e-01, // 2.718282
- 9.99948276813796166351266947458498179912567138671875e-01, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_PDF_2_1 = { //
- 2.00000000000000007286439463099548315833109413119928e-10, // 0.000000
- 1.99999999980000009935313803888234929218015167862177e-05, // 0.000010
- 1.98009966749833621335596944845747202634811401367188e-01, // 0.100000
- 2.43178589856831550708449185549397952854633331298828e-01, // 0.123457
- 3.84315775660929281887234765235916711390018463134766e-01, // 0.200000
- 5.04933534397422723039028369385050609707832336425781e-01, // 0.271828
- 5.48358711162736933708572450996143743395805358886719e-01, // 0.300000
- 5.69267933617237598120652819488896057009696960449219e-01, // 0.314159
- 6.81715031172969165851327488780952990055084228515625e-01, // 0.400000
- 7.78800783071404878477039801509818062186241149902344e-01, // 0.500000
- 8.37211591285237255455342619825387373566627502441406e-01, // 0.600000
- 8.57676951858182490262549890758236870169639587402344e-01, // 0.700000
- 8.43667878468877696640504382230574265122413635253906e-01, // 0.800000
- 8.00744519201293969423716134770074859261512756347656e-01, // 0.900000
- 7.35758882342884668048554885899648070335388183593750e-01, // 1.000000
- 6.56034014745752180886029236717149615287780761718750e-01, // 1.100000
- 5.68626620837092255911215943342540413141250610351562e-01, // 1.200000
- 4.79750762381772055675810406683012843132019042968750e-01, // 1.300000
- 3.94403578578926050646202838834142312407493591308594e-01, // 1.400000
- 3.16197673685592983705561209717416204512119293212891e-01, // 1.500000
- 2.47375169418559082146202854346483945846557617187500e-01, // 1.600000
- 1.88959122879042484832723403087584301829338073730469e-01, // 1.700000
- 1.40990022356353439381138059616205282509326934814453e-01, // 1.800000
- 1.02797018092131570154990072296641301363706588745117e-01, // 1.900000
- 7.32625555549367146745964873844059184193611145019531e-02, // 2.000000
- 3.35968211413639750162474229000508785247802734375000e-03, // 2.718282
- 3.24986363596307557474740512759581179125234484672546e-04, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_CDF_2_1 = { //
- 1.00000000000000009561654835946237267172778046723484e-20, // 0.000000
- 9.99999999950000199577634577816119890170121209393983e-11, // 0.000010
- 9.95016625083194883316650702909100800752639770507812e-03, // 0.100000
- 1.51259921218065002124220086443528998643159866333008e-02, // 0.123457
- 3.92105608476767952819130869102082215249538421630859e-02, // 0.200000
- 7.12266676858224756507809161121258512139320373535156e-02, // 0.271828
- 8.60688147287718141598134025116451084613800048828125e-02, // 0.300000
- 9.39819442110888109143118640531611163169145584106445e-02, // 0.314159
- 1.47856211033788681463718717168376315385103225708008e-01, // 0.400000
- 2.21199216928595121522960198490181937813758850097656e-01, // 0.500000
- 3.02323673928968916779780329306959174573421478271484e-01, // 0.600000
- 3.87373605815583887945763308380264788866043090820312e-01, // 0.700000
- 4.72707575956951508988623800178174860775470733642578e-01, // 0.800000
- 5.55141933777058893539901873737107962369918823242188e-01, // 0.900000
- 6.32120558828557665975722557050175964832305908203125e-01, // 1.000000
- 7.01802720570112725795297592412680387496948242187500e-01, // 1.100000
- 7.63072241317878208199942946521332487463951110839844e-01, // 1.200000
- 8.15480476007010790517881559935631230473518371582031e-01, // 1.300000
- 8.59141579078954942261248106660787016153335571289062e-01, // 1.400000
- 8.94600775438135653594429186341585591435432434082031e-01, // 1.500000
- 9.22695259556700286829311608016723766922950744628906e-01, // 1.600000
- 9.44423787388516955410011632920941337943077087402344e-01, // 1.700000
- 9.60836104901012899581758119893493130803108215332031e-01, // 1.800000
- 9.72948153133649573653940478834556415677070617675781e-01, // 1.900000
- 9.81684361111265779697987454710528254508972167968750e-01, // 2.000000
- 9.99382021010672083605186344357207417488098144531250e-01, // 2.718282
- 9.99948276813796277373569409974152222275733947753906e-01, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_PDF_2_1 = { //
- 2.00000000000000007286439463099548315833109413119928e-10, // 0.000000
- 1.99999999980000009935313803888234929218015167862177e-05, // 0.000010
- 1.98009966749833621335596944845747202634811401367188e-01, // 0.100000
- 2.43178589856831550708449185549397952854633331298828e-01, // 0.123457
- 3.84315775660929281887234765235916711390018463134766e-01, // 0.200000
- 5.04933534397574046437284778221510350704193115234375e-01, // 0.271828
- 5.48358711162736933708572450996143743395805358886719e-01, // 0.300000
- 5.69267933617267685164620161231141537427902221679688e-01, // 0.314159
- 6.81715031172969165851327488780952990055084228515625e-01, // 0.400000
- 7.78800783071404878477039801509818062186241149902344e-01, // 0.500000
- 8.37211591285237255455342619825387373566627502441406e-01, // 0.600000
- 8.57676951858182490262549890758236870169639587402344e-01, // 0.700000
- 8.43667878468877696640504382230574265122413635253906e-01, // 0.800000
- 8.00744519201293969423716134770074859261512756347656e-01, // 0.900000
- 7.35758882342884668048554885899648070335388183593750e-01, // 1.000000
- 6.56034014745752180886029236717149615287780761718750e-01, // 1.100000
- 5.68626620837092255911215943342540413141250610351562e-01, // 1.200000
- 4.79750762381772055675810406683012843132019042968750e-01, // 1.300000
- 3.94403578578926050646202838834142312407493591308594e-01, // 1.400000
- 3.16197673685592983705561209717416204512119293212891e-01, // 1.500000
- 2.47375169418559082146202854346483945846557617187500e-01, // 1.600000
- 1.88959122879042484832723403087584301829338073730469e-01, // 1.700000
- 1.40990022356353439381138059616205282509326934814453e-01, // 1.800000
- 1.02797018092131570154990072296641301363706588745117e-01, // 1.900000
- 7.32625555549367146745964873844059184193611145019531e-02, // 2.000000
- 3.35968211412013880584614966551271209027618169784546e-03, // 2.718282
- 3.24986363595906402670920876118998421588912606239319e-04, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_CDF_4_1 = { //
- 1.00000000000000013320864402483403646202733603332908e-40, // 0.000000
- 1.00000000000000039654310216996797471172433399612973e-20, // 0.000010
- 9.99950001666625217910250311703634906734805554151535e-05, // 0.100000
- 2.32278072192682402295413335302498580858809873461723e-04, // 0.123457
- 1.59872068239368765249497350566798559157177805900574e-03, // 0.200000
- 5.44493730219271481612919316717125184368342161178589e-03, // 0.271828
- 8.06728339442883482512947068698849761858582496643066e-03, // 0.300000
- 9.69362011877886869948284243037051055580377578735352e-03, // 0.314159
- 2.52750983982060611898745605685689952224493026733398e-02, // 0.400000
- 6.05869371865242131725004526288103079423308372497559e-02, // 0.500000
- 1.21553260650068689630032281456806231290102005004883e-01, // 0.600000
- 2.13450797786544993472901410314079839736223220825195e-01, // 0.700000
- 3.36084236664526470050873285799752920866012573242188e-01, // 0.800000
- 4.81129009534547624760136841359781101346015930175781e-01, // 0.900000
- 6.32120558828557665975722557050175964832305908203125e-01, // 1.000000
- 7.68713944715671448904004137148149311542510986328125e-01, // 1.100000
- 8.74267670405572072667155225644819438457489013671875e-01, // 1.200000
- 9.42507455473835520365355478134006261825561523437500e-01, // 1.300000
- 9.78540760919919594407190288620768114924430847167969e-01, // 1.400000
- 9.93670284572514272980470195761881768703460693359375e-01, // 1.500000
- 9.98575023561807495475761697889538481831550598144531e-01, // 1.600000
- 9.99764099393370408996872811258072033524513244628906e-01, // 1.700000
- 9.99972397383803390802370358869666233658790588378906e-01, // 1.800000
- 9.99997811074995079927418828447116538882255554199219e-01, // 1.900000
- 9.99999887464825265581680469040293246507644653320312e-01, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_PDF_4_1 = { //
- 4.00000000000000033334568243034394140372534410747462e-30, // 0.000000
- 4.00000000000000109968250472765612236495730768756629e-15, // 0.000010
- 3.99960001999933451033442111111071426421403884887695e-03, // 0.100000
- 7.52494092430275145211293619240677799098193645477295e-03, // 0.123457
- 3.19488409381634141936956439167261123657226562500000e-02, // 0.200000
- 7.99046897358400981525861084264761302620172500610352e-02, // 0.271828
- 1.07128733393401662232768956073414301499724388122559e-01, // 0.300000
- 1.22822854451452953550294466822379035875201225280762e-01, // 0.314159
- 2.49529574810059301404052689576928969472646713256836e-01, // 0.400000
- 4.69706531406737903822090629546437412500381469726562e-01, // 0.500000
- 7.58977982798340611303444802615558728575706481933594e-01, // 0.600000
- 1.07914550543685994199449851294048130512237548828125e+00, // 0.700000
- 1.35969948331105006111840793892042711377143859863281e+00, // 0.800000
- 1.51302780819725923855401106266072019934654235839844e+00, // 0.900000
- 1.47151776468576933609710977179929614067077636718750e+00, // 1.000000
- 1.23136695833376563768979394808411598205566406250000e+00, // 1.100000
- 8.69061862156685571711989268806064501404762268066406e-01, // 1.200000
- 5.05244481295933911546569561323849484324455261230469e-01, // 1.300000
- 2.35536608142962594625302585882309358566999435424805e-01, // 1.400000
- 8.54511582710575784416207056892744731158018112182617e-02, // 1.500000
- 2.33468139633453281023278691463929135352373123168945e-02, // 1.600000
- 4.63591872148445566931274086641678877640515565872192e-03, // 1.700000
- 6.43913830635281774633638107729893818031996488571167e-04, // 1.800000
- 6.00553464339657769527694441968890259886393323540688e-05, // 1.900000
- 3.60112559101629172664759369337783567743827006779611e-06, // 2.000000
- 1.56051574726592369321459464025011473518080818529307e-22, // 2.718282
- 6.15572040972424438967743933644082832917854496729035e-41, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_CDF_4_1 = { //
- 1.00000000000000013320864402483403646202733603332908e-40, // 0.000000
- 1.00000000000000039654310216996797471172433399612973e-20, // 0.000010
- 9.99950001666625217910250311703634906734805554151535e-05, // 0.100000
- 2.32278072192682402295413335302498580858809873461723e-04, // 0.123457
- 1.59872068239368765249497350566798559157177805900574e-03, // 0.200000
- 5.44493730220034933414696709519375872332602739334106e-03, // 0.271828
- 8.06728339442883482512947068698849761858582496643066e-03, // 0.300000
- 9.69362011878141006937514845276382402516901493072510e-03, // 0.314159
- 2.52750983982060611898745605685689952224493026733398e-02, // 0.400000
- 6.05869371865242131725004526288103079423308372497559e-02, // 0.500000
- 1.21553260650068689630032281456806231290102005004883e-01, // 0.600000
- 2.13450797786544993472901410314079839736223220825195e-01, // 0.700000
- 3.36084236664526470050873285799752920866012573242188e-01, // 0.800000
- 4.81129009534547624760136841359781101346015930175781e-01, // 0.900000
- 6.32120558828557665975722557050175964832305908203125e-01, // 1.000000
- 7.68713944715671448904004137148149311542510986328125e-01, // 1.100000
- 8.74267670405572072667155225644819438457489013671875e-01, // 1.200000
- 9.42507455473835520365355478134006261825561523437500e-01, // 1.300000
- 9.78540760919919594407190288620768114924430847167969e-01, // 1.400000
- 9.93670284572514272980470195761881768703460693359375e-01, // 1.500000
- 9.98575023561807495475761697889538481831550598144531e-01, // 1.600000
- 9.99764099393370408996872811258072033524513244628906e-01, // 1.700000
- 9.99972397383803390802370358869666233658790588378906e-01, // 1.800000
- 9.99997811074995079927418828447116538882255554199219e-01, // 1.900000
- 9.99999887464825265581680469040293246507644653320312e-01, // 2.000000
- 1.00000000000000000000000000000000000000000000000000e+00, // 2.718282
- 1.00000000000000000000000000000000000000000000000000e+00, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_PDF_4_1 = { //
- 4.00000000000000033334568243034394140372534410747462e-30, // 0.000000
- 4.00000000000000109968250472765612236495730768756629e-15, // 0.000010
- 3.99960001999933451033442111111071426421403884887695e-03, // 0.100000
- 7.52494092430275145211293619240677799098193645477295e-03, // 0.123457
- 3.19488409381634141936956439167261123657226562500000e-02, // 0.200000
- 7.99046897359237395797038061573402956128120422363281e-02, // 0.271828
- 1.07128733393401662232768956073414301499724388122559e-01, // 0.300000
- 1.22822854451476920489838562389195431023836135864258e-01, // 0.314159
- 2.49529574810059301404052689576928969472646713256836e-01, // 0.400000
- 4.69706531406737903822090629546437412500381469726562e-01, // 0.500000
- 7.58977982798340611303444802615558728575706481933594e-01, // 0.600000
- 1.07914550543685994199449851294048130512237548828125e+00, // 0.700000
- 1.35969948331104983907380301388911902904510498046875e+00, // 0.800000
- 1.51302780819725901650940613762941211462020874023438e+00, // 0.900000
- 1.47151776468576933609710977179929614067077636718750e+00, // 1.000000
- 1.23136695833376519360058409802149981260299682617188e+00, // 1.100000
- 8.69061862156685904778896656353026628494262695312500e-01, // 1.200000
- 5.05244481295934022568872023839503526687622070312500e-01, // 1.300000
- 2.35536608142962705647605048397963400930166244506836e-01, // 1.400000
- 8.54511582710575784416207056892744731158018112182617e-02, // 1.500000
- 2.33468139633453072856461574247077805921435356140137e-02, // 1.600000
- 4.63591872148445566931274086641678877640515565872192e-03, // 1.700000
- 6.43913830635280690431465622225459810579195618629456e-04, // 1.800000
- 6.00553464339657769527694441968890259886393323540688e-05, // 1.900000
- 3.60112559101629172664759369337783567743827006779611e-06, // 2.000000
- 1.56051574714787161674795427931483364971526738525937e-22, // 2.718282
- 6.15572040956738830521263230405220044059347242007796e-41, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_CDF_4_10 = { //
- 1.00000000000000045083134380686670919466036533826663e-44, // 0.000000
- 1.00000000000000065838446881563251711176039766238496e-24, // 0.000010
- 9.99999995000000102046765708798184424388466595701175e-09, // 0.100000
- 2.32305050223913381984605750103789478799853895907290e-08, // 0.123457
- 1.59999987200000687481607052758958431581959303002805e-07, // 0.200000
- 5.45981351283569954638893052117909476805834856349975e-07, // 0.271828
- 8.09999671950088426490164863341680856478888017591089e-07, // 0.300000
- 9.74090435913627788344247224183725109014631016179919e-07, // 0.314159
- 2.55999672320279633532034806175925467641718569211662e-06, // 0.400000
- 6.24998046879069103125628470429830940702231600880623e-06, // 0.500000
- 1.29599160195627932342429117218429723834560718387365e-05, // 0.600000
- 2.40097117622568567696633018426766170705377589911222e-05, // 0.700000
- 4.09591611506531300059170963567822809636709280312061e-05, // 0.800000
- 6.56078477110208019762102593652741688856622204184532e-05, // 0.900000
- 9.99950001666625217910250311703634906734805554151535e-05, // 1.000000
- 1.46399282579002344489502163149552416143706068396568e-04, // 1.100000
- 2.07338502401139678377878228232589208346325904130936e-04, // 1.200000
- 2.85569217346686983569764572976623639988247305154800e-04, // 1.300000
- 3.84086219995277808499090088645289142732508480548859e-04, // 1.400000
- 5.06121877090403020534037370481428297352977097034454e-04, // 1.500000
- 6.55145298540010952680068267994784037000499665737152e-04, // 1.600000
- 8.34861309211383712837462045541769839474000036716461e-04, // 1.700000
- 1.04920919472584086955257998141632924671284854412079e-03, // 1.800000
- 1.30236119061361726480241518544289647252298891544342e-03, // 1.900000
- 1.59872068239368765249497350566798559157177805900574e-03, // 2.000000
- 5.44493730219271481612919316717125184368342161178589e-03, // 2.718282
- 9.69362011877886869948284243037051055580377578735352e-03, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_PDF_4_10 = { //
- 4.00000000000000056598312279676865044379763820833960e-34, // 0.000000
- 4.00000000000000182691365172827638047889457880763485e-19, // 0.000010
- 3.99999996000000073268388234987158469380119640845805e-07, // 0.100000
- 7.52668903431345566337837965642520998699183110147715e-07, // 0.123457
- 3.19999948800004119659748033632773456247377907857299e-06, // 0.200000
- 8.03421038274362870484652382474521914446086157113314e-06, // 0.271828
- 1.07999912520035405629360153456630655455228406935930e-05, // 0.300000
- 1.24024985909529048835279324558555913426971528679132e-05, // 0.314159
- 2.55999344640838884224441629466895165023743174970150e-05, // 0.400000
- 4.99996875009765654775117926789107514196075499057770e-05, // 0.500000
- 8.63988802632558908862689395213863008393673226237297e-05, // 0.600000
- 1.37196705867546154882993802992530163464834913611412e-04, // 0.700000
- 2.04791611563796387964972445239197895716642960906029e-04, // 0.800000
- 2.91580868751607432971112432440463635430205613374710e-04, // 0.900000
- 3.99960001999933461875463835966115766495931893587112e-04, // 1.000000
- 5.32322057021955194998363847247446756227873265743256e-04, // 1.100000
- 6.91056687627140129107083943438283313298597931861877e-04, // 1.200000
- 8.78549041771795719522886169983166837482713162899017e-04, // 1.300000
- 1.09717842696493267894142231710929991095326840877533e-03, // 1.400000
- 1.34931673546592788628939452166832779766991734504700e-03, // 1.500000
- 1.63732660994287239700217817528482555644586682319641e-03, // 1.600000
- 1.96355933055513721952056727104718447662889957427979e-03, // 1.700000
- 2.33035240479054304302275468785410339478403329849243e-03, // 1.800000
- 2.74002684183743266954635942056484054774045944213867e-03, // 1.900000
- 3.19488409381634124589721679399190179537981748580933e-03, // 2.000000
- 7.99046897358400912136922045192477526143193244934082e-03, // 2.718282
- 1.22822854451452960489188370729607413522899150848389e-02, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_CDF_4_10 = { //
- 1.00000000000000045083134380686670919466036533826663e-44, // 0.000000
- 1.00000000000000065838446881563251711176039766238496e-24, // 0.000010
- 9.99999995000000102046765708798184424388466595701175e-09, // 0.100000
- 2.32305050223913381984605750103789478799853895907290e-08, // 0.123457
- 1.59999987200000687481607052758958431581959303002805e-07, // 0.200000
- 5.45981351284337366489105448225105376991450611967593e-07, // 0.271828
- 8.09999671950088426490164863341680856478888017591089e-07, // 0.300000
- 9.74090435913884227569028463611378043651711777783930e-07, // 0.314159
- 2.55999672320279633532034806175925467641718569211662e-06, // 0.400000
- 6.24998046879069103125628470429830940702231600880623e-06, // 0.500000
- 1.29599160195627932342429117218429723834560718387365e-05, // 0.600000
- 2.40097117622568567696633018426766170705377589911222e-05, // 0.700000
- 4.09591611506531300059170963567822809636709280312061e-05, // 0.800000
- 6.56078477110208019762102593652741688856622204184532e-05, // 0.900000
- 9.99950001666625217910250311703634906734805554151535e-05, // 1.000000
- 1.46399282579002344489502163149552416143706068396568e-04, // 1.100000
- 2.07338502401139678377878228232589208346325904130936e-04, // 1.200000
- 2.85569217346686983569764572976623639988247305154800e-04, // 1.300000
- 3.84086219995277808499090088645289142732508480548859e-04, // 1.400000
- 5.06121877090403020534037370481428297352977097034454e-04, // 1.500000
- 6.55145298540010952680068267994784037000499665737152e-04, // 1.600000
- 8.34861309211383712837462045541769839474000036716461e-04, // 1.700000
- 1.04920919472584086955257998141632924671284854412079e-03, // 1.800000
- 1.30236119061361726480241518544289647252298891544342e-03, // 1.900000
- 1.59872068239368765249497350566798559157177805900574e-03, // 2.000000
- 5.44493730220034412997653916477247548755258321762085e-03, // 2.718282
- 9.69362011878141006937514845276382402516901493072510e-03, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_PDF_4_10 = { //
- 4.00000000000000056598312279676865044379763820833960e-34, // 0.000000
- 4.00000000000000182691365172827638047889457880763485e-19, // 0.000010
- 3.99999996000000073268388234987158469380119640845805e-07, // 0.100000
- 7.52668903431345566337837965642520998699183110147715e-07, // 0.123457
- 3.19999948800004119659748033632773456247377907857299e-06, // 0.200000
- 8.03421038275209734025317231953522423282265663146973e-06, // 0.271828
- 1.07999912520035405629360153456630655455228406935930e-05, // 0.300000
- 1.24024985909553511146796028752348206580791156738997e-05, // 0.314159
- 2.55999344640838884224441629466895165023743174970150e-05, // 0.400000
- 4.99996875009765654775117926789107514196075499057770e-05, // 0.500000
- 8.63988802632558908862689395213863008393673226237297e-05, // 0.600000
- 1.37196705867546154882993802992530163464834913611412e-04, // 0.700000
- 2.04791611563796387964972445239197895716642960906029e-04, // 0.800000
- 2.91580868751607432971112432440463635430205613374710e-04, // 0.900000
- 3.99960001999933461875463835966115766495931893587112e-04, // 1.000000
- 5.32322057021955194998363847247446756227873265743256e-04, // 1.100000
- 6.91056687627140129107083943438283313298597931861877e-04, // 1.200000
- 8.78549041771795719522886169983166837482713162899017e-04, // 1.300000
- 1.09717842696493267894142231710929991095326840877533e-03, // 1.400000
- 1.34931673546592788628939452166832779766991734504700e-03, // 1.500000
- 1.63732660994287239700217817528482555644586682319641e-03, // 1.600000
- 1.96355933055513721952056727104718447662889957427979e-03, // 1.700000
- 2.33035240479054304302275468785410339478403329849243e-03, // 1.800000
- 2.74002684183743266954635942056484054774045944213867e-03, // 1.900000
- 3.19488409381634124589721679399190179537981748580933e-03, // 2.000000
- 7.99046897359236875379995268531274632550776004791260e-03, // 2.718282
- 1.22822854451476917020391610435581242199987173080444e-02, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_CDF_01_10 = { //
- 7.63599351831150269243053685386257711797952651977539e-02, // 0.000000
- 2.22124383190155039180524454422993585467338562011719e-01, // 0.000010
- 4.67917828829414239599771008215611800551414489746094e-01, // 0.100000
- 4.75019399203212733251433519399142824113368988037109e-01, // 0.123457
- 4.91476239432907469062428162942524068057537078857422e-01, // 0.200000
- 5.02079925428299933543030419968999922275543212890625e-01, // 0.271828
- 5.05508894037498435203303870366653427481651306152344e-01, // 0.300000
- 5.07115955277961494296334876707987859845161437988281e-01, // 0.314159
- 5.15568704992931170494330217479728162288665771484375e-01, // 0.400000
- 5.23427039033618868302255577873438596725463867187500e-01, // 0.500000
- 5.29881674984790551619084908452350646257400512695312e-01, // 0.600000
- 5.35361615308103777621795416052918881177902221679688e-01, // 0.700000
- 5.40124560432196254566861171042546629905700683593750e-01, // 0.800000
- 5.44337595924840766947738757153274491429328918457031e-01, // 0.900000
- 5.48115306569588400797954363952158018946647644042969e-01, // 1.000000
- 5.51539729658985344862287547584855929017066955566406e-01, // 1.100000
- 5.54671638850380399610173753899289295077323913574219e-01, // 1.200000
- 5.57557321771014247069331304373918101191520690917969e-01, // 1.300000
- 5.60232853193344815245779955148464068770408630371094e-01, // 1.400000
- 5.62726898877477954563630646589444950222969055175781e-01, // 1.500000
- 5.65062617878835049545216406841063871979713439941406e-01, // 1.600000
- 5.67258990450220990098273432522546499967575073242188e-01, // 1.700000
- 5.69331767989112891292791118758032098412513732910156e-01, // 1.800000
- 5.71294167272651032263297565805260092020034790039062e-01, // 1.900000
- 5.73157387426872722002713089750614017248153686523438e-01, // 2.000000
- 5.84332020844404609327682464936515316367149353027344e-01, // 2.718282
- 5.89617748244351203013025042309891432523727416992188e-01, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_PDF_01_10 = { //
- 7.33673382206617593765258789062500000000000000000000e+07, // 0.000000
- 1.95393520726679525978397578001022338867187500000000e+03, // 0.000010
- 3.35721153767048474669820734561653807759284973144531e-01, // 0.100000
- 2.74018609307649319006827681732829660177230834960938e-01, // 0.123457
- 1.71942902599836300314706249992013908922672271728516e-01, // 0.200000
- 1.27730497083068800234784134772780817002058029174805e-01, // 0.271828
- 1.16077849986715483932009362888493342325091361999512e-01, // 0.300000
- 1.10996650714204211918278986104269279167056083679199e-01, // 0.314159
- 8.77764877675434873616211461921920999884605407714844e-02, // 0.400000
- 7.06409277770171650789876593989902175962924957275391e-02, // 0.500000
- 5.91386021268343400891787098316854098811745643615723e-02, // 0.600000
- 5.08776272124714656897026543447282165288925170898438e-02, // 0.700000
- 4.46538827467651763813982768169807968661189079284668e-02, // 0.800000
- 3.97946728437166968861404825474892277270555496215820e-02, // 0.900000
- 3.58944770831502030228321586946549359709024429321289e-02, // 1.000000
- 3.26941881616923946118902222224278375506401062011719e-02, // 1.100000
- 3.00204524249116540268733643870291416533291339874268e-02, // 1.200000
- 2.77528760154124205794534674396345508284866809844971e-02, // 1.300000
- 2.58052190382604060281401814336277311667799949645996e-02, // 1.400000
- 2.41140762238259073746426963680278277024626731872559e-02, // 1.500000
- 2.26317820314968741468586443943422636948525905609131e-02, // 1.600000
- 2.13218078236213533227516592205574852414429187774658e-02, // 1.700000
- 2.01556859486728690011858589059556834399700164794922e-02, // 1.800000
- 1.91109005040240170769649807880341541022062301635742e-02, // 1.900000
- 1.81694078358287762486877880974134313873946666717529e-02, // 2.000000
- 1.34239874155454609605531146598877967335283756256104e-02, // 2.718282
- 1.16346596858789251560661881512714899145066738128662e-02, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_CDF_01_10 = { //
- 7.63599351831150269243053685386257711797952651977539e-02, // 0.000000
- 2.22124383190155039180524454422993585467338562011719e-01, // 0.000010
- 4.67917828829414239599771008215611800551414489746094e-01, // 0.100000
- 4.75019399203212733251433519399142824113368988037109e-01, // 0.123457
- 4.91476239432907469062428162942524068057537078857422e-01, // 0.200000
- 5.02079925428312145996301296690944582223892211914062e-01, // 0.271828
- 5.05508894037498435203303870366653427481651306152344e-01, // 0.300000
- 5.07115955277963825764686589536722749471664428710938e-01, // 0.314159
- 5.15568704992931170494330217479728162288665771484375e-01, // 0.400000
- 5.23427039033618868302255577873438596725463867187500e-01, // 0.500000
- 5.29881674984790551619084908452350646257400512695312e-01, // 0.600000
- 5.35361615308103777621795416052918881177902221679688e-01, // 0.700000
- 5.40124560432196254566861171042546629905700683593750e-01, // 0.800000
- 5.44337595924840766947738757153274491429328918457031e-01, // 0.900000
- 5.48115306569588400797954363952158018946647644042969e-01, // 1.000000
- 5.51539729658985344862287547584855929017066955566406e-01, // 1.100000
- 5.54671638850380399610173753899289295077323913574219e-01, // 1.200000
- 5.57557321771014247069331304373918101191520690917969e-01, // 1.300000
- 5.60232853193344815245779955148464068770408630371094e-01, // 1.400000
- 5.62726898877477954563630646589444950222969055175781e-01, // 1.500000
- 5.65062617878835049545216406841063871979713439941406e-01, // 1.600000
- 5.67258990450220990098273432522546499967575073242188e-01, // 1.700000
- 5.69331767989112891292791118758032098412513732910156e-01, // 1.800000
- 5.71294167272651032263297565805260092020034790039062e-01, // 1.900000
- 5.73157387426872722002713089750614017248153686523438e-01, // 2.000000
- 5.84332020844417376892465654236730188131332397460938e-01, // 2.718282
- 5.89617748244353534481376755138626322150230407714844e-01, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_PDF_01_10 = { //
- 7.33673382206617444753646850585937500000000000000000e+07, // 0.000000
- 1.95393520726679525978397578001022338867187500000000e+03, // 0.000010
- 3.35721153767048474669820734561653807759284973144531e-01, // 0.100000
- 2.74018609307649374517978912990656681358814239501953e-01, // 0.123457
- 1.71942902599836300314706249992013908922672271728516e-01, // 0.200000
- 1.27730497083025279492218828636396210640668869018555e-01, // 0.271828
- 1.16077849986715470054221555074036587029695510864258e-01, // 0.300000
- 1.10996650714197092613133577287953812628984451293945e-01, // 0.314159
- 8.77764877675434734838333383777353446930646896362305e-02, // 0.400000
- 7.06409277770171650789876593989902175962924957275391e-02, // 0.500000
- 5.91386021268343470280726137389137875288724899291992e-02, // 0.600000
- 5.08776272124714656897026543447282165288925170898438e-02, // 0.700000
- 4.46538827467651833202921807242091745138168334960938e-02, // 0.800000
- 3.97946728437166968861404825474892277270555496215820e-02, // 0.900000
- 3.58944770831502030228321586946549359709024429321289e-02, // 1.000000
- 3.26941881616924015507841261296562151983380317687988e-02, // 1.100000
- 3.00204524249116540268733643870291416533291339874268e-02, // 1.200000
- 2.77528760154124205794534674396345508284866809844971e-02, // 1.300000
- 2.58052190382604025586932294800135423429310321807861e-02, // 1.400000
- 2.41140762238259073746426963680278277024626731872559e-02, // 1.500000
- 2.26317820314968706774116924407280748710036277770996e-02, // 1.600000
- 2.13218078236213498533047072669432964175939559936523e-02, // 1.700000
- 2.01556859486728690011858589059556834399700164794922e-02, // 1.800000
- 1.91109005040240136075180288344199652783572673797607e-02, // 1.900000
- 1.81694078358287727792408361437992425635457038879395e-02, // 2.000000
- 1.34239874155408032280201169328393007162958383560181e-02, // 2.718282
- 1.16346596858781688166306622633783263154327869415283e-02, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_CDF_01_20 = { //
- 7.14336532604261248424748487195756752043962478637695e-02, // 0.000000
- 2.08928790931204783065666674701787997037172317504883e-01, // 0.000010
- 4.44953851727799498672055733550223521888256072998047e-01, // 0.100000
- 4.51868924426242546399379307331400923430919647216797e-01, // 0.123457
- 4.67917828829414239599771008215611800551414489746094e-01, // 0.200000
- 4.78277040424782917682478000642731785774230957031250e-01, // 0.271828
- 4.81630099462710015156829967963858507573604583740234e-01, // 0.300000
- 4.83202119329382395740424271934898570179939270019531e-01, // 0.314159
- 4.91476239432907469062428162942524068057537078857422e-01, // 0.400000
- 4.99177179518956792847461656492669135332107543945312e-01, // 0.500000
- 5.05508894037498435203303870366653427481651306152344e-01, // 0.600000
- 5.10889043159064359933552168513415381312370300292969e-01, // 0.700000
- 5.15568704992931170494330217479728162288665771484375e-01, // 0.800000
- 5.19710777811082103028184064896777272224426269531250e-01, // 0.900000
- 5.23427039033618868302255577873438596725463867187500e-01, // 1.000000
- 5.26797557160076923565839024377055466175079345703125e-01, // 1.100000
- 5.29881674984790551619084908452350646257400512695312e-01, // 1.200000
- 5.32724609600441545431692702550208196043968200683594e-01, // 1.300000
- 5.35361615308103777621795416052918881177902221679688e-01, // 1.400000
- 5.37820716140765320290029194438830018043518066406250e-01, // 1.500000
- 5.40124560432196254566861171042546629905700683593750e-01, // 1.600000
- 5.42291715817192598869667108374414965510368347167969e-01, // 1.700000
- 5.44337595924840766947738757153274491429328918457031e-01, // 1.800000
- 5.46275137813967970323858480696799233555793762207031e-01, // 1.900000
- 5.48115306569588400797954363952158018946647644042969e-01, // 2.000000
- 5.59163067520781487118597397056873887777328491210938e-01, // 2.718282
- 5.64395683719495666608167994127143174409866333007812e-01, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_PDF_01_20 = { //
- 6.88192507850085347890853881835937500000000000000000e+07, // 0.000000
- 1.85401216383494602268910966813564300537109375000000e+03, // 0.000010
- 3.26757898025421766874387685675173997879028320312500e-01, // 0.100000
- 2.66942809682530424186808204467524774372577667236328e-01, // 0.123457
- 1.67860576883524237334910367280826903879642486572266e-01, // 0.200000
- 1.24873969109886198691761194368154974654316902160645e-01, // 0.271828
- 1.13534446544550443602972222834068816155195236206055e-01, // 0.300000
- 1.08588251220167866795129896217986242845654487609863e-01, // 0.314159
- 8.59714512999181501573531249960069544613361358642578e-02, // 0.400000
- 6.92640857666013964877294029065524227917194366455078e-02, // 0.500000
- 5.80389249933577419660046814442466711625456809997559e-02, // 0.600000
- 4.99707831949509073687920590600697323679924011230469e-02, // 0.700000
- 4.38882438837717436808105730960960499942302703857422e-02, // 0.800000
- 3.91364638781799556443985466103185899555683135986328e-02, // 0.900000
- 3.53204638885085825394938296994951087981462478637695e-02, // 1.000000
- 3.21877457163609673185256099259277107194066047668457e-02, // 1.100000
- 2.95693010634171700445893549158427049405872821807861e-02, // 1.200000
- 2.73477053682244612697882502061474951915442943572998e-02, // 1.300000
- 2.54388136062357328448513271723641082644462585449219e-02, // 1.400000
- 2.37807387894387115001570975891809212043881416320801e-02, // 1.500000
- 2.23269413733825881906991384084903984330594539642334e-02, // 1.600000
- 2.10417445599888272567135061308363219723105430603027e-02, // 1.700000
- 1.98973364218583484430702412737446138635277748107910e-02, // 1.800000
- 1.88717135986907202926943227794254198670387268066406e-02, // 1.900000
- 1.79472385415751015114160793473274679854512214660645e-02, // 2.000000
- 1.32834210371973356068497906790071283467113971710205e-02, // 2.718282
- 1.15227009149735971915706755908104241825640201568604e-02, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_CDF_01_20 = { //
- 7.14336532604261248424748487195756752043962478637695e-02, // 0.000000
- 2.08928790931204783065666674701787997037172317504883e-01, // 0.000010
- 4.44953851727799498672055733550223521888256072998047e-01, // 0.100000
- 4.51868924426242546399379307331400923430919647216797e-01, // 0.123457
- 4.67917828829414239599771008215611800551414489746094e-01, // 0.200000
- 4.78277040424794852579992721075541339814662933349609e-01, // 0.271828
- 4.81630099462710015156829967963858507573604583740234e-01, // 0.300000
- 4.83202119329384616186473522247979417443275451660156e-01, // 0.314159
- 4.91476239432907469062428162942524068057537078857422e-01, // 0.400000
- 4.99177179518956792847461656492669135332107543945312e-01, // 0.500000
- 5.05508894037498435203303870366653427481651306152344e-01, // 0.600000
- 5.10889043159064359933552168513415381312370300292969e-01, // 0.700000
- 5.15568704992931170494330217479728162288665771484375e-01, // 0.800000
- 5.19710777811082103028184064896777272224426269531250e-01, // 0.900000
- 5.23427039033618868302255577873438596725463867187500e-01, // 1.000000
- 5.26797557160076923565839024377055466175079345703125e-01, // 1.100000
- 5.29881674984790551619084908452350646257400512695312e-01, // 1.200000
- 5.32724609600441545431692702550208196043968200683594e-01, // 1.300000
- 5.35361615308103777621795416052918881177902221679688e-01, // 1.400000
- 5.37820716140765320290029194438830018043518066406250e-01, // 1.500000
- 5.40124560432196254566861171042546629905700683593750e-01, // 1.600000
- 5.42291715817192598869667108374414965510368347167969e-01, // 1.700000
- 5.44337595924840766947738757153274491429328918457031e-01, // 1.800000
- 5.46275137813967970323858480696799233555793762207031e-01, // 1.900000
- 5.48115306569588400797954363952158018946647644042969e-01, // 2.000000
- 5.59163067520794143661078123841434717178344726562500e-01, // 2.718282
- 5.64395683719498109098822169471532106399536132812500e-01, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_PDF_01_20 = { //
- 6.88192507850085496902465820312500000000000000000000e+07, // 0.000000
- 1.85401216383494602268910966813564300537109375000000e+03, // 0.000010
- 3.26757898025421711363236454417346976697444915771484e-01, // 0.100000
- 2.66942809682530313164505741951870732009410858154297e-01, // 0.123457
- 1.67860576883524237334910367280826903879642486572266e-01, // 0.200000
- 1.24873969109843857561159552460594568401575088500977e-01, // 0.271828
- 1.13534446544550429725184415019612060859799385070801e-01, // 0.300000
- 1.08588251220160983412377220247435616329312324523926e-01, // 0.314159
- 8.59714512999181501573531249960069544613361358642578e-02, // 0.400000
- 6.92640857666013964877294029065524227917194366455078e-02, // 0.500000
- 5.80389249933577350271107775370182935148477554321289e-02, // 0.600000
- 4.99707831949509143076859629672981100156903266906738e-02, // 0.700000
- 4.38882438837717367419166691888676723465323448181152e-02, // 0.800000
- 3.91364638781799487055046427030902123078703880310059e-02, // 0.900000
- 3.53204638885085825394938296994951087981462478637695e-02, // 1.000000
- 3.21877457163609673185256099259277107194066047668457e-02, // 1.100000
- 2.95693010634171735140363068694568937644362449645996e-02, // 1.200000
- 2.73477053682244578003412982525333063676953315734863e-02, // 1.300000
- 2.54388136062357328448513271723641082644462585449219e-02, // 1.400000
- 2.37807387894387115001570975891809212043881416320801e-02, // 1.500000
- 2.23269413733825916601460903621045872569084167480469e-02, // 1.600000
- 2.10417445599888272567135061308363219723105430603027e-02, // 1.700000
- 1.98973364218583484430702412737446138635277748107910e-02, // 1.800000
- 1.88717135986907202926943227794254198670387268066406e-02, // 1.900000
- 1.79472385415751015114160793473274679854512214660645e-02, // 2.000000
- 1.32834210371927524674262599546636920422315597534180e-02, // 2.718282
- 1.15227009149728529951994815405669214669615030288696e-02, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_CDF_01_4 = { //
- 8.33733718538829660094080509225022979080677032470703e-02, // 0.000000
- 2.40649836762494045983018509105022531002759933471680e-01, // 0.000010
- 4.99177179518956792847461656492669135332107543945312e-01, // 0.100000
- 5.06498248113537830050745469634421169757843017578125e-01, // 0.123457
- 5.23427039033618868302255577873438596725463867187500e-01, // 0.200000
- 5.34307105228540524244351672678021714091300964355469e-01, // 0.271828
- 5.37820716140765320290029194438830018043518066406250e-01, // 0.300000
- 5.39466643360843156607131732016569003462791442871094e-01, // 0.314159
- 5.48115306569588400797954363952158018946647644042969e-01, // 0.400000
- 5.56142802864377228111436579638393595814704895019531e-01, // 0.500000
- 5.62726898877477954563630646589444950222969055175781e-01, // 0.600000
- 5.68309949920494883457422474748454988002777099609375e-01, // 0.700000
- 5.73157387426872722002713089750614017248153686523438e-01, // 0.800000
- 5.77441148174444141005778874387033283710479736328125e-01, // 0.900000
- 5.81279046613597527581873691815417259931564331054688e-01, // 1.000000
- 5.84755370118739237206284542480716481804847717285156e-01, // 1.100000
- 5.87932517498272577682882911176420748233795166015625e-01, // 1.200000
- 5.90857985095490256810535356635227799415588378906250e-01, // 1.300000
- 5.93568768820695535914921947551192715764045715332031e-01, // 1.400000
- 5.96094250977751372033708321396261453628540039062500e-01, // 1.500000
- 5.98458157890379149890236476494465023279190063476562e-01, // 1.600000
- 6.00679925779863399526448120013810694217681884765625e-01, // 1.700000
- 6.02775677450659741474225938873132690787315368652344e-01, // 1.800000
- 6.04758935771455119478900996909942477941513061523438e-01, // 1.900000
- 6.06641154768875257019544733338989317417144775390625e-01, // 2.000000
- 6.17913083162751508581322923419065773487091064453125e-01, // 2.718282
- 6.23234757420644713832302841183263808488845825195312e-01, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_PDF_01_4 = { //
- 7.97969827464829683303833007812500000000000000000000e+07, // 0.000000
- 2.09043222444361890666186809539794921875000000000000e+03, // 0.000010
- 3.46320428833006954683071398903848603367805480957031e-01, // 0.100000
- 2.82305605668253523088395695594954304397106170654297e-01, // 0.123457
- 1.76602319442542926575256956311932299286127090454102e-01, // 0.200000
- 1.30926807720308208127235616302641574293375015258789e-01, // 0.271828
- 1.18903693947193564439679391853132983669638633728027e-01, // 0.300000
- 1.13663285983750791952040515297994716092944145202637e-01, // 0.314159
- 8.97361927078755006181864928294089622795581817626953e-02, // 0.400000
- 7.21048144026743415002655979151313658803701400756836e-02, // 0.500000
- 6.02851905595647649671597889664553804323077201843262e-02, // 0.600000
- 5.18057307044127585138326708147360477596521377563477e-02, // 0.700000
- 4.54235195895719423564429462203406728804111480712891e-02, // 0.800000
- 4.04448236551064599364480045551317743957042694091797e-02, // 0.900000
- 3.64517761834422873712391321987524861469864845275879e-02, // 1.000000
- 3.31775726553523511719312466539122397080063819885254e-02, // 1.100000
- 3.04438254891350006114958404168646666221320629119873e-02, // 1.200000
- 2.81267182882828474521641481942424434237182140350342e-02, // 1.300000
- 2.61376080752830329545499665755414753220975399017334e-02, // 1.400000
- 2.44113559017523976124586226887913653627038002014160e-02, // 1.500000
- 2.28990161555940596738167869261815212666988372802734e-02, // 1.600000
- 2.15630959198551165612034452578882337547838687896729e-02, // 1.700000
- 2.03743883245797278991329193331694114021956920623779e-02, // 1.800000
- 1.93098019737789824978868580274138366803526878356934e-02, // 1.900000
- 1.83508390056730183448330251394509105011820793151855e-02, // 2.000000
- 1.35235631786254032610239406153596064541488885879517e-02, // 2.718282
- 1.17065775592872373112030004449479747563600540161133e-02, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_CDF_01_4 = { //
- 8.33733718538829660094080509225022979080677032470703e-02, // 0.000000
- 2.40649836762494045983018509105022531002759933471680e-01, // 0.000010
- 4.99177179518956792847461656492669135332107543945312e-01, // 0.100000
- 5.06498248113537830050745469634421169757843017578125e-01, // 0.123457
- 5.23427039033618868302255577873438596725463867187500e-01, // 0.200000
- 5.34307105228552958742227474431274458765983581542969e-01, // 0.271828
- 5.37820716140765320290029194438830018043518066406250e-01, // 0.300000
- 5.39466643360845488075483444845303893089294433593750e-01, // 0.314159
- 5.48115306569588400797954363952158018946647644042969e-01, // 0.400000
- 5.56142802864377228111436579638393595814704895019531e-01, // 0.500000
- 5.62726898877477954563630646589444950222969055175781e-01, // 0.600000
- 5.68309949920494883457422474748454988002777099609375e-01, // 0.700000
- 5.73157387426872722002713089750614017248153686523438e-01, // 0.800000
- 5.77441148174444141005778874387033283710479736328125e-01, // 0.900000
- 5.81279046613597527581873691815417259931564331054688e-01, // 1.000000
- 5.84755370118739237206284542480716481804847717285156e-01, // 1.100000
- 5.87932517498272577682882911176420748233795166015625e-01, // 1.200000
- 5.90857985095490256810535356635227799415588378906250e-01, // 1.300000
- 5.93568768820695535914921947551192715764045715332031e-01, // 1.400000
- 5.96094250977751372033708321396261453628540039062500e-01, // 1.500000
- 5.98458157890379149890236476494465023279190063476562e-01, // 1.600000
- 6.00679925779863399526448120013810694217681884765625e-01, // 1.700000
- 6.02775677450659741474225938873132690787315368652344e-01, // 1.800000
- 6.04758935771455119478900996909942477941513061523438e-01, // 1.900000
- 6.06641154768875257019544733338989317417144775390625e-01, // 2.000000
- 6.17913083162764387168408575234934687614440917968750e-01, // 2.718282
- 6.23234757420647156322957016527652740478515625000000e-01, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_PDF_01_4 = { //
- 7.97969827464829534292221069335937500000000000000000e+07, // 0.000000
- 2.09043222444361890666186809539794921875000000000000e+03, // 0.000010
- 3.46320428833006954683071398903848603367805480957031e-01, // 0.100000
- 2.82305605668253523088395695594954304397106170654297e-01, // 0.123457
- 1.76602319442542898819681340683018788695335388183594e-01, // 0.200000
- 1.30926807720263271850313913091667927801609039306641e-01, // 0.271828
- 1.18903693947193564439679391853132983669638633728027e-01, // 0.300000
- 1.13663285983743478357865797079284675419330596923828e-01, // 0.314159
- 8.97361927078755006181864928294089622795581817626953e-02, // 0.400000
- 7.21048144026743276224777901006746105849742889404297e-02, // 0.500000
- 6.02851905595647719060536928736837580800056457519531e-02, // 0.600000
- 5.18057307044127585138326708147360477596521377563477e-02, // 0.700000
- 4.54235195895719354175490423131122952327132225036621e-02, // 0.800000
- 4.04448236551064599364480045551317743957042694091797e-02, // 0.900000
- 3.64517761834422804323452282915241084992885589599609e-02, // 1.000000
- 3.31775726553523511719312466539122397080063819885254e-02, // 1.100000
- 3.04438254891349936726019365096362889744341373443604e-02, // 1.200000
- 2.81267182882828474521641481942424434237182140350342e-02, // 1.300000
- 2.61376080752830329545499665755414753220975399017334e-02, // 1.400000
- 2.44113559017523976124586226887913653627038002014160e-02, // 1.500000
- 2.28990161555940596738167869261815212666988372802734e-02, // 1.600000
- 2.15630959198551200306503972115024225786328315734863e-02, // 1.700000
- 2.03743883245797348380268232403977890498936176300049e-02, // 1.800000
- 1.93098019737789824978868580274138366803526878356934e-02, // 1.900000
- 1.83508390056730183448330251394509105011820793151855e-02, // 2.000000
- 1.35235631786206692006579999087989563122391700744629e-02, // 2.718282
- 1.17065775592864670939796667425980558618903160095215e-02, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_CDF_01_1 = { //
- 9.51625819640404130295152640428568702191114425659180e-02, // 0.000000
- 2.71106585889975382208660903415875509381294250488281e-01, // 0.000010
- 5.48115306569588400797954363952158018946647644042969e-01, // 0.100000
- 5.55694967119628291385424745385535061359405517578125e-01, // 0.123457
- 5.73157387426872722002713089750614017248153686523438e-01, // 0.200000
- 5.84332020844404609327682464936515316367149353027344e-01, // 0.271828
- 5.87932517498272577682882911176420748233795166015625e-01, // 0.300000
- 5.89617748244351203013025042309891432523727416992188e-01, // 0.314159
- 5.98458157890379149890236476494465023279190063476562e-01, // 0.400000
- 6.06641154768875257019544733338989317417144775390625e-01, // 0.500000
- 6.13336400730758013466470401908736675977706909179688e-01, // 0.600000
- 6.19001977866595609611977124586701393127441406250000e-01, // 0.700000
- 6.23912243750147643694958787818904966115951538085938e-01, // 0.800000
- 6.28244633588060930051710784027818590402603149414062e-01, // 0.900000
- 6.32120558828557665975722557050175964832305908203125e-01, // 1.000000
- 6.35626771185953010068203639093553647398948669433594e-01, // 1.100000
- 6.38827420796338696362681730533950030803680419921875e-01, // 1.200000
- 6.41771286235222282456902576086577028036117553710938e-01, // 1.300000
- 6.44496325671848335758795656147412955760955810546875e-01, // 1.400000
- 6.47032658735232191205000162881333380937576293945312e-01, // 1.500000
- 6.49404586860663601832754920906154438853263854980469e-01, // 1.600000
- 6.51632001805449334597142296843230724334716796875000e-01, // 1.700000
- 6.53731392071210781757883978571044281125068664550781e-01, // 1.800000
- 6.55716577591103022548679746250854805111885070800781e-01, // 1.900000
- 6.57599256245357088879188722785329446196556091308594e-01, // 2.000000
- 6.68845722847091206375580441090278327465057373046875e-01, // 2.718282
- 6.74138343168612985678578297665808349847793579101562e-01, // 3.141593
- };
-
- public static final double[] SCIPY_WEIBULL_PDF_01_1 = { //
- 9.04837418035960197448730468750000000000000000000000e+07, // 0.000000
- 2.30496336008399066486163064837455749511718750000000e+03, // 0.000010
- 3.58944770831502002472745971317635849118232727050781e-01, // 0.100000
- 2.91956423650103102929165288514923304319381713867188e-01, // 0.123457
- 1.81694078358287769425771784881362691521644592285156e-01, // 0.200000
- 1.34239874155454602666637242691649589687585830688477e-01, // 0.271828
- 1.21775301956540002445983361667458666488528251647949e-01, // 0.300000
- 1.16346596858789258499555785419943276792764663696289e-01, // 0.314159
- 9.15960646223762386952671477047260850667953491210938e-02, // 0.400000
- 7.34033560226920733793321005578036420047283172607422e-02, // 0.500000
- 6.12346392900829789018857240989746060222387313842773e-02, // 0.600000
- 5.25211812394763555289500800427049398422241210937500e-02, // 0.700000
- 4.59735675855645273268912376352091087028384208679199e-02, // 0.800000
- 4.08732327117912602743032834951009135693311691284180e-02, // 0.900000
- 3.67879441171442347902065250764280790463089942932129e-02, // 1.000000
- 3.34420617455878435575478135888261022046208381652832e-02, // 1.100000
- 3.06514941118683631460228866671968717128038406372070e-02, // 1.200000
- 2.82885949087761413844877012024880968965590000152588e-02, // 1.300000
- 2.62620643803951336892055223870556801557540893554688e-02, // 1.400000
- 2.45048692989323843582916140348970657214522361755371e-02, // 1.500000
- 2.29666813847786074886947460527153452858328819274902e-02, // 1.600000
- 2.16089778205777807706944315668806666508316993713379e-02, // 1.700000
- 2.04017709011452205714043373063759645447134971618652e-02, // 1.800000
- 1.93213679270299865109450365707743912935256958007812e-02, // 1.900000
- 1.83488015354457897898576845818752190098166465759277e-02, // 2.000000
- 1.34637281783702208309838610489350685384124517440796e-02, // 2.718282
- 1.16304997397552699334166703692972077988088130950928e-02, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_CDF_01_1 = { //
- 9.51625819640404130295152640428568702191114425659180e-02, // 0.000000
- 2.71106585889975382208660903415875509381294250488281e-01, // 0.000010
- 5.48115306569588400797954363952158018946647644042969e-01, // 0.100000
- 5.55694967119628291385424745385535061359405517578125e-01, // 0.123457
- 5.73157387426872722002713089750614017248153686523438e-01, // 0.200000
- 5.84332020844417376892465654236730188131332397460938e-01, // 0.271828
- 5.87932517498272577682882911176420748233795166015625e-01, // 0.300000
- 5.89617748244353534481376755138626322150230407714844e-01, // 0.314159
- 5.98458157890379149890236476494465023279190063476562e-01, // 0.400000
- 6.06641154768875257019544733338989317417144775390625e-01, // 0.500000
- 6.13336400730758013466470401908736675977706909179688e-01, // 0.600000
- 6.19001977866595609611977124586701393127441406250000e-01, // 0.700000
- 6.23912243750147643694958787818904966115951538085938e-01, // 0.800000
- 6.28244633588060930051710784027818590402603149414062e-01, // 0.900000
- 6.32120558828557665975722557050175964832305908203125e-01, // 1.000000
- 6.35626771185953010068203639093553647398948669433594e-01, // 1.100000
- 6.38827420796338696362681730533950030803680419921875e-01, // 1.200000
- 6.41771286235222282456902576086577028036117553710938e-01, // 1.300000
- 6.44496325671848335758795656147412955760955810546875e-01, // 1.400000
- 6.47032658735232191205000162881333380937576293945312e-01, // 1.500000
- 6.49404586860663601832754920906154438853263854980469e-01, // 1.600000
- 6.51632001805449334597142296843230724334716796875000e-01, // 1.700000
- 6.53731392071210781757883978571044281125068664550781e-01, // 1.800000
- 6.55716577591103022548679746250854805111885070800781e-01, // 1.900000
- 6.57599256245357088879188722785329446196556091308594e-01, // 2.000000
- 6.68845722847103862918061167874839156866073608398438e-01, // 2.718282
- 6.74138343168615428169232473010197281837463378906250e-01, // 3.141593
- };
-
- public static final double[] GNUR_WEIBULL_PDF_01_1 = { //
- 9.04837418035960048437118530273437500000000000000000e+07, // 0.000000
- 2.30496336008399021011427976191043853759765625000000e+03, // 0.000010
- 3.58944770831502002472745971317635849118232727050781e-01, // 0.100000
- 2.91956423650103102929165288514923304319381713867188e-01, // 0.123457
- 1.81694078358287741670196169252449180930852890014648e-01, // 0.200000
- 1.34239874155408001055178601745865307748317718505859e-01, // 0.271828
- 1.21775301956539974690407746038545155897736549377441e-01, // 0.300000
- 1.16346596858781695105200526541011640802025794982910e-01, // 0.314159
- 9.15960646223762386952671477047260850667953491210938e-02, // 0.400000
- 7.34033560226920733793321005578036420047283172607422e-02, // 0.500000
- 6.12346392900829858407796280062029836699366569519043e-02, // 0.600000
- 5.25211812394763624678439839499333174899220466613770e-02, // 0.700000
- 4.59735675855645273268912376352091087028384208679199e-02, // 0.800000
- 4.08732327117912672131971874023292912170290946960449e-02, // 0.900000
- 3.67879441171442347902065250764280790463089942932129e-02, // 1.000000
- 3.34420617455878435575478135888261022046208381652832e-02, // 1.100000
- 3.06514941118683666154698386208110605366528034210205e-02, // 1.200000
- 2.82885949087761448539346531561022857204079627990723e-02, // 1.300000
- 2.62620643803951267503116184798273025080561637878418e-02, // 1.400000
- 2.45048692989323808888446620812828768976032733917236e-02, // 1.500000
- 2.29666813847786040192477940991011564619839191436768e-02, // 1.600000
- 2.16089778205777807706944315668806666508316993713379e-02, // 1.700000
- 2.04017709011452171019573853527617757208645343780518e-02, // 1.800000
- 1.93213679270299865109450365707743912935256958007812e-02, // 1.900000
- 1.83488015354457863204107326282610301859676837921143e-02, // 2.000000
- 1.34637281783654468719779728758112469222396612167358e-02, // 2.718282
- 1.16304997397544927772994327597189112566411495208740e-02, // 3.141593
- };
-
- public static final double[] P_QUANT = { //
- 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99, 0.999, 0.9999 //
- };
-
- public static final double[] SCIPY_WEIBULL_QUANT_1_1 = { //
- 1.00005000333358343134713963618054322068928740918636e-04, // 0.000100
- 1.00050033358353349620395444929954464896582067012787e-03, // 0.001000
- 1.00503358535014419156139453548348683398216962814331e-02, // 0.010000
- 1.05360515657826309121603003404743503779172897338867e-01, // 0.100000
- 2.87682072451780901367612841568188741803169250488281e-01, // 0.250000
- 6.93147180559945286226763982995180413126945495605469e-01, // 0.500000
- 1.38629436111989057245352796599036082625389099121094e+00, // 0.750000
- 2.30258509299404590109361379290930926799774169921875e+00, // 0.900000
- 4.60517018598809002583038818556815385818481445312500e+00, // 0.990000
- 6.90775527898213592692400197847746312618255615234375e+00, // 0.999000
- 9.21034037197629373849849798716604709625244140625000e+00, // 0.999900
- };
-
- public static final double[] GNUR_WEIBULL_QUANT_1_1 = { //
- 1.00005000333358343134713963618054322068928740918636e-04, // 0.000100
- 1.00050033358353349620395444929954464896582067012787e-03, // 0.001000
- 1.00503358535014419156139453548348683398216962814331e-02, // 0.010000
- 1.05360515657826309121603003404743503779172897338867e-01, // 0.100000
- 2.87682072451780901367612841568188741803169250488281e-01, // 0.250000
- 6.93147180559945286226763982995180413126945495605469e-01, // 0.500000
- 1.38629436111989057245352796599036082625389099121094e+00, // 0.750000
- 2.30258509299404590109361379290930926799774169921875e+00, // 0.900000
- 4.60517018598809002583038818556815385818481445312500e+00, // 0.990000
- 6.90775527898213592692400197847746312618255615234375e+00, // 0.999000
- 9.21034037197629373849849798716604709625244140625000e+00, // 0.999900
- };
-
- public static final double[] SCIPY_WEIBULL_QUANT_2_1 = { //
- 1.00002500135425789751231206992088118568062782287598e-02, // 0.000100
- 3.16306865809696524660665772898937575519084930419922e-02, // 0.001000
- 1.00251363349839001104513158679765183478593826293945e-01, // 0.010000
- 3.24592845974501276185009146502125076949596405029297e-01, // 0.100000
- 5.36360021302651590602295073040295392274856567382812e-01, // 0.250000
- 8.32554611157697688206269504007650539278984069824219e-01, // 0.500000
- 1.17741002251547466350700688053620979189872741699219e+00, // 0.750000
- 1.51742712938514645593102159182308241724967956542969e+00, // 0.900000
- 2.14596602628934673973049029882531613111495971679688e+00, // 0.990000
- 2.62826088487846565300287693389691412448883056640625e+00, // 0.999000
- 3.03485425877031111951964703621342778205871582031250e+00, // 0.999900
- };
-
- public static final double[] GNUR_WEIBULL_QUANT_2_1 = { //
- 1.00002500135425789751231206992088118568062782287598e-02, // 0.000100
- 3.16306865809696524660665772898937575519084930419922e-02, // 0.001000
- 1.00251363349839001104513158679765183478593826293945e-01, // 0.010000
- 3.24592845974501276185009146502125076949596405029297e-01, // 0.100000
- 5.36360021302651590602295073040295392274856567382812e-01, // 0.250000
- 8.32554611157697688206269504007650539278984069824219e-01, // 0.500000
- 1.17741002251547466350700688053620979189872741699219e+00, // 0.750000
- 1.51742712938514645593102159182308241724967956542969e+00, // 0.900000
- 2.14596602628934673973049029882531613111495971679688e+00, // 0.990000
- 2.62826088487846565300287693389691412448883056640625e+00, // 0.999000
- 3.03485425877031111951964703621342778205871582031250e+00, // 0.999900
- };
-
- public static final double[] SCIPY_WEIBULL_QUANT_4_1 = { //
- 1.00001250059899640665328490740648703649640083312988e-01, // 0.000100
- 1.77850180154448117564314202354580629616975784301758e-01, // 0.001000
- 3.16624956928286072077582957717822864651679992675781e-01, // 0.010000
- 5.69730502934941429593607153947232291102409362792969e-01, // 0.100000
- 7.32366043247945519567565497709438204765319824218750e-01, // 0.250000
- 9.12444305784028575345701028709299862384796142578125e-01, // 0.500000
- 1.08508526048208508996140153612941503524780273437500e+00, // 0.750000
- 1.23183892185023369236773760349024087190628051757812e+00, // 0.900000
- 1.46491161040157868988842437829589471220970153808594e+00, // 0.990000
- 1.62119119319050875027699021302396431565284729003906e+00, // 0.999000
- 1.74208330993965687660818275617202743887901306152344e+00, // 0.999900
- };
-
- public static final double[] GNUR_WEIBULL_QUANT_4_1 = { //
- 1.00001250059899640665328490740648703649640083312988e-01, // 0.000100
- 1.77850180154448117564314202354580629616975784301758e-01, // 0.001000
- 3.16624956928286072077582957717822864651679992675781e-01, // 0.010000
- 5.69730502934941429593607153947232291102409362792969e-01, // 0.100000
- 7.32366043247945519567565497709438204765319824218750e-01, // 0.250000
- 9.12444305784028575345701028709299862384796142578125e-01, // 0.500000
- 1.08508526048208508996140153612941503524780273437500e+00, // 0.750000
- 1.23183892185023369236773760349024087190628051757812e+00, // 0.900000
- 1.46491161040157868988842437829589471220970153808594e+00, // 0.990000
- 1.62119119319050875027699021302396431565284729003906e+00, // 0.999000
- 1.74208330993965687660818275617202743887901306152344e+00, // 0.999900
- };
-
- public static final double[] SCIPY_WEIBULL_QUANT_4_10 = { //
- 1.00001250059899637889770929177757352590560913085938e+00, // 0.000100
- 1.77850180154448112013199079228797927498817443847656e+00, // 0.001000
- 3.16624956928286049873122465214692056179046630859375e+00, // 0.010000
- 5.69730502934941451798067646450363099575042724609375e+00, // 0.100000
- 7.32366043247945519567565497709438204765319824218750e+00, // 0.250000
- 9.12444305784028486527859058696776628494262695312500e+00, // 0.500000
- 1.08508526048208508996140153612941503524780273437500e+01, // 0.750000
- 1.23183892185023360354989563347771763801574707031250e+01, // 0.900000
- 1.46491161040157873429734536330215632915496826171875e+01, // 0.990000
- 1.62119119319050888350375316804274916648864746093750e+01, // 0.999000
- 1.74208330993965674338141980115324258804321289062500e+01, // 0.999900
- };
-
- public static final double[] GNUR_WEIBULL_QUANT_4_10 = { //
- 1.00001250059899637889770929177757352590560913085938e+00, // 0.000100
- 1.77850180154448112013199079228797927498817443847656e+00, // 0.001000
- 3.16624956928286049873122465214692056179046630859375e+00, // 0.010000
- 5.69730502934941451798067646450363099575042724609375e+00, // 0.100000
- 7.32366043247945519567565497709438204765319824218750e+00, // 0.250000
- 9.12444305784028486527859058696776628494262695312500e+00, // 0.500000
- 1.08508526048208508996140153612941503524780273437500e+01, // 0.750000
- 1.23183892185023360354989563347771763801574707031250e+01, // 0.900000
- 1.46491161040157873429734536330215632915496826171875e+01, // 0.990000
- 1.62119119319050888350375316804274916648864746093750e+01, // 0.999000
- 1.74208330993965674338141980115324258804321289062500e+01, // 0.999900
- };
-
- public static final double[] SCIPY_WEIBULL_QUANT_01_10 = { //
- 1.00050014586584021700243769737484031845767568464672e-39, // 0.000100
- 1.00501461589481204170765583646174510341434104691366e-29, // 0.001000
- 1.05149145760085306110809830513112699455704405376921e-19, // 0.010000
- 1.68569451981823333734044073758343712521323709552235e-09, // 0.100000
- 3.88264771194455187157575093426231660487246699631214e-05, // 0.250000
- 2.56008632895631083048471055008121766149997711181641e-01, // 0.500000
- 2.62152840085126229041634360328316688537597656250000e+02, // 0.750000
- 4.18944879802952418685890734195709228515625000000000e+04, // 0.900000
- 4.28999556918221637606620788574218750000000000000000e+07, // 0.990000
- 2.47382762074844741821289062500000000000000000000000e+09, // 0.999000
- 4.39295546284313201904296875000000000000000000000000e+10, // 0.999900
- };
-
- public static final double[] GNUR_WEIBULL_QUANT_01_10 = { //
- 1.00050014586584021700243769737484031845767568464672e-39, // 0.000100
- 1.00501461589481204170765583646174510341434104691366e-29, // 0.001000
- 1.05149145760085306110809830513112699455704405376921e-19, // 0.010000
- 1.68569451981823333734044073758343712521323709552235e-09, // 0.100000
- 3.88264771194455187157575093426231660487246699631214e-05, // 0.250000
- 2.56008632895631083048471055008121766149997711181641e-01, // 0.500000
- 2.62152840085126229041634360328316688537597656250000e+02, // 0.750000
- 4.18944879802952418685890734195709228515625000000000e+04, // 0.900000
- 4.28999556918221637606620788574218750000000000000000e+07, // 0.990000
- 2.47382762074844741821289062500000000000000000000000e+09, // 0.999000
- 4.39295546284313201904296875000000000000000000000000e+10, // 0.999900
- };
-
- public static final double[] SCIPY_WEIBULL_QUANT_01_20 = { //
- 2.00100029173168043400487539474968063691535136929345e-39, // 0.000100
- 2.01002923178962408341531167292349020682868209382732e-29, // 0.001000
- 2.10298291520170612221619661026225398911408810753842e-19, // 0.010000
- 3.37138903963646667468088147516687425042647419104469e-09, // 0.100000
- 7.76529542388910374315150186852463320974493399262428e-05, // 0.250000
- 5.12017265791262166096942110016243532299995422363281e-01, // 0.500000
- 5.24305680170252458083268720656633377075195312500000e+02, // 0.750000
- 8.37889759605904837371781468391418457031250000000000e+04, // 0.900000
- 8.57999113836443275213241577148437500000000000000000e+07, // 0.990000
- 4.94765524149689483642578125000000000000000000000000e+09, // 0.999000
- 8.78591092568626403808593750000000000000000000000000e+10, // 0.999900
- };
-
- public static final double[] GNUR_WEIBULL_QUANT_01_20 = { //
- 2.00100029173168043400487539474968063691535136929345e-39, // 0.000100
- 2.01002923178962408341531167292349020682868209382732e-29, // 0.001000
- 2.10298291520170612221619661026225398911408810753842e-19, // 0.010000
- 3.37138903963646667468088147516687425042647419104469e-09, // 0.100000
- 7.76529542388910374315150186852463320974493399262428e-05, // 0.250000
- 5.12017265791262166096942110016243532299995422363281e-01, // 0.500000
- 5.24305680170252458083268720656633377075195312500000e+02, // 0.750000
- 8.37889759605904837371781468391418457031250000000000e+04, // 0.900000
- 8.57999113836443275213241577148437500000000000000000e+07, // 0.990000
- 4.94765524149689483642578125000000000000000000000000e+09, // 0.999000
- 8.78591092568626403808593750000000000000000000000000e+10, // 0.999900
- };
-
- public static final double[] SCIPY_WEIBULL_QUANT_01_4 = { //
- 4.00200058346336103114236248946247444158805547000059e-40, // 0.000100
- 4.02005846357924816683062334584698041365736418765464e-30, // 0.001000
- 4.20596583040341236480301474472674879422679762663480e-20, // 0.010000
- 6.74277807927293355615691608859066721870512139958009e-10, // 0.100000
- 1.55305908477782068086766459336089951648318674415350e-05, // 0.250000
- 1.02403453158252430443830860440357355400919914245605e-01, // 0.500000
- 1.04861136034050488774482801090925931930541992187500e+02, // 0.750000
- 1.67577951921180974750313907861709594726562500000000e+04, // 0.900000
- 1.71599822767288647592067718505859375000000000000000e+07, // 0.990000
- 9.89531048299378991127014160156250000000000000000000e+08, // 0.999000
- 1.75718218513725280761718750000000000000000000000000e+10, // 0.999900
- };
-
- public static final double[] GNUR_WEIBULL_QUANT_01_4 = { //
- 4.00200058346336103114236248946247444158805547000059e-40, // 0.000100
- 4.02005846357924816683062334584698041365736418765464e-30, // 0.001000
- 4.20596583040341236480301474472674879422679762663480e-20, // 0.010000
- 6.74277807927293355615691608859066721870512139958009e-10, // 0.100000
- 1.55305908477782068086766459336089951648318674415350e-05, // 0.250000
- 1.02403453158252430443830860440357355400919914245605e-01, // 0.500000
- 1.04861136034050488774482801090925931930541992187500e+02, // 0.750000
- 1.67577951921180974750313907861709594726562500000000e+04, // 0.900000
- 1.71599822767288647592067718505859375000000000000000e+07, // 0.990000
- 9.89531048299378991127014160156250000000000000000000e+08, // 0.999000
- 1.75718218513725280761718750000000000000000000000000e+10, // 0.999900
- };
-
- public static final double[] SCIPY_WEIBULL_QUANT_01_1 = { //
- 1.00050014586584025778559062236561861039701386750015e-40, // 0.000100
- 1.00501461589481204170765583646174510341434104691366e-30, // 0.001000
- 1.05149145760085309120075368618168719855669940665870e-20, // 0.010000
- 1.68569451981823338903922902214766680467628034989502e-10, // 0.100000
- 3.88264771194455170216916148340224879120796686038375e-06, // 0.250000
- 2.56008632895631076109577151100893388502299785614014e-02, // 0.500000
- 2.62152840085126221936207002727314829826354980468750e+01, // 0.750000
- 4.18944879802952436875784769654273986816406250000000e+03, // 0.900000
- 4.28999556918221618980169296264648437500000000000000e+06, // 0.990000
- 2.47382762074844747781753540039062500000000000000000e+08, // 0.999000
- 4.39295546284313201904296875000000000000000000000000e+09, // 0.999900
- };
-
- public static final double[] GNUR_WEIBULL_QUANT_01_1 = { //
- 1.00050014586584025778559062236561861039701386750015e-40, // 0.000100
- 1.00501461589481204170765583646174510341434104691366e-30, // 0.001000
- 1.05149145760085309120075368618168719855669940665870e-20, // 0.010000
- 1.68569451981823338903922902214766680467628034989502e-10, // 0.100000
- 3.88264771194455170216916148340224879120796686038375e-06, // 0.250000
- 2.56008632895631076109577151100893388502299785614014e-02, // 0.500000
- 2.62152840085126221936207002727314829826354980468750e+01, // 0.750000
- 4.18944879802952436875784769654273986816406250000000e+03, // 0.900000
- 4.28999556918221618980169296264648437500000000000000e+06, // 0.990000
- 2.47382762074844747781753540039062500000000000000000e+08, // 0.999000
- 4.39295546284313201904296875000000000000000000000000e+09, // 0.999900
- };
-
- @Test
- public void testPDF() {
- checkPDF(new WeibullDistribution(1., 1.), P_CDFPDF, SCIPY_WEIBULL_PDF_1_1, 1e-13);
- checkPDF(new WeibullDistribution(2., 1.), P_CDFPDF, SCIPY_WEIBULL_PDF_2_1, 1e-12);
- checkPDF(new WeibullDistribution(4., 1.), P_CDFPDF, SCIPY_WEIBULL_PDF_4_1, 1e-11);
- checkPDF(new WeibullDistribution(4., 10.), P_CDFPDF, SCIPY_WEIBULL_PDF_4_10, 1e-11);
- checkPDF(new WeibullDistribution(.1, 1.), P_CDFPDF, SCIPY_WEIBULL_PDF_01_1, 1e-12);
- checkPDF(new WeibullDistribution(.1, 4.), P_CDFPDF, SCIPY_WEIBULL_PDF_01_4, 1e-12);
- checkPDF(new WeibullDistribution(.1, 10.), P_CDFPDF, SCIPY_WEIBULL_PDF_01_10, 1e-12);
- checkPDF(new WeibullDistribution(.1, 20.), P_CDFPDF, SCIPY_WEIBULL_PDF_01_20, 1e-12);
-
- checkPDF(new WeibullDistribution(1., 1.), P_CDFPDF, GNUR_WEIBULL_PDF_1_1, 1e-15);
- checkPDF(new WeibullDistribution(2., 1.), P_CDFPDF, GNUR_WEIBULL_PDF_2_1, 1e-15);
- checkPDF(new WeibullDistribution(4., 1.), P_CDFPDF, GNUR_WEIBULL_PDF_4_1, 1e-14);
- checkPDF(new WeibullDistribution(4., 10.), P_CDFPDF, GNUR_WEIBULL_PDF_4_10, 1e-15);
- checkPDF(new WeibullDistribution(.1, 1.), P_CDFPDF, GNUR_WEIBULL_PDF_01_1, 1e-15);
- checkPDF(new WeibullDistribution(.1, 4.), P_CDFPDF, GNUR_WEIBULL_PDF_01_4, 1e-15);
- checkPDF(new WeibullDistribution(.1, 10.), P_CDFPDF, GNUR_WEIBULL_PDF_01_10, 1e-15);
- checkPDF(new WeibullDistribution(.1, 20.), P_CDFPDF, GNUR_WEIBULL_PDF_01_20, 1e-15);
- }
-
- @Test
- public void testCDF() {
- checkCDF(new WeibullDistribution(1., 1.), P_CDFPDF, SCIPY_WEIBULL_CDF_1_1, 1e-12);
- checkCDF(new WeibullDistribution(2., 1.), P_CDFPDF, SCIPY_WEIBULL_CDF_2_1, 1e-12);
- checkCDF(new WeibullDistribution(4., 1.), P_CDFPDF, SCIPY_WEIBULL_CDF_4_1, 1e-11);
- checkCDF(new WeibullDistribution(4., 10.), P_CDFPDF, SCIPY_WEIBULL_CDF_4_10, 1e-11);
- checkCDF(new WeibullDistribution(.1, 1.), P_CDFPDF, SCIPY_WEIBULL_CDF_01_1, 1e-13);
- checkCDF(new WeibullDistribution(.1, 4.), P_CDFPDF, SCIPY_WEIBULL_CDF_01_4, 1e-13);
- checkCDF(new WeibullDistribution(.1, 10.), P_CDFPDF, SCIPY_WEIBULL_CDF_01_10, 1e-13);
- checkCDF(new WeibullDistribution(.1, 20.), P_CDFPDF, SCIPY_WEIBULL_CDF_01_20, 1e-13);
-
- checkCDF(new WeibullDistribution(1., 1.), P_CDFPDF, GNUR_WEIBULL_CDF_1_1, 1e-14);
- checkCDF(new WeibullDistribution(2., 1.), P_CDFPDF, GNUR_WEIBULL_CDF_2_1, 1e-14);
- checkCDF(new WeibullDistribution(4., 1.), P_CDFPDF, GNUR_WEIBULL_CDF_4_1, 1e-13);
- checkCDF(new WeibullDistribution(4., 10.), P_CDFPDF, GNUR_WEIBULL_CDF_4_10, 1e-13);
- checkCDF(new WeibullDistribution(.1, 1.), P_CDFPDF, GNUR_WEIBULL_CDF_01_1, 1e-15);
- checkCDF(new WeibullDistribution(.1, 4.), P_CDFPDF, GNUR_WEIBULL_CDF_01_4, 1e-15);
- checkCDF(new WeibullDistribution(.1, 10.), P_CDFPDF, GNUR_WEIBULL_CDF_01_10, 1e-15);
- checkCDF(new WeibullDistribution(.1, 20.), P_CDFPDF, GNUR_WEIBULL_CDF_01_20, 1e-15);
- }
-
- @Test
- public void testQuantile() {
- checkQuantile(new WeibullDistribution(1., 1.), P_QUANT, SCIPY_WEIBULL_QUANT_1_1, 1e-15);
- checkQuantile(new WeibullDistribution(2., 1.), P_QUANT, SCIPY_WEIBULL_QUANT_2_1, 1e-15);
- checkQuantile(new WeibullDistribution(4., 1.), P_QUANT, SCIPY_WEIBULL_QUANT_4_1, 1e-13);
- checkQuantile(new WeibullDistribution(4., 10.), P_QUANT, SCIPY_WEIBULL_QUANT_4_10, 1e-13);
- checkQuantile(new WeibullDistribution(.1, 1.), P_QUANT, SCIPY_WEIBULL_QUANT_01_1, 1e-14);
- checkQuantile(new WeibullDistribution(.1, 4.), P_QUANT, SCIPY_WEIBULL_QUANT_01_4, 1e-13);
- checkQuantile(new WeibullDistribution(.1, 10.), P_QUANT, SCIPY_WEIBULL_QUANT_01_10, 1e-13);
- checkQuantile(new WeibullDistribution(.1, 20.), P_QUANT, SCIPY_WEIBULL_QUANT_01_20, 1e-13);
-
- checkQuantile(new WeibullDistribution(1., 1.), P_QUANT, GNUR_WEIBULL_QUANT_1_1, 1e-15);
- checkQuantile(new WeibullDistribution(2., 1.), P_QUANT, GNUR_WEIBULL_QUANT_2_1, 1e-15);
- checkQuantile(new WeibullDistribution(4., 1.), P_QUANT, GNUR_WEIBULL_QUANT_4_1, 1e-13);
- checkQuantile(new WeibullDistribution(4., 10.), P_QUANT, GNUR_WEIBULL_QUANT_4_10, 1e-13);
- checkQuantile(new WeibullDistribution(.1, 1.), P_QUANT, GNUR_WEIBULL_QUANT_01_1, 1e-13);
- checkQuantile(new WeibullDistribution(.1, 4.), P_QUANT, GNUR_WEIBULL_QUANT_01_4, 1e-13);
- checkQuantile(new WeibullDistribution(.1, 10.), P_QUANT, GNUR_WEIBULL_QUANT_01_10, 1e-13);
- checkQuantile(new WeibullDistribution(.1, 20.), P_QUANT, GNUR_WEIBULL_QUANT_01_20, 1e-13);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/persistent/TestByteArrayUtil.java b/test/de/lmu/ifi/dbs/elki/persistent/TestByteArrayUtil.java
deleted file mode 100644
index 21848a04..00000000
--- a/test/de/lmu/ifi/dbs/elki/persistent/TestByteArrayUtil.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package de.lmu.ifi.dbs.elki.persistent;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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.nio.ByteBuffer;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Test some of the varint functions.
- *
- * @author Erich Schubert
- */
-public class TestByteArrayUtil implements JUnit4Test {
- /**
- * Test the Varint functions
- */
- @Test
- public void dotestUnsignedVarint32() {
- int[] testvals = { 0, 1, 127, 128, 16383, 16384, 2097151, 2097152, 268435455, 268435456, Integer.MAX_VALUE, 0xFFFFFFFF };
- int[] elen = { 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5 };
- ByteBuffer buffer = ByteBuffer.allocate(100);
- Assert.assertEquals("Test incorrectly set up.", testvals.length, elen.length);
-
- // Fill the buffer
- int totallen = 0;
- for(int i = 0; i < testvals.length; i++) {
- ByteArrayUtil.writeUnsignedVarint(buffer, testvals[i]);
- totallen += elen[i];
- Assert.assertEquals("len(Varint(" + testvals[i] + ")) != " + elen[i], totallen, buffer.position());
- }
- // Seek and read again.
- buffer.position(0);
- totallen = 0;
- for(int i = 0; i < testvals.length; i++) {
- int read = ByteArrayUtil.readUnsignedVarint(buffer);
- Assert.assertEquals("Varint read failed.", testvals[i], read);
- totallen += elen[i];
- Assert.assertEquals("len(Varint(" + testvals[i] + ")) != " + elen[i], totallen, buffer.position());
- }
- }
-
- /**
- * Test the Varint functions
- */
- @Test
- public void dotestSignedVarint32() {
- int[] testvals = { 0, 1, -1, 63, -64, 64, -65, 8191, -8192, 8192, -8193, 1048575, -1048576, 1048576, -1048577, 134217727, -134217728, 134217728, -134217729, Integer.MAX_VALUE, Integer.MIN_VALUE };
- int[] elen = { 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 };
- ByteBuffer buffer = ByteBuffer.allocate(100);
- Assert.assertEquals("Test incorrectly set up.", testvals.length, elen.length);
-
- // Fill the buffer
- int totallen = 0;
- for(int i = 0; i < testvals.length; i++) {
- ByteArrayUtil.writeSignedVarint(buffer, testvals[i]);
- totallen += elen[i];
- Assert.assertEquals("len(Varint(" + testvals[i] + ")) != " + elen[i], totallen, buffer.position());
- }
- // Seek and read again.
- buffer.position(0);
- totallen = 0;
- for(int i = 0; i < testvals.length; i++) {
- int read = ByteArrayUtil.readSignedVarint(buffer);
- Assert.assertEquals("Varint read failed.", testvals[i], read);
- totallen += elen[i];
- Assert.assertEquals("len(Varint(" + testvals[i] + ")) != " + elen[i], totallen, buffer.position());
- }
- }
-
- /**
- * Official examples
- */
- @Test
- public void dotestVarintExamples() {
- byte[] test = { 0x03, (byte) 0x8E, 0x02, (byte) 0x9E, (byte) 0xA7, 0x05, (byte) 0x96, 0x01 };
- int[] expect = { 3, 270, 86942, 150 };
- ByteBuffer buffer = ByteBuffer.wrap(test);
- for(int i = 0; i < expect.length; i++) {
- int read = ByteArrayUtil.readUnsignedVarint(buffer);
- Assert.assertEquals(expect[i], read);
- }
- Assert.assertEquals("Not all data processed.", 0, buffer.remaining());
- }
-
-}
diff --git a/test/de/lmu/ifi/dbs/elki/persistent/TestOnDiskArray.java b/test/de/lmu/ifi/dbs/elki/persistent/TestOnDiskArray.java
deleted file mode 100644
index 4483a29e..00000000
--- a/test/de/lmu/ifi/dbs/elki/persistent/TestOnDiskArray.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package de.lmu.ifi.dbs.elki.persistent;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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.File;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Test to validate proper OnDiskArray operation.
- *
- * @author Erich Schubert
- */
-// TODO: also test with a static sample file.
-public class TestOnDiskArray implements JUnit4Test {
- File file = new File("OnDiskArrayTestFile.test.dat");
-
- /**
- * Check that we don't overwrite any file.
- *
- * @throws Exception on errors.
- */
- @Before
- public void safetyCheck() throws Exception {
- if(file.exists()) {
- Assert.fail("Could not run test - test file already exists.");
- }
- }
-
- /**
- * Clean up afterwards
- *
- * @throws Exception on errors.
- */
- @After
- public void cleanup() throws Exception {
- if(file != null && file.exists()) {
- if(!file.delete()) {
- Assert.fail("Error cleaning up: can't remove test file.");
- }
- }
- }
-
- /**
- * Test the OnDiskArray class.
- *
- * @throws IOException on errors.
- */
- @Test
- public void dotestOnDiskArray() throws IOException {
- final int extraheadersize = 2;
- final int recsize = 3;
- int numrec = 4;
- // Only applicable to the version we are testing.
- final int ODR_HEADER_SIZE = 4 * 4;
- OnDiskArray array = new OnDiskArray(file, 1, extraheadersize, recsize, numrec);
- byte[] header = { 42, 23 };
- array.getExtraHeader().put(header);
- byte[] record1 = { 31, 41, 59 };
- byte[] record2 = { 26, 53, 58 };
- array.getRecordBuffer(0).put(record1);
- array.getRecordBuffer(1).put(record2);
- array.getRecordBuffer(2).put(record2);
- array.getRecordBuffer(3).put(record1);
- array.resizeFile(5);
- numrec = 5;
- array.getRecordBuffer(4).put(record1);
- array.close();
-
- // validate file size
- Assert.assertEquals("File size doesn't match.", ODR_HEADER_SIZE + extraheadersize + recsize * numrec, file.length());
-
- OnDiskArray roarray = new OnDiskArray(file, 1, 2, 3, false);
- Assert.assertEquals("Number of records incorrect.", numrec, roarray.getNumRecords());
-
- byte[] buf = new byte[recsize];
- ByteBuffer hbuf = roarray.getExtraHeader();
- for(int i = 0; i < header.length; i++) {
- Assert.assertEquals("Header doesn't match.", header[i], hbuf.get());
- }
- roarray.getRecordBuffer(0).get(buf);
- Assert.assertArrayEquals("Record 0 doesn't match.", record1, buf);
- roarray.getRecordBuffer(4).get(buf);
- Assert.assertArrayEquals("Record 4 doesn't match.", record1, buf);
- roarray.getRecordBuffer(1).get(buf);
- Assert.assertArrayEquals("Record 1 doesn't match.", record2, buf);
- roarray.getRecordBuffer(2).get(buf);
- Assert.assertArrayEquals("Record 2 doesn't match.", record2, buf);
- roarray.getRecordBuffer(3).get(buf);
- Assert.assertArrayEquals("Record 3 doesn't match.", record1, buf);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/persistent/TestOnDiskUpperTriangleMatrix.java b/test/de/lmu/ifi/dbs/elki/persistent/TestOnDiskUpperTriangleMatrix.java
deleted file mode 100644
index c5997615..00000000
--- a/test/de/lmu/ifi/dbs/elki/persistent/TestOnDiskUpperTriangleMatrix.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package de.lmu.ifi.dbs.elki.persistent;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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.File;
-import java.io.IOException;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Test the on-disk OnDiskUpperTriangleMatrix class.
- *
- * @author Erich Schubert
- *
- */
-// TODO: also test with a static sample file.
-public class TestOnDiskUpperTriangleMatrix implements JUnit4Test {
- static File file = new File("UpperTriangleTestFile.test.dat");
-
- /**
- * Check that we don't overwrite any file.
- *
- * @throws Exception on errors.
- */
- @Before
- public void safetyCheck() throws Exception {
- if(file.exists()) {
- Assert.fail("Could not run test - test file already exists.");
- }
- }
-
- /**
- * Clean up afterwards
- *
- * @throws Exception on errors.
- */
- @After
- public void cleanup() throws Exception {
- if(file != null && file.exists()) {
- if(!file.delete()) {
- Assert.fail("Error cleaning up: can't remove test file.");
- }
- }
- }
-
- /**
- * Test the ondisk triangle matrix
- *
- * @throws IOException on errors.
- */
- @Test
- public void testUpperTriangleMatrix() throws IOException {
- final int extraheadersize = 2;
- final int recsize = 3;
- int matsize = 2;
- // Only applicable to the version we are testing.
- final int ODR_HEADER_SIZE = 4 * 4 + 4;
- OnDiskUpperTriangleMatrix array = new OnDiskUpperTriangleMatrix(file, 1, extraheadersize, recsize, matsize);
- byte[] record1 = { 31, 41, 59 };
- byte[] record2 = { 26, 53, 58 };
- byte[] record3 = { 97, 93, 1 };
- array.getRecordBuffer(0, 0).put(record1);
- array.getRecordBuffer(0, 1).put(record2);
- array.getRecordBuffer(1, 1).put(record3);
- // test resizing.
- matsize = 3;
- array.resizeMatrix(3);
- array.getRecordBuffer(0, 2).put(record3);
- array.getRecordBuffer(1, 2).put(record2);
- array.getRecordBuffer(2, 2).put(record1);
- array.close();
-
- // validate file size
- Assert.assertEquals("File size doesn't match.", ODR_HEADER_SIZE + extraheadersize + recsize * matsize * (matsize + 1) / 2, file.length());
-
- OnDiskUpperTriangleMatrix roarray = new OnDiskUpperTriangleMatrix(file, 1, extraheadersize, recsize, false);
- Assert.assertEquals("Number of records incorrect.", matsize, roarray.getMatrixSize());
-
- byte[] buf = new byte[recsize];
- roarray.getRecordBuffer(0, 0).get(buf);
- Assert.assertArrayEquals("Record 0,0 doesn't match.", record1, buf);
- roarray.getRecordBuffer(0, 1).get(buf);
- Assert.assertArrayEquals("Record 0,1 doesn't match.", record2, buf);
- roarray.getRecordBuffer(1, 1).get(buf);
- Assert.assertArrayEquals("Record 1,1 doesn't match.", record3, buf);
- roarray.getRecordBuffer(1, 0).get(buf);
- Assert.assertArrayEquals("Record 1,0 doesn't match.", record2, buf);
- roarray.getRecordBuffer(0, 2).get(buf);
- Assert.assertArrayEquals("Record 0,2 doesn't match.", record3, buf);
- roarray.getRecordBuffer(1, 2).get(buf);
- Assert.assertArrayEquals("Record 1,2 doesn't match.", record2, buf);
- roarray.getRecordBuffer(2, 2).get(buf);
- Assert.assertArrayEquals("Record 2,2 doesn't match.", record1, buf);
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/TestBitsUtil.java b/test/de/lmu/ifi/dbs/elki/utilities/TestBitsUtil.java
deleted file mode 100644
index ea1bc757..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/TestBitsUtil.java
+++ /dev/null
@@ -1,212 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.*;
-
-import java.math.BigInteger;
-import java.util.BitSet;
-import java.util.Random;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.utilities.BitsUtil;
-
-public class TestBitsUtil implements JUnit4Test {
- @Test
- public void testAgainstBigInteger() {
- BigInteger bigint = new BigInteger("123");
- long[] bituti = BitsUtil.make(Long.SIZE, 123);
- assertEquals("Bit strings do not agree.", bigint.toString(2), BitsUtil.toString(bituti));
-
- bigint = bigint.shiftLeft(13);
- BitsUtil.shiftLeftI(bituti, 13);
- assertEquals("Bit strings do not agree.", bigint.toString(2), BitsUtil.toString(bituti));
-
- bigint = bigint.shiftRight(15);
- BitsUtil.shiftRightI(bituti, 15);
- assertEquals("Bit strings do not agree.", bigint.toString(2), BitsUtil.toString(bituti));
- }
-
- @Test
- public void testSimpleOperations() {
- long[] test = BitsUtil.zero(128);
- BitsUtil.setI(test, 5);
- BitsUtil.setI(test, 7);
- assertEquals(BitsUtil.toString(test), "10100000");
- assertEquals(BitsUtil.numberOfTrailingZerosSigned(test), 5);
- BitsUtil.truncateI(test, 7);
- assertEquals(BitsUtil.toString(test), "100000");
- assertEquals(BitsUtil.numberOfTrailingZerosSigned(test), 5);
- BitsUtil.setI(test, 7);
- assertEquals(BitsUtil.toString(test), "10100000");
- assertEquals(BitsUtil.numberOfTrailingZerosSigned(test), 5);
- BitsUtil.cycleRightI(test, 6, 8);
- assertEquals(BitsUtil.toString(test), "10000010");
- assertEquals(BitsUtil.numberOfTrailingZerosSigned(test), 1);
- assertEquals(BitsUtil.numberOfTrailingZeros(test), 1);
-
- BitsUtil.zeroI(test);
- BitsUtil.setI(test, 125);
- BitsUtil.setI(test, 60);
- BitsUtil.cycleRightI(test, 70, 128);
- assertTrue(BitsUtil.get(test, 55));
- assertTrue(BitsUtil.get(test, 118));
- assertEquals(BitsUtil.cardinality(test), 2);
- BitsUtil.cycleLeftI(test, 70, 128);
- assertTrue(BitsUtil.get(test, 125));
- assertTrue(BitsUtil.get(test, 60));
- assertEquals(BitsUtil.cardinality(test), 2);
- }
-
- @Test
- public void testSorting() {
- final Random r = new Random(0);
- final int cnt = 100;
- long[] rnds = new long[cnt];
- long[][] bits = new long[cnt][];
- for (int i = 0; i < cnt; i++) {
- rnds[i] = Math.abs(r.nextLong());
- bits[i] = BitsUtil.make(Long.SIZE, rnds[i]);
- }
-
- for (int i = 0; i < cnt; i++) {
- for (int j = 0; j < cnt; j++) {
- assertEquals(compare(rnds[i], rnds[j]), BitsUtil.compare(bits[i], bits[j]));
- }
- }
-
- for (int i = 0; i < cnt; i++) {
- long[] btmp = BitsUtil.copy(bits[i], 64 + r.nextInt(500));
- assertEquals(BitsUtil.compare(btmp, bits[i]), 0);
- for (int j = 0; j < cnt; j++) {
- assertEquals(compare(rnds[i], rnds[j]), BitsUtil.compare(btmp, bits[j]));
- }
- }
-
- for (int i = 0; i < cnt; i++) {
- long[] btmp = BitsUtil.truncateI(BitsUtil.copy(bits[i]), 47);
- for (int j = 0; j < cnt; j++) {
- assertEquals(compare(rnds[i] & ((1 << 48) - 1), rnds[j]), BitsUtil.compare(btmp, bits[j]));
- }
- }
-
- for (int i = 0; i < cnt; i++) {
- long[] btmp = BitsUtil.cycleRightI(BitsUtil.copy(bits[i]), 13, Long.SIZE - 32);
- long ltmp = BitsUtil.cycleRightC(rnds[i], 13, Long.SIZE - 32);
- for (int j = 0; j < cnt; j++) {
- assertEquals(compare(ltmp, rnds[j]), BitsUtil.compare(btmp, bits[j]));
- }
- }
- }
-
- /**
- * Not jet in Java 6. To come in JDK7 as Long.copmare
- *
- * @param x
- * @param y
- * @return
- */
- public static int compare(long x, long y) {
- return (x < y) ? -1 : ((x == y) ? 0 : 1);
- }
-
- @Test
- public void testAgainstBitSet() {
- BitSet bitset = new BitSet();
- long[] bituti = BitsUtil.zero(Long.SIZE);
- for (int i = 0; i >= 0;) {
- assertEquals("Bit strings do not agree.", bitset.nextSetBit(i), BitsUtil.nextSetBit(bituti, i));
- i = bitset.nextSetBit(i + 1);
- }
- // Java 7:
- // assertEquals("Bit strings do not agree.",
- // BitsUtil.toString(bitset.toLongArray()), BitsUtil.toString(bituti));
-
- bitset.set(4);
- BitsUtil.setI(bituti, 4);
- for (int i = 0; i >= 0;) {
- assertEquals("Bit strings do not agree.", bitset.nextSetBit(i), BitsUtil.nextSetBit(bituti, i));
- i = bitset.nextSetBit(i + 1);
- }
- // Java 7:
- // assertEquals("Bit strings do not agree.",
- // BitsUtil.toString(bitset.toLongArray()), BitsUtil.toString(bituti));
-
- bitset.set(15);
- BitsUtil.setI(bituti, 15);
- for (int i = 0; i >= 0;) {
- assertEquals("Bit strings do not agree.", bitset.nextSetBit(i), BitsUtil.nextSetBit(bituti, i));
- i = bitset.nextSetBit(i + 1);
- }
- // Java 7:
- // assertEquals("Bit strings do not agree.",
- // BitsUtil.toString(bitset.toLongArray()), BitsUtil.toString(bituti));
-
- assertEquals(bitset.nextSetBit(0), BitsUtil.nextSetBit(bituti, 0));
- assertEquals(bitset.nextSetBit(4), BitsUtil.nextSetBit(bituti, 4));
- assertEquals(bitset.nextSetBit(5), BitsUtil.nextSetBit(bituti, 5));
- // previousSetBit is not in JDK6.
- // assertEquals(bitset.previousSetBit(64), BitsUtil.previousSetBit(bituti,
- // 64));
- // assertEquals(bitset.previousSetBit(15), BitsUtil.previousSetBit(bituti,
- // 15));
- // assertEquals(bitset.previousSetBit(14), BitsUtil.previousSetBit(bituti,
- // 14));
- }
-
- @Test
- public void testGrayCoding() {
- long[] bits = BitsUtil.zero(123);
- long[] ones = BitsUtil.ones(123);
- BitsUtil.flipI(bits, 122);
- BitsUtil.invgrayI(bits);
- BitsUtil.xorI(bits, ones);
- assertTrue(BitsUtil.isZero(bits));
- BitsUtil.xorI(bits, ones);
- BitsUtil.grayI(bits);
- assertTrue(BitsUtil.get(bits, 122));
- assertEquals(1, BitsUtil.cardinality(bits));
- }
-
- @Test
- public void testLeadingTrailing() {
- int[] testi = new int[] { 0x7, 0x12345678, 0x23456789, 0x45678900, 0x89000000, 0xFFFF0000 };
- int[] truli = new int[] { 29, 3, 2, 1, 0, 0 };
- int[] truti = new int[] { 0, 3, 0, 8, 24, 16 };
- for (int i = 0; i < testi.length; i++) {
- assertEquals("Leading zeros don't agree for " + BitsUtil.toString(testi[i]), truli[i], BitsUtil.numberOfLeadingZeros(testi[i]));
- assertEquals("Trailing zeros don't agree for " + BitsUtil.toString(testi[i]), truti[i], BitsUtil.numberOfTrailingZeros(testi[i]));
- }
-
- long[] testl = new long[] { 0x7L, 0x12345678L, 0x23456789L, 0x45678900L, 0x89000000L, 0x1FFFF0000L, 0x123456789ABCDEFL, 0x0011001188008800L };
- int[] trull = new int[] { 61, 35, 34, 33, 32, 31, 7, 11 };
- int[] trutl = new int[] { 0, 3, 0, 8, 24, 16, 0, 11 };
- for (int i = 0; i < testl.length; i++) {
- assertEquals("Leading zeros don't agree for " + BitsUtil.toString(testl[i]), trull[i], BitsUtil.numberOfLeadingZeros(testl[i]));
- assertEquals("Trailing zeros don't agree for " + BitsUtil.toString(testl[i]), trutl[i], BitsUtil.numberOfTrailingZeros(testl[i]));
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/TestFormatUtil.java b/test/de/lmu/ifi/dbs/elki/utilities/TestFormatUtil.java
deleted file mode 100644
index 93a739ba..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/TestFormatUtil.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-public class TestFormatUtil implements JUnit4Test {
- @Test
- public void testParseDouble() {
- assertEquals(0., FormatUtil.parseDouble("0"), 0.);
- assertEquals(1., FormatUtil.parseDouble("1"), 0.);
- assertEquals(-1., FormatUtil.parseDouble("-1"), 0.);
- assertEquals(0., FormatUtil.parseDouble("0.0"), 0.);
- assertEquals(1., FormatUtil.parseDouble("1.0"), 0.);
- assertEquals(-1., FormatUtil.parseDouble("-1.0"), 0.);
- assertEquals(.2, FormatUtil.parseDouble("0.2"), 0.);
- assertEquals(-.2, FormatUtil.parseDouble("-0.2"), 0.);
- assertEquals(.2, FormatUtil.parseDouble(".2"), 0.);
- assertEquals(-.2, FormatUtil.parseDouble("-.2"), 0.);
- assertEquals(2000., FormatUtil.parseDouble("2.0e3"), 0.);
- assertEquals(2000., FormatUtil.parseDouble("2.0E3"), 0.);
- assertEquals(-2000., FormatUtil.parseDouble("-2.0e3"), 0.);
- assertEquals(-2000., FormatUtil.parseDouble("-2.0E3"), 0.);
- assertEquals(.002, FormatUtil.parseDouble("2.0e-3"), 0.);
- assertEquals(.002, FormatUtil.parseDouble("2.0E-3"), 0.);
- assertEquals(-.002, FormatUtil.parseDouble("-2.0e-3"), 0.);
- assertEquals(-.002, FormatUtil.parseDouble("-2.0E-3"), 0.);
-
- // Case where the JDK had a serious bug, in a few variations
- assertEquals(2.2250738585072012e-308, FormatUtil.parseDouble("2.2250738585072012e-308"), 0.);
- assertEquals(0.00022250738585072012e-304, FormatUtil.parseDouble("0.00022250738585072012e-304"), 0.);
- assertEquals(00000000002.2250738585072012e-308, FormatUtil.parseDouble("00000000002.2250738585072012e-308"), 0.);
- assertEquals(2.2250738585072012e-00308, FormatUtil.parseDouble("2.2250738585072012e-00308"), 0.);
-
- assertTrue(Double.POSITIVE_INFINITY == FormatUtil.parseDouble("inf"));
- assertTrue(Double.NEGATIVE_INFINITY == FormatUtil.parseDouble("-inf"));
- assertTrue(Double.POSITIVE_INFINITY == FormatUtil.parseDouble("∞"));
- assertTrue(Double.NEGATIVE_INFINITY == FormatUtil.parseDouble("-∞"));
- assertTrue(Double.isNaN(FormatUtil.parseDouble("nan")));
-
- assertEquals(1, FormatUtil.parseDouble("+1"), 0.);
- }
-
- @Test(expected = NumberFormatException.class)
- public void textOnlyPlus() {
- FormatUtil.parseDouble("+");
- }
-
- @Test(expected = NumberFormatException.class)
- public void textExtraCharacer() {
- FormatUtil.parseDouble("123Banana");
- }
-
- @Test(expected = NumberFormatException.class)
- public void textTooManyDigits() {
- FormatUtil.parseDouble("123456789012345678901234567890");
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/TestQuickSelect.java b/test/de/lmu/ifi/dbs/elki/utilities/datastructures/TestQuickSelect.java
deleted file mode 100644
index b9030d59..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/TestQuickSelect.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.datastructures;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-
-import java.util.Arrays;
-import java.util.Random;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.QuickSelect;
-
-/**
- * Test the QuickSelect math class.
- *
- * @author Erich Schubert
- */
-public class TestQuickSelect implements JUnit4Test {
- /**
- * Array size to use.
- */
- final int SIZE = 10000;
-
- @Test
- public void testRandomDoubles() {
- for(int i = 1; i < 10; i++) {
- testQuickSelect(i);
- }
- testQuickSelect(SIZE);
- testQuickSelect(SIZE + 1);
- }
-
- private void testQuickSelect(int size) {
- double[] data = new double[size];
- double[] test;
-
- // Make a random generator, but remember the seed for debugging.
- Random r = new Random();
- long seed = r.nextLong();
- r = new Random(seed);
-
- // Produce data
- for(int i = 0; i < size; i++) {
- data[i] = r.nextDouble();
- }
- // Duplicate for reference, sort.
- test = Arrays.copyOf(data, size);
- Arrays.sort(test);
-
- // Run QuickSelect and compare with full sort
- // After a few iterations, the array will be largely sorted.
- // Better just run the whole test a few times, than doing too many
- // iterations here.
- for(int j = 0; j < 20; j++) {
- int q = r.nextInt(size);
- double r1 = QuickSelect.quickSelect(data, q);
- double r2 = test[q];
- assertEquals("QuickSelect returned incorrect element. Seed=" + seed, r2, r1, Double.MIN_VALUE);
- }
- double med = QuickSelect.median(data);
- if(size % 2 == 1) {
- double met = test[(size - 1) / 2];
- assertEquals("QuickSelect returned incorrect median. Seed=" + seed, met, med, Double.MIN_VALUE);
- }
- else {
- double met = (test[(size - 1) / 2] + test[(size + 1) / 2]) / 2;
- assertEquals("QuickSelect returned incorrect median. Seed=" + seed, med, met, Double.MIN_VALUE);
- }
- double qua = QuickSelect.quantile(data, 0.5);
- assertEquals("Median and 0.5 quantile do not agree. Seed=" + seed, med, qua, 1E-15);
- }
-
- @Test
- public void testPartialArray() {
- double data[] = new double[] { 0.1, 0.2, 1, 2, 3, 0.9, 0.95 };
- assertEquals("Partial median incorrect.", 1, QuickSelect.median(data, 2, 3), Double.MIN_VALUE);
- assertEquals("Partial median incorrect.", 3, QuickSelect.median(data, 4, 5), Double.MIN_VALUE);
- // Note: do not change the order, since this modifies the array.
- assertEquals("Partial median incorrect.", 2, QuickSelect.median(data, 2, 5), Double.MIN_VALUE);
- // Note: do not change the order, since this modifies the array.
- assertEquals("Full median incorrect.", 0.95, QuickSelect.median(data), Double.MIN_VALUE);
- }
-
- @Test
- public void testTies() {
- double data[] = new double[] { 0.1, 0.1, 0.9, 0.9, 0.5, 0.9, 0.1, 0.1, 0.1, 0.9, 0.9, 0.9, 0.9, 0.1, 0.1 };
- assertEquals("Full median incorrect.", 0.5, QuickSelect.median(data), Double.MIN_VALUE);
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestDoubleHeap.java b/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestDoubleHeap.java
deleted file mode 100644
index 51663a9a..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestDoubleHeap.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertTrue;
-
-import java.util.Random;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Perform standard unit tests on the double-indexed heap structures.
- *
- * @author Erich Schubert
- */
-public class TestDoubleHeap implements JUnit4Test {
- @Test
- public void testDoubleMinHeap() {
- Random r = new Random();
- DoubleMinHeap heap = new DoubleMinHeap();
- for (int i = 0; i < 1000; i++) {
- double key = r.nextDouble();
- heap.add(key);
- }
- double cur = Double.NEGATIVE_INFINITY;
- for (int i = 0; i < 500; i++) {
- assertTrue("Heap incorrectly ordered!", cur <= heap.peek());
- cur = heap.peek();
- heap.poll();
- }
- for (int i = 0; i < 10000; i++) {
- double key = r.nextDouble();
- heap.add(key);
- }
- cur = Double.NEGATIVE_INFINITY;
- while (heap.size() > 0) {
- assertTrue("Heap incorrectly ordered!", cur <= heap.peek());
- cur = heap.peek();
- heap.poll();
- }
- }
-
- @Test
- public void testDoubleMaxHeap() {
- Random r = new Random();
- DoubleMaxHeap heap = new DoubleMaxHeap();
- for (int i = 0; i < 1000; i++) {
- double key = r.nextDouble();
- heap.add(key);
- }
- double cur = Double.POSITIVE_INFINITY;
- for (int i = 0; i < 500; i++) {
- assertTrue("Heap incorrectly ordered! "+cur+" < "+heap.peek(), cur >= heap.peek());
- cur = heap.peek();
- heap.poll();
- }
- for (int i = 0; i < 10000; i++) {
- double key = r.nextDouble();
- heap.add(key);
- }
- cur = Double.POSITIVE_INFINITY;
- while (heap.size() > 0) {
- assertTrue("Heap incorrectly ordered!", cur >= heap.peek());
- cur = heap.peek();
- heap.poll();
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestDoubleObjectHeaps.java b/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestDoubleObjectHeaps.java
deleted file mode 100644
index e75b8094..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestDoubleObjectHeaps.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertTrue;
-
-import java.util.Random;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * Perform standard unit tests on the double-object heap structures.
- *
- * @author Erich Schubert
- */
-public class TestDoubleObjectHeaps implements JUnit4Test {
- @Test
- public void testDoubleObjMinHeap() {
- Random r = new Random();
- DoubleObjectMinHeap<Double> heap = new DoubleObjectMinHeap<>();
- for(int i = 0; i < 1000; i++) {
- double key = r.nextDouble();
- heap.add(key, key);
- }
- double cur = Double.NEGATIVE_INFINITY;
- for(int i = 0; i < 500; i++) {
- assertTrue("Heap incorrectly ordered!", cur <= heap.peekKey());
- cur = heap.peekKey();
- heap.poll();
- }
- for(int i = 0; i < 10000; i++) {
- double key = r.nextDouble();
- heap.add(key, key);
- }
- cur = Double.NEGATIVE_INFINITY;
- while(heap.size() > 0) {
- assertTrue("Heap incorrectly ordered!", cur <= heap.peekKey());
- cur = heap.peekKey();
- heap.poll();
- }
- }
-
- @Test
- public void testDoubleObjMaxHeap() {
- Random r = new Random();
- DoubleObjectMaxHeap<Double> heap = new DoubleObjectMaxHeap<>();
- for(int i = 0; i < 1000; i++) {
- double key = r.nextDouble();
- heap.add(key, key);
- }
- double cur = Double.POSITIVE_INFINITY;
- for(int i = 0; i < 500; i++) {
- assertTrue("Heap incorrectly ordered!", cur >= heap.peekKey());
- cur = heap.peekKey();
- heap.poll();
- }
- for(int i = 0; i < 10000; i++) {
- double key = r.nextDouble();
- heap.add(key, key);
- }
- cur = Double.POSITIVE_INFINITY;
- while(heap.size() > 0) {
- assertTrue("Heap incorrectly ordered!", cur >= heap.peekKey());
- cur = heap.peekKey();
- heap.poll();
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestHeap.java b/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestHeap.java
deleted file mode 100644
index 66e06a9f..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestHeap.java
+++ /dev/null
@@ -1,232 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Random;
-
-import org.junit.Test;
-
-/**
- * Test the in-memory heap class.
- *
- * @author Erich Schubert
- */
-public class TestHeap {
- /**
- * Puts 10 integers into both an ascending and a descending heap and verifies
- * they come out in sequence.
- */
- @Test
- public void testHeap() {
- int dup = 2;
- Integer[] data = { 5, 3, 4, 2, 7, 1, 9, 8, 10, 6 };
- Integer[] asc = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
- Integer[] desc = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
- ComparableMinHeap<Integer> hasc = new ComparableMinHeap<>();
- ComparableMaxHeap<Integer> hdesc = new ComparableMaxHeap<>();
- for(Integer i : data) {
- for(int j = 0; j < dup; j++) {
- hasc.add(i);
- hdesc.add(i);
- }
- }
- // Empty
- for(int i = 0; i < asc.length; i++) {
- for(int j = 0; j < dup; j++) {
- final Integer gota = hasc.poll();
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- final Integer gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
- // Refill
- for(Integer i : data) {
- for(int j = 0; j < dup; j++) {
- hasc.add(i);
- hdesc.add(i);
- }
- }
- // Empty halfway
- for(int i = 0; i < 5; i++) {
- for(int j = 0; j < dup; j++) {
- final Integer gota = hasc.poll();
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- final Integer gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
- // Re-add
- for(int i = 0; i < 5; i++) {
- for(int j = 0; j < dup; j++) {
- hasc.add(asc[i]);
- hdesc.add(desc[i]);
- }
- }
- // Empty again
- for(int i = 0; i < asc.length; i++) {
- for(int j = 0; j < dup; j++) {
- final Integer gota = hasc.poll();
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- final Integer gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
- // Sequential insert
- for(int i : asc) {
- for(int j = 0; j < dup; j++) {
- hasc.add(i);
- hdesc.add(i);
- }
- }
- // Empty halfway
- for(int i = 0; i < 5; i++) {
- for(int j = 0; j < dup; j++) {
- final Integer gota = hasc.poll();
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- final Integer gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
- // Re-add
- for(int i = 0; i < 5; i++) {
- for(int j = 0; j < dup; j++) {
- hasc.add(asc[i]);
- hdesc.add(desc[i]);
- }
- }
- // Empty again
- for(int i = 0; i < asc.length; i++) {
- for(int j = 0; j < dup; j++) {
- final Integer gota = hasc.poll();
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- final Integer gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
-
- // Bonus: Sequential insert lower part only
- for(int i = 0; i < asc.length >> 1; i++) {
- for(int j = 0; j < dup << 1; j++) {
- hasc.add(asc[i]);
- hdesc.add(desc[i]);
- }
- }
- // Empty halfway
- for(int i = 0; i < 3; i++) {
- for(int j = 0; j < dup << 1; j++) {
- final Integer gota = hasc.poll();
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- final Integer gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
- // Add upper half
- for(int i = asc.length >> 1; i < asc.length; i++) {
- for(int j = 0; j < dup; j++) {
- hasc.add(asc[i]);
- hdesc.add(desc[i]);
- }
- }
- //System.err.println(hasc.toString() + " " + hasc.validSize);
- // Empty again
- for(int i = 3; i < asc.length; i++) {
- int f = (i < (asc.length >> 1)) ? 2 : 1;
- for(int j = 0; j < dup * f; j++) {
- final Integer gota = hasc.poll();
- //System.err.println(hasc.toString() + " " + hasc.validSize);
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- final Integer gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
- }
-
- /**
- * Puts 10 integers into both an ascending and a descending heap and verifies
- * they come out in sequence.
- */
- @Test
- public void testHeapRandomInt() {
- int size = 10000;
- Random r = new Random(123L);
- ComparableMinHeap<Integer> hasc = new ComparableMinHeap<>();
- ComparableMaxHeap<Integer> hdesc = new ComparableMaxHeap<>();
- for(int i = 0; i < size; i++) {
- int in = r.nextInt();
- hasc.add(in);
- hdesc.add(in);
- }
- int last = Integer.MIN_VALUE;
- for(int i = 0; i < size; i++) {
- final Integer gota = hasc.poll();
- assertTrue("Objects sorted incorrectly at ascending position " + i, gota >= last);
- last = gota;
- }
- last = Integer.MAX_VALUE;
- for(int i = 0; i < size; i++) {
- final Integer gotd = hdesc.poll();
- assertTrue("Objects sorted incorrectly at descending position " + i, gotd <= last);
- last = gotd;
- }
- // Rerun, but only halfway down
- for(int i = 0; i < size; i++) {
- int in = r.nextInt();
- hasc.add(in);
- hdesc.add(in);
- }
- last = Integer.MIN_VALUE;
- for(int i = 0; i < size >>> 1; i++) {
- final Integer gota = hasc.poll();
- assertTrue("Objects sorted incorrectly at ascending position " + i, gota >= last);
- last = gota;
- }
- last = Integer.MAX_VALUE;
- for(int i = 0; i < size >>> 1; i++) {
- final Integer gotd = hdesc.poll();
- assertTrue("Objects sorted incorrectly at descending position " + i, gotd <= last);
- last = gotd;
- }
- // Refill:
- for(int i = size >>> 1; i < size; i++) {
- int in = r.nextInt();
- hasc.add(in);
- hdesc.add(in);
- }
- last = Integer.MIN_VALUE;
- for(int i = 0; i < size; i++) {
- final Integer gota = hasc.poll();
- assertTrue("Objects sorted incorrectly at ascending position " + i, gota >= last);
- last = gota;
- }
- last = Integer.MAX_VALUE;
- for(int i = 0; i < size; i++) {
- final Integer gotd = hdesc.poll();
- assertTrue("Objects sorted incorrectly at descending position " + i, gotd <= last);
- last = gotd;
- }
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestHeapPerformance.java b/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestHeapPerformance.java
deleted file mode 100644
index f80fbec5..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestHeapPerformance.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.PriorityQueue;
-import java.util.Queue;
-import java.util.Random;
-
-import org.junit.Test;
-
-/**
- * Unit test to ensure that our heap is not significantly worse than SUN javas
- * regular PriorityQueue.
- *
- * @author Erich Schubert
- */
-public class TestHeapPerformance {
- final private int queueSize = 200000;
-
- final private int preiterations = 20;
-
- final private int iterations = 200;
-
- final private long seed = 123456L;
-
- @Test
- public void testRuntime() throws Exception {
- // prepare the data set
- final List<Integer> elements = new ArrayList<>(queueSize);
- {
- final Random random = new Random(seed);
- for(int i = 0; i < queueSize; i++) {
- elements.add(i);
- }
- Collections.shuffle(elements, random);
- }
-
- // Pretest, to trigger hotspot compiler, hopefully.
- {
- for(int j = 0; j < preiterations; j++) {
- ComparableMinHeap<Integer> pq = new ComparableMinHeap<>();
- testHeap(elements, pq);
- }
- for(int j = 0; j < preiterations; j++) {
- PriorityQueue<Integer> pq = new PriorityQueue<>();
- testQueue(elements, pq);
- }
- }
-
- long pqstart = System.nanoTime();
- {
- for(int j = 0; j < iterations; j++) {
- PriorityQueue<Integer> pq = new PriorityQueue<>();
- testQueue(elements, pq);
- }
- }
- long pqtime = System.nanoTime() - pqstart;
-
- long hstart = System.nanoTime();
- {
- for(int j = 0; j < iterations; j++) {
- ComparableMinHeap<Integer> pq = new ComparableMinHeap<>();
- testHeap(elements, pq);
- }
- }
- long htime = System.nanoTime() - hstart;
-
- System.err.println("Heap performance test: us: " + htime*1E-9 + " java: " + pqtime*1E-9);
- assertTrue("Heap performance regression - run test individually, since the hotspot optimizations may make the difference! " + htime + " >>= " + pqtime, htime < 1.05 * pqtime);
- // 1.05 allows some difference in measuring
- }
-
- private void testHeap(final List<Integer> elements, ComparableMinHeap<Integer> pq) {
- // Insert all
- for(int i = 0; i < elements.size(); i++) {
- pq.add(elements.get(i));
- }
- // Poll first half.
- for(int i = 0; i < elements.size() >> 1; i++) {
- assertEquals((int) pq.poll(), i);
- // assertEquals((int) pq.poll(), queueSize - 1 - i);
- }
- assertTrue("Heap not half-empty?", pq.size() == (elements.size() >> 1));
- pq.clear();
- }
-
- private void testQueue(final List<Integer> elements, Queue<Integer> pq) {
- // Insert all
- for(int i = 0; i < elements.size(); i++) {
- pq.add(elements.get(i));
- }
- // Poll first half.
- for(int i = 0; i < elements.size() >> 1; i++) {
- assertEquals((int) pq.poll(), i);
- // assertEquals((int) pq.poll(), queueSize - 1 - i);
- }
- assertTrue("Heap not half-empty?", pq.size() == (elements.size() >> 1));
- pq.clear();
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestIntegerHeap.java b/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestIntegerHeap.java
deleted file mode 100644
index 93c83dff..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestIntegerHeap.java
+++ /dev/null
@@ -1,232 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Random;
-
-import org.junit.Test;
-
-/**
- * Test the in-memory heap class.
- *
- * @author Erich Schubert
- */
-public class TestIntegerHeap {
- /**
- * Puts 10 integers into both an ascending and a descending heap and verifies
- * they come out in sequence.
- */
- @Test
- public void testHeap() {
- int dup = 2;
- int[] data = { 5, 3, 4, 2, 7, 1, 9, 8, 10, 6 };
- int[] asc = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
- int[] desc = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
- IntegerMinHeap hasc = new IntegerMinHeap();
- IntegerMaxHeap hdesc = new IntegerMaxHeap();
- for(Integer i : data) {
- for(int j = 0; j < dup; j++) {
- hasc.add(i);
- hdesc.add(i);
- }
- }
- // Empty
- for(int i = 0; i < asc.length; i++) {
- for(int j = 0; j < dup; j++) {
- final int gota = hasc.poll();
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- final int gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
- // Refill
- for(int i : data) {
- for(int j = 0; j < dup; j++) {
- hasc.add(i);
- hdesc.add(i);
- }
- }
- // Empty halfway
- for(int i = 0; i < 5; i++) {
- for(int j = 0; j < dup; j++) {
- final int gota = hasc.poll();
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- final int gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
- // Re-add
- for(int i = 0; i < 5; i++) {
- for(int j = 0; j < dup; j++) {
- hasc.add(asc[i]);
- hdesc.add(desc[i]);
- }
- }
- // Empty again
- for(int i = 0; i < asc.length; i++) {
- for(int j = 0; j < dup; j++) {
- final int gota = hasc.poll();
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- final int gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
- // Sequential insert
- for(int i : asc) {
- for(int j = 0; j < dup; j++) {
- hasc.add(i);
- hdesc.add(i);
- }
- }
- // Empty halfway
- for(int i = 0; i < 5; i++) {
- for(int j = 0; j < dup; j++) {
- final int gota = hasc.poll();
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- final int gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
- // Re-add
- for(int i = 0; i < 5; i++) {
- for(int j = 0; j < dup; j++) {
- hasc.add(asc[i]);
- hdesc.add(desc[i]);
- }
- }
- // Empty again
- for(int i = 0; i < asc.length; i++) {
- for(int j = 0; j < dup; j++) {
- final int gota = hasc.poll();
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- final int gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
-
- // Bonus: Sequential insert lower part only
- for(int i = 0; i < asc.length >> 1; i++) {
- for(int j = 0; j < dup << 1; j++) {
- hasc.add(asc[i]);
- hdesc.add(desc[i]);
- }
- }
- // Empty halfway
- for(int i = 0; i < 3; i++) {
- for(int j = 0; j < dup << 1; j++) {
- final int gota = hasc.poll();
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- final int gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
- // Add upper half
- for(int i = asc.length >> 1; i < asc.length; i++) {
- for(int j = 0; j < dup; j++) {
- hasc.add(asc[i]);
- hdesc.add(desc[i]);
- }
- }
- //System.err.println(hasc.toString() + " " + hasc.validSize);
- // Empty again
- for(int i = 3; i < asc.length; i++) {
- int f = (i < (asc.length >> 1)) ? 2 : 1;
- for(int j = 0; j < dup * f; j++) {
- final int gota = hasc.poll();
- //System.err.println(hasc.toString() + " " + hasc.validSize);
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- final int gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
- }
-
- /**
- * Puts 10 integers into both an ascending and a descending heap and verifies
- * they come out in sequence.
- */
- @Test
- public void testHeapRandomInt() {
- int size = 10000;
- Random r = new Random(123L);
- ComparableMinHeap<Integer> hasc = new ComparableMinHeap<>();
- ComparableMaxHeap<Integer> hdesc = new ComparableMaxHeap<>();
- for(int i = 0; i < size; i++) {
- int in = r.nextInt();
- hasc.add(in);
- hdesc.add(in);
- }
- int last = Integer.MIN_VALUE;
- for(int i = 0; i < size; i++) {
- final Integer gota = hasc.poll();
- assertTrue("Objects sorted incorrectly at ascending position " + i, gota >= last);
- last = gota;
- }
- last = Integer.MAX_VALUE;
- for(int i = 0; i < size; i++) {
- final Integer gotd = hdesc.poll();
- assertTrue("Objects sorted incorrectly at descending position " + i, gotd <= last);
- last = gotd;
- }
- // Rerun, but only halfway down
- for(int i = 0; i < size; i++) {
- int in = r.nextInt();
- hasc.add(in);
- hdesc.add(in);
- }
- last = Integer.MIN_VALUE;
- for(int i = 0; i < size >>> 1; i++) {
- final Integer gota = hasc.poll();
- assertTrue("Objects sorted incorrectly at ascending position " + i, gota >= last);
- last = gota;
- }
- last = Integer.MAX_VALUE;
- for(int i = 0; i < size >>> 1; i++) {
- final Integer gotd = hdesc.poll();
- assertTrue("Objects sorted incorrectly at descending position " + i, gotd <= last);
- last = gotd;
- }
- // Refill:
- for(int i = size >>> 1; i < size; i++) {
- int in = r.nextInt();
- hasc.add(in);
- hdesc.add(in);
- }
- last = Integer.MIN_VALUE;
- for(int i = 0; i < size; i++) {
- final Integer gota = hasc.poll();
- assertTrue("Objects sorted incorrectly at ascending position " + i, gota >= last);
- last = gota;
- }
- last = Integer.MAX_VALUE;
- for(int i = 0; i < size; i++) {
- final Integer gotd = hdesc.poll();
- assertTrue("Objects sorted incorrectly at descending position " + i, gotd <= last);
- last = gotd;
- }
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestIntegerMinHeapPerformance.java b/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestIntegerMinHeapPerformance.java
deleted file mode 100644
index 9f4cf08e..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestIntegerMinHeapPerformance.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.PriorityQueue;
-import java.util.Queue;
-import java.util.Random;
-
-import org.junit.Test;
-
-/**
- * Unit test to ensure that our heap is not significantly worse than SUN javas
- * regular PriorityQueue.
- *
- * @author Erich Schubert
- */
-public class TestIntegerMinHeapPerformance {
- final private int queueSize = 100000;
-
- final private int iterations = 20;
-
- final private long seed = 123456L;
-
- @Test
- public void testRuntime() throws Exception {
- // prepare the data set
- final List<Integer> elements = new ArrayList<>(queueSize);
- {
- final Random random = new Random(seed);
- for(int i = 0; i < queueSize; i++) {
- elements.add(i);
- }
- Collections.shuffle(elements, random);
- }
-
- // Pretest, to trigger hotspot compiler, hopefully.
- {
- for(int j = 0; j < iterations; j++) {
- IntegerMinHeap pq = new IntegerMinHeap();
- testHeap(elements, pq);
- }
- for(int j = 0; j < iterations; j++) {
- PriorityQueue<Integer> pq = new PriorityQueue<>(); // 11,
- testQueue(elements, pq);
- }
- }
-
- long hstart = System.nanoTime();
- {
- for(int j = 0; j < iterations; j++) {
- IntegerMinHeap pq = new IntegerMinHeap();
- testHeap(elements, pq);
- }
- }
- long htime = System.nanoTime() - hstart;
-
- long pqstart = System.nanoTime();
- {
- for(int j = 0; j < iterations; j++) {
- PriorityQueue<Integer> pq = new PriorityQueue<>(); // 11
- testQueue(elements, pq);
- }
- }
- long pqtime = System.nanoTime() - pqstart;
- System.err.println("Heap performance test: us: " + htime*1E-9 + " java: " + pqtime*1E-9);
- assertTrue("Heap performance regression - run test individually, since the hotspot optimizations may make the difference! " + htime + " >>= " + pqtime, htime < 1.05 * pqtime);
- // 1.05 allows some difference in measuring
- }
-
- private void testHeap(final List<Integer> elements, IntegerMinHeap pq) {
- // Insert all
- for(int i = 0; i < elements.size(); i++) {
- pq.add(elements.get(i));
- }
- // Poll first half.
- for(int i = 0; i < elements.size() >> 1; i++) {
- assertEquals(pq.poll(), i);
- // assertEquals((int) pq.poll(), queueSize - 1 - i);
- }
- assertTrue("Heap not half-empty?", pq.size() == (elements.size() >> 1));
- pq.clear();
- }
-
- private void testQueue(final List<Integer> elements, Queue<Integer> pq) {
- // Insert all
- for(int i = 0; i < elements.size(); i++) {
- pq.add(elements.get(i));
- }
- // Poll first half.
- for(int i = 0; i < elements.size() >> 1; i++) {
- assertEquals((int) pq.poll(), i);
- // assertEquals((int) pq.poll(), queueSize - 1 - i);
- }
- assertTrue("Heap not half-empty?", pq.size() == (elements.size() >> 1));
- pq.clear();
- }
-} \ No newline at end of file
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestTiedTopBoundedHeap.java b/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestTiedTopBoundedHeap.java
deleted file mode 100644
index f0c96231..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestTiedTopBoundedHeap.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-
-import java.util.Collections;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.TiedTopBoundedHeap;
-
-/**
- * Test the in-memory bounded heap class.
- *
- * @author Erich Schubert
- */
-public class TestTiedTopBoundedHeap {
- /**
- * Test bounded heap
- */
- @Test
- public void testTiedTopBoundedHeap() {
- Integer[] data = { 5, 3, 4, 2, 7, 1, 9, 8, 10, 6, 5 };
- Integer[] asc = { 5, 5, 6, 7, 8, 9, 10 };
- Integer[] desc = { 5, 5, 4, 3, 2, 1 };
- Heap<Integer> hasc = new TiedTopBoundedHeap<>(asc.length - 1);
- Heap<Integer> hdesc = new TiedTopBoundedHeap<>(desc.length - 1, Collections.reverseOrder());
- for(Integer i : data) {
- hasc.add(i);
- hdesc.add(i);
- }
- // LoggingUtil.warning("Heap: "+hasc.toString()+ " -- "+hdesc.toString());
- assertEquals("Ascending heap size doesn't match", asc.length, hasc.size());
- assertEquals("Descending heap size doesn't match", desc.length, hdesc.size());
- for(int i = 0; i < asc.length; i++) {
- final Integer gota = hasc.poll();
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- }
- for(int i = 0; i < desc.length; i++) {
- final Integer gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
-
- /**
- * Test bounded heap
- */
- @Test
- public void testTiedTopBoundedHeapTrival() {
- Heap<Integer> heap1 = new TiedTopBoundedHeap<>(1);
- Heap<Integer> heap2 = new TiedTopBoundedHeap<>(1);
- Heap<Integer> heap3 = new TiedTopBoundedHeap<>(1);
- Heap<Integer> heap4 = new TiedTopBoundedHeap<>(1);
- Heap<Integer> heap5 = new TiedTopBoundedHeap<>(1);
- heap2.add(2);
- heap4.add(0);
- for(int i = 0; i < 10; i++) {
- heap1.add(1);
- heap2.add(1);
- heap3.add(1);
- heap4.add(1);
- heap5.add(1);
- }
- heap3.add(2);
- heap5.add(0);
- assertEquals("First heap size doesn't match", 10, heap1.size());
- assertEquals("Second heap size doesn't match", 1, heap2.size());
- assertEquals("Third heap size doesn't match", 1, heap3.size());
- assertEquals("Fourth heap size doesn't match", 10, heap4.size());
- assertEquals("Fifth heap size doesn't match", 10, heap5.size());
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestTiedTopBoundedUpdatableHeap.java b/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestTiedTopBoundedUpdatableHeap.java
deleted file mode 100644
index a0c45901..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestTiedTopBoundedUpdatableHeap.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Random;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-public class TestTiedTopBoundedUpdatableHeap implements JUnit4Test {
- @Test
- public void testTiedTopBoundedUpdatableHeap() {
- final int iters = 100;
- final int maxid = 5000;
- final int bsize = 1000;
- final int limit = 200;
- final Random r = new Random(1);
- ArrayList<IntegerPriorityObject<Integer>> simulate = new ArrayList<>(1000);
- TiedTopBoundedUpdatableHeap<IntegerPriorityObject<Integer>> heap = new TiedTopBoundedUpdatableHeap<>(limit);
- for(int i = 0; i < iters; i++) {
- int batchsize = r.nextInt(bsize);
- for(int j = 0; j < batchsize; j++) {
- int id = r.nextInt(maxid);
- int score = r.nextInt(10000);
- IntegerPriorityObject<Integer> nobj = new IntegerPriorityObject<>(score, id);
- // Update heap
- heap.add(nobj);
- // Enabling the followig assertion *hides* certain problems!
- // assertTrue("Heap not valid at i="+i, heap.checkHeap());
- // Update simulation
- boolean found = false;
- for(IntegerPriorityObject<Integer> ent : simulate) {
- if(ent.getObject().equals(id)) {
- if(score > ent.priority) {
- ent.priority = score;
- }
- found = true;
- break;
- }
- }
- if(!found) {
- simulate.add(nobj);
- }
- Collections.sort(simulate, Collections.reverseOrder());
- while(simulate.size() > limit) {
- int max = simulate.get(limit - 1).priority;
- if(simulate.get(simulate.size() - 1).priority == max) {
- break;
- }
- else {
- assertTrue(simulate.get(simulate.size() - 1).priority > max);
- simulate.remove(simulate.size() - 1);
- }
- }
- if(simulate.size() != heap.size()) {
- System.err.println("Lost synchronization " + i + "/" + j + ": " + id + " to " + score + "(" + found + ") sizes: " + simulate.size() + " " + heap.size());
- System.err.println("Sim: " + simulate.get(simulate.size() - 1) + " <=> Heap: " + heap.peek());
- }
- assertEquals("Sizes don't match!", simulate.size(), heap.size());
- }
- assertEquals("Heap not valid at i=" + i, null, heap.checkHeap());
-
- // System.err.println("Sim: " + simulate.get(simulate.size() - 1) +
- // " <=> Heap: " + heap.peek());
- // System.err.println(simulate.size() + " <=> " + heap.size());
- int remove = r.nextInt(simulate.size());
- for(int j = 0; j < remove; j++) {
- // System.out.println(heap.toString());
- IntegerPriorityObject<Integer> fromheap = heap.poll();
- IntegerPriorityObject<Integer> fromsim = simulate.remove(simulate.size() - 1);
- assertEquals("Priority doesn't agree.", fromheap.priority, fromsim.priority);
- if(j + 1 == remove) {
- while(heap.size() > 0) {
- assertEquals("Priority doesn't agree.", heap.peek().priority, simulate.get(simulate.size() - 1).priority);
- if(heap.peek().priority == fromheap.priority) {
- fromheap = heap.poll();
- fromsim = simulate.remove(simulate.size() - 1);
- }
- else {
- break;
- }
- }
- }
- }
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestTopBoundedHeap.java b/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestTopBoundedHeap.java
deleted file mode 100644
index 2bc87013..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestTopBoundedHeap.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertEquals;
-
-import java.util.Collections;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.TopBoundedHeap;
-
-/**
- * Test the in-memory bounded heap class.
- *
- * @author Erich Schubert
- */
-public class TestTopBoundedHeap {
- /**
- * Test bounded heap
- */
- @Test
- public void testBoundedHeap() {
- Integer[] data = { 5, 3, 4, 2, 7, 1, 9, 8, 10, 6 };
- Integer[] asc = { 5, 6, 7, 8, 9, 10 };
- Integer[] desc = { 6, 5, 4, 3, 2, 1 };
- Heap<Integer> hasc = new TopBoundedHeap<>(asc.length);
- Heap<Integer> hdesc = new TopBoundedHeap<>(desc.length, Collections.reverseOrder());
- for(Integer i : data) {
- hasc.add(i);
- hdesc.add(i);
- }
- for(int i = 0; i < asc.length; i++) {
- final Integer gota = hasc.poll();
- assertEquals("Objects sorted incorrectly at ascending position " + i, asc[i], gota);
- }
- for(int i = 0; i < desc.length; i++) {
- final Integer gotd = hdesc.poll();
- assertEquals("Objects sorted incorrectly at descending position " + i, desc[i], gotd);
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestUpdatableHeap.java b/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestUpdatableHeap.java
deleted file mode 100644
index bfe7e1f4..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TestUpdatableHeap.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.*;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Random;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-public class TestUpdatableHeap implements JUnit4Test {
- @Test
- public void testUpdatableHeap() {
- final int iters = 100;
- final int maxid = 5000;
- final int bsize = 100;
- final Random r = new Random(1);
- ArrayList<IntegerPriorityObject<Integer>> simulate = new ArrayList<>(1000);
- UpdatableHeap<IntegerPriorityObject<Integer>> heap = new UpdatableHeap<>();
- for(int i = 0; i < iters; i++) {
- int batchsize = r.nextInt(bsize);
- for(int j = 0; j < batchsize; j++) {
- int id = r.nextInt(maxid);
- int score = r.nextInt(10000);
- // Update heap
- heap.add(new IntegerPriorityObject<>(score, id));
- // Update simulation
- boolean found = false;
- for(IntegerPriorityObject<Integer> ent : simulate) {
- if(ent.getObject().equals(id)) {
- if(score > ent.priority) {
- // System.err.println("Updating in ArrayList: " + ent + " to " + score);
- ent.priority = score;
- }
- found = true;
- break;
- }
- }
- if(!found) {
- simulate.add(new IntegerPriorityObject<>(score, id));
- }
- }
- // Keeping the simulation list reverse is a bit faster for removal
- Collections.sort(simulate, Collections.reverseOrder());
- // System.err.println(simulate.size() + " <=> " + heap.size());
- assertEquals("Sizes don't match!", simulate.size(), heap.size());
- int remove = r.nextInt(simulate.size());
- for(int j = 0; j < remove; j++) {
- // System.out.println(heap.toString());
- IntegerPriorityObject<Integer> fromheap = heap.poll();
- IntegerPriorityObject<Integer> fromsim = simulate.remove(simulate.size() - 1);
- //System.out.println(fromheap+" <=> "+fromsim);
- assertEquals("Priority doesn't agree.", fromheap.priority, fromsim.priority);
- if(fromheap.getObject() != fromsim.getObject()) {
- // Ties
- if(j + 1 == remove && heap.size() > 0) {
- j++;
- }
- }
- }
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/TestHashMapHierarchy.java b/test/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/TestHashMapHierarchy.java
deleted file mode 100644
index 3a97e72d..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/TestHashMapHierarchy.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy;
-
-/*
- 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.HashSet;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy.Iter;
-
-/**
- * Test the main hierarchy implementation.
- *
- * @author Erich Schubert
- */
-public class TestHashMapHierarchy implements JUnit4Test {
- @Test
- public void testEmpty() {
- HashMapHierarchy<Object> hier = new HashMapHierarchy<>();
- assertFalse("Iterator valid?", hier.iterAll().valid());
- assertFalse("Iterator valid?", hier.iterParents(hier).valid());
- assertFalse("Iterator valid?", hier.iterAncestors(hier).valid());
- assertFalse("Iterator valid?", hier.iterChildren(hier).valid());
- assertFalse("Iterator valid?", hier.iterDescendants(hier).valid());
- }
-
- @Test
- public void testSimple() {
- final String a = "a", b = "b", c = "c", d = "d";
- HashMapHierarchy<Object> hier = new HashMapHierarchy<>();
- // A diamond hierarchy.
- hier.add(a, b);
- hier.add(a, c);
- hier.add(b, d);
- hier.add(c, d);
- validate(hier.iterAll(), new String[] { a, b, c, d });
- validate(hier.iterChildren(a), new String[] { b, c });
- validate(hier.iterDescendants(a), new String[] { b, c, d });
- validate(hier.iterParents(d), new String[] { b, c });
- validate(hier.iterAncestors(d), new String[] { a, b, c });
- }
-
- private <O> void validate(Iter<O> iter, O[] all) {
- HashSet<O> seen = new HashSet<>(all.length);
- for (; iter.valid(); iter.advance()) {
- O cur = iter.get();
- boolean found = false;
- for (int i = 0; i < all.length; i++) {
- if (all[i].equals(cur)) {
- found = true;
- seen.add(cur);
- break;
- }
- }
- assertTrue("Object not found in master solution: " + cur, found);
- }
- assertEquals("Not all objects were seen.", all.length, seen.size());
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/TestDoubleHistogram.java b/test/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/TestDoubleHistogram.java
deleted file mode 100644
index 51a9836b..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/TestDoubleHistogram.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * JUnit test to test the {@link ReplacingHistogram} class.
- *
- * @author Erich Schubert
- */
-public class TestDoubleHistogram implements JUnit4Test {
- /**
- * Test that adds some data to the histogram and compares results.
- */
- @Test
- public final void testHistogram() {
- double[] initial = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
- double[] filled = { 0.0, 1.23, 4.56, 7.89, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
- double[] changed = { 0.0, 1.35, 8.01, 14.67, 9.01, 2.34, 0.0, 0.0, 0.0, 0.0 };
- double[] resized = { -1.23, 0.0, 0.0, 1.35, 8.01, 14.67, 9.01, 2.34, 0.0, 0.0, 0.0, 0.0, 0.0, -4.56 };
- DoubleStaticHistogram hist = new DoubleStaticHistogram(10, 0.0, 1.0);
- assertArrayEquals("Empty histogram doesn't match", initial, hist.data, 1E-15);
- hist.increment(0.15, 1.23);
- hist.increment(0.25, 4.56);
- hist.increment(0.35, 7.89);
- assertArrayEquals("Filled histogram doesn't match", filled, hist.data, 1E-15);
- hist.increment(0.15, 0.12);
- hist.increment(0.25, 3.45);
- hist.increment(0.35, 6.78);
- hist.increment(0.45, 9.01);
- hist.increment(0.50, 2.34);
- assertArrayEquals("Changed histogram doesn't match", changed, hist.data, 1E-15);
- hist.increment(-.13, -1.23);
- hist.increment(1.13, -4.56);
- assertArrayEquals("Resized histogram doesn't match", resized, hist.data, 1E-15);
-
- // compare results via Iterator.
- int off = 0;
- for (DoubleStaticHistogram.Iter iter = hist.iter(); iter.valid(); iter.advance()) {
- assertEquals("Array iterator bin position", -0.15 + 0.1 * off, iter.getCenter(), 0.00001);
- assertEquals("Array iterator bin contents", resized[off], iter.getValue(), 0.00001);
- off++;
- }
- }
-}
diff --git a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/TestFlexiHistogram.java b/test/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/TestFlexiHistogram.java
deleted file mode 100644
index 9750977d..00000000
--- a/test/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/TestFlexiHistogram.java
+++ /dev/null
@@ -1,159 +0,0 @@
-package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2012
- 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 static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import java.util.Random;
-
-import org.junit.Test;
-
-import de.lmu.ifi.dbs.elki.JUnit4Test;
-
-/**
- * JUnit test to test the {@link AbstractObjDynamicHistogram} class.
- *
- * @author Erich Schubert
- */
-public class TestFlexiHistogram implements JUnit4Test {
- /**
- * Test that adds some data to the histogram and compares results.
- */
- @Test
- public final void testObjHistogram() {
- Double[] filled = { 0.0, 1.23, 4.56, 7.89, 0.0, null, null, null, null, null };
- Double[] changed = { 0.0, 1.35, 8.01, 14.67, 9.01, 2.34, null, null, null, null };
- Double[] resized = { -1.23, 1.35, 22.68, 11.35, 0.0, 0.0, -4.56, null, null, null };
- Double[] expanded = { 1., 0.0, 0.0, 0.0, 0.0, 0.0, 29.59, null, null, null };
- AbstractObjDynamicHistogram<Double> hist = new AbstractObjDynamicHistogram<Double>(5) {
- @Override
- public Double aggregate(Double first, Double second) {
- return Double.valueOf(first.doubleValue() + second.doubleValue());
- }
-
- @Override
- protected Double downsample(Object[] data, int start, int end, int size) {
- double sum = 0;
- for (int i = start; i < end; i++) {
- final Double val = (Double) data[i];
- if (val != null) {
- sum += val;
- }
- }
- return Double.valueOf(sum);
- }
-
- @Override
- protected Double makeObject() {
- return Double.valueOf(0.);
- }
-
- @Override
- protected Double cloneForCache(Double data) {
- return data;
- }
- };
- hist.putData(0.0, 0.0);
- hist.putData(0.15, 1.23);
- hist.putData(0.25, 4.56);
- hist.putData(0.35, 7.89);
- hist.putData(0.5, 0.0);
- hist.materialize();
- assertArrayEquals("Filled histogram doesn't match", filled, hist.data);
- hist.putData(0.15, 0.12);
- hist.putData(0.25, 3.45);
- hist.putData(0.35, 6.78);
- hist.putData(0.45, 9.01);
- hist.putData(0.55, 2.34);
- assertArrayEquals("Changed histogram doesn't match", changed, hist.data);
- hist.putData(-.13, -1.23);
- hist.putData(1.13, -4.56);
- assertArrayEquals("Resized histogram doesn't match", resized, hist.data);
-
- // compare results via Iterator.
- int off = 0;
- for (ObjHistogram.Iter<Double> iter = hist.iter(); iter.valid(); iter.advance()) {
- assertEquals("Array iterator bin position", -0.1 + 0.2 * off, iter.getCenter(), 0.00001);
- assertEquals("Array iterator bin contents", resized[off], iter.getValue(), 0.00001);
- off++;
- }
-
- // totally break out of the data range
- hist.putData(-10., 1.);
- assertArrayEquals("Expanded histogram doesn't match", expanded, hist.data);
-
- // Try some random operations, too
- Random r = new Random(0);
- for (int i = 0; i < 1000; i++) {
- hist.putData((r.nextDouble() - .5) * i * i, i * .1);
- }
- }
-
- /**
- * Test that adds some data to the histogram and compares results.
- */
- @Test
- public final void testDoubleHistogram() {
- double[] filled = { 0.0, 1.23, 4.56, 7.89, 0.0, 0, 0, 0, 0, 0 };
- double[] changed = { 0.0, 1.35, 8.01, 14.67, 9.01, 2.34, 0, 0, 0, 0 };
- double[] resized = { -1.23, 1.35, 22.68, 11.35, 0.0, 0.0, -4.56, 0, 0, 0 };
- double[] expanded = { 1., 0.0, 0.0, 0.0, 0.0, 0.0, 29.59, 0, 0, 0 };
- DoubleDynamicHistogram hist = new DoubleDynamicHistogram(5);
- hist.increment(0.0, 0.0);
- hist.increment(0.15, 1.23);
- hist.increment(0.25, 4.56);
- hist.increment(0.35, 7.89);
- hist.increment(0.5, 0.0);
- hist.materialize();
- assertArrayEquals("Filled histogram doesn't match", filled, hist.data, 1E-15);
- hist.increment(0.15, 0.12);
- hist.increment(0.25, 3.45);
- hist.increment(0.35, 6.78);
- hist.increment(0.45, 9.01);
- hist.increment(0.55, 2.34);
- assertArrayEquals("Changed histogram doesn't match", changed, hist.data, 1E-15);
- hist.increment(-.13, -1.23);
- hist.increment(1.13, -4.56);
- assertArrayEquals("Resized histogram doesn't match", resized, hist.data, 1E-15);
-
- // compare results via Iterator.
- int off = 0;
- for (DoubleHistogram.Iter iter = hist.iter(); iter.valid(); iter.advance()) {
- assertEquals("Array iterator bin position", -0.1 + 0.2 * off, iter.getCenter(), 0.00001);
- assertEquals("Array iterator bin contents", resized[off], iter.getValue(), 0.00001);
- off++;
- }
-
- // totally break out of the data range
- hist.increment(-10., 1.);
- assertArrayEquals("Expanded histogram doesn't match", expanded, hist.data, 1E-15);
-
- // Try some random operations, too
- Random r = new Random(0);
- for (int i = 0; i < 1000; i++) {
- hist.increment((r.nextDouble() - .5) * i * i, i * .1);
- }
- }
-}