use of de.lmu.ifi.dbs.elki.database.ids.KNNList in project elki by elki-project.
the class GeoIndexing method main.
public static void main(String[] args) {
// Set the logging level to statistics:
LoggingConfiguration.setStatistics();
// Generate a random data set.
Random rand = new Random(0L);
// Note: ELKI has a nice data generator class, use that instead.
double[][] data = new double[100000][];
for (int i = 0; i < data.length; i++) {
data[i] = randomLatitudeLongitude(rand);
}
// Adapter to load data from an existing array.
DatabaseConnection dbc = new ArrayAdapterDatabaseConnection(data);
// Since the R-tree has so many options, it is a bit easier to configure it
// using the parameterization API, which handles defaults, instantiation,
// and additional constraint checks.
RStarTreeFactory<?> indexfactory = //
new ELKIBuilder<>(RStarTreeFactory.class).with(AbstractPageFileFactory.Parameterizer.PAGE_SIZE_ID, //
512).with(RStarTreeFactory.Parameterizer.BULK_SPLIT_ID, //
SortTileRecursiveBulkSplit.class).build();
// Create the database, and initialize it.
Database db = new StaticArrayDatabase(dbc, Arrays.asList(indexfactory));
// This will build the index of the database.
db.initialize();
// Relation containing the number vectors we put in above:
Relation<NumberVector> rel = db.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
// We can use this to identify rows of the input data below.
DBIDRange ids = (DBIDRange) rel.getDBIDs();
// For all indexes, dump their statistics.
for (It<Index> it = db.getHierarchy().iterDescendants(db).filter(Index.class); it.valid(); it.advance()) {
it.get().logStatistics();
}
// We use the WGS84 earth model, and "latitude, longitude" coordinates:
// This distance function returns meters.
LatLngDistanceFunction df = new LatLngDistanceFunction(WGS84SpheroidEarthModel.STATIC);
// k nearest neighbor query:
KNNQuery<NumberVector> knnq = QueryUtil.getKNNQuery(rel, df);
// Let's find the closest points to New York:
DoubleVector newYork = DoubleVector.wrap(new double[] { 40.730610, -73.935242 });
KNNList knns = knnq.getKNNForObject(newYork, 10);
// Iterate over all results.
System.out.println("Close to New York:");
for (DoubleDBIDListIter it = knns.iter(); it.valid(); it.advance()) {
// To kilometers
double km = it.doubleValue() / 1000;
System.out.println(rel.get(it) + " distance: " + km + " km row: " + ids.getOffset(it));
}
// Many other indexes will fail if we search close to the date line.
DoubleVector tuvalu = DoubleVector.wrap(new double[] { -7.4784205, 178.679924 });
knns = knnq.getKNNForObject(tuvalu, 10);
// Iterate over all results.
System.out.println("Close to Tuvalu:");
for (DoubleDBIDListIter it = knns.iter(); it.valid(); it.advance()) {
// To kilometers
double km = it.doubleValue() / 1000;
System.out.println(rel.get(it) + " distance: " + km + " km row: " + ids.getOffset(it));
}
// the distances to a few points in the data set.
for (It<Index> it = db.getHierarchy().iterDescendants(db).filter(Index.class); it.valid(); it.advance()) {
it.get().logStatistics();
}
}
use of de.lmu.ifi.dbs.elki.database.ids.KNNList in project elki by elki-project.
the class ODIN method run.
/**
* Run the ODIN algorithm
*
* Tutorial note: the <em>signature</em> of this method depends on the types
* that we requested in the {@link #getInputTypeRestriction} method. Here we
* requested a single relation of type {@code O} , the data type of our
* distance function.
*
* @param database Database to run on.
* @param relation Relation to process.
* @return ODIN outlier result.
*/
public OutlierResult run(Database database, Relation<O> relation) {
// Get the query functions:
DistanceQuery<O> dq = database.getDistanceQuery(relation, getDistanceFunction());
KNNQuery<O> knnq = database.getKNNQuery(dq, k);
// Get the objects to process, and a data storage for counting and output:
DBIDs ids = relation.getDBIDs();
WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_DB, 0.);
// Process all objects
for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
// Find the nearest neighbors (using an index, if available!)
KNNList neighbors = knnq.getKNNForDBID(iter, k);
// For each neighbor, except ourselves, increase the in-degree:
for (DBIDIter nei = neighbors.iter(); nei.valid(); nei.advance()) {
if (DBIDUtil.equal(iter, nei)) {
continue;
}
scores.put(nei, scores.doubleValue(nei) + 1);
}
}
// Compute maximum
double min = Double.POSITIVE_INFINITY, max = 0.0;
for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
min = Math.min(min, scores.doubleValue(iter));
max = Math.max(max, scores.doubleValue(iter));
}
// Wrap the result and add metadata.
// By actually specifying theoretical min, max and baseline, we get a better
// visualization (try it out - or see the screenshots in the tutorial)!
OutlierScoreMeta meta = new InvertedOutlierScoreMeta(min, max, 0., ids.size() - 1, k);
DoubleRelation rel = new MaterializedDoubleRelation("ODIN In-Degree", "odin", scores, ids);
return new OutlierResult(meta, rel);
}
use of de.lmu.ifi.dbs.elki.database.ids.KNNList 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.KNNList in project elki by elki-project.
the class MaterializeKNNAndRKNNPreprocessor method affectedkNN.
/**
* 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 affectedkNN(List<? extends KNNList> extract, DBIDs remove) {
HashSetModifiableDBIDs ids = DBIDUtil.newHashSet();
for (KNNList drps : extract) {
for (DBIDIter iter = drps.iter(); iter.valid(); iter.advance()) {
ids.add(iter);
}
}
ids.removeDBIDs(remove);
// Convert back to array
return DBIDUtil.newArray(ids);
}
use of de.lmu.ifi.dbs.elki.database.ids.KNNList in project elki by elki-project.
the class MaterializeKNNPreprocessor method updateKNNsAfterDeletion.
/**
* Updates the kNNs of the RkNNs of the specified ids.
*
* @param ids the ids of deleted objects causing a change of materialized kNNs
* @return the RkNNs of the specified ids, i.e. the kNNs which have been
* updated
*/
private ArrayDBIDs updateKNNsAfterDeletion(DBIDs ids) {
SetDBIDs idsSet = DBIDUtil.ensureSet(ids);
ArrayModifiableDBIDs rkNN_ids = DBIDUtil.newArray();
for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
KNNList kNNs = storage.get(iditer);
for (DBIDIter it = kNNs.iter(); it.valid(); it.advance()) {
if (idsSet.contains(it)) {
rkNN_ids.add(iditer);
break;
}
}
}
// update the kNNs of the RkNNs
List<? extends KNNList> kNNList = knnQuery.getKNNForBulkDBIDs(rkNN_ids, k);
DBIDIter iter = rkNN_ids.iter();
for (int i = 0; i < rkNN_ids.size(); i++, iter.advance()) {
storage.put(iter, kNNList.get(i));
}
return rkNN_ids;
}
Aggregations