Search in sources :

Example 11 with HyperBoundingBox

use of de.lmu.ifi.dbs.elki.data.HyperBoundingBox in project elki by elki-project.

the class AbstractXTree method adjustTree.

/**
 * Adjusts the tree after insertion of some nodes.
 *
 * @param subtree the subtree to be adjusted
 */
@Override
protected void adjustTree(IndexTreePath<SpatialEntry> subtree) {
    if (getLogger().isDebugging()) {
        getLogger().debugFine("Adjust tree " + subtree);
    }
    // get the root of the subtree
    N node = getNode(subtree.getEntry());
    // overflow in node
    if (hasOverflow(node)) {
        if (node.isSuperNode()) {
            int new_capacity = node.growSuperNode();
            getLogger().finest("Extending supernode to new capacity " + new_capacity);
            if (isRoot(node)) {
                // is root
                node.adjustEntry(getRootEntry());
            } else {
                N parent = getNode(subtree.getParentPath().getEntry());
                SpatialEntry e = parent.getEntry(subtree.getIndex());
                HyperBoundingBox mbr = new HyperBoundingBox(e);
                node.adjustEntry(e);
                if (!SpatialUtil.equals(mbr, e)) {
                    // MBR has changed
                    // write changes in parent to file
                    writeNode(parent);
                    adjustTree(subtree.getParentPath());
                }
            }
        } else {
            int[] splitAxis = { -1 };
            // treatment of overflow: reinsertion or split
            N split = overflowTreatment(node, subtree, splitAxis);
            // node was split
            if (split != null) {
                // split nodes
                if (isRoot(node)) {
                    IndexTreePath<SpatialEntry> newRootPath = createNewRoot(node, split, splitAxis[0]);
                    height++;
                    adjustTree(newRootPath);
                } else // node is not root
                {
                    // get the parent and add the new split node
                    N parent = getNode(subtree.getParentPath().getEntry());
                    if (getLogger().isDebugging()) {
                        getLogger().debugFine("parent " + parent);
                    }
                    SpatialEntry newEntry = createNewDirectoryEntry(split);
                    parent.addDirectoryEntry(newEntry);
                    // The below variant does not work in the persistent version
                    // E oldEntry = subtree.getEntry();
                    // [reason: if oldEntry is modified, this must be permanent]
                    SpatialEntry oldEntry = parent.getEntry(subtree.getIndex());
                    // adjust split history
                    SplitHistory sh = ((SplitHistorySpatialEntry) oldEntry).getSplitHistory();
                    if (sh == null) {
                        // not yet initialized (dimension not known of this tree)
                        sh = new SplitHistory(oldEntry.getDimensionality());
                        sh.setDim(splitAxis[0]);
                        ((SplitHistorySpatialEntry) oldEntry).setSplitHistory(sh);
                    } else {
                        ((SplitHistorySpatialEntry) oldEntry).addSplitDimension(splitAxis[0]);
                    }
                    try {
                        ((SplitHistorySpatialEntry) newEntry).setSplitHistory((SplitHistory) sh.clone());
                    } catch (CloneNotSupportedException e) {
                        throw new RuntimeException("Clone of a split history should not throw an Exception", e);
                    }
                    // adjust the entry representing the (old) node, that has
                    // been split
                    node.adjustEntry(oldEntry);
                    // write changes in parent to file
                    writeNode(parent);
                    adjustTree(subtree.getParentPath());
                }
            }
        }
    } else // no overflow, only adjust parameters of the entry representing the
    // node
    {
        if (!isRoot(node)) {
            N parent = getNode(subtree.getParentPath().getEntry());
            SpatialEntry e = parent.getEntry(subtree.getIndex());
            HyperBoundingBox mbr = new HyperBoundingBox(e);
            node.adjustEntry(e);
            if (// we already know that mbr is extended
            node.isLeaf() || !SpatialUtil.equals(mbr, e)) {
                // MBR has changed
                // write changes in parent to file
                writeNode(parent);
                adjustTree(subtree.getParentPath());
            }
        } else // root level is reached
        {
            node.adjustEntry(getRootEntry());
        }
    }
}
Also used : ModifiableHyperBoundingBox(de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox) HyperBoundingBox(de.lmu.ifi.dbs.elki.data.HyperBoundingBox) SpatialEntry(de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry) SplitHistory(de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.xtree.util.SplitHistory)

Example 12 with HyperBoundingBox

use of de.lmu.ifi.dbs.elki.data.HyperBoundingBox in project elki by elki-project.

the class ApproximativeLeastOverlapInsertionStrategy method choose.

@Override
public <A> int choose(A options, ArrayAdapter<? extends SpatialComparable, A> getter, SpatialComparable obj, int height, int depth) {
    final int size = getter.size(options);
    assert (size > 0) : "Choose from empty set?";
    if (size <= numCandidates) {
        // Skip building the heap.
        return super.choose(options, getter, obj, height, depth);
    }
    // Heap of candidates
    TopBoundedHeap<DoubleIntPair> candidates = new TopBoundedHeap<>(numCandidates, Collections.reverseOrder());
    for (int i = 0; i < size; i++) {
        // Existing object and extended rectangle:
        SpatialComparable entry = getter.get(options, i);
        HyperBoundingBox mbr = SpatialUtil.union(entry, obj);
        // Area increase
        final double inc_area = SpatialUtil.volume(mbr) - SpatialUtil.volume(entry);
        candidates.add(new DoubleIntPair(inc_area, i));
    }
    // R*-Tree: overlap increase for leaves.
    int best = -1;
    double least_overlap = Double.POSITIVE_INFINITY;
    double least_areainc = Double.POSITIVE_INFINITY;
    double least_area = Double.POSITIVE_INFINITY;
    // least overlap increase, on reduced candidate set:
    while (!candidates.isEmpty()) {
        DoubleIntPair pair = candidates.poll();
        final double inc_area = pair.first;
        // Existing object and extended rectangle:
        SpatialComparable entry = getter.get(options, pair.second);
        HyperBoundingBox mbr = SpatialUtil.union(entry, obj);
        // Compute relative overlap increase.
        double overlap_wout = 0.0;
        double overlap_with = 0.0;
        for (int k = 0; k < size; k++) {
            if (pair.second != k) {
                SpatialComparable other = getter.get(options, k);
                overlap_wout += SpatialUtil.relativeOverlap(entry, other);
                overlap_with += SpatialUtil.relativeOverlap(mbr, other);
            }
        }
        double inc_overlap = overlap_with - overlap_wout;
        if (inc_overlap < least_overlap) {
            final double area = SpatialUtil.volume(entry);
            // Volume increase and overlap increase:
            least_overlap = inc_overlap;
            least_areainc = inc_area;
            least_area = area;
            best = pair.second;
        } else if (inc_overlap == least_overlap) {
            final double area = SpatialUtil.volume(entry);
            if (inc_area < least_areainc || (inc_area == least_areainc && area < least_area)) {
                least_overlap = inc_overlap;
                least_areainc = inc_area;
                least_area = area;
                best = pair.second;
            }
        }
    }
    assert (best > -1) : "No split found? Volume outside of double precision?";
    return best;
}
Also used : TopBoundedHeap(de.lmu.ifi.dbs.elki.utilities.datastructures.heap.TopBoundedHeap) SpatialComparable(de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable) DoubleIntPair(de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair) HyperBoundingBox(de.lmu.ifi.dbs.elki.data.HyperBoundingBox)

Example 13 with HyperBoundingBox

use of de.lmu.ifi.dbs.elki.data.HyperBoundingBox in project elki by elki-project.

the class LeastOverlapInsertionStrategy method choose.

@Override
public <A> int choose(A options, ArrayAdapter<? extends SpatialComparable, A> getter, SpatialComparable obj, int height, int depth) {
    final int size = getter.size(options);
    assert (size > 0) : "Choose from empty set?";
    // R*-Tree: overlap increase for leaves.
    int best = -1;
    double least_overlap = Double.POSITIVE_INFINITY;
    double least_areainc = Double.POSITIVE_INFINITY;
    double least_area = Double.POSITIVE_INFINITY;
    // least overlap increase, on reduced candidate set:
    for (int i = 0; i < size; i++) {
        // Existing object and extended rectangle:
        SpatialComparable entry = getter.get(options, i);
        HyperBoundingBox mbr = SpatialUtil.union(entry, obj);
        // Compute relative overlap increase.
        double overlap_wout = 0.0;
        double overlap_with = 0.0;
        for (int k = 0; k < size; k++) {
            if (i != k) {
                SpatialComparable other = getter.get(options, k);
                overlap_wout += SpatialUtil.relativeOverlap(entry, other);
                overlap_with += SpatialUtil.relativeOverlap(mbr, other);
            }
        }
        double inc_overlap = overlap_with - overlap_wout;
        if (inc_overlap < least_overlap) {
            final double area = SpatialUtil.volume(entry);
            final double inc_area = SpatialUtil.volume(mbr) - area;
            // Volume increase and overlap increase:
            least_overlap = inc_overlap;
            least_areainc = inc_area;
            least_area = area;
            best = i;
        } else if (inc_overlap == least_overlap) {
            final double area = SpatialUtil.volume(entry);
            final double inc_area = SpatialUtil.volume(mbr) - area;
            if (inc_area < least_areainc || (inc_area == least_areainc && area < least_area)) {
                least_overlap = inc_overlap;
                least_areainc = inc_area;
                least_area = area;
                best = i;
            }
        }
    }
    assert (best > -1) : "No split found? Volume outside of double precision?";
    return best;
}
Also used : SpatialComparable(de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable) HyperBoundingBox(de.lmu.ifi.dbs.elki.data.HyperBoundingBox)

Example 14 with HyperBoundingBox

use of de.lmu.ifi.dbs.elki.data.HyperBoundingBox in project elki by elki-project.

the class AbstractRStarTreeNode method integrityCheckParameters.

/**
 * 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
 */
protected void integrityCheckParameters(N parent, int index) {
    // test if mbr is correctly set
    E entry = parent.getEntry(index);
    HyperBoundingBox mbr = computeMBR();
    if (/* entry.getMBR() == null && */
    mbr == null) {
        return;
    }
    if (!SpatialUtil.equals(entry, mbr)) {
        String soll = mbr.toString();
        String ist = new HyperBoundingBox(entry).toString();
        throw new RuntimeException("Wrong MBR in node " + parent.getPageID() + " at index " + index + " (child " + entry + ")" + "\nsoll: " + soll + ",\n ist: " + ist);
    }
}
Also used : ModifiableHyperBoundingBox(de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox) HyperBoundingBox(de.lmu.ifi.dbs.elki.data.HyperBoundingBox)

Aggregations

HyperBoundingBox (de.lmu.ifi.dbs.elki.data.HyperBoundingBox)14 ModifiableHyperBoundingBox (de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox)6 SpatialEntry (de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry)4 SpatialComparable (de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable)3 ModifiableDBIDs (de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs)2 SplitHistory (de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.xtree.util.SplitHistory)2 TopBoundedHeap (de.lmu.ifi.dbs.elki.utilities.datastructures.heap.TopBoundedHeap)2 DoubleIntPair (de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair)2 NumberVector (de.lmu.ifi.dbs.elki.data.NumberVector)1 SimpleGaussianContinuousUncertainObject (de.lmu.ifi.dbs.elki.data.uncertain.SimpleGaussianContinuousUncertainObject)1 UniformContinuousUncertainObject (de.lmu.ifi.dbs.elki.data.uncertain.UniformContinuousUncertainObject)1 DBID (de.lmu.ifi.dbs.elki.database.ids.DBID)1 DBIDIter (de.lmu.ifi.dbs.elki.database.ids.DBIDIter)1 IndexTreePath (de.lmu.ifi.dbs.elki.index.tree.IndexTreePath)1 LeafEntry (de.lmu.ifi.dbs.elki.index.tree.LeafEntry)1 Heap (de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap)1 ArrayList (java.util.ArrayList)1