diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/result')
65 files changed, 1054 insertions, 1166 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/result/AbstractHierarchicalResult.java b/src/de/lmu/ifi/dbs/elki/result/AbstractHierarchicalResult.java index 203e8395..67286b65 100644 --- a/src/de/lmu/ifi/dbs/elki/result/AbstractHierarchicalResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/AbstractHierarchicalResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/AprioriResult.java b/src/de/lmu/ifi/dbs/elki/result/AprioriResult.java index 45e82b92..b39f15d9 100644 --- a/src/de/lmu/ifi/dbs/elki/result/AprioriResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/AprioriResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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,58 +23,58 @@ package de.lmu.ifi.dbs.elki.result; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.BitSet; import java.util.List; -import java.util.Map; + +import de.lmu.ifi.dbs.elki.algorithm.itemsetmining.Itemset; +import de.lmu.ifi.dbs.elki.data.BitVector; +import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation; +import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable; +import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream; /** * Result class for Apriori Algorithm. * * @author Erich Schubert - * */ -public class AprioriResult extends BasicResult { +public class AprioriResult extends BasicResult implements TextWriteable { /** - * The frequent itemsets. + * The supports of all frequent itemsets. */ - private List<BitSet> solution; + private List<Itemset> itemsets; /** - * The supports of all itemsets. + * Metadata of the data relation, for item labels. */ - private Map<BitSet, Integer> supports; + private VectorFieldTypeInformation<BitVector> meta; /** * Constructor. * * @param name The long name (for pretty printing) * @param shortname the short name (for filenames etc.) - * @param solution Frequent itemsets - * @param supports Supports for the itemsets + * @param itemsets Frequent itemsets + * @param meta Metadata */ - public AprioriResult(String name, String shortname, List<BitSet> solution, Map<BitSet, Integer> supports) { + public AprioriResult(String name, String shortname, List<Itemset> itemsets, VectorFieldTypeInformation<BitVector> meta) { super(name, shortname); - this.solution = solution; - this.supports = supports; + this.itemsets = itemsets; + this.meta = meta; } /** * Returns the frequent item sets. - * + * * @return the frequent item sets. */ - public List<BitSet> getSolution() { - return solution; + public List<Itemset> getItemsets() { + return itemsets; } - /** - * Returns the frequencies of the frequent item sets. - * - * @return the frequencies of the frequent item sets - */ - public Map<BitSet, Integer> getSupports() { - return supports; + @Override + public void writeToText(TextWriterStream out, String label) { + for(Itemset itemset : itemsets) { + out.inlinePrintNoQuotes(itemset.appendTo(new StringBuilder(), meta)); + out.flush(); + } } - - // TODO: text writer for AprioriResult! } diff --git a/src/de/lmu/ifi/dbs/elki/result/BasicResult.java b/src/de/lmu/ifi/dbs/elki/result/BasicResult.java index f2d10149..06ef2d6d 100644 --- a/src/de/lmu/ifi/dbs/elki/result/BasicResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/BasicResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/ClusteringVectorDumper.java b/src/de/lmu/ifi/dbs/elki/result/ClusteringVectorDumper.java new file mode 100644 index 00000000..7d78ca65 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/result/ClusteringVectorDumper.java @@ -0,0 +1,269 @@ +package de.lmu.ifi.dbs.elki.result; + +/* + 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.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.List; + +import de.lmu.ifi.dbs.elki.data.Cluster; +import de.lmu.ifi.dbs.elki.data.Clustering; +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.WritableIntegerDataStore; +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.DBIDRange; +import de.lmu.ifi.dbs.elki.database.ids.DBIDs; +import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.datasource.parser.ClusteringVectorParser; +import de.lmu.ifi.dbs.elki.logging.Logging; +import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy.Iter; +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.Parameterization; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.StringParameter; + +/** + * <p> + * Class to output a clustering result in a simple and compact ascii format: + * whitespace separated cluster indexes + * </p> + * + * This format can be read using {@link ClusteringVectorParser} for analysis. + * + * @author Erich Schubert + */ +public class ClusteringVectorDumper implements ResultHandler { + /** + * Class logger. + */ + private static final Logging LOG = Logging.getLogger(ClusteringVectorDumper.class); + + /** + * Output file. + */ + private File outputFile; + + /** + * Optional label to force for this output. + */ + private String forceLabel; + + /** + * Always append to the output file. + */ + private boolean append; + + /** + * Constructor. + * + * @param outputFile Output file + * @param append Append to output file (overwrite otherwise). + * @param forceLabel Forced label to use for the output, may be {@code null}. + */ + public ClusteringVectorDumper(File outputFile, boolean append, String forceLabel) { + super(); + this.outputFile = outputFile; + this.forceLabel = forceLabel; + this.append = append; + } + + /** + * Constructor. + * + * @param outputFile Output file + * @param append Append to output file (overwrite otherwise). + */ + public ClusteringVectorDumper(File outputFile, boolean append) { + this(outputFile, append, null); + } + + @Override + public void processNewResult(HierarchicalResult baseResult, Result newResult) { + List<Clustering<?>> cs = ResultUtil.getClusteringResults(newResult); + if(cs.size() < 1) { + return; + } + if(forceLabel != null && forceLabel.length() > 0 && cs.size() > 1) { + LOG.warning("Found more than one clustering result, they will have the same (forced) label."); + } + + // Open output stream - or use stdout. + if(outputFile != null) { + try (FileOutputStream os = new FileOutputStream(outputFile, append); // + PrintStream writer = new PrintStream(os)) { + // TODO: dump settings, too? + for(Clustering<?> c : cs) { + dumpClusteringOutput(writer, baseResult.getHierarchy(), c); + } + append = true; // Append future results. + } + catch(IOException e) { + LOG.exception("Error writing to output stream.", e); + } + } + else { + for(Clustering<?> c : cs) { + dumpClusteringOutput(System.out, baseResult.getHierarchy(), c); + } + } + } + + /** + * Dump a single clustering result. + * + * @param writer Output writer + * @param hierarchy Cluster hierarchy to process + * @param c Clustering result + */ + protected void dumpClusteringOutput(PrintStream writer, ResultHierarchy hierarchy, Clustering<?> c) { + DBIDRange ids = null; + for(Iter<Result> iter = hierarchy.iterParents(c); iter.valid(); iter.advance()) { + Result parent = iter.get(); + if(parent instanceof Relation) { + DBIDs pids = ((Relation<?>) parent).getDBIDs(); + if(pids instanceof DBIDRange) { + ids = (DBIDRange) pids; + break; + } + LOG.warning("Parent result " + parent.getLongName() + " has DBID type " + pids.getClass()); + } + } + // Fallback: try to locate a database. + if(ids == null) { + for(Iter<Result> iter = hierarchy.iterAll(); iter.valid(); iter.advance()) { + Result parent = iter.get(); + if(parent instanceof Database) { + DBIDs pids = ((Database) parent).getRelation(TypeUtil.ANY).getDBIDs(); + if(pids instanceof DBIDRange) { + ids = (DBIDRange) pids; + break; + } + LOG.warning("Parent result " + parent.getLongName() + " has DBID type " + pids.getClass()); + } + } + } + if(ids == null) { + LOG.warning("Cannot dump cluster assignment, as I do not have a well-defined DBIDRange to use for a unique column assignment. DBIDs must be a continuous range."); + return; + } + + WritableIntegerDataStore map = DataStoreUtil.makeIntegerStorage(ids, DataStoreFactory.HINT_TEMP); + int cnum = 0; + for(Cluster<?> clu : c.getAllClusters()) { + for(DBIDIter iter = clu.getIDs().iter(); iter.valid(); iter.advance()) { + map.putInt(iter, cnum); + } + ++cnum; + } + for(DBIDArrayIter iter = ids.iter(); iter.valid(); iter.advance()) { + if(iter.getOffset() > 0) { + writer.append(' '); + } + writer.append(Integer.toString(map.intValue(iter))); + } + if(forceLabel != null) { + if(forceLabel.length() > 0) { + writer.append(' ').append(forceLabel); + } + } + else { + writer.append(' ').append(c.getLongName()); + } + writer.append('\n'); + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + /** + * Output file name parameter. + */ + public static final OptionID OUT_ID = new OptionID("clustering.output", "Output file name. When not given, the result will be written to stdout."); + + /** + * Append flag. + */ + public static final OptionID APPEND_ID = new OptionID("clustering.output.append", "Always append to the output file."); + + /** + * Force label parameter. + */ + public static final OptionID FORCE_LABEL_ID = new OptionID("clustering.label", "Parameter to override the clustering label, mostly to give a more descriptive label."); + + /** + * Output file. + */ + private File outputFile = null; + + /** + * Optional label to force for this output. + */ + private String forceLabel; + + /** + * Always append to the output file. + */ + private boolean append; + + @Override + protected void makeOptions(Parameterization config) { + super.makeOptions(config); + FileParameter outputP = new FileParameter(OUT_ID, FileParameter.FileType.OUTPUT_FILE) // + .setOptional(true); + if(config.grab(outputP)) { + outputFile = outputP.getValue(); + } + + Flag appendF = new Flag(APPEND_ID); + if(config.grab(appendF)) { + append = appendF.isTrue(); + } + + StringParameter labelP = new StringParameter(FORCE_LABEL_ID) // + .setOptional(true); + if(config.grab(labelP)) { + forceLabel = labelP.getValue(); + } + } + + @Override + protected ClusteringVectorDumper makeInstance() { + return new ClusteringVectorDumper(outputFile, append, forceLabel); + } + + } +} diff --git a/src/de/lmu/ifi/dbs/elki/result/CollectionResult.java b/src/de/lmu/ifi/dbs/elki/result/CollectionResult.java index 76e35e48..de0442d9 100644 --- a/src/de/lmu/ifi/dbs/elki/result/CollectionResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/CollectionResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/DBIDSelection.java b/src/de/lmu/ifi/dbs/elki/result/DBIDSelection.java index 97459a6a..d70089d7 100644 --- a/src/de/lmu/ifi/dbs/elki/result/DBIDSelection.java +++ b/src/de/lmu/ifi/dbs/elki/result/DBIDSelection.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/DiscardResultHandler.java b/src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java index 847e22fb..165fa070 100644 --- a/src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java +++ b/src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/EvaluationResult.java b/src/de/lmu/ifi/dbs/elki/result/EvaluationResult.java new file mode 100644 index 00000000..aaf01821 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/result/EvaluationResult.java @@ -0,0 +1,305 @@ +package de.lmu.ifi.dbs.elki.result; + +/* + 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.Iterator; + +import de.lmu.ifi.dbs.elki.result.textwriter.TextWriteable; +import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream; + +/** + * Abstract evaluation result. + * + * @author Erich Schubert + * + * @apiviz.composedOf EvaluationResult.MeasurementGroup + */ +public class EvaluationResult extends BasicResult implements TextWriteable, Iterable<EvaluationResult.MeasurementGroup> { + /** + * Measurements. + */ + ArrayList<EvaluationResult.MeasurementGroup> groups = new ArrayList<>(); + + /** + * Header lines. + */ + ArrayList<String> header = new ArrayList<>(); + + /** + * Constructor. + * + * @param name Evaluation name + * @param shortname Short name + */ + public EvaluationResult(String name, String shortname) { + super(name, shortname); + } + + /** + * Add a new measurement group. + * + * @param string Group name + * @return Measurement group. + */ + public EvaluationResult.MeasurementGroup newGroup(String string) { + EvaluationResult.MeasurementGroup g = new MeasurementGroup(string); + groups.add(g); + return g; + } + + @Override + public void writeToText(TextWriterStream out, String label) { + for(EvaluationResult.MeasurementGroup g : groups) { + out.commentPrintLn(g.getName()); + out.flush(); + for(Measurement m : g) { + out.inlinePrintNoQuotes(m.name); + out.inlinePrintNoQuotes(m.val); + out.flush(); + } + } + } + + /** + * Add a header line to this result. + * + * @param line Header line + */ + public void addHeader(String line) { + header.add(line); + } + + /** + * Get the header lines. + * + * @return Header lines + */ + public Iterable<String> getHeaderLines() { + return header; + } + + @Override + public Iterator<MeasurementGroup> iterator() { + return groups.iterator(); + } + + /** + * A group of evaluation measurements. + * + * @author Erich Schubert + * + * @apiviz.composedOf EvaluationResult.Measurement + */ + public static class MeasurementGroup implements Iterable<Measurement> { + /** + * Group name + */ + private String groupname; + + /** + * Measurements in this group. + */ + private ArrayList<Measurement> measurements = new ArrayList<>(); + + /** + * Constructor. + * + * @param gname Group name + */ + protected MeasurementGroup(String gname) { + this.groupname = gname; + } + + /** + * Get the group name. + * + * @return Group name + */ + public String getName() { + return groupname; + } + + /** + * Add a single measurement. + * + * @param name Measurement name + * @param val Observed value + * @param min Minimum value + * @param max Maximum value + * @param lowerisbetter Flag + * @return {@code this} (Builder pattern) + */ + public MeasurementGroup addMeasure(String name, double val, double min, double max, boolean lowerisbetter) { + measurements.add(new Measurement(name, val, min, max, lowerisbetter)); + return this; + } + + /** + * Add a single measurement. + * + * @param name Measurement name + * @param val Observed value + * @param min Minimum value + * @param exp Expected value + * @param lowerisbetter Flag + * @return {@code this} (Builder pattern) + */ + public MeasurementGroup addMeasure(String name, double val, double min, double max, double exp, boolean lowerisbetter) { + measurements.add(new Measurement(name, val, min, max, exp, lowerisbetter)); + return this; + } + + @Override + public Iterator<Measurement> iterator() { + return measurements.iterator(); + } + } + + /** + * Class representing a single measurement. + * + * TODO: indicate whether high or low is better. + * + * @author Erich Schubert + */ + public static class Measurement { + /** + * Measurement name. + */ + String name; + + /** + * Observed value, minimum, maximum, expected value. + */ + double val; + + /** + * Observed value, minimum, maximum, expected value. + */ + double min; + + /** + * Observed value, minimum, maximum, expected value. + */ + double max; + + /** + * Observed value, minimum, maximum, expected value. + */ + double exp; + + /** + * Indicates low values are better. + */ + private boolean lowerisbetter; + + /** + * Constructor. + * + * @param name Name + * @param val Value + * @param min Minimum + * @param max Maximum + * @param lowerisbetter Flag + */ + protected Measurement(String name, double val, double min, double max, boolean lowerisbetter) { + this(name, val, min, max, Double.NaN, lowerisbetter); + } + + /** + * Constructor. + * + * @param name Name + * @param val Value + * @param min Minimum + * @param max Maximum + * @param exp Expected value + * @param lowerisbetter Flag + */ + protected Measurement(String name, double val, double min, double max, double exp, boolean lowerisbetter) { + super(); + this.name = name; + this.val = val; + this.min = min; + this.max = max; + this.exp = exp; + this.lowerisbetter = lowerisbetter; + } + + /** + * Get the name of this measurement. + * + * @return Measurement name. + */ + public String getName() { + return name; + } + + /** + * Get the observed value. + * + * @return observed value. + */ + public double getVal() { + return val; + } + + /** + * Get the minimum value. + * + * @return Minimum value. + */ + public double getMin() { + return min; + } + + /** + * Get the maximum value. + * + * @return Maximum value. + */ + public double getMax() { + return max; + } + + /** + * Get the expected value. May be {@code Double.NaN}. + * + * @return Expected value. + */ + public double getExp() { + return exp; + } + + /** + * Return {@code true} if low values are better. + * + * @return {@code true} when low values are better. + */ + public boolean lowerIsBetter() { + return lowerisbetter; + } + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/result/HierarchicalResult.java b/src/de/lmu/ifi/dbs/elki/result/HierarchicalResult.java index 28841ddf..fce7b6d9 100644 --- a/src/de/lmu/ifi/dbs/elki/result/HierarchicalResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/HierarchicalResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/HistogramResult.java b/src/de/lmu/ifi/dbs/elki/result/HistogramResult.java index 6e3fc745..936fa933 100644 --- a/src/de/lmu/ifi/dbs/elki/result/HistogramResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/HistogramResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/IterableResult.java b/src/de/lmu/ifi/dbs/elki/result/IterableResult.java index e7a6f35c..d539a896 100644 --- a/src/de/lmu/ifi/dbs/elki/result/IterableResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/IterableResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/KMLOutputHandler.java b/src/de/lmu/ifi/dbs/elki/result/KMLOutputHandler.java index 11391036..108d8c08 100644 --- a/src/de/lmu/ifi/dbs/elki/result/KMLOutputHandler.java +++ b/src/de/lmu/ifi/dbs/elki/result/KMLOutputHandler.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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,11 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; import java.util.LinkedList; +import java.util.List; +import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -38,30 +42,40 @@ import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; +import de.lmu.ifi.dbs.elki.data.Cluster; +import de.lmu.ifi.dbs.elki.data.Clustering; +import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.data.model.Model; import de.lmu.ifi.dbs.elki.data.spatial.Polygon; import de.lmu.ifi.dbs.elki.data.spatial.PolygonsObject; +import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil; import de.lmu.ifi.dbs.elki.data.type.TypeUtil; import de.lmu.ifi.dbs.elki.database.Database; import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs; 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.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.logging.Logging; +import de.lmu.ifi.dbs.elki.math.geometry.GrahamScanConvexHull2D; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult; import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; import de.lmu.ifi.dbs.elki.utilities.FormatUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy; +import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy.Iter; import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.ArrayListIter; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; 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.Parameterizable; 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.Flag; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter; +import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleObjPair; import de.lmu.ifi.dbs.elki.utilities.scaling.outlier.OutlierLinearScaling; import de.lmu.ifi.dbs.elki.utilities.scaling.outlier.OutlierScalingFunction; import de.lmu.ifi.dbs.elki.workflow.OutputStep; @@ -77,11 +91,18 @@ import de.lmu.ifi.dbs.elki.workflow.OutputStep; * (SSTD), Minneapolis, MN, 2011 * </p> * + * Note: This class - currently - is an ugly hack. This code needs to be + * modularized to make it more reusable, to support multiple results and + * different result types. + * * @author Erich Schubert */ // TODO: make configurable color scheme -@Reference(authors = "E. Achtert, A. Hettab, H.-P. Kriegel, E. Schubert, A. Zimek", booktitle = "Proc. 12th International Symposium on Spatial and Temporal Databases (SSTD), Minneapolis, MN, 2011", title = "Spatial Outlier Detection: Data, Algorithms, Visualizations") -public class KMLOutputHandler implements ResultHandler, Parameterizable { +@Reference(authors = "E. Achtert, A. Hettab, H.-P. Kriegel, E. Schubert, A. Zimek", // +booktitle = "Proc. 12th International Symposium on Spatial and Temporal Databases (SSTD), Minneapolis, MN, 2011", // +title = "Spatial Outlier Detection: Data, Algorithms, Visualizations", // +url = "http://dx.doi.org/10.1007/978-3-642-22922-0_41") +public class KMLOutputHandler implements ResultHandler { /** * Logger class to use. */ @@ -131,50 +152,70 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { @Override public void processNewResult(HierarchicalResult baseResult, Result newResult) { ArrayList<OutlierResult> ors = ResultUtil.filterResults(newResult, OutlierResult.class); - if (ors.size() > 1) { - throw new AbortException("More than one outlier result found. The KML writer only supports a single outlier result!"); + ArrayList<Clustering<?>> crs = ResultUtil.filterResults(newResult, Clustering.class); + if(ors.size() + crs.size() > 1) { + throw new AbortException("More than one visualizable result found. The KML writer only supports a single result!"); + } + for(OutlierResult outlierResult : ors) { + Database database = ResultUtil.findDatabase(baseResult); + try { + XMLOutputFactory factory = XMLOutputFactory.newInstance(); + ZipOutputStream out = new ZipOutputStream(new FileOutputStream(filename)); + out.putNextEntry(new ZipEntry("doc.kml")); + final XMLStreamWriter xmlw = factory.createXMLStreamWriter(out); + writeOutlierResult(xmlw, outlierResult, database); + xmlw.flush(); + xmlw.close(); + out.closeEntry(); + out.flush(); + out.close(); + if(autoopen) { + Desktop.getDesktop().open(filename); + } + } + catch(XMLStreamException e) { + LOG.exception(e); + throw new AbortException("XML error in KML output.", e); + } + catch(IOException e) { + LOG.exception(e); + throw new AbortException("IO error in KML output.", e); + } } - if (ors.size() == 1) { + for(Clustering<?> clusteringResult : crs) { Database database = ResultUtil.findDatabase(baseResult); try { XMLOutputFactory factory = XMLOutputFactory.newInstance(); ZipOutputStream out = new ZipOutputStream(new FileOutputStream(filename)); out.putNextEntry(new ZipEntry("doc.kml")); final XMLStreamWriter xmlw = factory.createXMLStreamWriter(out); - writeKMLData(xmlw, ors.get(0), database); + @SuppressWarnings("unchecked") + Clustering<Model> cres = (Clustering<Model>) clusteringResult; + writeClusteringResult(xmlw, cres, database); xmlw.flush(); xmlw.close(); out.closeEntry(); out.flush(); out.close(); - if (autoopen) { + if(autoopen) { Desktop.getDesktop().open(filename); } - } catch (XMLStreamException e) { + } + catch(XMLStreamException e) { LOG.exception(e); throw new AbortException("XML error in KML output.", e); - } catch (IOException e) { + } + catch(IOException e) { LOG.exception(e); throw new AbortException("IO error in KML output.", e); } } } - private void writeKMLData(XMLStreamWriter xmlw, OutlierResult outlierResult, Database database) throws XMLStreamException { - Relation<Double> scores = outlierResult.getScores(); + private void writeOutlierResult(XMLStreamWriter xmlw, OutlierResult outlierResult, Database database) throws XMLStreamException { Relation<PolygonsObject> polys = database.getRelation(TypeUtil.POLYGON_TYPE); Relation<String> labels = DatabaseUtil.guessObjectLabelRepresentation(database); - Collection<Relation<?>> otherrel = new LinkedList<>(database.getRelations()); - otherrel.remove(scores); - otherrel.remove(polys); - otherrel.remove(labels); - otherrel.remove(database.getRelation(TypeUtil.DBID)); - - ArrayModifiableDBIDs ids = DBIDUtil.newArray(scores.getDBIDs()); - - scaling.prepare(outlierResult); - xmlw.writeStartDocument(); xmlw.writeCharacters("\n"); xmlw.writeStartElement("kml"); @@ -194,7 +235,7 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { } { // TODO: generate styles from color scheme - for (int i = 0; i < NUMSTYLES; i++) { + for(int i = 0; i < NUMSTYLES; i++) { Color col = getColorForValue(i / (NUMSTYLES - 1.0)); xmlw.writeStartElement("Style"); xmlw.writeAttribute("id", "s" + i); @@ -227,14 +268,26 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { writeNewlineOnDebug(xmlw); } } - for (DBIDIter iter = outlierResult.getOrdering().iter(ids).iter(); iter.valid(); iter.advance()) { - Double score = scores.get(iter); + + DoubleRelation scores = outlierResult.getScores(); + Collection<Relation<?>> otherrel = new LinkedList<>(database.getRelations()); + otherrel.remove(scores); + otherrel.remove(polys); + otherrel.remove(labels); + otherrel.remove(database.getRelation(TypeUtil.DBID)); + + ArrayModifiableDBIDs ids = DBIDUtil.newArray(scores.getDBIDs()); + + scaling.prepare(outlierResult); + + for(DBIDIter iter = outlierResult.getOrdering().iter(ids).iter(); iter.valid(); iter.advance()) { + double score = scores.doubleValue(iter); PolygonsObject poly = polys.get(iter); String label = labels.get(iter); - if (score == null) { + if(Double.isNaN(score)) { LOG.warning("No score for object " + DBIDUtil.toString(iter)); } - if (poly == null) { + if(poly == null) { LOG.warning("No polygon for object " + DBIDUtil.toString(iter) + " - skipping."); continue; } @@ -256,7 +309,7 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { { xmlw.writeStartElement("Polygon"); writeNewlineOnDebug(xmlw); - if (compat) { + if(compat) { xmlw.writeStartElement("altitudeMode"); xmlw.writeCharacters("relativeToGround"); xmlw.writeEndElement(); // close altitude mode @@ -264,10 +317,11 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { } // First polygon clockwise? boolean first = true; - for (Polygon p : poly.getPolygons()) { - if (first) { + for(Polygon p : poly.getPolygons()) { + if(first) { xmlw.writeStartElement("outerBoundaryIs"); - } else { + } + else { xmlw.writeStartElement("innerBoundaryIs"); } xmlw.writeStartElement("LinearRing"); @@ -276,19 +330,20 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { // Reverse anti-clockwise polygons. boolean reverse = (p.testClockwise() >= 0); ArrayListIter<Vector> it = p.iter(); - if (reverse) { + if(reverse) { it.seek(p.size() - 1); } - while (it.valid()) { + while(it.valid()) { Vector v = it.get(); xmlw.writeCharacters(FormatUtil.format(v.getArrayRef(), ",")); - if (compat && (v.getDimensionality() == 2)) { + if(compat && (v.getDimensionality() == 2)) { xmlw.writeCharacters(",500"); } xmlw.writeCharacters(" "); - if (!reverse) { + if(!reverse) { it.advance(); - } else { + } + else { it.retract(); } } @@ -308,6 +363,187 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { xmlw.writeEndDocument(); } + private void writeClusteringResult(XMLStreamWriter xmlw, Clustering<Model> clustering, Database database) throws XMLStreamException { + xmlw.writeStartDocument(); + xmlw.writeCharacters("\n"); + xmlw.writeStartElement("kml"); + xmlw.writeDefaultNamespace("http://earth.google.com/kml/2.2"); + xmlw.writeStartElement("Document"); + { + // TODO: can we automatically generate more helpful data here? + xmlw.writeStartElement("name"); + xmlw.writeCharacters("ELKI KML output for " + clustering.getLongName()); + xmlw.writeEndElement(); // name + writeNewlineOnDebug(xmlw); + // TODO: e.g. list the settings in the description? + xmlw.writeStartElement("description"); + xmlw.writeCharacters("ELKI KML output for " + clustering.getLongName()); + xmlw.writeEndElement(); // description + writeNewlineOnDebug(xmlw); + } + + List<Cluster<Model>> clusters = clustering.getAllClusters(); + Relation<NumberVector> coords = database.getRelation(TypeUtil.NUMBER_VECTOR_FIELD_2D); + List<Cluster<Model>> topc = clustering.getToplevelClusters(); + Hierarchy<Cluster<Model>> hier = clustering.getClusterHierarchy(); + Map<Object, DoubleObjPair<Polygon>> hullmap = new HashMap<>(); + for(Cluster<Model> clu : topc) { + buildHullsRecursively(clu, hier, hullmap, coords); + } + + int numc = clusters.size(); + { + final double projarea = 90. * 90.; // 1/8 of earth + // TODO: generate styles from color scheme + Iterator<Cluster<Model>> it = clusters.iterator(); + for(int i = 0; it.hasNext(); i++) { + Cluster<Model> clus = it.next(); + Color col = Color.getHSBColor(i * 51.f / (float) numc, 1.f, .5f); + DoubleObjPair<Polygon> pair = hullmap.get(clus); + // Approximate area (using bounding box) + double hullarea = SpatialUtil.volume(pair.second); + final double relativeArea = 1. - (hullarea / projarea); + // final double relativeSize = pair.first / coords.size(); + final double opacity = 1. * Math.sqrt(relativeArea); + xmlw.writeStartElement("Style"); + xmlw.writeAttribute("id", "s" + i); + writeNewlineOnDebug(xmlw); + { + xmlw.writeStartElement("LineStyle"); + xmlw.writeStartElement("width"); + xmlw.writeCharacters("0"); + xmlw.writeEndElement(); // width + + xmlw.writeEndElement(); // LineStyle + } + writeNewlineOnDebug(xmlw); + { + xmlw.writeStartElement("PolyStyle"); + xmlw.writeStartElement("color"); + // KML uses AABBGGRR format! + xmlw.writeCharacters(String.format("%02x%02x%02x%02x", (int) (255 * Math.min(1., opacity)), col.getBlue(), col.getGreen(), col.getRed())); + xmlw.writeEndElement(); // color + // out.writeStartElement("fill"); + // out.writeCharacters("1"); // Default 1 + // out.writeEndElement(); // fill + xmlw.writeStartElement("outline"); + xmlw.writeCharacters("0"); + xmlw.writeEndElement(); // outline + xmlw.writeEndElement(); // PolyStyle + } + writeNewlineOnDebug(xmlw); + xmlw.writeEndElement(); // Style + writeNewlineOnDebug(xmlw); + } + } + + Cluster<?> ignore = topc.size() == 1 ? topc.get(0) : null; + Iterator<Cluster<Model>> it = clusters.iterator(); + for(int cnum = 0; it.hasNext(); cnum++) { + Cluster<?> c = it.next(); + // Ignore sole toplevel cluster (usually: noise) + if(c == ignore) { + continue; + } + Polygon p = hullmap.get(c).second; + xmlw.writeStartElement("Placemark"); + { + xmlw.writeStartElement("name"); + xmlw.writeCharacters(c.getNameAutomatic()); + xmlw.writeEndElement(); // name + xmlw.writeStartElement("description"); + xmlw.writeCData(makeDescription(c).toString()); + xmlw.writeEndElement(); // description + xmlw.writeStartElement("styleUrl"); + xmlw.writeCharacters("#s" + cnum); + xmlw.writeEndElement(); // styleUrl + } + { + xmlw.writeStartElement("Polygon"); + writeNewlineOnDebug(xmlw); + if(compat) { + xmlw.writeStartElement("altitudeMode"); + xmlw.writeCharacters("relativeToGround"); + xmlw.writeEndElement(); // close altitude mode + writeNewlineOnDebug(xmlw); + } + { + xmlw.writeStartElement("outerBoundaryIs"); + xmlw.writeStartElement("LinearRing"); + xmlw.writeStartElement("coordinates"); + + // Reverse anti-clockwise polygons. + boolean reverse = (p.testClockwise() >= 0); + ArrayListIter<Vector> itp = p.iter(); + if(reverse) { + itp.seek(p.size() - 1); + } + while(itp.valid()) { + Vector v = itp.get(); + xmlw.writeCharacters(FormatUtil.format(v.getArrayRef(), ",")); + if(compat && (v.getDimensionality() == 2)) { + xmlw.writeCharacters(",500"); + } + xmlw.writeCharacters(" "); + if(!reverse) { + itp.advance(); + } + else { + itp.retract(); + } + } + xmlw.writeEndElement(); // close coordinates + xmlw.writeEndElement(); // close LinearRing + xmlw.writeEndElement(); // close *BoundaryIs + } + writeNewlineOnDebug(xmlw); + xmlw.writeEndElement(); // Polygon + } + xmlw.writeEndElement(); // Placemark + writeNewlineOnDebug(xmlw); + } + xmlw.writeEndElement(); // Document + xmlw.writeEndElement(); // kml + xmlw.writeEndDocument(); + } + + /** + * Recursively step through the clusters to build the hulls. + * + * @param clu Current cluster + * @param hier Clustering hierarchy + * @param hulls Hull map + */ + private DoubleObjPair<Polygon> buildHullsRecursively(Cluster<Model> clu, Hierarchy<Cluster<Model>> hier, Map<Object, DoubleObjPair<Polygon>> hulls, Relation<? extends NumberVector> coords) { + final DBIDs ids = clu.getIDs(); + + GrahamScanConvexHull2D hull = new GrahamScanConvexHull2D(); + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + hull.add(coords.get(iter).getColumnVector()); + } + double weight = ids.size(); + if(hier != null && hulls != null) { + final int numc = hier.numChildren(clu); + if(numc > 0) { + for(Iter<Cluster<Model>> iter = hier.iterChildren(clu); iter.valid(); iter.advance()) { + final Cluster<Model> iclu = iter.get(); + DoubleObjPair<Polygon> poly = hulls.get(iclu); + if(poly == null) { + poly = buildHullsRecursively(iclu, hier, hulls, coords); + } + // Add inner convex hull to outer convex hull. + for(ArrayListIter<Vector> vi = poly.second.iter(); vi.valid(); vi.advance()) { + hull.add(vi.get()); + } + weight += poly.first / numc; + } + } + } + DoubleObjPair<Polygon> pair = new DoubleObjPair<>(weight, hull.getHull()); + hulls.put(clu, pair); + return pair; + } + /** * Make an HTML description. * @@ -317,15 +553,15 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { */ private StringBuilder makeDescription(Collection<Relation<?>> relations, DBIDRef id) { StringBuilder buf = new StringBuilder(); - for (Relation<?> rel : relations) { + for(Relation<?> rel : relations) { Object o = rel.get(id); - if (o == null) { + if(o == null) { continue; } String s = o.toString(); // FIXME: strip html characters - if (s != null) { - if (buf.length() > 0) { + if(s != null) { + if(buf.length() > 0) { buf.append("<br />"); } buf.append(s); @@ -335,13 +571,29 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { } /** + * Make an HTML description. + * + * @param c Cluster + * @return Buffer + */ + private StringBuilder makeDescription(Cluster<?> c) { + StringBuilder buf = new StringBuilder(); + buf.append("<div>"); + buf.append(c.getNameAutomatic()); + buf.append("<br />"); + buf.append("Size: " + c.size()); + buf.append("</div>"); + return buf; + } + + /** * Print a newline when debugging. * * @param out Output XML stream * @throws XMLStreamException */ private void writeNewlineOnDebug(XMLStreamWriter out) throws XMLStreamException { - if (LOG.isDebugging()) { + if(LOG.isDebugging()) { out.writeCharacters("\n"); } } @@ -358,12 +610,12 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { // Colors at these positions Color[] cols = new Color[] { new Color(0.0f, 0.0f, 0.0f, 0.6f), new Color(0.0f, 0.0f, 1.0f, 0.8f), new Color(1.0f, 0.0f, 0.0f, 0.9f), new Color(1.0f, 1.0f, 0.0f, 1.0f) }; assert (pos.length == cols.length); - if (val < pos[0]) { + if(val < pos[0]) { val = pos[0]; } // Linear interpolation: - for (int i = 1; i < pos.length; i++) { - if (val <= pos[i]) { + for(int i = 1; i < pos.length; i++) { + if(val <= pos[i]) { Color prev = cols[i - 1]; Color next = cols[i]; final double mix = (val - pos[i - 1]) / (pos[i] - pos[i - 1]); @@ -438,22 +690,22 @@ public class KMLOutputHandler implements ResultHandler, Parameterizable { super.makeOptions(config); FileParameter outputP = new FileParameter(OutputStep.Parameterizer.OUTPUT_ID, FileParameter.FileType.OUTPUT_FILE); outputP.setShortDescription("Filename the KMZ file (compressed KML) is written to."); - if (config.grab(outputP)) { + if(config.grab(outputP)) { filename = outputP.getValue(); } ObjectParameter<OutlierScalingFunction> scalingP = new ObjectParameter<>(SCALING_ID, OutlierScalingFunction.class, OutlierLinearScaling.class); - if (config.grab(scalingP)) { + if(config.grab(scalingP)) { scaling = scalingP.instantiateClass(config); } Flag compatF = new Flag(COMPAT_ID); - if (config.grab(compatF)) { + if(config.grab(compatF)) { compat = compatF.getValue(); } Flag autoopenF = new Flag(AUTOOPEN_ID); - if (config.grab(autoopenF)) { + if(config.grab(autoopenF)) { autoopen = autoopenF.getValue(); } } diff --git a/src/de/lmu/ifi/dbs/elki/result/KNNDistanceOrderResult.java b/src/de/lmu/ifi/dbs/elki/result/KNNDistanceOrderResult.java deleted file mode 100644 index bbe21b0a..00000000 --- a/src/de/lmu/ifi/dbs/elki/result/KNNDistanceOrderResult.java +++ /dev/null @@ -1,63 +0,0 @@ -package de.lmu.ifi.dbs.elki.result; - -/* - 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 java.util.List; - -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; - -/** - * Wraps a list containing the knn distances. - * - * @author Arthur Zimek - * @param <D> the type of Distance used by this Result - * - */ -public class KNNDistanceOrderResult<D extends Distance<D>> extends BasicResult implements IterableResult<D> { - /** - * Store the kNN Distances - */ - private final List<D> knnDistances; - - /** - * Construct result - * - * @param name The long name (for pretty printing) - * @param shortname the short name (for filenames etc.) - * @param knnDistances distance list to wrap. - */ - public KNNDistanceOrderResult(String name, String shortname, final List<D> knnDistances) { - super(name, shortname); - this.knnDistances = knnDistances; - } - - /** - * Return an iterator. - */ - @Override - public Iterator<D> iterator() { - return knnDistances.iterator(); - } -} diff --git a/src/de/lmu/ifi/dbs/elki/result/LogResultStructureResultHandler.java b/src/de/lmu/ifi/dbs/elki/result/LogResultStructureResultHandler.java index 4224ae0a..92ccab42 100644 --- a/src/de/lmu/ifi/dbs/elki/result/LogResultStructureResultHandler.java +++ b/src/de/lmu/ifi/dbs/elki/result/LogResultStructureResultHandler.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/OrderingFromDataStore.java b/src/de/lmu/ifi/dbs/elki/result/OrderingFromDataStore.java index 74eb5323..076ecdd6 100644 --- a/src/de/lmu/ifi/dbs/elki/result/OrderingFromDataStore.java +++ b/src/de/lmu/ifi/dbs/elki/result/OrderingFromDataStore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/OrderingResult.java b/src/de/lmu/ifi/dbs/elki/result/OrderingResult.java index b3261e61..8e8f0c61 100644 --- a/src/de/lmu/ifi/dbs/elki/result/OrderingResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/OrderingResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/PixmapResult.java b/src/de/lmu/ifi/dbs/elki/result/PixmapResult.java index f6b4512b..5bbdd72f 100644 --- a/src/de/lmu/ifi/dbs/elki/result/PixmapResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/PixmapResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/RangeSelection.java b/src/de/lmu/ifi/dbs/elki/result/RangeSelection.java index b4cc092f..051788a7 100644 --- a/src/de/lmu/ifi/dbs/elki/result/RangeSelection.java +++ b/src/de/lmu/ifi/dbs/elki/result/RangeSelection.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/ReferencePointsResult.java b/src/de/lmu/ifi/dbs/elki/result/ReferencePointsResult.java index 92f59101..aade3c02 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ReferencePointsResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/ReferencePointsResult.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/Result.java b/src/de/lmu/ifi/dbs/elki/result/Result.java index 99f68402..2d7cec6a 100644 --- a/src/de/lmu/ifi/dbs/elki/result/Result.java +++ b/src/de/lmu/ifi/dbs/elki/result/Result.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/ResultAdapter.java b/src/de/lmu/ifi/dbs/elki/result/ResultAdapter.java index fa02b57b..238338a4 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ResultAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/result/ResultAdapter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/ResultHandler.java b/src/de/lmu/ifi/dbs/elki/result/ResultHandler.java index 56e25d27..2d96f4b6 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ResultHandler.java +++ b/src/de/lmu/ifi/dbs/elki/result/ResultHandler.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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.result; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; - /** * Interface for any class that can handle results * @@ -33,6 +31,6 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; * @apiviz.landmark * @apiviz.uses Result oneway - - processes */ -public interface ResultHandler extends Parameterizable, ResultProcessor { +public interface ResultHandler extends ResultProcessor { // Empty - moved to ResultProcessor, this interface merely serves UI purposes. }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java b/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java index 52b63d3b..6b844a39 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java +++ b/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/ResultListener.java b/src/de/lmu/ifi/dbs/elki/result/ResultListener.java index 899aa008..dc007141 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ResultListener.java +++ b/src/de/lmu/ifi/dbs/elki/result/ResultListener.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/ResultProcessor.java b/src/de/lmu/ifi/dbs/elki/result/ResultProcessor.java index 88eb3607..df73b4c1 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ResultProcessor.java +++ b/src/de/lmu/ifi/dbs/elki/result/ResultProcessor.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/ResultUtil.java b/src/de/lmu/ifi/dbs/elki/result/ResultUtil.java index e0e59482..9721245f 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ResultUtil.java +++ b/src/de/lmu/ifi/dbs/elki/result/ResultUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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 @@ -252,7 +252,7 @@ public class ResultUtil { * @param rel Relation * @return associated scales result */ - public static ScalesResult getScalesResult(final Relation<? extends NumberVector<?>> rel) { + public static ScalesResult getScalesResult(final Relation<? extends NumberVector> rel) { Collection<ScalesResult> scas = ResultUtil.filterResults(rel, ScalesResult.class); if (scas.size() == 0) { final ScalesResult newsca = new ScalesResult(rel); diff --git a/src/de/lmu/ifi/dbs/elki/result/ResultWriter.java b/src/de/lmu/ifi/dbs/elki/result/ResultWriter.java index f3b39580..4ffc39c6 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ResultWriter.java +++ b/src/de/lmu/ifi/dbs/elki/result/ResultWriter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/SamplingResult.java b/src/de/lmu/ifi/dbs/elki/result/SamplingResult.java index 17471b9a..1d8b71da 100644 --- a/src/de/lmu/ifi/dbs/elki/result/SamplingResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/SamplingResult.java @@ -7,7 +7,7 @@ import de.lmu.ifi.dbs.elki.database.relation.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/result/ScalesResult.java b/src/de/lmu/ifi/dbs/elki/result/ScalesResult.java index 8f9653d8..b8c45bfc 100644 --- a/src/de/lmu/ifi/dbs/elki/result/ScalesResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/ScalesResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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 @@ -46,7 +46,7 @@ public class ScalesResult extends BasicResult { * * @param relation Relation to use */ - public ScalesResult(Relation<? extends NumberVector<?>> relation) { + public ScalesResult(Relation<? extends NumberVector> relation) { this(Scales.calcScales(relation)); } diff --git a/src/de/lmu/ifi/dbs/elki/result/SelectionResult.java b/src/de/lmu/ifi/dbs/elki/result/SelectionResult.java index fda68c68..7b9364e6 100644 --- a/src/de/lmu/ifi/dbs/elki/result/SelectionResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/SelectionResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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/result/SettingsResult.java b/src/de/lmu/ifi/dbs/elki/result/SettingsResult.java index ea6664e8..f389236b 100644 --- a/src/de/lmu/ifi/dbs/elki/result/SettingsResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/SettingsResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result; 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,8 +25,7 @@ package de.lmu.ifi.dbs.elki.result; import java.util.Collection; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter; -import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackedParameter; /** * Result that keeps track of settings that were used in generating this @@ -38,14 +37,14 @@ public class SettingsResult extends BasicResult { /** * Settings storage. */ - Collection<Pair<Object, Parameter<?>>> settings; + Collection<TrackedParameter> settings; /** * Constructor. * * @param settings Settings to store */ - public SettingsResult(Collection<Pair<Object, Parameter<?>>> settings) { + public SettingsResult(Collection<TrackedParameter> settings) { super("Settings", "settings"); this.settings = settings; } @@ -55,7 +54,7 @@ public class SettingsResult extends BasicResult { * * @return the settings */ - public Collection<Pair<Object, Parameter<?>>> getSettings() { + public Collection<TrackedParameter> getSettings() { return settings; } } diff --git a/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderEntry.java b/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderEntry.java deleted file mode 100644 index fab3a8c3..00000000 --- a/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderEntry.java +++ /dev/null @@ -1,63 +0,0 @@ -package de.lmu.ifi.dbs.elki.result.optics; - -/* - 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.DBID; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; - -/** - * Generic Cluster Order Entry Interface. - * - * @author Erich Schubert - * - * @apiviz.landmark - * - * @apiviz.composedOf DBID - * @apiviz.composedOf Distance - * - * @param <D> Distance type - */ -public interface ClusterOrderEntry<D extends Distance<D>> { - /** - * Returns the object id of this entry. - * - * @return the object id of this entry - */ - public DBID getID(); - - /** - * Returns the id of the predecessor of this entry if this entry has a - * predecessor, null otherwise. - * - * @return the id of the predecessor of this entry - */ - public DBID getPredecessorID(); - - /** - * Returns the reachability distance of this entry - * - * @return the reachability distance of this entry - */ - public D getReachability(); -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java b/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java deleted file mode 100644 index bd500dfa..00000000 --- a/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java +++ /dev/null @@ -1,384 +0,0 @@ -package de.lmu.ifi.dbs.elki.result.optics; - -/* - 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.Iterator; -import java.util.List; - -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.DataStore; -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.WritableDataStore; -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.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.ModifiableDBIDs; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -import de.lmu.ifi.dbs.elki.result.BasicResult; -import de.lmu.ifi.dbs.elki.result.IterableResult; -import de.lmu.ifi.dbs.elki.result.OrderingResult; -import de.lmu.ifi.dbs.elki.result.ResultAdapter; -import de.lmu.ifi.dbs.elki.result.ResultHierarchy; - -/** - * Class to store the result of an ordering clustering algorithm such as OPTICS. - * - * @author Erich Schubert - * - * @apiviz.landmark - * - * @apiviz.has ClusterOrderEntry oneway - - contains - * @apiviz.composedOf ClusterOrderResult.ClusterOrderAdapter - * @apiviz.composedOf ClusterOrderResult.ReachabilityDistanceAdapter - * @apiviz.composedOf ClusterOrderResult.PredecessorAdapter - * - * @param <D> distance type. - */ -public class ClusterOrderResult<D extends Distance<D>> extends BasicResult implements IterableResult<ClusterOrderEntry<D>> { - /** - * Cluster order storage - */ - private ArrayList<ClusterOrderEntry<D>> clusterOrder; - - /** - * Map of object IDs to their cluster order entry - */ - private WritableDataStore<ClusterOrderEntry<D>> map; - - /** - * The DBIDs we are defined for - */ - ModifiableDBIDs dbids; - - /** - * Constructor - * - * @param name The long name (for pretty printing) - * @param shortname the short name (for filenames etc.) - */ - public ClusterOrderResult(String name, String shortname) { - super(name, shortname); - clusterOrder = new ArrayList<>(); - dbids = DBIDUtil.newHashSet(); - map = DataStoreUtil.makeStorage(dbids, DataStoreFactory.HINT_DB, ClusterOrderEntry.class); - - addChildResult(new ClusterOrderAdapter(clusterOrder)); - addChildResult(new ReachabilityDistanceAdapter(map, dbids)); - addChildResult(new PredecessorAdapter(map, dbids)); - } - - /** - * Retrieve the complete cluster order. - * - * @return cluster order - */ - public List<ClusterOrderEntry<D>> getClusterOrder() { - return clusterOrder; - } - - /** - * The cluster order is iterable - */ - @Override - public Iterator<ClusterOrderEntry<D>> iterator() { - return clusterOrder.iterator(); - } - - /** - * Add an object to the cluster order. - * - * @param id Object ID - * @param predecessor Predecessor ID - * @param reachability Reachability distance - */ - public void add(DBID id, DBID predecessor, D reachability) { - add(new GenericClusterOrderEntry<>(id, predecessor, reachability)); - dbids.add(id); - } - - /** - * Add an object to the cluster order. - * - * @param ce Entry - */ - public void add(ClusterOrderEntry<D> ce) { - clusterOrder.add(ce); - map.put(ce.getID(), ce); - dbids.add(ce.getID()); - } - - /** - * Get the distance class - * - * @return distance class. Can be {@code null} for an all-undefined result! - */ - public Class<?> getDistanceClass() { - for(ClusterOrderEntry<D> ce : clusterOrder) { - D dist = ce.getReachability(); - if(dist != null) { - return dist.getClass(); - } - } - return null; - } - - /** - * Ordering part of the result. - * - * @author Erich Schubert - */ - class ClusterOrderAdapter implements OrderingResult, ResultAdapter { - /** - * Access reference. - */ - private ArrayList<ClusterOrderEntry<D>> clusterOrder; - - /** - * Constructor. - * - * @param clusterOrder order to return - */ - public ClusterOrderAdapter(final ArrayList<ClusterOrderEntry<D>> clusterOrder) { - super(); - this.clusterOrder = clusterOrder; - } - - @Override - public DBIDs getDBIDs() { - return dbids; - } - - /** - * Use the cluster order to sort the given collection ids. - * - * Implementation of the {@link OrderingResult} interface. - */ - @Override - public ArrayModifiableDBIDs iter(DBIDs ids) { - ArrayModifiableDBIDs res = DBIDUtil.newArray(ids.size()); - for(ClusterOrderEntry<D> e : clusterOrder) { - if(ids.contains(e.getID())) { - res.add(e.getID()); - } - } - return res; - } - - @Override - public String getLongName() { - return "Derived Object Order"; - } - - @Override - public String getShortName() { - return "clusterobjectorder"; - } - } - - /** - * Result containing the reachability distances. - * - * @author Erich Schubert - */ - class ReachabilityDistanceAdapter implements Relation<D>, ResultAdapter { - /** - * Access reference. - */ - private DataStore<ClusterOrderEntry<D>> map; - - /** - * DBIDs - */ - private DBIDs dbids; - - /** - * Constructor. - * - * @param map Map that stores the results. - * @param dbids DBIDs we are defined for. - */ - public ReachabilityDistanceAdapter(DataStore<ClusterOrderEntry<D>> map, DBIDs dbids) { - super(); - this.map = map; - this.dbids = dbids; - } - - @Override - public D get(DBIDRef objID) { - return map.get(objID).getReachability(); - } - - @Override - public String getLongName() { - return "Reachability"; - } - - @Override - public String getShortName() { - return "reachability"; - } - - @Override - public DBIDs getDBIDs() { - return DBIDUtil.makeUnmodifiable(dbids); - } - - @Override - public DBIDIter iterDBIDs() { - return dbids.iter(); - } - - @Override - public int size() { - return dbids.size(); - } - - @Override - public Database getDatabase() { - return null; // FIXME - } - - @Override - public void set(DBIDRef id, D val) { - throw new UnsupportedOperationException(); - } - - @Override - public void delete(DBIDRef id) { - throw new UnsupportedOperationException(); - } - - @Override - public SimpleTypeInformation<D> getDataTypeInformation() { - return new SimpleTypeInformation<>(Distance.class); - } - - @Override - public ResultHierarchy getHierarchy() { - return ClusterOrderResult.this.getHierarchy(); - } - - @Override - public void setHierarchy(ResultHierarchy hierarchy) { - ClusterOrderResult.this.setHierarchy(hierarchy); - } - } - - /** - * Result containing the predecessor ID. - * - * @author Erich Schubert - */ - class PredecessorAdapter implements Relation<DBID>, ResultAdapter { - /** - * Access reference. - */ - private DataStore<ClusterOrderEntry<D>> map; - - /** - * Database IDs - */ - private DBIDs dbids; - - /** - * Constructor. - * - * @param map Map that stores the results. - * @param dbids DBIDs we are defined for - */ - public PredecessorAdapter(DataStore<ClusterOrderEntry<D>> map, DBIDs dbids) { - super(); - this.map = map; - this.dbids = dbids; - } - - @Override - public DBID get(DBIDRef objID) { - return map.get(objID).getPredecessorID(); - } - - @Override - public String getLongName() { - return "Predecessor"; - } - - @Override - public String getShortName() { - return "predecessor"; - } - - @Override - public DBIDs getDBIDs() { - return DBIDUtil.makeUnmodifiable(dbids); - } - - @Override - public DBIDIter iterDBIDs() { - return dbids.iter(); - } - - @Override - public int size() { - return dbids.size(); - } - - @Override - public Database getDatabase() { - return null; // FIXME - } - - @Override - public void set(DBIDRef id, DBID val) { - throw new UnsupportedOperationException(); - } - - @Override - public void delete(DBIDRef id) { - throw new UnsupportedOperationException(); - } - - @Override - public SimpleTypeInformation<DBID> getDataTypeInformation() { - return TypeUtil.DBID; - } - - @Override - public ResultHierarchy getHierarchy() { - return ClusterOrderResult.this.getHierarchy(); - } - - @Override - public void setHierarchy(ResultHierarchy hierarchy) { - ClusterOrderResult.this.setHierarchy(hierarchy); - } - } -} diff --git a/src/de/lmu/ifi/dbs/elki/result/optics/DoubleDistanceClusterOrderEntry.java b/src/de/lmu/ifi/dbs/elki/result/optics/DoubleDistanceClusterOrderEntry.java deleted file mode 100644 index 74f65e73..00000000 --- a/src/de/lmu/ifi/dbs/elki/result/optics/DoubleDistanceClusterOrderEntry.java +++ /dev/null @@ -1,154 +0,0 @@ -package de.lmu.ifi.dbs.elki.result.optics; - -/* - 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.DBID; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; - -/** - * Provides an entry in a cluster order. - * - * @author Elke Achtert - */ -public class DoubleDistanceClusterOrderEntry implements Comparable<ClusterOrderEntry<DoubleDistance>>, ClusterOrderEntry<DoubleDistance> { - /** - * The id of the entry. - */ - private DBID objectID; - - /** - * The id of the entry's predecessor. - */ - private DBID predecessorID; - - /** - * The reachability of the entry. - */ - private double reachability; - - /** - * Creates a new entry in a cluster order with the specified parameters. - * - * @param objectID the id of the entry - * @param predecessorID the id of the entry's predecessor - * @param reachability the reachability of the entry - */ - public DoubleDistanceClusterOrderEntry(DBID objectID, DBID predecessorID, double reachability) { - this.objectID = objectID; - this.predecessorID = predecessorID; - this.reachability = reachability; - } - - /** - * Indicates whether some other object is "equal to" this one. - * - * NOTE: for the use in an UpdatableHeap, only the ID is compared! - * - * @param o the reference object with which to compare. - * @return <code>true</code> if this object has the same attribute values as - * the o argument; <code>false</code> otherwise. - */ - @Override - public boolean equals(Object o) { - if(this == o) { - return true; - } - if(!(o instanceof ClusterOrderEntry)) { - return false; - } - - final ClusterOrderEntry<?> that = (ClusterOrderEntry<?>) o; - // Compare by ID only, for UpdatableHeap! - return DBIDUtil.equal(objectID, that.getID()); - } - - /** - * Returns a hash code value for the object. - * - * @return the object id if this entry - */ - @Override - public int hashCode() { - return objectID.hashCode(); - } - - /** - * Returns a string representation of the object. - * - * @return a string representation of the object. - */ - @Override - public String toString() { - return objectID + "(" + predecessorID + "," + reachability + ")"; - } - - /** - * Returns the object id of this entry. - * - * @return the object id of this entry - */ - @Override - public DBID getID() { - return objectID; - } - - /** - * Returns the id of the predecessor of this entry if this entry has a - * predecessor, null otherwise. - * - * @return the id of the predecessor of this entry - */ - @Override - public DBID getPredecessorID() { - return predecessorID; - } - - /** - * Returns the reachability distance of this entry - * - * @return the reachability distance of this entry - */ - @Override - public DoubleDistance getReachability() { - return new DoubleDistance(reachability); - } - - @Override - public int compareTo(ClusterOrderEntry<DoubleDistance> o) { - if(o instanceof DoubleDistanceClusterOrderEntry) { - int delta = Double.compare(this.reachability, ((DoubleDistanceClusterOrderEntry) o).reachability); - if(delta != 0) { - return delta; - } - } - else { - int delta = this.getReachability().compareTo(o.getReachability()); - if(delta != 0) { - return delta; - } - } - return -getID().compareTo(o.getID()); - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/result/optics/GenericClusterOrderEntry.java b/src/de/lmu/ifi/dbs/elki/result/optics/GenericClusterOrderEntry.java deleted file mode 100644 index 7af8a3ec..00000000 --- a/src/de/lmu/ifi/dbs/elki/result/optics/GenericClusterOrderEntry.java +++ /dev/null @@ -1,147 +0,0 @@ -package de.lmu.ifi.dbs.elki.result.optics; - -/* - 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.DBID; -import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; - -/** - * Provides an entry in a cluster order. - * - * @author Elke Achtert - * @param <D> the type of Distance used by the ClusterOrderEntry - */ -public class GenericClusterOrderEntry<D extends Distance<D>> implements Comparable<ClusterOrderEntry<D>>, ClusterOrderEntry<D> { - /** - * The id of the entry. - */ - private DBID objectID; - - /** - * The id of the entry's predecessor. - */ - private DBID predecessorID; - - /** - * The reachability of the entry. - */ - private D reachability; - - /** - * Creates a new entry in a cluster order with the specified parameters. - * - * @param objectID the id of the entry - * @param predecessorID the id of the entry's predecessor - * @param reachability the reachability of the entry - */ - public GenericClusterOrderEntry(DBID objectID, DBID predecessorID, D reachability) { - this.objectID = objectID; - this.predecessorID = predecessorID; - this.reachability = reachability; - } - - /** - * Indicates whether some other object is "equal to" this one. - * - * NOTE: for the use in an UpdatableHeap, only the ID is compared! - * - * @param o the reference object with which to compare. - * @return <code>true</code> if this object has the same attribute values as - * the o argument; <code>false</code> otherwise. - */ - @Override - public boolean equals(Object o) { - if(this == o) { - return true; - } - if(!(o instanceof ClusterOrderEntry)) { - return false; - } - - final ClusterOrderEntry<?> that = (ClusterOrderEntry<?>) o; - // Compare by ID only, for UpdatableHeap! - return DBIDUtil.equal(objectID, that.getID()); - } - - /** - * Returns a hash code value for the object. - * - * @return the object id if this entry - */ - @Override - public int hashCode() { - return objectID.hashCode(); - } - - /** - * Returns a string representation of the object. - * - * @return a string representation of the object. - */ - @Override - public String toString() { - return objectID + "(" + predecessorID + "," + reachability + ")"; - } - - /** - * Returns the object id of this entry. - * - * @return the object id of this entry - */ - @Override - public DBID getID() { - return objectID; - } - - /** - * Returns the id of the predecessor of this entry if this entry has a - * predecessor, null otherwise. - * - * @return the id of the predecessor of this entry - */ - @Override - public DBID getPredecessorID() { - return predecessorID; - } - - /** - * Returns the reachability distance of this entry - * - * @return the reachability distance of this entry - */ - @Override - public D getReachability() { - return reachability; - } - - @Override - public int compareTo(ClusterOrderEntry<D> o) { - int delta = this.getReachability().compareTo(o.getReachability()); - if(delta != 0) { - return delta; - } - return -getID().compareTo(o.getID()); - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/result/optics/package-info.java b/src/de/lmu/ifi/dbs/elki/result/optics/package-info.java deleted file mode 100644 index e74b3c7b..00000000 --- a/src/de/lmu/ifi/dbs/elki/result/optics/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * <p>Result classes for OPTICS.</p> - */ -/* -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.result.optics;
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/BasicOutlierScoreMeta.java b/src/de/lmu/ifi/dbs/elki/result/outlier/BasicOutlierScoreMeta.java index 4dc64b2c..0a87fd98 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/BasicOutlierScoreMeta.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/BasicOutlierScoreMeta.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; 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/result/outlier/InvertedOutlierScoreMeta.java b/src/de/lmu/ifi/dbs/elki/result/outlier/InvertedOutlierScoreMeta.java index d4ea456a..a3b40682 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/InvertedOutlierScoreMeta.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/InvertedOutlierScoreMeta.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; 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/result/outlier/OrderingFromRelation.java b/src/de/lmu/ifi/dbs/elki/result/outlier/OrderingFromRelation.java index 2950a2f8..013be8f9 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/OrderingFromRelation.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/OrderingFromRelation.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; 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,13 +23,11 @@ package de.lmu.ifi.dbs.elki.result.outlier; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.Comparator; - import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs; -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.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; +import de.lmu.ifi.dbs.elki.database.relation.RelationUtil; import de.lmu.ifi.dbs.elki.result.OrderingResult; /** @@ -37,38 +35,38 @@ import de.lmu.ifi.dbs.elki.result.OrderingResult; * * @author Erich Schubert * - * @apiviz.uses Relation + * @apiviz.uses DoubleRelation */ public class OrderingFromRelation implements OrderingResult { /** * Outlier scores. */ - protected Relation<Double> scores; + protected DoubleRelation scores; /** * Factor for ascending (+1) and descending (-1) ordering. */ - protected int ascending = +1; - + protected boolean ascending = false; + /** * Constructor for outlier orderings * * @param scores outlier score result * @param ascending Ascending when {@code true}, descending otherwise */ - public OrderingFromRelation(Relation<Double> scores, boolean ascending) { + public OrderingFromRelation(DoubleRelation scores, boolean ascending) { super(); this.scores = scores; - this.ascending = ascending ? +1 : -1; + this.ascending = ascending; } - + /** * Ascending constructor. * * @param scores */ - public OrderingFromRelation(Relation<Double> scores) { - this(scores, true); + public OrderingFromRelation(DoubleRelation scores) { + this(scores, false); } @Override @@ -79,35 +77,19 @@ public class OrderingFromRelation implements OrderingResult { @Override public ArrayModifiableDBIDs iter(DBIDs ids) { ArrayModifiableDBIDs sorted = DBIDUtil.newArray(ids); - sorted.sort(new ImpliedComparator()); + sorted.sort(ascending ? // + new RelationUtil.AscendingByDoubleRelation(scores) // + : new RelationUtil.DescendingByDoubleRelation(scores)); return sorted; } @Override public String getLongName() { - return scores.getLongName()+" Order"; + return scores.getLongName() + " Order"; } @Override public String getShortName() { - return scores.getShortName()+"_order"; - } - - /** - * Internal comparator, accessing the map to sort objects - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - protected final class ImpliedComparator implements Comparator<DBIDRef> { - @Override - public int compare(DBIDRef id1, DBIDRef id2) { - Double k1 = scores.get(id1); - Double k2 = scores.get(id2); - assert (k1 != null); - assert (k2 != null); - return ascending * k2.compareTo(k1); - } + return scores.getShortName() + "_order"; } } diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java b/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java index 13d5c1a0..3289723f 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; 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,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.result.BasicResult; import de.lmu.ifi.dbs.elki.result.OrderingResult; @@ -35,7 +35,7 @@ import de.lmu.ifi.dbs.elki.result.OrderingResult; * * @apiviz.landmark * @apiviz.composedOf OutlierScoreMeta - * @apiviz.composedOf Relation oneway - - contains + * @apiviz.composedOf DoubleRelation oneway - - contains * @apiviz.composedOf OrderingFromRelation */ public class OutlierResult extends BasicResult { @@ -47,7 +47,7 @@ public class OutlierResult extends BasicResult { /** * Outlier scores. */ - private Relation<Double> scores; + private DoubleRelation scores; /** * Outlier ordering. @@ -60,11 +60,11 @@ public class OutlierResult extends BasicResult { * @param meta Outlier score metadata. * @param scores Scores result. */ - public OutlierResult(OutlierScoreMeta meta, Relation<Double> scores) { + public OutlierResult(OutlierScoreMeta meta, DoubleRelation scores) { super(scores.getLongName(), scores.getShortName()); this.meta = meta; this.scores = scores; - this.ordering = new OrderingFromRelation(scores, !(meta instanceof InvertedOutlierScoreMeta)); + this.ordering = new OrderingFromRelation(scores, meta instanceof InvertedOutlierScoreMeta); this.addChildResult(scores); this.addChildResult(ordering); this.addChildResult(meta); @@ -84,7 +84,7 @@ public class OutlierResult extends BasicResult { * * @return the scores */ - public Relation<Double> getScores() { + public DoubleRelation getScores() { return scores; } diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierScoreMeta.java b/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierScoreMeta.java index a17bade5..e619b3e3 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierScoreMeta.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierScoreMeta.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; 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/result/outlier/ProbabilisticOutlierScore.java b/src/de/lmu/ifi/dbs/elki/result/outlier/ProbabilisticOutlierScore.java index 36cd081e..c4f48838 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/ProbabilisticOutlierScore.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/ProbabilisticOutlierScore.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; 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/result/outlier/QuotientOutlierScoreMeta.java b/src/de/lmu/ifi/dbs/elki/result/outlier/QuotientOutlierScoreMeta.java index 3ac643e6..eb4ee1e1 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/QuotientOutlierScoreMeta.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/QuotientOutlierScoreMeta.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.outlier; 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/result/outlier/package-info.java b/src/de/lmu/ifi/dbs/elki/result/outlier/package-info.java index 7007c8b4..ff28fa05 100644 --- a/src/de/lmu/ifi/dbs/elki/result/outlier/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/result/outlier/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/result/package-info.java b/src/de/lmu/ifi/dbs/elki/result/package-info.java index 0f3e3aa8..a7a28f68 100644 --- a/src/de/lmu/ifi/dbs/elki/result/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/result/package-info.java @@ -12,7 +12,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/result/textwriter/MultipleFilesOutput.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/MultipleFilesOutput.java index 22bde5be..f811f051 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/MultipleFilesOutput.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/MultipleFilesOutput.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter; 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/result/textwriter/SingleStreamOutput.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/SingleStreamOutput.java index eb2b6170..23d75a29 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/SingleStreamOutput.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/SingleStreamOutput.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter; 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/result/textwriter/StreamFactory.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/StreamFactory.java index 431fdc2c..33b6de74 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/StreamFactory.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/StreamFactory.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter; 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/result/textwriter/TextWriteable.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriteable.java index 5b56cee6..019bab49 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriteable.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriteable.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter; 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/result/textwriter/TextWriter.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java index 0cbc81f2..836292ac 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter; 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,7 +41,6 @@ import de.lmu.ifi.dbs.elki.data.FeatureVector; import de.lmu.ifi.dbs.elki.data.HierarchicalClassLabel; import de.lmu.ifi.dbs.elki.data.LabelList; import de.lmu.ifi.dbs.elki.data.SimpleClassLabel; -import de.lmu.ifi.dbs.elki.data.model.ClusterModel; import de.lmu.ifi.dbs.elki.data.model.Model; import de.lmu.ifi.dbs.elki.data.type.TypeUtil; import de.lmu.ifi.dbs.elki.database.Database; @@ -51,7 +50,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; 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.distancevalue.Distance; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.result.CollectionResult; import de.lmu.ifi.dbs.elki.result.IterableResult; @@ -66,17 +64,15 @@ import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterObjectArray; import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterObjectInline; import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterPair; import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterTextWriteable; -import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterTriple; import de.lmu.ifi.dbs.elki.result.textwriter.writers.TextWriterVector; import de.lmu.ifi.dbs.elki.utilities.HandlerList; import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy; import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackedParameter; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.SerializedParameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter; import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleDoublePair; import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; -import de.lmu.ifi.dbs.elki.utilities.pairs.Triple; /** * Class to write a result to human-readable text output. @@ -108,7 +104,6 @@ public class TextWriter { TextWriterObjectInline trivialwriter = new TextWriterObjectInline(); writers.insertHandler(Pair.class, new TextWriterPair()); writers.insertHandler(DoubleDoublePair.class, new TextWriterDoubleDoublePair()); - writers.insertHandler(Triple.class, new TextWriterTriple()); writers.insertHandler(FeatureVector.class, trivialwriter); // these object can be serialized inline with toString() writers.insertHandler(String.class, trivialwriter); @@ -119,7 +114,6 @@ public class TextWriter { writers.insertHandler(Integer[].class, new TextWriterObjectArray<Integer>()); writers.insertHandler(BitSet.class, trivialwriter); writers.insertHandler(Vector.class, new TextWriterVector()); - writers.insertHandler(Distance.class, trivialwriter); writers.insertHandler(SimpleClassLabel.class, trivialwriter); writers.insertHandler(HierarchicalClassLabel.class, trivialwriter); writers.insertHandler(LabelList.class, trivialwriter); @@ -141,19 +135,20 @@ public class TextWriter { * @return unique filename */ protected String getFilename(Object result, String filenamepre) { - if (filenamepre == null || filenamepre.length() == 0) { + if(filenamepre == null || filenamepre.length() == 0) { filenamepre = "result"; } int i = 0; - while (true) { + while(true) { String filename; - if (i > 0) { + if(i > 0) { filename = filenamepre + "-" + i; - } else { + } + else { filename = filenamepre; } Object existing = filenames.get(filename); - if (existing == null || existing == result) { + if(existing == null || existing == result) { filenames.put(filename, result); return filename; } @@ -183,33 +178,33 @@ public class TextWriter { // Split result objects in different known types: { List<Result> results = ResultUtil.filterResults(r, Result.class); - for (Result res : results) { - if (filter != null) { + for(Result res : results) { + if(filter != null) { final String nam = res.getShortName(); - if (nam == null || !filter.matcher(nam).find()) { + if(nam == null || !filter.matcher(nam).find()) { continue; } } - if (res instanceof Database) { + if(res instanceof Database) { continue; } - if (res instanceof Relation) { + if(res instanceof Relation) { ra.add((Relation<?>) res); continue; } - if (res instanceof OrderingResult) { + if(res instanceof OrderingResult) { ro.add((OrderingResult) res); continue; } - if (res instanceof Clustering) { + if(res instanceof Clustering) { rc.add((Clustering<?>) res); continue; } - if (res instanceof IterableResult) { + if(res instanceof IterableResult) { ri.add((IterableResult<?>) res); continue; } - if (res instanceof SettingsResult) { + if(res instanceof SettingsResult) { rs.add((SettingsResult) res); continue; } @@ -219,19 +214,19 @@ public class TextWriter { writeSettingsResult(streamOpener, rs); - for (IterableResult<?> rii : ri) { + for(IterableResult<?> rii : ri) { writeIterableResult(streamOpener, rii); } - for (Clustering<?> c : rc) { + for(Clustering<?> c : rc) { NamingScheme naming = new SimpleEnumeratingScheme(c); - for (Cluster<?> clus : c.getAllClusters()) { + for(Cluster<?> clus : c.getAllClusters()) { writeClusterResult(db, streamOpener, (Clustering<Model>) c, (Cluster<Model>) clus, ra, naming); } } - for (OrderingResult ror : ro) { + for(OrderingResult ror : ro) { writeOrderingResult(db, streamOpener, ror, ra); } - for (Result otherr : otherres) { + for(Result otherr : otherres) { writeOtherResult(streamOpener, otherr); } } @@ -239,16 +234,16 @@ public class TextWriter { private void printObject(TextWriterStream out, Database db, final DBIDRef objID, List<Relation<?>> ra) throws UnableToComplyException, IOException { SingleObjectBundle bundle = db.getBundle(objID); // Write database element itself. - for (int i = 0; i < bundle.metaLength(); i++) { + for(int i = 0; i < bundle.metaLength(); i++) { Object obj = bundle.data(i); - if (obj != null) { + if(obj != null) { TextWriterWriterInterface<?> owriter = out.getWriterFor(obj); - if (owriter == null) { + if(owriter == null) { throw new UnableToComplyException("No handler for database object itself: " + obj.getClass().getSimpleName()); } String lbl = null; // TODO: ugly compatibility hack... - if (TypeUtil.DBID.isAssignableFromType(bundle.meta(i))) { + if(TypeUtil.DBID.isAssignableFromType(bundle.meta(i))) { lbl = "ID"; } owriter.writeObject(out, lbl, obj); @@ -257,19 +252,19 @@ public class TextWriter { Collection<Relation<?>> dbrels = db.getRelations(); // print the annotations - if (ra != null) { - for (Relation<?> a : ra) { + if(ra != null) { + for(Relation<?> a : ra) { // Avoid duplicated output. - if (dbrels.contains(a)) { + if(dbrels.contains(a)) { continue; } String label = a.getShortName(); Object value = a.get(objID); - if (value == null) { + if(value == null) { continue; } TextWriterWriterInterface<?> writer = out.getWriterFor(value); - if (writer == null) { + if(writer == null) { // Ignore continue; } @@ -281,9 +276,10 @@ public class TextWriter { private void writeClusterResult(Database db, StreamFactory streamOpener, Clustering<Model> clustering, Cluster<Model> clus, List<Relation<?>> ra, NamingScheme naming) throws FileNotFoundException, UnableToComplyException, IOException { String filename = null; - if (naming != null) { + if(naming != null) { filename = filenameFromLabel(naming.getNameFor(clus)); - } else { + } + else { filename = "cluster"; } @@ -292,25 +288,19 @@ public class TextWriter { // Write cluster information out.commentPrintLn("Cluster: " + naming.getNameFor(clus)); - Model model = clus.getModel(); - if (model != ClusterModel.CLUSTER && model != null) { - TextWriterWriterInterface<?> mwri = out.getWriterFor(model); - if (mwri != null) { - mwri.writeObject(out, null, model); - } - } - if (clustering.getClusterHierarchy().numParents(clus) > 0) { + clus.writeToText(out, null); + if(clustering.getClusterHierarchy().numParents(clus) > 0) { StringBuilder buf = new StringBuilder(); buf.append("Parents:"); - for (Hierarchy.Iter<Cluster<Model>> iter = clustering.getClusterHierarchy().iterParents(clus); iter.valid(); iter.advance()) { + for(Hierarchy.Iter<Cluster<Model>> iter = clustering.getClusterHierarchy().iterParents(clus); iter.valid(); iter.advance()) { buf.append(' ').append(naming.getNameFor(iter.get())); } out.commentPrintLn(buf.toString()); } - if (clustering.getClusterHierarchy().numChildren(clus) > 0) { + if(clustering.getClusterHierarchy().numChildren(clus) > 0) { StringBuilder buf = new StringBuilder(); buf.append("Children:"); - for (Hierarchy.Iter<Cluster<Model>> iter = clustering.getClusterHierarchy().iterChildren(clus); iter.valid(); iter.advance()) { + for(Hierarchy.Iter<Cluster<Model>> iter = clustering.getClusterHierarchy().iterChildren(clus); iter.valid(); iter.advance()) { buf.append(' ').append(naming.getNameFor(iter.get())); } out.commentPrintLn(buf.toString()); @@ -319,7 +309,7 @@ public class TextWriter { // print ids. DBIDs ids = clus.getIDs(); - for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { + for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { printObject(out, db, iter, ra); } out.flush(); @@ -331,20 +321,20 @@ public class TextWriter { TextWriterStream out = new TextWriterStream(outStream, writers); // hack to print collectionResult header information - if (ri instanceof CollectionResult<?>) { + if(ri instanceof CollectionResult<?>) { final Collection<String> hdr = ((CollectionResult<?>) ri).getHeader(); - if (hdr != null) { - for (String header : hdr) { + if(hdr != null) { + for(String header : hdr) { out.commentPrintLn(header); } out.flush(); } } Iterator<?> i = ri.iterator(); - while (i.hasNext()) { + while(i.hasNext()) { Object o = i.next(); TextWriterWriterInterface<?> writer = out.getWriterFor(o); - if (writer != null) { + if(writer != null) { writer.writeObject(out, null, o); } out.flush(); @@ -357,7 +347,7 @@ public class TextWriter { PrintStream outStream = streamOpener.openStream(getFilename(or, or.getShortName())); TextWriterStream out = new TextWriterStream(outStream, writers); - for (DBIDIter i = or.iter(or.getDBIDs()).iter(); i.valid(); i.advance()) { + for(DBIDIter i = or.iter(or.getDBIDs()).iter(); i.valid(); i.advance()) { printObject(out, db, i, ra); } out.flush(); @@ -365,7 +355,7 @@ public class TextWriter { } private void writeSettingsResult(StreamFactory streamOpener, List<SettingsResult> rs) throws UnableToComplyException, IOException { - if (rs.size() < 1) { + if(rs.size() < 1) { return; } SettingsResult r = rs.get(0); @@ -373,38 +363,41 @@ public class TextWriter { TextWriterStream out = new TextWriterStream(outStream, writers); // Write settings preamble out.commentPrintLn("Settings:"); - - if (rs != null) { - for (SettingsResult settings : rs) { + + if(rs != null) { + for(SettingsResult settings : rs) { Object last = null; - for (Pair<Object, Parameter<?>> setting : settings.getSettings()) { - if (setting.first != last && setting.first != null) { - if (last != null) { + for(TrackedParameter setting : settings.getSettings()) { + if(setting.getOwner() != last && setting.getOwner() != null) { + if(last != null) { out.commentPrintLn(""); } String name; try { - if (setting.first instanceof Class) { - name = ((Class<?>) setting.first).getName(); - } else { - name = setting.first.getClass().getName(); + if(setting.getOwner() instanceof Class) { + name = ((Class<?>) setting.getOwner()).getName(); + } + else { + name = setting.getOwner().getClass().getName(); } - if (ClassParameter.class.isInstance(setting.first)) { - name = ((ClassParameter<?>) setting.first).getValue().getName(); + if(ClassParameter.class.isInstance(setting.getOwner())) { + name = ((ClassParameter<?>) setting.getOwner()).getValue().getName(); } - } catch (NullPointerException e) { + } + catch(NullPointerException e) { name = "[null]"; } out.commentPrintLn(name); - last = setting.first; + last = setting.getOwner(); } - String name = setting.second.getOptionID().getName(); + String name = setting.getParameter().getOptionID().getName(); String value = "[unset]"; try { - if (setting.second.isDefined()) { - value = setting.second.getValueAsString(); + if(setting.getParameter().isDefined()) { + value = setting.getParameter().getValueAsString(); } - } catch (NullPointerException e) { + } + catch(NullPointerException e) { value = "[null]"; } out.commentPrintLn(SerializedParameterization.OPTION_PREFIX + name + " " + value); @@ -416,11 +409,11 @@ public class TextWriter { } private void writeOtherResult(StreamFactory streamOpener, Result r) throws UnableToComplyException, IOException { - if (writers.getHandler(r) != null) { + if(writers.getHandler(r) != null) { PrintStream outStream = streamOpener.openStream(getFilename(r, r.getShortName())); TextWriterStream out = new TextWriterStream(outStream, writers); TextWriterWriterInterface<?> owriter = out.getWriterFor(r); - if (owriter == null) { + if(owriter == null) { throw new UnableToComplyException("No handler for result class: " + r.getClass().getSimpleName()); } // Write data diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterStream.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterStream.java index 542be099..c174963d 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterStream.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterStream.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter; 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/result/textwriter/TextWriterWriterInterface.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterWriterInterface.java index 35fa487f..cbbbdd21 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterWriterInterface.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriterWriterInterface.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter; 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/result/textwriter/naming/NamingScheme.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/NamingScheme.java index a63d3726..42b57149 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/NamingScheme.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/NamingScheme.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.naming; 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/result/textwriter/naming/SimpleEnumeratingScheme.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/SimpleEnumeratingScheme.java index dacb342b..2e0885fd 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/SimpleEnumeratingScheme.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/SimpleEnumeratingScheme.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.naming; 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/result/textwriter/naming/package-info.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/package-info.java index ab4b93d0..85fa0278 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/naming/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/result/textwriter/package-info.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/package-info.java index 60f2f534..7b178fe5 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/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/result/textwriter/writers/TextWriterDoubleDoublePair.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterDoubleDoublePair.java index a9975195..b39c0b1e 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterDoubleDoublePair.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterDoubleDoublePair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; 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/result/textwriter/writers/TextWriterObjectArray.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectArray.java index 34d5b419..5f9d5000 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectArray.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectArray.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; 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/result/textwriter/writers/TextWriterObjectComment.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectComment.java index d3de4ff3..e56c9dfe 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectComment.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectComment.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; 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/result/textwriter/writers/TextWriterObjectInline.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectInline.java index 28c549d7..57bf699f 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectInline.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterObjectInline.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; 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/result/textwriter/writers/TextWriterPair.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterPair.java index 1705f5cc..decc9efa 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterPair.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterPair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; 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/result/textwriter/writers/TextWriterTextWriteable.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTextWriteable.java index 04e56ae5..62e22a1b 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTextWriteable.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTextWriteable.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; 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,7 +32,7 @@ import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterWriterInterface; * * @author Erich Schubert * - * @apiviz.has TextWriteable + * @apiviz.uses TextWriteable */ public class TextWriterTextWriteable extends TextWriterWriterInterface<TextWriteable> { /** diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTriple.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTriple.java deleted file mode 100644 index 1efde342..00000000 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterTriple.java +++ /dev/null @@ -1,73 +0,0 @@ -package de.lmu.ifi.dbs.elki.result.textwriter.writers; - -/* - 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.io.IOException; - -import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterStream; -import de.lmu.ifi.dbs.elki.result.textwriter.TextWriterWriterInterface; -import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException; -import de.lmu.ifi.dbs.elki.utilities.pairs.Triple; - -/** - * Write a triple - * - * @author Erich Schubert - * - */ -public class TextWriterTriple extends TextWriterWriterInterface<Triple<?,?,?>> { - /** - * Serialize a triple, component-wise - */ - @Override - @SuppressWarnings("unchecked") - public void write(TextWriterStream out, String label, Triple<?,?,?> object) throws UnableToComplyException, IOException { - if (object != null) { - Object first = object.getFirst(); - if (first != null) { - TextWriterWriterInterface<Object> tw = (TextWriterWriterInterface<Object>) out.getWriterFor(first); - if (tw == null) { - throw new UnableToComplyException("No handler for database object itself: " + first.getClass().getSimpleName()); - } - tw.write(out, label, first); - } - Object second = object.getSecond(); - if (second != null) { - TextWriterWriterInterface<Object> tw = (TextWriterWriterInterface<Object>) out.getWriterFor(second); - if (tw == null) { - throw new UnableToComplyException("No handler for database object itself: " + second.getClass().getSimpleName()); - } - tw.write(out, label, second); - } - Object third = object.getThird(); - if (third != null) { - TextWriterWriterInterface<Object> tw = (TextWriterWriterInterface<Object>) out.getWriterFor(third); - if (tw == null) { - throw new UnableToComplyException("No handler for database object itself: " + third.getClass().getSimpleName()); - } - tw.write(out, label, third); - } - } - } -} diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterVector.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterVector.java index 46197e21..5cdfa574 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterVector.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/TextWriterVector.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.result.textwriter.writers; 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/result/textwriter/writers/package-info.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/package-info.java index da527a67..ecae74ee 100644 --- a/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/writers/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 |