Search in sources :

Example 21 with KNNHeap

use of de.lmu.ifi.dbs.elki.database.ids.KNNHeap 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 22 with KNNHeap

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

the class SpacefillingMaterializeKNNPreprocessor method preprocess.

@Override
protected void preprocess() {
    // Prepare space filling curve:
    final long starttime = System.currentTimeMillis();
    final int size = relation.size();
    final int numgen = curvegen.size();
    final int numcurves = numgen * variants;
    List<List<SpatialPair<DBID, NumberVector>>> curves = new ArrayList<>(numcurves);
    for (int i = 0; i < numcurves; i++) {
        curves.add(new ArrayList<SpatialPair<DBID, NumberVector>>(size));
    }
    for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
        final NumberVector v = relation.get(iditer);
        SpatialPair<DBID, NumberVector> ref = new SpatialPair<DBID, NumberVector>(DBIDUtil.deref(iditer), v);
        for (List<SpatialPair<DBID, NumberVector>> curve : curves) {
            curve.add(ref);
        }
    }
    // Sort spatially
    final double[] mms = SpatialSorter.computeMinMax(curves.get(0));
    final double[] mmscratch = new double[mms.length];
    final int numdim = mms.length >>> 1;
    final int[] permutation = new int[numdim];
    for (int j = 0; j < variants; j++) {
        for (int i = 0; i < mms.length; i += 2) {
            double len = mms[i + 1] - mms[i];
            mmscratch[i] = mms[i] - len * random.nextDouble();
            mmscratch[i + 1] = mms[i + 1] + len * random.nextDouble();
        }
        // Generate permutation:
        for (int i = 0; i < numdim; i++) {
            permutation[i] = i;
        }
        // Knuth / Fisher-Yates style shuffle
        for (int i = numdim - 1; i > 0; i--) {
            // Swap with random preceeding element.
            int ri = random.nextInt(i + 1);
            int tmp = permutation[ri];
            permutation[ri] = permutation[i];
            permutation[i] = tmp;
        }
        for (int i = 0; i < numgen; i++) {
            curvegen.get(i).sort(curves.get(i + numgen * j), 0, size, mmscratch, permutation);
        }
    }
    // Build position index, DBID -> position in the three curves
    WritableDataStore<int[]> positions = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, int[].class);
    for (int cnum = 0; cnum < numcurves; cnum++) {
        Iterator<SpatialPair<DBID, NumberVector>> it = curves.get(cnum).iterator();
        for (int i = 0; it.hasNext(); i++) {
            SpatialPair<DBID, NumberVector> r = it.next();
            final int[] data;
            if (cnum == 0) {
                data = new int[numcurves];
                positions.put(r.first, data);
            } else {
                data = positions.get(r.first);
            }
            data[cnum] = i;
        }
    }
    // Convert to final storage
    final int wsize = (int) Math.ceil(window * k);
    storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC, KNNList.class);
    HashSetModifiableDBIDs cands = DBIDUtil.newHashSet(2 * wsize * numcurves);
    for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
        // Get candidates.
        cands.clear();
        int[] posi = positions.get(iditer);
        for (int i = 0; i < posi.length; i++) {
            List<SpatialPair<DBID, NumberVector>> curve = curves.get(i);
            final int start = Math.max(0, posi[i] - wsize);
            final int end = Math.min(posi[i] + wsize + 1, curve.size());
            for (int pos = start; pos < end; pos++) {
                cands.add(curve.get(pos).first);
            }
        }
        int distc = 0;
        KNNHeap heap = DBIDUtil.newHeap(k);
        O vec = relation.get(iditer);
        for (DBIDIter iter = cands.iter(); iter.valid(); iter.advance()) {
            heap.insert(distanceQuery.distance(vec, iter), iter);
            distc++;
        }
        storage.put(iditer, heap.toKNNList());
        mean.put(distc / (double) k);
    }
    final long end = System.currentTimeMillis();
    if (LOG.isStatistics()) {
        LOG.statistics(new LongStatistic(this.getClass().getCanonicalName() + ".construction-time.ms", end - starttime));
    }
}
Also used : DBID(de.lmu.ifi.dbs.elki.database.ids.DBID) ArrayList(java.util.ArrayList) KNNHeap(de.lmu.ifi.dbs.elki.database.ids.KNNHeap) DBIDIter(de.lmu.ifi.dbs.elki.database.ids.DBIDIter) HashSetModifiableDBIDs(de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs) NumberVector(de.lmu.ifi.dbs.elki.data.NumberVector) KNNList(de.lmu.ifi.dbs.elki.database.ids.KNNList) LongStatistic(de.lmu.ifi.dbs.elki.logging.statistics.LongStatistic) ArrayList(java.util.ArrayList) KNNList(de.lmu.ifi.dbs.elki.database.ids.KNNList) List(java.util.List)

Example 23 with KNNHeap

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

the class MkMaxTree method preInsert.

/**
 * Adapts the knn distances before insertion of the specified entry.
 */
@Override
protected void preInsert(MkMaxEntry entry) {
    KNNHeap knns_o = DBIDUtil.newHeap(getKmax());
    preInsert(entry, getRootEntry(), knns_o);
}
Also used : KNNHeap(de.lmu.ifi.dbs.elki.database.ids.KNNHeap)

Example 24 with KNNHeap

use of de.lmu.ifi.dbs.elki.database.ids.KNNHeap 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

KNNHeap (de.lmu.ifi.dbs.elki.database.ids.KNNHeap)24 DBIDIter (de.lmu.ifi.dbs.elki.database.ids.DBIDIter)17 KNNList (de.lmu.ifi.dbs.elki.database.ids.KNNList)11 ArrayDBIDs (de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs)6 DBIDs (de.lmu.ifi.dbs.elki.database.ids.DBIDs)5 ArrayList (java.util.ArrayList)5 FiniteProgress (de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress)4 MeanVariance (de.lmu.ifi.dbs.elki.math.MeanVariance)4 WritableDoubleDataStore (de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore)3 ArrayModifiableDBIDs (de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs)3 DBID (de.lmu.ifi.dbs.elki.database.ids.DBID)3 DoubleDBIDListIter (de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter)3 DoubleRelation (de.lmu.ifi.dbs.elki.database.relation.DoubleRelation)3 MaterializedDoubleRelation (de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation)3 DoubleMinMax (de.lmu.ifi.dbs.elki.math.DoubleMinMax)3 OutlierResult (de.lmu.ifi.dbs.elki.result.outlier.OutlierResult)3 OutlierScoreMeta (de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta)3 DBIDPair (de.lmu.ifi.dbs.elki.database.ids.DBIDPair)2 HashSetModifiableDBIDs (de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs)2 ModifiableDoubleDBIDList (de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList)2