diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/database')
179 files changed, 2655 insertions, 5099 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/database/AbstractDatabase.java b/src/de/lmu/ifi/dbs/elki/database/AbstractDatabase.java index ef2374cc..5ff2c6e9 100644 --- a/src/de/lmu/ifi/dbs/elki/database/AbstractDatabase.java +++ b/src/de/lmu/ifi/dbs/elki/database/AbstractDatabase.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -43,8 +43,8 @@ import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.datasource.bundle.SingleObjectBundle; import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; import de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction; +import de.lmu.ifi.dbs.elki.index.DistanceIndex; import de.lmu.ifi.dbs.elki.index.Index; import de.lmu.ifi.dbs.elki.index.IndexFactory; import de.lmu.ifi.dbs.elki.index.KNNIndex; @@ -155,15 +155,30 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem } @Override - public <O, D extends Distance<D>> DistanceQuery<O, D> getDistanceQuery(Relation<O> objQuery, DistanceFunction<? super O, D> distanceFunction, Object... hints) { + public <O> DistanceQuery<O> getDistanceQuery(Relation<O> objQuery, DistanceFunction<? super O> distanceFunction, Object... hints) { if(distanceFunction == null) { throw new AbortException("Distance query requested for 'null' distance!"); } + ListIterator<Index> iter = indexes.listIterator(indexes.size()); + while(iter.hasPrevious()) { + Index idx = iter.previous(); + if(idx instanceof DistanceIndex) { + if(getLogger().isDebuggingFinest()) { + getLogger().debugFinest("Considering index for kNN Query: " + idx); + } + @SuppressWarnings("unchecked") + final DistanceIndex<O> distanceIndex = (DistanceIndex<O>) idx; + DistanceQuery<O> q = distanceIndex.getDistanceQuery(distanceFunction, hints); + if(q != null) { + return q; + } + } + } return distanceFunction.instantiate(objQuery); } @Override - public <O, D extends Distance<D>> SimilarityQuery<O, D> getSimilarityQuery(Relation<O> objQuery, SimilarityFunction<? super O, D> similarityFunction, Object... hints) { + public <O> SimilarityQuery<O> getSimilarityQuery(Relation<O> objQuery, SimilarityFunction<? super O> similarityFunction, Object... hints) { if(similarityFunction == null) { throw new AbortException("Similarity query requested for 'null' similarity!"); } @@ -171,7 +186,7 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem } @Override - public <O, D extends Distance<D>> KNNQuery<O, D> getKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints) { + public <O> KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) { if(distanceQuery == null) { throw new AbortException("kNN query requested for 'null' distance!"); } @@ -184,7 +199,7 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem } @SuppressWarnings("unchecked") final KNNIndex<O> knnIndex = (KNNIndex<O>) idx; - KNNQuery<O, D> q = knnIndex.getKNNQuery(distanceQuery, hints); + KNNQuery<O> q = knnIndex.getKNNQuery(distanceQuery, hints); if(q != null) { return q; } @@ -201,7 +216,7 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem } @Override - public <O, D extends Distance<D>> RangeQuery<O, D> getRangeQuery(DistanceQuery<O, D> distanceQuery, Object... hints) { + public <O> RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints) { if(distanceQuery == null) { throw new AbortException("Range query requested for 'null' distance!"); } @@ -214,7 +229,7 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem } @SuppressWarnings("unchecked") final RangeIndex<O> rangeIndex = (RangeIndex<O>) idx; - RangeQuery<O, D> q = rangeIndex.getRangeQuery(distanceQuery, hints); + RangeQuery<O> q = rangeIndex.getRangeQuery(distanceQuery, hints); if(q != null) { return q; } @@ -231,7 +246,7 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem } @Override - public <O, D extends Distance<D>> RKNNQuery<O, D> getRKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints) { + public <O> RKNNQuery<O> getRKNNQuery(DistanceQuery<O> distanceQuery, Object... hints) { if(distanceQuery == null) { throw new AbortException("RKNN query requested for 'null' distance!"); } @@ -244,7 +259,7 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem } @SuppressWarnings("unchecked") final RKNNIndex<O> rknnIndex = (RKNNIndex<O>) idx; - RKNNQuery<O, D> q = rknnIndex.getRKNNQuery(distanceQuery, hints); + RKNNQuery<O> q = rknnIndex.getRKNNQuery(distanceQuery, hints); if(q != null) { return q; } @@ -261,7 +276,7 @@ public abstract class AbstractDatabase extends AbstractHierarchicalResult implem maxk = (Integer) hint; } } - KNNQuery<O, D> knnQuery = getKNNQuery(distanceQuery, DatabaseQuery.HINT_BULK, maxk); + KNNQuery<O> knnQuery = getKNNQuery(distanceQuery, DatabaseQuery.HINT_BULK, maxk); return new LinearScanRKNNQuery<>(distanceQuery, knnQuery, maxk); } diff --git a/src/de/lmu/ifi/dbs/elki/database/Database.java b/src/de/lmu/ifi/dbs/elki/database/Database.java index 10bc0eac..9eab5c94 100644 --- a/src/de/lmu/ifi/dbs/elki/database/Database.java +++ b/src/de/lmu/ifi/dbs/elki/database/Database.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -38,7 +38,6 @@ import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.datasource.bundle.SingleObjectBundle; import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; import de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction; import de.lmu.ifi.dbs.elki.index.Index; import de.lmu.ifi.dbs.elki.result.HierarchicalResult; @@ -87,25 +86,23 @@ public interface Database extends HierarchicalResult { * Get the distance query for a particular distance function. * * @param <O> Object type - * @param <D> Distance result type * @param relation Relation used * @param distanceFunction Distance function to use * @param hints Optimizer hints * @return Instance to query the database with this distance */ - <O, D extends Distance<D>> DistanceQuery<O, D> getDistanceQuery(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, Object... hints); + <O> DistanceQuery<O> getDistanceQuery(Relation<O> relation, DistanceFunction<? super O> distanceFunction, Object... hints); /** * Get the similarity query for a particular similarity function. * * @param <O> Object type - * @param <D> Similarity result type * @param relation Relation used * @param similarityFunction Similarity function to use * @param hints Optimizer hints * @return Instance to query the database with this similarity */ - <O, D extends Distance<D>> SimilarityQuery<O, D> getSimilarityQuery(Relation<O> relation, SimilarityFunction<? super O, D> similarityFunction, Object... hints); + <O> SimilarityQuery<O> getSimilarityQuery(Relation<O> relation, SimilarityFunction<? super O> similarityFunction, Object... hints); /** * Get a KNN query object for the given distance query. @@ -121,12 +118,11 @@ public interface Database extends HierarchicalResult { * </ul> * * @param <O> Object type - * @param <D> Distance type * @param distanceQuery Distance query * @param hints Optimizer hints * @return KNN Query object */ - <O, D extends Distance<D>> KNNQuery<O, D> getKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints); + <O> KNNQuery<O> getKNNQuery(DistanceQuery<O> distanceQuery, Object... hints); /** * Get a range query object for the given distance query. @@ -142,12 +138,11 @@ public interface Database extends HierarchicalResult { * </ul> * * @param <O> Object type - * @param <D> Distance type * @param distanceQuery Distance query * @param hints Optimizer hints * @return KNN Query object */ - <O, D extends Distance<D>> RangeQuery<O, D> getRangeQuery(DistanceQuery<O, D> distanceQuery, Object... hints); + <O> RangeQuery<O> getRangeQuery(DistanceQuery<O> distanceQuery, Object... hints); /** * Get a rKNN query object for the given distance query. @@ -163,12 +158,11 @@ public interface Database extends HierarchicalResult { * </ul> * * @param <O> Object type - * @param <D> Distance type * @param distanceQuery Distance query * @param hints Optimizer hints * @return KNN Query object */ - <O, D extends Distance<D>> RKNNQuery<O, D> getRKNNQuery(DistanceQuery<O, D> distanceQuery, Object... hints); + <O> RKNNQuery<O> getRKNNQuery(DistanceQuery<O> distanceQuery, Object... hints); /** * Returns the DatabaseObject represented by the specified id. diff --git a/src/de/lmu/ifi/dbs/elki/database/DatabaseEventManager.java b/src/de/lmu/ifi/dbs/elki/database/DatabaseEventManager.java index 4b9c9d94..1596c82f 100644 --- a/src/de/lmu/ifi/dbs/elki/database/DatabaseEventManager.java +++ b/src/de/lmu/ifi/dbs/elki/database/DatabaseEventManager.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.database; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/HashmapDatabase.java b/src/de/lmu/ifi/dbs/elki/database/HashmapDatabase.java index 26f18bce..541d59fc 100644 --- a/src/de/lmu/ifi/dbs/elki/database/HashmapDatabase.java +++ b/src/de/lmu/ifi/dbs/elki/database/HashmapDatabase.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,11 +29,11 @@ import java.util.Collection; import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs; -import de.lmu.ifi.dbs.elki.database.ids.DBID; import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; +import de.lmu.ifi.dbs.elki.database.ids.DBIDVar; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs; import de.lmu.ifi.dbs.elki.database.relation.DBIDView; @@ -50,15 +50,13 @@ import de.lmu.ifi.dbs.elki.index.IndexFactory; import de.lmu.ifi.dbs.elki.logging.Logging; import de.lmu.ifi.dbs.elki.utilities.documentation.Description; import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParameter; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; /** - * Provides a mapping for associations based on a Hashtable and functions to get - * the next usable ID for insertion, making IDs reusable after deletion of the - * entry. + * Database storing data using hashtable storage, and thus allowing additional + * and removal of objects. * * @author Arthur Zimek * @author Erich Schubert @@ -67,7 +65,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; * @apiviz.composedOf HashSetModifiableDBIDs */ @Description("Database using an in-memory hashtable and at least providing linear scans.") -public class HashmapDatabase extends AbstractDatabase implements UpdatableDatabase, Parameterizable { +public class HashmapDatabase extends AbstractDatabase implements UpdatableDatabase { /** * Our logger */ @@ -103,7 +101,7 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba this.addChildResult(idrep); // Add indexes. - if (indexFactories != null) { + if(indexFactories != null) { this.indexFactories.addAll(indexFactories); } } @@ -121,7 +119,7 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba */ @Override public void initialize() { - if (databaseConnection != null) { + if(databaseConnection != null) { this.insert(databaseConnection.loadData()); // Run at most once. databaseConnection = null; @@ -130,50 +128,37 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba @Override public DBIDs insert(ObjectBundle objpackages) { - if (objpackages.dataLength() == 0) { + if(objpackages.dataLength() == 0) { return DBIDUtil.EMPTYDBIDS; } // insert into db ArrayModifiableDBIDs newids = DBIDUtil.newArray(objpackages.dataLength()); Relation<?>[] targets = alignColumns(objpackages); - int idrepnr = -1; - for (int i = 0; i < targets.length; i++) { - if (targets[i] == idrep) { - idrepnr = i; - break; - } - } - - for (int j = 0; j < objpackages.dataLength(); j++) { + DBIDVar var = DBIDUtil.newVar(); + for(int j = 0; j < objpackages.dataLength(); j++) { // insert object - final DBID newid; - if (idrepnr < 0) { - newid = DBIDUtil.generateSingleDBID(); - } else { - newid = (DBID) objpackages.data(j, idrepnr); + if(!objpackages.assignDBID(j, var)) { + var.set(DBIDUtil.generateSingleDBID()); } - if (ids.contains(newid)) { + if(ids.contains(var)) { throw new AbortException("Duplicate DBID conflict."); } - ids.add(newid); - for (int i = 0; i < targets.length; i++) { - // DBIDs were handled above. - if (i == idrepnr) { - continue; - } + ids.add(var); + for(int i = 0; i < targets.length; i++) { @SuppressWarnings("unchecked") final Relation<Object> relation = (Relation<Object>) targets[i]; - relation.set(newid, objpackages.data(j, i)); + relation.set(var, objpackages.data(j, i)); } - newids.add(newid); + newids.add(var); } // Notify indexes of insertions - for (Index index : indexes) { - if (index instanceof DynamicIndex) { + for(Index index : indexes) { + if(index instanceof DynamicIndex) { ((DynamicIndex) index).insertAll(newids); - } else { + } + else { LOG.warning("Non-dynamic indexes have been added to the database. Updates are not possible!"); } } @@ -195,19 +180,19 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba Relation<?>[] targets = new Relation<?>[pack.metaLength()]; { BitSet used = new BitSet(relations.size()); - for (int i = 0; i < targets.length; i++) { + for(int i = 0; i < targets.length; i++) { SimpleTypeInformation<?> meta = pack.meta(i); // TODO: aggressively try to match exact metas first? // Try to match unused representations only - for (int j = used.nextClearBit(0); j >= 0 && j < relations.size(); j = used.nextClearBit(j + 1)) { + for(int j = used.nextClearBit(0); j >= 0 && j < relations.size(); j = used.nextClearBit(j + 1)) { Relation<?> relation = relations.get(j); - if (relation.getDataTypeInformation().isAssignableFromType(meta)) { + if(relation.getDataTypeInformation().isAssignableFromType(meta)) { targets[i] = relation; used.set(j); break; } } - if (targets[i] == null) { + if(targets[i] == null) { targets[i] = addNewRelation(meta); used.set(relations.size() - 1); } @@ -229,8 +214,8 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba relations.add(relation); getHierarchy().add(this, relation); // Try to add indexes where appropriate - for (IndexFactory<?, ?> factory : indexFactories) { - if (factory.getInputTypeRestriction().isAssignableFromType(meta)) { + for(IndexFactory<?, ?> factory : indexFactories) { + if(factory.getInputTypeRestriction().isAssignableFromType(meta)) { @SuppressWarnings("unchecked") final IndexFactory<Object, ?> ofact = (IndexFactory<Object, ?>) factory; @SuppressWarnings("unchecked") @@ -254,22 +239,23 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba public MultipleObjectsBundle delete(DBIDs ids) { // Prepare bundle to return MultipleObjectsBundle bundle = new MultipleObjectsBundle(); - for (Relation<?> relation : relations) { + for(Relation<?> relation : relations) { ArrayList<Object> data = new ArrayList<>(ids.size()); - for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { data.add(relation.get(iter)); } bundle.appendColumn(relation.getDataTypeInformation(), data); } // remove from db - for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { doDelete(iter); } // Remove from indexes - for (Index index : indexes) { - if (index instanceof DynamicIndex) { + for(Index index : indexes) { + if(index instanceof DynamicIndex) { ((DynamicIndex) index).deleteAll(ids); - } else { + } + else { LOG.warning("Non-dynamic indexes have been added to the database. Updates are not possible!"); } @@ -290,15 +276,16 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba public SingleObjectBundle delete(DBIDRef id) { // Prepare bundle to return SingleObjectBundle bundle = new SingleObjectBundle(); - for (Relation<?> relation : relations) { + for(Relation<?> relation : relations) { bundle.append(relation.getDataTypeInformation(), relation.get(id)); } doDelete(id); // Remove from indexes - for (Index index : indexes) { - if (index instanceof DynamicIndex) { + for(Index index : indexes) { + if(index instanceof DynamicIndex) { ((DynamicIndex) index).delete(id); - } else { + } + else { LOG.warning("Non-dynamic indexes have been added to the database. Updates are not possible!"); } } @@ -317,9 +304,9 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba // Remove id ids.remove(id); // Remove from all representations. - for (Relation<?> relation : relations) { + for(Relation<?> relation : relations) { // ID has already been removed, and this would loop... - if (relation != idrep) { + if(relation != idrep) { relation.delete(id); } } @@ -354,12 +341,12 @@ public class HashmapDatabase extends AbstractDatabase implements UpdatableDataba super.makeOptions(config); // Get database connection. final ObjectParameter<DatabaseConnection> dbcP = new ObjectParameter<>(DATABASE_CONNECTION_ID, DatabaseConnection.class, FileBasedDatabaseConnection.class); - if (config.grab(dbcP)) { + if(config.grab(dbcP)) { databaseConnection = dbcP.instantiateClass(config); } // Get indexes. final ObjectListParameter<IndexFactory<?, ?>> indexFactoryP = new ObjectListParameter<>(INDEX_ID, IndexFactory.class, true); - if (config.grab(indexFactoryP)) { + if(config.grab(indexFactoryP)) { indexFactories = indexFactoryP.instantiateClasses(config); } } diff --git a/src/de/lmu/ifi/dbs/elki/database/ProxyDatabase.java b/src/de/lmu/ifi/dbs/elki/database/ProxyDatabase.java index a06b7a12..bdcec783 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ProxyDatabase.java +++ b/src/de/lmu/ifi/dbs/elki/database/ProxyDatabase.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/QueryUtil.java b/src/de/lmu/ifi/dbs/elki/database/QueryUtil.java index 44afece1..6ebd870d 100644 --- a/src/de/lmu/ifi/dbs/elki/database/QueryUtil.java +++ b/src/de/lmu/ifi/dbs/elki/database/QueryUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,23 +23,25 @@ package de.lmu.ifi.dbs.elki.database; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter; +import de.lmu.ifi.dbs.elki.database.ids.KNNList; +import de.lmu.ifi.dbs.elki.database.ids.integer.DoubleIntegerDBIDKNNList; import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.database.query.knn.DoubleOptimizedDistanceKNNQuery; import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery; import de.lmu.ifi.dbs.elki.database.query.knn.LinearScanDistanceKNNQuery; +import de.lmu.ifi.dbs.elki.database.query.knn.LinearScanEuclideanDistanceKNNQuery; import de.lmu.ifi.dbs.elki.database.query.knn.LinearScanPrimitiveDistanceKNNQuery; -import de.lmu.ifi.dbs.elki.database.query.range.DoubleOptimizedDistanceRangeQuery; import de.lmu.ifi.dbs.elki.database.query.range.LinearScanDistanceRangeQuery; +import de.lmu.ifi.dbs.elki.database.query.range.LinearScanEuclideanDistanceRangeQuery; import de.lmu.ifi.dbs.elki.database.query.range.LinearScanPrimitiveDistanceRangeQuery; import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery; import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery; import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction; import de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction; /** @@ -63,13 +65,12 @@ public final class QueryUtil { * a relation. * * @param <O> Object type - * @param <D> Distance type * @param database Database * @param distanceFunction Distance function * @param hints Optimizer hints * @return Distance query */ - public static <O, D extends Distance<D>> DistanceQuery<O, D> getDistanceQuery(Database database, DistanceFunction<? super O, D> distanceFunction, Object... hints) { + public static <O> DistanceQuery<O> getDistanceQuery(Database database, DistanceFunction<? super O> distanceFunction, Object... hints) { final Relation<O> objectQuery = database.getRelation(distanceFunction.getInputTypeRestriction(), hints); return database.getDistanceQuery(objectQuery, distanceFunction, hints); } @@ -78,13 +79,12 @@ public final class QueryUtil { * Get a similarity query, automatically choosing a relation. * * @param <O> Object type - * @param <D> Distance type * @param database Database * @param similarityFunction Similarity function * @param hints Optimizer hints * @return Similarity Query */ - public static <O, D extends Distance<D>> SimilarityQuery<O, D> getSimilarityQuery(Database database, SimilarityFunction<? super O, D> similarityFunction, Object... hints) { + public static <O> SimilarityQuery<O> getSimilarityQuery(Database database, SimilarityFunction<? super O> similarityFunction, Object... hints) { final Relation<O> objectQuery = database.getRelation(similarityFunction.getInputTypeRestriction(), hints); return database.getSimilarityQuery(objectQuery, similarityFunction, hints); } @@ -103,15 +103,14 @@ public final class QueryUtil { * </ul> * * @param <O> Object type - * @param <D> Distance type * @param database Database * @param distanceFunction Distance function * @param hints Optimizer hints * @return KNN Query object */ - public static <O, D extends Distance<D>> KNNQuery<O, D> getKNNQuery(Database database, DistanceFunction<? super O, D> distanceFunction, Object... hints) { + public static <O> KNNQuery<O> getKNNQuery(Database database, DistanceFunction<? super O> distanceFunction, Object... hints) { final Relation<O> relation = database.getRelation(distanceFunction.getInputTypeRestriction(), hints); - final DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints); + final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints); return database.getKNNQuery(distanceQuery, hints); } @@ -133,12 +132,11 @@ public final class QueryUtil { * @param hints Optimizer hints * * @param <O> Object type - * @param <D> Distance type * @return KNN Query object */ - public static <O, D extends Distance<D>> KNNQuery<O, D> getKNNQuery(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, Object... hints) { + public static <O> KNNQuery<O> getKNNQuery(Relation<O> relation, DistanceFunction<? super O> distanceFunction, Object... hints) { final Database database = relation.getDatabase(); - final DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints); + final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints); return database.getKNNQuery(distanceQuery, hints); } @@ -156,15 +154,14 @@ public final class QueryUtil { * </ul> * * @param <O> Object type - * @param <D> Distance type * @param database Database * @param distanceFunction Distance function * @param hints Optimizer hints * @return KNN Query object */ - public static <O, D extends Distance<D>> RangeQuery<O, D> getRangeQuery(Database database, DistanceFunction<? super O, D> distanceFunction, Object... hints) { + public static <O> RangeQuery<O> getRangeQuery(Database database, DistanceFunction<? super O> distanceFunction, Object... hints) { final Relation<O> relation = database.getRelation(distanceFunction.getInputTypeRestriction(), hints); - final DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints); + final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints); return database.getRangeQuery(distanceQuery, hints); } @@ -186,12 +183,11 @@ public final class QueryUtil { * @param hints Optimizer hints * * @param <O> Object type - * @param <D> Distance type * @return KNN Query object */ - public static <O, D extends Distance<D>> RangeQuery<O, D> getRangeQuery(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, Object... hints) { + public static <O> RangeQuery<O> getRangeQuery(Relation<O> relation, DistanceFunction<? super O> distanceFunction, Object... hints) { final Database database = relation.getDatabase(); - final DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints); + final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints); return database.getRangeQuery(distanceQuery, hints); } @@ -213,12 +209,11 @@ public final class QueryUtil { * @param hints Optimizer hints * * @param <O> Object type - * @param <D> Distance type * @return RKNN Query object */ - public static <O, D extends Distance<D>> RKNNQuery<O, D> getRKNNQuery(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, Object... hints) { + public static <O> RKNNQuery<O> getRKNNQuery(Relation<O> relation, DistanceFunction<? super O> distanceFunction, Object... hints) { final Database database = relation.getDatabase(); - final DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints); + final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distanceFunction, hints); return database.getRKNNQuery(distanceQuery, hints); } @@ -226,25 +221,19 @@ public final class QueryUtil { * Get a linear scan query for the given distance query. * * @param <O> Object type - * @param <D> Distance type * @param distanceQuery distance query * @return KNN query */ - public static <O, D extends Distance<D>> KNNQuery<O, D> getLinearScanKNNQuery(DistanceQuery<O, D> distanceQuery) { + @SuppressWarnings("unchecked") + public static <O> KNNQuery<O> getLinearScanKNNQuery(DistanceQuery<O> distanceQuery) { // Slight optimizations of linear scans if(distanceQuery instanceof PrimitiveDistanceQuery) { - if(distanceQuery.getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction) { - final PrimitiveDistanceQuery<O, ?> pdq = (PrimitiveDistanceQuery<O, ?>) distanceQuery; - @SuppressWarnings("unchecked") - final KNNQuery<O, ?> knnQuery = new DoubleOptimizedDistanceKNNQuery<>((PrimitiveDistanceQuery<O, DoubleDistance>) pdq); - @SuppressWarnings("unchecked") - final KNNQuery<O, D> castQuery = (KNNQuery<O, D>) knnQuery; - return castQuery; - } - else { - final PrimitiveDistanceQuery<O, D> pdq = (PrimitiveDistanceQuery<O, D>) distanceQuery; - return new LinearScanPrimitiveDistanceKNNQuery<>(pdq); + final PrimitiveDistanceQuery<O> pdq = (PrimitiveDistanceQuery<O>) distanceQuery; + if (EuclideanDistanceFunction.STATIC.equals(pdq.getDistanceFunction())) { + final PrimitiveDistanceQuery<NumberVector> ndq = (PrimitiveDistanceQuery<NumberVector>)pdq; + return (KNNQuery<O>) new LinearScanEuclideanDistanceKNNQuery<>(ndq); } + return new LinearScanPrimitiveDistanceKNNQuery<>(pdq); } return new LinearScanDistanceKNNQuery<>(distanceQuery); } @@ -253,26 +242,34 @@ public final class QueryUtil { * Get a linear scan query for the given distance query. * * @param <O> Object type - * @param <D> Distance type * @param distanceQuery distance query * @return Range query */ - public static <O, D extends Distance<D>> RangeQuery<O, D> getLinearScanRangeQuery(DistanceQuery<O, D> distanceQuery) { + @SuppressWarnings("unchecked") + public static <O> RangeQuery<O> getLinearScanRangeQuery(DistanceQuery<O> distanceQuery) { // Slight optimizations of linear scans if(distanceQuery instanceof PrimitiveDistanceQuery) { - if(distanceQuery.getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction) { - final PrimitiveDistanceQuery<O, ?> pdq = (PrimitiveDistanceQuery<O, ?>) distanceQuery; - @SuppressWarnings("unchecked") - final RangeQuery<O, ?> knnQuery = new DoubleOptimizedDistanceRangeQuery<>((PrimitiveDistanceQuery<O, DoubleDistance>) pdq); - @SuppressWarnings("unchecked") - final RangeQuery<O, D> castQuery = (RangeQuery<O, D>) knnQuery; - return castQuery; - } - else { - final PrimitiveDistanceQuery<O, D> pdq = (PrimitiveDistanceQuery<O, D>) distanceQuery; - return new LinearScanPrimitiveDistanceRangeQuery<>(pdq); + final PrimitiveDistanceQuery<O> pdq = (PrimitiveDistanceQuery<O>) distanceQuery; + if (EuclideanDistanceFunction.STATIC.equals(pdq.getDistanceFunction())) { + final PrimitiveDistanceQuery<NumberVector> ndq = (PrimitiveDistanceQuery<NumberVector>)pdq; + return (RangeQuery<O>) new LinearScanEuclideanDistanceRangeQuery<>(ndq); } + return new LinearScanPrimitiveDistanceRangeQuery<>(pdq); } return new LinearScanDistanceRangeQuery<>(distanceQuery); } + + /** + * Apply the square root function to each value in the list. + * + * @param knnList kNN list + * @return new list, after taking the square root + */ + public static KNNList applySqrt(KNNList knnList) { + DoubleIntegerDBIDKNNList ret = new DoubleIntegerDBIDKNNList(knnList.getK(), knnList.size()); + for(DoubleDBIDListIter iter = knnList.iter(); iter.valid(); iter.advance()) { + ret.add(Math.sqrt(iter.doubleValue()), iter); + } + return ret; + } } diff --git a/src/de/lmu/ifi/dbs/elki/database/StaticArrayDatabase.java b/src/de/lmu/ifi/dbs/elki/database/StaticArrayDatabase.java index 2fc4a5bb..8b34583f 100644 --- a/src/de/lmu/ifi/dbs/elki/database/StaticArrayDatabase.java +++ b/src/de/lmu/ifi/dbs/elki/database/StaticArrayDatabase.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,12 +27,10 @@ import java.util.BitSet; import java.util.Collection; import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; -import de.lmu.ifi.dbs.elki.data.type.TypeUtil; -import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; -import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs; -import de.lmu.ifi.dbs.elki.database.ids.DBID; +import de.lmu.ifi.dbs.elki.database.ids.ArrayStaticDBIDs; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; +import de.lmu.ifi.dbs.elki.database.ids.DBIDs; import de.lmu.ifi.dbs.elki.database.relation.DBIDView; import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation; import de.lmu.ifi.dbs.elki.database.relation.Relation; @@ -45,7 +43,6 @@ import de.lmu.ifi.dbs.elki.index.IndexFactory; import de.lmu.ifi.dbs.elki.logging.Logging; import de.lmu.ifi.dbs.elki.logging.statistics.Duration; import de.lmu.ifi.dbs.elki.utilities.documentation.Description; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParameter; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; @@ -63,7 +60,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; * @apiviz.uses DatabaseConnection */ @Description("Database using an in-memory hashtable and at least providing linear scans.") -public class StaticArrayDatabase extends AbstractDatabase implements Parameterizable { +public class StaticArrayDatabase extends AbstractDatabase { /** * Our logger */ @@ -72,7 +69,7 @@ public class StaticArrayDatabase extends AbstractDatabase implements Parameteriz /** * IDs of this database */ - private ArrayDBIDs ids; + private ArrayStaticDBIDs ids; /** * The DBID representation we use @@ -123,26 +120,22 @@ public class StaticArrayDatabase extends AbstractDatabase implements Parameteriz // Run at most once. databaseConnection = null; - // Find DBID column - int idrepnr = findDBIDColumn(objpackages); - // Build DBID array - final int numObjects = objpackages.dataLength(); - if(LOG.isDebugging()) { - LOG.debugFine("Importing " + numObjects + " instances."); - } - if(idrepnr == -1) { - this.ids = DBIDUtil.generateStaticDBIDRange(numObjects); - } - else { - final ArrayModifiableDBIDs newids = DBIDUtil.newArray(numObjects); - for(int j = 0; j < numObjects; j++) { - DBID newid = (DBID) objpackages.data(j, idrepnr); - newids.add(newid); + // Find DBIDs for bundle + int numObjects = objpackages.dataLength(); + { + DBIDs bids = objpackages.getDBIDs(); + if(bids instanceof ArrayStaticDBIDs) { + this.ids = (ArrayStaticDBIDs) bids; + } + else if(bids == null) { + this.ids = DBIDUtil.generateStaticDBIDRange(objpackages.dataLength()); + } + else { + this.ids = (ArrayStaticDBIDs) DBIDUtil.makeUnmodifiable(bids); } - this.ids = newids; } - // Replace id representation. - // TODO: this is an ugly hack + // Replace id representation (it would be nicer if we would not need + // DBIDView at all) this.idrep = new DBIDView(this, this.ids); relations.add(this.idrep); getHierarchy().add(this, idrep); @@ -154,10 +147,6 @@ public class StaticArrayDatabase extends AbstractDatabase implements Parameteriz for(int j = 0; j < numObjects; j++, newid.advance()) { // insert object for(int i = 0; i < targets.length; i++) { - // DBIDs were handled above. - if(i == idrepnr) { - continue; - } @SuppressWarnings("unchecked") final Relation<Object> relation = (Relation<Object>) targets[i]; relation.set(newid, objpackages.data(j, i)); @@ -174,14 +163,10 @@ public class StaticArrayDatabase extends AbstractDatabase implements Parameteriz @SuppressWarnings("unchecked") final Relation<Object> orep = (Relation<Object>) relation; final Index index = ofact.instantiate(orep); - Duration duration = LOG.isStatistics() ? LOG.newDuration(index.getClass().getName() + ".construction") : null; - if(duration != null) { - duration.begin(); - } + Duration duration = LOG.isStatistics() ? LOG.newDuration(index.getClass().getName() + ".construction").begin() : null; index.initialize(); if(duration != null) { - duration.end(); - LOG.statistics(duration); + LOG.statistics(duration.end()); } addIndex(index); } @@ -204,22 +189,6 @@ public class StaticArrayDatabase extends AbstractDatabase implements Parameteriz } /** - * Find an DBID column. - * - * @param pack Package to process - * @return DBID column - */ - protected int findDBIDColumn(ObjectBundle pack) { - for(int i = 0; i < pack.metaLength(); i++) { - SimpleTypeInformation<?> meta = pack.meta(i); - if(TypeUtil.DBID.isAssignableFromType(meta)) { - return i; - } - } - return -1; - } - - /** * Find a mapping from package columns to database columns, eventually adding * new database columns when needed. * diff --git a/src/de/lmu/ifi/dbs/elki/database/UpdatableDatabase.java b/src/de/lmu/ifi/dbs/elki/database/UpdatableDatabase.java index f22dd799..b7ae2d0a 100644 --- a/src/de/lmu/ifi/dbs/elki/database/UpdatableDatabase.java +++ b/src/de/lmu/ifi/dbs/elki/database/UpdatableDatabase.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -41,9 +41,8 @@ public interface UpdatableDatabase extends Database { * * @param objpackages the objects to be inserted * @return the IDs assigned to the inserted objects - * @throws UnableToComplyException if insertion is not possible */ - DBIDs insert(ObjectBundle objpackages) throws UnableToComplyException; + DBIDs insert(ObjectBundle objpackages); /** * Removes and returns the specified objects with the given ids from the diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/DBIDDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DBIDDataStore.java index 8c0eb2cb..8100fb66 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/DBIDDataStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DBIDDataStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStore.java index 384680c6..368488f2 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreEvent.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreEvent.java index 7942fb9b..5b374a4e 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreEvent.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreEvent.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreFactory.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreFactory.java index 7b3cd0e7..2695f51f 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreFactory.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreFactory.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -34,8 +34,11 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDs; * @author Erich Schubert * * @apiviz.stereotype factory,interface - * @apiviz.uses WritableDataStore oneway - - «create» - * @apiviz.uses WritableRecordStore oneway - - «create» + * @apiviz.has WritableDataStore oneway - - «create» + * @apiviz.has WritableIntegerDataStore oneway - - «create» + * @apiviz.has WritableDoubleDataStore oneway - - «create» + * @apiviz.has WritableDBIDDataStore oneway - - «create» + * @apiviz.has WritableRecordStore oneway - - «create» */ public interface DataStoreFactory { /** diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreIDMap.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreIDMap.java index adfd1354..215c660f 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreIDMap.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreIDMap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreListener.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreListener.java index a3f1319d..e437af78 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreListener.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreListener.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreUtil.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreUtil.java index 6d0c2d0f..5369dda9 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreUtil.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DataStoreUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,8 +23,10 @@ package de.lmu.ifi.dbs.elki.database.datastore; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import java.util.Comparator; + +import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; /** * Storage utility class. Mostly a shorthand for @@ -126,15 +128,60 @@ public final class DataStoreUtil { } /** - * Make a new storage, to associate the given ids with an double valued - * distance. + * Sort objects by a double relation * - * @param ids DBIDs to store data for - * @param hints Hints for the storage manager - * @return new data store + * @author Erich Schubert + * + * @apiviz.exclude */ - public static WritableDoubleDistanceDataStore makeDoubleDistanceStorage(DBIDs ids, int hints) { - // FIXME: this is an ugly work-around. - return (WritableDoubleDistanceDataStore) DataStoreFactory.FACTORY.makeStorage(ids, hints, DoubleDistance.class); + public static class AscendingByDoubleDataStore implements Comparator<DBIDRef> { + /** + * Scores to use for sorting. + */ + private final DoubleDataStore scores; + + /** + * Constructor. + * + * @param scores Scores for sorting + */ + public AscendingByDoubleDataStore(DoubleDataStore scores) { + super(); + this.scores = scores; + } + + @Override + public int compare(DBIDRef id1, DBIDRef id2) { + return Double.compare(scores.doubleValue(id1), scores.doubleValue(id2)); + } + } + + /** + * Sort objects by a double relation + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class DescendingByDoubleDataStore implements Comparator<DBIDRef> { + /** + * Scores to use for sorting. + */ + private final DoubleDataStore scores; + + /** + * Constructor. + * + * @param scores Scores for sorting + */ + public DescendingByDoubleDataStore(DoubleDataStore scores) { + super(); + this.scores = scores; + } + + @Override + public int compare(DBIDRef id1, DBIDRef id2) { + return Double.compare(scores.doubleValue(id2), scores.doubleValue(id1)); + } } } diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/DoubleDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/DoubleDataStore.java index b121d195..0995d40a 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/DoubleDataStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/DoubleDataStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/IntegerDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/IntegerDataStore.java index 969e2228..45b5f43c 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/IntegerDataStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/IntegerDataStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/RecordStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/RecordStore.java index 07bf2dcf..e7f6adc1 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/RecordStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/RecordStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDBIDDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDBIDDataStore.java index bae55a57..d7bf02bc 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDBIDDataStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDBIDDataStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDataStore.java index c62fc721..c746eda3 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDataStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDataStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDataStore.java index a40f0ef4..7755d0de 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDataStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDataStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -61,4 +61,18 @@ public interface WritableDoubleDataStore extends DoubleDataStore, WritableDataSt * @return previous value */ public double put(DBIDRef id, double value); + + + /** + * Increment the specified value with the specified id in this storage. + * + * @param id Database ID. + * @param value Value to add to the previous value. + */ + public void increment(DBIDRef id, double value); + + /** + * Reinitialize (reset to default value). + */ + public void clear(); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDistanceDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDistanceDataStore.java deleted file mode 100644 index f929d5d7..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableDoubleDistanceDataStore.java +++ /dev/null @@ -1,65 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.datastore; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Data store specialized for doubles. Avoids boxing/unboxing. - * - * @author Erich Schubert - */ -public interface WritableDoubleDistanceDataStore extends DoubleDistanceDataStore, WritableDataStore<DoubleDistance> { - /** - * Setter, but using objects. - * - * @deprecated Use {@link #putDouble} instead, to avoid boxing/unboxing cost. - */ - @Override - @Deprecated - public DoubleDistance put(DBIDRef id, DoubleDistance value); - - /** - * Associates the specified value with the specified id in this storage. If - * the storage previously contained a value for the id, the previous value is - * replaced by the specified value. - * - * @param id Database ID. - * @param value Value to store. - * @return previous value - */ - public double putDouble(DBIDRef id, double value); - - /** - * Associates the specified value with the specified id in this storage. If - * the storage previously contained a value for the id, the previous value is - * replaced by the specified value. - * - * @param id Database ID. - * @param value Value to store. - * @return previous value - */ - public double put(DBIDRef id, double value); -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableIntegerDataStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableIntegerDataStore.java index fb323b02..2c0e61e9 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableIntegerDataStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableIntegerDataStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableRecordStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableRecordStore.java index c4c182e9..8d0c58fd 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/WritableRecordStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/WritableRecordStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDBIDStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDBIDStore.java index 78cb51d2..2134c75a 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDBIDStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDBIDStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleDistanceStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleDistanceStore.java deleted file mode 100644 index abb81d95..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleDistanceStore.java +++ /dev/null @@ -1,133 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.datastore.memory; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import java.util.Arrays; - -import de.lmu.ifi.dbs.elki.database.datastore.DataStoreIDMap; -import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDistanceDataStore; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * A class to answer representation queries using the stored Array. - * - * @author Erich Schubert - * - * @apiviz.composedOf de.lmu.ifi.dbs.elki.database.datastore.DataStoreIDMap - */ -public class ArrayDoubleDistanceStore implements WritableDoubleDistanceDataStore { - /** - * Data array - */ - private double[] data; - - /** - * DBID to index map - */ - private DataStoreIDMap idmap; - - /** - * Constructor. - * - * @param size Size - * @param idmap ID map - */ - public ArrayDoubleDistanceStore(int size, DataStoreIDMap idmap) { - this(size, idmap, Double.NaN); - } - - /** - * Constructor. - * - * @param size Size - * @param idmap ID map - * @param def Default value - */ - public ArrayDoubleDistanceStore(int size, DataStoreIDMap idmap, double def) { - super(); - this.data = new double[size]; - if (def != 0) { - Arrays.fill(this.data, def); - } - this.idmap = idmap; - } - - @Override - @Deprecated - public DoubleDistance get(DBIDRef id) { - return new DoubleDistance(data[idmap.mapDBIDToOffset(id)]); - } - - @Override - @Deprecated - public DoubleDistance put(DBIDRef id, DoubleDistance value) { - final int off = idmap.mapDBIDToOffset(id); - double ret = data[off]; - data[off] = value.doubleValue(); - return new DoubleDistance(ret); - } - - @Override - public double doubleValue(DBIDRef id) { - return data[idmap.mapDBIDToOffset(id)]; - } - - @Override - public double putDouble(DBIDRef id, double value) { - final int off = idmap.mapDBIDToOffset(id); - final double ret = data[off]; - data[off] = value; - return ret; - } - - @Override - public double put(DBIDRef id, double value) { - final int off = idmap.mapDBIDToOffset(id); - final double ret = data[off]; - data[off] = value; - return ret; - } - - @Override - public void destroy() { - data = null; - idmap = null; - } - - @Override - public void delete(DBIDRef id) { - throw new UnsupportedOperationException("Can't delete from a static array storage."); - } - - @Override - public String getLongName() { - return "raw"; - } - - @Override - public String getShortName() { - return "raw"; - } -} diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleStore.java index c41991eb..8b2ec127 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayDoubleStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -41,6 +41,11 @@ public class ArrayDoubleStore implements WritableDoubleDataStore { * Data array */ private double[] data; + + /** + * Default value. + */ + private double def; /** * DBID to index map @@ -67,9 +72,10 @@ public class ArrayDoubleStore implements WritableDoubleDataStore { public ArrayDoubleStore(int size, DataStoreIDMap idmap, double def) { super(); this.data = new double[size]; - if (def != 0) { + if(def != 0) { Arrays.fill(this.data, def); } + this.def = def; this.idmap = idmap; } @@ -110,6 +116,16 @@ public class ArrayDoubleStore implements WritableDoubleDataStore { } @Override + public void increment(DBIDRef id, double value) { + data[idmap.mapDBIDToOffset(id)] += value; + } + + @Override + public void clear() { + Arrays.fill(data, def); + } + + @Override public void destroy() { data = null; idmap = null; diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayIntegerStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayIntegerStore.java index b8a76646..29541065 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayIntegerStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayIntegerStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayRecordStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayRecordStore.java index e9c78cb7..2fac747f 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayRecordStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayRecordStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayStore.java index 695ddc48..b0e5add8 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/ArrayStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDBIDStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDBIDStore.java index 9b8a4be8..ed60cf0a 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDBIDStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDBIDStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -50,7 +50,7 @@ public class MapIntegerDBIDDBIDStore implements WritableDBIDDataStore { */ public MapIntegerDBIDDBIDStore(int size) { super(); - map = new TIntIntHashMap(size, 0.5f, Integer.MIN_VALUE, DBIDUtil.invalid().internalGetIndex()); + map = new TIntIntHashMap(size, 0.5f, Integer.MIN_VALUE, DBIDUtil.asInteger(DBIDUtil.invalid())); } @Override @@ -72,7 +72,7 @@ public class MapIntegerDBIDDBIDStore implements WritableDBIDDataStore { @Override @Deprecated public DBID put(DBIDRef id, DBID value) { - return DBIDUtil.importInteger(map.put(id.internalGetIndex(), value.internalGetIndex())); + return DBIDUtil.importInteger(map.put(DBIDUtil.asInteger(id), DBIDUtil.asInteger(value))); } @Override @@ -88,17 +88,17 @@ public class MapIntegerDBIDDBIDStore implements WritableDBIDDataStore { @Override public void put(DBIDRef id, DBIDRef value) { - map.put(id.internalGetIndex(), value.internalGetIndex()); + map.put(DBIDUtil.asInteger(id), DBIDUtil.asInteger(value)); } @Override public void putDBID(DBIDRef id, DBIDRef value) { - map.put(id.internalGetIndex(), value.internalGetIndex()); + map.put(DBIDUtil.asInteger(id), DBIDUtil.asInteger(value)); } @Override public void assignVar(DBIDRef id, DBIDVar var) { - final int val = map.get(id.internalGetIndex()); + final int val = map.get(DBIDUtil.asInteger(id)); DBIDFactory.FACTORY.assignVar(var, val); } } diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleDistanceStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleDistanceStore.java deleted file mode 100644 index be12b54c..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleDistanceStore.java +++ /dev/null @@ -1,111 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.datastore.memory; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import gnu.trove.map.TIntDoubleMap; -import gnu.trove.map.hash.TIntDoubleHashMap; -import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDistanceDataStore; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Writable data store for double values. - * - * @author Erich Schubert - */ -public class MapIntegerDBIDDoubleDistanceStore implements WritableDoubleDistanceDataStore { - /** - * Data storage. - */ - private TIntDoubleMap map; - - /** - * Constructor. - * - * @param size Expected size - */ - public MapIntegerDBIDDoubleDistanceStore(int size) { - this(size, Double.NaN); - } - - /** - * Constructor. - * - * @param size Expected size - * @param def Default value - */ - public MapIntegerDBIDDoubleDistanceStore(int size, double def) { - super(); - map = new TIntDoubleHashMap(size, 0.5f, Integer.MIN_VALUE, def); - } - - @Override - @Deprecated - public DoubleDistance get(DBIDRef id) { - return new DoubleDistance(map.get(DBIDUtil.asInteger(id))); - } - - @Override - public double doubleValue(DBIDRef id) { - return map.get(DBIDUtil.asInteger(id)); - } - - @Override - public String getLongName() { - return "raw"; - } - - @Override - public String getShortName() { - return "raw"; - } - - @Override - @Deprecated - public DoubleDistance put(DBIDRef id, DoubleDistance value) { - return new DoubleDistance(map.put(DBIDUtil.asInteger(id), value.doubleValue())); - } - - @Override - public void destroy() { - map.clear(); - map = null; - } - - @Override - public void delete(DBIDRef id) { - map.remove(DBIDUtil.asInteger(id)); - } - - @Override - public double putDouble(DBIDRef id, double value) { - return map.put(DBIDUtil.asInteger(id), value); - } - - @Override - public double put(DBIDRef id, double value) { - return map.put(DBIDUtil.asInteger(id), value); - } -} diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleStore.java index 8d73b672..8779eb46 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDDoubleStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -88,12 +88,6 @@ public class MapIntegerDBIDDoubleStore implements WritableDoubleDataStore { } @Override - public void destroy() { - map.clear(); - map = null; - } - - @Override public void delete(DBIDRef id) { map.remove(DBIDUtil.asInteger(id)); } @@ -107,4 +101,20 @@ public class MapIntegerDBIDDoubleStore implements WritableDoubleDataStore { public double put(DBIDRef id, double value) { return map.put(DBIDUtil.asInteger(id), value); } + + @Override + public void increment(DBIDRef id, double value) { + map.adjustOrPutValue(DBIDUtil.asInteger(id), value, map.getNoEntryValue() + value); + } + + @Override + public void clear() { + map.clear(); + } + + @Override + public void destroy() { + map.clear(); + map = null; + } } diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDIntegerStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDIntegerStore.java index 935f23f4..2f2a42a2 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDIntegerStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDIntegerStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDRecordStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDRecordStore.java index 9efe2221..7963b78c 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDRecordStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDRecordStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDStore.java index ede82f15..55402703 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapIntegerDBIDStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapRecordStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapRecordStore.java index 045d5bf4..6b5b1a50 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapRecordStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapRecordStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapStore.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapStore.java index c40e0a72..3432e124 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MapStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MemoryDataStoreFactory.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MemoryDataStoreFactory.java index 2a6cd1cb..2ad2dd05 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MemoryDataStoreFactory.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/MemoryDataStoreFactory.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.datastore.memory; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,12 +27,10 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory; import de.lmu.ifi.dbs.elki.database.datastore.WritableDBIDDataStore; import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore; import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore; -import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDistanceDataStore; import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore; import de.lmu.ifi.dbs.elki.database.datastore.WritableRecordStore; import de.lmu.ifi.dbs.elki.database.ids.DBIDRange; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; /** * Simple factory class that will store all data in memory using object arrays @@ -44,18 +42,15 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; * @author Erich Schubert * * @apiviz.stereotype factory - * @apiviz.uses ArrayStore oneway - - «create» - * @apiviz.uses ArrayRecordStore oneway - - «create» - * @apiviz.uses MapStore oneway - - «create» - * @apiviz.uses MapRecordStore oneway - - «create» + * @apiviz.has ArrayStore oneway - - «create» + * @apiviz.has ArrayRecordStore oneway - - «create» + * @apiviz.has MapStore oneway - - «create» + * @apiviz.has MapRecordStore oneway - - «create» */ public class MemoryDataStoreFactory implements DataStoreFactory { @SuppressWarnings("unchecked") @Override public <T> WritableDataStore<T> makeStorage(DBIDs ids, int hints, Class<? super T> dataclass) { - if (DoubleDistance.class.equals(dataclass)) { - return (WritableDataStore<T>) makeDoubleDistanceStorage(ids, hints); - } if (Double.class.equals(dataclass)) { return (WritableDataStore<T>) makeDoubleStorage(ids, hints); } @@ -83,23 +78,6 @@ public class MemoryDataStoreFactory implements DataStoreFactory { } } - /** - * Make a data storage for double distances. - * - * @param ids IDs to store for - * @param hints Storage hints - * @return double distance storage - */ - public WritableDoubleDistanceDataStore makeDoubleDistanceStorage(DBIDs ids, int hints) { - if(ids instanceof DBIDRange) { - DBIDRange range = (DBIDRange) ids; - return new ArrayDoubleDistanceStore(range.size(), range); - } - else { - return new MapIntegerDBIDDoubleDistanceStore(ids.size()); - } - } - @Override public WritableDoubleDataStore makeDoubleStorage(DBIDs ids, int hints) { if(ids instanceof DBIDRange) { @@ -155,4 +133,4 @@ public class MemoryDataStoreFactory implements DataStoreFactory { return new MapIntegerDBIDRecordStore(ids.size(), dataclasses.length); } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/package-info.java b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/package-info.java index 5ea46015..dada2a9b 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/memory/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/memory/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/package-info.java b/src/de/lmu/ifi/dbs/elki/database/datastore/package-info.java index f213019d..aa15d1c2 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/database/datastore/package-info.java @@ -24,7 +24,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/ArrayDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/ArrayDBIDs.java index 5839a2e0..3cca1242 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/ArrayDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/ArrayDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/ArrayModifiableDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/ArrayModifiableDBIDs.java index 3db40630..0554a0e2 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/ArrayModifiableDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/ArrayModifiableDBIDs.java @@ -6,7 +6,7 @@ import java.util.Comparator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/ArrayStaticDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/ArrayStaticDBIDs.java index 47cf295f..6328f375 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/ArrayStaticDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/ArrayStaticDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBID.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBID.java index a773ee27..c46b13bd 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/DBID.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBID.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayIter.java index ef1132b3..c5cf171a 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayIter.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayIter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -30,5 +30,15 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.ArrayIter; * @author Erich Schubert */ public interface DBIDArrayIter extends DBIDIter, ArrayIter { - // Nothing added - see {@link ArrayIter}! + @Override + DBIDArrayIter advance(); + + @Override + DBIDArrayIter advance(int count); + + @Override + DBIDArrayIter retract(); + + @Override + DBIDArrayIter seek(int off); } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayMIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayMIter.java index 1aaefc8e..9700de1b 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayMIter.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDArrayMIter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDFactory.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDFactory.java index 1b269eea..58cf5791 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDFactory.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDFactory.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,15 +23,9 @@ package de.lmu.ifi.dbs.elki.database.ids; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList; import de.lmu.ifi.dbs.elki.database.ids.integer.TrivialDBIDFactory; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer; -import de.lmu.ifi.dbs.elki.persistent.FixedSizeByteBufferSerializer; +import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer; +import de.lmu.ifi.dbs.elki.utilities.io.FixedSizeByteBufferSerializer; /** * Factory interface for generating DBIDs. See {@link #FACTORY} for the static @@ -106,6 +100,15 @@ public interface DBIDFactory { DBIDRange generateStaticDBIDRange(int size); /** + * Generate a static DBID range. + * + * @param begin Range begin + * @param size Requested size + * @return DBID range + */ + DBIDRange generateStaticDBIDRange(int begin, int size); + + /** * Deallocate a static DBID range. * * @param range Range to deallocate @@ -132,25 +135,6 @@ public interface DBIDFactory { DoubleDBIDPair newPair(double val, DBIDRef id); /** - * Make a new distance-DBID pair. - * - * @param val Distance value - * @param id Object ID - * @param <D> Distance type - * @return New pair - */ - <D extends Distance<D>> DistanceDBIDPair<D> newDistancePair(D val, DBIDRef id); - - /** - * Make a new distance-DBID pair. - * - * @param val Distance value - * @param id Object ID - * @return New pair - */ - DoubleDistanceDBIDPair newDistancePair(double val, DBIDRef id); - - /** * Make a new (modifiable) array of DBIDs. * * @return New array @@ -197,33 +181,20 @@ public interface DBIDFactory { HashSetModifiableDBIDs newHashSet(DBIDs existing); /** - * Create an appropriate heap for the distance function. - * - * This will use a double heap if appropriate. + * Create an heap for kNN search. * - * @param factory distance prototype * @param k K value - * @param <D> distance type - * @return New heap of size k, appropriate for this distance type. + * @return New heap of size k. */ - <D extends Distance<D>> KNNHeap<D> newHeap(D factory, int k); + KNNHeap newHeap(int k); /** * Build a new heap from a given list. * * @param exist Existing result - * @param <D> Distance type * @return New heap */ - <D extends Distance<D>> KNNHeap<D> newHeap(KNNList<D> exist); - - /** - * Create an appropriate heap for double distances. - * - * @param k K value - * @return New heap of size k, appropriate for this distance type. - */ - DoubleDistanceKNNHeap newDoubleDistanceHeap(int k); + KNNHeap newHeap(KNNList exist); /** * Get a serializer for DBIDs. @@ -278,4 +249,19 @@ public interface DBIDFactory { * @return Invalid value */ DBIDRef invalid(); + + /** + * Create a modifiable list to store distance-DBID pairs. + * + * @param size initial size estimate + * @return New list of given initial size + */ + ModifiableDoubleDBIDList newDistanceDBIDList(int size); + + /** + * Create a modifiable list to store distance-DBID pairs. + * + * @return New list + */ + ModifiableDoubleDBIDList newDistanceDBIDList(); } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDIter.java index f051d51c..0c1bedba 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDIter.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDIter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -54,9 +54,10 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter; * </ul> * * @author Erich Schubert - * + * * @apiviz.landmark */ public interface DBIDIter extends DBIDRef, Iter { - // Empty - use as DBIDRef or Iter + @Override + DBIDIter advance(); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDMIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDMIter.java index 0fbed7e0..8778a5a3 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDMIter.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDMIter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDPair.java index bdbbe2da..f8bcfb88 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDPair.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDPair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,8 +23,6 @@ package de.lmu.ifi.dbs.elki.database.ids; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.utilities.pairs.PairInterface; - /** * Immutable pair of two DBIDs. This can be stored more efficiently than when * using {@link de.lmu.ifi.dbs.elki.utilities.pairs.Pair} @@ -33,21 +31,24 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.PairInterface; * * @apiviz.composedOf de.lmu.ifi.dbs.elki.database.ids.DBID */ -// TODO: implement DBIDs? -public interface DBIDPair extends PairInterface<DBID, DBID> { +public interface DBIDPair extends DBIDs { /** - * Getter for first + * Getter for first. * * @return first element in pair + * @deprecated This method can be expensive. The use of a {@link DBIDVar} is + * recommended when many such accesses are needed. */ - @Override + @Deprecated public DBID getFirst(); /** * Getter for second element in pair * * @return second element in pair + * @deprecated This method can be expensive. The use of a {@link DBIDVar} is + * recommended when many such accesses are needed. */ - @Override + @Deprecated public DBID getSecond(); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRange.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRange.java index 588cfe6a..1bd2d0d1 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRange.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRange.java @@ -1,12 +1,10 @@ package de.lmu.ifi.dbs.elki.database.ids; -import de.lmu.ifi.dbs.elki.database.datastore.DataStoreIDMap; - /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,6 +23,8 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreIDMap; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import de.lmu.ifi.dbs.elki.database.datastore.DataStoreIDMap; + /** * Static DBID range. * @@ -35,7 +35,7 @@ public interface DBIDRange extends ArrayStaticDBIDs, DataStoreIDMap { * Get offset in the array for a particular DBID. * * Should satisfy {@code range.get(getOffset(id)) == id} and - * {@code range.getOffset(range.get(idx)) == idx}. + * {@code range.getOffset(range.get(idx)) == idx}. * * @param dbid ID to compute index for * @return index diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRef.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRef.java index 77cc621e..8d7ee6b3 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRef.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDRef.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDUtil.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDUtil.java index c60e63ae..9c39fc77 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDUtil.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,24 +25,19 @@ package de.lmu.ifi.dbs.elki.database.ids; import java.util.Random; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList; -import de.lmu.ifi.dbs.elki.database.ids.generic.DoubleDistanceKNNSubList; import de.lmu.ifi.dbs.elki.database.ids.generic.KNNSubList; import de.lmu.ifi.dbs.elki.database.ids.generic.UnmodifiableArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.generic.UnmodifiableDBIDs; import de.lmu.ifi.dbs.elki.database.ids.integer.IntegerArrayDBIDs; +import de.lmu.ifi.dbs.elki.database.ids.integer.IntegerDBIDKNNList; +import de.lmu.ifi.dbs.elki.database.ids.integer.IntegerDBIDKNNSubList; import de.lmu.ifi.dbs.elki.database.ids.integer.IntegerDBIDs; import de.lmu.ifi.dbs.elki.database.ids.integer.UnmodifiableIntegerArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.integer.UnmodifiableIntegerDBIDs; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer; -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; -import de.lmu.ifi.dbs.elki.utilities.UnsafeRandom; +import de.lmu.ifi.dbs.elki.math.random.FastNonThreadsafeRandom; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; +import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; +import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer; /** * DBID Utility functions. @@ -51,9 +46,8 @@ import de.lmu.ifi.dbs.elki.utilities.UnsafeRandom; * * @apiviz.landmark * - * @apiviz.has DBID * @apiviz.has DBIDs - * @apiviz.uses DBIDRef + * @apiviz.has DBIDRef * @apiviz.composedOf DBIDFactory */ public final class DBIDUtil { @@ -131,7 +125,7 @@ public final class DBIDUtil { * @return DBID */ public static DBID deref(DBIDRef ref) { - if (ref instanceof DBID) { + if(ref instanceof DBID) { return (DBID) ref; } return importInteger(ref.internalGetIndex()); @@ -154,12 +148,12 @@ public final class DBIDUtil { * @return String representation */ public static String toString(DBIDs ids) { - if (ids instanceof DBID) { + if(ids instanceof DBID) { return DBIDFactory.FACTORY.toString((DBID) ids); } StringBuilder buf = new StringBuilder(); - for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { - if (buf.length() > 0) { + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + if(buf.length() > 0) { buf.append(", "); } buf.append(DBIDFactory.FACTORY.toString(iter)); @@ -308,12 +302,12 @@ public final class DBIDUtil { */ // TODO: optimize better? public static ModifiableDBIDs intersection(DBIDs first, DBIDs second) { - if (first.size() > second.size()) { + if(first.size() > second.size()) { return intersection(second, first); } ModifiableDBIDs inter = newHashSet(first.size()); - for (DBIDIter it = first.iter(); it.valid(); it.advance()) { - if (second.contains(it)) { + for(DBIDIter it = first.iter(); it.valid(); it.advance()) { + if(second.contains(it)) { inter.add(it); } } @@ -329,20 +323,22 @@ public final class DBIDUtil { */ public static int intersectionSize(DBIDs first, DBIDs second) { // If exactly one is a Set, use it as second parameter. - if (second instanceof SetDBIDs) { - if (!(first instanceof SetDBIDs)) { + if(second instanceof SetDBIDs) { + if(!(first instanceof SetDBIDs)) { return internalIntersectionSize(first, second); } - } else { - if (first instanceof SetDBIDs) { + } + else { + if(first instanceof SetDBIDs) { return internalIntersectionSize(second, first); } } // Both are the same type: both set or both non set. // Smaller goes first. - if (first.size() <= second.size()) { + if(first.size() <= second.size()) { return internalIntersectionSize(first, second); - } else { + } + else { return internalIntersectionSize(second, first); } } @@ -356,8 +352,8 @@ public final class DBIDUtil { */ private static int internalIntersectionSize(DBIDs first, DBIDs second) { int c = 0; - for (DBIDIter it = first.iter(); it.valid(); it.advance()) { - if (second.contains(it)) { + for(DBIDIter it = first.iter(); it.valid(); it.advance()) { + if(second.contains(it)) { c++; } } @@ -375,7 +371,7 @@ public final class DBIDUtil { */ // TODO: optimize? public static void symmetricIntersection(DBIDs first, DBIDs second, HashSetModifiableDBIDs firstonly, HashSetModifiableDBIDs intersection, HashSetModifiableDBIDs secondonly) { - if (first.size() > second.size()) { + if(first.size() > second.size()) { symmetricIntersection(second, first, secondonly, intersection, firstonly); return; } @@ -384,11 +380,12 @@ public final class DBIDUtil { assert (secondonly.size() == 0) : "OUTPUT set should be empty!"; // Initialize with second secondonly.addDBIDs(second); - for (DBIDIter it = first.iter(); it.valid(); it.advance()) { + for(DBIDIter it = first.iter(); it.valid(); it.advance()) { // Try to remove - if (secondonly.remove(it)) { + if(secondonly.remove(it)) { intersection.add(it); - } else { + } + else { firstonly.add(it); } } @@ -428,16 +425,16 @@ public final class DBIDUtil { * @return Unmodifiable collection */ public static StaticDBIDs makeUnmodifiable(DBIDs existing) { - if (existing instanceof StaticDBIDs) { + if(existing instanceof StaticDBIDs) { return (StaticDBIDs) existing; } - if (existing instanceof IntegerArrayDBIDs) { + if(existing instanceof IntegerArrayDBIDs) { return new UnmodifiableIntegerArrayDBIDs((IntegerArrayDBIDs) existing); } - if (existing instanceof IntegerDBIDs) { + if(existing instanceof IntegerDBIDs) { return new UnmodifiableIntegerDBIDs((IntegerDBIDs) existing); } - if (existing instanceof ArrayDBIDs) { + if(existing instanceof ArrayDBIDs) { return new UnmodifiableArrayDBIDs((ArrayDBIDs) existing); } return new UnmodifiableDBIDs(existing); @@ -450,9 +447,10 @@ public final class DBIDUtil { * @return Array DBIDs. */ public static ArrayDBIDs ensureArray(DBIDs ids) { - if (ids instanceof ArrayDBIDs) { + if(ids instanceof ArrayDBIDs) { return (ArrayDBIDs) ids; - } else { + } + else { return newArray(ids); } } @@ -464,9 +462,10 @@ public final class DBIDUtil { * @return Set DBIDs. */ public static SetDBIDs ensureSet(DBIDs ids) { - if (ids instanceof SetDBIDs) { + if(ids instanceof SetDBIDs) { return (SetDBIDs) ids; - } else { + } + else { return newHashSet(ids); } } @@ -478,13 +477,14 @@ public final class DBIDUtil { * @return Modifiable DBIDs. */ public static ModifiableDBIDs ensureModifiable(DBIDs ids) { - if (ids instanceof ModifiableDBIDs) { + if(ids instanceof ModifiableDBIDs) { return (ModifiableDBIDs) ids; - } else { - if (ids instanceof ArrayDBIDs) { + } + else { + if(ids instanceof ArrayDBIDs) { return newArray(ids); } - if (ids instanceof HashSetDBIDs) { + if(ids instanceof HashSetDBIDs) { return newHashSet(ids); } return newArray(ids); @@ -515,59 +515,24 @@ public final class DBIDUtil { } /** - * Make a DistanceDBIDPair. - * - * @param dist Distance value - * @param id ID - * @return new pair - */ - public static <D extends Distance<D>> DistanceDBIDPair<D> newDistancePair(D dist, DBIDRef id) { - return DBIDFactory.FACTORY.newDistancePair(dist, id); - } - - /** - * Make a DoubleDistanceDBIDPair. - * - * @param dist Distance value - * @param id ID - * @return new pair - */ - public static DoubleDistanceDBIDPair newDistancePair(double dist, DBIDRef id) { - return DBIDFactory.FACTORY.newDistancePair(dist, id); - } - - /** * Create an appropriate heap for the distance type. * * This will use a double heap if appropriate. * - * @param distancetype distance prototype - * @param k K value - * @param <D> distance type - * @return New heap of size k, appropriate for this distance type. - */ - public static <D extends Distance<D>> KNNHeap<D> newHeap(D distancetype, int k) { - return DBIDFactory.FACTORY.newHeap(distancetype, k); - } - - /** - * Create an appropriate heap for double distances. - * * @param k K value * @return New heap of size k, appropriate for this distance type. */ - public static DoubleDistanceKNNHeap newDoubleDistanceHeap(int k) { - return DBIDFactory.FACTORY.newDoubleDistanceHeap(k); + public static KNNHeap newHeap(int k) { + return DBIDFactory.FACTORY.newHeap(k); } /** * Build a new heap from a given list. * * @param exist Existing result - * @param <D> Distance type * @return New heap */ - public static <D extends Distance<D>> KNNHeap<D> newHeap(KNNList<D> exist) { + public static KNNHeap newHeap(KNNList exist) { return DBIDFactory.FACTORY.newHeap(exist); } @@ -601,7 +566,7 @@ public final class DBIDUtil { * @param limit Shuffling limit. */ public static void randomShuffle(ArrayModifiableDBIDs ids, Random random, final int limit) { - for (int i = 1; i < limit; i++) { + for(int i = 1; i < limit; i++) { ids.swap(i - 1, i + random.nextInt(limit - i)); } } @@ -627,9 +592,10 @@ public final class DBIDUtil { * @return new DBIDs */ public static ModifiableDBIDs randomSample(DBIDs source, int k, Long seed) { - if (seed != null) { + if(seed != null) { return randomSample(source, k, new Random(seed.longValue())); - } else { + } + else { return randomSample(source, k, new Random()); } } @@ -655,29 +621,31 @@ public final class DBIDUtil { * @return new DBIDs */ public static ModifiableDBIDs randomSample(DBIDs source, int k, Random random) { - if (k < 0 || k > source.size()) { + if(k < 0 || k > source.size()) { throw new IllegalArgumentException("Illegal value for size of random sample: " + k + " > " + source.size() + " or < 0"); } - if (random == null) { - random = new UnsafeRandom(); // Fast, and we're single-threaded here anyway. + if(random == null) { + // Fast, and we're single-threaded here anyway. + random = new FastNonThreadsafeRandom(); } - + // TODO: better balancing for different sizes // Two methods: constructive vs. destructive - if (k < source.size() >> 1) { + if(k < source.size() >> 1) { ArrayDBIDs aids = DBIDUtil.ensureArray(source); DBIDArrayIter iter = aids.iter(); HashSetModifiableDBIDs sample = DBIDUtil.newHashSet(k); - while (sample.size() < k) { + while(sample.size() < k) { iter.seek(random.nextInt(aids.size())); sample.add(iter); } return sample; - } else { + } + else { ArrayModifiableDBIDs sample = DBIDUtil.newArray(source); randomShuffle(sample, random, k); // Delete trailing elements - for (int i = sample.size() - 1; i > k; i--) { + for(int i = sample.size() - 1; i > k; i--) { sample.remove(i); } return sample; @@ -703,19 +671,20 @@ public final class DBIDUtil { * @param random Random generator */ public static ArrayDBIDs[] randomSplit(DBIDs oids, int p, Random random) { - if (random == null) { - random = new UnsafeRandom(); // Fast, and we're single-threaded here anyway. + if(random == null) { + // Fast, and we're single-threaded here anyway. + random = new FastNonThreadsafeRandom(); } ArrayModifiableDBIDs ids = newArray(oids); final int size = ids.size(); ArrayDBIDs[] split = new ArrayDBIDs[p]; // Shuffle - for (int i = 1; i < size; i++) { + for(int i = 1; i < size; i++) { ids.swap(i - 1, i + random.nextInt(size - i)); } final int minsize = size / p; // Floor. final int extra = size % p; // Remainder - for (int beg = 0, part = 0; part < p; part++) { + for(int beg = 0, part = 0; part < p; part++) { // First partitions are smaller, last partitions are larger. final int psize = minsize + ((part < extra) ? 1 : 0); split[part] = ids.slice(beg, beg + psize); @@ -729,17 +698,48 @@ public final class DBIDUtil { * * @param list Existing list * @param k k - * @param <D> distance type * @return Subset */ - @SuppressWarnings("unchecked") - public static <D extends Distance<D>> KNNList<D> subList(KNNList<D> list, int k) { - if (k >= list.size()) { + public static KNNList subList(KNNList list, int k) { + if(k >= list.size()) { return list; } - if (list instanceof DoubleDistanceKNNList) { - return (KNNList<D>) new DoubleDistanceKNNSubList((DoubleDistanceKNNList) list, k); + if(list instanceof IntegerDBIDKNNList) { + return new IntegerDBIDKNNSubList((IntegerDBIDKNNList) list, k); + } + return new KNNSubList(list, k); + } + + /** + * Create a modifiable list to store distance-DBID pairs. + * + * @param size Estimated upper list size + * @return Empty list + */ + public static ModifiableDoubleDBIDList newDistanceDBIDList(int size) { + return DBIDFactory.FACTORY.newDistanceDBIDList(size); + } + + /** + * Create a modifiable list to store distance-DBID pairs. + * + * @return Empty list + */ + public static ModifiableDoubleDBIDList newDistanceDBIDList() { + return DBIDFactory.FACTORY.newDistanceDBIDList(); + } + + /** + * Assert that the presented ids constitute a continuous {@link DBIDRange}. + * + * @param ids ID range. + * @return DBID range. + * @throws AbortException + */ + public static DBIDRange assertRange(DBIDs ids) { + if(!(ids instanceof DBIDRange)) { + throw new AbortException("This class may currently only be used with static databases and DBID ranges."); } - return new KNNSubList<>(list, k); + return (DBIDRange) ids; } } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDVar.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDVar.java index 94480fe9..bdc7b76a 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDVar.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDVar.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -39,4 +39,30 @@ public interface DBIDVar extends DBIDRef, ArrayDBIDs, SetDBIDs { * @param ref Reference */ void set(DBIDRef ref); + + /** + * Clear the contents. + */ + void unset(); + + /** + * Test if the variable is well-defined. + * + * @return {@code true} when assigned. + */ + boolean isSet(); + + /** + * Assign the first pair member to this variable. + * + * @param pair Pair + */ + void setFirst(DBIDPair pair); + + /** + * Assign the second pair member to this variable. + * + * @param pair Pair + */ + void setSecond(DBIDPair pair); } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDs.java index 2bf2b28d..5aecff02 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/DBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDList.java b/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDList.java index 360dda12..939a0fe7 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDList.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDList.java @@ -1,10 +1,10 @@ -package de.lmu.ifi.dbs.elki.database.ids.distance; +package de.lmu.ifi.dbs.elki.database.ids; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,19 +23,17 @@ package de.lmu.ifi.dbs.elki.database.ids.distance; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.database.ids.DBIDs; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** - * Collection of objects and their distances. + * Collection of double values associated with objects. * * To iterate over the results, use the following code: * * <pre> * {@code - * for (DistanceDBIDResultIter<D> iter = result.iter(); iter.valid(); iter.advance()) { - * // You can get the distance via: iter.getDistance(); - * // Or use iter just like any other DBIDRef + * for (DoubleDBIDListIter iter = result.iter(); iter.valid(); iter.advance()) { + * // You can get the distance via: iter.doubleValue(); + * // And use iter just like any other DBIDRef * } * } * </pre> @@ -45,7 +43,7 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * * <pre> * {@code - * for (DBIDIter<D> iter = result.iter(); iter.valid(); iter.advance()) { + * for (DBIDIter iter = result.iter(); iter.valid(); iter.advance()) { * // Use iter just like any other DBIDRef * } * } @@ -55,12 +53,10 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * * @apiviz.landmark * - * @apiviz.composedOf DistanceDBIDPair - * @apiviz.has DistanceDBIDListIter - * - * @param <D> Distance type + * @apiviz.composedOf DoubleDBIDPair + * @apiviz.has DoubleDBIDListIter */ -public interface DistanceDBIDList<D extends Distance<D>> extends DBIDs { +public interface DoubleDBIDList extends DBIDs { /** * Size of list. * @@ -70,12 +66,12 @@ public interface DistanceDBIDList<D extends Distance<D>> extends DBIDs { int size(); /** - * Access a single pair. + * Materialize a single pair. * * @param off Offset * @return Pair */ - DistanceDBIDPair<D> get(int off); + DoubleDBIDPair get(int off); /** * Get an iterator @@ -83,5 +79,5 @@ public interface DistanceDBIDList<D extends Distance<D>> extends DBIDs { * @return New iterator */ @Override - DistanceDBIDListIter<D> iter(); + DoubleDBIDListIter iter(); } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDListIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDListIter.java index 914f3676..d5b0e4f7 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDListIter.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDListIter.java @@ -1,10 +1,11 @@ -package de.lmu.ifi.dbs.elki.database.ids.distance; +package de.lmu.ifi.dbs.elki.database.ids; + /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,11 +24,8 @@ package de.lmu.ifi.dbs.elki.database.ids.distance; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; - /** - * Iterator over distance-based query results. + * Iterator over double-DBID pairs results. * * There is no getter for the DBID, as this implements * {@link de.lmu.ifi.dbs.elki.database.ids.DBIDRef}. @@ -36,20 +34,37 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * * @apiviz.landmark * - * @apiviz.has DistanceDBIDPair - - iterator for + * @apiviz.has DoubleDBIDPair */ -public interface DistanceDBIDListIter<D extends Distance<D>> extends DBIDArrayIter { +public interface DoubleDBIDListIter extends DBIDArrayIter { /** - * Get the distance + * Get the double value * - * @return distance + * @return double value */ - public D getDistance(); + public double doubleValue(); /** - * Get an object pair. + * Materialize an object pair. + * + * Note: currently, this will create a <em>new object</em>. In order to avoid + * the garbage collection overhead, it is preferable to use + * {@code #doubleValue()} and exploit that the iterator itself is a + * {@code DBIDRef} reference. * * @return object pair */ - public DistanceDBIDPair<D> getDistancePair(); + public DoubleDBIDPair getPair(); + + @Override + DoubleDBIDListIter advance(); + + @Override + DoubleDBIDListIter advance(int count); + + @Override + DoubleDBIDListIter retract(); + + @Override + DoubleDBIDListIter seek(int off); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDPair.java index 970092b0..9459dbf6 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDPair.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/DoubleDBIDPair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,42 +23,19 @@ package de.lmu.ifi.dbs.elki.database.ids; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.utilities.pairs.PairInterface; - /** - * Pair of a double value and a DBID + * Pair of a double value and a DBID. + * + * Note: this interface implements {@link DBIDRef}, i.e. it can be used as DBID + * object reference. * * @author Erich Schubert */ -public interface DoubleDBIDPair extends PairInterface<Double, DBID>, DBIDRef, Comparable<DoubleDBIDPair> { +public interface DoubleDBIDPair extends DBIDRef, Comparable<DoubleDBIDPair> { /** * Get the double value of the pair. * * @return Double */ public double doubleValue(); - - /** - * Get the first object - note: this may cause autoboxing, use pair.first for - * native pairs! - * - * @deprecated Avoid autoboxing. Use {@link #doubleValue}! - * - * @return First object - */ - @Override - @Deprecated - public Double getFirst(); - - /** - * Get the second object - note: this may cause autoboxing, use pair.second - * for native pairs! - * - * @deprecated Avoid autoboxing! Use {@link DBIDRef} interface! - * - * @return Second object - */ - @Override - @Deprecated - public DBID getSecond(); } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/EmptyDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/EmptyDBIDs.java index 0081fd44..3fb539df 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/EmptyDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/EmptyDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -99,8 +99,9 @@ public class EmptyDBIDs implements ArrayStaticDBIDs, SetDBIDs { } @Override - public void advance() { + public EmptyDBIDIterator advance() { assert (false) : "Misplaced call to advance()"; + return this; } @Override @@ -122,18 +123,21 @@ public class EmptyDBIDs implements ArrayStaticDBIDs, SetDBIDs { } @Override - public void advance(int count) { + public EmptyDBIDIterator advance(int count) { assert (count != 0) : "Misplaced call to advance()"; + return this; } @Override - public void retract() { + public EmptyDBIDIterator retract() { assert (false) : "Misplaced call to retract()"; + return this; } @Override - public void seek(int off) { + public EmptyDBIDIterator seek(int off) { // Ignore + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/HashSetDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/HashSetDBIDs.java index cabe9898..6fcb40cc 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/HashSetDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/HashSetDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/HashSetModifiableDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/HashSetModifiableDBIDs.java index 6a57f5f0..90574599 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/HashSetModifiableDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/HashSetModifiableDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/KNNHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/KNNHeap.java index 5e94de47..1169caf6 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/KNNHeap.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/KNNHeap.java @@ -1,10 +1,10 @@ -package de.lmu.ifi.dbs.elki.database.ids.distance; +package de.lmu.ifi.dbs.elki.database.ids; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,30 +23,27 @@ package de.lmu.ifi.dbs.elki.database.ids.distance; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * Interface for kNN heaps. * - * To instantiate, use: {@link de.lmu.ifi.dbs.elki.database.ids.DBIDUtil#newHeap}! + * To instantiate, use: + * {@link de.lmu.ifi.dbs.elki.database.ids.DBIDUtil#newHeap}! * * @author Erich Schubert * * @apiviz.landmark * * @apiviz.uses KNNList - - «serializes to» - * @apiviz.composedOf DistanceDBIDPair - * - * @param <D> Distance function + * @apiviz.composedOf DoubleDBIDPair */ -public interface KNNHeap<D extends Distance<D>> { +public interface KNNHeap { /** * Serialize to a {@link KNNList}. This empties the heap! * * @return KNNList with the heaps contents. */ - KNNList<D> toKNNList(); + KNNList toKNNList(); /** * Get the K parameter ("maxsize" internally). @@ -60,7 +57,7 @@ public interface KNNHeap<D extends Distance<D>> { * * @return Maximum distance */ - D getKNNDistance(); + double getKNNDistance(); /** * Add a distance-id pair to the heap unless the distance is too large. @@ -69,8 +66,18 @@ public interface KNNHeap<D extends Distance<D>> { * * @param distance Distance value * @param id ID number + * @return current k-distance */ - void insert(D distance, DBIDRef id); + double insert(double distance, DBIDRef id); + + /** + * Add a distance-id pair to the heap unless the distance is too large. + * + * Use for existing pairs. + * + * @param e Existing distance pair + */ + void insert(DoubleDBIDPair e); /** * Current size of heap. @@ -78,14 +85,14 @@ public interface KNNHeap<D extends Distance<D>> { * @return Heap size */ int size(); - + /** * Test if the heap is empty. * * @return true when empty. */ boolean isEmpty(); - + /** * Clear the heap. */ @@ -100,12 +107,12 @@ public interface KNNHeap<D extends Distance<D>> { * * @return largest element */ - DistanceDBIDPair<D> poll(); + DoubleDBIDPair poll(); /** * Peek at the <em>largest</em> element in the heap. * * @return The current largest element. */ - DistanceDBIDPair<D> peek(); + DoubleDBIDPair peek(); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/KNNList.java b/src/de/lmu/ifi/dbs/elki/database/ids/KNNList.java index 61b75ba8..6d3dc778 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/KNNList.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/KNNList.java @@ -1,10 +1,11 @@ -package de.lmu.ifi.dbs.elki.database.ids.distance; +package de.lmu.ifi.dbs.elki.database.ids; + /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,7 +24,6 @@ package de.lmu.ifi.dbs.elki.database.ids.distance; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * Interface for kNN results. @@ -54,11 +54,9 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * * @apiviz.landmark * - * @apiviz.composedOf DistanceDBIDPair - * - * @param <D> Distance type + * @apiviz.composedOf DoubleDBIDPair */ -public interface KNNList<D extends Distance<D>> extends DistanceDBIDList<D> { +public interface KNNList extends DoubleDBIDList { /** * Size */ @@ -78,12 +76,12 @@ public interface KNNList<D extends Distance<D>> extends DistanceDBIDList<D> { * @param index */ @Override - public DistanceDBIDPair<D> get(int index); + public DoubleDBIDPair get(int index); /** * Get the distance to the k nearest neighbor, or maxdist otherwise. * * @return Maximum distance */ - public D getKNNDistance(); + public double getKNNDistance(); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/ModifiableDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/ModifiableDBIDs.java index 1cd8c4e7..aa9a5052 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/ModifiableDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/ModifiableDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/ModifiableDistanceDBIDList.java b/src/de/lmu/ifi/dbs/elki/database/ids/ModifiableDoubleDBIDList.java index afb15f93..2ae62345 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/ModifiableDistanceDBIDList.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/ModifiableDoubleDBIDList.java @@ -1,10 +1,10 @@ -package de.lmu.ifi.dbs.elki.database.ids.distance; +package de.lmu.ifi.dbs.elki.database.ids; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,23 +23,34 @@ package de.lmu.ifi.dbs.elki.database.ids.distance; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; + /** * Modifiable API for Distance-DBID results * * @author Erich Schubert - * - * @param <D> Distance type + * + * @apiviz.composedOf DoubleDBIDPair */ -public interface ModifiableDistanceDBIDList<D extends Distance<D>> extends DistanceDBIDList<D> { +public interface ModifiableDoubleDBIDList extends DoubleDBIDList { /** * Add an object to this result. * * @param distance Distance to add * @param id DBID to add */ - public void add(D distance, DBIDRef id); + void add(double distance, DBIDRef id); + + /** + * Add an element. + * + * @param pair Pair to add + */ + void add(DoubleDBIDPair pair); + + /** + * Clear the list contents. + */ + void clear(); /** * Sort the result in ascending order diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/SetDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/SetDBIDs.java index 3a92593e..0b316ca2 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/SetDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/SetDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/StaticDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/StaticDBIDs.java index 2ba30d4b..24f6b585 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/StaticDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/StaticDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDPair.java deleted file mode 100644 index a9d879d9..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DistanceDBIDPair.java +++ /dev/null @@ -1,53 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.distance; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; - -/** - * Pair containing a distance an an object ID - * - * Note: there is no getter for the object, as this is a {@link DBIDRef}. - * - * @author Erich Schubert - * - * @param <D> Distance - */ -public interface DistanceDBIDPair<D extends Distance<D>> extends DBIDRef { - /** - * Get the distance. - * - * @return Distance - */ - public D getDistance(); - - /** - * Compare to another result, by distance, smaller first. - * - * @param other Other result - * @return Comparison result - */ - public int compareByDistance(DistanceDBIDPair<D> other); -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDListIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDListIter.java deleted file mode 100644 index 68b2de1e..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDListIter.java +++ /dev/null @@ -1,60 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.distance; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Iterator for double valued distance-based query results. - * - * @author Erich Schubert - */ -public interface DoubleDistanceDBIDListIter extends DistanceDBIDListIter<DoubleDistance> { - /** - * Get the distance - * - * @return distance - */ - public double doubleDistance(); - - /** - * Get an object pair. - * - * @return object pair - */ - @Override - public DoubleDistanceDBIDPair getDistancePair(); - - /** - * Get the distance - * - * @deprecated Use {@link #doubleDistance} to avoid creating unnecessary - * objects. - * - * @return distance - */ - @Deprecated - @Override - public DoubleDistance getDistance(); -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDPair.java deleted file mode 100644 index 5286029b..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDPair.java +++ /dev/null @@ -1,54 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.distance; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Pair containing a double distance a DBID. - * - * There is no getter for the DBID, as this is a {@link DBIDRef} already. - * - * @author Erich Schubert - */ -public interface DoubleDistanceDBIDPair extends DistanceDBIDPair<DoubleDistance> { - /** - * Get the distance. - * - * @deprecated Would produce a DoubleDistance object. Use {@link #doubleDistance} instead! - * - * @return Distance - */ - @Override - @Deprecated - public DoubleDistance getDistance(); - - /** - * Get the distance. - * - * @return Distance - */ - public double doubleDistance(); -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDPairList.java b/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDPairList.java deleted file mode 100644 index 58ce433d..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDPairList.java +++ /dev/null @@ -1,217 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.distance; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import java.util.ArrayList; -import java.util.Collections; - -import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory; -import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.distance.distanceresultlist.DistanceDBIDResultUtil; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Default class to keep a list of distance-object pairs. - * - * @author Erich Schubert - * - * @apiviz.composedOf DoubleDistanceDBIDPair - * @apiviz.has DoubleDistanceDBIDListIter - */ -public class DoubleDistanceDBIDPairList implements ModifiableDoubleDistanceDBIDList { - /** - * Actual storage. - */ - final ArrayList<DoubleDistanceDBIDPair> storage; - - /** - * Constructor. - */ - public DoubleDistanceDBIDPairList() { - super(); - storage = new ArrayList<>(); - } - - /** - * Constructor. - * - * @param initialCapacity Capacity - */ - public DoubleDistanceDBIDPairList(int initialCapacity) { - super(); - storage = new ArrayList<>(initialCapacity); - } - - /** - * Add an element. - * - * @deprecated Pass a double value instead. - * - * @param dist Distance - * @param id ID - */ - @Override - @Deprecated - public void add(DoubleDistance dist, DBIDRef id) { - storage.add(DBIDFactory.FACTORY.newDistancePair(dist.doubleValue(), id)); - } - - /** - * Add an element. - * - * @param dist Distance - * @param id ID - */ - @Override - public void add(double dist, DBIDRef id) { - storage.add(DBIDFactory.FACTORY.newDistancePair(dist, id)); - } - - /** - * Add an element. - * - * @param pair Pair to add - */ - @Override - public void add(DoubleDistanceDBIDPair pair) { - storage.add(pair); - } - - @Override - public void clear() { - storage.clear(); - } - - @Override - public void sort() { - Collections.sort(storage, DistanceDBIDResultUtil.distanceComparator()); - } - - @Override - public int size() { - return storage.size(); - } - - @Override - public DoubleDistanceDBIDPair get(int off) { - return storage.get(off); - } - - @Override - public DoubleDistanceDBIDListIter iter() { - return new Itr(); - } - - @Override - public boolean contains(DBIDRef o) { - for(DBIDIter iter = iter(); iter.valid(); iter.advance()) { - if(DBIDUtil.equal(iter, o)) { - return true; - } - } - return false; - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public String toString() { - return DistanceDBIDResultUtil.toString(this); - } - - /** - * Iterator class. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - protected class Itr implements DoubleDistanceDBIDListIter { - /** - * Iterator position. - */ - int pos = 0; - - @Override - public int internalGetIndex() { - return get(pos).internalGetIndex(); - } - - @Override - public boolean valid() { - return pos < size(); - } - - @Override - public void advance() { - pos++; - } - - @Override - @Deprecated - public DoubleDistance getDistance() { - return get(pos).getDistance(); - } - - @Override - public double doubleDistance() { - return get(pos).doubleDistance(); - } - - @Override - public DoubleDistanceDBIDPair getDistancePair() { - return get(pos); - } - - @Override - public String toString() { - return valid() ? getDistancePair().toString() : "null"; - } - - @Override - public int getOffset() { - return pos; - } - - @Override - public void advance(int count) { - pos += count; - } - - @Override - public void retract() { - --pos; - } - - @Override - public void seek(int off) { - pos = off; - } - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceKNNHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceKNNHeap.java deleted file mode 100644 index ed687877..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceKNNHeap.java +++ /dev/null @@ -1,101 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.distance; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Interface for kNN heaps storing double distances and DBIDs. - * - * @author Erich Schubert - */ -public interface DoubleDistanceKNNHeap extends KNNHeap<DoubleDistance> { - /** - * Add a distance-id pair to the heap unless the distance is too large. - * - * Compared to the super.add() method, this often saves the pair construction. - * - * @param distance Distance value - * @param id ID number - * @return updated k-distance - */ - double insert(double distance, DBIDRef id); - - /** - * Add a distance-id pair to the heap unless the distance is too large. - * - * Compared to the super.add() method, this often saves the pair construction. - * - * @param distance Distance value - * @param id ID number - */ - @Deprecated - void insert(Double distance, DBIDRef id); - - /** - * Add a distance-id pair to the heap unless the distance is too large. - * - * Use for existing pairs. - * - * @param e Existing distance pair - */ - void insert(DoubleDistanceDBIDPair e); - - /** - * {@inheritDoc} - * - * @deprecated if you know your distances are double-valued, you should be - * using the primitive type. - */ - @Override - @Deprecated - void insert(DoubleDistance dist, DBIDRef id); - - /** - * Get the distance to the k nearest neighbor, or maxdist otherwise. - * - * @return Maximum distance - */ - double doubleKNNDistance(); - - /** - * {@inheritDoc} - * - * @deprecated if you know your distances are double-valued, you should be - * using the primitive type. - */ - @Override - @Deprecated - DoubleDistance getKNNDistance(); - - @Override - DoubleDistanceDBIDPair poll(); - - @Override - DoubleDistanceDBIDPair peek(); - - @Override - DoubleDistanceKNNList toKNNList(); -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceKNNList.java b/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceKNNList.java deleted file mode 100644 index c54110ab..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceKNNList.java +++ /dev/null @@ -1,55 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.distance; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Double-valued KNN result. - * - * @author Erich Schubert - */ -public interface DoubleDistanceKNNList extends KNNList<DoubleDistance> { - /** - * {@inheritDoc} - * - * @deprecated use doubleKNNDistance()! - */ - @Override - @Deprecated - DoubleDistance getKNNDistance(); - - /** - * Get the kNN distance as double value. - * - * @return Distance - */ - double doubleKNNDistance(); - - @Override - DoubleDistanceDBIDListIter iter(); - - @Override - DoubleDistanceDBIDPair get(int off); -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/ModifiableDoubleDistanceDBIDList.java b/src/de/lmu/ifi/dbs/elki/database/ids/distance/ModifiableDoubleDistanceDBIDList.java deleted file mode 100644 index 4b29e3b6..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/ModifiableDoubleDistanceDBIDList.java +++ /dev/null @@ -1,68 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.distance; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDList; -import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDistanceDBIDList; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * An object containing Double-DBID-Pairs. - * - * @author Erich Schubert - */ -public interface ModifiableDoubleDistanceDBIDList extends DoubleDistanceDBIDList, ModifiableDistanceDBIDList<DoubleDistance> { - /** - * Add an element. - * - * @deprecated Pass a double value instead. - * - * @param dist Distance - * @param id ID - */ - @Override - @Deprecated - void add(DoubleDistance dist, DBIDRef id); - - /** - * Add an element. - * - * @param dist Distance - * @param id ID - */ - void add(double dist, DBIDRef id); - - /** - * Add an element. - * - * @param pair Pair to add - */ - void add(DoubleDistanceDBIDPair pair); - - /** - * Clear the list contents. - */ - void clear(); -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/package-info.java b/src/de/lmu/ifi/dbs/elki/database/ids/distance/package-info.java deleted file mode 100644 index 7fefbedd..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Distance-DBID pairs, lists and heaps. - */ -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package de.lmu.ifi.dbs.elki.database.ids.distance; diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/AbstractKNNHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/AbstractKNNHeap.java deleted file mode 100644 index c42c728d..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/AbstractKNNHeap.java +++ /dev/null @@ -1,93 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.generic; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - - -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap; -import de.lmu.ifi.dbs.elki.distance.distanceresultlist.DistanceDBIDResultUtil; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.TiedTopBoundedHeap; - -/** - * Heap used for KNN management. - * - * @author Erich Schubert - * - * @param <P> pair type - * @param <D> distance type - */ -abstract class AbstractKNNHeap<P extends DistanceDBIDPair<D>, D extends Distance<D>> implements KNNHeap<D> { - /** - * The actual heap. - */ - protected final TiedTopBoundedHeap<P> heap; - - /** - * Constructor. - * - * @param k Maximum heap size (unless tied) - */ - public AbstractKNNHeap(int k) { - super(); - heap = new TiedTopBoundedHeap<>(k, DistanceDBIDResultUtil.BY_REVERSE_DISTANCE); - } - - /** - * Add a pair to the heap. - * - * @param pair Pair to add. - */ - public abstract void insert(P pair); - - @Override - public final int getK() { - return heap.getMaxSize(); - } - - @Override - public int size() { - return heap.size(); - } - - @Override - public P peek() { - return heap.peek(); - } - - @Override - public boolean isEmpty() { - return heap.isEmpty(); - } - - @Override - public void clear() { - heap.clear(); - } - - @Override - public P poll() { - return heap.poll(); - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DBIDIterAdapter.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/DBIDIterAdapter.java deleted file mode 100644 index 85fdcffd..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DBIDIterAdapter.java +++ /dev/null @@ -1,82 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.generic; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import java.util.Iterator; - -import de.lmu.ifi.dbs.elki.database.ids.DBID; -import de.lmu.ifi.dbs.elki.database.ids.DBIDMIter; - -/** - * Iterator for classic collections. - * - * @author Erich Schubert - */ -public class DBIDIterAdapter implements DBIDMIter { - /** - * Current DBID. - */ - DBID cur = null; - - /** - * The real iterator. - */ - Iterator<DBID> iter; - - /** - * Constructor. - * - * @param iter Iterator - */ - public DBIDIterAdapter(Iterator<DBID> iter) { - super(); - this.iter = iter; - advance(); - } - - @Override - public boolean valid() { - return cur != null; - } - - @Override - public void advance() { - if(iter.hasNext()) { - cur = iter.next(); - } - else { - cur = null; - } - } - - @Override - public int internalGetIndex() { - return cur.internalGetIndex(); - } - - @Override - public void remove() { - iter.remove(); - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DistanceDBIDPairKNNHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/DistanceDBIDPairKNNHeap.java deleted file mode 100644 index e102d716..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DistanceDBIDPairKNNHeap.java +++ /dev/null @@ -1,106 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.generic; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; - -/** - * Heap for collecting kNN candidates with arbitrary distance types. - * - * For double distances, see {@link DoubleDistanceDBIDPairKNNHeap} - * - * <b>To instantiate, use {@link de.lmu.ifi.dbs.elki.database.ids.DBIDUtil#newHeap} instead!</b> - * - * @author Erich Schubert - * - * @param <D> Distance type - */ -public class DistanceDBIDPairKNNHeap<D extends Distance<D>> extends AbstractKNNHeap<DistanceDBIDPair<D>, D> { - /** - * Cached distance to k nearest neighbor (to avoid going through {@link #peek} - * each time). - */ - protected D knndistance = null; - - /** - * Constructor. - * - * <b>To instantiate, use {@link de.lmu.ifi.dbs.elki.database.ids.DBIDUtil#newHeap} instead!</b> - * - * @param k Heap size - */ - public DistanceDBIDPairKNNHeap(int k) { - super(k); - } - - /** - * Serialize to a {@link DistanceDBIDPairKNNList}. This empties the heap! - * - * @return KNNList with the heaps contents. - */ - @Override - public DistanceDBIDPairKNNList<D> toKNNList() { - return new DistanceDBIDPairKNNList<>(this); - } - - @Override - public void insert(D distance, DBIDRef id) { - if (size() < getK()) { - heap.add(DBIDFactory.FACTORY.newDistancePair(distance, id)); - heapModified(); - return; - } - // size >= maxsize. Insert only when necessary. - if (knndistance.compareTo(distance) >= 0) { - // Replace worst element. - heap.add(DBIDFactory.FACTORY.newDistancePair(distance, id)); - heapModified(); - } - } - - @Override - public void insert(DistanceDBIDPair<D> pair) { - if (size() < getK() || knndistance.compareTo(pair.getDistance()) >= 0) { - heap.add(pair); - heapModified(); - } - } - - // @Override - protected void heapModified() { - // super.heapModified(); - // Update threshold. - if (size() >= getK()) { - knndistance = heap.peek().getDistance(); - } - } - - @Override - public D getKNNDistance() { - return knndistance; - } -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DistanceDBIDPairKNNList.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/DistanceDBIDPairKNNList.java deleted file mode 100644 index bc5392d6..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DistanceDBIDPairKNNList.java +++ /dev/null @@ -1,211 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.generic; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap; - -/** - * Finalized KNN List. - * - * @author Erich Schubert - * - * @param <D> Distance type - */ -public class DistanceDBIDPairKNNList<D extends Distance<D>> implements KNNList<D> { - /** - * The value of k this was materialized for. - */ - private final int k; - - /** - * The actual data array. - */ - private final Object[] data; - - /** - * Constructor, to be called from KNNHeap only. Use {@link KNNHeap#toKNNList} - * instead! - * - * @param heap Calling heap - */ - protected DistanceDBIDPairKNNList(KNNHeap<D> heap) { - super(); - this.data = new Object[heap.size()]; - this.k = heap.getK(); - // Get sorted data from heap; but in reverse. - int i = heap.size(); - while (heap.size() > 0) { - i--; - assert (i >= 0); - data[i] = heap.poll(); - } - assert (data.length == 0 || data[0] != null); - assert (heap.size() == 0); - } - - /** - * Constructor. With a KNNHeap, use {@link KNNHeap#toKNNList} instead! - * - * @param heap Calling heap - * @param k K value - */ - public DistanceDBIDPairKNNList(Heap<? extends DistanceDBIDPair<D>> heap, int k) { - super(); - this.data = new Object[heap.size()]; - this.k = k; - assert (heap.size() >= this.k) : "Heap doesn't contain enough objects!"; - // Get sorted data from heap; but in reverse. - int i = heap.size(); - while (!heap.isEmpty()) { - i--; - assert (i >= 0); - data[i] = heap.poll(); - } - assert (data.length == 0 || data[0] != null); - assert (heap.size() == 0); - } - - @Override - public int getK() { - return k; - } - - @Override - public D getKNNDistance() { - return get(getK() - 1).getDistance(); - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append("kNNList["); - for (DistanceDBIDListIter<D> iter = this.iter(); iter.valid();) { - buf.append(iter.getDistance()).append(':').append(DBIDUtil.toString(iter)); - iter.advance(); - if (iter.valid()) { - buf.append(','); - } - } - buf.append(']'); - return buf.toString(); - } - - @SuppressWarnings("unchecked") - @Override - public DistanceDBIDPair<D> get(int index) { - return (DistanceDBIDPair<D>) data[index]; - } - - @Override - public DistanceDBIDListIter<D> iter() { - return new Itr(); - } - - @Override - public int size() { - return data.length; - } - - @Override - public boolean contains(DBIDRef o) { - for (DBIDIter iter = iter(); iter.valid(); iter.advance()) { - if (DBIDUtil.equal(iter, o)) { - return true; - } - } - return false; - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - /** - * Iterator. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - private class Itr implements DistanceDBIDListIter<D> { - /** - * Cursor position. - */ - private int pos = 0; - - @Override - public int internalGetIndex() { - return get(pos).internalGetIndex(); - } - - @Override - public boolean valid() { - return pos < data.length; - } - - @Override - public void advance() { - pos++; - } - - @Override - public D getDistance() { - return get(pos).getDistance(); - } - - @Override - public DistanceDBIDPair<D> getDistancePair() { - return get(pos); - } - - @Override - public int getOffset() { - return pos; - } - - @Override - public void advance(int count) { - pos += count; - } - - @Override - public void retract() { - --pos; - } - - @Override - public void seek(int off) { - pos += off; - } - } -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNHeap.java deleted file mode 100644 index 8e489a79..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNHeap.java +++ /dev/null @@ -1,218 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.generic; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import java.util.Comparator; - -import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Heap for collecting double-valued KNN instances. - * - * See also: {@link de.lmu.ifi.dbs.elki.database.ids.DBIDUtil#newHeap}! - * - * Experiments have shown that it <em>can</em> be much more performant to track - * the knndistance <em>outside</em> of the heap, and do comparisons on the - * stack: <blockquote> - * - * <pre> - * {@code - * double knndist = Double.POSITIVE_INFINITY; - * DoubleDistanceDBIDPairKNNHeap heap = new DoubleDistanceDBIDPairKNNHeap(k); - * for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) { - * double dist = computeDistance(iditer, ...); - * if (dist < knndist) { - * heap.add(dist, iditer); - * if (heap.size() >= k) { - * max = heap.doubleKNNDistance(); - * } - * } - * } - * } - * </pre> - * - * </blockquote> - * - * The reason probably is that {@code knndist} resides on the stack and can be - * better optimized by the hotspot compiler. - * - * @author Erich Schubert - */ -public class DoubleDistanceDBIDPairKNNHeap extends AbstractKNNHeap<DoubleDistanceDBIDPair, DoubleDistance> implements DoubleDistanceKNNHeap { - /** - * Comparator class. - */ - public static final Comparator<DoubleDistanceDBIDPair> COMPARATOR = new Comp(); - - /** - * Reverse comparator. - */ - public static final Comparator<DoubleDistanceDBIDPair> REVERSE_COMPARATOR = new RComp(); - - /** - * Cached distance to k nearest neighbor (to avoid going through {@link #peek} - * too often). - */ - protected double knndistance = Double.POSITIVE_INFINITY; - - /** - * Constructor. - * - * See also: {@link de.lmu.ifi.dbs.elki.database.ids.DBIDUtil#newHeap}! - * - * @param k Heap size - */ - public DoubleDistanceDBIDPairKNNHeap(int k) { - super(k); - } - - /** - * Serialize to a {@link DoubleDistanceDBIDPairKNNList}. This empties the - * heap! - * - * @return KNNList with the heaps contents. - */ - @Override - public DoubleDistanceDBIDPairKNNList toKNNList() { - return new DoubleDistanceDBIDPairKNNList(this); - } - - /** - * Add a distance-id pair to the heap unless the distance is too large. - * - * Compared to the super.add() method, this often saves the pair construction. - * - * @param distance Distance value - * @param id ID number - * @return knn distance. - */ - @Override - public final double insert(final double distance, final DBIDRef id) { - if (size() < getK() || knndistance >= distance) { - heap.add(DBIDFactory.FACTORY.newDistancePair(distance, id)); - heapModified(); - } - return knndistance; - } - - /** - * Add a distance-id pair to the heap unless the distance is too large. - * - * Compared to the super.add() method, this often saves the pair construction. - * - * @param distance Distance value - * @param id ID number - */ - @Override - @Deprecated - public final void insert(final Double distance, final DBIDRef id) { - if (size() < getK() || knndistance >= distance) { - heap.add(DBIDFactory.FACTORY.newDistancePair(distance, id)); - heapModified(); - } - } - - // @Override - protected void heapModified() { - // super.heapModified(); - if (size() >= getK()) { - knndistance = heap.peek().doubleDistance(); - } - } - - @Override - public void insert(final DoubleDistanceDBIDPair e) { - if (size() < getK() || knndistance >= e.doubleDistance()) { - heap.add(e); - heapModified(); - } - } - - /** - * {@inheritDoc} - * - * @deprecated if you know your distances are double-valued, you should be - * using the primitive type. - * - */ - @Override - @Deprecated - public void insert(DoubleDistance dist, DBIDRef id) { - insert(dist.doubleValue(), id); - } - - /** - * Get the distance to the k nearest neighbor, or maxdist otherwise. - * - * @return Maximum distance - */ - @Override - public double doubleKNNDistance() { - return knndistance; - } - - /** - * {@inheritDoc} - * - * @deprecated if you know your distances are double-valued, you should be - * using the primitive type. - */ - @Override - @Deprecated - public DoubleDistance getKNNDistance() { - return new DoubleDistance(knndistance); - } - - /** - * Comparator to use. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - protected static class Comp implements Comparator<DoubleDistanceDBIDPair> { - @Override - public int compare(DoubleDistanceDBIDPair o1, DoubleDistanceDBIDPair o2) { - return -Double.compare(o1.doubleDistance(), o2.doubleDistance()); - } - } - - /** - * Comparator to use. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - protected static class RComp implements Comparator<DoubleDistanceDBIDPair> { - @Override - public int compare(DoubleDistanceDBIDPair o1, DoubleDistanceDBIDPair o2) { - return Double.compare(o1.doubleDistance(), o2.doubleDistance()); - } - } -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNList.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNList.java deleted file mode 100644 index c72529ad..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNList.java +++ /dev/null @@ -1,257 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.generic; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import java.util.Collection; -import java.util.Iterator; - -import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; -import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap; - -/** - * Finalized KNN List. - * - * @author Erich Schubert - * - * @apiviz.composedOf DoubleDistanceDBIDPair - * @apiviz.has DoubleDistanceDBIDListIter - */ -public class DoubleDistanceDBIDPairKNNList implements DoubleDistanceKNNList { - /** - * The value of k this was materialized for. - */ - private final int k; - - /** - * The actual data array. - */ - private final DoubleDistanceDBIDPair[] data; - - /** - * Constructor. This will <em>clone</em> the given collection! - * - * @param col Existing collection - * @param k K parameter - */ - public DoubleDistanceDBIDPairKNNList(Collection<DoubleDistanceDBIDPair> col, int k) { - super(); - this.data = new DoubleDistanceDBIDPair[col.size()]; - this.k = k; - assert (col.size() >= this.k) : "Collection doesn't contain enough objects!"; - // Get sorted data from heap; but in reverse. - Iterator<DoubleDistanceDBIDPair> it = col.iterator(); - for (int i = 0; it.hasNext(); i++) { - data[i] = it.next(); - } - assert (data.length == 0 || data[0] != null); - } - - /** - * Constructor, to be called from KNNHeap only. Use {@link KNNHeap#toKNNList} - * instead! - * - * @param heap Calling heap - */ - protected DoubleDistanceDBIDPairKNNList(DoubleDistanceDBIDPairKNNHeap heap) { - super(); - this.data = new DoubleDistanceDBIDPair[heap.size()]; - this.k = heap.getK(); - // Get sorted data from heap; but in reverse. - int i = heap.size(); - while (heap.size() > 0) { - i--; - assert (i >= 0); - data[i] = heap.poll(); - } - assert (data.length == 0 || data[0] != null); - assert (heap.size() == 0); - } - - /** - * Constructor, to be called from KNNHeap only. Use {@link KNNHeap#toKNNList} - * instead! - * - * @param heap Calling heap - * @param k Target number of neighbors (before ties) - */ - public DoubleDistanceDBIDPairKNNList(Heap<DoubleDistanceDBIDPair> heap, int k) { - super(); - this.data = new DoubleDistanceDBIDPair[heap.size()]; - this.k = k; - assert (heap.size() >= this.k) : "Heap doesn't contain enough objects!"; - // Get sorted data from heap; but in reverse. - int i = heap.size(); - while (heap.size() > 0) { - i--; - assert (i >= 0); - data[i] = heap.poll(); - } - assert (data.length == 0 || data[0] != null); - assert (heap.size() == 0); - } - - @Override - public int getK() { - return k; - } - - @Override - @Deprecated - public DoubleDistance getKNNDistance() { - if (size() < k) { - return DoubleDistance.INFINITE_DISTANCE; - } - return get(k - 1).getDistance(); - } - - @Override - public double doubleKNNDistance() { - if (size() < k) { - return Double.POSITIVE_INFINITY; - } - return get(k - 1).doubleDistance(); - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append("kNNList["); - for (DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) { - buf.append(iter.doubleDistance()).append(':').append(DBIDUtil.toString(iter)); - iter.advance(); - if (iter.valid()) { - buf.append(','); - } - } - buf.append(']'); - return buf.toString(); - } - - @Override - public DoubleDistanceDBIDPair get(int index) { - return data[index]; - } - - @Override - public DoubleDistanceDBIDListIter iter() { - return new Itr(); - } - - @Override - public int size() { - return data.length; - } - - @Override - public boolean contains(DBIDRef o) { - for (DBIDIter iter = iter(); iter.valid(); iter.advance()) { - if (DBIDUtil.equal(iter, o)) { - return true; - } - } - return false; - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - /** - * Iterator. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - private class Itr implements DoubleDistanceDBIDListIter { - /** - * Cursor position. - */ - private int pos = 0; - - @Override - public int internalGetIndex() { - return get(pos).internalGetIndex(); - } - - @Override - public boolean valid() { - return pos < data.length; - } - - @Override - public void advance() { - pos++; - } - - /** - * {@inheritDoc} - * - * @deprecated use {@link #doubleDistance}! - */ - @Override - @Deprecated - public DoubleDistance getDistance() { - return get(pos).getDistance(); - } - - @Override - public double doubleDistance() { - return get(pos).doubleDistance(); - } - - @Override - public DoubleDistanceDBIDPair getDistancePair() { - return get(pos); - } - - @Override - public int getOffset() { - return pos; - } - - @Override - public void advance(int count) { - pos += count; - } - - @Override - public void retract() { - --pos; - } - - @Override - public void seek(int off) { - pos = off; - } - } -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNListHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNListHeap.java deleted file mode 100644 index ca00129b..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceDBIDPairKNNListHeap.java +++ /dev/null @@ -1,289 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.generic; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import java.util.Arrays; - -import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Finalized KNN List. - * - * @author Erich Schubert - * - * @apiviz.composedOf DoubleDistanceDBIDPair - * @apiviz.has DoubleDistanceDBIDListIter - */ -public class DoubleDistanceDBIDPairKNNListHeap implements DoubleDistanceKNNList, DoubleDistanceKNNHeap { - /** - * The value of k this was materialized for. - */ - private final int k; - - /** - * The actual data array. - */ - private DoubleDistanceDBIDPair[] data; - - /** - * Current size - */ - private int size; - - /** - * Constructor. - * - * @param k K parameter - */ - public DoubleDistanceDBIDPairKNNListHeap(int k) { - super(); - this.data = new DoubleDistanceDBIDPair[k + 11]; - this.k = k; - } - - @Override - public void clear() { - size = 0; - Arrays.fill(data, null); - } - - @Override - public double insert(double distance, DBIDRef id) { - if (size < k || distance <= data[k - 1].doubleDistance()) { - insert(DBIDUtil.newDistancePair(distance, id)); - } - return (size < k) ? Double.POSITIVE_INFINITY : get(k - 1).doubleDistance(); - } - - @Override - @Deprecated - public void insert(Double distance, DBIDRef id) { - insert(DBIDUtil.newDistancePair(distance.doubleValue(), id)); - } - - @Override - @Deprecated - public void insert(DoubleDistance dist, DBIDRef id) { - insert(DBIDUtil.newDistancePair(dist.doubleValue(), id)); - } - - @Override - public void insert(DoubleDistanceDBIDPair e) { - if (size >= k) { - if (e.doubleDistance() > data[size - 1].doubleDistance()) { - return; - } - // Ensure we have enough space. - final int len = data.length; - if (size > len) { - final int newlength = len + (len >>> 1); - assert (newlength > size); - data = Arrays.copyOf(data, newlength); - } - } - insertionSort(e); - // Truncate if necessary: - if (size > k && data[k].doubleDistance() > data[k - 1].doubleDistance()) { - size = k; - } - } - - /** - * Perform insertion sort. - * - * @param obj Object to insert - */ - private void insertionSort(DoubleDistanceDBIDPair obj) { - // Insertion sort: - int pos = size; - while (pos > 0) { - DoubleDistanceDBIDPair pobj = data[pos - 1]; - if (pobj.doubleDistance() <= obj.doubleDistance()) { - break; - } - data[pos] = pobj; - --pos; - } - data[pos] = obj; - ++size; - } - - @Override - public DoubleDistanceDBIDPair poll() { - assert (size > 0); - return data[size--]; - } - - @Override - public DoubleDistanceDBIDPair peek() { - assert (size > 0); - return data[size - 1]; - } - - @Override - public DoubleDistanceKNNList toKNNList() { - return this; - } - - @Override - public int getK() { - return k; - } - - @Override - @Deprecated - public DoubleDistance getKNNDistance() { - if (size < k) { - return DoubleDistance.INFINITE_DISTANCE; - } - return get(k - 1).getDistance(); - } - - @Override - public double doubleKNNDistance() { - return (size < k) ? Double.POSITIVE_INFINITY : get(k - 1).doubleDistance(); - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append("kNNList["); - for (DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) { - buf.append(iter.doubleDistance()).append(':').append(DBIDUtil.toString(iter)); - iter.advance(); - if (iter.valid()) { - buf.append(','); - } - } - buf.append(']'); - return buf.toString(); - } - - @Override - public DoubleDistanceDBIDPair get(int index) { - return data[index]; - } - - @Override - public DoubleDistanceDBIDListIter iter() { - return new Itr(); - } - - @Override - public int size() { - return data.length; - } - - @Override - public boolean contains(DBIDRef o) { - for (DBIDIter iter = iter(); iter.valid(); iter.advance()) { - if (DBIDUtil.equal(iter, o)) { - return true; - } - } - return false; - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - /** - * Iterator. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - private class Itr implements DoubleDistanceDBIDListIter { - /** - * Cursor position. - */ - private int pos = 0; - - @Override - public int internalGetIndex() { - return get(pos).internalGetIndex(); - } - - @Override - public boolean valid() { - return pos < data.length; - } - - @Override - public void advance() { - pos++; - } - - /** - * {@inheritDoc} - * - * @deprecated use {@link #doubleDistance}! - */ - @Override - @Deprecated - public DoubleDistance getDistance() { - return get(pos).getDistance(); - } - - @Override - public double doubleDistance() { - return get(pos).doubleDistance(); - } - - @Override - public DoubleDistanceDBIDPair getDistancePair() { - return get(pos); - } - - @Override - public int getOffset() { - return pos; - } - - @Override - public void advance(int count) { - pos += count; - } - - @Override - public void retract() { - --pos; - } - - @Override - public void seek(int off) { - pos = off; - } - } -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/GenericDistanceDBIDList.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/GenericDistanceDBIDList.java deleted file mode 100644 index 911c58e7..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/GenericDistanceDBIDList.java +++ /dev/null @@ -1,206 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.generic; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import java.util.Arrays; -import java.util.Comparator; - -import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory; -import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDistanceDBIDList; -import de.lmu.ifi.dbs.elki.distance.distanceresultlist.DistanceDBIDResultUtil; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; - -/** - * Default class to keep a list of distance-object pairs. - * - * @author Erich Schubert - * - * @param <D> Distance type - */ -public class GenericDistanceDBIDList<D extends Distance<D>> implements ModifiableDistanceDBIDList<D> { - /** - * Actual storage. - */ - Object[] storage; - - /** - * Current size. - */ - int size = 0; - - /** - * Constructor. - */ - public GenericDistanceDBIDList() { - super(); - storage = new Object[21]; - } - - /** - * Constructor. - * - * @param initialCapacity Capacity - */ - public GenericDistanceDBIDList(int initialCapacity) { - super(); - storage = new Object[initialCapacity]; - } - - @Override - public void add(D dist, DBIDRef id) { - ensureSize(size + 1); - storage[size] = DBIDFactory.FACTORY.newDistancePair(dist, id); - ++size; - } - - /** - * Add a prepared pair. - * - * @param pair Pair to add - */ - public void add(DistanceDBIDPair<D> pair) { - ensureSize(size + 1); - storage[size] = pair; - ++size; - } - - private void ensureSize(int size) { - if (size < storage.length) { - storage = Arrays.copyOf(storage, (size << 1) + 1); - } - } - - @Override - public void sort() { - @SuppressWarnings("unchecked") - final Comparator<Object> comp = (Comparator<Object>) DistanceDBIDResultUtil.distanceComparator(); - Arrays.sort(storage, 0, size, comp); - // DistanceDBIDResultUtil.sortByDistance(storage); - } - - @Override - public int size() { - return size; - } - - @SuppressWarnings("unchecked") - @Override - public DistanceDBIDPair<D> get(int off) { - return (DistanceDBIDPair<D>) storage[off]; - } - - @Override - public DistanceDBIDListIter<D> iter() { - return new Itr(); - } - - @Override - public boolean contains(DBIDRef o) { - for (DBIDIter iter = iter(); iter.valid(); iter.advance()) { - if (DBIDUtil.equal(iter, o)) { - return true; - } - } - return false; - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public String toString() { - return DistanceDBIDResultUtil.toString(this); - } - - /** - * Iterator class. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - protected class Itr implements DistanceDBIDListIter<D> { - /** - * Iterator position. - */ - int pos = 0; - - @Override - public int internalGetIndex() { - return get(pos).internalGetIndex(); - } - - @Override - public boolean valid() { - return pos < size(); - } - - @Override - public void advance() { - pos++; - } - - @Override - public D getDistance() { - return get(pos).getDistance(); - } - - @Override - public DistanceDBIDPair<D> getDistancePair() { - return get(pos); - } - - @Override - public String toString() { - return valid() ? getDistancePair().toString() : "null"; - } - - @Override - public int getOffset() { - return pos; - } - - @Override - public void advance(int count) { - pos += count; - } - - @Override - public void retract() { - --pos; - } - - @Override - public void seek(int off) { - pos = off; - } - } -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/KNNSubList.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/KNNSubList.java index 3d7863fd..6bfb05b0 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/KNNSubList.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/generic/KNNSubList.java @@ -1,18 +1,10 @@ package de.lmu.ifi.dbs.elki.database.ids.generic; -import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; - /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -30,15 +22,19 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; +import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; +import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair; +import de.lmu.ifi.dbs.elki.database.ids.KNNList; /** * Sublist of an existing result to contain only the first k elements. * * @author Erich Schubert - * - * @param <D> Distance */ -public class KNNSubList<D extends Distance<D>> implements KNNList<D> { +public class KNNSubList implements KNNList { /** * Parameter k. */ @@ -52,7 +48,7 @@ public class KNNSubList<D extends Distance<D>> implements KNNList<D> { /** * Wrapped inner result. */ - private final KNNList<D> inner; + private final KNNList inner; /** * Constructor. @@ -60,22 +56,24 @@ public class KNNSubList<D extends Distance<D>> implements KNNList<D> { * @param inner Inner instance * @param k k value */ - public KNNSubList(KNNList<D> inner, int k) { + public KNNSubList(KNNList inner, int k) { this.inner = inner; this.k = k; // Compute list size - // TODO: optimize for double distances. - { - DistanceDBIDPair<D> dist = inner.get(k); + if(k < inner.getK()) { + DoubleDBIDPair dist = inner.get(k); int i = k; - while (i + 1 < inner.size()) { - if (dist.compareByDistance(inner.get(i + 1)) < 0) { + while(i + 1 < inner.size()) { + if(dist.doubleValue() < inner.get(i + 1).doubleValue()) { break; } i++; } size = i; } + else { + size = inner.size(); + } } @Override @@ -84,25 +82,25 @@ public class KNNSubList<D extends Distance<D>> implements KNNList<D> { } @Override - public DistanceDBIDPair<D> get(int index) { + public DoubleDBIDPair get(int index) { assert (index < size) : "Access beyond design size of list."; return inner.get(index); } @Override - public D getKNNDistance() { - return inner.get(k).getDistance(); + public double getKNNDistance() { + return inner.get(k).doubleValue(); } @Override - public DistanceDBIDListIter<D> iter() { + public DoubleDBIDListIter iter() { return new Itr(); } @Override public boolean contains(DBIDRef o) { - for (DBIDIter iter = iter(); iter.valid(); iter.advance()) { - if (DBIDUtil.equal(iter, o)) { + for(DBIDIter iter = iter(); iter.valid(); iter.advance()) { + if(DBIDUtil.equal(iter, o)) { return true; } } @@ -126,7 +124,7 @@ public class KNNSubList<D extends Distance<D>> implements KNNList<D> { * * @apiviz.exclude */ - private class Itr implements DistanceDBIDListIter<D> { + private class Itr implements DoubleDBIDListIter { /** * Current position. */ @@ -134,21 +132,22 @@ public class KNNSubList<D extends Distance<D>> implements KNNList<D> { @Override public boolean valid() { - return pos < size; + return pos < size && pos >= 0; } @Override - public void advance() { + public Itr advance() { pos++; + return this; } @Override - public D getDistance() { - return inner.get(pos).getDistance(); + public double doubleValue() { + return inner.get(pos).doubleValue(); } @Override - public DistanceDBIDPair<D> getDistancePair() { + public DoubleDBIDPair getPair() { return inner.get(pos); } @@ -163,18 +162,21 @@ public class KNNSubList<D extends Distance<D>> implements KNNList<D> { } @Override - public void advance(int count) { - pos -= count; + public Itr advance(int count) { + pos += count; + return this; } @Override - public void retract() { + public Itr retract() { --pos; + return this; } @Override - public void seek(int off) { + public Itr seek(int off) { pos = off; + return this; } } } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/MaskedDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/MaskedDBIDs.java index 2b481fca..19162450 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/MaskedDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/generic/MaskedDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.generic; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -35,6 +35,8 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDs; /** * View on an ArrayDBIDs masked using a BitMask for efficient mask changing. * + * FIXME: switch to long[] instead of BitSet + * * @author Erich Schubert * * @apiviz.uses DBIDs @@ -137,8 +139,9 @@ public class MaskedDBIDs implements DBIDs { } @Override - public void advance() { + public DBIDIter advance() { pos = bits.nextSetBit(pos + 1); + return this; } @Override @@ -180,8 +183,9 @@ public class MaskedDBIDs implements DBIDs { } @Override - public void advance() { + public DBIDIter advance() { pos = bits.nextClearBit(pos + 1); + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/MergedDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/MergedDBIDs.java deleted file mode 100644 index 7df6975c..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/MergedDBIDs.java +++ /dev/null @@ -1,83 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.generic; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DBIDs; -import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; - -/** - * Merge the IDs of multiple layers into one. - * - * @author Erich Schubert - * - * @apiviz.uses de.lmu.ifi.dbs.elki.database.ids.DBIDs - */ -// TODO: include ID mapping? -public class MergedDBIDs implements DBIDs { - /** - * Childs to merge - */ - DBIDs childs[]; - - /** - * Constructor. - * - * @param childs - */ - public MergedDBIDs(DBIDs... childs) { - super(); - this.childs = childs; - } - - @Override - public DBIDIter iter() { - throw new AbortException("Merged iterators not completely implemented yet!"); - } - - @Override - public int size() { - int si = 0; - for(DBIDs child : childs) { - si += child.size(); - } - return si; - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public boolean contains(DBIDRef o) { - for(DBIDs child : childs) { - if(child.contains(o)) { - return true; - } - } - return false; - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableArrayDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableArrayDBIDs.java index 49c6b07e..0b5d8ed2 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableArrayDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableArrayDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.generic; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -131,8 +131,9 @@ public class UnmodifiableArrayDBIDs implements ArrayStaticDBIDs { } @Override - public void advance() { + public DBIDArrayIter advance() { it.advance(); + return this; } @Override @@ -141,18 +142,21 @@ public class UnmodifiableArrayDBIDs implements ArrayStaticDBIDs { } @Override - public void advance(int count) { + public DBIDArrayIter advance(int count) { it.advance(count); + return this; } @Override - public void retract() { + public DBIDArrayIter retract() { it.retract(); + return this; } @Override - public void seek(int off) { + public DBIDArrayIter seek(int off) { it.seek(off); + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableDBIDs.java index 458dab3f..0f4920a5 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/generic/UnmodifiableDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.generic; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -109,8 +109,9 @@ public class UnmodifiableDBIDs implements StaticDBIDs { } @Override - public void advance() { + public DBIDIter advance() { it.advance(); + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/package-info.java b/src/de/lmu/ifi/dbs/elki/database/ids/generic/package-info.java index 9920cac7..e2232e18 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/generic/package-info.java @@ -7,7 +7,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/AbstractIntegerDBIDFactory.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/AbstractIntegerDBIDFactory.java index 72ecb9be..2317ac43 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/AbstractIntegerDBIDFactory.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/AbstractIntegerDBIDFactory.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -31,17 +31,11 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDVar; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair; import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList; -import de.lmu.ifi.dbs.elki.database.ids.generic.DistanceDBIDPairKNNHeap; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; -import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer; -import de.lmu.ifi.dbs.elki.persistent.FixedSizeByteBufferSerializer; +import de.lmu.ifi.dbs.elki.database.ids.KNNHeap; +import de.lmu.ifi.dbs.elki.database.ids.KNNList; +import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList; +import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer; +import de.lmu.ifi.dbs.elki.utilities.io.FixedSizeByteBufferSerializer; /** * Abstract base class for DBID factories. @@ -89,7 +83,7 @@ abstract class AbstractIntegerDBIDFactory implements DBIDFactory { @Override public String toString(DBIDRef id) { - return Integer.toString(id.internalGetIndex()); + return (id != null) ? Integer.toString(id.internalGetIndex()) : "null"; } @Override @@ -134,60 +128,32 @@ abstract class AbstractIntegerDBIDFactory implements DBIDFactory { @Override public DoubleDBIDPair newPair(double val, DBIDRef id) { - return new IntegerDoubleDBIDPair(val, id.internalGetIndex()); + return new DoubleIntegerDBIDPair(val, id.internalGetIndex()); } - @SuppressWarnings("unchecked") @Override - public <D extends Distance<D>> DistanceDBIDPair<D> newDistancePair(D val, DBIDRef id) { - if(val instanceof DoubleDistance) { - return (DistanceDBIDPair<D>) new DoubleDistanceIntegerDBIDPair(((DoubleDistance) val).doubleValue(), id.internalGetIndex()); - } - return new DistanceIntegerDBIDPair<>(val, id.internalGetIndex()); - } - - @Override - public DoubleDistanceDBIDPair newDistancePair(double val, DBIDRef id) { - return new DoubleDistanceIntegerDBIDPair(val, id.internalGetIndex()); + public KNNHeap newHeap(int k) { + return new DoubleIntegerDBIDKNNHeap(k); } - @SuppressWarnings("unchecked") @Override - public <D extends Distance<D>> KNNHeap<D> newHeap(D factory, int k) { - if(factory instanceof DoubleDistance) { - return (KNNHeap<D>) newDoubleDistanceHeap(k); + public KNNHeap newHeap(KNNList exist) { + KNNHeap heap = newHeap(exist.getK()); + // Insert backwards, as this will produce a proper heap + for(int i = exist.size() - 1; i >= 0; i--) { + heap.insert(exist.get(i)); } - return new DistanceDBIDPairKNNHeap<>(k); + return heap; } - @SuppressWarnings("unchecked") @Override - public <D extends Distance<D>> KNNHeap<D> newHeap(KNNList<D> exist) { - if(exist instanceof DoubleDistanceKNNList) { - DoubleDistanceKNNHeap heap = newDoubleDistanceHeap(exist.getK()); - // Insert backwards, as this will produce a proper heap - for(int i = exist.size() - 1; i >= 0; i--) { - heap.insert((DoubleDistanceDBIDPair) exist.get(i)); - } - return (KNNHeap<D>) heap; - } - else { - DistanceDBIDPairKNNHeap<D> heap = new DistanceDBIDPairKNNHeap<>(exist.getK()); - // Insert backwards, as this will produce a proper heap - for(int i = exist.size() - 1; i >= 0; i--) { - heap.insert(exist.get(i)); - } - return heap; - } + public ModifiableDoubleDBIDList newDistanceDBIDList(int size) { + return new DoubleIntegerDBIDList(size); } @Override - public DoubleDistanceKNNHeap newDoubleDistanceHeap(int k) { - // TODO: benchmark threshold! - if(k > 1000) { - return new DoubleDistanceIntegerDBIDKNNHeap(k); - } - return new DoubleDistanceIntegerDBIDSortedKNNList(k); + public ModifiableDoubleDBIDList newDistanceDBIDList() { + return new DoubleIntegerDBIDList(); } @Override diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayModifiableIntegerDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayModifiableIntegerDBIDs.java index 2fc94ddb..1ead59b6 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayModifiableIntegerDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayModifiableIntegerDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -38,7 +38,7 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDs; * * @author Erich Schubert */ -public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, IntegerArrayDBIDs { +class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, IntegerArrayDBIDs { /** * The actual Trove array list. */ @@ -292,8 +292,9 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege } @Override - public void advance() { + public Itr advance() { ++pos; + return this; } @Override @@ -302,18 +303,21 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege } @Override - public void advance(int count) { + public Itr advance(int count) { pos += count; + return this; } @Override - public void retract() { + public Itr retract() { --pos; + return this; } @Override - public void seek(int off) { + public Itr seek(int off) { pos = off; + return this; } @Override @@ -423,8 +427,9 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege } @Override - public void advance() { + public SliceItr advance() { ++pos; + return this; } @Override @@ -433,18 +438,21 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege } @Override - public void advance(int count) { + public SliceItr advance(int count) { pos += count; + return this; } @Override - public void retract() { + public SliceItr retract() { --pos; + return this; } @Override - public void seek(int off) { + public SliceItr seek(int off) { pos = off; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayStaticIntegerDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayStaticIntegerDBIDs.java index fcb426ac..60d43ff8 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayStaticIntegerDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayStaticIntegerDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -37,7 +37,7 @@ import de.lmu.ifi.dbs.elki.logging.LoggingUtil; * * @author Erich Schubert */ -public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs { +class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs { /** * The actual storage. */ @@ -48,7 +48,7 @@ public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs { * * @param ids Array of ids. */ - public ArrayStaticIntegerDBIDs(int... ids) { + protected ArrayStaticIntegerDBIDs(int... ids) { super(); this.store = ids; } @@ -123,23 +123,27 @@ public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs { } @Override - public void advance() { + public Itr advance() { pos++; + return this; } @Override - public void advance(int count) { + public Itr advance(int count) { pos += 0; + return this; } @Override - public void retract() { + public Itr retract() { pos--; + return this; } @Override - public void seek(int off) { + public Itr seek(int off) { pos = off; + return this; } @Override @@ -262,8 +266,9 @@ public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs { } @Override - public void advance() { + public SliceItr advance() { ++pos; + return this; } @Override @@ -272,18 +277,21 @@ public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs { } @Override - public void advance(int count) { + public SliceItr advance(int count) { pos += count; + return this; } @Override - public void retract() { + public SliceItr retract() { --pos; + return this; } @Override - public void seek(int off) { + public SliceItr seek(int off) { pos = begin + off; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DistanceIntegerDBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DistanceIntegerDBIDPair.java deleted file mode 100644 index a8930b87..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DistanceIntegerDBIDPair.java +++ /dev/null @@ -1,101 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.integer; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; -import de.lmu.ifi.dbs.elki.utilities.Util; - -/** - * Class storing a double distance a DBID. - * - * @author Erich Schubert - * - * @param <D> Distance type - */ -class DistanceIntegerDBIDPair<D extends Distance<D>> implements DistanceDBIDPair<D>, IntegerDBIDRef { - /** - * The distance value. - */ - D distance; - - /** - * The integer DBID. - */ - int id; - - /** - * Constructor. - * - * @param distance Distance - * @param id Object ID - */ - protected DistanceIntegerDBIDPair(D distance, int id) { - super(); - this.distance = distance; - this.id = id; - } - - @Override - public D getDistance() { - return distance; - } - - @Override - public int internalGetIndex() { - return id; - } - - @Override - public int compareByDistance(DistanceDBIDPair<D> o) { - return distance.compareTo(o.getDistance()); - } - - @Override - public String toString() { - return distance.toString() + ":" + id; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o instanceof DistanceIntegerDBIDPair) { - DistanceIntegerDBIDPair<?> p = (DistanceIntegerDBIDPair<?>) o; - return (this.id == p.id) && distance.equals(p.getDistance()); - } - if (o instanceof DoubleDistanceIntegerDBIDPair && distance instanceof DoubleDistance) { - DoubleDistanceIntegerDBIDPair p = (DoubleDistanceIntegerDBIDPair) o; - return (this.id == p.id) && (Double.compare(((DoubleDistance) this.distance).doubleValue(), p.distance) == 0); - } - return false; - } - - @Override - public int hashCode() { - return Util.mixHashCodes(distance.hashCode(), id); - } -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPair.java deleted file mode 100644 index 1f3b2a45..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPair.java +++ /dev/null @@ -1,110 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.integer; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; -import de.lmu.ifi.dbs.elki.utilities.Util; - -/** - * Class storing a double distance a DBID. - * - * @author Erich Schubert - */ -class DoubleDistanceIntegerDBIDPair implements DoubleDistanceDBIDPair, IntegerDBIDRef { - /** - * The distance value. - */ - final double distance; - - /** - * The integer DBID. - */ - final int id; - - /** - * Constructor. - * - * @param distance Distance value - * @param id integer object ID - */ - protected DoubleDistanceIntegerDBIDPair(double distance, int id) { - super(); - this.distance = distance; - this.id = id; - } - - @Override - public double doubleDistance() { - return distance; - } - - @Override - @Deprecated - public DoubleDistance getDistance() { - return new DoubleDistance(distance); - } - - @Override - public int internalGetIndex() { - return id; - } - - @Override - public int compareByDistance(DistanceDBIDPair<DoubleDistance> o) { - if (o instanceof DoubleDistanceDBIDPair) { - return Double.compare(distance, ((DoubleDistanceDBIDPair) o).doubleDistance()); - } - return Double.compare(distance, o.getDistance().doubleValue()); - } - - @Override - public String toString() { - return distance + ":" + id; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o instanceof DoubleDistanceIntegerDBIDPair) { - DoubleDistanceIntegerDBIDPair p = (DoubleDistanceIntegerDBIDPair) o; - return (this.id == p.id) && (Double.compare(this.distance, p.distance) == 0); - } - if (o instanceof DistanceIntegerDBIDPair) { - DistanceIntegerDBIDPair<?> p = (DistanceIntegerDBIDPair<?>) o; - if (p.distance instanceof DoubleDistance) { - return (this.id == p.id) && (Double.compare(this.distance, ((DoubleDistance) p.distance).doubleValue()) == 0); - } - } - return false; - } - - @Override - public int hashCode() { - long bits = Double.doubleToLongBits(distance); - return Util.mixHashCodes((int) (bits ^ (bits >>> 32)), id); - } -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairKNNListHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairKNNListHeap.java deleted file mode 100644 index aa0a9739..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairKNNListHeap.java +++ /dev/null @@ -1,339 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.integer; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Finalized KNN List. - * - * @author Erich Schubert - * - * @apiviz.composedOf DoubleDistanceDBIDPair - * @apiviz.has DoubleDistanceDBIDListIter - */ -public class DoubleDistanceIntegerDBIDPairKNNListHeap implements DoubleDistanceKNNList, DoubleDistanceKNNHeap { - /** - * The value of k this was materialized for. - */ - private final int k; - - /** - * The actual data array. - */ - private DoubleDistanceIntegerDBIDPair[] data; - - /** - * Current size - */ - private int size; - - /** - * Constructor. - * - * @param k K parameter - */ - public DoubleDistanceIntegerDBIDPairKNNListHeap(int k) { - super(); - this.data = new DoubleDistanceIntegerDBIDPair[k + 5]; - this.k = k; - this.size = 0; - } - - @Override - public void clear() { - for(int i = 0; i < size; i++) { - data[i] = null; // discard - } - size = 0; - } - - @Override - public double insert(double distance, DBIDRef id) { - final int kminus1 = k - 1; - if(size < k || distance <= data[kminus1].doubleDistance()) { - // Ensure we have enough space. - if(size > data.length) { - grow(); - } - insertionSort(new DoubleDistanceIntegerDBIDPair(distance, id.internalGetIndex())); - // Truncate if necessary: - if(size > k && data[k].doubleDistance() > data[kminus1].doubleDistance()) { - truncate(); - } - } - return (size < k) ? Double.POSITIVE_INFINITY : get(kminus1).doubleDistance(); - } - - private void truncate() { - for(int i = k; i < size; i++) { - data[i] = null; // discard - } - size = k; - } - - @Override - @Deprecated - public void insert(Double distance, DBIDRef id) { - final int kminus1 = k - 1; - if(size < k || distance.doubleValue() <= data[kminus1].doubleDistance()) { - // Ensure we have enough space. - if(size > data.length) { - grow(); - } - insertionSort(new DoubleDistanceIntegerDBIDPair(distance.doubleValue(), id.internalGetIndex())); - // Truncate if necessary: - if(size > k && data[k].doubleDistance() > data[kminus1].doubleDistance()) { - truncate(); - } - } - } - - @Override - @Deprecated - public void insert(DoubleDistance dist, DBIDRef id) { - final int kminus1 = k - 1; - if(size < k || dist.doubleValue() <= data[kminus1].doubleDistance()) { - // Ensure we have enough space. - if(size > data.length) { - grow(); - } - insertionSort(new DoubleDistanceIntegerDBIDPair(dist.doubleValue(), id.internalGetIndex())); - // Truncate if necessary: - if(size > k && data[k].doubleDistance() > data[kminus1].doubleDistance()) { - truncate(); - } - } - } - - @Override - public void insert(DoubleDistanceDBIDPair e) { - final int kminus1 = k - 1; - final double dist = e.doubleDistance(); - if(size < k || dist <= data[kminus1].doubleDistance()) { - // Ensure we have enough space. - if(size > data.length) { - grow(); - } - if(e instanceof DoubleDistanceIntegerDBIDPair) { - insertionSort((DoubleDistanceIntegerDBIDPair) e); - } - else { - insertionSort(new DoubleDistanceIntegerDBIDPair(dist, e.internalGetIndex())); - } - // Truncate if necessary: - if(size > k && data[k].doubleDistance() > data[kminus1].doubleDistance()) { - truncate(); - } - } - } - - /** - * Perform insertion sort. - * - * @param obj Object to insert - */ - private void insertionSort(DoubleDistanceIntegerDBIDPair obj) { - // Insertion sort: - int pos = size; - while(pos > 0) { - final int prev = pos - 1; - DoubleDistanceIntegerDBIDPair pobj = data[prev]; - if(pobj.doubleDistance() <= obj.doubleDistance()) { - break; - } - data[pos] = pobj; - pos = prev; - } - data[pos] = obj; - ++size; - } - - private void grow() { - final DoubleDistanceIntegerDBIDPair[] old = data; - data = new DoubleDistanceIntegerDBIDPair[data.length + (data.length >> 1)]; - System.arraycopy(old, 0, data, 0, old.length); - } - - @Override - public DoubleDistanceIntegerDBIDPair poll() { - assert (size > 0); - return data[size--]; - } - - @Override - public DoubleDistanceIntegerDBIDPair peek() { - assert (size > 0); - return data[size - 1]; - } - - @Override - public DoubleDistanceKNNList toKNNList() { - return this; - } - - @Override - public int getK() { - return k; - } - - @Override - @Deprecated - public DoubleDistance getKNNDistance() { - if(size < k) { - return DoubleDistance.INFINITE_DISTANCE; - } - return get(k - 1).getDistance(); - } - - @Override - public double doubleKNNDistance() { - if(size < k) { - return Double.POSITIVE_INFINITY; - } - return get(k - 1).doubleDistance(); - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(); - buf.append("kNNList["); - for(DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) { - buf.append(iter.doubleDistance()).append(':').append(DBIDUtil.toString(iter)); - iter.advance(); - if(iter.valid()) { - buf.append(','); - } - } - buf.append(']'); - return buf.toString(); - } - - @Override - public DoubleDistanceIntegerDBIDPair get(int index) { - return data[index]; - } - - @Override - public DoubleDistanceIntegerDBIDListIter iter() { - return new Itr(); - } - - @Override - public int size() { - return size; - } - - @Override - public boolean contains(DBIDRef o) { - for(DBIDIter iter = iter(); iter.valid(); iter.advance()) { - if(DBIDUtil.equal(iter, o)) { - return true; - } - } - return false; - } - - @Override - public boolean isEmpty() { - return size == 0; - } - - /** - * Iterator. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - private class Itr implements DoubleDistanceIntegerDBIDListIter { - /** - * Cursor position. - */ - private int pos = 0; - - @Override - public int internalGetIndex() { - return get(pos).internalGetIndex(); - } - - @Override - public boolean valid() { - return pos < size; - } - - @Override - public void advance() { - pos++; - } - - /** - * {@inheritDoc} - * - * @deprecated use {@link #doubleDistance}! - */ - @Override - @Deprecated - public DoubleDistance getDistance() { - return get(pos).getDistance(); - } - - @Override - public double doubleDistance() { - return get(pos).doubleDistance(); - } - - @Override - public DoubleDistanceIntegerDBIDPair getDistancePair() { - return get(pos); - } - - @Override - public int getOffset() { - return pos; - } - - @Override - public void advance(int count) { - pos += count; - } - - @Override - public void retract() { - --pos; - } - - @Override - public void seek(int off) { - pos = off; - } - } -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerArrayQuickSort.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerArrayQuickSort.java deleted file mode 100644 index 8f1c58d6..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerArrayQuickSort.java +++ /dev/null @@ -1,181 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.ids.integer; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** - * Class to sort a double and an integer DBID array, using a quicksort with a - * best of 5 heuristic. - * - * @author Erich Schubert - */ -class DoubleIntegerArrayQuickSort { - /** - * Threshold for using insertion sort. - */ - private static final int INSERTION_THRESHOLD = 22; - - /** - * Sort the full array using the given comparator. - * - * @param keys Keys for sorting - * @param values Values for sorting - * @param len Length to sort. - */ - public static void sort(double[] keys, int[] values, int len) { - sort(keys, values, 0, len); - } - - /** - * Sort the array using the given comparator. - * - * @param keys Keys for sorting - * @param values Values for sorting - * @param start First index - * @param end Last index (exclusive) - */ - public static void sort(double[] keys, int[] values, int start, int end) { - quickSort(keys, values, start, end); - } - - /** - * Actual recursive sort function. - * - * @param keys Keys for sorting - * @param vals Values for sorting - * @param start First index - * @param end Last index (exclusive!) - */ - private static void quickSort(double[] keys, int[] vals, final int start, final int end) { - final int len = end - start; - if (len < INSERTION_THRESHOLD) { - // Classic insertion sort. - for (int i = start + 1; i < end; i++) { - for (int j = i; j > start; j--) { - if (keys[j] < keys[j - 1]) { - swap(keys, vals, j, j - 1); - } else { - break; - } - } - } - return; - } - - // Choose pivots by looking at five candidates. - final int seventh = (len >> 3) + (len >> 6) + 1; - final int m3 = (start + end) >> 1; // middle - final int m2 = m3 - seventh; - final int m1 = m2 - seventh; - final int m4 = m3 + seventh; - final int m5 = m4 + seventh; - - // Mixture of insertion and merge sort: - if (keys[m1] > keys[m2]) { - swap(keys, vals, m1, m2); - } - if (keys[m3] > keys[m4]) { - swap(keys, vals, m3, m4); - } - // Merge 1+2 and 3+4 - if (keys[m2] > keys[m4]) { - swap(keys, vals, m2, m4); - } - if (keys[m1] > keys[m3]) { - swap(keys, vals, m1, m3); - } - if (keys[m2] > keys[m3]) { - swap(keys, vals, m2, m3); - } - // Insertion sort m5: - if (keys[m4] > keys[m5]) { - swap(keys, vals, m4, m5); - if (keys[m3] > keys[m4]) { - swap(keys, vals, m3, m4); - if (keys[m2] > keys[m3]) { - swap(keys, vals, m2, m3); - if (keys[m1] > keys[m1]) { - swap(keys, vals, m1, m2); - } - } - } - } - - // Move pivot to the front. - double pivotkey = keys[m3]; - int pivotval = vals[m3]; - keys[m3] = keys[start]; - vals[m3] = vals[start]; - - // The interval to pivotize - int left = start + 1; - int right = end - 1; - - // This is the classic QuickSort loop: - while (true) { - while (left <= right && keys[left] <= pivotkey) { - left++; - } - while (left <= right && pivotkey <= keys[right]) { - right--; - } - if (right <= left) { - break; - } - swap(keys, vals, left, right); - left++; - right--; - } - - // Move pivot back into the appropriate place - keys[start] = keys[right]; - vals[start] = vals[right]; - keys[right] = pivotkey; - vals[right] = pivotval; - - // Recursion: - if (start + 1 < right) { - quickSort(keys, vals, start, right); - } - if (right + 2 < end) { - quickSort(keys, vals, right + 1, end); - } - } - - /** - * Swap two entries. - * - * @param keys Keys - * @param vals Values - * @param j First index - * @param i Second index - */ - private static void swap(double[] keys, int[] vals, int j, int i) { - double td = keys[j]; - keys[j] = keys[i]; - keys[i] = td; - int ti = vals[j]; - vals[j] = vals[i]; - vals[i] = ti; - } -} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDKNNHeap.java index 96babaa3..45a247f9 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNHeap.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDKNNHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,9 +26,8 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; import java.util.Arrays; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair; +import de.lmu.ifi.dbs.elki.database.ids.KNNHeap; import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.DoubleIntegerMaxHeap; /** @@ -36,10 +35,10 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.DoubleIntegerMaxHeap; * * @author Erich Schubert * - * @apiviz.has DoubleDistanceIntegerDBIDKNNList + * @apiviz.has DoubleIntegerDBIDKNNList * @apiviz.composedOf DoubleIntegerMaxHeap */ -public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap { +class DoubleIntegerDBIDKNNHeap implements KNNHeap { /** * k for this heap. */ @@ -75,7 +74,7 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap { * * @param k Size of knn. */ - public DoubleDistanceIntegerDBIDKNNHeap(int k) { + protected DoubleIntegerDBIDKNNHeap(int k) { super(); this.k = k; this.heap = new DoubleIntegerMaxHeap(k); @@ -88,66 +87,11 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap { } @Override - @Deprecated - public DoubleDistance getKNNDistance() { - if(heap.size() < k) { - return DoubleDistance.INFINITE_DISTANCE; - } - return new DoubleDistance(kdist); - } - - @Override - public double doubleKNNDistance() { + public double getKNNDistance() { return kdist; } @Override - @Deprecated - public void insert(DoubleDistance distance, DBIDRef id) { - final double dist = distance.doubleValue(); - final int iid = id.internalGetIndex(); - if(heap.size() < k) { - heap.add(dist, iid); - if(heap.size() >= k) { - kdist = heap.peekKey(); - } - return; - } - // Tied with top: - if(dist >= kdist) { - if(dist == kdist) { - addToTies(iid); - } - return; - } - // Old top element: (kdist, previd) - updateHeap(dist, iid); - } - - @Override - @Deprecated - public void insert(Double distance, DBIDRef id) { - final double dist = distance.doubleValue(); - final int iid = id.internalGetIndex(); - if(heap.size() < k) { - heap.add(dist, iid); - if(heap.size() >= k) { - kdist = heap.peekKey(); - } - return; - } - // Tied with top: - if(dist >= kdist) { - if(dist == kdist) { - addToTies(iid); - } - return; - } - // Old top element: (kdist, previd) - updateHeap(dist, iid); - } - - @Override public final double insert(final double distance, final DBIDRef id) { final int iid = id.internalGetIndex(); if(heap.size() < k) { @@ -170,8 +114,8 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap { } @Override - public void insert(final DoubleDistanceDBIDPair e) { - final double distance = e.doubleDistance(); + public void insert(final DoubleDBIDPair e) { + final double distance = e.doubleValue(); final int iid = e.internalGetIndex(); if(heap.size() < k) { heap.add(distance, iid); @@ -225,16 +169,12 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap { } @Override - public DoubleDistanceIntegerDBIDPair poll() { - final DoubleDistanceIntegerDBIDPair ret; + public DoubleIntegerDBIDPair poll() { if(numties > 0) { - ret = new DoubleDistanceIntegerDBIDPair(kdist, ties[numties - 1]); - --numties; - } - else { - ret = new DoubleDistanceIntegerDBIDPair(heap.peekKey(), heap.peekValue()); - heap.poll(); + return new DoubleIntegerDBIDPair(kdist, ties[--numties]); } + final DoubleIntegerDBIDPair ret = new DoubleIntegerDBIDPair(heap.peekKey(), heap.peekValue()); + heap.poll(); return ret; } @@ -251,11 +191,11 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap { } @Override - public DoubleDistanceIntegerDBIDPair peek() { + public DoubleIntegerDBIDPair peek() { if(numties > 0) { - return new DoubleDistanceIntegerDBIDPair(kdist, ties[numties - 1]); + return new DoubleIntegerDBIDPair(kdist, ties[numties - 1]); } - return new DoubleDistanceIntegerDBIDPair(heap.peekKey(), heap.peekValue()); + return new DoubleIntegerDBIDPair(heap.peekKey(), heap.peekValue()); } @Override @@ -265,7 +205,7 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap { @Override public boolean isEmpty() { - return heap.size() == 0; + return heap.isEmpty(); } @Override @@ -275,9 +215,9 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap { } @Override - public DoubleDistanceIntegerDBIDKNNList toKNNList() { + public DoubleIntegerDBIDKNNList toKNNList() { final int hsize = heap.size(); - DoubleDistanceIntegerDBIDKNNList ret = new DoubleDistanceIntegerDBIDKNNList(k, hsize + numties); + DoubleIntegerDBIDKNNList ret = new DoubleIntegerDBIDKNNList(k, hsize + numties); // Add ties: for(int i = 0; i < numties; i++) { ret.dists[hsize + i] = kdist; @@ -289,7 +229,6 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap { heap.poll(); } ret.size = hsize + numties; - ret.sort(); return ret; } @@ -299,12 +238,7 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap { * @return distance */ protected double peekDistance() { - if(numties > 0) { - return kdist; - } - else { - return heap.peekKey(); - } + return (numties > 0) ? kdist : heap.peekKey(); } /** @@ -313,9 +247,6 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap { * @return internal id */ protected int peekInternalDBID() { - if(numties > 0) { - return ties[numties - 1]; - } - return heap.peekValue(); + return (numties > 0) ? ties[numties - 1] : heap.peekValue(); } } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDKNNList.java index f6515d88..b324955a 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNList.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDKNNList.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -22,9 +22,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter; /** * kNN list, but without automatic sorting. Use with care, as others may expect @@ -32,7 +30,7 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; * * @author Erich Schubert */ -public class DoubleDistanceIntegerDBIDKNNList extends DoubleDistanceIntegerDBIDList implements DoubleDistanceKNNList { +public class DoubleIntegerDBIDKNNList extends DoubleIntegerDBIDList implements IntegerDBIDKNNList { /** * The k value this list was generated for. */ @@ -41,7 +39,7 @@ public class DoubleDistanceIntegerDBIDKNNList extends DoubleDistanceIntegerDBIDL /** * Constructor. */ - public DoubleDistanceIntegerDBIDKNNList() { + public DoubleIntegerDBIDKNNList() { super(); this.k = -1; } @@ -52,7 +50,7 @@ public class DoubleDistanceIntegerDBIDKNNList extends DoubleDistanceIntegerDBIDL * @param k K parameter * @param size Actual size */ - public DoubleDistanceIntegerDBIDKNNList(final int k, int size) { + public DoubleIntegerDBIDKNNList(final int k, int size) { super(size); this.k = k; } @@ -62,18 +60,8 @@ public class DoubleDistanceIntegerDBIDKNNList extends DoubleDistanceIntegerDBIDL return k; } - /** - * @deprecated Since you know this is a double distance heap, use - * {@link #doubleKNNDistance()} - */ - @Override - @Deprecated - public DoubleDistance getKNNDistance() { - return new DoubleDistance(doubleKNNDistance()); - } - @Override - public double doubleKNNDistance() { + public double getKNNDistance() { return (size >= k) ? dists[k - 1] : Double.POSITIVE_INFINITY; } @@ -81,10 +69,10 @@ public class DoubleDistanceIntegerDBIDKNNList extends DoubleDistanceIntegerDBIDL public String toString() { StringBuilder buf = new StringBuilder(); buf.append("kNNList["); - for (DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) { - buf.append(iter.doubleDistance()).append(':').append(iter.internalGetIndex()); + for(DoubleDBIDListIter iter = this.iter(); iter.valid();) { + buf.append(iter.doubleValue()).append(':').append(iter.internalGetIndex()); iter.advance(); - if (iter.valid()) { + if(iter.valid()) { buf.append(','); } } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDList.java index 0db0204c..706938d5 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDList.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDList.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,10 +24,10 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDoubleDistanceDBIDList; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair; +import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arrays.DoubleIntegerArrayQuickSort; /** * Class to store double distance, integer DBID results. @@ -36,7 +36,7 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; * * @apiviz.uses DoubleIntegerArrayQuickSort */ -public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDBIDList, IntegerDBIDs { +class DoubleIntegerDBIDList implements ModifiableDoubleDBIDList, IntegerDBIDs { /** * Initial size allocation. */ @@ -70,7 +70,7 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB /** * Constructor. */ - public DoubleDistanceIntegerDBIDList() { + protected DoubleIntegerDBIDList() { dists = EMPTY_DISTS; ids = EMPTY_IDS; } @@ -80,10 +80,10 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB * * @param size Initial size */ - public DoubleDistanceIntegerDBIDList(int size) { + protected DoubleIntegerDBIDList(int size) { this.dists = new double[size]; this.ids = new int[size]; - // This is default anyway: this.size = 0; + // This is default: this.size = 0; } @Override @@ -94,8 +94,8 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB @Override public boolean contains(DBIDRef o) { final int q = o.internalGetIndex(); - for (int i = 0; i < size; i++) { - if (q == ids[i]) { + for(int i = 0; i < size; i++) { + if(q == ids[i]) { return true; } } @@ -113,8 +113,8 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB } @Override - public DoubleDistanceIntegerDBIDPair get(int index) { - return new DoubleDistanceIntegerDBIDPair(dists[index], ids[index]); + public DoubleIntegerDBIDPair get(int index) { + return new DoubleIntegerDBIDPair(dists[index], ids[index]); } /** @@ -124,7 +124,7 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB * @param id Internal index */ protected void addInternal(double dist, int id) { - if (size == dists.length) { + if(size == dists.length) { grow(); } dists[size] = dist; @@ -136,7 +136,7 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB * Grow the data storage. */ protected void grow() { - if (dists == EMPTY_DISTS) { + if(dists == EMPTY_DISTS) { dists = new double[INITIAL_SIZE]; ids = new int[INITIAL_SIZE]; return; @@ -152,19 +152,13 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB } @Override - @Deprecated - public void add(DoubleDistance dist, DBIDRef id) { - addInternal(dist.doubleValue(), id.internalGetIndex()); - } - - @Override public void add(double dist, DBIDRef id) { addInternal(dist, id.internalGetIndex()); } @Override - public void add(DoubleDistanceDBIDPair pair) { - addInternal(pair.doubleDistance(), pair.internalGetIndex()); + public void add(DoubleDBIDPair pair) { + addInternal(pair.doubleValue(), pair.internalGetIndex()); } @Override @@ -182,7 +176,7 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB * Reverse the list. */ protected void reverse() { - for (int i = 0, j = size - 1; i < j; i++, j--) { + for(int i = 0, j = size - 1; i < j; i++, j--) { double tmpd = dists[j]; dists[j] = dists[i]; dists[i] = tmpd; @@ -198,7 +192,7 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB * @param newsize New size */ public void truncate(int newsize) { - if (newsize < size) { + if(newsize < size) { double[] odists = dists; dists = new double[newsize]; System.arraycopy(odists, 0, dists, 0, newsize); @@ -225,11 +219,11 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB @Override public String toString() { StringBuilder buf = new StringBuilder(); - buf.append("DistanceDBIDList["); - for (DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) { - buf.append(iter.doubleDistance()).append(':').append(iter.internalGetIndex()); + buf.append("DoubleDBIDList["); + for(DoubleDBIDListIter iter = this.iter(); iter.valid();) { + buf.append(iter.doubleValue()).append(':').append(iter.internalGetIndex()); iter.advance(); - if (iter.valid()) { + if(iter.valid()) { buf.append(','); } } @@ -244,11 +238,11 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB * * @apiviz.exclude */ - private class Itr implements DoubleDistanceIntegerDBIDListIter { + private class Itr implements DoubleIntegerDBIDListIter, IntegerDBIDArrayIter { /** * Current offset. */ - int offset = 0; + int pos = 0; /** * Constructor. @@ -259,53 +253,51 @@ public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDB @Override public boolean valid() { - return offset < size; + return pos < size && pos >= 0; } @Override - public void advance() { - ++offset; + public Itr advance() { + ++pos; + return this; } @Override public int getOffset() { - return offset; + return pos; } @Override - public void advance(int count) { - offset += count; + public Itr advance(int count) { + pos += count; + return this; } @Override - public void retract() { - --offset; + public Itr retract() { + --pos; + return this; } @Override - public void seek(int off) { - offset = off; + public Itr seek(int off) { + pos = off; + return this; } @Override public int internalGetIndex() { - return ids[offset]; - } - - @Override - public double doubleDistance() { - return dists[offset]; + return ids[pos]; } @Override - public DoubleDistanceDBIDPair getDistancePair() { - return new DoubleDistanceIntegerDBIDPair(dists[offset], ids[offset]); + public double doubleValue() { + return dists[pos]; } @Override - @Deprecated - public DoubleDistance getDistance() { - return new DoubleDistance(dists[offset]); + public DoubleDBIDPair getPair() { + return new DoubleIntegerDBIDPair(dists[pos], ids[pos]); } } } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDListIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDListIter.java index 0df81929..82d19990 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDListIter.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDListIter.java @@ -1,10 +1,9 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; - /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -22,13 +21,14 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter; + +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter; /** - * Combination interface. + * Combination interface of the DoubleDBIDListIter with IntegerDBIDIter. * * @author Erich Schubert */ -public interface DoubleDistanceIntegerDBIDListIter extends DoubleDistanceDBIDListIter, IntegerDBIDArrayIter { - // Yet another painful combination interface. +public interface DoubleIntegerDBIDListIter extends DoubleDBIDListIter, IntegerDBIDIter { + // No additional methods. } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDSortedKNNList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDListKNNHeap.java index c4c60bc0..b2cd9d25 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDSortedKNNList.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDListKNNHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,11 +23,10 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; along with this program. If not, see <http://www.gnu.org/licenses/>. */ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair; +import de.lmu.ifi.dbs.elki.database.ids.KNNHeap; +import de.lmu.ifi.dbs.elki.database.ids.KNNList; /** * Track the k nearest neighbors, with insertion sort to ensure the correct @@ -35,13 +34,13 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; * * @author Erich Schubert */ -public class DoubleDistanceIntegerDBIDSortedKNNList extends DoubleDistanceIntegerDBIDKNNList implements DoubleDistanceKNNHeap { +class DoubleIntegerDBIDListKNNHeap extends DoubleIntegerDBIDKNNList implements KNNHeap { /** * Constructor. * * @param k K parameter */ - public DoubleDistanceIntegerDBIDSortedKNNList(int k) { + protected DoubleIntegerDBIDListKNNHeap(int k) { super(k, k + 11); } @@ -107,36 +106,24 @@ public class DoubleDistanceIntegerDBIDSortedKNNList extends DoubleDistanceIntege } @Override - @Deprecated - public void insert(Double dist, DBIDRef id) { - addInternal(dist.doubleValue(), id.internalGetIndex()); + public void insert(DoubleDBIDPair e) { + addInternal(e.doubleValue(), e.internalGetIndex()); } @Override - public void insert(DoubleDistanceDBIDPair e) { - addInternal(e.doubleDistance(), e.internalGetIndex()); - } - - @Override - @Deprecated - public void insert(DoubleDistance dist, DBIDRef id) { - addInternal(dist.doubleValue(), id.internalGetIndex()); - } - - @Override - public DoubleDistanceIntegerDBIDPair poll() { + public DoubleIntegerDBIDPair poll() { final int last = size - 1; - return new DoubleDistanceIntegerDBIDPair(dists[last], ids[last]); + return new DoubleIntegerDBIDPair(dists[last], ids[last]); } @Override - public DoubleDistanceIntegerDBIDPair peek() { + public DoubleIntegerDBIDPair peek() { final int last = size - 1; - return new DoubleDistanceIntegerDBIDPair(dists[last], ids[last]); + return new DoubleIntegerDBIDPair(dists[last], ids[last]); } @Override - public DoubleDistanceKNNList toKNNList() { + public KNNList toKNNList() { return this; } @@ -144,8 +131,8 @@ public class DoubleDistanceIntegerDBIDSortedKNNList extends DoubleDistanceIntege public String toString() { StringBuilder buf = new StringBuilder(); buf.append("kNNListHeap["); - for(DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) { - buf.append(iter.doubleDistance()).append(':').append(iter.internalGetIndex()); + for(DoubleDBIDListIter iter = this.iter(); iter.valid();) { + buf.append(iter.doubleValue()).append(':').append(iter.internalGetIndex()); iter.advance(); if(iter.valid()) { buf.append(','); diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDoubleDBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPair.java index b522ffb2..563fceb5 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDoubleDBIDPair.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,7 +23,6 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.database.ids.DBID; import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair; /** @@ -31,7 +30,7 @@ import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair; * * @author Erich Schubert */ -class IntegerDoubleDBIDPair implements DoubleDBIDPair, IntegerDBIDRef { +class DoubleIntegerDBIDPair implements DoubleDBIDPair, IntegerDBIDRef { /** * The double value. */ @@ -48,7 +47,7 @@ class IntegerDoubleDBIDPair implements DoubleDBIDPair, IntegerDBIDRef { * @param value Double value * @param id DBID */ - protected IntegerDoubleDBIDPair(double value, int id) { + protected DoubleIntegerDBIDPair(double value, int id) { super(); this.value = value; this.id = id; @@ -68,16 +67,4 @@ class IntegerDoubleDBIDPair implements DoubleDBIDPair, IntegerDBIDRef { public double doubleValue() { return value; } - - @Override - @Deprecated - public Double getFirst() { - return new Double(value); - } - - @Override - @Deprecated - public DBID getSecond() { - return new IntegerDBID(id); - } } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPairKNNListHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPairKNNListHeap.java new file mode 100644 index 00000000..086b5f69 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPairKNNListHeap.java @@ -0,0 +1,286 @@ +package de.lmu.ifi.dbs.elki.database.ids.integer; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; +import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; +import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair; +import de.lmu.ifi.dbs.elki.database.ids.KNNHeap; +import de.lmu.ifi.dbs.elki.database.ids.KNNList; + +/** + * KNN Heap implemented using a list of DoubleInt pair objects. + * + * Currently unused, needs benchmarking. + * + * @author Erich Schubert + * + * @apiviz.composedOf DoubleIntegerDBIDPair + */ +class DoubleIntegerDBIDPairKNNListHeap implements IntegerDBIDKNNList, KNNHeap { + /** + * The value of k this was materialized for. + */ + private final int k; + + /** + * The actual data array. + */ + private DoubleIntegerDBIDPair[] data; + + /** + * Current size + */ + private int size; + + /** + * Constructor. + * + * @param k K parameter + */ + protected DoubleIntegerDBIDPairKNNListHeap(int k) { + super(); + this.data = new DoubleIntegerDBIDPair[k + 5]; + this.k = k; + this.size = 0; + } + + @Override + public void clear() { + for(int i = 0; i < size; i++) { + data[i] = null; // discard + } + size = 0; + } + + @Override + public double insert(double distance, DBIDRef id) { + final int kminus1 = k - 1; + if(size < k || distance <= data[kminus1].doubleValue()) { + // Ensure we have enough space. + if(size > data.length) { + grow(); + } + insertionSort(new DoubleIntegerDBIDPair(distance, id.internalGetIndex())); + // Truncate if necessary: + if(size > k && data[k].doubleValue() > data[kminus1].doubleValue()) { + truncate(); + } + } + return (size < k) ? Double.POSITIVE_INFINITY : get(kminus1).doubleValue(); + } + + private void truncate() { + for(int i = k; i < size; i++) { + data[i] = null; // discard + } + size = k; + } + + @Override + public void insert(DoubleDBIDPair e) { + final int kminus1 = k - 1; + final double dist = e.doubleValue(); + if(size < k || dist <= data[kminus1].doubleValue()) { + // Ensure we have enough space. + if(size > data.length) { + grow(); + } + if(e instanceof DoubleIntegerDBIDPair) { + insertionSort((DoubleIntegerDBIDPair) e); + } + else { + insertionSort(new DoubleIntegerDBIDPair(dist, e.internalGetIndex())); + } + // Truncate if necessary: + if(size > k && data[k].doubleValue() > data[kminus1].doubleValue()) { + truncate(); + } + } + } + + /** + * Perform insertion sort. + * + * @param obj Object to insert + */ + private void insertionSort(DoubleIntegerDBIDPair obj) { + // Insertion sort: + int pos = size; + while(pos > 0) { + final int prev = pos - 1; + DoubleIntegerDBIDPair pobj = data[prev]; + if(pobj.doubleValue() <= obj.doubleValue()) { + break; + } + data[pos] = pobj; + pos = prev; + } + data[pos] = obj; + ++size; + } + + private void grow() { + final DoubleIntegerDBIDPair[] old = data; + data = new DoubleIntegerDBIDPair[data.length + (data.length >> 1)]; + System.arraycopy(old, 0, data, 0, old.length); + } + + @Override + public DoubleIntegerDBIDPair poll() { + assert (size > 0); + return data[size--]; + } + + @Override + public DoubleIntegerDBIDPair peek() { + assert (size > 0); + return data[size - 1]; + } + + @Override + public KNNList toKNNList() { + return this; + } + + @Override + public int getK() { + return k; + } + + @Override + public double getKNNDistance() { + return (size >= k) ? get(k - 1).doubleValue() : Double.POSITIVE_INFINITY; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append("kNNList["); + for(DoubleDBIDListIter iter = this.iter(); iter.valid();) { + buf.append(iter.doubleValue()).append(':').append(DBIDUtil.toString(iter)); + iter.advance(); + if(iter.valid()) { + buf.append(','); + } + } + buf.append(']'); + return buf.toString(); + } + + @Override + public DoubleIntegerDBIDPair get(int index) { + return data[index]; + } + + @Override + public Itr iter() { + return new Itr(); + } + + @Override + public int size() { + return size; + } + + @Override + public boolean contains(DBIDRef o) { + for(DBIDIter iter = iter(); iter.valid(); iter.advance()) { + if(DBIDUtil.equal(iter, o)) { + return true; + } + } + return false; + } + + @Override + public boolean isEmpty() { + return size == 0; + } + + /** + * Iterator. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + private class Itr implements DoubleIntegerDBIDListIter, IntegerDBIDArrayIter { + /** + * Cursor position. + */ + private int pos = 0; + + @Override + public int internalGetIndex() { + return get(pos).internalGetIndex(); + } + + @Override + public boolean valid() { + return pos < size && pos >= 0; + } + + @Override + public Itr advance() { + pos++; + return this; + } + + @Override + public double doubleValue() { + return get(pos).doubleValue(); + } + + @Override + public DoubleIntegerDBIDPair getPair() { + return get(pos); + } + + @Override + public int getOffset() { + return pos; + } + + @Override + public Itr advance(int count) { + pos += count; + return this; + } + + @Override + public Itr retract() { + --pos; + return this; + } + + @Override + public Itr seek(int off) { + pos = off; + return this; + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPairList.java index 5b33d3f9..bee9d47d 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairList.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleIntegerDBIDPairList.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,18 +25,18 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; import java.util.Arrays; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDoubleDistanceDBIDList; -import de.lmu.ifi.dbs.elki.distance.distanceresultlist.DistanceDBIDResultUtil; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair; +import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList; /** * Class to store double distance, integer DBID results. * + * Currently unused. Needs benchmarking. + * * @author Erich Schubert */ -public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistanceDBIDList, IntegerDBIDs { +class DoubleIntegerDBIDPairList implements ModifiableDoubleDBIDList, IntegerDBIDs { /** * The size */ @@ -45,14 +45,14 @@ public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistan /** * Distance values */ - DoubleDistanceIntegerDBIDPair[] data; + DoubleIntegerDBIDPair[] data; /** * Constructor. */ - public DoubleDistanceIntegerDBIDPairList() { + protected DoubleIntegerDBIDPairList() { super(); - this.data = new DoubleDistanceIntegerDBIDPair[21]; + this.data = new DoubleIntegerDBIDPair[21]; } /** @@ -60,24 +60,24 @@ public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistan * * @param size Initial size */ - public DoubleDistanceIntegerDBIDPairList(int size) { + protected DoubleIntegerDBIDPairList(int size) { super(); - if (size > 0) { + if(size > 0) { size = 21; } - this.data = new DoubleDistanceIntegerDBIDPair[size]; + this.data = new DoubleIntegerDBIDPair[size]; } @Override - public DoubleDistanceIntegerDBIDListIter iter() { + public Itr iter() { return new Itr(); } @Override public boolean contains(DBIDRef o) { final int q = o.internalGetIndex(); - for (int i = 0; i < size; i++) { - if (q == data[i].internalGetIndex()) { + for(int i = 0; i < size; i++) { + if(q == data[i].internalGetIndex()) { return true; } } @@ -95,7 +95,7 @@ public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistan } @Override - public DoubleDistanceIntegerDBIDPair get(int index) { + public DoubleIntegerDBIDPair get(int index) { return data[index]; } @@ -104,32 +104,27 @@ public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistan * * @param pair entry */ - protected void addInternal(DoubleDistanceIntegerDBIDPair pair) { - if (size == data.length) { - DoubleDistanceIntegerDBIDPair[] old = data; - data = new DoubleDistanceIntegerDBIDPair[(data.length << 1) + 1]; + protected void addInternal(DoubleIntegerDBIDPair pair) { + if(size == data.length) { + DoubleIntegerDBIDPair[] old = data; + data = new DoubleIntegerDBIDPair[(data.length << 1) + 1]; System.arraycopy(old, 0, data, 0, old.length); } data[size++] = pair; } @Override - @Deprecated - public void add(DoubleDistance dist, DBIDRef id) { - add(dist.doubleValue(), id); - } - - @Override public void add(double dist, DBIDRef id) { - addInternal(new DoubleDistanceIntegerDBIDPair(dist, id.internalGetIndex())); + addInternal(new DoubleIntegerDBIDPair(dist, id.internalGetIndex())); } @Override - public void add(DoubleDistanceDBIDPair pair) { - if (pair instanceof DoubleDistanceIntegerDBIDPair) { - addInternal((DoubleDistanceIntegerDBIDPair) pair); - } else { - addInternal(new DoubleDistanceIntegerDBIDPair(pair.doubleDistance(), pair.internalGetIndex())); + public void add(DoubleDBIDPair pair) { + if(pair instanceof DoubleIntegerDBIDPair) { + addInternal((DoubleIntegerDBIDPair) pair); + } + else { + addInternal(new DoubleIntegerDBIDPair(pair.doubleValue(), pair.internalGetIndex())); } } @@ -141,15 +136,15 @@ public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistan @Override public void sort() { - Arrays.sort(data, 0, size, DistanceDBIDResultUtil.distanceComparator()); + Arrays.sort(data, 0, size); } /** * Reverse the list. */ protected void reverse() { - for (int i = 0, j = size - 1; i < j; i++, j--) { - DoubleDistanceIntegerDBIDPair tmpd = data[j]; + for(int i = 0, j = size - 1; i < j; i++, j--) { + DoubleIntegerDBIDPair tmpd = data[j]; data[j] = data[i]; data[i] = tmpd; } @@ -159,10 +154,10 @@ public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistan public String toString() { StringBuilder buf = new StringBuilder(); buf.append("kNNList["); - for (DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) { - buf.append(iter.doubleDistance()).append(':').append(iter.internalGetIndex()); + for(DoubleDBIDListIter iter = this.iter(); iter.valid();) { + buf.append(iter.doubleValue()).append(':').append(iter.internalGetIndex()); iter.advance(); - if (iter.valid()) { + if(iter.valid()) { buf.append(','); } } @@ -177,58 +172,56 @@ public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistan * * @apiviz.exclude */ - private class Itr implements DoubleDistanceIntegerDBIDListIter { - int offset = 0; + private class Itr implements DoubleDBIDListIter, IntegerDBIDArrayIter { + int pos = 0; @Override public boolean valid() { - return offset < size; + return pos < size && pos >= 0; } @Override - public void advance() { - ++offset; + public Itr advance() { + ++pos; + return this; } @Override public int getOffset() { - return offset; + return pos; } @Override - public void advance(int count) { - offset += count; + public Itr advance(int count) { + pos += count; + return this; } @Override - public void retract() { - offset--; + public Itr retract() { + pos--; + return this; } @Override - public void seek(int off) { - offset = off; + public Itr seek(int off) { + pos = off; + return this; } @Override public int internalGetIndex() { - return data[offset].internalGetIndex(); - } - - @Override - public double doubleDistance() { - return data[offset].doubleDistance(); + return data[pos].internalGetIndex(); } @Override - public DoubleDistanceDBIDPair getDistancePair() { - return data[offset]; + public double doubleValue() { + return data[pos].doubleValue(); } @Override - @Deprecated - public DoubleDistance getDistance() { - return new DoubleDistance(data[offset].doubleDistance()); + public DoubleDBIDPair getPair() { + return data[pos]; } } } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayDBIDs.java index 286bedf9..99519ce8 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayStaticDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayStaticDBIDs.java index 9e18631b..8e82ba3f 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayStaticDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayStaticDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -30,7 +30,7 @@ import de.lmu.ifi.dbs.elki.database.ids.ArrayStaticDBIDs; * * @author Erich Schubert */ -public interface IntegerArrayStaticDBIDs extends ArrayStaticDBIDs, IntegerArrayDBIDs { +interface IntegerArrayStaticDBIDs extends ArrayStaticDBIDs, IntegerArrayDBIDs { @Override IntegerDBIDArrayIter iter(); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBID.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBID.java index 6b7ec5ac..572ec5d9 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBID.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBID.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -32,9 +32,9 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; import de.lmu.ifi.dbs.elki.database.ids.DBIDVar; import de.lmu.ifi.dbs.elki.logging.LoggingUtil; -import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil; -import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer; -import de.lmu.ifi.dbs.elki.persistent.FixedSizeByteBufferSerializer; +import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil; +import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer; +import de.lmu.ifi.dbs.elki.utilities.io.FixedSizeByteBufferSerializer; /** * Database ID object. @@ -185,23 +185,27 @@ final class IntegerDBID implements DBID, IntegerDBIDRef { int pos = 0; @Override - public void advance() { + public Itr advance() { pos++; + return this; } @Override - public void advance(int count) { + public Itr advance(int count) { pos += count; + return this; } @Override - public void retract() { + public Itr retract() { pos--; + return this; } @Override - public void seek(int off) { + public Itr seek(int off) { pos = off; + return this; } @Override @@ -248,7 +252,7 @@ final class IntegerDBID implements DBID, IntegerDBIDRef { /** * Constructor. Protected: use static instance! */ - protected DynamicSerializer() { + public DynamicSerializer() { super(); } @@ -277,7 +281,7 @@ final class IntegerDBID implements DBID, IntegerDBIDRef { /** * Constructor. Protected: use static instance! */ - protected StaticSerializer() { + public StaticSerializer() { super(); } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayIter.java index c604ac71..30255d87 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayIter.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayIter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,6 +29,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter; * * @author Erich Schubert */ -public interface IntegerDBIDArrayIter extends IntegerDBIDIter, DBIDArrayIter { +interface IntegerDBIDArrayIter extends IntegerDBIDIter, DBIDArrayIter { // Empty } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayMIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayMIter.java index dcead6bd..750f7644 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayMIter.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayMIter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,6 +29,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayMIter; * * @author Erich Schubert */ -public interface IntegerDBIDArrayMIter extends IntegerDBIDArrayIter, IntegerDBIDMIter, DBIDArrayMIter { +interface IntegerDBIDArrayMIter extends IntegerDBIDArrayIter, IntegerDBIDMIter, DBIDArrayMIter { // Empty } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayQuickSort.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayQuickSort.java index d6cadf60..03fcb16b 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayQuickSort.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayQuickSort.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDIter.java index 721e6e4e..893649fa 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDIter.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDIter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -31,6 +31,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; * * @apiviz.landmark */ -public interface IntegerDBIDIter extends IntegerDBIDRef, DBIDIter { +interface IntegerDBIDIter extends IntegerDBIDRef, DBIDIter { // Empty } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDKNNList.java index 85182313..d493271e 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/distance/DoubleDistanceDBIDList.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDKNNList.java @@ -1,10 +1,9 @@ -package de.lmu.ifi.dbs.elki.database.ids.distance; - +package de.lmu.ifi.dbs.elki.database.ids.integer; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,17 +22,18 @@ package de.lmu.ifi.dbs.elki.database.ids.distance; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.KNNList; /** - * An object containing Double-DBID-Pairs. + * Combination interface for KNNList and IntegerDBIDs. * * @author Erich Schubert */ -public interface DoubleDistanceDBIDList extends DistanceDBIDList<DoubleDistance> { +public interface IntegerDBIDKNNList extends KNNList, DoubleDBIDList, IntegerDBIDs { @Override - DoubleDistanceDBIDListIter iter(); - + DoubleIntegerDBIDListIter iter(); + @Override - DoubleDistanceDBIDPair get(int off); + public DoubleIntegerDBIDPair get(int index); } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceKNNSubList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDKNNSubList.java index c2854a54..bd53f7e1 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/generic/DoubleDistanceKNNSubList.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDKNNSubList.java @@ -1,10 +1,10 @@ -package de.lmu.ifi.dbs.elki.database.ids.generic; +package de.lmu.ifi.dbs.elki.database.ids.integer; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,19 +25,14 @@ package de.lmu.ifi.dbs.elki.database.ids.generic; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair; /** * Sublist of an existing result to contain only the first k elements. * - * TOOD: can be optimized slightly better. - * * @author Erich Schubert */ -public class DoubleDistanceKNNSubList implements DoubleDistanceKNNList { +public class IntegerDBIDKNNSubList implements IntegerDBIDKNNList { /** * Parameter k. */ @@ -51,7 +46,7 @@ public class DoubleDistanceKNNSubList implements DoubleDistanceKNNList { /** * Wrapped inner result. */ - private final DoubleDistanceKNNList inner; + private final IntegerDBIDKNNList inner; /** * Constructor. @@ -59,21 +54,23 @@ public class DoubleDistanceKNNSubList implements DoubleDistanceKNNList { * @param inner Inner instance * @param k k value */ - public DoubleDistanceKNNSubList(DoubleDistanceKNNList inner, int k) { + public IntegerDBIDKNNSubList(IntegerDBIDKNNList inner, int k) { this.inner = inner; this.k = k; // Compute list size - { - DoubleDistanceDBIDPair dist = inner.get(k); + if(k < inner.getK()) { + DoubleIntegerDBIDListIter iter = inner.iter(); + final double kdist = iter.seek(k - 1).doubleValue(); + // Add all values tied: int i = k; - while (i + 1 < inner.size()) { - if (dist.compareByDistance(inner.get(i + 1)) < 0) { - break; - } + for(iter.advance(); iter.valid() && iter.doubleValue() <= kdist; iter.advance()) { i++; } size = i; } + else { + size = inner.size(); + } } @Override @@ -82,31 +79,25 @@ public class DoubleDistanceKNNSubList implements DoubleDistanceKNNList { } @Override - public DoubleDistanceDBIDPair get(int index) { + public DoubleIntegerDBIDPair get(int index) { assert (index < size) : "Access beyond design size of list."; return inner.get(index); } @Override - @Deprecated - public DoubleDistance getKNNDistance() { - return inner.get(k).getDistance(); - } - - @Override - public double doubleKNNDistance() { - return inner.get(k).doubleDistance(); + public double getKNNDistance() { + return inner.get(k).doubleValue(); } @Override - public DoubleDistanceDBIDListIter iter() { + public DoubleIntegerDBIDListIter iter() { return new Itr(); } @Override public boolean contains(DBIDRef o) { - for (DBIDIter iter = iter(); iter.valid(); iter.advance()) { - if (DBIDUtil.equal(iter, o)) { + for(DBIDIter iter = iter(); iter.valid(); iter.advance()) { + if(DBIDUtil.equal(iter, o)) { return true; } } @@ -130,7 +121,7 @@ public class DoubleDistanceKNNSubList implements DoubleDistanceKNNList { * * @apiviz.exclude */ - private class Itr implements DoubleDistanceDBIDListIter { + private class Itr implements DoubleIntegerDBIDListIter { /** * Current position. */ @@ -138,27 +129,22 @@ public class DoubleDistanceKNNSubList implements DoubleDistanceKNNList { @Override public boolean valid() { - return pos < size; + return pos < size && pos >= 0; } @Override - public void advance() { + public Itr advance() { pos++; + return this; } @Override - @Deprecated - public DoubleDistance getDistance() { - return inner.get(pos).getDistance(); - } - - @Override - public double doubleDistance() { - return inner.get(pos).doubleDistance(); + public double doubleValue() { + return inner.get(pos).doubleValue(); } @Override - public DoubleDistanceDBIDPair getDistancePair() { + public DoubleDBIDPair getPair() { return inner.get(pos); } @@ -173,18 +159,21 @@ public class DoubleDistanceKNNSubList implements DoubleDistanceKNNList { } @Override - public void advance(int count) { + public Itr advance(int count) { pos += count; + return this; } @Override - public void retract() { + public Itr retract() { --pos; + return this; } @Override - public void seek(int off) { + public Itr seek(int off) { pos = off; + return this; } } } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDMIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDMIter.java index c0291d5b..067a257b 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDMIter.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDMIter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,6 +29,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDMIter; * * @author Erich Schubert */ -public interface IntegerDBIDMIter extends DBIDMIter, IntegerDBIDIter { +interface IntegerDBIDMIter extends DBIDMIter, IntegerDBIDIter { // Empty. } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDPair.java index 12e9b685..9c691bc9 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDPair.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDPair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,14 +23,16 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDPair; +import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; /** * DBID pair using two ints for storage. * * @author Erich Schubert */ -public class IntegerDBIDPair implements DBIDPair { +class IntegerDBIDPair implements DBIDPair, IntegerDBIDs { /** * First value in pair */ @@ -47,7 +49,7 @@ public class IntegerDBIDPair implements DBIDPair { * @param first first parameter * @param second second parameter */ - public IntegerDBIDPair(int first, int second) { + protected IntegerDBIDPair(int first, int second) { this.first = first; this.second = second; } @@ -60,36 +62,18 @@ public class IntegerDBIDPair implements DBIDPair { return "Pair(" + first + ", " + second + ")"; } - /** - * Getter for first - * - * @return first element in pair - */ + @Deprecated @Override public final IntegerDBID getFirst() { return new IntegerDBID(first); } - /** - * Getter for second element in pair - * - * @return second element in pair - */ + @Deprecated @Override public final IntegerDBID getSecond() { return new IntegerDBID(second); } - /** - * Simple equals statement. - * - * This Pair equals another Object if they are identical or if the other - * Object is also a Pair and the {@link #first} and {@link #second} element of - * this Pair equal the {@link #first} and {@link #second} element, - * respectively, of the other Pair. - * - * @param obj Object to compare to - */ @Override public boolean equals(Object obj) { if(this == obj) { @@ -118,4 +102,68 @@ public class IntegerDBIDPair implements DBIDPair { result = prime * result + second; return (int) result; } + + @Override + public int size() { + return 2; + } + + @Override + public boolean contains(DBIDRef o) { + final int i = o.internalGetIndex(); + return (i == first) || (i == second); + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public IntegerDBIDIter iter() { + return new Itr(first, second); + } + + /** + * Iterator. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + private static class Itr implements IntegerDBIDIter { + /** + * State + */ + int first, second, pos; + + /** + * Constructor. + * + * @param first First ID + * @param second Second ID + */ + public Itr(int first, int second) { + super(); + this.first = first; + this.second = second; + this.pos = 0; + } + + @Override + public boolean valid() { + return pos < 2; + } + + @Override + public DBIDIter advance() { + ++pos; + return this; + } + + @Override + public int internalGetIndex() { + return (pos == 0) ? first : second; + } + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRange.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRange.java index e418db5f..4b8aed26 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRange.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRange.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -184,23 +184,27 @@ final class IntegerDBIDRange implements IntegerDBIDs, DBIDRange, SetDBIDs { } @Override - public void advance() { + public Itr advance() { ++pos; + return this; } @Override - public void advance(int count) { + public Itr advance(int count) { pos += count; + return this; } @Override - public void retract() { + public Itr retract() { --pos; + return this; } @Override - public void seek(int off) { + public Itr seek(int off) { pos = off; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRef.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRef.java index 0e1e82a9..ddd56209 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRef.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRef.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDVar.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDVar.java index 9120c0d7..c5dfb9b6 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDVar.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDVar.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,6 +25,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.DBID; +import de.lmu.ifi.dbs.elki.database.ids.DBIDPair; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; import de.lmu.ifi.dbs.elki.database.ids.DBIDVar; @@ -49,7 +50,7 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs { * Constructor. */ protected IntegerDBIDVar() { - this.id = -1; + this.id = Integer.MIN_VALUE; } /** @@ -81,8 +82,21 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs { } @Override + public void setFirst(DBIDPair pair) { + assert pair instanceof IntegerDBIDPair; + id = ((IntegerDBIDPair) pair).first; + } + + @Override + public void setSecond(DBIDPair pair) { + assert pair instanceof IntegerDBIDPair; + id = ((IntegerDBIDPair) pair).second; + } + + @Override + @Deprecated public DBID get(int i) { - if (i != 0) { + if(i != 0) { throw new ArrayIndexOutOfBoundsException(); } return new IntegerDBID(i); @@ -90,12 +104,22 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs { @Override public int size() { - return 1; + return id < 0 ? 0 : 1; } @Override public boolean isEmpty() { - return false; + return id < 0; + } + + @Override + public void unset() { + id = Integer.MIN_VALUE; + } + + @Override + public boolean isSet() { + return id > 0; } @Override @@ -111,9 +135,10 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs { @Override public void assignVar(int i, DBIDVar var) { - if (var instanceof IntegerDBIDVar) { + if(var instanceof IntegerDBIDVar) { ((IntegerDBIDVar) var).internalSetIndex(i); - } else { + } + else { // Much less efficient: var.set(get(i)); } @@ -121,9 +146,10 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs { @Override public ArrayDBIDs slice(int begin, int end) { - if (begin == 0 && end == 1) { + if(begin == 0 && end == 1) { return this; - } else { + } + else { return DBIDUtil.EMPTYDBIDS; } } @@ -150,56 +176,60 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs { * Iterator position: We use an integer so we can support retract(). */ int pos = 0; - + @Override - public void advance() { + public Itr advance() { pos++; + return this; } - + @Override - public void advance(int count) { + public Itr advance(int count) { pos += count; + return this; } - + @Override - public void retract() { + public Itr retract() { pos--; + return this; } - + @Override - public void seek(int off) { + public Itr seek(int off) { pos = off; + return this; } - + @Override public int getOffset() { return pos; } - + @Override public int internalGetIndex() { return IntegerDBIDVar.this.id; } - + @Override public boolean valid() { return (pos == 0); } - + @Override public int hashCode() { // Override, because we also are overriding equals. return super.hashCode(); } - + @Override public boolean equals(Object other) { - if (other instanceof DBID) { + if(other instanceof DBID) { LoggingUtil.warning("Programming error detected: DBIDItr.equals(DBID). Use sameDBID()!", new Throwable()); } return super.equals(other); } - + @Override public String toString() { return Integer.toString(internalGetIndex()); diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDs.java index 14faa72a..1abaa423 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ReusingDBIDFactory.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ReusingDBIDFactory.java index ebb36f22..da730f4f 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ReusingDBIDFactory.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ReusingDBIDFactory.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/SimpleDBIDFactory.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/SimpleDBIDFactory.java index c3abd43a..33ddd240 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/SimpleDBIDFactory.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/SimpleDBIDFactory.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -48,7 +48,7 @@ public class SimpleDBIDFactory extends AbstractIntegerDBIDFactory { * The starting point for static DBID range allocations. */ int rangestart = 0; - + /** * Constructor. */ @@ -81,6 +81,16 @@ public class SimpleDBIDFactory extends AbstractIntegerDBIDFactory { } @Override + public DBIDRange generateStaticDBIDRange(int begin, int size) { + if(begin + size >= Integer.MAX_VALUE) { + throw new AbortException("DBID range allocation error - too many objects allocated!"); + } + DBIDRange alloc = new IntegerDBIDRange(begin, size); + rangestart = Math.max(rangestart, begin + size); + return alloc; + } + + @Override public void deallocateDBIDRange(DBIDRange range) { // ignore. } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/TrivialDBIDFactory.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/TrivialDBIDFactory.java index 577c29ac..cc5f6add 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/TrivialDBIDFactory.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/TrivialDBIDFactory.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -55,7 +55,7 @@ final public class TrivialDBIDFactory extends AbstractIntegerDBIDFactory { @Override final public DBID generateSingleDBID() { final int id = next.getAndIncrement(); - if (id == Integer.MAX_VALUE) { + if(id == Integer.MAX_VALUE) { throw new AbortException("DBID allocation error - too many objects allocated!"); } DBID ret = new IntegerDBID(id); @@ -70,7 +70,7 @@ final public class TrivialDBIDFactory extends AbstractIntegerDBIDFactory { @Override final public DBIDRange generateStaticDBIDRange(int size) { final int start = next.getAndAdd(size); - if (start > next.get()) { + if(start > next.get()) { throw new AbortException("DBID range allocation error - too many objects allocated!"); } DBIDRange alloc = new IntegerDBIDRange(start, size); @@ -78,6 +78,22 @@ final public class TrivialDBIDFactory extends AbstractIntegerDBIDFactory { } @Override + public DBIDRange generateStaticDBIDRange(int begin, int size) { + final int end = begin + size; + if(end > Integer.MAX_VALUE) { + throw new AbortException("DBID range allocation error - too many objects allocated!"); + } + DBIDRange alloc = new IntegerDBIDRange(begin, size); + int v; + while((v = next.get()) < end) { + if(next.compareAndSet(v, end)) { + break; + } + } + return alloc; + } + + @Override public void deallocateDBIDRange(DBIDRange range) { // ignore. } diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveHashSetModifiableDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveHashSetModifiableDBIDs.java index 35276606..61007e10 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveHashSetModifiableDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveHashSetModifiableDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -184,8 +184,9 @@ class TroveHashSetModifiableDBIDs implements HashSetModifiableDBIDs, IntegerDBID } @Override - public void advance() { + public IntegerDBIDMIter advance() { it.advance(); + return this; } @Override @@ -237,8 +238,9 @@ class TroveHashSetModifiableDBIDs implements HashSetModifiableDBIDs, IntegerDBID } @Override - public void advance() { + public Iter advance() { this._index = nextIndex(); + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerArrayDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerArrayDBIDs.java index d1c37ab9..1e68cb5a 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerArrayDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerArrayDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,6 +24,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; */ import de.lmu.ifi.dbs.elki.database.ids.DBID; +import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDMIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.DBIDVar; @@ -65,7 +66,7 @@ public class UnmodifiableIntegerArrayDBIDs implements IntegerArrayStaticDBIDs { @Override public IntegerDBIDArrayIter iter() { IntegerDBIDArrayIter it = inner.iter(); - if (it instanceof DBIDMIter) { + if(it instanceof DBIDMIter) { return new UnmodifiableDBIDIter(it); } return it; @@ -128,23 +129,27 @@ public class UnmodifiableIntegerArrayDBIDs implements IntegerArrayStaticDBIDs { } @Override - public void advance() { + public DBIDArrayIter advance() { it.advance(); + return this; } @Override - public void advance(int count) { + public DBIDArrayIter advance(int count) { it.advance(count); + return this; } @Override - public void retract() { + public DBIDArrayIter retract() { it.retract(); + return this; } @Override - public void seek(int off) { + public DBIDArrayIter seek(int off) { it.seek(off); + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerDBIDs.java index a3f03bd9..6ac91c5e 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerDBIDs.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerDBIDs.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,6 +23,7 @@ package de.lmu.ifi.dbs.elki.database.ids.integer; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDMIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.StaticDBIDs; @@ -107,8 +108,9 @@ public class UnmodifiableIntegerDBIDs implements StaticDBIDs, IntegerDBIDs { } @Override - public void advance() { + public DBIDIter advance() { it.advance(); + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/package-info.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/package-info.java index 74a39fb9..661a9cf4 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/package-info.java @@ -10,7 +10,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/package-info.java b/src/de/lmu/ifi/dbs/elki/database/ids/package-info.java index eb0a6733..b4c8fd1f 100644 --- a/src/de/lmu/ifi/dbs/elki/database/ids/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/database/ids/package-info.java @@ -57,8 +57,6 @@ * </ul> * * <h2>Generic utility classes:</h2> - * <p>{@link de.lmu.ifi.dbs.elki.database.ids.generic.MergedDBIDs MergedDBIDs} - * allows virtual concatenation of multiple DBIDs objects.</p> * * <p>{@link de.lmu.ifi.dbs.elki.database.ids.generic.MaskedDBIDs MaskedDBIDs} * allows masking an ArrayDBIDs with a BitSet.</p> @@ -69,21 +67,17 @@ * @apiviz.exclude de.lmu.ifi.dbs.elki.database.ids.EmptyDBIDs.EmptyDBIDIterator * @apiviz.exclude de.lmu.ifi.dbs.elki.database.*Database * @apiviz.exclude de.lmu.ifi.dbs.elki.data.Cluster - * @apiviz.exclude de.lmu.ifi.dbs.elki.utilities.* * @apiviz.exclude de.lmu.ifi.dbs.elki.datasource.filter.* * @apiviz.exclude de.lmu.ifi.dbs.elki.database.query.* - * @apiviz.exclude de.lmu.ifi.dbs.elki.distance.* - * @apiviz.exclude de.lmu.ifi.dbs.elki.index.* - * @apiviz.exclude de.lmu.ifi.dbs.elki.result.* - * @apiviz.exclude de.lmu.ifi.dbs.elki.persistent.* - * @apiviz.exclude de.lmu.ifi.dbs.elki.algorithm.* + * @apiviz.exclude de.lmu.ifi.dbs.elki.(algorithm|evaluation|parallel|distance|index|result|persistent|utilities).* + * @apiviz.exclude de.lmu.ifi.dbs.elki.database.relation.* * @apiviz.exclude java.* */ /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/package-info.java b/src/de/lmu/ifi/dbs/elki/database/package-info.java index 0b5d16ea..99d3a941 100644 --- a/src/de/lmu/ifi/dbs/elki/database/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/database/package-info.java @@ -9,7 +9,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/query/AbstractDataBasedQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/AbstractDataBasedQuery.java deleted file mode 100644 index 5d0e8444..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/query/AbstractDataBasedQuery.java +++ /dev/null @@ -1,59 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.query; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.database.relation.Relation; - -/** - * Abstract query bound to a certain representation. - * - * @author Erich Schubert - * - * @param <O> Database object type - */ -public abstract class AbstractDataBasedQuery<O> implements DatabaseQuery { - /** - * The data to use for this query - */ - final protected Relation<? extends O> relation; - - /** - * Database this query works on. - * - * @param relation Representation - */ - public AbstractDataBasedQuery(Relation<? extends O> relation) { - super(); - this.relation = relation; - } - - /** - * Get the queries relation. - * - * @return Relation - */ - public Relation<? extends O> getRelation() { - return relation; - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/DatabaseQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/DatabaseQuery.java index caba81e3..f88261a8 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/DatabaseQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/DatabaseQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/query/DistanceSimilarityQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/DistanceSimilarityQuery.java index 8906e07c..f0bc7e9a 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/DistanceSimilarityQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/DistanceSimilarityQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,17 +25,15 @@ package de.lmu.ifi.dbs.elki.database.query; import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; import de.lmu.ifi.dbs.elki.database.query.similarity.SimilarityQuery; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** - * Interface that is a combination of distance and a similarity function. - * For combined implementations of both. + * Interface that is a combination of distance and a similarity function. For + * combined implementations of both. * * @author Erich Schubert - * + * * @param <O> Object type - * @param <D> Distance type */ -public interface DistanceSimilarityQuery<O, D extends Distance<D>> extends DistanceQuery<O, D>, SimilarityQuery<O, D> { +public interface DistanceSimilarityQuery<O> extends DistanceQuery<O>, SimilarityQuery<O> { // Empty } diff --git a/src/de/lmu/ifi/dbs/elki/database/query/LinearScanQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/LinearScanQuery.java index 6cb35025..e55e7d19 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/LinearScanQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/LinearScanQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDatabaseDistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDatabaseDistanceQuery.java index f530b72a..2edd9d0b 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDatabaseDistanceQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDatabaseDistanceQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,10 +23,8 @@ package de.lmu.ifi.dbs.elki.database.query.distance; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.database.ids.DBID; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * Run a database query in a database context. @@ -34,9 +32,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @author Erich Schubert * * @param <O> Database object type. - * @param <D> Distance result type. */ -public abstract class AbstractDatabaseDistanceQuery<O, D extends Distance<D>> extends AbstractDistanceQuery<O, D> { +public abstract class AbstractDatabaseDistanceQuery<O> extends AbstractDistanceQuery<O> { /** * Constructor. * @@ -47,25 +44,25 @@ public abstract class AbstractDatabaseDistanceQuery<O, D extends Distance<D>> ex } @Override - public D distance(O o1, DBIDRef id2) { - if(o1 instanceof DBID) { - return distance((DBID) o1, id2); + public double distance(O o1, DBIDRef id2) { + if(o1 instanceof DBIDRef) { + return distance((DBIDRef) o1, id2); } throw new UnsupportedOperationException("This distance function is only defined for known DBIDs."); } @Override - public D distance(DBIDRef id1, O o2) { - if(o2 instanceof DBID) { - return distance(id1, (DBID) o2); + public double distance(DBIDRef id1, O o2) { + if(o2 instanceof DBIDRef) { + return distance(id1, (DBIDRef) o2); } throw new UnsupportedOperationException("This distance function is only defined for known DBIDs."); } @Override - public D distance(O o1, O o2) { - if(o1 instanceof DBID && o2 instanceof DBID) { - return distance((DBID) o1, (DBID) o2); + public double distance(O o1, O o2) { + if(o1 instanceof DBIDRef && o2 instanceof DBIDRef) { + return distance((DBIDRef) o1, (DBIDRef) o2); } throw new UnsupportedOperationException("This distance function is only defined for known DBIDs."); } diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDistanceQuery.java index 933bd0d3..8f35eb58 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDistanceQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/AbstractDistanceQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,9 +24,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.query.AbstractDataBasedQuery; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * A distance query serves as adapter layer for database and primitive @@ -35,16 +33,21 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @author Erich Schubert * * @param O Input object type - * @param D Distance result type */ -public abstract class AbstractDistanceQuery<O, D extends Distance<D>> extends AbstractDataBasedQuery<O> implements DistanceQuery<O, D> { +public abstract class AbstractDistanceQuery<O> implements DistanceQuery<O> { + /** + * The data to use for this query + */ + final protected Relation<? extends O> relation; + /** * Constructor. * * @param relation Relation to use. */ public AbstractDistanceQuery(Relation<? extends O> relation) { - super(relation); + super(); + this.relation = relation; } /** @@ -55,7 +58,7 @@ public abstract class AbstractDistanceQuery<O, D extends Distance<D>> extends Ab * @return the distance between the two objects specified by their object ids */ @Override - public abstract D distance(DBIDRef id1, DBIDRef id2); + public abstract double distance(DBIDRef id1, DBIDRef id2); /** * Returns the distance between the two objects specified by their object ids. @@ -65,7 +68,7 @@ public abstract class AbstractDistanceQuery<O, D extends Distance<D>> extends Ab * @return the distance between the two objects specified by their object ids */ @Override - public abstract D distance(O o1, DBIDRef id2); + public abstract double distance(O o1, DBIDRef id2); /** * Returns the distance between the two objects specified by their object ids. @@ -75,7 +78,7 @@ public abstract class AbstractDistanceQuery<O, D extends Distance<D>> extends Ab * @return the distance between the two objects specified by their object ids */ @Override - public abstract D distance(DBIDRef id1, O o2); + public abstract double distance(DBIDRef id1, O o2); /** * Returns the distance between the two objects specified by their object ids. @@ -85,40 +88,10 @@ public abstract class AbstractDistanceQuery<O, D extends Distance<D>> extends Ab * @return the distance between the two objects specified by their object ids */ @Override - public abstract D distance(O o1, O o2); - - @Override - public D getDistanceFactory() { - return getDistanceFunction().getDistanceFactory(); - } + public abstract double distance(O o1, O o2); - /** - * Provides an infinite distance. - * - * @return an infinite distance - */ - @Override - public D infiniteDistance() { - return getDistanceFunction().getDistanceFactory().infiniteDistance(); - } - - /** - * Provides a null distance. - * - * @return a null distance - */ - @Override - public D nullDistance() { - return getDistanceFunction().getDistanceFactory().nullDistance(); - } - - /** - * Provides an undefined distance. - * - * @return an undefined distance - */ @Override - public D undefinedDistance() { - return getDistanceFunction().getDistanceFactory().undefinedDistance(); + public Relation<? extends O> getRelation() { + return relation; } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDDistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDDistanceQuery.java index e619bc57..b9966b53 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDDistanceQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDDistanceQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,7 +27,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBID; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.distance.distancefunction.DBIDDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * Run a distance query based on DBIDs @@ -36,14 +35,12 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * * @apiviz.landmark * @apiviz.uses DBIDDistanceFunction - * - * @param <D> Distance result type. */ -public class DBIDDistanceQuery<D extends Distance<D>> extends AbstractDatabaseDistanceQuery<DBID, D> { +public class DBIDDistanceQuery extends AbstractDatabaseDistanceQuery<DBID> { /** * The distance function we use. */ - final protected DBIDDistanceFunction<D> distanceFunction; + final protected DBIDDistanceFunction distanceFunction; /** * Constructor. @@ -51,13 +48,13 @@ public class DBIDDistanceQuery<D extends Distance<D>> extends AbstractDatabaseDi * @param relation Database to use. * @param distanceFunction Our distance function */ - public DBIDDistanceQuery(Relation<DBID> relation, DBIDDistanceFunction<D> distanceFunction) { + public DBIDDistanceQuery(Relation<DBID> relation, DBIDDistanceFunction distanceFunction) { super(relation); this.distanceFunction = distanceFunction; } @Override - public D distance(DBIDRef id1, DBIDRef id2) { + public double distance(DBIDRef id1, DBIDRef id2) { if(id1 == null) { throw new UnsupportedOperationException("This distance function can only be used for objects stored in the database."); } @@ -68,7 +65,7 @@ public class DBIDDistanceQuery<D extends Distance<D>> extends AbstractDatabaseDi } @Override - public DBIDDistanceFunction<D> getDistanceFunction() { + public DBIDDistanceFunction getDistanceFunction() { return distanceFunction; } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDRangeDistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDRangeDistanceQuery.java new file mode 100644 index 00000000..d5457dd5 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/DBIDRangeDistanceQuery.java @@ -0,0 +1,74 @@ +package de.lmu.ifi.dbs.elki.database.query.distance; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import de.lmu.ifi.dbs.elki.database.ids.DBID; +import de.lmu.ifi.dbs.elki.database.ids.DBIDRange; +import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; +import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; +import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.distance.distancefunction.DBIDDistanceFunction; +import de.lmu.ifi.dbs.elki.distance.distancefunction.DBIDRangeDistanceFunction; + +/** + * Run a distance query based on DBIDRanges + * + * @author Erich Schubert + * + * @apiviz.landmark + * @apiviz.uses DBIDRangeDistanceFunction + */ +public class DBIDRangeDistanceQuery extends DBIDDistanceQuery { + /** + * The distance function we use. + */ + final protected DBIDRangeDistanceFunction distanceFunction; + + /** + * The DBID range we are accessing. + */ + final protected DBIDRange range; + + /** + * Constructor. + * + * @param relation Database to use. + * @param distanceFunction Our distance function + */ + public DBIDRangeDistanceQuery(Relation<DBID> relation, DBIDRangeDistanceFunction distanceFunction) { + super(relation, distanceFunction); + this.range = DBIDUtil.assertRange(relation.getDBIDs()); + this.distanceFunction = distanceFunction; + } + + @Override + public double distance(DBIDRef id1, DBIDRef id2) { + return distanceFunction.distance(range.getOffset(id1), range.getOffset(id2)); + } + + @Override + public DBIDDistanceFunction getDistanceFunction() { + return distanceFunction; + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/DistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/DistanceQuery.java index 12e76ace..07bd6c53 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/distance/DistanceQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/DistanceQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,20 +27,18 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** - * A distance query serves as adapter layer for database and primitive distances. + * A distance query serves as adapter layer for database and primitive + * distances. * * @author Erich Schubert * * @apiviz.landmark - * @apiviz.has Distance * * @param O Input object type - * @param D Distance result type */ -public interface DistanceQuery<O, D extends Distance<?>> extends DatabaseQuery { +public interface DistanceQuery<O> extends DatabaseQuery { /** * Returns the distance between the two objects specified by their object ids. * @@ -48,7 +46,7 @@ public interface DistanceQuery<O, D extends Distance<?>> extends DatabaseQuery { * @param id2 second object id * @return the distance between the two objects specified by their object ids */ - D distance(DBIDRef id1, DBIDRef id2); + double distance(DBIDRef id1, DBIDRef id2); /** * Returns the distance between the two objects specified by their object ids. @@ -57,7 +55,7 @@ public interface DistanceQuery<O, D extends Distance<?>> extends DatabaseQuery { * @param id2 second object id * @return the distance between the two objects specified by their object ids */ - D distance(O o1, DBIDRef id2); + double distance(O o1, DBIDRef id2); /** * Returns the distance between the two objects specified by their object ids. @@ -66,7 +64,7 @@ public interface DistanceQuery<O, D extends Distance<?>> extends DatabaseQuery { * @param o2 second object * @return the distance between the two objects specified by their object ids */ - D distance(DBIDRef id1, O o2); + double distance(DBIDRef id1, O o2); /** * Returns the distance between the two objects specified by their object ids. @@ -75,44 +73,16 @@ public interface DistanceQuery<O, D extends Distance<?>> extends DatabaseQuery { * @param o2 second object * @return the distance between the two objects specified by their object ids */ - D distance(O o1, O o2); - - /** - * Method to get the distance functions factory. - * - * @return Factory for distance objects - */ - D getDistanceFactory(); + double distance(O o1, O o2); /** * Get the inner distance function. * * @return Distance function */ - DistanceFunction<? super O, D> getDistanceFunction(); - - /** - * Provides an infinite distance. - * - * @return an infinite distance - */ - D infiniteDistance(); + DistanceFunction<? super O> getDistanceFunction(); /** - * Provides a null distance. - * - * @return a null distance - */ - D nullDistance(); - - /** - * Provides an undefined distance. - * - * @return an undefined distance - */ - D undefinedDistance(); - - /** * Access the underlying data query. * * @return data query in use diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceQuery.java index ab3046ed..92125ae7 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,7 +26,6 @@ package de.lmu.ifi.dbs.elki.database.query.distance; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * Run a database query in a database context. @@ -37,13 +36,12 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @apiviz.uses PrimitiveDistanceFunction * * @param <O> Database object type. - * @param <D> Distance result type. */ -public class PrimitiveDistanceQuery<O, D extends Distance<D>> extends AbstractDistanceQuery<O, D> { +public class PrimitiveDistanceQuery<O> extends AbstractDistanceQuery<O> { /** * The distance function we use. */ - final protected PrimitiveDistanceFunction<? super O, D> distanceFunction; + final protected PrimitiveDistanceFunction<? super O> distanceFunction; /** * Constructor. @@ -51,32 +49,32 @@ public class PrimitiveDistanceQuery<O, D extends Distance<D>> extends AbstractDi * @param relation Representation to use. * @param distanceFunction Our distance function */ - public PrimitiveDistanceQuery(Relation<? extends O> relation, PrimitiveDistanceFunction<? super O, D> distanceFunction) { + public PrimitiveDistanceQuery(Relation<? extends O> relation, PrimitiveDistanceFunction<? super O> distanceFunction) { super(relation); this.distanceFunction = distanceFunction; } @Override - public D distance(DBIDRef id1, DBIDRef id2) { + public double distance(DBIDRef id1, DBIDRef id2) { O o1 = relation.get(id1); O o2 = relation.get(id2); return distance(o1, o2); } @Override - public D distance(O o1, DBIDRef id2) { + public double distance(O o1, DBIDRef id2) { O o2 = relation.get(id2); return distance(o1, o2); } @Override - public D distance(DBIDRef id1, O o2) { + public double distance(DBIDRef id1, O o2) { O o1 = relation.get(id1); return distance(o1, o2); } @Override - public D distance(O o1, O o2) { + public double distance(O o1, O o2) { if(o1 == null) { throw new UnsupportedOperationException("This distance function can only be used for object instances."); } @@ -87,7 +85,7 @@ public class PrimitiveDistanceQuery<O, D extends Distance<D>> extends AbstractDi } @Override - public PrimitiveDistanceFunction<? super O, D> getDistanceFunction() { + public PrimitiveDistanceFunction<? super O> getDistanceFunction() { return distanceFunction; } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceSimilarityQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceSimilarityQuery.java index 52f79f06..b90abc23 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceSimilarityQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/PrimitiveDistanceSimilarityQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,7 +27,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.query.DistanceSimilarityQuery; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; import de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFunction; /** @@ -38,14 +37,13 @@ import de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFuncti * @apiviz.uses PrimitiveSimilarityFunction * * @param <O> Object type - * @param <D> Distance type */ -public class PrimitiveDistanceSimilarityQuery<O, D extends Distance<D>> extends PrimitiveDistanceQuery<O, D> implements DistanceSimilarityQuery<O, D> { +public class PrimitiveDistanceSimilarityQuery<O> extends PrimitiveDistanceQuery<O> implements DistanceSimilarityQuery<O> { /** * Typed reference to the similarity function (usually the same as the * distance function!) */ - private PrimitiveSimilarityFunction<? super O, D> similarityFunction; + private PrimitiveSimilarityFunction<? super O> similarityFunction; /** * Constructor. @@ -55,37 +53,37 @@ public class PrimitiveDistanceSimilarityQuery<O, D extends Distance<D>> extends * @param similarityFunction similarity function (usually the same as the * distance function!) */ - public PrimitiveDistanceSimilarityQuery(Relation<? extends O> relation, PrimitiveDistanceFunction<? super O, D> distanceFunction, PrimitiveSimilarityFunction<? super O, D> similarityFunction) { + public PrimitiveDistanceSimilarityQuery(Relation<? extends O> relation, PrimitiveDistanceFunction<? super O> distanceFunction, PrimitiveSimilarityFunction<? super O> similarityFunction) { super(relation, distanceFunction); this.similarityFunction = similarityFunction; } @Override - public D similarity(DBIDRef id1, DBIDRef id2) { + public double similarity(DBIDRef id1, DBIDRef id2) { O o1 = relation.get(id1); O o2 = relation.get(id2); return similarity(o1, o2); } @Override - public D similarity(O o1, DBIDRef id2) { + public double similarity(O o1, DBIDRef id2) { O o2 = relation.get(id2); return similarity(o1, o2); } @Override - public D similarity(DBIDRef id1, O o2) { + public double similarity(DBIDRef id1, O o2) { O o1 = relation.get(id1); return similarity(o1, o2); } @Override - public D similarity(O o1, O o2) { + public double similarity(O o1, O o2) { return this.similarityFunction.similarity(o1, o2); } @Override - public PrimitiveSimilarityFunction<? super O, D> getSimilarityFunction() { + public PrimitiveSimilarityFunction<? super O> getSimilarityFunction() { return similarityFunction; } } diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialDistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialDistanceQuery.java index 14839dd7..1340130e 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialDistanceQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialDistanceQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,7 +26,6 @@ package de.lmu.ifi.dbs.elki.database.query.distance; import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; import de.lmu.ifi.dbs.elki.database.ids.DBID; import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * Query interface for spatial distance queries. @@ -34,9 +33,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @author Erich Schubert * * @param <V> Vector type - * @param <D> Distance type */ -public interface SpatialDistanceQuery<V extends SpatialComparable, D extends Distance<D>> extends DistanceQuery<V, D> { +public interface SpatialDistanceQuery<V extends SpatialComparable> extends DistanceQuery<V> { /** * Computes the minimum distance between the given MBR and the FeatureVector * object according to this distance function. @@ -46,7 +44,7 @@ public interface SpatialDistanceQuery<V extends SpatialComparable, D extends Dis * @return the minimum distance between the given MBR and the FeatureVector * object according to this distance function */ - D minDist(SpatialComparable mbr, V v); + double minDist(SpatialComparable mbr, V v); /** * Computes the minimum distance between the given MBR and the FeatureVector @@ -57,7 +55,7 @@ public interface SpatialDistanceQuery<V extends SpatialComparable, D extends Dis * @return the minimum distance between the given MBR and the FeatureVector * object according to this distance function */ - D minDist(SpatialComparable mbr, DBID id); + double minDist(SpatialComparable mbr, DBID id); /** * Get the inner distance function. @@ -65,5 +63,5 @@ public interface SpatialDistanceQuery<V extends SpatialComparable, D extends Dis * @return Distance function */ @Override - SpatialPrimitiveDistanceFunction<? super V, D> getDistanceFunction(); + SpatialPrimitiveDistanceFunction<? super V> getDistanceFunction(); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialPrimitiveDistanceQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialPrimitiveDistanceQuery.java index c5a601bd..4453a2ef 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialPrimitiveDistanceQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/SpatialPrimitiveDistanceQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.distance; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,7 +27,6 @@ import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; import de.lmu.ifi.dbs.elki.database.ids.DBID; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * Distance query for spatial distance functions @@ -36,35 +35,34 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @apiviz.uses SpatialPrimitiveDistanceFunction * * @param <V> Vector type to use - * @param <D> Distance result type */ -public class SpatialPrimitiveDistanceQuery<V extends SpatialComparable, D extends Distance<D>> extends PrimitiveDistanceQuery<V, D> implements SpatialDistanceQuery<V, D> { +public class SpatialPrimitiveDistanceQuery<V extends SpatialComparable> extends PrimitiveDistanceQuery<V> implements SpatialDistanceQuery<V> { /** * The distance function we use. */ - final protected SpatialPrimitiveDistanceFunction<? super V, D> distanceFunction; + final protected SpatialPrimitiveDistanceFunction<? super V> distanceFunction; /** * @param relation Representation to use * @param distanceFunction Distance function to use */ - public SpatialPrimitiveDistanceQuery(Relation<? extends V> relation, SpatialPrimitiveDistanceFunction<? super V, D> distanceFunction) { + public SpatialPrimitiveDistanceQuery(Relation<? extends V> relation, SpatialPrimitiveDistanceFunction<? super V> distanceFunction) { super(relation, distanceFunction); this.distanceFunction = distanceFunction; } @Override - public D minDist(SpatialComparable mbr, V v) { + public double minDist(SpatialComparable mbr, V v) { return distanceFunction.minDist(mbr, v); } @Override - public D minDist(SpatialComparable mbr, DBID id) { + public double minDist(SpatialComparable mbr, DBID id) { return distanceFunction.minDist(mbr, relation.get(id)); } @Override - public SpatialPrimitiveDistanceFunction<? super V, D> getDistanceFunction() { + public SpatialPrimitiveDistanceFunction<? super V> getDistanceFunction() { return distanceFunction; } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/distance/package-info.java b/src/de/lmu/ifi/dbs/elki/database/query/distance/package-info.java index 97bc471d..0d949669 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/distance/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/distance/package-info.java @@ -2,12 +2,13 @@ * <p>Prepared queries for distances.</p> * * @apiviz.exclude .*Instance + * @apiviz.exclude de.lmu.ifi.dbs.elki.index.distance.* */ /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/AbstractDistanceKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/AbstractDistanceKNNQuery.java index f9f7d018..8d0d574f 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/knn/AbstractDistanceKNNQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/knn/AbstractDistanceKNNQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.knn; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,49 +29,54 @@ import java.util.List; import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList; -import de.lmu.ifi.dbs.elki.database.query.AbstractDataBasedQuery; +import de.lmu.ifi.dbs.elki.database.ids.KNNList; import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; +import de.lmu.ifi.dbs.elki.database.relation.Relation; /** * Instance for the query on a particular database. * * @author Erich Schubert */ -public abstract class AbstractDistanceKNNQuery<O, D extends Distance<D>> extends AbstractDataBasedQuery<O> implements KNNQuery<O, D> { +public abstract class AbstractDistanceKNNQuery<O> implements KNNQuery<O> { + /** + * The data to use for this query + */ + final protected Relation<? extends O> relation; + /** * Hold the distance function to be used. */ - protected DistanceQuery<O, D> distanceQuery; + final protected DistanceQuery<O> distanceQuery; /** * Constructor. * * @param distanceQuery Distance query used */ - public AbstractDistanceKNNQuery(DistanceQuery<O, D> distanceQuery) { - super(distanceQuery.getRelation()); + public AbstractDistanceKNNQuery(DistanceQuery<O> distanceQuery) { + super(); + this.relation = distanceQuery.getRelation(); this.distanceQuery = distanceQuery; } @Override - public List<? extends KNNList<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) { + public List<? extends KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) { // throw new // UnsupportedOperationException(ExceptionMessages.UNSUPPORTED_NOT_YET); // TODO: optimize - List<KNNList<D>> ret = new ArrayList<>(ids.size()); - for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + List<KNNList> ret = new ArrayList<>(ids.size()); + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { ret.add(getKNNForDBID(iter, k)); } return ret; } @Override - public KNNList<D> getKNNForDBID(DBIDRef id, int k) { + public KNNList getKNNForDBID(DBIDRef id, int k) { return getKNNForObject(relation.get(id), k); } @Override - abstract public KNNList<D> getKNNForObject(O obj, int k); + abstract public KNNList getKNNForObject(O obj, int k); } diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/DoubleOptimizedDistanceKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/DoubleOptimizedDistanceKNNQuery.java deleted file mode 100644 index 4391b745..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/query/knn/DoubleOptimizedDistanceKNNQuery.java +++ /dev/null @@ -1,91 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.query.knn; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory; -import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap; -import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList; -import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery; -import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Optimized linear scan query for {@link PrimitiveDoubleDistanceFunction}s. - * - * @author Erich Schubert - * - * @apiviz.uses PrimitiveDoubleDistanceFunction - * - * @param <O> Object type - */ -public class DoubleOptimizedDistanceKNNQuery<O> extends AbstractDistanceKNNQuery<O, DoubleDistance> implements LinearScanQuery { - /** - * Raw distance function. - */ - PrimitiveDoubleDistanceFunction<O> rawdist; - - /** - * Constructor.newDoubleDistanceHeap - * - * @param distanceQuery Distance function to use - */ - @SuppressWarnings("unchecked") - public DoubleOptimizedDistanceKNNQuery(PrimitiveDistanceQuery<O, DoubleDistance> distanceQuery) { - super(distanceQuery); - if(!(distanceQuery.getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction)) { - throw new UnsupportedOperationException("DoubleOptimizedKNNQuery instantiated for non-PrimitiveDoubleDistanceFunction!"); - } - rawdist = (PrimitiveDoubleDistanceFunction<O>) distanceQuery.getDistanceFunction(); - } - - @Override - public DoubleDistanceKNNList getKNNForDBID(DBIDRef id, int k) { - final Relation<? extends O> relation = this.relation; - DoubleDistanceKNNHeap heap = DBIDFactory.FACTORY.newDoubleDistanceHeap(k); - linearScan(relation, relation.iterDBIDs(), rawdist, relation.get(id), heap); - return heap.toKNNList(); - } - - @Override - public DoubleDistanceKNNList getKNNForObject(O obj, int k) { - DoubleDistanceKNNHeap heap = DBIDFactory.FACTORY.newDoubleDistanceHeap(k); - linearScan(relation, relation.iterDBIDs(), rawdist, obj, heap); - return heap.toKNNList(); - } - - private static <O> void linearScan(Relation<? extends O> relation, DBIDIter iter, PrimitiveDoubleDistanceFunction<? super O> rawdist, final O obj, DoubleDistanceKNNHeap heap) { - double kdist = Double.POSITIVE_INFINITY; - while(iter.valid()) { - final double dist = rawdist.doubleDistance(obj, relation.get(iter)); - if(dist <= kdist) { - kdist = heap.insert(dist, iter); - } - iter.advance(); - } - } -} diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/KNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/KNNQuery.java index c94f3d42..1798ea0b 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/knn/KNNQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/knn/KNNQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.knn; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,9 +27,8 @@ import java.util.List; import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList; +import de.lmu.ifi.dbs.elki.database.ids.KNNList; import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * The interface of an actual instance. @@ -40,9 +39,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @apiviz.has KNNList oneway - - «create» * * @param <O> Object type - * @param <D> Distance type */ -public interface KNNQuery<O, D extends Distance<D>> extends DatabaseQuery { +public interface KNNQuery<O> extends DatabaseQuery { /** * Get the k nearest neighbors for a particular id. * @@ -50,7 +48,7 @@ public interface KNNQuery<O, D extends Distance<D>> extends DatabaseQuery { * @param k Number of neighbors requested * @return neighbors */ - public KNNList<D> getKNNForDBID(DBIDRef id, int k); + public KNNList getKNNForDBID(DBIDRef id, int k); /** * Bulk query method @@ -59,7 +57,7 @@ public interface KNNQuery<O, D extends Distance<D>> extends DatabaseQuery { * @param k Number of neighbors requested * @return neighbors */ - public List<? extends KNNList<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k); + public List<? extends KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k); /** * Get the k nearest neighbors for a particular id. @@ -68,5 +66,5 @@ public interface KNNQuery<O, D extends Distance<D>> extends DatabaseQuery { * @param k Number of neighbors requested * @return neighbors */ - public KNNList<D> getKNNForObject(O obj, int k); + public KNNList getKNNForObject(O obj, int k); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanDistanceKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanDistanceKNNQuery.java index 395db289..06e8ca00 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanDistanceKNNQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanDistanceKNNQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.knn; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -30,12 +30,10 @@ import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList; +import de.lmu.ifi.dbs.elki.database.ids.KNNHeap; +import de.lmu.ifi.dbs.elki.database.ids.KNNList; import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery; import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; -import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * Instance of this query for a particular database. @@ -45,76 +43,73 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @apiviz.landmark * @apiviz.has DistanceQuery */ -public class LinearScanDistanceKNNQuery<O, D extends Distance<D>> extends AbstractDistanceKNNQuery<O, D> implements LinearScanQuery { +public class LinearScanDistanceKNNQuery<O> extends AbstractDistanceKNNQuery<O> implements LinearScanQuery { /** * Constructor. * * @param distanceQuery Distance function to use */ - public LinearScanDistanceKNNQuery(DistanceQuery<O, D> distanceQuery) { + public LinearScanDistanceKNNQuery(DistanceQuery<O> distanceQuery) { super(distanceQuery); } - /** - * Linear batch knn for arbitrary distance functions. - * - * @param ids DBIDs to process - * @param heaps Heaps to store the results in - */ - private void linearScanBatchKNN(ArrayDBIDs ids, List<KNNHeap<D>> heaps) { - // The distance is computed on database IDs + @Override + public KNNList getKNNForDBID(DBIDRef id, int k) { + KNNHeap heap = DBIDUtil.newHeap(k); + double max = Double.POSITIVE_INFINITY; for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) { - int index = 0; - for(DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) { - KNNHeap<D> heap = heaps.get(index); - heap.insert(distanceQuery.distance(iter2, iter), iter); - index++; + final double dist = distanceQuery.distance(id, iter); + if(dist <= max) { + max = heap.insert(dist, iter); } } + return heap.toKNNList(); } @Override - public KNNList<D> getKNNForDBID(DBIDRef id, int k) { - if(PrimitiveDistanceQuery.class.isInstance(distanceQuery)) { - // This should have yielded a LinearScanPrimitiveDistanceKNNQuery class! - return getKNNForObject(relation.get(id), k); - } - KNNHeap<D> heap = DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k); - D max = distanceQuery.getDistanceFactory().infiniteDistance(); + public KNNList getKNNForObject(O obj, int k) { + KNNHeap heap = DBIDUtil.newHeap(k); + double max = Double.POSITIVE_INFINITY; for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) { - final D dist = distanceQuery.distance(id, iter); - if(max.compareTo(dist) > 0) { - heap.insert(dist, iter); - if(heap.size() >= k) { - max = heap.getKNNDistance(); - } + final double dist = distanceQuery.distance(obj, iter); + if(dist <= max) { + max = heap.insert(dist, iter); } } return heap.toKNNList(); } @Override - public List<KNNList<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) { + public List<KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) { final int size = ids.size(); - final List<KNNHeap<D>> heaps = new ArrayList<>(size); + final List<KNNHeap> heaps = new ArrayList<>(size); for(int i = 0; i < size; i++) { - heaps.add(DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k)); + heaps.add(DBIDUtil.newHeap(k)); } linearScanBatchKNN(ids, heaps); // Serialize heaps - List<KNNList<D>> result = new ArrayList<>(size); - for(KNNHeap<D> heap : heaps) { + List<KNNList> result = new ArrayList<>(size); + for(KNNHeap heap : heaps) { result.add(heap.toKNNList()); } return result; } - @Override - public KNNList<D> getKNNForObject(O obj, int k) { - KNNHeap<D> heap = DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k); + /** + * Linear batch knn for arbitrary distance functions. + * + * @param ids DBIDs to process + * @param heaps Heaps to store the results in + */ + private void linearScanBatchKNN(ArrayDBIDs ids, List<KNNHeap> heaps) { + // The distance is computed on database IDs for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) { - heap.insert(distanceQuery.distance(obj, iter), iter); + int index = 0; + for(DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) { + KNNHeap heap = heaps.get(index); + heap.insert(distanceQuery.distance(iter2, iter), iter); + index++; + } } - return heap.toKNNList(); } } diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanEuclideanDistanceKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanEuclideanDistanceKNNQuery.java new file mode 100644 index 00000000..36d739ac --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanEuclideanDistanceKNNQuery.java @@ -0,0 +1,141 @@ +package de.lmu.ifi.dbs.elki.database.query.knn; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import java.util.ArrayList; +import java.util.List; + +import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.database.QueryUtil; +import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; +import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; +import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; +import de.lmu.ifi.dbs.elki.database.ids.KNNHeap; +import de.lmu.ifi.dbs.elki.database.ids.KNNList; +import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery; +import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceQuery; +import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction; +import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction; + +/** + * Instance of this query for a particular database. + * + * This is a subtle optimization: for primitive queries, it is clearly faster to + * retrieve the query object from the relation only once! + * + * @author Erich Schubert + * + * @apiviz.uses PrimitiveDistanceQuery + * @apiviz.uses EuclideanDistanceFunction + * @apiviz.uses SquaredEuclideanDistanceFunction + */ +public class LinearScanEuclideanDistanceKNNQuery<O extends NumberVector> extends LinearScanPrimitiveDistanceKNNQuery<O> implements LinearScanQuery { + /** + * Squared Euclidean distance function. + */ + private static final SquaredEuclideanDistanceFunction SQUARED = SquaredEuclideanDistanceFunction.STATIC; + + /** + * Constructor. + * + * @param distanceQuery Distance function to use + */ + public LinearScanEuclideanDistanceKNNQuery(PrimitiveDistanceQuery<O> distanceQuery) { + super(distanceQuery); + assert (EuclideanDistanceFunction.STATIC.equals(distanceQuery.getDistanceFunction())); + } + + @Override + public KNNList getKNNForDBID(DBIDRef id, int k) { + return QueryUtil.applySqrt(linearScan(relation, relation.iterDBIDs(), relation.get(id), DBIDUtil.newHeap(k)).toKNNList()); + } + + @Override + public KNNList getKNNForObject(O obj, int k) { + return QueryUtil.applySqrt(linearScan(relation, relation.iterDBIDs(), obj, DBIDUtil.newHeap(k)).toKNNList()); + } + + /** + * Main loop of the linear scan. + * + * @param relation Data relation + * @param iter ID iterator + * @param obj Query object + * @param heap Output heap + * @return Heap + */ + private KNNHeap linearScan(Relation<? extends O> relation, DBIDIter iter, final O obj, KNNHeap heap) { + double max = Double.POSITIVE_INFINITY; + while(iter.valid()) { + final double dist = SQUARED.distance(obj, relation.get(iter)); + if(dist <= max) { + max = heap.insert(dist, iter); + } + iter.advance(); + } + return heap; + } + + @Override + public List<KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) { + final int size = ids.size(); + final List<KNNHeap> heaps = new ArrayList<>(size); + List<O> objs = new ArrayList<>(size); + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + heaps.add(DBIDUtil.newHeap(k)); + objs.add(relation.get(iter)); + } + linearScanBatchKNN(objs, heaps); + + List<KNNList> result = new ArrayList<>(heaps.size()); + for(KNNHeap heap : heaps) { + result.add(QueryUtil.applySqrt(heap.toKNNList())); + } + return result; + } + + /** + * Perform a linear scan batch kNN for primitive distance functions. + * + * @param objs Objects list + * @param heaps Heaps array + */ + @Override + protected void linearScanBatchKNN(List<O> objs, List<KNNHeap> heaps) { + final int size = objs.size(); + // Linear scan style KNN. + for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) { + O candidate = relation.get(iter); + for(int index = 0; index < size; index++) { + final KNNHeap heap = heaps.get(index); + final double dist = SQUARED.distance(objs.get(index), candidate); + if(dist <= heap.getKNNDistance()) { + heap.insert(dist, iter); + } + } + } + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanPrimitiveDistanceKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanPrimitiveDistanceKNNQuery.java index 59a6d6e3..20a120e5 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanPrimitiveDistanceKNNQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/knn/LinearScanPrimitiveDistanceKNNQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.knn; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -30,11 +30,12 @@ import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList; +import de.lmu.ifi.dbs.elki.database.ids.KNNHeap; +import de.lmu.ifi.dbs.elki.database.ids.KNNList; import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery; import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; +import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction; /** * Instance of this query for a particular database. @@ -45,69 +46,91 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @author Erich Schubert * * @apiviz.uses PrimitiveDistanceQuery + * @apiviz.uses PrimitiveDistanceFunction */ -public class LinearScanPrimitiveDistanceKNNQuery<O, D extends Distance<D>> extends AbstractDistanceKNNQuery<O, D> implements LinearScanQuery { +public class LinearScanPrimitiveDistanceKNNQuery<O> extends AbstractDistanceKNNQuery<O> implements LinearScanQuery { + /** + * Unboxed distance function. + */ + private PrimitiveDistanceFunction<? super O> rawdist; + /** * Constructor. * * @param distanceQuery Distance function to use */ - public LinearScanPrimitiveDistanceKNNQuery(PrimitiveDistanceQuery<O, D> distanceQuery) { + public LinearScanPrimitiveDistanceKNNQuery(PrimitiveDistanceQuery<O> distanceQuery) { super(distanceQuery); + rawdist = distanceQuery.getDistanceFunction(); } - /** - * Perform a linear scan batch kNN for primitive distance functions. - * - * @param objs Objects list - * @param heaps Heaps array - */ - protected void linearScanBatchKNN(List<O> objs, List<KNNHeap<D>> heaps) { - final int size = objs.size(); - // Linear scan style KNN. - for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) { - O candidate = relation.get(iter); - for(int index = 0; index < size; index++) { - O object = objs.get(index); - heaps.get(index).insert(distanceQuery.distance(object, candidate), iter); - } - } + @Override + public KNNList getKNNForDBID(DBIDRef id, int k) { + return linearScan(relation, relation.iterDBIDs(), relation.get(id), DBIDUtil.newHeap(k)).toKNNList(); } @Override - public KNNList<D> getKNNForDBID(DBIDRef id, int k) { - final O obj = relation.get(id); - KNNHeap<D> heap = DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k); - for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) { - heap.insert(distanceQuery.distance(obj, iter), iter); - } - return heap.toKNNList(); + public KNNList getKNNForObject(O obj, int k) { + return linearScan(relation, relation.iterDBIDs(), obj, DBIDUtil.newHeap(k)).toKNNList(); } - @Override - public KNNList<D> getKNNForObject(O obj, int k) { - KNNHeap<D> heap = DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k); - for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) { - heap.insert(distanceQuery.distance(obj, iter), iter); + /** + * Main loop of the linear scan. + * + * @param relation Data relation + * @param iter ID iterator + * @param obj Query object + * @param heap Output heap + * @return Heap + */ + private KNNHeap linearScan(Relation<? extends O> relation, DBIDIter iter, final O obj, KNNHeap heap) { + double max = Double.POSITIVE_INFINITY; + while(iter.valid()) { + final double dist = rawdist.distance(obj, relation.get(iter)); + if(dist <= max) { + max = heap.insert(dist, iter); + } + iter.advance(); } - return heap.toKNNList(); + return heap; } @Override - public List<KNNList<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) { + public List<KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) { final int size = ids.size(); - final List<KNNHeap<D>> heaps = new ArrayList<>(size); + final List<KNNHeap> heaps = new ArrayList<>(size); List<O> objs = new ArrayList<>(size); for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { - heaps.add(DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k)); + heaps.add(DBIDUtil.newHeap(k)); objs.add(relation.get(iter)); } linearScanBatchKNN(objs, heaps); - List<KNNList<D>> result = new ArrayList<>(heaps.size()); - for(KNNHeap<D> heap : heaps) { + List<KNNList> result = new ArrayList<>(heaps.size()); + for(KNNHeap heap : heaps) { result.add(heap.toKNNList()); } return result; } + + /** + * Perform a linear scan batch kNN for primitive distance functions. + * + * @param objs Objects list + * @param heaps Heaps array + */ + protected void linearScanBatchKNN(List<O> objs, List<KNNHeap> heaps) { + final int size = objs.size(); + // Linear scan style KNN. + for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) { + O candidate = relation.get(iter); + for(int index = 0; index < size; index++) { + final KNNHeap heap = heaps.get(index); + final double dist = rawdist.distance(objs.get(index), candidate); + if(dist <= heap.getKNNDistance()) { + heap.insert(dist, iter); + } + } + } + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/PreprocessorKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/PreprocessorKNNQuery.java index 0f555c79..2f51c998 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/knn/PreprocessorKNNQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/knn/PreprocessorKNNQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.knn; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -30,10 +30,8 @@ import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList; -import de.lmu.ifi.dbs.elki.database.query.AbstractDataBasedQuery; +import de.lmu.ifi.dbs.elki.database.ids.KNNList; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; import de.lmu.ifi.dbs.elki.index.preprocessed.knn.AbstractMaterializeKNNPreprocessor; import de.lmu.ifi.dbs.elki.logging.LoggingUtil; import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; @@ -42,12 +40,19 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; * Instance for a particular database, invoking the preprocessor. * * @author Erich Schubert + * + * @param <O> Data object type */ -public class PreprocessorKNNQuery<O, D extends Distance<D>, T extends KNNList<D>> extends AbstractDataBasedQuery<O> implements KNNQuery<O, D> { +public class PreprocessorKNNQuery<O> implements KNNQuery<O> { + /** + * The data to use for this query + */ + final protected Relation<? extends O> relation; + /** * The last preprocessor result */ - final private AbstractMaterializeKNNPreprocessor<O, D, T> preprocessor; + final private AbstractMaterializeKNNPreprocessor<O> preprocessor; /** * Warn only once. @@ -57,36 +62,27 @@ public class PreprocessorKNNQuery<O, D extends Distance<D>, T extends KNNList<D> /** * Constructor. * - * @param database Database to query + * @param relation Relation to query * @param preprocessor Preprocessor instance to use */ - public PreprocessorKNNQuery(Relation<O> database, AbstractMaterializeKNNPreprocessor<O, D, T> preprocessor) { - super(database); + public PreprocessorKNNQuery(Relation<O> relation, AbstractMaterializeKNNPreprocessor<O> preprocessor) { + super(); + this.relation = relation; this.preprocessor = preprocessor; } - /** - * Constructor. - * - * @param database Database to query - * @param preprocessor Preprocessor to use - */ - public PreprocessorKNNQuery(Relation<O> database, AbstractMaterializeKNNPreprocessor.Factory<O, D, T> preprocessor) { - this(database, preprocessor.instantiate(database)); - } - @Override - public KNNList<D> getKNNForDBID(DBIDRef id, int k) { + public KNNList getKNNForDBID(DBIDRef id, int k) { if(!warned && k > preprocessor.getK()) { LoggingUtil.warning("Requested more neighbors than preprocessed!"); } if(!warned && k < preprocessor.getK()) { - KNNList<D> dr = preprocessor.get(id); + KNNList dr = preprocessor.get(id); int subk = k; - D kdist = dr.get(subk - 1).getDistance(); + double kdist = dr.get(subk - 1).doubleValue(); while(subk < dr.size()) { - D ndist = dr.get(subk).getDistance(); - if(kdist.equals(ndist)) { + double ndist = dr.get(subk).doubleValue(); + if(kdist == ndist) { // Tie - increase subk. subk++; } @@ -105,19 +101,19 @@ public class PreprocessorKNNQuery<O, D extends Distance<D>, T extends KNNList<D> } @Override - public List<KNNList<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) { + public List<KNNList> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) { if(!warned && k > preprocessor.getK()) { LoggingUtil.warning("Requested more neighbors than preprocessed!"); } - List<KNNList<D>> result = new ArrayList<>(ids.size()); + List<KNNList> result = new ArrayList<>(ids.size()); if(k < preprocessor.getK()) { - for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { - KNNList<D> dr = preprocessor.get(iter); + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + KNNList dr = preprocessor.get(iter); int subk = k; - D kdist = dr.get(subk - 1).getDistance(); + double kdist = dr.get(subk - 1).doubleValue(); while(subk < dr.size()) { - D ndist = dr.get(subk).getDistance(); - if(kdist.equals(ndist)) { + double ndist = dr.get(subk).doubleValue(); + if(kdist == ndist) { // Tie - increase subk. subk++; } @@ -134,7 +130,7 @@ public class PreprocessorKNNQuery<O, D extends Distance<D>, T extends KNNList<D> } } else { - for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { result.add(preprocessor.get(iter)); } } @@ -142,7 +138,7 @@ public class PreprocessorKNNQuery<O, D extends Distance<D>, T extends KNNList<D> } @Override - public KNNList<D> getKNNForObject(O obj, int k) { + public KNNList getKNNForObject(O obj, int k) { throw new AbortException("Preprocessor KNN query only supports ID queries."); } @@ -151,7 +147,7 @@ public class PreprocessorKNNQuery<O, D extends Distance<D>, T extends KNNList<D> * * @return preprocessor instance */ - public AbstractMaterializeKNNPreprocessor<O, D, T> getPreprocessor() { + public AbstractMaterializeKNNPreprocessor<O> getPreprocessor() { return preprocessor; } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/knn/package-info.java b/src/de/lmu/ifi/dbs/elki/database/query/knn/package-info.java index 17d8e4b0..31ecd704 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/knn/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/knn/package-info.java @@ -8,7 +8,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/query/package-info.java b/src/de/lmu/ifi/dbs/elki/database/query/package-info.java index fb3539bc..bf4b4be9 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/package-info.java @@ -81,7 +81,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/query/range/AbstractDistanceRangeQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/range/AbstractDistanceRangeQuery.java index 531fa09d..1a3687d6 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/range/AbstractDistanceRangeQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/range/AbstractDistanceRangeQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.range; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,10 +24,9 @@ package de.lmu.ifi.dbs.elki.database.query.range; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; -import de.lmu.ifi.dbs.elki.database.query.AbstractDataBasedQuery; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; +import de.lmu.ifi.dbs.elki.database.relation.Relation; /** * Abstract base class for range queries that use a distance query in their @@ -36,34 +35,34 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @author Erich Schubert * * @param <O> Database object type - * @param <D> Distance type */ -public abstract class AbstractDistanceRangeQuery<O, D extends Distance<D>> extends AbstractDataBasedQuery<O> implements RangeQuery<O, D> { +public abstract class AbstractDistanceRangeQuery<O> implements RangeQuery<O> { + /** + * The data to use for this query + */ + final protected Relation<? extends O> relation; + /** * Hold the distance function to be used. */ - protected DistanceQuery<O, D> distanceQuery; + final protected DistanceQuery<O> distanceQuery; /** * Constructor. * * @param distanceQuery Distance query */ - public AbstractDistanceRangeQuery(DistanceQuery<O, D> distanceQuery) { - super(distanceQuery.getRelation()); + public AbstractDistanceRangeQuery(DistanceQuery<O> distanceQuery) { + super(); + this.relation = distanceQuery.getRelation(); this.distanceQuery = distanceQuery; } @Override - public DistanceDBIDList<D> getRangeForDBID(DBIDRef id, D range) { + public DoubleDBIDList getRangeForDBID(DBIDRef id, double range) { return getRangeForObject(relation.get(id), range); } @Override - abstract public DistanceDBIDList<D> getRangeForObject(O obj, D range); - - @Override - public D getDistanceFactory() { - return distanceQuery.getDistanceFactory(); - } + abstract public DoubleDBIDList getRangeForObject(O obj, double range); } diff --git a/src/de/lmu/ifi/dbs/elki/database/query/range/DoubleOptimizedDistanceRangeQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/range/DoubleOptimizedDistanceRangeQuery.java deleted file mode 100644 index 90b867e3..00000000 --- a/src/de/lmu/ifi/dbs/elki/database/query/range/DoubleOptimizedDistanceRangeQuery.java +++ /dev/null @@ -1,92 +0,0 @@ -package de.lmu.ifi.dbs.elki.database.query.range; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2013 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme - ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; -import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDoubleDistanceDBIDList; -import de.lmu.ifi.dbs.elki.database.ids.integer.DoubleDistanceIntegerDBIDList; -import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery; -import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Default linear scan range query class. - * - * @author Erich Schubert - * - * @apiviz.uses PrimitiveDoubleDistanceFunction - * - * @param <O> Database object type - */ -public class DoubleOptimizedDistanceRangeQuery<O> extends AbstractDistanceRangeQuery<O, DoubleDistance> implements LinearScanQuery { - /** - * Raw distance function. - */ - PrimitiveDoubleDistanceFunction<? super O> rawdist; - - /** - * Constructor. - * - * @param distanceQuery Distance function to use - */ - @SuppressWarnings("unchecked") - public DoubleOptimizedDistanceRangeQuery(DistanceQuery<O, DoubleDistance> distanceQuery) { - super(distanceQuery); - if(!(distanceQuery.getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction)) { - throw new UnsupportedOperationException("DoubleOptimizedRangeQuery instantiated for non-PrimitiveDoubleDistanceFunction!"); - } - rawdist = (PrimitiveDoubleDistanceFunction<O>) distanceQuery.getDistanceFunction(); - } - - @Override - public DistanceDBIDList<DoubleDistance> getRangeForDBID(DBIDRef id, DoubleDistance range) { - final Relation<? extends O> relation = this.relation; - DoubleDistanceIntegerDBIDList result = new DoubleDistanceIntegerDBIDList(); - linearScan(relation, relation.iterDBIDs(), rawdist, relation.get(id), range.doubleValue(), result); - result.sort(); - return result; - } - - @Override - public DistanceDBIDList<DoubleDistance> getRangeForObject(O obj, DoubleDistance range) { - DoubleDistanceIntegerDBIDList result = new DoubleDistanceIntegerDBIDList(); - linearScan(relation, relation.iterDBIDs(), rawdist, obj, range.doubleValue(), result); - result.sort(); - return result; - } - - private static <O> void linearScan(Relation<? extends O> relation, DBIDIter iter, PrimitiveDoubleDistanceFunction<? super O> rawdist, O obj, double range, ModifiableDoubleDistanceDBIDList result) { - while(iter.valid()) { - final double doubleDistance = rawdist.doubleDistance(obj, relation.get(iter)); - if(doubleDistance <= range) { - result.add(doubleDistance, iter); - } - iter.advance(); - } - } -} diff --git a/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanDistanceRangeQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanDistanceRangeQuery.java index 8830dd45..8747cebf 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanDistanceRangeQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanDistanceRangeQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.range; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,11 +25,11 @@ package de.lmu.ifi.dbs.elki.database.query.range; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; -import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList; import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery; import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * Default linear scan range query class. @@ -40,24 +40,23 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @apiviz.has DistanceQuery * * @param <O> Database object type - * @param <D> Distance type */ -public class LinearScanDistanceRangeQuery<O, D extends Distance<D>> extends AbstractDistanceRangeQuery<O, D> implements LinearScanQuery { +public class LinearScanDistanceRangeQuery<O> extends AbstractDistanceRangeQuery<O> implements LinearScanQuery { /** * Constructor. * * @param distanceQuery Distance function to use */ - public LinearScanDistanceRangeQuery(DistanceQuery<O, D> distanceQuery) { + public LinearScanDistanceRangeQuery(DistanceQuery<O> distanceQuery) { super(distanceQuery); } @Override - public DistanceDBIDList<D> getRangeForDBID(DBIDRef id, D range) { - GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>(); + public DoubleDBIDList getRangeForDBID(DBIDRef id, double range) { + ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList(); for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) { - D currentDistance = distanceQuery.distance(id, iter); - if(currentDistance.compareTo(range) <= 0) { + double currentDistance = distanceQuery.distance(id, iter); + if(currentDistance <= range) { result.add(currentDistance, iter); } } @@ -66,11 +65,11 @@ public class LinearScanDistanceRangeQuery<O, D extends Distance<D>> extends Abst } @Override - public DistanceDBIDList<D> getRangeForObject(O obj, D range) { - GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>(); + public DoubleDBIDList getRangeForObject(O obj, double range) { + ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList(); for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) { - D currentDistance = distanceQuery.distance(obj, iter); - if(currentDistance.compareTo(range) <= 0) { + double currentDistance = distanceQuery.distance(obj, iter); + if(currentDistance <= range) { result.add(currentDistance, iter); } } diff --git a/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanEuclideanDistanceRangeQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanEuclideanDistanceRangeQuery.java new file mode 100644 index 00000000..a12a4368 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanEuclideanDistanceRangeQuery.java @@ -0,0 +1,104 @@ +package de.lmu.ifi.dbs.elki.database.query.range; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; +import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; +import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList; +import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceQuery; +import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction; + +/** + * Optimized linear scan for Euclidean distance range queries. + * + * @author Erich Schubert + * + * @apiviz.uses SquaredEuclideanDistanceFunction + * + * @param <O> Database object type + */ +public class LinearScanEuclideanDistanceRangeQuery<O extends NumberVector> extends LinearScanPrimitiveDistanceRangeQuery<O> { + /** + * Squared Euclidean distance function. + */ + private static final SquaredEuclideanDistanceFunction SQUARED = SquaredEuclideanDistanceFunction.STATIC; + + /** + * Constructor. + * + * @param distanceQuery Distance function to use + */ + public LinearScanEuclideanDistanceRangeQuery(PrimitiveDistanceQuery<O> distanceQuery) { + super(distanceQuery); + } + + @Override + public DoubleDBIDList getRangeForDBID(DBIDRef id, double range) { + // Note: subtle optimization. Get "id" only once! + final O obj = relation.get(id); + ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList(); + linearScan(relation, relation.iterDBIDs(), obj, range, result); + result.sort(); + return result; + } + + @Override + public DoubleDBIDList getRangeForObject(O obj, double range) { + ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList(); + linearScan(relation, relation.iterDBIDs(), obj, range, result); + result.sort(); + return result; + } + + /** + * Main loop for linear scan, + * + * @param relation Data relation + * @param iter Iterator + * @param obj Query object + * @param range Query radius + * @param result Output data structure + */ + private void linearScan(Relation<? extends O> relation, DBIDIter iter, O obj, double range, ModifiableDoubleDBIDList result) { + // Avoid a loss in numerical precision when using the squared radius: + final double upper = range * 1.0000001; + // This should be more precise, but slower: + // upper = MathUtil.floatToDoubleUpper((float)range); + final double sqrange = upper * upper; + while(iter.valid()) { + final double sqdistance = SQUARED.distance(obj, relation.get(iter)); + if(sqdistance <= sqrange) { + final double dist = Math.sqrt(sqdistance); + if(dist <= range) { // double check, as we increased the radius above + result.add(dist, iter); + } + } + iter.advance(); + } + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanPrimitiveDistanceRangeQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanPrimitiveDistanceRangeQuery.java index ab4dd2be..69d6a0b7 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanPrimitiveDistanceRangeQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/range/LinearScanPrimitiveDistanceRangeQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.range; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,10 +25,12 @@ package de.lmu.ifi.dbs.elki.database.query.range; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; -import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList; import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceQuery; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; +import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction; /** * Default linear scan range query class. @@ -41,43 +43,57 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @apiviz.uses PrimitiveDistanceQuery * * @param <O> Database object type - * @param <D> Distance type */ -public class LinearScanPrimitiveDistanceRangeQuery<O, D extends Distance<D>> extends AbstractDistanceRangeQuery<O, D> { +public class LinearScanPrimitiveDistanceRangeQuery<O> extends AbstractDistanceRangeQuery<O> { + /** + * Unboxed distance function. + */ + private PrimitiveDistanceFunction<? super O> rawdist; + /** * Constructor. * * @param distanceQuery Distance function to use */ - public LinearScanPrimitiveDistanceRangeQuery(PrimitiveDistanceQuery<O, D> distanceQuery) { + public LinearScanPrimitiveDistanceRangeQuery(PrimitiveDistanceQuery<O> distanceQuery) { super(distanceQuery); + rawdist = distanceQuery.getDistanceFunction(); } @Override - public DistanceDBIDList<D> getRangeForDBID(DBIDRef id, D range) { + public DoubleDBIDList getRangeForDBID(DBIDRef id, double range) { // Note: subtle optimization. Get "id" only once! final O obj = relation.get(id); - GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>(); - for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) { - D currentDistance = distanceQuery.distance(obj, iter); - if(currentDistance.compareTo(range) <= 0) { - result.add(currentDistance, iter); - } - } + ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList(); + linearScan(relation, relation.iterDBIDs(), obj, range, result); result.sort(); return result; } @Override - public DistanceDBIDList<D> getRangeForObject(O obj, D range) { - GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>(); - for(DBIDIter iter = relation.getDBIDs().iter(); iter.valid(); iter.advance()) { - D currentDistance = distanceQuery.distance(obj, iter); - if(currentDistance.compareTo(range) <= 0) { - result.add(currentDistance, iter); - } - } + public DoubleDBIDList getRangeForObject(O obj, double range) { + ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList(); + linearScan(relation, relation.iterDBIDs(), obj, range, result); result.sort(); return result; } + + /** + * Main loop for linear scan, + * + * @param relation Data relation + * @param iter Iterator + * @param obj Query object + * @param range Query radius + * @param result Output data structure + */ + private void linearScan(Relation<? extends O> relation, DBIDIter iter, O obj, double range, ModifiableDoubleDBIDList result) { + while(iter.valid()) { + final double distance = rawdist.distance(obj, relation.get(iter)); + if(distance <= range) { + result.add(distance, iter); + } + iter.advance(); + } + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/range/RangeQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/range/RangeQuery.java index 3f21c5f8..364b79c2 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/range/RangeQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/range/RangeQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.range; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,9 +24,8 @@ package de.lmu.ifi.dbs.elki.database.query.range; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * The interface for range queries @@ -34,12 +33,11 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @author Erich Schubert * * @apiviz.landmark - * @apiviz.uses DistanceDBIDList oneway - - «create» + * @apiviz.uses DoubleDBIDList oneway - - «create» * * @param <O> Object type - * @param <D> Distance type */ -public interface RangeQuery<O, D extends Distance<D>> extends DatabaseQuery { +public interface RangeQuery<O> extends DatabaseQuery { /** * Get the nearest neighbors for a particular id in a given query range * @@ -47,7 +45,7 @@ public interface RangeQuery<O, D extends Distance<D>> extends DatabaseQuery { * @param range Query range * @return neighbors */ - public DistanceDBIDList<D> getRangeForDBID(DBIDRef id, D range); + public DoubleDBIDList getRangeForDBID(DBIDRef id, double range); /** * Get the nearest neighbors for a particular object in a given query range @@ -56,12 +54,5 @@ public interface RangeQuery<O, D extends Distance<D>> extends DatabaseQuery { * @param range Query range * @return neighbors */ - public DistanceDBIDList<D> getRangeForObject(O obj, D range); - - /** - * Get the distance factory for the given distance type. - * - * @return Distance factory. - */ - public D getDistanceFactory(); + public DoubleDBIDList getRangeForObject(O obj, double range); } diff --git a/src/de/lmu/ifi/dbs/elki/database/query/range/package-info.java b/src/de/lmu/ifi/dbs/elki/database/query/range/package-info.java index b2e3427d..d47d3ad4 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/range/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/range/package-info.java @@ -7,7 +7,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/query/rknn/AbstractRKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/rknn/AbstractRKNNQuery.java index 8a88bf0f..5036ae43 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/rknn/AbstractRKNNQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/rknn/AbstractRKNNQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.rknn; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,32 +24,37 @@ package de.lmu.ifi.dbs.elki.database.query.rknn; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; -import de.lmu.ifi.dbs.elki.database.query.AbstractDataBasedQuery; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; +import de.lmu.ifi.dbs.elki.database.relation.Relation; /** * Instance for the query on a particular database. * * @author Erich Schubert */ -public abstract class AbstractRKNNQuery<O, D extends Distance<D>> extends AbstractDataBasedQuery<O> implements RKNNQuery<O, D> { +public abstract class AbstractRKNNQuery<O> implements RKNNQuery<O> { + /** + * The data to use for this query + */ + final protected Relation<? extends O> relation; + /** * Hold the distance function to be used. */ - protected final DistanceQuery<O, D> distanceQuery; + final protected DistanceQuery<O> distanceQuery; /** * Constructor. * * @param distanceQuery distance query */ - public AbstractRKNNQuery(DistanceQuery<O, D> distanceQuery) { - super(distanceQuery.getRelation()); + public AbstractRKNNQuery(DistanceQuery<O> distanceQuery) { + super(); + this.relation = distanceQuery.getRelation(); this.distanceQuery = distanceQuery; } @Override - abstract public DistanceDBIDList<D> getRKNNForDBID(DBIDRef id, int k); + abstract public DoubleDBIDList getRKNNForDBID(DBIDRef id, int k); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/rknn/LinearScanRKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/rknn/LinearScanRKNNQuery.java index 71cf0619..3d55c3a6 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/rknn/LinearScanRKNNQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/rknn/LinearScanRKNNQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.rknn; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -30,14 +30,13 @@ import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList; -import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter; +import de.lmu.ifi.dbs.elki.database.ids.KNNList; +import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList; import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery; import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * Default linear scan RKNN query class. @@ -48,14 +47,13 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @apiviz.has KNNQuery * * @param <O> Database object type - * @param <D> Distance type */ // FIXME: Validate this works correctly. -public class LinearScanRKNNQuery<O, D extends Distance<D>> extends AbstractRKNNQuery<O, D> implements LinearScanQuery { +public class LinearScanRKNNQuery<O> extends AbstractRKNNQuery<O> implements LinearScanQuery { /** * KNN query we use. */ - protected final KNNQuery<O, D> knnQuery; + protected final KNNQuery<O> knnQuery; /** * Constructor. @@ -64,24 +62,24 @@ public class LinearScanRKNNQuery<O, D extends Distance<D>> extends AbstractRKNNQ * @param knnQuery kNN query to use. * @param maxk k to use */ - public LinearScanRKNNQuery(DistanceQuery<O, D> distanceQuery, KNNQuery<O, D> knnQuery, Integer maxk) { + public LinearScanRKNNQuery(DistanceQuery<O> distanceQuery, KNNQuery<O> knnQuery, Integer maxk) { super(distanceQuery); this.knnQuery = knnQuery; } @Override - public DistanceDBIDList<D> getRKNNForObject(O obj, int k) { - GenericDistanceDBIDList<D> rNNlist = new GenericDistanceDBIDList<>(); + public DoubleDBIDList getRKNNForObject(O obj, int k) { + ModifiableDoubleDBIDList rNNlist = DBIDUtil.newDistanceDBIDList(); ArrayDBIDs allIDs = DBIDUtil.ensureArray(relation.getDBIDs()); - List<? extends KNNList<D>> kNNLists = knnQuery.getKNNForBulkDBIDs(allIDs, k); + List<? extends KNNList> kNNLists = knnQuery.getKNNForBulkDBIDs(allIDs, k); int i = 0; - for (DBIDIter iter = allIDs.iter(); iter.valid(); iter.advance()) { - KNNList<D> knn = kNNLists.get(i); + for(DBIDIter iter = allIDs.iter(); iter.valid(); iter.advance()) { + KNNList knn = kNNLists.get(i); int last = Math.min(k - 1, knn.size() - 1); - D dist = distanceQuery.distance(obj, iter); - if(last < k - 1 || dist.compareTo(knn.get(last).getDistance()) < 1) { + double dist = distanceQuery.distance(obj, iter); + if(last < k - 1 || dist <= knn.get(last).doubleValue()) { rNNlist.add(dist, iter); } i++; @@ -91,18 +89,18 @@ public class LinearScanRKNNQuery<O, D extends Distance<D>> extends AbstractRKNNQ } @Override - public DistanceDBIDList<D> getRKNNForDBID(DBIDRef id, int k) { - GenericDistanceDBIDList<D> rNNList = new GenericDistanceDBIDList<>(); - + public DoubleDBIDList getRKNNForDBID(DBIDRef id, int k) { + ModifiableDoubleDBIDList rNNList = DBIDUtil.newDistanceDBIDList(); + ArrayDBIDs allIDs = DBIDUtil.ensureArray(relation.getDBIDs()); - List<? extends KNNList<D>> kNNList = knnQuery.getKNNForBulkDBIDs(allIDs, k); + List<? extends KNNList> kNNList = knnQuery.getKNNForBulkDBIDs(allIDs, k); int i = 0; - for (DBIDIter iter = allIDs.iter(); iter.valid(); iter.advance()) { - KNNList<D> knn = kNNList.get(i); - for(DistanceDBIDListIter<D> n = knn.iter(); n.valid(); n.advance()) { + for(DBIDIter iter = allIDs.iter(); iter.valid(); iter.advance()) { + KNNList knn = kNNList.get(i); + for(DoubleDBIDListIter n = knn.iter(); n.valid(); n.advance()) { if(DBIDUtil.equal(n, id)) { - rNNList.add(n.getDistance(), iter); + rNNList.add(n.doubleValue(), iter); } } i++; @@ -112,24 +110,24 @@ public class LinearScanRKNNQuery<O, D extends Distance<D>> extends AbstractRKNNQ } @Override - public List<GenericDistanceDBIDList<D>> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k) { - List<GenericDistanceDBIDList<D>> rNNList = new ArrayList<>(ids.size()); + public List<? extends DoubleDBIDList> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k) { + List<ModifiableDoubleDBIDList> rNNList = new ArrayList<>(ids.size()); for(int i = 0; i < ids.size(); i++) { - rNNList.add(new GenericDistanceDBIDList<D>()); + rNNList.add(DBIDUtil.newDistanceDBIDList()); } ArrayDBIDs allIDs = DBIDUtil.ensureArray(relation.getDBIDs()); - List<? extends KNNList<D>> kNNList = knnQuery.getKNNForBulkDBIDs(allIDs, k); + List<? extends KNNList> kNNList = knnQuery.getKNNForBulkDBIDs(allIDs, k); int i = 0; - for (DBIDIter iter = allIDs.iter(); iter.valid(); iter.advance()) { - KNNList<D> knn = kNNList.get(i); - for(DistanceDBIDListIter<D> n = knn.iter(); n.valid(); n.advance()) { + for(DBIDIter iter = allIDs.iter(); iter.valid(); iter.advance()) { + KNNList knn = kNNList.get(i); + for(DoubleDBIDListIter n = knn.iter(); n.valid(); n.advance()) { int j = 0; - for (DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) { + for(DBIDIter iter2 = ids.iter(); iter2.valid(); iter2.advance()) { if(DBIDUtil.equal(n, iter2)) { - GenericDistanceDBIDList<D> rNN = rNNList.get(j); - rNN.add(n.getDistance(), iter); + ModifiableDoubleDBIDList rNN = rNNList.get(j); + rNN.add(n.doubleValue(), iter); } j++; } diff --git a/src/de/lmu/ifi/dbs/elki/database/query/rknn/PreprocessorRKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/rknn/PreprocessorRKNNQuery.java index 9f8f9c71..d18b2c21 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/rknn/PreprocessorRKNNQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/rknn/PreprocessorRKNNQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.rknn; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,10 +29,8 @@ import java.util.List; import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; -import de.lmu.ifi.dbs.elki.database.query.AbstractDataBasedQuery; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; import de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNAndRKNNPreprocessor; import de.lmu.ifi.dbs.elki.logging.LoggingUtil; import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; @@ -42,11 +40,16 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; * * @author Elke Achtert */ -public class PreprocessorRKNNQuery<O, D extends Distance<D>> extends AbstractDataBasedQuery<O> implements RKNNQuery<O, D> { +public class PreprocessorRKNNQuery<O> implements RKNNQuery<O> { + /** + * The data to use for this query + */ + final protected Relation<? extends O> relation; + /** * The last preprocessor result */ - final private MaterializeKNNAndRKNNPreprocessor<O, D> preprocessor; + final private MaterializeKNNAndRKNNPreprocessor<O> preprocessor; /** * Warn only once. @@ -56,11 +59,12 @@ public class PreprocessorRKNNQuery<O, D extends Distance<D>> extends AbstractDat /** * Constructor. * - * @param database Database to query + * @param relation Relation to query * @param preprocessor Preprocessor instance to use */ - public PreprocessorRKNNQuery(Relation<O> database, MaterializeKNNAndRKNNPreprocessor<O, D> preprocessor) { - super(database); + public PreprocessorRKNNQuery(Relation<O> relation, MaterializeKNNAndRKNNPreprocessor<O> preprocessor) { + super(); + this.relation = relation; this.preprocessor = preprocessor; } @@ -70,30 +74,30 @@ public class PreprocessorRKNNQuery<O, D extends Distance<D>> extends AbstractDat * @param database Database to query * @param preprocessor Preprocessor to use */ - public PreprocessorRKNNQuery(Relation<O> database, MaterializeKNNAndRKNNPreprocessor.Factory<O, D> preprocessor) { + public PreprocessorRKNNQuery(Relation<O> database, MaterializeKNNAndRKNNPreprocessor.Factory<O> preprocessor) { this(database, preprocessor.instantiate(database)); } @Override - public DistanceDBIDList<D> getRKNNForDBID(DBIDRef id, int k) { + public DoubleDBIDList getRKNNForDBID(DBIDRef id, int k) { if(!warned && k != preprocessor.getK()) { LoggingUtil.warning("Requested more neighbors than preprocessed!"); } return preprocessor.getRKNN(id); } - + @Override - public DistanceDBIDList<D> getRKNNForObject(O obj, int k) { + public DoubleDBIDList getRKNNForObject(O obj, int k) { throw new AbortException("Preprocessor KNN query only supports ID queries."); } - + @Override - public List<? extends DistanceDBIDList<D>> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k) { + public List<? extends DoubleDBIDList> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k) { if(!warned && k != preprocessor.getK()) { LoggingUtil.warning("Requested more neighbors than preprocessed!"); } - List<DistanceDBIDList<D>> result = new ArrayList<>(ids.size()); - for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + List<DoubleDBIDList> result = new ArrayList<>(ids.size()); + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { result.add(preprocessor.getRKNN(iter)); } return result; diff --git a/src/de/lmu/ifi/dbs/elki/database/query/rknn/RKNNQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/rknn/RKNNQuery.java index 0a05d797..97ea76be 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/rknn/RKNNQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/rknn/RKNNQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.rknn; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,21 +27,19 @@ import java.util.List; import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * Abstract reverse kNN Query interface. * * @author Erich Schubert * - * @apiviz.uses DistanceDBIDList oneway - - «create» + * @apiviz.uses DoubleDBIDList oneway - - «create» * * @param <O> Object type - * @param <D> Distance type */ -public interface RKNNQuery<O, D extends Distance<D>> extends DatabaseQuery { +public interface RKNNQuery<O> extends DatabaseQuery { /** * Get the reverse k nearest neighbors for a particular id. * @@ -49,7 +47,7 @@ public interface RKNNQuery<O, D extends Distance<D>> extends DatabaseQuery { * @param k number of neighbors requested * @return reverse k nearest neighbors */ - public DistanceDBIDList<D> getRKNNForDBID(DBIDRef id, int k); + public DoubleDBIDList getRKNNForDBID(DBIDRef id, int k); /** * Get the reverse k nearest neighbors for a particular object. @@ -58,7 +56,7 @@ public interface RKNNQuery<O, D extends Distance<D>> extends DatabaseQuery { * @param k number of neighbors requested * @return reverse k nearest neighbors */ - public DistanceDBIDList<D> getRKNNForObject(O obj, int k); + public DoubleDBIDList getRKNNForObject(O obj, int k); /** * Bulk query method for reverse k nearest neighbors for ids. @@ -67,5 +65,5 @@ public interface RKNNQuery<O, D extends Distance<D>> extends DatabaseQuery { * @param k number of neighbors requested * @return reverse k nearest neighbors */ - public List<? extends DistanceDBIDList<D>> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k); + public List<? extends DoubleDBIDList> getRKNNForBulkDBIDs(ArrayDBIDs ids, int k); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/rknn/package-info.java b/src/de/lmu/ifi/dbs/elki/database/query/rknn/package-info.java index 8c0501b6..9ab02433 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/rknn/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/rknn/package-info.java @@ -7,7 +7,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractDBIDSimilarityQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractDBIDSimilarityQuery.java index 8dc6dd61..b7a8c5af 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractDBIDSimilarityQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractDBIDSimilarityQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.similarity; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,6 @@ package de.lmu.ifi.dbs.elki.database.query.similarity; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * Run a database query in a database context. @@ -33,9 +32,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * @author Erich Schubert * * @param <O> Database object type. - * @param <D> Distance result type. */ -public abstract class AbstractDBIDSimilarityQuery<O, D extends Distance<D>> extends AbstractSimilarityQuery<O, D> { +public abstract class AbstractDBIDSimilarityQuery<O> extends AbstractSimilarityQuery<O> { /** * Constructor. * @@ -46,17 +44,17 @@ public abstract class AbstractDBIDSimilarityQuery<O, D extends Distance<D>> exte } @Override - public D similarity(O o1, DBIDRef id2) { + public double similarity(O o1, DBIDRef id2) { throw new UnsupportedOperationException("This distance function can only be used for objects when referenced by ID."); } @Override - public D similarity(DBIDRef id1, O o2) { + public double similarity(DBIDRef id1, O o2) { throw new UnsupportedOperationException("This distance function can only be used for objects when referenced by ID."); } @Override - public D similarity(O o1, O o2) { + public double similarity(O o1, O o2) { throw new UnsupportedOperationException("This distance function can only be used for objects when referenced by ID."); } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractSimilarityQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractSimilarityQuery.java index fbcf76a7..99cce405 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractSimilarityQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/similarity/AbstractSimilarityQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.similarity; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,9 +24,7 @@ package de.lmu.ifi.dbs.elki.database.query.similarity; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.database.query.AbstractDataBasedQuery; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; /** * A distance query serves as adapter layer for database and primitive @@ -34,17 +32,22 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; * * @author Erich Schubert * - * @param O Input object type - * @param D Distance result type + * @param <O> Input object type */ -public abstract class AbstractSimilarityQuery<O, D extends Distance<D>> extends AbstractDataBasedQuery<O> implements SimilarityQuery<O, D> { +public abstract class AbstractSimilarityQuery<O> implements SimilarityQuery<O> { + /** + * The data to use for this query + */ + final protected Relation<? extends O> relation; + /** * Constructor. * * @param relation Relation to use. */ public AbstractSimilarityQuery(Relation<? extends O> relation) { - super(relation); + super(); + this.relation = relation; } /** @@ -55,7 +58,7 @@ public abstract class AbstractSimilarityQuery<O, D extends Distance<D>> extends * @return the distance between the two objects specified by their object ids */ @Override - public abstract D similarity(DBIDRef id1, DBIDRef id2); + public abstract double similarity(DBIDRef id1, DBIDRef id2); /** * Returns the distance between the two objects specified by their object ids. @@ -65,7 +68,7 @@ public abstract class AbstractSimilarityQuery<O, D extends Distance<D>> extends * @return the distance between the two objects specified by their object ids */ @Override - public abstract D similarity(O o1, DBIDRef id2); + public abstract double similarity(O o1, DBIDRef id2); /** * Returns the distance between the two objects specified by their object ids. @@ -75,7 +78,7 @@ public abstract class AbstractSimilarityQuery<O, D extends Distance<D>> extends * @return the distance between the two objects specified by their object ids */ @Override - public abstract D similarity(DBIDRef id1, O o2); + public abstract double similarity(DBIDRef id1, O o2); /** * Returns the distance between the two objects specified by their object ids. @@ -85,5 +88,10 @@ public abstract class AbstractSimilarityQuery<O, D extends Distance<D>> extends * @return the distance between the two objects specified by their object ids */ @Override - public abstract D similarity(O o1, O o2); + public abstract double similarity(O o1, O o2); + + @Override + public Relation<? extends O> getRelation() { + return relation; + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/similarity/PrimitiveSimilarityQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/similarity/PrimitiveSimilarityQuery.java index 58020239..f39383a2 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/similarity/PrimitiveSimilarityQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/similarity/PrimitiveSimilarityQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.similarity; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,6 @@ package de.lmu.ifi.dbs.elki.database.query.similarity; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; import de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFunction; /** @@ -33,14 +32,15 @@ import de.lmu.ifi.dbs.elki.distance.similarityfunction.PrimitiveSimilarityFuncti * * @author Erich Schubert * + * @apiviz.has PrimitiveSimilarityFunction + * * @param <O> Database object type. - * @param <D> Distance result type. */ -public class PrimitiveSimilarityQuery<O, D extends Distance<D>> extends AbstractSimilarityQuery<O, D> { +public class PrimitiveSimilarityQuery<O> extends AbstractSimilarityQuery<O> { /** * The distance function we use. */ - final protected PrimitiveSimilarityFunction<? super O, D> similarityFunction; + final protected PrimitiveSimilarityFunction<? super O> similarityFunction; /** * Constructor. @@ -48,48 +48,33 @@ public class PrimitiveSimilarityQuery<O, D extends Distance<D>> extends Abstract * @param relation Relation to use. * @param similarityFunction Our similarity function */ - public PrimitiveSimilarityQuery(Relation<? extends O> relation, PrimitiveSimilarityFunction<? super O, D> similarityFunction) { + public PrimitiveSimilarityQuery(Relation<? extends O> relation, PrimitiveSimilarityFunction<? super O> similarityFunction) { super(relation); this.similarityFunction = similarityFunction; } @Override - public D similarity(DBIDRef id1, DBIDRef id2) { - O o1 = relation.get(id1); - O o2 = relation.get(id2); - return similarity(o1, o2); + public double similarity(DBIDRef id1, DBIDRef id2) { + return similarity(relation.get(id1), relation.get(id2)); } @Override - public D similarity(O o1, DBIDRef id2) { - O o2 = relation.get(id2); - return similarity(o1, o2); + public double similarity(O o1, DBIDRef id2) { + return similarity(o1, relation.get(id2)); } @Override - public D similarity(DBIDRef id1, O o2) { - O o1 = relation.get(id1); - return similarity(o1, o2); + public double similarity(DBIDRef id1, O o2) { + return similarity(relation.get(id1), o2); } @Override - public D similarity(O o1, O o2) { - if (o1 == null) { - throw new UnsupportedOperationException("This distance function can only be used for object instances."); - } - if (o2 == null) { - throw new UnsupportedOperationException("This distance function can only be used for object instances."); - } + public double similarity(O o1, O o2) { return similarityFunction.similarity(o1, o2); } @Override - public D getDistanceFactory() { - return similarityFunction.getDistanceFactory(); - } - - @Override - public PrimitiveSimilarityFunction<? super O, D> getSimilarityFunction() { + public PrimitiveSimilarityFunction<? super O> getSimilarityFunction() { return similarityFunction; } } diff --git a/src/de/lmu/ifi/dbs/elki/database/query/similarity/SimilarityQuery.java b/src/de/lmu/ifi/dbs/elki/database/query/similarity/SimilarityQuery.java index 80347fb7..2b835437 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/similarity/SimilarityQuery.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/similarity/SimilarityQuery.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.query.similarity; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,7 +26,6 @@ package de.lmu.ifi.dbs.elki.database.query.similarity; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; import de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction; /** @@ -36,12 +35,10 @@ import de.lmu.ifi.dbs.elki.distance.similarityfunction.SimilarityFunction; * @author Erich Schubert * * @apiviz.landmark - * @apiviz.has Distance * - * @param O Input object type - * @param D Distance result type + * @param <O> Input object type */ -public interface SimilarityQuery<O, D extends Distance<?>> extends DatabaseQuery { +public interface SimilarityQuery<O> extends DatabaseQuery { /** * Returns the similarity between the two objects specified by their object * ids. @@ -51,7 +48,7 @@ public interface SimilarityQuery<O, D extends Distance<?>> extends DatabaseQuery * @return the similarity between the two objects specified by their object * ids */ - D similarity(DBIDRef id1, DBIDRef id2); + double similarity(DBIDRef id1, DBIDRef id2); /** * Returns the similarity between the two objects specified by their object @@ -62,7 +59,7 @@ public interface SimilarityQuery<O, D extends Distance<?>> extends DatabaseQuery * @return the similarity between the two objects specified by their object * ids */ - D similarity(O o1, DBIDRef id2); + double similarity(O o1, DBIDRef id2); /** * Returns the similarity between the two objects specified by their object @@ -73,7 +70,7 @@ public interface SimilarityQuery<O, D extends Distance<?>> extends DatabaseQuery * @return the similarity between the two objects specified by their object * ids */ - D similarity(DBIDRef id1, O o2); + double similarity(DBIDRef id1, O o2); /** * Returns the similarity between the two objects specified by their object @@ -84,14 +81,7 @@ public interface SimilarityQuery<O, D extends Distance<?>> extends DatabaseQuery * @return the similarity between the two objects specified by their object * ids */ - D similarity(O o1, O o2); - - /** - * Method to get the distance functions factory. - * - * @return Factory for distance objects - */ - D getDistanceFactory(); + double similarity(O o1, O o2); /** * Access the underlying data query. @@ -105,5 +95,5 @@ public interface SimilarityQuery<O, D extends Distance<?>> extends DatabaseQuery * * @return Similarity function */ - SimilarityFunction<? super O, D> getSimilarityFunction(); + SimilarityFunction<? super O> getSimilarityFunction(); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/query/similarity/package-info.java b/src/de/lmu/ifi/dbs/elki/database/query/similarity/package-info.java index dde6909b..720096ad 100644 --- a/src/de/lmu/ifi/dbs/elki/database/query/similarity/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/database/query/similarity/package-info.java @@ -6,7 +6,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/relation/ConvertToStringView.java b/src/de/lmu/ifi/dbs/elki/database/relation/ConvertToStringView.java index 3ce4d935..26cd6675 100644 --- a/src/de/lmu/ifi/dbs/elki/database/relation/ConvertToStringView.java +++ b/src/de/lmu/ifi/dbs/elki/database/relation/ConvertToStringView.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.relation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/relation/DBIDView.java b/src/de/lmu/ifi/dbs/elki/database/relation/DBIDView.java index 7eb14983..47891443 100644 --- a/src/de/lmu/ifi/dbs/elki/database/relation/DBIDView.java +++ b/src/de/lmu/ifi/dbs/elki/database/relation/DBIDView.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.relation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/datastore/DoubleDistanceDataStore.java b/src/de/lmu/ifi/dbs/elki/database/relation/DoubleRelation.java index 88b9d4dc..f128cb23 100644 --- a/src/de/lmu/ifi/dbs/elki/database/datastore/DoubleDistanceDataStore.java +++ b/src/de/lmu/ifi/dbs/elki/database/relation/DoubleRelation.java @@ -1,10 +1,9 @@ -package de.lmu.ifi.dbs.elki.database.datastore; - +package de.lmu.ifi.dbs.elki.database.relation; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,28 +23,41 @@ package de.lmu.ifi.dbs.elki.database.datastore; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; /** - * Double-valued data store (avoids boxing/unboxing). + * Interface for double-valued relations. * * @author Erich Schubert */ -public interface DoubleDistanceDataStore extends DataStore<DoubleDistance> { +public interface DoubleRelation extends Relation<Double> { /** - * Getter, but using objects. + * Get the representation of an object. * - * @deprecated Use {@link #doubleValue} instead, to avoid boxing/unboxing cost. + * @param id Object ID + * @return object instance */ - @Override - @Deprecated - public DoubleDistance get(DBIDRef id); + public double doubleValue(DBIDRef id); /** - * Retrieves an object from the storage. + * Set an object representation. * - * @param id Database ID. - * @return Double value + * @param id Object ID + * @param val Value */ - public double doubleValue(DBIDRef id); -}
\ No newline at end of file + // TODO: remove / move to a writable API? + public void set(DBIDRef id, double val); + + /** + * @deprecated use {@link #doubleValue} instead. + */ + @Deprecated + @Override + public Double get(DBIDRef id); + + /** + * @deprecated use {@link #set(DBIDRef, double)} instead. + */ + @Deprecated + @Override + public void set(DBIDRef id, Double val); +} diff --git a/src/de/lmu/ifi/dbs/elki/database/relation/MaterializedDoubleRelation.java b/src/de/lmu/ifi/dbs/elki/database/relation/MaterializedDoubleRelation.java new file mode 100644 index 00000000..8687efd8 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/database/relation/MaterializedDoubleRelation.java @@ -0,0 +1,209 @@ +package de.lmu.ifi.dbs.elki.database.relation; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; +import de.lmu.ifi.dbs.elki.data.type.TypeUtil; +import de.lmu.ifi.dbs.elki.database.Database; +import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory; +import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil; +import de.lmu.ifi.dbs.elki.database.datastore.DoubleDataStore; +import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore; +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; +import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; +import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; +import de.lmu.ifi.dbs.elki.database.ids.DBIDs; +import de.lmu.ifi.dbs.elki.database.ids.StaticDBIDs; +import de.lmu.ifi.dbs.elki.result.AbstractHierarchicalResult; + +/** + * Represents a single representation. This is attached to a DBIDs object, which + * you are supposed to manage first. I.e. put the new DBID in, then invoke + * set(), remove the DBID, then delete(). + * + * @author Erich Schubert + */ +public class MaterializedDoubleRelation extends AbstractHierarchicalResult implements DoubleRelation { + /** + * Our database + */ + private final Database database; + + /** + * Map to hold the objects of the database. + */ + private final DoubleDataStore content; + + /** + * The DBIDs this is supposed to be defined for. + * + * Note: we only keep an unmodifiable reference. + */ + private final StaticDBIDs ids; + + /** + * The relation name. + */ + private String name; + + /** + * The relation name (short version) + */ + private String shortname = "relation"; + + /** + * Constructor. + * + * @param database Database + * @param ids IDs + */ + public MaterializedDoubleRelation(Database database, DBIDs ids) { + this(database, ids, null); + } + + /** + * Constructor. + * + * @param database Database + * @param ids IDs + * @param name Name + */ + public MaterializedDoubleRelation(Database database, DBIDs ids, String name) { + // We can't call this() since we'll have generics issues then. + super(); + this.database = database; + this.ids = DBIDUtil.makeUnmodifiable(ids); + this.name = name; + this.content = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_DB); + } + + /** + * Constructor. + * + * @param database Database + * @param ids IDs + * @param name Name + * @param content Content + */ + public MaterializedDoubleRelation(Database database, DBIDs ids, String name, DoubleDataStore content) { + super(); + this.database = database; + this.ids = DBIDUtil.makeUnmodifiable(ids); + this.name = name; + this.content = content; + } + + /** + * Constructor. + * + * @param name Name + * @param shortname Short name of the result + * @param content Content + * @param ids IDs + */ + public MaterializedDoubleRelation(String name, String shortname, DoubleDataStore content, DBIDs ids) { + super(); + this.database = null; + this.ids = DBIDUtil.makeUnmodifiable(ids); + this.name = name; + this.shortname = shortname; + this.content = content; + } + + @Override + public Database getDatabase() { + return database; + } + + @Deprecated + @Override + public Double get(DBIDRef id) { + return content.doubleValue(id); + } + + @Override + public double doubleValue(DBIDRef id) { + return content.doubleValue(id); + } + + @Override + public void set(DBIDRef id, double val) { + assert (ids.contains(id)); + if(content instanceof WritableDoubleDataStore) { + ((WritableDoubleDataStore) content).putDouble(id, val); + } + } + + @Deprecated + @Override + public void set(DBIDRef id, Double val) { + assert (ids.contains(id)); + if(content instanceof WritableDoubleDataStore) { + ((WritableDoubleDataStore) content).putDouble(id, val); + } + } + + /** + * Delete an objects values. + * + * @param id ID to delete + */ + @Override + public void delete(DBIDRef id) { + assert (!ids.contains(id)); + if(content instanceof WritableDoubleDataStore) { + ((WritableDoubleDataStore) content).delete(id); + } + } + + @Override + public StaticDBIDs getDBIDs() { + return ids; + } + + @Override + public DBIDIter iterDBIDs() { + return ids.iter(); + } + + @Override + public int size() { + return ids.size(); + } + + @Override + public SimpleTypeInformation<Double> getDataTypeInformation() { + return TypeUtil.DOUBLE; + } + + @Override + public String getLongName() { + return (name != null) ? name : "Double"; + } + + @Override + public String getShortName() { + return shortname; + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/database/relation/MaterializedRelation.java b/src/de/lmu/ifi/dbs/elki/database/relation/MaterializedRelation.java index 8df4a42b..6ad66b6e 100644 --- a/src/de/lmu/ifi/dbs/elki/database/relation/MaterializedRelation.java +++ b/src/de/lmu/ifi/dbs/elki/database/relation/MaterializedRelation.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.relation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -129,6 +129,7 @@ public class MaterializedRelation<O> extends AbstractHierarchicalResult implemen /** * Constructor. + * * @param name Name * @param shortname Short name of the result * @param type Type information @@ -198,10 +199,7 @@ public class MaterializedRelation<O> extends AbstractHierarchicalResult implemen @Override public String getLongName() { - if(name != null) { - return name; - } - return type.toString(); + return (name != null) ? name : type.toString(); } @Override diff --git a/src/de/lmu/ifi/dbs/elki/database/relation/ProjectedView.java b/src/de/lmu/ifi/dbs/elki/database/relation/ProjectedView.java index 252b651b..71fc25e4 100644 --- a/src/de/lmu/ifi/dbs/elki/database/relation/ProjectedView.java +++ b/src/de/lmu/ifi/dbs/elki/database/relation/ProjectedView.java @@ -12,7 +12,7 @@ import de.lmu.ifi.dbs.elki.result.AbstractHierarchicalResult; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/relation/ProxyView.java b/src/de/lmu/ifi/dbs/elki/database/relation/ProxyView.java index d6e12d60..56f349dc 100644 --- a/src/de/lmu/ifi/dbs/elki/database/relation/ProxyView.java +++ b/src/de/lmu/ifi/dbs/elki/database/relation/ProxyView.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.relation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/database/relation/Relation.java b/src/de/lmu/ifi/dbs/elki/database/relation/Relation.java index 9ac4e408..e6acea60 100644 --- a/src/de/lmu/ifi/dbs/elki/database/relation/Relation.java +++ b/src/de/lmu/ifi/dbs/elki/database/relation/Relation.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.relation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -37,6 +37,7 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; * @author Erich Schubert * * @apiviz.uses DBIDRef + * @apiviz.exclude TooltipStringVisualization * * @param <O> Object type */ @@ -96,7 +97,7 @@ public interface Relation<O> extends DatabaseQuery, HierarchicalResult { * <pre> * {@code * for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) { - * DBID id = iter.getDBID(); + * relation.get(iter); // Get the current element * } * } * </pre> diff --git a/src/de/lmu/ifi/dbs/elki/database/relation/RelationUtil.java b/src/de/lmu/ifi/dbs/elki/database/relation/RelationUtil.java index 662767b7..925af2c2 100644 --- a/src/de/lmu/ifi/dbs/elki/database/relation/RelationUtil.java +++ b/src/de/lmu/ifi/dbs/elki/database/relation/RelationUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.database.relation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,11 +23,19 @@ package de.lmu.ifi.dbs.elki.database.relation; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import java.util.AbstractCollection; +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; + import de.lmu.ifi.dbs.elki.data.FeatureVector; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation; import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter; +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; +import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; +import de.lmu.ifi.dbs.elki.database.ids.DBIDs; /** * Utility functions for handling database relation. @@ -35,6 +43,8 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter; * @author Erich Schubert * * @apiviz.uses Relation oneway + * @apiviz.has CollectionFromRelation + * @apiviz.has RelationObjectIterator */ public final class RelationUtil { /** @@ -54,7 +64,8 @@ public final class RelationUtil { public static <V extends FeatureVector<?>> VectorFieldTypeInformation<V> assumeVectorField(Relation<V> relation) { try { return ((VectorFieldTypeInformation<V>) relation.getDataTypeInformation()); - } catch (Exception e) { + } + catch(Exception e) { throw new UnsupportedOperationException("Expected a vector field, got type information: " + relation.getDataTypeInformation().toString(), e); } } @@ -64,13 +75,12 @@ public final class RelationUtil { * * @param relation relation * @param <V> Vector type - * @param <N> Number type * @return Vector field type information */ - public static <V extends NumberVector<? extends N>, N extends Number> NumberVector.Factory<V, N> getNumberVectorFactory(Relation<V> relation) { + public static <V extends NumberVector> NumberVector.Factory<V> getNumberVectorFactory(Relation<V> relation) { final VectorFieldTypeInformation<V> type = assumeVectorField(relation); @SuppressWarnings("unchecked") - final NumberVector.Factory<V, N> factory = (NumberVector.Factory<V, N>) type.getFactory(); + final NumberVector.Factory<V> factory = (NumberVector.Factory<V>) type.getFactory(); return factory; } @@ -83,12 +93,61 @@ public final class RelationUtil { public static int dimensionality(Relation<? extends FeatureVector<?>> relation) { try { return ((VectorFieldTypeInformation<? extends FeatureVector<?>>) relation.getDataTypeInformation()).getDimensionality(); - } catch (Exception e) { + } + catch(Exception e) { return -1; } } /** + * Determines the minimum and maximum values in each dimension of all objects + * stored in the given database. + * + * @param relation the database storing the objects + * @return Minimum and Maximum vector for the hyperrectangle + */ + public static double[][] computeMinMax(Relation<? extends NumberVector> relation) { + int dim = RelationUtil.dimensionality(relation); + double[] mins = new double[dim], maxs = new double[dim]; + for(int i = 0; i < dim; i++) { + mins[i] = Double.MAX_VALUE; + maxs[i] = -Double.MAX_VALUE; + } + for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) { + final NumberVector o = relation.get(iditer); + for(int d = 0; d < dim; d++) { + final double v = o.doubleValue(d); + mins[d] = (v < mins[d]) ? v : mins[d]; + maxs[d] = (v > maxs[d]) ? v : maxs[d]; + } + } + return new double[][] { mins, maxs }; + } + + /** + * Determines the variances in each dimension of the specified objects stored + * in the given database. + * + * @param database the database storing the objects + * @param ids the ids of the objects + * @param centroid the centroid or reference vector of the ids + * @return the variances in each dimension of the specified objects + */ + public static double[] variances(Relation<? extends NumberVector> database, NumberVector centroid, DBIDs ids) { + final int size = ids.size(); + double[] variances = new double[centroid.getDimensionality()]; + + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + NumberVector o = database.get(iter); + for(int d = 0; d < centroid.getDimensionality(); d++) { + final double diff = o.doubleValue(d) - centroid.doubleValue(d); + variances[d] += diff * diff / size; + } + } + return variances; + } + + /** * <em>Copy</em> a relation into a double matrix. * * This is <em>not recommended</em> unless you need to modify the data @@ -98,15 +157,15 @@ public final class RelationUtil { * @param ids IDs, with well-defined order (i.e. array) * @return Data matrix */ - public static double[][] relationAsMatrix(final Relation<? extends NumberVector<?>> relation, ArrayDBIDs ids) { + public static double[][] relationAsMatrix(final Relation<? extends NumberVector> relation, ArrayDBIDs ids) { final int rowdim = ids.size(); final int coldim = dimensionality(relation); double[][] mat = new double[rowdim][coldim]; int r = 0; - for (DBIDArrayIter iter = ids.iter(); iter.valid(); iter.advance(), r++) { - NumberVector<?> vec = relation.get(iter); + for(DBIDArrayIter iter = ids.iter(); iter.valid(); iter.advance(), r++) { + NumberVector vec = relation.get(iter); double[] row = mat[r]; - for (int c = 0; c < coldim; c++) { + for(int c = 0; c < coldim; c++) { row[c] = vec.doubleValue(c); } } @@ -124,10 +183,171 @@ public final class RelationUtil { */ public static <V extends FeatureVector<?>> String getColumnLabel(Relation<? extends V> rel, int col) { String lbl = assumeVectorField(rel).getLabel(col); - if (lbl != null) { + if(lbl != null) { return lbl; - } else { + } + else { return "Column " + col; } } + + /** + * An ugly vector type cast unavoidable in some situations due to Generics. + * + * @param <V> Base vector type + * @param <T> Derived vector type (is actually V, too) + * @param database Database + * @return Database + */ + @SuppressWarnings("unchecked") + public static <V extends NumberVector, T extends NumberVector> Relation<V> relationUglyVectorCast(Relation<T> database) { + return (Relation<V>) database; + } + + /** + * Iterator class that retrieves the given objects from the database. + * + * @author Erich Schubert + */ + public static class RelationObjectIterator<O> implements Iterator<O> { + /** + * The real iterator. + */ + final DBIDIter iter; + + /** + * The database we use. + */ + final Relation<? extends O> database; + + /** + * Full Constructor. + * + * @param iter Original iterator. + * @param database Database + */ + public RelationObjectIterator(DBIDIter iter, Relation<? extends O> database) { + super(); + this.iter = iter; + this.database = database; + } + + /** + * Simplified constructor. + * + * @param database Database + */ + public RelationObjectIterator(Relation<? extends O> database) { + super(); + this.database = database; + this.iter = database.iterDBIDs(); + } + + @Override + public boolean hasNext() { + return iter.valid(); + } + + @Override + public O next() { + O ret = database.get(iter); + iter.advance(); + return ret; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } + + /** + * Collection view on a database that retrieves the objects when needed. + * + * @author Erich Schubert + */ + public static class CollectionFromRelation<O> extends AbstractCollection<O> implements Collection<O> { + /** + * The database we query. + */ + Relation<? extends O> db; + + /** + * Constructor. + * + * @param db Database + */ + public CollectionFromRelation(Relation<? extends O> db) { + super(); + this.db = db; + } + + @Override + public Iterator<O> iterator() { + return new RelationObjectIterator<>(db); + } + + @Override + public int size() { + return db.size(); + } + } + + /** + * Sort objects by a double relation + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class AscendingByDoubleRelation implements Comparator<DBIDRef> { + /** + * Scores to use for sorting. + */ + private final DoubleRelation scores; + + /** + * Constructor. + * + * @param scores Scores for sorting + */ + public AscendingByDoubleRelation(DoubleRelation scores) { + super(); + this.scores = scores; + } + + @Override + public int compare(DBIDRef id1, DBIDRef id2) { + return Double.compare(scores.doubleValue(id1), scores.doubleValue(id2)); + } + } + + /** + * Sort objects by a double relation + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class DescendingByDoubleRelation implements Comparator<DBIDRef> { + /** + * Scores to use for sorting. + */ + private final DoubleRelation scores; + + /** + * Constructor. + * + * @param scores Scores for sorting + */ + public DescendingByDoubleRelation(DoubleRelation scores) { + super(); + this.scores = scores; + } + + @Override + public int compare(DBIDRef id1, DBIDRef id2) { + return Double.compare(scores.doubleValue(id2), scores.doubleValue(id1)); + } + } } diff --git a/src/de/lmu/ifi/dbs/elki/database/relation/package-info.java b/src/de/lmu/ifi/dbs/elki/database/relation/package-info.java index 133d6574..396c41f0 100644 --- a/src/de/lmu/ifi/dbs/elki/database/relation/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/database/relation/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team |