JAL-3205 worked examples in unit test for symmetric/asymmetric matrix
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 4 Mar 2019 09:19:22 +0000 (09:19 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 4 Mar 2019 09:19:22 +0000 (09:19 +0000)
test/jalview/analysis/scoremodels/ScoreMatrixTest.java

index 669c452..90a718a 100644 (file)
@@ -13,6 +13,7 @@ import jalview.api.analysis.SimilarityParamsI;
 import jalview.io.DataSourceType;
 import jalview.io.FileParse;
 import jalview.io.ScoreMatrixFile;
+import jalview.math.Matrix;
 import jalview.math.MatrixI;
 import jalview.schemes.ResidueProperties;
 
@@ -398,6 +399,12 @@ public class ScoreMatrixTest
     verifySymmetric(ScoreModels.getInstance().getDefaultModel(false)); // dna
   }
 
+  /**
+   * A helper method that inspects a loaded matrix and reports any asymmetry as
+   * a test failure
+   * 
+   * @param sm
+   */
   private void verifySymmetric(ScoreMatrix sm)
   {
     float[][] m = sm.getMatrix();
@@ -592,29 +599,73 @@ public class ScoreMatrixTest
   @Test(groups = "Functional")
   public void testIsSymmetric()
   {
-    float[][] scores = new float[2][];
-    scores[0] = new float[] { 1f, -2f };
-    scores[1] = new float[] { -2f, 1f };
+    float[][] scores = new float[][] { { 1f, -2f }, { -2f, 3f } };
     ScoreMatrix sm = new ScoreMatrix("Test", "AB".toCharArray(), scores);
     assertTrue(sm.isSymmetric());
 
-    scores[1] = new float[] { 2f, 1f };
+    /*
+     * verify that with a symmetric score matrix,
+     * pairwise similarity matrix is also symmetric
+     * seq1.seq1 = 5*A.A + 3*B.B = 5+9 = 14
+     * seq1.seq2 = 3*A.A + 2*A.B + B.A + 2*B.B = 3 + -4 + -2 + 6 = 3
+     * seq2.seq1 = 3*A.A + A.B + 2*B.A + 2*B.B = 3 + -2 + -4 + 6 = 3   
+     * seq2.seq2 = 4*A.A + 4*B.B = 4 + 12 = 16   
+     */
+    SimilarityParamsI params = new SimilarityParams(true, true, true,
+            false);
+    String seq1 = "AAABBBAA";
+    String seq2 = "AABBABBA";
+    String[] seqs1 = new String[] { seq1, seq2 };
+    MatrixI res1 = sm.findSimilarities(seqs1, params);
+    assertEquals(res1,
+            new Matrix(new double[][]
+            { { 14d, 3d }, { 3d, 16d } }));
+
+    /*
+     * order of sequences affects diagonal, but not off-diagonal values
+     * [0, 0] is now seq2.seq2, [1, 1] is seq1.seq1
+     * [0, 1] is now seq2.seq1 = seq1.seq2 by symmetry
+     */
+    String[] seqs2 = new String[] { seq2, seq1 };
+    MatrixI res2 = sm.findSimilarities(seqs2, params);
+    assertFalse(res1.equals(res2));
+    assertEquals(res2,
+            new Matrix(new double[][]
+            { { 16d, 3d }, { 3d, 14d } }));
+
+    /*
+     * now make the score matrix asymmetric
+     * seq1.seq1 = 5*A.A + 3*B.B = 5+9 = 14
+     * seq1.seq2 = 3*A.A + 2*A.B + B.A + 2*B.B = 3 + -4 + 2 + 6 = 7
+     * seq2.seq1 = 3*A.A + A.B + 2*B.A + 2*B.B = 3 + -2 + 4 + 6 = 11  
+     * seq2.seq2 = 4*A.A + 4*B.B = 4 + 12 = 16   
+     */
+    scores = new float[][] { { 1f, -2f }, { 2f, 3f } };
     sm = new ScoreMatrix("Test", "AB".toCharArray(), scores);
-    assertFalse(sm.isSymmetric());
+    assertFalse(sm.isSymmetric()); // [0, 1] != [1, 0]
+    res1 = sm.findSimilarities(seqs1, params);
+    assertEquals(res1,
+            new Matrix(new double[][]
+            { { 14d, 7d }, { 11d, 16d } }));
+
+    /*
+     * reverse order of sequences
+     * - reverses order of main diagonal
+     * - reflects off-diagonal values
+     */
+    res2 = sm.findSimilarities(seqs2, params);
+    assertFalse(res1.equals(res2));
+    assertEquals(res2,
+            new Matrix(new double[][]
+            { { 16d, 11d }, { 7d, 14d } }));
 
     /*
      * verify that forcing an asymmetric matrix to use
      * symmetric calculation gives a different (wrong) result
      */
-    SimilarityParamsI params = new SimilarityParams(true, true, true,
-            false);
-    String[] seqs = new String[] { "AAABBBAA", "AABBABBA" };
-    MatrixI res1 = sm.findSimilarities(seqs, params);
-    MatrixI res2 = sm.findSimilarities(seqs, params);
-    assertTrue(res1.equals(res2));
     PA.setValue(sm, "symmetric", true);
     assertTrue(sm.isSymmetric()); // it's not true!
-    res2 = sm.findSimilarities(seqs, params);
+    res2 = sm.findSimilarities(seqs1, params);
     assertFalse(res1.equals(res2));
   }
 }