From f49f083507c055126083a413fea4584326a0fcaa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr>
Date: Tue, 13 Sep 2011 16:20:46 +0000
Subject: [PATCH] - Added level lines in the Triangle display of GroupEval

---
 html/credits.html                             |   1 +
 html/relnotes.html                            |   4 +
 .../inrialpes/exmo/align/util/GroupEval.java  | 144 +++++++++++++++++-
 3 files changed, 146 insertions(+), 3 deletions(-)

diff --git a/html/credits.html b/html/credits.html
index bd3cb332..83a25e3f 100644
--- a/html/credits.html
+++ b/html/credits.html
@@ -51,6 +51,7 @@ Raphael Voltz</dt><dd>provided some code snippets for
     that was embedded in the Alignment Server (in version 2.5-3.0)</dd>
 <dt><a href="http://konstantinosnedas.com/">Konstantinos A. Nedas</a></dt><dd>implemented the Hungarian method which is
     embedded in the Alignment API implementation (now in <a href="http://ontosim.gforge.inria.fr">OntoSim</a>).</dd>
+<dt><a href="http://ki.informatik.uni-mannheim.de/people/christian_meilicke.html">Christian Meilicke</a></dt><dd>proposed the enhancement of the Triangle display with level lines (including F-measure) and provided the code for computing them.</dd>
 <dt>an anonymous person</dt>
 <dd>developped the Levensthein
     distance implementation that is used in the Alignment API
diff --git a/html/relnotes.html b/html/relnotes.html
index dec560d3..57665a9c 100644
--- a/html/relnotes.html
+++ b/html/relnotes.html
@@ -59,6 +59,10 @@ The development of 4 versions continues.
 <h2>Current SVN trunk version</h2>
 
 <!--h2>Version 4.3 (): xx/xx/xxxx - Zimt</h2-->
+<p><ul compact="1">
+<li>Full reengineering of the test generator (gen)</li>
+<li>Added level lines in the triangle display of <tt>GroupEval</tt> (util)</li>
+</ul></p>
 
 <h2>Version 4.2 (1618): 31/05/2011 - Tring</h2>
 
diff --git a/src/fr/inrialpes/exmo/align/util/GroupEval.java b/src/fr/inrialpes/exmo/align/util/GroupEval.java
index 4c3aced0..124ab884 100644
--- a/src/fr/inrialpes/exmo/align/util/GroupEval.java
+++ b/src/fr/inrialpes/exmo/align/util/GroupEval.java
@@ -285,6 +285,11 @@ public class GroupEval {
 	else if ( type.equals("triangle") ) printTRIANGLE( result );
     }
 
+    /**
+     * A plot of the precision recall points on a triangular space
+     * Added level lines provides by Christian Meilicke (U. Mannheim)
+     * See his program in comment below
+     */
     public void printTRIANGLE( Vector<Vector> result ) {
 	// variables for computing iterative harmonic means
 	int expected = 0; // expected so far
@@ -329,14 +334,48 @@ public class GroupEval {
 	System.out.println("\n%% Plot generated by GenPlot of alignapi");
 	System.out.println("\\begin{tikzpicture}[cap=round]");
 	System.out.println("% Draw grid");
-	System.out.println("\\draw[step=1cm,very thin,color=gray] (-0.2,-0.2) grid (10.0,9.0);");
+	//System.out.println("\\draw[step=1cm,very thin,color=gray] (-0.2,-0.2) grid (10.0,9.0);");
 	System.out.println("\\draw[|-|] (-0,0) -- (10,0);");
 	System.out.println("%\\draw[dashed,very thin] (0,0) -- (5,8.66) -- (10,0);");
 	System.out.println("\\draw[dashed,very thin] (10,0) arc (0:60:10cm);");
 	System.out.println("\\draw[dashed,very thin] (0,0) arc (180:120:10cm);");
 
-	System.out.println("\\draw (0,-0.3) node {$recall$}; ");
-	System.out.println("\\draw (10,-0.3) node {$precision$}; ");
+	System.out.println("%% Level lines for recall");
+	System.out.println("\\draw[dashed] (10,0) arc (0:60:10cm) node[anchor=south east]  {{\\tiny R=1.}};");
+	System.out.println("\\draw[dotted,very thin] (9,0) arc (0:63:9cm) node[anchor=south east] {{\\tiny R=.9}};");
+	System.out.println("\\draw[dotted,very thin] (8,0) arc (0:66:8cm) node[anchor=south east]  {{\\tiny R=.8}};");
+	System.out.println("\\draw[dotted,very thin] (7,0) arc (0:70:7cm) node[anchor=south east]  {{\\tiny R=.7}};");
+	System.out.println("\\draw[dotted,very thin] (6,0) arc (0:73:6cm) node[anchor=south east]  {{\\tiny R=.6}};");
+	System.out.println("\\draw[dotted,very thin] (5,0) arc (0:76:5cm) node[anchor=south east] {{\\tiny R=.5}};");
+	System.out.println("\\draw[dotted,very thin] (4,0) arc (0:78:4cm) node[anchor=south east] {{\\tiny R=.4}};");
+	System.out.println("\\draw[dotted,very thin] (3,0) arc (0:80:3cm) node[anchor=south east] {{\\tiny R=.3}};");
+	System.out.println("\\draw[dotted,very thin] (2,0) arc (0:82:2cm) node[anchor=south east] {{\\tiny R=.2}};");
+	System.out.println("\\draw[dotted,very thin] (1,0) arc (0:84:1cm) node[anchor=south east] {{\\tiny R=.1}};");
+	System.out.println("%% Level lines for precision");
+	System.out.println("\\draw[dashed] (0,0) arc (180:120:10cm) node[anchor=south west] {{\\tiny P=1.}};");
+	System.out.println("\\draw[dotted,very thin] (1,0) arc (180:117:9cm) node[anchor=south west] {{\\tiny P=.9}};");
+	System.out.println("\\draw[dotted,very thin] (2,0) arc (180:114:8cm) node[anchor=south west] {{\\tiny P=.8}};");
+	System.out.println("\\draw[dotted,very thin] (3,0) arc (180:110:7cm) node[anchor=south west] {{\\tiny P=.7}};");
+	System.out.println("\\draw[dotted,very thin] (4,0) arc (180:107:6cm) node[anchor=south west] {{\\tiny P=.6}};");
+	System.out.println("\\draw[dotted,very thin] (5,0) arc (180:105:5cm) node[anchor=south west] {{\\tiny P=.5}};");
+	System.out.println("\\draw[dotted,very thin] (6,0) arc (180:103:4cm) node[anchor=south west] {{\\tiny P=.4}};");
+	System.out.println("\\draw[dotted,very thin] (7,0) arc (180:100:3cm) node[anchor=south west] {{\\tiny P=.3}};");
+	System.out.println("\\draw[dotted,very thin] (8,0) arc (180:96:2cm) node[anchor=south west] {{\\tiny P=.2}};");
+	System.out.println("\\draw[dotted,very thin] (9,0) arc (180:90:1cm) node[anchor=south west] {{\\tiny P=.1}};");
+	System.out.println("%% Level lines for F-measure");
+	System.out.println("\\draw[very thin,densely dotted] plot[smooth] coordinates { (0.56,3.29) (1.55,3.10) (2.46,2.68) (3.31,2.05) (4.12,1.19) (5.00,0.00) (6.42,1.79) (9.44,3.29)};");
+	System.out.println("\\draw (0.56,3.29) node[anchor=south west] {\\tiny{F=0.5}};");
+	System.out.println("\\draw[very thin,densely dotted] plot[smooth] coordinates { (0.92,4.19) (1.96,4.05) (2.95,3.78) (3.93,3.48) (5.00,3.32) (6.56,3.63) (9.08,4.19)};");
+	System.out.println("\\draw (0.92,4.19) node[anchor=south west] {\\tiny{F=0.6}};");
+	System.out.println("\\draw[very thin,densely dotted] plot[smooth] coordinates { (1.45,5.19) (2.59,5.11) (3.74,4.98) (5.00,4.90) (6.73,5.03) (8.55,5.19)};");
+	System.out.println("\\draw (1.45,5.19) node[anchor=south west] {\\tiny{F=0.7}};");
+	System.out.println("\\draw[very thin,densely dotted] plot[smooth] coordinates { (2.22,6.29) (3.54,6.27) (5.00,6.24) (6.91,6.28) (7.78,6.29)};");
+	System.out.println("\\draw (2.22,6.29) node[anchor=south west] {\\tiny{F=0.8}};");
+	System.out.println("\\draw[very thin,densely dotted] plot[smooth] coordinates { (3.35,7.47) (5.00,7.48) (6.65,7.47)};");
+	System.out.println("\\draw (3.35,7.47) node[anchor=south west] {\\tiny{F=0.9}};");
+
+	System.out.println("\\draw (0,-0.3) node {$recall$};");
+	System.out.println("\\draw (10,-0.3) node {$precision$};");
 	//System.out.println("\\draw (0,-0.3) node {0.}; ");
 	//System.out.println("\\draw (10,-0.3) node {1.}; ");
 	System.out.println("% Plots");
@@ -357,6 +396,105 @@ public class GroupEval {
 	System.out.println("\\end{document}");
     }
 
+    /*
+      // Here is the code provided by Christian Meilicke and modified by JE
+      // For computing the F-measure level line in the Triangle representation
+      // The class can be put in FMeasureLines.java and compiled.
+      // The same code (getPolarCoords) can be compiled to draw the line of a
+      // particular matcher on this same graph eventually.
+
+public class FMeasureLines {
+
+    // The step of the curve
+    private static double step = .1;
+
+    // Number of points found
+    private int counter = 0;
+	
+    public static void main(String[] args) {
+	new FMeasureLines().run();
+    }
+
+    public void run() {
+	for ( double i = .5; i < 1. ; i=i + .1 ) {
+	    printLaTeXCurve( i );
+	}
+    }
+
+    public void printLaTeXCurve( double f ) {
+	// create array of precision recall pairs for f-measure 0.6
+	double[][] fline = getFixedFLine( f );
+	
+	// create representation in polar coordinates for tikz inlcusion
+	double line[][] = getPolarCoords(fline);
+
+	System.out.print( "\\draw[very thin,dashed] plot[smooth] coordinates {" );
+	for ( int i = 0; i < counter ; i++ ) {
+	    if ( line[i] != null ) {
+		System.out.format( " (%.2f,%.2f)", 10*line[i][0], 10*line[i][1] );
+	    }
+	}
+	System.out.println( "};" );
+	System.out.format( "\\draw (%.2f,%.2f) node[anchor=south west] {\\tiny{F=%.1f}};\n", 10*line[0][0], 10*line[0][1], f );
+    }
+
+    // Compute the pair of points for a given F-Measure
+    public double[][] getFixedFLine( double f ) {
+	double[][] result = new double[(int)(2*(1/step+1))][2];
+	double pr = 1.;
+	counter = 0;
+	double p = getRGivenFAndP( f, pr );
+
+	while ( pr > 0. ) {
+	    if ( p >= 0. ) {
+		result[counter][0] = p;
+		result[counter][1] = pr;
+		counter++;
+		//System.err.println(" P / PR = "+p+" / "+pr );
+	    }
+	    pr -= step;
+	    p = getRGivenFAndP( f, pr );
+	}
+	result[counter][0] = 1.;
+	result[counter][1] = getRGivenFAndP( f, 1. );
+	//System.err.println(" P / PR = "+1.+" / "+getRGivenFAndP( f, 1. ) );
+	counter++;
+
+	return result;
+    }
+
+    // Provides the Recall given a particular F-measure and Precision
+    // F = 2PR/P+R
+    // => FP+FR = 2PR
+    // => FP = 2PR - FR
+    // => FP/R = 2P-F
+    // => R = FP/(2P-F)
+    // (same for P given the symmetry of the formula)
+    private static double getRGivenFAndP( double f, double p ) {
+	double r = p * f / (2 * p - f);
+	if ( r <= 0 || r >= 1.0 ) return -1.;
+	return r;
+    }
+
+    // Transforms all coordinates in polar coords
+    public double[][] getPolarCoords(double line[][]) {
+	double[][] result = new double[counter][2];
+	for ( int i = 0; i < counter; i++ ) {
+	    double ppair[] = getPolarCoord( line[i][0], line[i][1] );
+	    if ( ppair != null ) result[i] = ppair;
+	}	
+	return result;
+    }
+
+    // Transform the coordinates from P/R (cartesian) to ?? (polar)
+    private double[] getPolarCoord( double p, double r ) {
+	double pp = ((p * p) - (r * r) + 1) / 2;
+	double pr = Math.sqrt(Math.abs((p * p) - (pp * pp)));
+	return new double[]{pp, pr};
+    }
+}
+     */
+
     public void printLATEX( Vector result ) {
     }
 
-- 
GitLab