diff options
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.java | 74 |
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); } } |