summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceInOnDiskMatrix.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceInOnDiskMatrix.java')
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceInOnDiskMatrix.java74
1 files changed, 34 insertions, 40 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceInOnDiskMatrix.java b/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceInOnDiskMatrix.java
index 6a28282c..02290ced 100644
--- a/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceInOnDiskMatrix.java
+++ b/src/de/lmu/ifi/dbs/elki/application/cache/CacheDoubleDistanceInOnDiskMatrix.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.cache;
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
@@ -28,17 +28,17 @@ import java.io.IOException;
import de.lmu.ifi.dbs.elki.application.AbstractApplication;
import de.lmu.ifi.dbs.elki.database.Database;
-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.DBIDArrayIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRange;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
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.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.external.DiskCacheBasedDoubleDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.persistent.OnDiskUpperTriangleMatrix;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
@@ -54,9 +54,8 @@ import de.lmu.ifi.dbs.elki.workflow.InputStep;
* @apiviz.has DistanceFunction
*
* @param <O> Object type
- * @param <D> Distance type
*/
-public class CacheDoubleDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>> extends AbstractApplication {
+public class CacheDoubleDistanceInOnDiskMatrix<O> extends AbstractApplication {
/**
* The logger for this class.
*/
@@ -75,7 +74,7 @@ public class CacheDoubleDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>
/**
* Distance function that is to be cached.
*/
- private DistanceFunction<O, D> distance;
+ private DistanceFunction<O> distance;
/**
* Output file.
@@ -89,7 +88,7 @@ public class CacheDoubleDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>
* @param distance Distance function
* @param out Matrix output file
*/
- public CacheDoubleDistanceInOnDiskMatrix(InputStep input, DistanceFunction<O, D> distance, File out) {
+ public CacheDoubleDistanceInOnDiskMatrix(InputStep input, DistanceFunction<O> distance, File out) {
super();
this.input = input;
this.distance = distance;
@@ -100,40 +99,35 @@ public class CacheDoubleDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>
public void run() {
Database database = input.getDatabase();
Relation<O> relation = database.getRelation(distance.getInputTypeRestriction());
- DistanceQuery<O, D> distanceQuery = database.getDistanceQuery(relation, distance);
-
- int matrixsize = 0;
- for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
- int intid = DBIDUtil.asInteger(iditer);
- matrixsize = Math.max(matrixsize, intid + 1);
- if (intid < 0) {
- throw new AbortException("OnDiskMatrixCache does not allow negative DBIDs.");
- }
- }
+ DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, distance);
+
+ DBIDRange ids = DBIDUtil.assertRange(relation.getDBIDs());
+ int matrixsize = ids.size();
OnDiskUpperTriangleMatrix matrix;
try {
- matrix = new OnDiskUpperTriangleMatrix(out, DiskCacheBasedDoubleDistanceFunction.DOUBLE_CACHE_MAGIC, 0, 8, matrixsize);
- } catch (IOException e) {
+ matrix = new OnDiskUpperTriangleMatrix(out, DiskCacheBasedDoubleDistanceFunction.DOUBLE_CACHE_MAGIC, 0, ByteArrayUtil.SIZE_DOUBLE, matrixsize);
+ }
+ catch(IOException e) {
throw new AbortException("Error creating output matrix.", e);
}
- for (DBIDIter id1 = relation.iterDBIDs(); id1.valid(); id1.advance()) {
- for (DBIDIter id2 = relation.iterDBIDs(); id2.valid(); id2.advance()) {
- if (DBIDUtil.asInteger(id2) >= DBIDUtil.asInteger(id1)) {
- double d = distanceQuery.distance(id1, id2).doubleValue();
- if (debugExtraCheckSymmetry) {
- double d2 = distanceQuery.distance(id2, id1).doubleValue();
- if (Math.abs(d - d2) > 0.0000001) {
- LOG.warning("Distance function doesn't appear to be symmetric!");
- }
- }
- try {
- matrix.getRecordBuffer(DBIDUtil.asInteger(id1), DBIDUtil.asInteger(id2)).putDouble(d);
- } catch (IOException e) {
- throw new AbortException("Error writing distance record " + DBIDFactory.FACTORY.toString(id1) + "," + DBIDFactory.FACTORY.toString(id2) + " to matrix.", e);
+ DBIDArrayIter id1 = ids.iter(), id2 = ids.iter();
+ for(; id1.valid(); id1.advance()) {
+ for(id2.seek(id1.getOffset()); id2.valid(); id2.advance()) {
+ double d = distanceQuery.distance(id1, id2);
+ if(debugExtraCheckSymmetry) {
+ double d2 = distanceQuery.distance(id2, id1);
+ if(Math.abs(d - d2) > 0.0000001) {
+ LOG.warning("Distance function doesn't appear to be symmetric!");
}
}
+ try {
+ matrix.getRecordBuffer(id1.getOffset(), id2.getOffset()).putDouble(d);
+ }
+ catch(IOException e) {
+ throw new AbortException("Error writing distance record " + DBIDUtil.toString(id1) + "," + DBIDUtil.toString(id2) + " to matrix.", e);
+ }
}
}
}
@@ -145,7 +139,7 @@ public class CacheDoubleDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractApplication.Parameterizer {
+ public static class Parameterizer<O> extends AbstractApplication.Parameterizer {
/**
* Parameter that specifies the name of the directory to be re-parsed.
* <p>
@@ -170,7 +164,7 @@ public class CacheDoubleDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>
/**
* Distance function that is to be cached.
*/
- private DistanceFunction<O, D> distance = null;
+ private DistanceFunction<O> distance = null;
/**
* Output file.
@@ -182,19 +176,19 @@ public class CacheDoubleDistanceInOnDiskMatrix<O, D extends NumberDistance<D, ?>
super.makeOptions(config);
input = config.tryInstantiate(InputStep.class);
// Distance function parameter
- final ObjectParameter<DistanceFunction<O, D>> dpar = new ObjectParameter<>(DISTANCE_ID, DistanceFunction.class);
- if (config.grab(dpar)) {
+ final ObjectParameter<DistanceFunction<O>> dpar = new ObjectParameter<>(DISTANCE_ID, DistanceFunction.class);
+ if(config.grab(dpar)) {
distance = dpar.instantiateClass(config);
}
// Output file parameter
final FileParameter cpar = new FileParameter(CACHE_ID, FileParameter.FileType.OUTPUT_FILE);
- if (config.grab(cpar)) {
+ if(config.grab(cpar)) {
out = cpar.getValue();
}
}
@Override
- protected CacheDoubleDistanceInOnDiskMatrix<O, D> makeInstance() {
+ protected CacheDoubleDistanceInOnDiskMatrix<O> makeInstance() {
return new CacheDoubleDistanceInOnDiskMatrix<>(input, distance, out);
}
}