summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java
diff options
context:
space:
mode:
authorAndrej Shadura <andrewsh@debian.org>2019-03-09 22:30:40 +0000
committerAndrej Shadura <andrewsh@debian.org>2019-03-09 22:30:40 +0000
commit337087b668d3a54f3afee3a9adb597a32e9f7e94 (patch)
treed860094269622472f8079d497ac7af02dbb4e038 /src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java
parent14a486343aef55f97f54082d6b542dedebf6f3ba (diff)
Import Upstream version 0.6.5~20141030
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java')
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java137
1 files changed, 65 insertions, 72 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java
index 29546401..055d5d75 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/external/FileBasedDoubleDistanceFunction.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
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,63 +23,44 @@ package de.lmu.ifi.dbs.elki.distance.distancefunction.external;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import gnu.trove.map.TLongDoubleMap;
+import gnu.trove.map.hash.TLongDoubleHashMap;
+
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.Map;
-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.distance.distancefunction.AbstractDBIDDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractDBIDRangeDistanceFunction;
import de.lmu.ifi.dbs.elki.utilities.FileUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ChainedParameterization;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
- * Provides a DistanceFunction that is based on double distances given by a
- * distance matrix of an external file.
+ * Distance function that is based on double distances given by a distance
+ * matrix of an external ascii file.
+ *
+ * See {@link AsciiDistanceParser} for the default input format.
*
- * See {@link NumberDistanceParser} for the default input format.
+ * TODO: use a {@code double[]} instead of the hash map.
*
* @author Elke Achtert
+ * @author Erich Schubert
*/
@Title("File based double distance for database objects.")
@Description("Loads double distance values from an external text file.")
-public class FileBasedDoubleDistanceFunction extends AbstractDBIDDistanceFunction<DoubleDistance> {
- /**
- * Parameter that specifies the name of the distance matrix file.
- * <p>
- * Key: {@code -distance.matrix}
- * </p>
- */
- public static final OptionID MATRIX_ID = new OptionID("distance.matrix", "The name of the file containing the distance matrix.");
-
- /**
- * Optional parameter to specify the parsers to provide a database, must
- * extend {@link DistanceParser}. If this parameter is not set,
- * {@link NumberDistanceParser} is used as parser for all input files.
- * <p>
- * Key: {@code -distance.parser}
- * </p>
- */
- public static final OptionID PARSER_ID = new OptionID("distance.parser", "Parser used to load the distance matrix.");
-
+public class FileBasedDoubleDistanceFunction extends AbstractDBIDRangeDistanceFunction {
/**
* The distance cache
*/
- private Map<DBIDPair, DoubleDistance> cache;
+ private TLongDoubleMap cache;
/**
* Constructor.
@@ -87,7 +68,7 @@ public class FileBasedDoubleDistanceFunction extends AbstractDBIDDistanceFunctio
* @param parser Parser
* @param matrixfile input file
*/
- public FileBasedDoubleDistanceFunction(DistanceParser<DoubleDistance> parser, File matrixfile) {
+ public FileBasedDoubleDistanceFunction(DistanceParser parser, File matrixfile) {
super();
try {
loadCache(parser, matrixfile);
@@ -97,45 +78,41 @@ public class FileBasedDoubleDistanceFunction extends AbstractDBIDDistanceFunctio
}
}
- /**
- * Returns the distance between the two objects specified by their objects
- * ids. If a cache is used, the distance value is looked up in the cache. If
- * the distance does not yet exists in cache, it will be computed an put to
- * cache. If no cache is used, the distance is computed.
- *
- * @param id1 first object id
- * @param id2 second object id
- * @return the distance between the two objects specified by their objects ids
- */
@Override
- public DoubleDistance distance(DBIDRef id1, DBIDRef id2) {
- if(id1 == null) {
- return getDistanceFactory().undefinedDistance();
- }
- if(id2 == null) {
- return getDistanceFactory().undefinedDistance();
+ public double distance(int i1, int i2) {
+ if(i1 == i2) {
+ return 0.;
}
- // the smaller id is the first key
- if(DBIDUtil.compare(id1, id2) > 0) {
- return distance(id2, id1);
- }
-
- DoubleDistance ret = cache.get(DBIDUtil.newPair(id1, id2));
- if (ret == null && DBIDUtil.equal(id1, id2)) {
- return DoubleDistance.ZERO_DISTANCE;
- }
- return ret;
+ return cache.get(makeKey(i1, i2));
}
- private void loadCache(DistanceParser<DoubleDistance> parser, File matrixfile) throws IOException {
+ private void loadCache(DistanceParser parser, File matrixfile) throws IOException {
InputStream in = new BufferedInputStream(FileUtil.tryGzipInput(new FileInputStream(matrixfile)));
- DistanceParsingResult<DoubleDistance> res = parser.parse(in);
- cache = res.getDistanceCache();
+ cache = new TLongDoubleHashMap();
+ parser.parse(in, new DistanceCacheWriter() {
+ @Override
+ public void put(int id1, int id2, double distance) {
+ cache.put(makeKey(id1, id2), distance);
+ }
+
+ @Override
+ public boolean containsKey(int id1, int id2) {
+ return cache.containsKey(makeKey(id1, id2));
+ }
+ });
}
- @Override
- public DoubleDistance getDistanceFactory() {
- return DoubleDistance.FACTORY;
+ /**
+ * Combine two integer ids into a long value.
+ *
+ * @param i1 First id
+ * @param i2 Second id
+ * @return Combined value
+ */
+ protected static final long makeKey(int i1, int i2) {
+ return (i1 < i2) //
+ ? ((((long) i1) << 32) | i2)//
+ : ((((long) i2) << 32) | i1);
}
@Override
@@ -158,9 +135,29 @@ public class FileBasedDoubleDistanceFunction extends AbstractDBIDDistanceFunctio
* @apiviz.exclude
*/
public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Parameter that specifies the name of the distance matrix file.
+ * <p>
+ * Key: {@code -distance.matrix}
+ * </p>
+ */
+ public static final OptionID MATRIX_ID = new OptionID("distance.matrix", //
+ "The name of the file containing the distance matrix.");
+
+ /**
+ * Optional parameter to specify the parsers to provide a database, must
+ * extend {@link DistanceParser}. If this parameter is not set,
+ * {@link AsciiDistanceParser} is used as parser for all input files.
+ * <p>
+ * Key: {@code -distance.parser}
+ * </p>
+ */
+ public static final OptionID PARSER_ID = new OptionID("distance.parser", //
+ "Parser used to load the distance matrix.");
+
protected File matrixfile = null;
- protected DistanceParser<DoubleDistance> parser = null;
+ protected DistanceParser parser = null;
@Override
protected void makeOptions(Parameterization config) {
@@ -170,13 +167,9 @@ public class FileBasedDoubleDistanceFunction extends AbstractDBIDDistanceFunctio
matrixfile = MATRIX_PARAM.getValue();
}
- final ObjectParameter<DistanceParser<DoubleDistance>> PARSER_PARAM = new ObjectParameter<>(PARSER_ID, DistanceParser.class, NumberDistanceParser.class);
+ final ObjectParameter<DistanceParser> PARSER_PARAM = new ObjectParameter<>(PARSER_ID, DistanceParser.class, AsciiDistanceParser.class);
if(config.grab(PARSER_PARAM)) {
- ListParameterization parserConfig = new ListParameterization();
- parserConfig.addParameter(DistanceParser.DISTANCE_ID, DoubleDistance.class);
- ChainedParameterization combinedConfig = new ChainedParameterization(parserConfig, config);
- combinedConfig.errorsTo(config);
- parser = PARSER_PARAM.instantiateClass(combinedConfig);
+ parser = PARSER_PARAM.instantiateClass(config);
}
}