import jalview.io.DataSourceType;
import jalview.io.FileParse;
import jalview.io.ScoreMatrixFile;
+import jalview.math.Matrix;
import jalview.math.MatrixI;
import jalview.schemes.ResidueProperties;
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();
@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));
}
}