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());
}
}
}
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;
}
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;
}
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);
}
}
Aggregations