JAL-629 Change all stdout and stderr output to use Console.outPrintln and Console...
[jalview.git] / src / jalview / analysis / scoremodels / ScoreMatrix.java
index 9bec6e4..aa841ac 100644 (file)
@@ -20,7 +20,9 @@
  */
 package jalview.analysis.scoremodels;
 
+import jalview.api.AlignmentViewPanel;
 import jalview.api.analysis.PairwiseScoreModelI;
+import jalview.api.analysis.ScoreModelI;
 import jalview.api.analysis.SimilarityParamsI;
 import jalview.datamodel.AlignmentView;
 import jalview.math.Matrix;
@@ -31,10 +33,11 @@ import java.util.Arrays;
 
 /**
  * A class that models a substitution score matrix for any given alphabet of
- * symbols. Instances of this class are immutable and thread-safe.
+ * symbols. Instances of this class are immutable and thread-safe, so the same
+ * object is returned from calls to getInstance().
  */
-public class ScoreMatrix extends SimilarityScoreModel implements
-        PairwiseScoreModelI
+public class ScoreMatrix extends SimilarityScoreModel
+        implements PairwiseScoreModelI
 {
   private static final char GAP_CHARACTER = Comparison.GAP_DASH;
 
@@ -95,7 +98,9 @@ public class ScoreMatrix extends SimilarityScoreModel implements
   private float minValue;
 
   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
@@ -127,8 +132,8 @@ public class ScoreMatrix extends SimilarityScoreModel implements
    * @param values
    *          Pairwise scores indexed according to the symbol alphabet
    */
-  public ScoreMatrix(String theName, String theDescription,
-          char[] alphabet, float[][] values)
+  public ScoreMatrix(String theName, String theDescription, char[] alphabet,
+          float[][] values)
   {
     if (alphabet.length != values.length)
     {
@@ -153,6 +158,8 @@ public class ScoreMatrix extends SimilarityScoreModel implements
 
     findMinMax();
 
+    symmetric = checkSymmetry();
+
     /*
      * crude heuristic for now...
      */
@@ -160,6 +167,27 @@ public class ScoreMatrix extends SimilarityScoreModel implements
   }
 
   /**
+   * 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()
@@ -303,12 +331,12 @@ public class ScoreMatrix extends SimilarityScoreModel implements
   {
     if (c >= symbolIndex.length)
     {
-      System.err.println(String.format(BAD_ASCII_ERROR, c));
+      jalview.bin.Console.errPrintln(String.format(BAD_ASCII_ERROR, c));
       return 0;
     }
     if (d >= symbolIndex.length)
     {
-      System.err.println(String.format(BAD_ASCII_ERROR, d));
+      jalview.bin.Console.errPrintln(String.format(BAD_ASCII_ERROR, d));
       return 0;
     }
 
@@ -451,16 +479,20 @@ public class ScoreMatrix extends SimilarityScoreModel implements
    * @param params
    * @return
    */
-  protected MatrixI findSimilarities(String[] seqs, SimilarityParamsI params)
+  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);
@@ -582,4 +614,15 @@ public class ScoreMatrix extends SimilarityScoreModel implements
   {
     return maxValue;
   }
+
+  @Override
+  public ScoreModelI getInstance(AlignmentViewPanel avp)
+  {
+    return this;
+  }
+
+  public boolean isSymmetric()
+  {
+    return symmetric;
+  }
 }