use of de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter in project elki by elki-project.
the class WeightedCovarianceMatrixBuilder method processQueryResults.
/**
* Compute Covariance Matrix for a QueryResult Collection.
*
* By default it will just collect the ids and run processIds
*
* @param results a collection of QueryResults
* @param database the database used
* @param k number of elements to process
* @return Covariance Matrix
*/
@Override
public double[][] processQueryResults(DoubleDBIDList results, Relation<? extends NumberVector> database, int k) {
final int dim = RelationUtil.dimensionality(database);
final CovarianceMatrix cmat = new CovarianceMatrix(dim);
// avoid bad parameters
k = k <= results.size() ? k : results.size();
// find maximum distance
double maxdist = 0.0, stddev = 0.0;
{
int i = 0;
for (DoubleDBIDListIter it = results.iter(); it.valid() && i < k; it.advance(), k++) {
final double dist = it.doubleValue();
stddev += dist * dist;
if (dist > maxdist) {
maxdist = dist;
}
}
if (maxdist == 0.0) {
maxdist = 1.0;
}
stddev = FastMath.sqrt(stddev / k);
}
// calculate weighted PCA
int i = 0;
for (DoubleDBIDListIter it = results.iter(); it.valid() && i < k; it.advance(), k++) {
final double dist = it.doubleValue();
NumberVector obj = database.get(it);
double weight = weightfunction.getWeight(dist, maxdist, stddev);
cmat.put(obj, weight);
}
return cmat.destroyToPopulationMatrix();
}
use of de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter 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.DoubleDBIDListIter in project elki by elki-project.
the class PreprocessorKNNQuery method getSublist.
/**
* Subset a knn list for a smaller k.
*
* @param knn k nearest neighbor list
* @param k New k
* @return Sublist
*/
protected static KNNList getSublist(KNNList knn, int k) {
DoubleDBIDListIter it = knn.iter();
// k-distance for the new k.
final double kdist = it.seek(k - 1).doubleValue();
if (kdist >= knn.getKNNDistance()) {
return knn;
}
// Find ties:
int subk = k;
for (it.advance(); it.valid() && kdist < it.doubleValue() && subk < k; it.advance()) {
subk++;
}
return subk < knn.size() ? DBIDUtil.subList(knn, subk) : knn;
}
use of de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter in project elki by elki-project.
the class MkTabTree method kNNdistanceAdjustment.
@Override
protected void kNNdistanceAdjustment(MkTabEntry entry, Map<DBID, KNNList> knnLists) {
MkTabTreeNode<O> node = getNode(entry);
double[] knnDistances_node = initKnnDistanceList();
if (node.isLeaf()) {
for (int i = 0; i < node.getNumEntries(); i++) {
MkTabEntry leafEntry = node.getEntry(i);
KNNList knns = knnLists.get(getPageID(leafEntry));
double[] distances = new double[knns.size()];
int j = 0;
for (DoubleDBIDListIter iter = knns.iter(); iter.valid(); iter.advance(), j++) {
distances[j] = iter.doubleValue();
}
leafEntry.setKnnDistances(distances);
// FIXME: save copy
knnDistances_node = max(knnDistances_node, leafEntry.getKnnDistances());
}
} else {
for (int i = 0; i < node.getNumEntries(); i++) {
MkTabEntry dirEntry = node.getEntry(i);
kNNdistanceAdjustment(dirEntry, knnLists);
// FIXME: save copy
knnDistances_node = max(knnDistances_node, dirEntry.getKnnDistances());
}
}
entry.setKnnDistances(knnDistances_node);
}
use of de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter in project elki by elki-project.
the class MkAppTree method getMeanKNNList.
private double[] getMeanKNNList(DBIDs ids, Map<DBID, KNNList> knnLists) {
double[] means = new double[settings.kmax];
for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
DBID id = DBIDUtil.deref(iter);
KNNList knns = knnLists.get(id);
int k = 0;
for (DoubleDBIDListIter it = knns.iter(); k < settings.kmax && it.valid(); it.advance(), k++) {
means[k] += it.doubleValue();
}
}
for (int k = 0; k < settings.kmax; k++) {
means[k] /= ids.size();
}
return means;
}
Aggregations