From a82815eb0521c12ba25c8018a19d0e44a3c1ab12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr> Date: Thu, 15 Sep 2011 20:29:40 +0000 Subject: [PATCH] - Implemented extractss for ** alignments in DistanceAlignment (impl) - Changed default type of StringDistAlignment to "?*" for preserving the previous behaviour (impl) - Suppressed the guard for applying the Hungarian algorithm to equisimilarity situation (impl) - Fixed a bug on DistanceAlignment 1:1 extraction when the second ontology is larger than the first one (impl) - Added corresponding test --- html/relnotes.html | 14 +- .../exmo/align/impl/DistanceAlignment.java | 246 +++++++++++------- .../impl/method/StringDistAlignment.java | 13 +- test/src/MatcherTest.java | 130 ++++++++- 4 files changed, 306 insertions(+), 97 deletions(-) diff --git a/html/relnotes.html b/html/relnotes.html index 57665a9c..8f9c27c0 100644 --- a/html/relnotes.html +++ b/html/relnotes.html @@ -56,12 +56,24 @@ The development of 4 versions continues. <li>Add more tests</li> </ul></p> +<!-- NOTE FOR VERSION 5 +The default type of StringDistAlignment should be reverted to "**" +with a warning: +--> + <h2>Current SVN trunk version</h2> -<!--h2>Version 4.3 (): xx/xx/xxxx - Zimt</h2--> +<!--h2>Version 4.3 (): xx/xx/2011 - Zimt</h2--> <p><ul compact="1"> <li>Full reengineering of the test generator (gen)</li> +<li>Implemented <tt>extractss</tt> for ** alignments in <tt>DistanceAlignment</tt> (impl)</li> +<li>Changed default type of <tt>StringDistAlignment</tt> to "?*" for + preserving the previous behaviour (impl)</li> <li>Added level lines in the triangle display of <tt>GroupEval</tt> (util)</li> +<li>Suppressed the guard for applying the Hungarian algorithm to + equisimilarity situations (impl)</li> +<li>Fixed a bug on <tt>DistanceAlignment</tt> 1:1 extraction when the + second ontology is larger than the first one (impl)</li> </ul></p> <h2>Version 4.2 (1618): 31/05/2011 - Tring</h2> diff --git a/src/fr/inrialpes/exmo/align/impl/DistanceAlignment.java b/src/fr/inrialpes/exmo/align/impl/DistanceAlignment.java index 99864d18..76385ec7 100644 --- a/src/fr/inrialpes/exmo/align/impl/DistanceAlignment.java +++ b/src/fr/inrialpes/exmo/align/impl/DistanceAlignment.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2003-2010 + * Copyright (C) INRIA, 2003-2011 * * 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 @@ -138,16 +138,17 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align if ( type.equals("?*") || type.equals("1*") || type.equals("?+") || type.equals("1+") ) return extractqs( threshold, params ); else if ( type.equals("??") || type.equals("1?") || type.equals("?1") || type.equals("11") ) return extractqq( threshold, params ); else if ( type.equals("*?") || type.equals("+?") || type.equals("*1") || type.equals("+1") ) return extractqs( threshold, params ); - else if ( type.equals("**") || type.equals("+*") || type.equals("*+") || type.equals("++") ) return extractqs( threshold, params ); + else if ( type.equals("**") || type.equals("+*") || type.equals("*+") || type.equals("++") ) return extractss( threshold, params ); // The else should be an error message else throw new AlignmentException("Unknown alignment type: "+type); } - // JE: It is now certainly possible to virtualise extraction has it has + // JE: It is now certainly possible to virtualise extraction as it has // been done for printing matrix in MatrixMeasure (todo) /** * Extract the alignment of a ?* type + * Non symmetric: for each entity of onto1, take the highest if superior to threshold * Complexity: O(n^2) */ @SuppressWarnings("unchecked") //ConcatenatedIterator @@ -169,7 +170,7 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align ontology2().getDataProperties().iterator()); for ( Object current : pit2 ){ if ( sim.getSimilarity() ) val = sim.getPropertySimilarity(prop1,current); - else val = 1 - sim.getPropertySimilarity(prop1,current); + else val = 1. - sim.getPropertySimilarity(prop1,current); if ( val > max) { found = true; max = val; prop2 = current; } @@ -182,7 +183,7 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align Object class2 = null; for ( Object current : ontology2().getClasses() ) { if ( sim.getSimilarity() ) val = sim.getClassSimilarity(class1,current); - else val = 1 - sim.getClassSimilarity(class1,current); + else val = 1. - sim.getClassSimilarity(class1,current); if (val > max) { found = true; max = val; class2 = current; } @@ -213,10 +214,64 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align return((Alignment)this); } + /** + * Extract the alignment of a ** type + * Symmetric: return all elements above threshold + * Complexity: O(n^2) + */ + @SuppressWarnings("unchecked") //ConcatenatedIterator + public Alignment extractss( double threshold, Properties params) { + double val = 0.; + try { + // Extract for properties + ConcatenatedIterator pit1 = new + ConcatenatedIterator(ontology1().getObjectProperties().iterator(), + ontology1().getDataProperties().iterator()); + for( Object prop1 : pit1 ){ + ConcatenatedIterator pit2 = new + ConcatenatedIterator(ontology2().getObjectProperties().iterator(), + ontology2().getDataProperties().iterator()); + for ( Object prop2 : pit2 ){ + if ( sim.getSimilarity() ) val = sim.getPropertySimilarity(prop1,prop2); + else val = 1. - sim.getPropertySimilarity(prop1,prop2); + if ( val > threshold ) addAlignCell(prop1,prop2, "=", val); + } + } + // Extract for classes + for ( Object class1 : ontology1().getClasses() ) { + for ( Object class2 : ontology2().getClasses() ) { + if ( sim.getSimilarity() ) val = sim.getClassSimilarity(class1,class2); + else val = 1. - sim.getClassSimilarity(class1,class2); + if (val > threshold ) addAlignCell(class1, class2, "=", val); + } + } + // Extract for individuals + if ( params.getProperty("noinst") == null ){ + for ( Object ind1 : ontology1().getIndividuals() ) { + if ( ontology1().getEntityURI( ind1 ) != null ) { + for ( Object ind2 : ontology2().getIndividuals() ) { + if ( ontology2().getEntityURI( ind2 ) != null ) { + if ( sim.getSimilarity() ) val = sim.getIndividualSimilarity( ind1, ind2 ); + else val = 1 - sim.getIndividualSimilarity( ind1, ind2 ); + if ( val > threshold ) addAlignCell(ind1,ind2, "=", val); + } + } + } + } + } + } catch (OntowrapException owex) { owex.printStackTrace(); //} + } catch (AlignmentException alex) { alex.printStackTrace(); } + return((Alignment)this); + } + /** * Extract the alignment of a ?? type * - * exact algorithm using the Hungarian method + * exact algorithm using the Hungarian method. + * This algorithm contains several guards to prevent the HungarianAlgorithm to + * raise problems: + * - It invert column and rows when nbrows > nbcol (Hungarian loops) + * - It prevents to generate alignments when one category has no elements. */ @SuppressWarnings("unchecked") //ConcatenatedIterator public Alignment extractqq( double threshold, Properties params) { @@ -227,29 +282,26 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align // Create a matrix int nbclasses1 = ontology1().nbClasses(); int nbclasses2 = ontology2().nbClasses(); - double[][] matrix = new double[nbclasses1][nbclasses2]; - Object[] class1 = new Object[nbclasses1]; - Object[] class2 = new Object[nbclasses2]; - int i = 0; - for ( Object ob : ontology1().getClasses() ) { - class1[i++] = ob; - } - int j = 0; - for ( Object ob : ontology2().getClasses() ) { - class2[j++] = ob; - } - // ival indicates if all cells have the same value, or different (-1) - double ival = sim.getClassSimilarity(class1[0],class2[0]); - for( i = 0; i < nbclasses1; i++ ){ - for( j = 0; j < nbclasses2; j++ ){ - if ( ival != -1. && ival != sim.getClassSimilarity(class1[i],class2[j] ) ) ival = -1.; - if ( sim.getSimilarity() ) matrix[i][j] = sim.getClassSimilarity(class1[i],class2[j]); - else matrix[i][j] = 1 - sim.getClassSimilarity(class1[i],class2[j]); + if ( nbclasses1 != 0 && nbclasses2 != 0 ) { + double[][] matrix = new double[nbclasses1][nbclasses2]; + Object[] class1 = new Object[nbclasses1]; + Object[] class2 = new Object[nbclasses2]; + int i = 0; + for ( Object ob : ontology1().getClasses() ) { + class1[i++] = ob; } - } - // Pass it to the algorithm - if ( ival == -1. ) { // if values are the same, return an empty alignment - int[][] result = HungarianAlgorithm.hgAlgorithm( matrix, "max" ); + int j = 0; + for ( Object ob : ontology2().getClasses() ) { + class2[j++] = ob; + } + for( i = 0; i < nbclasses1; i++ ){ + for( j = 0; j < nbclasses2; j++ ){ + if ( sim.getSimilarity() ) matrix[i][j] = sim.getClassSimilarity(class1[i],class2[j]); + else matrix[i][j] = 1. - sim.getClassSimilarity(class1[i],class2[j]); + } + } + // Pass it to the algorithm + int[][] result = callHungarianMethod( matrix, nbclasses1, nbclasses2 ); // Extract the result for( i=0; i < result.length ; i++ ){ // The matrix has been destroyed @@ -264,56 +316,53 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align } } } - } catch (AlignmentException alex) { alex.printStackTrace(); } - catch (OntowrapException owex) { owex.printStackTrace(); } + } catch ( AlignmentException alex) { alex.printStackTrace(); } + catch ( OntowrapException owex) { owex.printStackTrace(); } // For properties try{ int nbprop1 = ontology1().nbProperties(); int nbprop2 = ontology2().nbProperties(); - double[][] matrix = new double[nbprop1][nbprop2]; - Object[] prop1 = new Object[nbprop1]; - Object[] prop2 = new Object[nbprop2]; - int i = 0; - ConcatenatedIterator pit1 = new - ConcatenatedIterator(ontology1().getObjectProperties().iterator(), - ontology1().getDataProperties().iterator()); - for ( Object ob: pit1 ) prop1[i++] = ob; - int j = 0; - ConcatenatedIterator pit2 = new - ConcatenatedIterator(ontology2().getObjectProperties().iterator(), - ontology2().getDataProperties().iterator()); - for ( Object ob: pit2 ) prop2[j++] = ob; - double ival = sim.getPropertySimilarity(prop1[0],prop2[0]); - for( i = 0; i < nbprop1; i++ ){ - for( j = 0; j < nbprop2; j++ ){ - if ( ival != -1. && ival != sim.getPropertySimilarity(prop1[i],prop2[j] ) ) ival = -1.; - if ( sim.getSimilarity() ) matrix[i][j] = sim.getPropertySimilarity(prop1[i],prop2[j]); - else - matrix[i][j] = 1 - sim.getPropertySimilarity(prop1[i],prop2[j]); + if ( nbprop1 != 0 && nbprop2 != 0 ) { + double[][] matrix = new double[nbprop1][nbprop2]; + Object[] prop1 = new Object[nbprop1]; + Object[] prop2 = new Object[nbprop2]; + int i = 0; + ConcatenatedIterator pit1 = new + ConcatenatedIterator(ontology1().getObjectProperties().iterator(), + ontology1().getDataProperties().iterator()); + for ( Object ob: pit1 ) prop1[i++] = ob; + int j = 0; + ConcatenatedIterator pit2 = new + ConcatenatedIterator(ontology2().getObjectProperties().iterator(), + ontology2().getDataProperties().iterator()); + for ( Object ob: pit2 ) prop2[j++] = ob; + for( i = 0; i < nbprop1; i++ ){ + for( j = 0; j < nbprop2; j++ ){ + if ( sim.getSimilarity() ) matrix[i][j] = sim.getPropertySimilarity(prop1[i],prop2[j]); + else matrix[i][j] = 1. - sim.getPropertySimilarity(prop1[i],prop2[j]); + } } - } - // Pass it to the algorithm - if ( ival == -1. ) { - int[][] result = HungarianAlgorithm.hgAlgorithm( matrix, "max" ); - // Extract the result - for( i=0; i < result.length ; i++ ){ - // The matrix has been destroyed - double val; - if ( sim.getSimilarity() ) val = sim.getPropertySimilarity(prop1[result[i][0]],prop2[result[i][1]]); - else val = 1 - sim.getPropertySimilarity(prop1[result[i][0]],prop2[result[i][1]]); - // JE: here using strict-> is a very good idea. - // it means that alignments with 0. similarity - // will be excluded from the best match. - if( val > threshold ){ - addCell( new ObjectCell( (String)null, prop1[result[i][0]], prop2[result[i][1]], BasicRelation.createRelation("="), val ) ); + // Pass it to the algorithm + int[][] result = callHungarianMethod( matrix, nbprop1, nbprop2 ); + // Extract the result + for( i=0; i < result.length ; i++ ){ + // The matrix has been destroyed + double val; + if ( sim.getSimilarity() ) val = sim.getPropertySimilarity(prop1[result[i][0]],prop2[result[i][1]]); + else val = 1 - sim.getPropertySimilarity(prop1[result[i][0]],prop2[result[i][1]]); + // JE: here using strict-> is a very good idea. + // it means that alignments with 0. similarity + // will be excluded from the best match. + if( val > threshold ){ + addCell( new ObjectCell( (String)null, prop1[result[i][0]], prop2[result[i][1]], BasicRelation.createRelation("="), val ) ); + } } } - } } catch (AlignmentException alex) { alex.printStackTrace(); } catch (OntowrapException owex) { owex.printStackTrace(); } // For individuals if ( params.getProperty("noinst") == null ){ - try{ + try { // Create individual lists Object[] ind1 = new Object[ontology1().nbIndividuals()]; Object[] ind2 = new Object[ontology2().nbIndividuals()]; @@ -331,40 +380,53 @@ public abstract class DistanceAlignment extends ObjectAlignment implements Align ind1[nbind1++] = ob; } } - double[][] matrix = new double[nbind1][nbind2]; - int i, j; - double ival = sim.getIndividualSimilarity(ind1[0],ind2[0]); - for( i=0; i < nbind1; i++ ){ - for( j=0; j < nbind2; j++ ){ - if ( ival != -1. && ival != sim.getIndividualSimilarity(ind1[i],ind2[j] ) ) ival = -1.; - if ( sim.getSimilarity() ) matrix[i][j] = sim.getIndividualSimilarity(ind1[i],ind2[j]); - else - matrix[i][j] = 1 - sim.getIndividualSimilarity(ind1[i],ind2[j]); + if ( nbind1 != 0 && nbind2 != 0 ) { + double[][] matrix = new double[nbind1][nbind2]; + int i, j; + for( i=0; i < nbind1; i++ ){ + for( j=0; j < nbind2; j++ ){ + if ( sim.getSimilarity() ) matrix[i][j] = sim.getIndividualSimilarity(ind1[i],ind2[j]); + else matrix[i][j] = 1 - sim.getIndividualSimilarity(ind1[i],ind2[j]); + } } - } - // Pass it to the algorithm - if ( ival == -1. ) { - int[][] result = HungarianAlgorithm.hgAlgorithm( matrix, "max" ); - // Extract the result - for( i=0; i < result.length ; i++ ){ - // The matrix has been destroyed - double val; - if ( sim.getSimilarity() ) val = sim.getIndividualSimilarity(ind1[result[i][0]],ind2[result[i][1]]); - else val = 1 - sim.getIndividualSimilarity(ind1[result[i][0]],ind2[result[i][1]]); - // JE: here using strict-> is a very good idea. - // it means that alignments with 0. similarity - // will be excluded from the best match. - if( val > threshold ){ - addCell( new ObjectCell( (String)null, ind1[result[i][0]], ind2[result[i][1]], BasicRelation.createRelation("="), val ) ); + // Pass it to the algorithm + int[][] result = callHungarianMethod( matrix, nbind1, nbind2 ); + // Extract the result + for( i=0; i < result.length ; i++ ){ + // The matrix has been destroyed + double val; + if ( sim.getSimilarity() ) val = sim.getIndividualSimilarity(ind1[result[i][0]],ind2[result[i][1]]); + else val = 1 - sim.getIndividualSimilarity(ind1[result[i][0]],ind2[result[i][1]]); + // JE: here using strict-> is a very good idea. + // it means that alignments with 0. similarity + // will be excluded from the best match. + if( val > threshold ){ + addCell( new ObjectCell( (String)null, ind1[result[i][0]], ind2[result[i][1]], BasicRelation.createRelation("="), val ) ); + } } } - } } catch (AlignmentException alex) { alex.printStackTrace(); //} } catch (OntowrapException owex) { owex.printStackTrace(); } } return((Alignment)this); } + public int[][] callHungarianMethod( double[][] matrix, int i, int j ) { + boolean transposed = false; + if ( i > j ) { // transposed aray (because rows>columns). + matrix = HungarianAlgorithm.transpose(matrix); + transposed = true; + } + int[][] result = HungarianAlgorithm.hgAlgorithm( matrix, "max" ); + if ( transposed ) { + for( int k=0; k < result.length ; k++ ) { + int val = result[k][0]; result[k][0] = result[k][1]; result[k][1] = val; + } + + } + return result; + } + /** * Greedy algorithm: * 1) dump the part of the matrix distance above threshold in a sorted set diff --git a/src/fr/inrialpes/exmo/align/impl/method/StringDistAlignment.java b/src/fr/inrialpes/exmo/align/impl/method/StringDistAlignment.java index e9ad98c8..39dc7813 100644 --- a/src/fr/inrialpes/exmo/align/impl/method/StringDistAlignment.java +++ b/src/fr/inrialpes/exmo/align/impl/method/StringDistAlignment.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2003-2010 + * Copyright (C) INRIA, 2003-2011 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -80,10 +80,17 @@ public class StringDistAlignment extends DistanceAlignment implements AlignmentP } } - /** Creation **/ + /** + * Creation + * (4.3) For compatibility reason with previous versions, the type is set to + * "?*" so that the behaviour is the same. + * In future version (5.0), this should be reverted to "**", + * so the extractors will behave differently + **/ public StringDistAlignment() { setSimilarity( new StringDistMatrixMeasure() ); - setType("**"); + setType("?*"); + //setType("11"); } /* Processing */ diff --git a/test/src/MatcherTest.java b/test/src/MatcherTest.java index 4eefd406..f38f2dac 100644 --- a/test/src/MatcherTest.java +++ b/test/src/MatcherTest.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2008-2010 + * Copyright (C) INRIA, 2008-2011 * * 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 @@ -34,9 +34,11 @@ import org.semanticweb.owl.align.AlignmentException; import org.semanticweb.owl.align.AlignmentProcess; import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.Evaluator; +import org.semanticweb.owl.align.Cell; import fr.inrialpes.exmo.align.impl.renderer.RDFRendererVisitor; import fr.inrialpes.exmo.align.impl.method.StringDistAlignment; +import fr.inrialpes.exmo.align.impl.MatrixMeasure; import fr.inrialpes.exmo.ontosim.string.StringDistances; import fr.inrialpes.exmo.align.impl.eval.PRecEvaluator; import fr.inrialpes.exmo.align.impl.URIAlignment; @@ -117,4 +119,130 @@ $ java -jar lib/Procalign.jar file://$CWD/examples/rdf/edu.umbc.ebiquity.publica alignment.init( new URI("file:examples/rdf/edu.umbc.ebiquity.publication.owl"), new URI("file:examples/rdf/edu.mit.visus.bibtex.owl")); alignment.align( (Alignment)null, params ); } + + /* This tests an errors in extraction methods (Hungarian method) */ + @Test(groups = { "full", "impl", "raw" }) + public void hungarianExtractionTest() throws Exception { + StringDistAlignment dal = new StringDistAlignment(); + dal.init( new URI("file:examples/rdf/edu.umbc.ebiquity.publication.owl"), new URI("file:examples/rdf/edu.mit.visus.bibtex.owl") ); + assertEquals( dal.nbCells(), 0 ); + // Extract with nothing + Properties params = new Properties(); + params.setProperty( "noinst", "1" ); + dal.align( (Alignment)null, params ); // This initialises the matrix + assertEquals( dal.nbCells(), 10 ); + // ****CLASSICAL EXTRACTIONS**** + // Test ** extraction + for ( Cell c : dal ) { dal.removeAlignCell( c ); } + dal.extractqs( 0., params ); + assertEquals( dal.nbCells(), 10 ); + // Test 11 extraction + for ( Cell c : dal ) { dal.removeAlignCell( c ); } + dal.extractqq( 0., params ); + assertEquals( dal.nbCells(), 10 ); + for ( Cell c : dal ) { dal.removeAlignCell( c ); } + dal.extractqqgreedy( 0., params ); + assertEquals( dal.nbCells(), 10 ); + // ****ZERO'ED ALIGNMENT**** + // Do it with only one cell... (all 0. but 1) + MatrixMeasure mm = (MatrixMeasure)dal.getSimilarity(); + for ( int i = mm.nbclass1-1; i >= 0; i-- ) { + for ( int j = mm.nbclass2-1; j >= 0; j-- ) { + mm.clmatrix[i][j] = 1.; // this is a distance... + } + } + // Useless + for ( int i = mm.nbprop1-1; i >= 0; i-- ) { + for ( int j = mm.nbprop2-1; j >= 0; j-- ) { + mm.prmatrix[i][j] = 1.; // distance... + } + } + //dal.printDistanceMatrix( params ); + // Test ** extraction + for ( Cell c : dal ) { dal.removeAlignCell( c ); } + //printAlignment( dal ); + dal.extractqs( 0., params ); + assertEquals( dal.nbCells(), 0 ); + for ( Cell c : dal ) { dal.removeAlignCell( c ); } + dal.extractqs( 1., params ); + assertEquals( dal.nbCells(), 0 ); + // Test 11 extraction + for ( Cell c : dal ) { dal.removeAlignCell( c ); } + dal.extractqq( 0., params ); + assertEquals( dal.nbCells(), 0 ); + for ( Cell c : dal ) { dal.removeAlignCell( c ); } + dal.extractqqgreedy( 0., params ); + assertEquals( dal.nbCells(), 0 ); + // ****ADDED ONE EXPECTED CORRESPONDENCE**** + // Do it with only one cell... (all 0. but 1) + mm.clmatrix[5][5] = .5; + // Test ** extraction + for ( Cell c : dal ) { dal.removeAlignCell( c ); } + //printAlignment( dal ); + dal.extractqs( 0., params ); + assertEquals( dal.nbCells(), 1 ); + // ******** TEST THIS ******* + //for ( Cell c : dal ) { dal.removeAlignCell( c ); } + //dal.extractqs( .6, params ); + //assertEquals( dal.nbCells(), 0 ); + // Test 11 extraction + for ( Cell c : dal ) { dal.removeAlignCell( c ); } + dal.extractqq( 0., params ); + assertEquals( dal.nbCells(), 1 ); + for ( Cell c : dal ) { dal.removeAlignCell( c ); } + dal.extractqqgreedy( 0., params ); + assertEquals( dal.nbCells(), 1 ); + // ****ADDED ONE EXPECTED CORRESPONDENCE**** + // Do it with only one cell... (all 0. but 1) + mm.clmatrix[5][8] = .5; + mm.clmatrix[8][8] = .5; + mm.clmatrix[8][5] = .5; + // Test ** extraction + for ( Cell c : dal ) { dal.removeAlignCell( c ); } + //printAlignment( dal ); + dal.extractqs( 0., params ); + assertEquals( dal.nbCells(), 2 ); + // ******** TEST THIS ******* + //for ( Cell c : dal ) { dal.removeAlignCell( c ); } + //dal.extractqs( .6, params ); + //assertEquals( dal.nbCells(), 0 ); + // Test 11 extraction + for ( Cell c : dal ) { dal.removeAlignCell( c ); } + dal.extractqq( 0., params ); + assertEquals( dal.nbCells(), 2 ); + for ( Cell c : dal ) { dal.removeAlignCell( c ); } + dal.extractqqgreedy( 0., params ); + assertEquals( dal.nbCells(), 2 ); + } + + /* This identifies a very specific bug in the Hungarian algorithm when: + * class2 < class1 + * a subset of class2 is matched with a subset of class1 + * In a simple 0/1 alignment + */ + @Test(groups = { "full", "impl", "raw" }, dependsOnMethods = { "hungarianExtractionTest" }) + public void naughtyHungarianExtractionTest() throws Exception { + StringDistAlignment dal = new StringDistAlignment(); + dal.init( new URI("file:examples/rdf/edu.mit.visus.bibtex.owl"), new URI("file:examples/rdf/edu.umbc.ebiquity.publication.owl")); + assertEquals( dal.nbCells(), 0 ); + // Extract with nothing + Properties params = new Properties(); + params.setProperty( "noinst", "1" ); + dal.align( (Alignment)null, params ); // This initialises the matrix + assertEquals( dal.nbCells(), 10 ); + // Test 11 extraction + for ( Cell c : dal ) { dal.removeAlignCell( c ); } + dal.extractqq( 0., params ); + assertEquals( dal.nbCells(), 10 ); // **** java.lang.ArrayIndexOutOfBoundsException: 0 + } + + + public void printAlignment( Alignment dal ) { + try { + for ( Cell c : dal ) { + System.err.println( "< "+c.getObject1AsURI(dal).getFragment()+" "+c.getRelation()+" "+c.getObject1AsURI(dal).getFragment()+" / "+c.getStrength() ); + } + } catch (Exception e) {} + } + } -- GitLab