use of de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair in project elki by elki-project.
the class SOD method getNearestNeighbors.
/**
* Get the k nearest neighbors in terms of the shared nearest neighbor
* distance.
*
* The query object is excluded from the knn list.
*
* FIXME: move this to the database layer.
*
* @param relation the database holding the objects
* @param simQ similarity function
* @param queryObject the query object for which the kNNs should be determined
* @return the k nearest neighbors in terms of the shared nearest neighbor
* distance without the query object
*/
private DBIDs getNearestNeighbors(Relation<V> relation, SimilarityQuery<V> simQ, DBIDRef queryObject) {
Heap<DoubleDBIDPair> nearestNeighbors = new TiedTopBoundedHeap<>(knn);
for (DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
if (DBIDUtil.equal(iter, queryObject)) {
continue;
}
double sim = simQ.similarity(queryObject, iter);
if (sim > 0.) {
nearestNeighbors.add(DBIDUtil.newPair(sim, iter));
}
}
// Collect DBIDs
ArrayModifiableDBIDs dbids = DBIDUtil.newArray(nearestNeighbors.size());
while (nearestNeighbors.size() > 0) {
dbids.add(nearestNeighbors.poll());
}
return dbids;
}
use of de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair in project elki by elki-project.
the class UnweightedNeighborhoodAdapter method getWeightedNeighbors.
@Override
public Collection<DoubleDBIDPair> getWeightedNeighbors(DBIDRef reference) {
DBIDs neighbors = inner.getNeighborDBIDs(reference);
ArrayList<DoubleDBIDPair> adapted = new ArrayList<>(neighbors.size());
for (DBIDIter iter = neighbors.iter(); iter.valid(); iter.advance()) {
adapted.add(DBIDUtil.newPair(1.0, iter));
}
return adapted;
}
use of de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair in project elki by elki-project.
the class OUTRES method refineRange.
/**
* Refine a range query.
*
* @param neighc Original result
* @param adjustedEps New epsilon
* @return refined list
*/
private DoubleDBIDList refineRange(DoubleDBIDList neighc, double adjustedEps) {
ModifiableDoubleDBIDList n = DBIDUtil.newDistanceDBIDList(neighc.size());
// We don't have a guarantee for this list to be sorted
for (DoubleDBIDListIter neighbor = neighc.iter(); neighbor.valid(); neighbor.advance()) {
DoubleDBIDPair p = neighbor.getPair();
double dist = p.doubleValue();
if (dist <= adjustedEps) {
n.add(dist, p);
}
}
return n;
}
use of de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair in project elki by elki-project.
the class MaterializeKNNAndRKNNPreprocessor method materializeKNNAndRKNNs.
/**
* Materializes the kNNs and RkNNs of the specified object IDs.
*
* @param ids the IDs of the objects
*/
private void materializeKNNAndRKNNs(ArrayDBIDs ids, FiniteProgress progress) {
// add an empty list to each rknn
for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
if (materialized_RkNN.get(iter) == null) {
materialized_RkNN.put(iter, new TreeSet<DoubleDBIDPair>());
}
}
// knn query
List<? extends KNNList> kNNList = knnQuery.getKNNForBulkDBIDs(ids, k);
int i = 0;
for (DBIDIter id = ids.iter(); id.valid(); id.advance(), i++) {
KNNList kNNs = kNNList.get(i);
storage.put(id, kNNs);
for (DoubleDBIDListIter iter = kNNs.iter(); iter.valid(); iter.advance()) {
TreeSet<DoubleDBIDPair> rknns = materialized_RkNN.get(iter);
rknns.add(makePair(iter, id));
}
getLogger().incrementProcessed(progress);
}
getLogger().ensureCompleted(progress);
}
use of de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair 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;
}
Aggregations