use of de.lmu.ifi.dbs.elki.database.ids.KNNList in project elki by elki-project.
the class MkMaxTree method reverseKNNQuery.
/**
* Performs a reverse k-nearest neighbor query for the given object ID. In the
* first step the candidates are chosen by performing a reverse k-nearest
* neighbor query with k = {@link #getKmax()}. Then these candidates are refined
* in a second step.
*/
@Override
public DoubleDBIDList reverseKNNQuery(DBIDRef id, int k) {
if (k > this.getKmax()) {
throw new IllegalArgumentException("Parameter k has to be equal or less than " + "parameter k of the MkMax-Tree!");
}
// get the candidates
ModifiableDoubleDBIDList candidates = DBIDUtil.newDistanceDBIDList();
doReverseKNNQuery(id, getRoot(), null, candidates);
if (k == this.getKmax()) {
candidates.sort();
// rkNNStatistics.addResults(candidates.size());
return candidates;
}
// refinement of candidates
ModifiableDBIDs candidateIDs = DBIDUtil.newArray(candidates.size());
for (DBIDIter candidate = candidates.iter(); candidate.valid(); candidate.advance()) {
candidateIDs.add(candidate);
}
Map<DBID, KNNList> knnLists = batchNN(getRoot(), candidateIDs, k);
ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
for (DBIDIter iter = candidateIDs.iter(); iter.valid(); iter.advance()) {
DBID cid = DBIDUtil.deref(iter);
KNNList cands = knnLists.get(cid);
for (DoubleDBIDListIter iter2 = cands.iter(); iter2.valid(); iter2.advance()) {
if (DBIDUtil.equal(id, iter2)) {
result.add(iter2.doubleValue(), cid);
break;
}
}
}
// FIXME: re-add statistics.
// rkNNStatistics.addResults(result.size());
// rkNNStatistics.addCandidates(candidates.size());
result.sort();
return result;
}
use of de.lmu.ifi.dbs.elki.database.ids.KNNList in project elki by elki-project.
the class MkTabTreeIndex method knnDistances.
/**
* Returns the knn distance of the object with the specified id.
*
* @param object the query object
* @return the knn distance of the object with the specified id
*/
private double[] knnDistances(O object) {
KNNList knns = knnq.getKNNForObject(object, getKmax() - 1);
double[] distances = new double[getKmax()];
int i = 0;
for (DoubleDBIDListIter iter = knns.iter(); iter.valid() && i < getKmax(); iter.advance(), i++) {
distances[i] = iter.doubleValue();
}
return distances;
}
use of de.lmu.ifi.dbs.elki.database.ids.KNNList in project elki by elki-project.
the class MaterializeKNNPreprocessor method preprocess.
/**
* The actual preprocessing step.
*/
@Override
protected void preprocess() {
// Could be subclass
final Logging log = getLogger();
createStorage();
ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs());
if (log.isStatistics()) {
log.statistics(new LongStatistic(this.getClass().getName() + ".k", k));
}
Duration duration = log.isStatistics() ? log.newDuration(this.getClass().getName() + ".precomputation-time").begin() : null;
FiniteProgress progress = getLogger().isVerbose() ? new FiniteProgress("Materializing k nearest neighbors (k=" + k + ")", ids.size(), getLogger()) : null;
// Try bulk
List<? extends KNNList> kNNList = null;
if (usebulk) {
kNNList = knnQuery.getKNNForBulkDBIDs(ids, k);
if (kNNList != null) {
int i = 0;
for (DBIDIter id = ids.iter(); id.valid(); id.advance(), i++) {
storage.put(id, kNNList.get(i));
log.incrementProcessed(progress);
}
}
} else {
final boolean ismetric = getDistanceQuery().getDistanceFunction().isMetric();
for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
if (ismetric && storage.get(iter) != null) {
log.incrementProcessed(progress);
// Previously computed (duplicate point?)
continue;
}
KNNList knn = knnQuery.getKNNForDBID(iter, k);
storage.put(iter, knn);
if (ismetric) {
for (DoubleDBIDListIter it = knn.iter(); it.valid() && it.doubleValue() == 0.; it.advance()) {
// Reuse
storage.put(it, knn);
}
}
log.incrementProcessed(progress);
}
}
log.ensureCompleted(progress);
if (duration != null) {
log.statistics(duration.end());
}
}
use of de.lmu.ifi.dbs.elki.database.ids.KNNList in project elki by elki-project.
the class MaterializeKNNPreprocessor method updateKNNsAfterInsertion.
/**
* Updates the kNNs of the RkNNs of the specified ids.
*
* @param ids the ids of newly inserted objects causing a change of
* materialized kNNs
* @return the RkNNs of the specified ids, i.e. the kNNs which have been
* updated
*/
private ArrayDBIDs updateKNNsAfterInsertion(DBIDs ids) {
ArrayModifiableDBIDs rkNN_ids = DBIDUtil.newArray();
DBIDs oldids = DBIDUtil.difference(relation.getDBIDs(), ids);
for (DBIDIter iter = oldids.iter(); iter.valid(); iter.advance()) {
KNNList kNNs = storage.get(iter);
double knnDist = kNNs.getKNNDistance();
// look for new kNNs
KNNHeap heap = null;
for (DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) {
double dist = distanceQuery.distance(iter, iter2);
if (dist <= knnDist) {
if (heap == null) {
heap = DBIDUtil.newHeap(kNNs);
}
heap.insert(dist, iter2);
}
}
if (heap != null) {
kNNs = heap.toKNNList();
storage.put(iter, kNNs);
rkNN_ids.add(iter);
}
}
return rkNN_ids;
}
use of de.lmu.ifi.dbs.elki.database.ids.KNNList in project elki by elki-project.
the class PreprocessorKNNQuery method getKNNForBulkDBIDs.
@Override
public List<KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
if (!warned && k > preprocessor.getK()) {
getLogger().warning("Requested more neighbors than preprocessed: requested " + k + " preprocessed " + preprocessor.getK(), new Throwable());
warned = true;
}
if (k < preprocessor.getK()) {
List<KNNList> result = new ArrayList<>(ids.size());
for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
result.add(getSublist(preprocessor.get(iter), k));
}
return result;
}
List<KNNList> result = new ArrayList<>(ids.size());
for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
result.add(preprocessor.get(iter));
}
return result;
}
Aggregations