use of de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialPointLeafEntry 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.SpatialPointLeafEntry in project elki by elki-project.
the class KNNJoin method processDataPages.
/**
* Processes the two data pages pr and ps and determines the k-nearest
* neighbors of pr in ps.
*
* @param df the distance function to use
* @param pr the first data page
* @param ps the second data page
* @param pr_heaps the knn lists for each data object
* @param ps_heaps the knn lists for each data object in ps
*/
private void processDataPages(SpatialPrimitiveDistanceFunction<? super V> df, List<KNNHeap> pr_heaps, List<KNNHeap> ps_heaps, N pr, N ps) {
// Compare pairwise
for (int j = 0; j < ps.getNumEntries(); j++) {
final SpatialPointLeafEntry s_e = (SpatialPointLeafEntry) ps.getEntry(j);
final KNNHeap hj = ps_heaps != null ? ps_heaps.get(j) : null;
final DBID s_id = s_e.getDBID();
for (int i = 0; i < pr.getNumEntries(); i++) {
final SpatialPointLeafEntry r_e = (SpatialPointLeafEntry) pr.getEntry(i);
double distance = df.minDist(s_e, r_e);
pr_heaps.get(i).insert(distance, s_id);
if (hj != null) {
hj.insert(distance, r_e.getDBID());
}
}
}
}
use of de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialPointLeafEntry in project elki by elki-project.
the class AbstractXTree method initializeCapacities.
@Override
protected void initializeCapacities(SpatialEntry exampleLeaf) {
/* Simulate the creation of a leaf page to get the page capacity */
try {
int cap = 0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
SpatialPointLeafEntry sl = new SpatialPointLeafEntry(DBIDUtil.importInteger(0), new double[exampleLeaf.getDimensionality()]);
while (baos.size() <= getPageSize()) {
sl.writeExternal(oos);
oos.flush();
cap++;
}
// the last one caused the page to overflow.
leafCapacity = cap - 1;
} catch (IOException e) {
throw new AbortException("Error determining page sizes.", e);
}
/* Simulate the creation of a directory page to get the capacity */
try {
int cap = 0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
ModifiableHyperBoundingBox hb = new ModifiableHyperBoundingBox(new double[exampleLeaf.getDimensionality()], new double[exampleLeaf.getDimensionality()]);
XTreeDirectoryEntry xl = new XTreeDirectoryEntry(0, hb);
while (baos.size() <= getPageSize()) {
xl.writeExternal(oos);
oos.flush();
cap++;
}
dirCapacity = cap - 1;
} catch (IOException e) {
throw new AbortException("Error determining page sizes.", e);
}
if (dirCapacity <= 1) {
throw new IllegalArgumentException("Node size of " + getPageSize() + " Bytes is chosen too small!");
}
if (dirCapacity < 10) {
getLogger().warning("Page size is choosen very small! Maximum number of entries " + "in a directory node = " + (dirCapacity - 1));
}
// minimum entries per directory node
dirMinimum = (int) Math.round((dirCapacity - 1) * settings.relativeMinEntries);
if (dirMinimum < 2) {
dirMinimum = 2;
}
// minimum entries per directory node
settings.min_fanout = (int) Math.round((dirCapacity - 1) * settings.relativeMinFanout);
if (settings.min_fanout < 2) {
settings.min_fanout = 2;
}
if (leafCapacity <= 1) {
throw new IllegalArgumentException("Node size of " + getPageSize() + " Bytes is chosen too small!");
}
if (leafCapacity < 10) {
getLogger().warning("Page size is choosen very small! Maximum number of entries " + "in a leaf node = " + (leafCapacity - 1));
}
// minimum entries per leaf node
leafMinimum = (int) Math.round((leafCapacity - 1) * settings.relativeMinEntries);
if (leafMinimum < 2) {
leafMinimum = 2;
}
dimensionality = exampleLeaf.getDimensionality();
if (getLogger().isVerbose()) {
getLogger().verbose("Directory Capacity: " + (dirCapacity - 1) + "\nDirectory minimum: " + dirMinimum + "\nLeaf Capacity: " + (leafCapacity - 1) + "\nLeaf Minimum: " + leafMinimum + "\nminimum fanout: " + settings.min_fanout);
}
}
use of de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialPointLeafEntry in project elki by elki-project.
the class AbstractXTreeNode method readExternal.
/**
* Reads the id of this node, the numEntries and the entries array from the
* specified stream. If the {@link #supernode} field is set, <code>this</code>
* cannot be contained in <code>in</code>. Such a node has to be manually
* filled using {@link #readSuperNode(ObjectInput, AbstractXTree)}.
*
* @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 {
setPageID(in.readInt());
isLeaf = in.readBoolean();
supernode = in.readBoolean();
numEntries = in.readInt();
final int capacity = in.readInt();
if (supernode) {
// this node is a supernode and is yet to be filled
capacity_to_be_filled = capacity;
return;
}
// entries = (E[]) java.lang.reflect.Array.newInstance(eclass, capacity);
if (isLeaf()) {
entries = (Entry[]) new SpatialPointLeafEntry[capacity];
} else {
entries = (Entry[]) new XTreeDirectoryEntry[capacity];
}
for (int i = 0; i < numEntries; i++) {
SpatialEntry s = isLeaf() ? new SpatialPointLeafEntry() : new XTreeDirectoryEntry();
s.readExternal(in);
entries[i] = s;
}
}
use of de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialPointLeafEntry 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));
}
}
Aggregations