Search in sources :

Example 41 with ArrayDBIDs

use of de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs 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;
}
Also used : DoubleDBIDListIter(de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter) ArrayModifiableDBIDs(de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs) KNNList(de.lmu.ifi.dbs.elki.database.ids.KNNList) ModifiableDoubleDBIDList(de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList) DoubleDBIDPair(de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair) ArrayDBIDs(de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs) ArrayModifiableDBIDs(de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs) DBIDs(de.lmu.ifi.dbs.elki.database.ids.DBIDs) HashSetModifiableDBIDs(de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs) SetDBIDs(de.lmu.ifi.dbs.elki.database.ids.SetDBIDs) KNNHeap(de.lmu.ifi.dbs.elki.database.ids.KNNHeap) DBIDIter(de.lmu.ifi.dbs.elki.database.ids.DBIDIter)

Example 42 with ArrayDBIDs

use of de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs in project elki by elki-project.

the class NNDescentTest method testKNNQueries.

private void testKNNQueries(Relation<DoubleVector> rep, KNNQuery<DoubleVector> lin_knn_query, KNNQuery<DoubleVector> preproc_knn_query, int k) {
    ArrayDBIDs sample = DBIDUtil.ensureArray(rep.getDBIDs());
    List<? extends KNNList> lin_knn_ids = lin_knn_query.getKNNForBulkDBIDs(sample, k);
    List<? extends KNNList> preproc_knn_ids = preproc_knn_query.getKNNForBulkDBIDs(sample, k);
    for (int i = 0; i < rep.size(); i++) {
        KNNList lin_knn = lin_knn_ids.get(i);
        KNNList pre_knn = preproc_knn_ids.get(i);
        DoubleDBIDListIter lin = lin_knn.iter(), pre = pre_knn.iter();
        for (; lin.valid() && pre.valid(); lin.advance(), pre.advance(), i++) {
            if (DBIDUtil.equal(lin, pre) || lin.doubleValue() == pre.doubleValue()) {
                continue;
            }
            fail(// 
            new StringBuilder(1000).append("Neighbor distances do not agree: ").append(lin_knn.toString()).append(" got: ").append(pre_knn.toString()).toString());
        }
        assertEquals("kNN sizes do not agree.", lin_knn.size(), pre_knn.size());
        for (int j = 0; j < lin_knn.size(); j++) {
            assertTrue("kNNs of linear scan and preprocessor do not match!", DBIDUtil.equal(lin_knn.get(j), pre_knn.get(j)));
            assertEquals("kNNs of linear scan and preprocessor do not match!", lin_knn.get(j).doubleValue(), pre_knn.get(j).doubleValue(), 0.);
        }
    }
}
Also used : DoubleDBIDListIter(de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter) KNNList(de.lmu.ifi.dbs.elki.database.ids.KNNList) ArrayDBIDs(de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs)

Example 43 with ArrayDBIDs

use of de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs in project elki by elki-project.

the class MaterializeKNNPreprocessor method objectsInserted.

/**
 * Called after new objects have been inserted, updates the materialized
 * neighborhood.
 *
 * @param ids the ids of the newly inserted objects
 */
protected void objectsInserted(DBIDs ids) {
    // Could be subclass
    final Logging log = getLogger();
    StepProgress stepprog = log.isVerbose() ? new StepProgress(3) : null;
    ArrayDBIDs aids = DBIDUtil.ensureArray(ids);
    // materialize the new kNNs
    log.beginStep(stepprog, 1, "New insertions ocurred, materialize their new kNNs.");
    // Bulk-query kNNs
    List<? extends KNNList> kNNList = knnQuery.getKNNForBulkDBIDs(aids, k);
    // Store in storage
    DBIDIter iter = aids.iter();
    for (int i = 0; i < aids.size(); i++, iter.advance()) {
        storage.put(iter, kNNList.get(i));
    }
    // update the affected kNNs
    log.beginStep(stepprog, 2, "New insertions ocurred, update the affected kNNs.");
    ArrayDBIDs rkNN_ids = updateKNNsAfterInsertion(ids);
    // inform listener
    log.beginStep(stepprog, 3, "New insertions ocurred, inform listeners.");
    fireKNNsInserted(ids, rkNN_ids);
    log.setCompleted(stepprog);
}
Also used : Logging(de.lmu.ifi.dbs.elki.logging.Logging) ArrayDBIDs(de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs) StepProgress(de.lmu.ifi.dbs.elki.logging.progress.StepProgress) DBIDIter(de.lmu.ifi.dbs.elki.database.ids.DBIDIter)

Example 44 with ArrayDBIDs

use of de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs 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());
    }
}
Also used : Logging(de.lmu.ifi.dbs.elki.logging.Logging) DoubleDBIDListIter(de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter) KNNList(de.lmu.ifi.dbs.elki.database.ids.KNNList) LongStatistic(de.lmu.ifi.dbs.elki.logging.statistics.LongStatistic) FiniteProgress(de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress) ArrayDBIDs(de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs) Duration(de.lmu.ifi.dbs.elki.logging.statistics.Duration) DBIDIter(de.lmu.ifi.dbs.elki.database.ids.DBIDIter)

Example 45 with ArrayDBIDs

use of de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs 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;
}
Also used : ArrayModifiableDBIDs(de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs) KNNList(de.lmu.ifi.dbs.elki.database.ids.KNNList) ArrayDBIDs(de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs) ArrayModifiableDBIDs(de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs) DBIDs(de.lmu.ifi.dbs.elki.database.ids.DBIDs) SetDBIDs(de.lmu.ifi.dbs.elki.database.ids.SetDBIDs) KNNHeap(de.lmu.ifi.dbs.elki.database.ids.KNNHeap) DBIDIter(de.lmu.ifi.dbs.elki.database.ids.DBIDIter)

Aggregations

ArrayDBIDs (de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs)45 DBIDIter (de.lmu.ifi.dbs.elki.database.ids.DBIDIter)23 DBIDs (de.lmu.ifi.dbs.elki.database.ids.DBIDs)16 DBIDArrayIter (de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter)14 FiniteProgress (de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress)13 KNNList (de.lmu.ifi.dbs.elki.database.ids.KNNList)12 WritableDoubleDataStore (de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore)10 ArrayModifiableDBIDs (de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs)9 DoubleDBIDListIter (de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter)9 ModifiableDBIDs (de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs)8 DoubleRelation (de.lmu.ifi.dbs.elki.database.relation.DoubleRelation)8 MaterializedDoubleRelation (de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation)7 DoubleMinMax (de.lmu.ifi.dbs.elki.math.DoubleMinMax)7 OutlierResult (de.lmu.ifi.dbs.elki.result.outlier.OutlierResult)7 OutlierScoreMeta (de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta)7 ArrayList (java.util.ArrayList)7 Clustering (de.lmu.ifi.dbs.elki.data.Clustering)6 KNNHeap (de.lmu.ifi.dbs.elki.database.ids.KNNHeap)6 ModifiableDoubleDBIDList (de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList)6 LongStatistic (de.lmu.ifi.dbs.elki.logging.statistics.LongStatistic)5