use of de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry in project elki by elki-project.
the class RStarTreeKNNQuery method expandNode.
private double expandNode(O object, KNNHeap knnList, DoubleIntegerMinHeap 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.minDist(entry, object);
tree.statistics.countDistanceCalculation();
if (distance <= maxDist) {
maxDist = knnList.insert(distance, entry.getDBID());
}
}
} else // directory node
{
for (int i = 0; i < node.getNumEntries(); i++) {
SpatialDirectoryEntry entry = (SpatialDirectoryEntry) node.getEntry(i);
double distance = distanceFunction.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(distance, entry.getPageID());
}
}
}
}
return maxDist;
}
use of de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry in project elki by elki-project.
the class DeLiClu method run.
public ClusterOrder run(Database database, Relation<NV> relation) {
Collection<DeLiCluTreeIndex<NV>> indexes = ResultUtil.filterResults(database.getHierarchy(), relation, DeLiCluTreeIndex.class);
if (indexes.size() != 1) {
throw new MissingPrerequisitesException("DeLiClu found " + indexes.size() + " DeLiCluTree indexes. DeLiClu needs a special index to operate, therefore you need to add this index to your database.");
}
DeLiCluTreeIndex<NV> index = indexes.iterator().next();
if (!(getDistanceFunction() instanceof SpatialPrimitiveDistanceFunction<?>)) {
throw new IllegalArgumentException("Distance Function must be an instance of " + SpatialPrimitiveDistanceFunction.class.getName());
}
@SuppressWarnings("unchecked") SpatialPrimitiveDistanceFunction<NV> distFunction = (SpatialPrimitiveDistanceFunction<NV>) getDistanceFunction();
// first do the knn-Join
if (LOG.isVerbose()) {
LOG.verbose("knnJoin...");
}
Relation<KNNList> knns = knnJoin.run(relation);
DBIDs ids = relation.getDBIDs();
final int size = ids.size();
FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("DeLiClu", size, LOG) : null;
ClusterOrder clusterOrder = new ClusterOrder(ids, "DeLiClu Clustering", "deliclu-clustering");
heap = new UpdatableHeap<>();
// add start object to cluster order and (root, root) to priority queue
DBID startID = DBIDUtil.deref(ids.iter());
clusterOrder.add(startID, Double.POSITIVE_INFINITY, null);
int numHandled = 1;
index.setHandled(startID, relation.get(startID));
SpatialDirectoryEntry rootEntry = (SpatialDirectoryEntry) index.getRootEntry();
SpatialObjectPair spatialObjectPair = new SpatialObjectPair(0., rootEntry, rootEntry, true);
heap.add(spatialObjectPair);
while (numHandled < size) {
if (heap.isEmpty()) {
throw new AbortException("DeLiClu heap was empty when it shouldn't have been.");
}
SpatialObjectPair dataPair = heap.poll();
// pair of nodes
if (dataPair.isExpandable) {
expandNodes(index, distFunction, dataPair, knns);
} else // pair of objects
{
// set handled
LeafEntry e1 = (LeafEntry) dataPair.entry1;
LeafEntry e2 = (LeafEntry) dataPair.entry2;
final DBID e1id = e1.getDBID();
IndexTreePath<DeLiCluEntry> path = index.setHandled(e1id, relation.get(e1id));
if (path == null) {
throw new RuntimeException("snh: parent(" + e1id + ") = null!!!");
}
// add to cluster order
clusterOrder.add(e1id, dataPair.distance, e2.getDBID());
numHandled++;
// reinsert expanded leafs
reinsertExpanded(distFunction, index, path, knns);
if (progress != null) {
progress.setProcessed(numHandled, LOG);
}
}
}
LOG.ensureCompleted(progress);
return clusterOrder;
}
use of de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry in project elki by elki-project.
the class AbstractXTreeNode method readSuperNode.
/**
* Reads the id of this supernode, the numEntries and the entries array from
* the specified stream.
*
* @param in the stream to read data from in order to restore the object
* @param tree the tree this supernode is to be assigned to
* @throws java.io.IOException if I/O errors occur
* @throws ClassNotFoundException If the class for an object being restored
* cannot be found.
* @throws IllegalStateException if the parameters of the file's supernode do
* not match this
*/
public <T extends AbstractXTree<N>> void readSuperNode(ObjectInput in, T tree) throws IOException, ClassNotFoundException {
readExternal(in);
if (capacity_to_be_filled <= 0 || !isSuperNode()) {
throw new IllegalStateException("This node does not appear to be a supernode");
}
if (isLeaf) {
throw new IllegalStateException("A supernode is cannot be a leaf");
}
// TODO: verify
entries = new Entry[capacity_to_be_filled];
// old way:
// entries = (E[]) new XDirectoryEntry[capacity_to_be_filled];
capacity_to_be_filled = 0;
for (int i = 0; i < numEntries; i++) {
SpatialEntry s = new SpatialDirectoryEntry();
s.readExternal(in);
entries[i] = s;
}
N n = tree.getSupernodes().put((long) getPageID(), (N) this);
if (n != null) {
Logging.getLogger(this.getClass()).fine("Warning: this supernode should only be read once. Now a node of size " + entries.length + " has replaced a node of size " + n.entries.length + " for id " + getPageID());
}
}
use of de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry in project elki by elki-project.
the class IndexPurity method processNewResult.
@Override
public void processNewResult(ResultHierarchy hier, Result newResult) {
Database database = ResultUtil.findDatabase(hier);
final ArrayList<SpatialIndexTree<?, ?>> indexes = ResultUtil.filterResults(hier, newResult, SpatialIndexTree.class);
if (indexes == null || indexes.isEmpty()) {
return;
}
Relation<String> lblrel = DatabaseUtil.guessLabelRepresentation(database);
for (SpatialIndexTree<?, ?> index : indexes) {
List<? extends SpatialEntry> leaves = index.getLeaves();
MeanVariance mv = new MeanVariance();
for (SpatialEntry e : leaves) {
SpatialDirectoryEntry leaf = (SpatialDirectoryEntry) e;
Node<?> n = index.getNode(leaf.getPageID());
final int total = n.getNumEntries();
HashMap<String, Integer> map = new HashMap<>(total);
for (int i = 0; i < total; i++) {
DBID id = ((SpatialPointLeafEntry) n.getEntry(i)).getDBID();
String label = lblrel.get(id);
Integer val = map.get(label);
if (val == null) {
val = 1;
} else {
val += 1;
}
map.put(label, val);
}
double gini = 0.0;
for (Entry<String, Integer> ent : map.entrySet()) {
double rel = ent.getValue() / (double) total;
gini += rel * rel;
}
mv.put(gini);
}
Collection<double[]> col = new ArrayList<>();
col.add(new double[] { mv.getMean(), mv.getSampleStddev() });
database.getHierarchy().add((Result) index, new CollectionResult<>("Gini coefficient of index", "index-gini", col));
}
}
use of de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry in project elki by elki-project.
the class EuclideanRStarTreeKNNQuery method expandNode.
private double expandNode(O object, KNNHeap knnList, DoubleIntegerMinHeap 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());
}
}
} else // directory node
{
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(distance, entry.getPageID());
}
}
}
}
return maxDist;
}
Aggregations