use of de.lmu.ifi.dbs.elki.database.ids.KNNHeap in project elki by elki-project.
the class LinearScanDistanceKNNQuery method getKNNForBulkDBIDs.
@Override
public List<KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
final int size = ids.size();
final List<KNNHeap> heaps = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
heaps.add(DBIDUtil.newHeap(k));
}
linearScanBatchKNN(ids, heaps);
// Serialize heaps
List<KNNList> result = new ArrayList<>(size);
for (KNNHeap heap : heaps) {
result.add(heap.toKNNList());
}
return result;
}
use of de.lmu.ifi.dbs.elki.database.ids.KNNHeap in project elki by elki-project.
the class LinearScanEuclideanDistanceKNNQuery method getKNNForBulkDBIDs.
@Override
public List<KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
final Relation<? extends O> relation = getRelation();
final int size = ids.size();
final List<KNNHeap> heaps = new ArrayList<>(size);
List<O> objs = new ArrayList<>(size);
for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
heaps.add(DBIDUtil.newHeap(k));
objs.add(relation.get(iter));
}
linearScanBatchKNN(objs, heaps);
List<KNNList> result = new ArrayList<>(heaps.size());
for (KNNHeap heap : heaps) {
result.add(heap.toKNNListSqrt());
}
return result;
}
use of de.lmu.ifi.dbs.elki.database.ids.KNNHeap in project elki by elki-project.
the class MetricalIndexApproximationMaterializeKNNPreprocessor method preprocess.
@Override
protected void preprocess() {
final Logging log = getLogger();
DistanceQuery<O> distanceQuery = relation.getDistanceQuery(distanceFunction);
MetricalIndexTree<O, N, E> index = getMetricalIndex(relation);
createStorage();
MeanVariance pagesize = new MeanVariance();
MeanVariance ksize = new MeanVariance();
if (log.isVerbose()) {
log.verbose("Approximating nearest neighbor lists to database objects");
}
List<E> leaves = index.getLeaves();
FiniteProgress progress = getLogger().isVerbose() ? new FiniteProgress("Processing leaf nodes", leaves.size(), getLogger()) : null;
for (E leaf : leaves) {
N node = index.getNode(leaf);
int size = node.getNumEntries();
pagesize.put(size);
if (log.isDebuggingFinest()) {
log.debugFinest("NumEntires = " + size);
}
// Collect the ids in this node.
ArrayModifiableDBIDs ids = DBIDUtil.newArray(size);
for (int i = 0; i < size; i++) {
ids.add(((LeafEntry) node.getEntry(i)).getDBID());
}
Object2DoubleOpenHashMap<DBIDPair> cache = new Object2DoubleOpenHashMap<>((size * size * 3) >> 2);
cache.defaultReturnValue(Double.NaN);
for (DBIDIter id = ids.iter(); id.valid(); id.advance()) {
KNNHeap kNN = DBIDUtil.newHeap(k);
for (DBIDIter id2 = ids.iter(); id2.valid(); id2.advance()) {
DBIDPair key = DBIDUtil.newPair(id, id2);
double d = cache.removeDouble(key);
if (d == d) {
// Not NaN
// consume the previous result.
kNN.insert(d, id2);
} else {
// compute new and store the previous result.
d = distanceQuery.distance(id, id2);
kNN.insert(d, id2);
// put it into the cache, but with the keys reversed
key = DBIDUtil.newPair(id2, id);
cache.put(key, d);
}
}
ksize.put(kNN.size());
storage.put(id, kNN.toKNNList());
}
if (log.isDebugging() && cache.size() > 0) {
log.warning("Cache should be empty after each run, but still has " + cache.size() + " elements.");
}
log.incrementProcessed(progress);
}
log.ensureCompleted(progress);
if (log.isVerbose()) {
log.verbose("Average page size = " + pagesize.getMean() + " +- " + pagesize.getSampleStddev());
log.verbose("On average, " + ksize.getMean() + " +- " + ksize.getSampleStddev() + " neighbors returned.");
}
}
use of de.lmu.ifi.dbs.elki.database.ids.KNNHeap in project elki by elki-project.
the class LinearScanDistanceKNNQuery method getKNNForObject.
@Override
public KNNList getKNNForObject(O obj, int k) {
final DistanceQuery<O> dq = distanceQuery;
KNNHeap heap = DBIDUtil.newHeap(k);
double max = Double.POSITIVE_INFINITY;
for (DBIDIter iter = getRelation().getDBIDs().iter(); iter.valid(); iter.advance()) {
final double dist = dq.distance(obj, iter);
if (dist <= max) {
max = heap.insert(dist, iter);
}
}
return heap.toKNNList();
}
use of de.lmu.ifi.dbs.elki.database.ids.KNNHeap in project elki by elki-project.
the class LinearScanDistanceKNNQuery method linearScanBatchKNN.
/**
* Linear batch knn for arbitrary distance functions.
*
* @param ids DBIDs to process
* @param heaps Heaps to store the results in
*/
private void linearScanBatchKNN(ArrayDBIDs ids, List<KNNHeap> heaps) {
final DistanceQuery<O> dq = distanceQuery;
// The distance is computed on database IDs
for (DBIDIter iter = getRelation().getDBIDs().iter(); iter.valid(); iter.advance()) {
int index = 0;
for (DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance(), index++) {
KNNHeap heap = heaps.get(index);
heap.insert(dq.distance(iter2, iter), iter);
}
}
}
Aggregations