summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/index
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/index')
-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.java52
-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.java26
-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.java46
-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/index/preprocessed/subspaceproj/package-info.java)6
-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
250 files changed, 5477 insertions, 3880 deletions
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/index/DistanceIndex.java b/src/de/lmu/ifi/dbs/elki/index/DistanceIndex.java
new file mode 100644
index 00000000..b9094c24
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/DistanceIndex.java
@@ -0,0 +1,52 @@
+package de.lmu.ifi.dbs.elki.index;
+
+/*
+ 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.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+
+/**
+ * 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 DistanceIndex<O> extends Index {
+ /**
+ * 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 distanceFunction Distance function to use.
+ * @param hints Hints for the optimizer
+ * @return KNN Query object or {@code null}
+ */
+ 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/tree/spatial/rstarvariants/flat/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/package-info.java
new file mode 100644
index 00000000..fd092666
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/flat/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * <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) 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.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/index/tree/spatial/rstarvariants/rdknn/RdkNNSettings.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdkNNSettings.java
new file mode 100644
index 00000000..3f9997e2
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rdknn/RdkNNSettings.java
@@ -0,0 +1,46 @@
+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.distance.distancefunction.SpatialPrimitiveDistanceFunction;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRTreeSettings;
+
+/**
+ * Settings for the RdKNN Tree.
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Object type
+ */
+public class RdkNNSettings<O extends NumberVector> extends AbstractRTreeSettings {
+ /**
+ * Parameter k.
+ */
+ int k_max;
+
+ /**
+ * The distance function.
+ */
+ SpatialPrimitiveDistanceFunction<O> distanceFunction;
+}
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/rdknn/package-info.java
index 4c529c66..972376d6 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/rdknn/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.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
@@ -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.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