JAL-3205 faster calculation with symmetric score matrix
[jalview.git] / src / jalview / analysis / scoremodels / ScoreMatrix.java
index 6cdfacb..b206339 100644 (file)
@@ -99,6 +99,8 @@ public class ScoreMatrix extends SimilarityScoreModel
 
   private float maxValue;
 
+  private boolean symmetric;
+
   /**
    * Constructor given a name, symbol alphabet, and matrix of scores for pairs
    * of symbols. The matrix should be square and of the same size as the
@@ -156,6 +158,8 @@ public class ScoreMatrix extends SimilarityScoreModel
 
     findMinMax();
 
+    symmetric = checkSymmetry();
+
     /*
      * crude heuristic for now...
      */
@@ -163,6 +167,27 @@ public class ScoreMatrix extends SimilarityScoreModel
   }
 
   /**
+   * Answers true if the matrix is symmetric, else false. Usually, substitution
+   * matrices are symmetric, which allows calculations to be short cut.
+   * 
+   * @return
+   */
+  private boolean checkSymmetry()
+  {
+    for (int i = 0; i < matrix.length; i++)
+    {
+      for (int j = i; j < matrix.length; j++)
+      {
+        if (matrix[i][j] != matrix[j][i])
+        {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  /**
    * Record the minimum and maximum score values
    */
   protected void findMinMax()
@@ -457,14 +482,17 @@ public class ScoreMatrix extends SimilarityScoreModel
   protected MatrixI findSimilarities(String[] seqs,
           SimilarityParamsI params)
   {
-    double[][] values = new double[seqs.length][];
+    double[][] values = new double[seqs.length][seqs.length];
     for (int row = 0; row < seqs.length; row++)
     {
-      values[row] = new double[seqs.length];
-      for (int col = 0; col < seqs.length; col++)
+      for (int col = symmetric ? row : 0; col < seqs.length; col++)
       {
         double total = computeSimilarity(seqs[row], seqs[col], params);
         values[row][col] = total;
+        if (symmetric)
+        {
+          values[col][row] = total;
+        }
       }
     }
     return new Matrix(values);
@@ -592,4 +620,9 @@ public class ScoreMatrix extends SimilarityScoreModel
   {
     return this;
   }
+
+  public boolean isSymmetric()
+  {
+    return symmetric;
+  }
 }