use of de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair in project elki by elki-project.
the class MaterializeKNNAndRKNNPreprocessor method affectedRkNN.
/**
* Extracts and removes the DBIDs in the given collections.
*
* @param extract a list of lists of DistanceResultPair to extract
* @param remove the ids to remove
* @return the DBIDs in the given collection
*/
protected ArrayDBIDs affectedRkNN(List<? extends Collection<DoubleDBIDPair>> extract, DBIDs remove) {
HashSetModifiableDBIDs ids = DBIDUtil.newHashSet();
for (Collection<DoubleDBIDPair> drps : extract) {
for (DoubleDBIDPair drp : drps) {
ids.add(drp);
}
}
ids.removeDBIDs(remove);
// Convert back to array
return DBIDUtil.newArray(ids);
}
use of de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair in project elki by elki-project.
the class MaterializeKNNAndRKNNPreprocessor method objectsRemoved.
@Override
protected void objectsRemoved(DBIDs ids) {
StepProgress stepprog = getLogger().isVerbose() ? new StepProgress(3) : null;
// For debugging: valid DBIDs still in the database.
final DBIDs valid = DBIDUtil.ensureSet(distanceQuery.getRelation().getDBIDs());
ArrayDBIDs aids = DBIDUtil.ensureArray(ids);
// delete the materialized (old) kNNs and RkNNs
getLogger().beginStep(stepprog, 1, "New deletions ocurred, remove their materialized kNNs and RkNNs.");
// Temporary storage of removed lists
List<KNNList> kNNs = new ArrayList<>(ids.size());
List<TreeSet<DoubleDBIDPair>> rkNNs = new ArrayList<>(ids.size());
for (DBIDIter iter = aids.iter(); iter.valid(); iter.advance()) {
kNNs.add(storage.get(iter));
for (DBIDIter it = storage.get(iter).iter(); it.valid(); it.advance()) {
if (!valid.contains(it) && !ids.contains(it)) {
LOG.warning("False kNN: " + it);
}
}
storage.delete(iter);
rkNNs.add(materialized_RkNN.get(iter));
for (DoubleDBIDPair it : materialized_RkNN.get(iter)) {
if (!valid.contains(it) && !ids.contains(it)) {
LOG.warning("False RkNN: " + it);
}
}
materialized_RkNN.delete(iter);
}
// Keep only those IDs not also removed
ArrayDBIDs kNN_ids = affectedkNN(kNNs, aids);
ArrayDBIDs rkNN_ids = affectedRkNN(rkNNs, aids);
// update the affected kNNs and RkNNs
getLogger().beginStep(stepprog, 2, "New deletions ocurred, update the affected kNNs and RkNNs.");
// Recompute the kNN for affected objects (in rkNN lists)
{
List<? extends KNNList> kNNList = knnQuery.getKNNForBulkDBIDs(rkNN_ids, k);
int i = 0;
for (DBIDIter reknn = rkNN_ids.iter(); reknn.valid(); reknn.advance(), i++) {
if (kNNList.get(i) == null && !valid.contains(reknn)) {
LOG.warning("BUG in online kNN/RkNN maintainance: " + DBIDUtil.toString(reknn) + " no longer in database.");
continue;
}
assert (kNNList.get(i) != null);
storage.put(reknn, kNNList.get(i));
for (DoubleDBIDListIter it = kNNList.get(i).iter(); it.valid(); it.advance()) {
materialized_RkNN.get(it).add(makePair(it, reknn));
}
}
}
// remove objects from RkNNs of objects (in kNN lists)
{
SetDBIDs idsSet = DBIDUtil.ensureSet(ids);
for (DBIDIter nn = kNN_ids.iter(); nn.valid(); nn.advance()) {
TreeSet<DoubleDBIDPair> rkNN = materialized_RkNN.get(nn);
for (Iterator<DoubleDBIDPair> it = rkNN.iterator(); it.hasNext(); ) {
if (idsSet.contains(it.next())) {
it.remove();
}
}
}
}
// inform listener
getLogger().beginStep(stepprog, 3, "New deletions ocurred, inform listeners.");
fireKNNsRemoved(ids, rkNN_ids);
getLogger().ensureCompleted(stepprog);
}
use of de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair in project elki by elki-project.
the class HilOut method innerScan.
/**
* innerScan function calculates new upper and lower bounds and inserts the
* points of the neighborhood the bounds are based on in the NN Set
*
* @param i position in pf of the feature for which the bounds should be
* calculated
* @param maxcount maximal size of the neighborhood
*/
private void innerScan(HilbertFeatures hf, final int i, final int maxcount) {
// Get only once for performance
final O p = hf.relation.get(hf.pf[i].id);
int a = i, b = i;
int level = h, levela = h, levelb = h;
// Explore up to "maxcount" neighbors in this pass
for (int count = 0; count < maxcount; count++) {
// Neighbor to explore
final int c;
if (a == 0) {
// At left end, explore right
// assert (b < capital_n - 1);
levelb = Math.min(levelb, hf.pf[b].level);
b++;
c = b;
} else if (b >= capital_n - 1) {
// At right end, explore left
// assert (a > 0);
a--;
levela = Math.min(levela, hf.pf[a].level);
c = a;
} else if (hf.pf[a - 1].level >= hf.pf[b].level) {
// Prefer higher level
a--;
levela = Math.min(levela, hf.pf[a].level);
c = a;
} else {
// assert (b < capital_n - 1);
levelb = Math.min(levelb, hf.pf[b].level);
b++;
c = b;
}
if (!hf.pf[i].nn_keys.contains(hf.pf[c].id)) {
// hf.distcomp ++;
hf.pf[i].insert(hf.pf[c].id, distq.distance(p, hf.pf[c].id), k);
if (hf.pf[i].nn.size() == k) {
if (hf.pf[i].sum_nn < omega_star) {
// stop = true
break;
}
final int mlevel = Math.max(levela, levelb);
if (mlevel < level) {
level = mlevel;
final double delta = hf.minDistLevel(hf.pf[i].id, level);
if (delta >= hf.pf[i].nn.peek().doubleValue()) {
// stop = true
break;
}
}
}
}
}
double br = hf.boxRadius(i, a - 1, b + 1);
double newlb = 0.0;
double newub = 0.0;
for (ObjectHeap.UnsortedIter<DoubleDBIDPair> iter = hf.pf[i].nn.unsortedIter(); iter.valid(); iter.advance()) {
DoubleDBIDPair entry = iter.get();
newub += entry.doubleValue();
if (entry.doubleValue() <= br) {
newlb += entry.doubleValue();
}
}
if (newlb > hf.pf[i].lbound) {
hf.pf[i].lbound = newlb;
}
if (newub < hf.pf[i].ubound) {
hf.pf[i].ubound = newub;
}
}
use of de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair in project elki by elki-project.
the class LinearWeightedExtendedNeighborhood method getWeightedNeighbors.
@Override
public Collection<DoubleDBIDPair> getWeightedNeighbors(DBIDRef reference) {
ModifiableDBIDs seen = DBIDUtil.newHashSet();
List<DoubleDBIDPair> result = new ArrayList<>();
// Add starting object
result.add(DBIDUtil.newPair(computeWeight(0), reference));
seen.add(reference);
// Extend.
DBIDs cur = DBIDUtil.deref(reference);
for (int i = 1; i <= steps; i++) {
final double weight = computeWeight(i);
// Collect newly discovered IDs
ModifiableDBIDs add = DBIDUtil.newHashSet();
for (DBIDIter iter = cur.iter(); iter.valid(); iter.advance()) {
for (DBIDIter iter2 = inner.getNeighborDBIDs(iter).iter(); iter2.valid(); iter2.advance()) {
// Seen before?
if (seen.contains(iter2)) {
continue;
}
add.add(iter2);
result.add(DBIDUtil.newPair(weight, iter2));
}
}
if (add.size() == 0) {
break;
}
cur = add;
}
return result;
}
use of de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair in project elki by elki-project.
the class OUTRES method subsetNeighborhoodQuery.
/**
* Refine neighbors within a subset.
*
* @param neighc Neighbor candidates
* @param dbid Query object
* @param df distance function
* @param adjustedEps Epsilon range
* @param kernel Kernel
* @return Neighbors of neighbor object
*/
private DoubleDBIDList subsetNeighborhoodQuery(DoubleDBIDList neighc, DBIDRef dbid, PrimitiveDistanceFunction<? super V> df, double adjustedEps, KernelDensityEstimator kernel) {
ModifiableDoubleDBIDList n = DBIDUtil.newDistanceDBIDList(neighc.size());
V query = kernel.relation.get(dbid);
for (DoubleDBIDListIter neighbor = neighc.iter(); neighbor.valid(); neighbor.advance()) {
DoubleDBIDPair p = neighbor.getPair();
double dist = df.distance(query, kernel.relation.get(p));
if (dist <= adjustedEps) {
n.add(dist, p);
}
}
return n;
}
Aggregations