Search in sources :

Example 6 with LeafEntry

use of de.lmu.ifi.dbs.elki.index.tree.LeafEntry in project elki by elki-project.

the class XSplitter method minimumOverlapSplit.

/**
 * Perform an minimum overlap split. The
 * {@link #chooseMinimumOverlapSplit(int, int, int, boolean) minimum overlap
 * split} calculates the partition for the split dimension determined by
 * {@link #chooseSplitAxis(Iterable, int, int) chooseSplitAxis}
 * <code>(common split
 * history, minFanout, maxEntries - minFanout + 1)</code> with the minimum
 * overlap. This range may have been tested before (by the
 * {@link #topologicalSplit()}), but for the minimum overlap test we need to
 * test that anew. Note that this method returns <code>null</code>, if the
 * minimum overlap split has a volume which is larger than the allowed
 * <code>maxOverlap</code> ratio or if the tree's minimum fanout is not larger
 * than the minimum directory size.
 *
 * @return distribution resulting from the minimum overlap split
 */
public SplitSorting minimumOverlapSplit() {
    if (node.getEntry(0) instanceof LeafEntry) {
        throw new IllegalArgumentException("The minimum overlap split will only be performed on directory nodes");
    }
    if (node.getNumEntries() < 2) {
        throw new IllegalArgumentException("Splitting less than two entries is pointless.");
    }
    int maxEntries = tree.getDirCapacity() - 1;
    int minFanout = tree.get_min_fanout();
    if (node.getNumEntries() < maxEntries) {
        throw new IllegalArgumentException("This entry list has not yet reached the maximum limit: " + node.getNumEntries() + "<=" + maxEntries);
    }
    assert !(node.getEntry(0) instanceof LeafEntry);
    if (minFanout >= tree.getDirMinimum()) {
        // minFanout not set for allowing underflowing nodes
        return null;
    }
    IntIterator dimensionListing;
    if (node.getEntry(0) instanceof XTreeDirectoryEntry) {
        // filter common split dimensions
        dimensionListing = getCommonSplitDimensions(node);
        if (!dimensionListing.hasNext()) {
            // no common dimensions
            return null;
        }
    } else {
        // test all dimensions
        dimensionListing = new IntegerRangeIterator(0, node.getEntry(0).getDimensionality());
    }
    int formerSplitAxis = this.splitAxis;
    // = maximum left-hand size
    maxEntries = maxEntries + 1 - minFanout;
    chooseSplitAxis(dimensionListing, minFanout, maxEntries);
    // find the best split point
    if (formerSplitAxis == this.splitAxis && tree.getDirMinimum() > minFanout) {
        // remember: this follows an unsuccessful topological split
        // avoid duplicate computations of {minEntries, ..., maxEntries}
        double minOverlap = pastOverlap;
        // test {minFanout, ..., minEntries - 1}
        SplitSorting ret1 = chooseMinimumOverlapSplit(this.splitAxis, minFanout, tree.getDirMinimum() - 1, false);
        if (ret1 != null && pastOverlap < minOverlap) {
            // this is a valid choice
            minOverlap = pastOverlap;
        }
        // test {maxEntries - minEntries + 2, ..., maxEntries - minFanout + 1}
        SplitSorting ret2 = chooseMinimumOverlapSplit(this.splitAxis, minFanout, tree.getDirMinimum() - 1, true);
        if (ret2 == null) {
            // accept first range regardless of whether or not there is one
            pastOverlap = minOverlap;
            return ret1;
        }
        if (pastOverlap < minOverlap) {
            // the second range is better
            return ret2;
        }
        // the first range is better
        pastOverlap = minOverlap;
        return ret1;
    } else {
        return chooseMinimumOverlapSplit(this.splitAxis, minFanout, maxEntries, false);
    }
}
Also used : XTreeDirectoryEntry(de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.xtree.XTreeDirectoryEntry) IntIterator(it.unimi.dsi.fastutil.ints.IntIterator) LeafEntry(de.lmu.ifi.dbs.elki.index.tree.LeafEntry)

Example 7 with LeafEntry

use of de.lmu.ifi.dbs.elki.index.tree.LeafEntry in project elki by elki-project.

the class RdKNNTree method adjustKNNDistance.

/**
 * 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);
}
Also used : DBID(de.lmu.ifi.dbs.elki.database.ids.DBID) LeafEntry(de.lmu.ifi.dbs.elki.index.tree.LeafEntry)

Example 8 with LeafEntry

use of de.lmu.ifi.dbs.elki.index.tree.LeafEntry in project elki by elki-project.

the class RStarTreeKNNQuery method batchNN.

/**
 * 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> knnLists) {
    if (node.isLeaf()) {
        for (int i = 0; i < node.getNumEntries(); i++) {
            SpatialEntry p = node.getEntry(i);
            for (Entry<DBID, KNNHeap> ent : knnLists.entrySet()) {
                final DBID q = ent.getKey();
                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.distance(relation.get(pid), relation.get(q));
                tree.statistics.countDistanceCalculation();
                if (dist_pq <= knn_q_maxDist) {
                    knns_q.insert(dist_pq, pid);
                }
            }
        }
    } else {
        ModifiableDBIDs ids = DBIDUtil.newArray(knnLists.size());
        for (DBID id : knnLists.keySet()) {
            ids.add(id);
        }
        List<DoubleDistanceEntry> entries = getSortedEntries(node, ids);
        for (DoubleDistanceEntry distEntry : entries) {
            double minDist = distEntry.distance;
            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;
                    AbstractRStarTreeNode<?, ?> child = tree.getNode(((DirectoryEntry) entry).getPageID());
                    batchNN(child, knnLists);
                    break;
                }
            }
        }
    }
}
Also used : SpatialPointLeafEntry(de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialPointLeafEntry) LeafEntry(de.lmu.ifi.dbs.elki.index.tree.LeafEntry) SpatialEntry(de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry)

Aggregations

LeafEntry (de.lmu.ifi.dbs.elki.index.tree.LeafEntry)8 SpatialEntry (de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry)4 DBID (de.lmu.ifi.dbs.elki.database.ids.DBID)2 SpatialPointLeafEntry (de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialPointLeafEntry)2 DeLiCluEntry (de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluEntry)2 HyperBoundingBox (de.lmu.ifi.dbs.elki.data.HyperBoundingBox)1 ModifiableHyperBoundingBox (de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox)1 DBIDs (de.lmu.ifi.dbs.elki.database.ids.DBIDs)1 KNNList (de.lmu.ifi.dbs.elki.database.ids.KNNList)1 SpatialPrimitiveDistanceFunction (de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction)1 BreadthFirstEnumeration (de.lmu.ifi.dbs.elki.index.tree.BreadthFirstEnumeration)1 SpatialDirectoryEntry (de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry)1 DeLiCluDirectoryEntry (de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluDirectoryEntry)1 DeLiCluNode (de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluNode)1 DeLiCluTreeIndex (de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluTreeIndex)1 XTreeDirectoryEntry (de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.xtree.XTreeDirectoryEntry)1 FiniteProgress (de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress)1 AbortException (de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException)1 MissingPrerequisitesException (de.lmu.ifi.dbs.elki.utilities.exceptions.MissingPrerequisitesException)1 IntIterator (it.unimi.dsi.fastutil.ints.IntIterator)1