X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjalview%2Fmath%2FMatrix.java;h=647fc3ad082db043ca3b4d24112a1dfc0c3c8bd1;hb=ee1ce9d286ce8ec18238b74f1cbb19af63b66a7a;hp=4722c1a2fac227c93de121f3d2accfc8693f2676;hpb=d423f22792e47dbc800ae220a58677f988971d06;p=jalview.git
diff --git a/src/jalview/math/Matrix.java b/src/jalview/math/Matrix.java
index 4722c1a..647fc3a 100755
--- a/src/jalview/math/Matrix.java
+++ b/src/jalview/math/Matrix.java
@@ -1,43 +1,48 @@
/*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
- * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
*
* This file is part of Jalview.
*
* Jalview is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
* Jalview is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along with Jalview. If not, see
+ * new Matrix(new double[][] {{2, 3, 4}, {5, 6, 7}) + * constructs + * (2 3 4) + * (5 6 7) + *+ * + * Note that ragged arrays (with not all rows, or columns, of the same + * length), are not supported by this class. They can be constructed, but + * results of operations on them are undefined and may throw exceptions. + * + * @param values + * the matrix values in row-major order + */ + public Matrix(double[][] values) { - this.rows = rows; - this.cols = cols; - this.value = value; + this.rows = values.length; + this.cols = this.rows == 0 ? 0 : values[0].length; + this.value = values; } /** - * DOCUMENT ME! + * Returns a new matrix which is the transposes of this one * * @return DOCUMENT ME! */ @@ -80,7 +98,7 @@ public class Matrix } } - return new Matrix(out, cols, rows); + return new Matrix(out); } /** @@ -103,15 +121,24 @@ public class Matrix } /** - * DOCUMENT ME! + * Returns a new matrix which is the result of premultiplying this matrix by + * the supplied argument. If this of size AxB (A rows and B columns), and the + * argument is CxA (C rows and A columns), the result is of size CxB. * * @param in - * DOCUMENT ME! * - * @return DOCUMENT ME! + * @return + * @throws IllegalArgumentException + * if the number of columns in the pre-multiplier is not equal to + * the number of rows in the multiplicand (this) */ public Matrix preMultiply(Matrix in) { + if (in.cols != this.rows) + { + throw new IllegalArgumentException("Can't pre-multiply " + this.rows + + " rows by " + in.cols + " columns"); + } double[][] tmp = new double[in.rows][this.cols]; for (int i = 0; i < in.rows; i++) @@ -127,16 +154,14 @@ public class Matrix } } - return new Matrix(tmp, in.rows, this.cols); + return new Matrix(tmp); } /** - * DOCUMENT ME! * * @param in - * DOCUMENT ME! * - * @return DOCUMENT ME! + * @return */ public double[] vectorPostMultiply(double[] in) { @@ -156,37 +181,34 @@ public class Matrix } /** - * DOCUMENT ME! + * Returns a new matrix which is the result of postmultiplying this matrix by + * the supplied argument. If this of size AxB (A rows and B columns), and the + * argument is BxC (B rows and C columns), the result is of size AxC. + *
+ * This method simply returns the result of in.preMultiply(this) * * @param in - * DOCUMENT ME! * - * @return DOCUMENT ME! + * @return + * @throws IllegalArgumentException + * if the number of rows in the post-multiplier is not equal to the + * number of columns in the multiplicand (this) + * @see #preMultiply(Matrix) */ public Matrix postMultiply(Matrix in) { - double[][] out = new double[this.rows][in.cols]; - - for (int i = 0; i < this.rows; i++) + if (in.rows != this.cols) { - for (int j = 0; j < in.cols; j++) - { - out[i][j] = 0.0; - - for (int k = 0; k < rows; k++) - { - out[i][j] = out[i][j] + (value[i][k] * in.value[k][j]); - } - } + throw new IllegalArgumentException("Can't post-multiply " + this.cols + + " columns by " + in.rows + " rows"); } - - return new Matrix(out, this.cols, in.rows); + return in.preMultiply(this); } /** - * DOCUMENT ME! + * Answers a new matrix with a copy of the values in this one * - * @return DOCUMENT ME! + * @return */ public Matrix copy() { @@ -194,13 +216,10 @@ public class Matrix for (int i = 0; i < rows; i++) { - for (int j = 0; j < cols; j++) - { - newmat[i][j] = value[i][j]; - } + System.arraycopy(value[i], 0, newmat[i], 0, value[i].length); } - return new Matrix(newmat, rows, cols); + return new Matrix(newmat); } /** @@ -345,7 +364,7 @@ public class Matrix /** * DOCUMENT ME! */ - public void tqli() + public void tqli() throws Exception { int n = rows; @@ -392,10 +411,11 @@ public class Matrix { iter++; - if (iter == 30) + if (iter == maxIter) { - System.err.print("Too many iterations in tqli"); - System.exit(0); // JBPNote - should this really be here ??? + throw new Exception(MessageManager.formatMessage( + "exception.matrix_too_many_iteration", new String[] { + "tqli", Integer.valueOf(maxIter).toString() })); } else { @@ -595,7 +615,7 @@ public class Matrix /** * DOCUMENT ME! */ - public void tqli2() + public void tqli2() throws Exception { int n = rows; @@ -642,10 +662,11 @@ public class Matrix { iter++; - if (iter == 30) + if (iter == maxIter) { - System.err.print("Too many iterations in tqli"); - System.exit(0); // JBPNote - same as above - not a graceful exit! + throw new Exception(MessageManager.formatMessage( + "exception.matrix_too_many_iteration", new String[] { + "tqli2", Integer.valueOf(maxIter).toString() })); } else { @@ -726,20 +747,19 @@ public class Matrix } /** - * DOCUMENT ME! + * Returns an array containing the values in the specified column * - * @param n - * DOCUMENT ME! + * @param col * - * @return DOCUMENT ME! + * @return */ - public double[] getColumn(int n) + public double[] getColumn(int col) { double[] out = new double[rows]; for (int i = 0; i < rows; i++) { - out[i] = value[i][n]; + out[i] = value[i][col]; } return out; @@ -772,85 +792,4 @@ public class Matrix Format.print(ps, "%15.4e", e[j]); } } - - /** - * DOCUMENT ME! - * - * @param args - * DOCUMENT ME! - */ - public static void main(String[] args) - { - int n = Integer.parseInt(args[0]); - double[][] in = new double[n][n]; - - for (int i = 0; i < n; i++) - { - for (int j = 0; j < n; j++) - { - in[i][j] = (double) Math.random(); - } - } - - Matrix origmat = new Matrix(in, n, n); - - // System.out.println(" --- Original matrix ---- "); - // / origmat.print(System.out); - // System.out.println(); - // System.out.println(" --- transpose matrix ---- "); - Matrix trans = origmat.transpose(); - - // trans.print(System.out); - // System.out.println(); - // System.out.println(" --- OrigT * Orig ---- "); - Matrix symm = trans.postMultiply(origmat); - - // symm.print(System.out); - // System.out.println(); - // Copy the symmetric matrix for later - // Matrix origsymm = symm.copy(); - - // This produces the tridiagonal transformation matrix - // long tstart = System.currentTimeMillis(); - symm.tred(); - - // long tend = System.currentTimeMillis(); - - // System.out.println("Time take for tred = " + (tend-tstart) + "ms"); - // System.out.println(" ---Tridiag transform matrix ---"); - // symm.print(System.out); - // System.out.println(); - // System.out.println(" --- D vector ---"); - // symm.printD(System.out); - // System.out.println(); - // System.out.println(" --- E vector ---"); - // symm.printE(System.out); - // System.out.println(); - // Now produce the diagonalization matrix - // tstart = System.currentTimeMillis(); - symm.tqli(); - // tend = System.currentTimeMillis(); - - // System.out.println("Time take for tqli = " + (tend-tstart) + " ms"); - // System.out.println(" --- New diagonalization matrix ---"); - // symm.print(System.out); - // System.out.println(); - // System.out.println(" --- D vector ---"); - // symm.printD(System.out); - // System.out.println(); - // System.out.println(" --- E vector ---"); - // symm.printE(System.out); - // System.out.println(); - // System.out.println(" --- First eigenvector --- "); - // double[] eigenv = symm.getColumn(0); - // for (int i=0; i < eigenv.length;i++) { - // Format.print(System.out,"%15.4f",eigenv[i]); - // } - // System.out.println(); - // double[] neigenv = origsymm.vectorPostMultiply(eigenv); - // for (int i=0; i < neigenv.length;i++) { - // Format.print(System.out,"%15.4f",neigenv[i]/symm.d[0]); - // } - // System.out.println(); - } }