diff --git a/src/fr/inrialpes/exmo/align/impl/eval/GraphEvaluator.java b/src/fr/inrialpes/exmo/align/impl/eval/GraphEvaluator.java new file mode 100644 index 0000000000000000000000000000000000000000..3d2e8d725b733c0d22cc8f0136b1494abee5d4c9 --- /dev/null +++ b/src/fr/inrialpes/exmo/align/impl/eval/GraphEvaluator.java @@ -0,0 +1,192 @@ +/* + * $Id$ + * + * Copyright (C) INRIA, 2004-2005, 2007-2010 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +package fr.inrialpes.exmo.align.impl.eval; + +import org.semanticweb.owl.align.Alignment; +import org.semanticweb.owl.align.AlignmentException; +import org.semanticweb.owl.align.Cell; + +import fr.inrialpes.exmo.align.impl.BasicEvaluator; + +import java.util.Enumeration; +import java.util.Properties; +import java.util.Iterator; +import java.util.TreeSet; +import java.util.Set; +import java.util.SortedSet; +import java.util.Comparator; +import java.util.Vector; +import java.io.PrintWriter; +import java.net.URI; + +/** + * GraphEvaluator: an abstraction that is used for providing evaluation curves + * instead of values (or sets of values) + * Pair: only used for recording sets of points in a curve + * + * @author Jerome Euzenat + * @version $Id$ + */ + +public abstract class GraphEvaluator extends BasicEvaluator { + + public Vector<Pair> points = null; + + /** Creation: + * A priori, evaluators can deal with any kind of alignments. + * However, it will not work if these are not of the same type. + **/ + public GraphEvaluator( Alignment align1, Alignment align2 ) { + super(align1, align2); + if ( align1.getClass() != align2.getClass() ) { + // This should throw an exception... + } + points = new Vector<Pair>(); + } + + /** + * Compute precision and recall graphs. + * The algorithm is as follows: + * 1) Order the pairs of the found alignment. + * 2) For + */ + public double eval( Properties params ) throws AlignmentException { + return eval( params, (Object)null ); + } + + public SortedSet<Cell> orderAlignment() { + // Create a sorted structure in which putting the cells + // TreeSet could be replaced by something else + SortedSet<Cell> cellSet = new TreeSet<Cell>( + new Comparator<Cell>() { + public int compare( Cell o1, Cell o2 ) + throws ClassCastException{ + try { + //System.err.println(((Cell)o1).getObject1()+" -- "+((Cell)o1).getObject2()+" // "+((Cell)o2).getObject1()+" -- "+((Cell)o2).getObject2()); + if ( o1 instanceof Cell && o2 instanceof Cell ) { + if ( ((Cell)o1).getStrength() > ((Cell)o2).getStrength() ){ + return -1; + } else if ( ((Cell)o1).getStrength() < ((Cell)o2).getStrength() ){ + return 1; + //The comparator must always tell that things are different! + } else if ( (((Cell)o1).getObject1AsURI(align1).getFragment() == null) + || (((Cell)o2).getObject1AsURI(align2).getFragment() == null) ) { + return -1; + } else if ( ((Cell)o1).getObject1AsURI(align1).getFragment().compareTo(((Cell)o2).getObject1AsURI(align2).getFragment()) > 0) { + return -1; + } else if ( ((Cell)o1).getObject1AsURI(align1).getFragment().compareTo(((Cell)o2).getObject1AsURI(align2).getFragment()) < 0 ) { + return 1; + } else if ( (((Cell)o1).getObject2AsURI(align1).getFragment() == null) + || (((Cell)o2).getObject2AsURI(align2).getFragment() == null) ) { + return -1; + } else if ( ((Cell)o1).getObject2AsURI(align1).getFragment().compareTo(((Cell)o2).getObject2AsURI(align2).getFragment()) > 0) { + return -1; + // We assume that they have different names + } else { return 1; } + } else { throw new ClassCastException(); } + } catch ( AlignmentException e) { e.printStackTrace(); return 0;} + } + } + ); + + // Set the found cells in the sorted structure + for ( Cell c : align2 ) { + cellSet.add( c ); + } + + return cellSet; + } + + /* + * This checks if a particular cell is in the reference alignment or not. + * This could be changed for other kind of correctness (e.g., Semantics). + */ + public double correctCell( Cell c2, Alignment align2, Alignment refalign ) throws AlignmentException { + Set s1 = (Set)refalign.getAlignCells1( c2.getObject1() ); + if( s1 != null ) { // for all cells matching our first entity + for( Iterator it1 = s1.iterator(); it1.hasNext(); ){ + Cell c1 = (Cell)it1.next(); + URI uri1 = c1.getObject2AsURI(refalign); + URI uri2 = c2.getObject2AsURI(align2); + if (uri1.toString().equals(uri2.toString())) { //This cell matches a correct one + return 1.; + } + } + } + return 0.; + } + + /** + * This output the result + */ + public void writeXMLMap(PrintWriter writer) throws java.io.IOException { + for( int j = 0; j < points.size(); j++ ){ + Pair precrec = points.get(j); + writer.print(" <step>\n <x>"); + writer.print( precrec.getX() ); + writer.print("</x>\n <y>"); + writer.print( precrec.getY() ); + writer.print("</y>\n </step>\n"); + } + } + + /** + * This output the result + */ + public void writeFullPlot(PrintWriter writer) { + for( int j = 0; j < points.size(); j++ ){ + Pair precrec = points.get(j); + writer.println( precrec.getX()+" "+precrec.getY() ); + } + } + + /* Write out the final interpolated recall/precision graph data. + * One line for each recall/precision point in the form: 'R-value P-value'. + * This is the format needed for GNUPLOT. + public void writePlot( PrintWriter writer ) throws java.io.IOException { + for(int i = 0; i < STEP+1; i++){ + writer.println( (double)i/10 + "\t" + precisions[i]); + } + } + */ + + public void writePlot( PrintWriter writer ) { + // Print header + int size = points.size(); + writer.println("#Curve 0, "+size+" points"); + writer.println("#x y type"); + writer.println("%% Plot generated by GraphEvaluator of alignapi"); + writer.println("%% Include in PGF tex by:\n"); + writer.println("%% \\begin{tikzpicture}[cap=round]"); + writer.println("%% \\draw[step="+size+"cm,very thin,color=gray] (-0.2,-0.2) grid ("+size+","+size+");"); + writer.println("%% \\draw[->] (-0.2,0) -- (10.2,0) node[right] {$recall$}; "); + writer.println("%% \\draw[->] (0,-0.2) -- (0,10.2) node[above] {$precision$}; "); + //writer.println("%% \\draw plot[mark=+,smooth] file {"+algo+".table};"); + writer.println("%% \\end{tikzpicture}"); + writer.println(); + for( int j = 0; j < size; j++ ){ + Pair precrec = points.get(j); + writer.println( precrec.getX()+" "+precrec.getY() ); + } + } + +} diff --git a/src/fr/inrialpes/exmo/align/impl/eval/PRGraphEvaluator.java b/src/fr/inrialpes/exmo/align/impl/eval/PRGraphEvaluator.java index f3224f1ffb52fcaa4c5d2376dd75aaba887b8e43..62c134dd1ca4e9ceaa7687e575a4e88b86c25e29 100644 --- a/src/fr/inrialpes/exmo/align/impl/eval/PRGraphEvaluator.java +++ b/src/fr/inrialpes/exmo/align/impl/eval/PRGraphEvaluator.java @@ -24,11 +24,9 @@ package fr.inrialpes.exmo.align.impl.eval; import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentException; import org.semanticweb.owl.align.Cell; -import org.semanticweb.owl.align.Parameters; - -import fr.inrialpes.exmo.align.impl.BasicEvaluator; import java.util.Enumeration; +import java.util.Properties; import java.util.Iterator; import java.util.TreeSet; import java.util.Set; @@ -66,9 +64,12 @@ import java.net.URI; * provided all the correspondences in the reference. * Otherwise, it would basically be: * SUM_c\in correct( P( c ) ) / nbexpected + * + * NOTE (JE:2010): This should be adapated for other notions of Precision and Recall + * */ -public class PRGraphEvaluator extends BasicEvaluator { +public class PRGraphEvaluator extends GraphEvaluator { private int STEP = 10; @@ -77,30 +78,17 @@ public class PRGraphEvaluator extends BasicEvaluator { private double map = 0.0; // For MAP - private Vector<Pair> points; - - /** Creation: - * A priori, evaluators can deal with any kind of alignments. - * However, it will not work if these are not of the same type. - **/ public PRGraphEvaluator(Alignment align1, Alignment align2) { super(align1, align2); - if ( align1.getClass() != align2.getClass() ) { - // This should throw an exception... - } - points = new Vector<Pair>(); } /** * Compute precision and recall graphs. - * The algorithm is as follows: - * 1) Order the pairs of the found alignment. - * 2) For */ - public double eval(Parameters params) throws AlignmentException { + public double eval( Properties params ) throws AlignmentException { return eval( params, (Object)null ); } - public double eval(Parameters params, Object cache) throws AlignmentException { + public double eval( Properties params, Object cache ) throws AlignmentException { // Local variables int nbexpected = align1.nbCells(); int nbfound = 0; @@ -108,105 +96,63 @@ public class PRGraphEvaluator extends BasicEvaluator { double sumprecisions = 0.; // For MAP // unchecked - if( params.getParameter("step") != null ){ - STEP = ((Integer)params.getParameter("step")).intValue(); + if( params.getProperty("step") != null ){ + STEP = Integer.parseInt( params.getProperty("step") ); } precisions = new double[ STEP+1 ]; - // Create a sorted structure in which putting the cells - // TreeSet could be replaced by something else - SortedSet<Cell> cellSet = new TreeSet<Cell>( - new Comparator<Cell>() { - public int compare( Cell o1, Cell o2 ) - throws ClassCastException{ - try { - //System.err.println(((Cell)o1).getObject1()+" -- "+((Cell)o1).getObject2()+" // "+((Cell)o2).getObject1()+" -- "+((Cell)o2).getObject2()); - if ( o1 instanceof Cell && o2 instanceof Cell ) { - if ( ((Cell)o1).getStrength() > ((Cell)o2).getStrength() ){ - return -1; - } else if ( ((Cell)o1).getStrength() < ((Cell)o2).getStrength() ){ - return 1; - //The comparator must always tell that things are different! - } else if ( (((Cell)o1).getObject1AsURI(align1).getFragment() == null) - || (((Cell)o2).getObject1AsURI(align2).getFragment() == null) ) { - return -1; - } else if ( ((Cell)o1).getObject1AsURI(align1).getFragment().compareTo(((Cell)o2).getObject1AsURI(align2).getFragment()) > 0) { - return -1; - } else if ( ((Cell)o1).getObject1AsURI(align1).getFragment().compareTo(((Cell)o2).getObject1AsURI(align2).getFragment()) < 0 ) { - return 1; - } else if ( (((Cell)o1).getObject2AsURI(align1).getFragment() == null) - || (((Cell)o2).getObject2AsURI(align2).getFragment() == null) ) { - return -1; - } else if ( ((Cell)o1).getObject2AsURI(align1).getFragment().compareTo(((Cell)o2).getObject2AsURI(align2).getFragment()) > 0) { - return -1; - // We assume that they have different names - } else { return 1; } - } else { throw new ClassCastException(); } - } catch ( AlignmentException e) { e.printStackTrace(); return 0;} - } - } - ); - - // Set the found cells in the sorted structure - for ( Cell c : align2 ) { - cellSet.add( c ); - } - - // Collect the points that change recall - // (the other provide lower precision from the same recall and are not considered) - points.add( new Pair( 0., 1. ) ); // [R=0%] - for( Cell c2 : cellSet ){ - nbfound++; - Set s1 = (Set)align1.getAlignCells1( c2.getObject1() ); - if( s1 != null ){ // for all cells matching our first entity - for( Iterator it1 = s1.iterator(); it1.hasNext() && c2 != null; ){ - Cell c1 = (Cell)it1.next(); - URI uri1 = c1.getObject2AsURI(align1); - URI uri2 = c2.getObject2AsURI(align2); - if (uri1.toString().equals(uri2.toString())) { //This cell matches a correct one - nbcorrect++; - double recall = (double)nbcorrect / (double)nbexpected; - double precision = (double)nbcorrect / (double)nbfound; - sumprecisions += precision; // For MAP - // Create a new pair to put in the list - // It records real precision and recall at that point - points.add( new Pair( recall, precision ) ); - c2 = null; // out of the loop. - } - } - } - } - // Now if we want to have a regular curve we must penalize those system - // that do not reach 100% recall. - // for that purpose, and for each other bound we add a point with the worse - // precision which is the required recall level divided with the maximum - // cardinality possible (i.e., the multiplication of the ontology sizes). - // JE[R=100%]: that's a fine idea! Unfortunately SIZEOFO1 and SIZEOFO2 are undefined values - //points.add( new Pair( 1., (double)nbexpected/(double)(SIZEOFO1*SIZEOFA2) ) ); - points.add( new Pair( 1.0, 0. ) ); // useless because - - // [Interp.] Interpolate curve points at each n-recall level - // This is inspired form Ray Mooney's program - // It works backward in the vector, - // (in the same spirit as before, the maximum value so far -best- is retained) - int j = points.size()-1; // index in recall-ordered vector of points - int i = STEP; // index of the current recall interval - double level = (double)i/STEP; // max level of that interval - double best = 0.; // best value found for that interval - while( j >= 0 ){ - Pair precrec = points.get(j); - while ( precrec.getX() < level ){ - precisions[i] = best; - i--; - level = (double)i/STEP; - }; - if ( precrec.getY() > best ) best = precrec.getY(); - j--; - } - precisions[0] = best; // It should be 1. that's why it is now added in points. [R=0%] + // Create a sorted structure in which putting the cells + // TreeSet could be replaced by something else + SortedSet<Cell> cellSet = orderAlignment(); + + // Collect the points that change recall + // (the other provide lower precision from the same recall and are not considered) + points.add( new Pair( 0., 1. ) ); // [R=0%] + for( Cell c2 : cellSet ){ + nbfound++; + if ( correctCell( c2, align2, align1 ) > 0. ) { + nbcorrect++; + double recall = (double)nbcorrect / (double)nbexpected; + double precision = (double)nbcorrect / (double)nbfound; + sumprecisions += precision; // For MAP + // Create a new pair to put in the list + // It records real precision and recall at that point + points.add( new Pair( recall, precision ) ); + c2 = null; // out of the loop. + } + } - map = sumprecisions / nbexpected; // For MAP - return map; + // Now if we want to have a regular curve we must penalize those system + // that do not reach 100% recall. + // for that purpose, and for each other bound we add a point with the worse + // precision which is the required recall level divided with the maximum + // cardinality possible (i.e., the multiplication of the ontology sizes). + // JE[R=100%]: that's a fine idea! Unfortunately SIZEOFO1 and SIZEOFO2 are undefined values + //points.add( new Pair( 1., (double)nbexpected/(double)(SIZEOFO1*SIZEOFA2) ) ); + points.add( new Pair( 1.0, 0. ) ); // useless because + + // [Interp.] Interpolate curve points at each n-recall level + // This is inspired form Ray Mooney's program + // It works backward in the vector, + // (in the same spirit as before, the maximum value so far -best- is retained) + int j = points.size()-1; // index in recall-ordered vector of points + int i = STEP; // index of the current recall interval + double level = (double)i/STEP; // max level of that interval + double best = 0.; // best value found for that interval + while( j >= 0 ){ + Pair precrec = points.get(j); + while ( precrec.getX() < level ){ + precisions[i] = best; + i--; + level = (double)i/STEP; + }; + if ( precrec.getY() > best ) best = precrec.getY(); + j--; + } + precisions[0] = best; // It should be 1. that's why it is now added in points. [R=0%] + + map = sumprecisions / nbexpected; // For MAP + return map; } /** @@ -225,24 +171,13 @@ public class PRGraphEvaluator extends BasicEvaluator { } writer.print(" <MAP>"+map+"</MAP>\n"); writer.print(" </output>\n</rdf:RDF>\n"); - writePlot( writer ); - } - - /** - * This output the result - */ - public void writeFullPlot(PrintWriter writer) throws java.io.IOException { - for( int j = 0; j < points.size(); j++ ){ - Pair precrec = points.get(j); - writer.println( precrec.getX()+" "+precrec.getY() ); - } } /* Write out the final interpolated recall/precision graph data. * One line for each recall/precision point in the form: 'R-value P-value'. * This is the format needed for GNUPLOT. */ - public void writePlot(PrintWriter writer) throws java.io.IOException { + public void writePlot( PrintWriter writer ) { for(int i = 0; i < STEP+1; i++){ writer.println( (double)i/10 + "\t" + precisions[i]); } @@ -257,13 +192,3 @@ public class PRGraphEvaluator extends BasicEvaluator { } } -class Pair { - private double x; - private double y; - public Pair( double x, double y ){ - this.x = x; - this.y = y; - } - public double getX(){ return x; } - public double getY(){ return y; } -} diff --git a/src/fr/inrialpes/exmo/align/impl/eval/Pair.java b/src/fr/inrialpes/exmo/align/impl/eval/Pair.java new file mode 100644 index 0000000000000000000000000000000000000000..fc2da3157c837913f0ea695fc196d5bff4ae1242 --- /dev/null +++ b/src/fr/inrialpes/exmo/align/impl/eval/Pair.java @@ -0,0 +1,33 @@ +/* + * $Id$ + * + * Copyright (C) INRIA, 2004-2005, 2007-2010 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +package fr.inrialpes.exmo.align.impl.eval; + +public class Pair { + private double x; + private double y; + public Pair( double x, double y ){ + this.x = x; + this.y = y; + } + public double getX(){ return x; } + public double getY(){ return y; } +} diff --git a/src/fr/inrialpes/exmo/align/util/GenPlot.java b/src/fr/inrialpes/exmo/align/util/GenPlot.java index 0e9cde8dd022adce44c59050ebb8293f65440100..2c0a5e55774cb0504a2b118c090acab1e5e4668c 100644 --- a/src/fr/inrialpes/exmo/align/util/GenPlot.java +++ b/src/fr/inrialpes/exmo/align/util/GenPlot.java @@ -1,8 +1,6 @@ /* * $Id$ * - * Copyright (C) 2003 The University of Manchester - * Copyright (C) 2003 The University of Karlsruhe * Copyright (C) 2003-2009, INRIA * Copyright (C) 2004, Université de Montréal * @@ -27,9 +25,8 @@ package fr.inrialpes.exmo.align.util; import org.semanticweb.owl.align.Alignment; -import org.semanticweb.owl.align.Parameters; -import fr.inrialpes.exmo.align.impl.BasicParameters; +import fr.inrialpes.exmo.align.impl.eval.GraphEvaluator; import fr.inrialpes.exmo.align.impl.eval.PRGraphEvaluator; import fr.inrialpes.exmo.align.onto.OntologyFactory; @@ -42,6 +39,7 @@ import java.io.BufferedWriter; import java.io.OutputStreamWriter; import java.lang.Integer; import java.util.Hashtable; +import java.util.Properties; import java.util.Vector; import java.util.Enumeration; import java.util.StringTokenizer; @@ -91,10 +89,11 @@ import fr.inrialpes.exmo.align.parser.AlignmentParser; public class GenPlot { int STEP = 10; - Parameters params = null; + Properties params = null; Vector<String> listAlgo; String fileNames = ""; String outFile = null; + java.lang.reflect.Constructor evalConstructor = null; String type = "tsv"; int debug = 0; PrintWriter output = null; @@ -111,11 +110,13 @@ public class GenPlot { longopts[1] = new LongOpt("output", LongOpt.REQUIRED_ARGUMENT, null, 'o'); longopts[3] = new LongOpt("type", LongOpt.REQUIRED_ARGUMENT, null, 't'); longopts[4] = new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'd'); + longopts[5] = new LongOpt("evaluator", LongOpt.REQUIRED_ARGUMENT, null, 'e'); longopts[6] = new LongOpt("list", LongOpt.REQUIRED_ARGUMENT, null, 'l'); - Getopt g = new Getopt("", args, "ho:d::l:t:", longopts); + Getopt g = new Getopt("", args, "ho:d::l:e:t:", longopts); int c; String arg; + String cl = "fr.inrialpes.exmo.align.impl.eval.PRGraphEvaluator"; while ((c = g.getopt()) != -1) { switch (c) { @@ -126,6 +127,10 @@ public class GenPlot { /* Write output here */ outFile = g.getOptarg(); break; + case 'e' : + /* Name of the class to compute */ + cl = g.getOptarg(); + break; case 't' : /* Type of output (tex/tsv(/html/xml/ascii)) */ type = g.getOptarg(); @@ -143,6 +148,11 @@ public class GenPlot { } } + Class evalClass = Class.forName( cl ); + Class oClass = Class.forName("org.semanticweb.owl.align.Alignment"); + Class[] cparams = { oClass, oClass }; + evalConstructor = evalClass.getConstructor( cparams ); + // JE: StringTokenizer is obsoleted in Java 1.4 in favor of split: to change listAlgo = new Vector<String>(); StringTokenizer st = new StringTokenizer(fileNames,","); @@ -150,10 +160,10 @@ public class GenPlot { listAlgo.add(st.nextToken()); } - params = new BasicParameters(); - if (debug > 0) params.setParameter("debug", new Integer(debug-1)); + params = new Properties(); + if (debug > 0) params.setProperty( "debug", Integer.toString( debug-1 ) ); - params.setParameter("step", new Integer(STEP)); + params.setProperty("step", Integer.toString( STEP ) ); // Set output file OutputStream stream; @@ -227,11 +237,14 @@ public class GenPlot { for ( String algo : listAlgo ) { // call eval if ( debug > 0 ) System.err.println(" Considering result "+algo+" ("+i+")"); + // JE2010GRAPH PRGraphEvaluator evaluator = eval( prefix+"refalign.rdf", prefix+algo+".rdf"); // store the result + // This cannot be done for ROC curves + // JE2010GRAPH if ( evaluator != null ){ for( int j = 0; j <= STEP ; j++ ){ - result[i][j] = result[i][j] + evaluator.getPrecision(j); + result[i][j] += evaluator.getPrecision(j); } } i++; @@ -254,11 +267,13 @@ public class GenPlot { Alignment align2 = aparser.parse( alignName2 ); if ( debug > 1 ) System.err.println(" Alignment structure2 parsed"); // Create evaluator object - eval = new PRGraphEvaluator( align1, align2 ); + // JE2010GRAPH + Object[] mparams = { align1, align2 }; + eval = (PRGraphEvaluator)evalConstructor.newInstance( mparams ); + //eval = new PRGraphEvaluator( align1, align2 ); // Compare - params.setParameter( "debug", new Integer( nextdebug ) ); + params.setProperty( "debug", Integer.toString( nextdebug ) ); eval.eval( params ) ; - // Unload the ontologies. //loaded.clear(); } catch (Exception ex) { @@ -295,11 +310,13 @@ public class GenPlot { output.println("% Draw grid"); output.println("\\draw[step="+(STEP/10)+"cm,very thin,color=gray] (-0.2,-0.2) grid ("+STEP+","+STEP+");"); output.println("\\draw[->] (-0.2,0) -- (10.2,0);"); + // JE2010GRAPH output.println("\\draw (5,-0.3) node {$recall$}; "); output.println("\\draw (0,-0.3) node {0.}; "); output.println("\\draw (10,-0.3) node {1.}; "); output.println("\\draw[->] (0,-0.2) -- (0,10.2);"); output.println("\\draw (-0.3,0) node {0.}; "); + // JE2010GRAPH output.println("\\draw (-0.3,5) node[rotate=90] {$precision$}; "); output.println("\\draw (-0.3,10) node {1.}; "); output.println("% Plots"); @@ -340,6 +357,7 @@ public class GenPlot { writer.println("%% \\draw plot[mark=+,smooth] file {"+algo+".table};"); writer.println("%% \\end{tikzpicture}"); writer.println(); + // JE2010GRAPH: it outputs the plot by itself !!!! for( int j = 0; j <= STEP; j++ ){ writer.print((double)j*10/STEP); writer.println(" "+result[i][j]*10); @@ -372,6 +390,7 @@ public class GenPlot { System.out.println("usage: GenPlot [options]"); System.out.println("options are:"); System.out.println("\t--type=tsv|tex|(html|xml) -t tsv|tex|(html|xml)\tSpecifies the output format"); + System.out.println("\t--evaluator=class -e class\tSpecifies the class of GraphEvaluator to be used"); System.out.println("\t--list=algo1,...,algon -l algo1,...,algon\tSequence of the filenames to consider"); System.out.println("\t--debug[=n] -d [n]\t\tReport debug info at level n"); System.out.println("\t--help -h\t\t\tPrint this message");