use of de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList in project elki by elki-project.
the class MaterializeKNNAndRKNNPreprocessor method updateKNNsAndRkNNs.
/**
* Updates the kNNs and RkNNs after insertion of the specified ids.
*
* @param ids the ids of newly inserted objects causing a change of
* materialized kNNs and RkNNs
* @return the RkNNs of the specified ids, i.e. the kNNs which have been
* updated
*/
private ArrayDBIDs updateKNNsAndRkNNs(DBIDs ids) {
ArrayModifiableDBIDs rkNN_ids = DBIDUtil.newArray();
DBIDs oldids = DBIDUtil.difference(relation.getDBIDs(), ids);
for (DBIDIter id = oldids.iter(); id.valid(); id.advance()) {
KNNList oldkNNs = storage.get(id);
double knnDist = oldkNNs.getKNNDistance();
// look for new kNNs
KNNHeap heap = null;
for (DBIDIter newid = ids.iter(); newid.valid(); newid.advance()) {
double dist = distanceQuery.distance(id, newid);
if (dist <= knnDist) {
// New id changes the kNNs of oldid.
if (heap == null) {
heap = DBIDUtil.newHeap(oldkNNs);
}
heap.insert(dist, newid);
}
}
// kNNs for oldid have changed:
if (heap != null) {
KNNList newkNNs = heap.toKNNList();
storage.put(id, newkNNs);
// get the difference
int i = 0;
int j = 0;
ModifiableDoubleDBIDList added = DBIDUtil.newDistanceDBIDList();
ModifiableDoubleDBIDList removed = DBIDUtil.newDistanceDBIDList();
// TODO: use iterators.
while (i < oldkNNs.size() && j < newkNNs.size()) {
DoubleDBIDPair drp1 = oldkNNs.get(i);
DoubleDBIDPair drp2 = newkNNs.get(j);
// NOTE: we assume that on ties they are ordered the same way!
if (!DBIDUtil.equal(drp1, drp2)) {
added.add(drp2);
j++;
} else {
i++;
j++;
}
}
if (i != j) {
for (; i < oldkNNs.size(); i++) {
removed.add(oldkNNs.get(i));
}
for (; j < newkNNs.size(); i++) {
added.add(newkNNs.get(i));
}
}
// add new RkNN
for (DoubleDBIDListIter newnn = added.iter(); newnn.valid(); newnn.advance()) {
TreeSet<DoubleDBIDPair> rknns = materialized_RkNN.get(newnn);
rknns.add(makePair(newnn, id));
}
// remove old RkNN
for (DoubleDBIDListIter oldnn = removed.iter(); oldnn.valid(); oldnn.advance()) {
TreeSet<DoubleDBIDPair> rknns = materialized_RkNN.get(oldnn);
rknns.remove(makePair(oldnn, id));
}
rkNN_ids.add(id);
}
}
return rkNN_ids;
}
use of de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList in project elki by elki-project.
the class MaterializeKNNAndRKNNPreprocessor method getRKNN.
/**
* Returns the materialized RkNNs of the specified id.
*
* @param id the query id
* @return the RkNNs
*/
public DoubleDBIDList getRKNN(DBIDRef id) {
TreeSet<DoubleDBIDPair> rKNN = materialized_RkNN.get(id);
if (rKNN == null) {
return null;
}
ModifiableDoubleDBIDList ret = DBIDUtil.newDistanceDBIDList(rKNN.size());
for (DoubleDBIDPair pair : rKNN) {
ret.add(pair);
}
ret.sort();
return ret;
}
use of de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList in project elki by elki-project.
the class RStarTreeRangeQuery method getRangeForDBID.
@Override
public DoubleDBIDList getRangeForDBID(DBIDRef id, double range) {
ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
getRangeForObject(relation.get(id), range, result);
result.sort();
return result;
}
use of de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList in project elki by elki-project.
the class RStarTreeRangeQuery method getRangeForObject.
@Override
public DoubleDBIDList getRangeForObject(O obj, double range) {
ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
getRangeForObject(obj, range, result);
result.sort();
return result;
}
use of de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList 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;
}
Aggregations