X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fmath%2FMatrix.java;h=28b9d67e443d04c54adb458465da55540266d837;hb=e06941005a462eff3578ec863630edbc519b560f;hp=8d95203b1c6f4b532a8fb06309179a6bbe211b2d;hpb=eb702b3c903f2e17ab074382df1f2c26884f2551;p=jalview.git diff --git a/src/jalview/math/Matrix.java b/src/jalview/math/Matrix.java index 8d95203..28b9d67 100755 --- a/src/jalview/math/Matrix.java +++ b/src/jalview/math/Matrix.java @@ -1,26 +1,29 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.0b1) - * Copyright (C) 2014 The Jalview Authors + * 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 . + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.math; -import java.io.*; +import jalview.util.Format; +import jalview.util.MessageManager; -import jalview.util.*; +import java.io.PrintStream; /** * DOCUMENT ME! @@ -48,30 +51,39 @@ public class Matrix public double[] e; // off diagonal /** - * maximum number of iterations for tqli + * maximum number of iterations for tqli * */ int maxIter = 45; // fudge - add 15 iterations, just in case /** - * Creates a new Matrix object. + * Creates a new Matrix object. For example * - * @param value - * DOCUMENT ME! + *
+   *   new Matrix(new double[][] {{2, 3}, {4, 5}, 2, 2)
+   * constructs
+   *   (2 3)
+   *   (4 5)
+   * 
+ * + * 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 * @param rows - * DOCUMENT ME! * @param cols - * DOCUMENT ME! */ - public Matrix(double[][] value, int rows, int cols) + public Matrix(double[][] values, int rows, int cols) { this.rows = rows; this.cols = cols; - this.value = value; + this.value = values; } /** - * DOCUMENT ME! + * Returns a new matrix which is the transposes of this one * * @return DOCUMENT ME! */ @@ -110,15 +122,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++) @@ -138,12 +159,10 @@ public class Matrix } /** - * DOCUMENT ME! * * @param in - * DOCUMENT ME! * - * @return DOCUMENT ME! + * @return */ public double[] vectorPostMultiply(double[] in) { @@ -163,37 +182,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() { @@ -201,10 +217,11 @@ 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); + // for (int j = 0; j < cols; j++) + // { + // newmat[i][j] = value[i][j]; + // } } return new Matrix(newmat, rows, cols); @@ -348,7 +365,7 @@ public class Matrix } } } - + /** * DOCUMENT ME! */ @@ -401,7 +418,9 @@ public class Matrix if (iter == maxIter) { - throw new Exception("Too many iterations in tqli ("+maxIter+")"); + throw new Exception(MessageManager.formatMessage( + "exception.matrix_too_many_iteration", new String[] { + "tqli", Integer.valueOf(maxIter).toString() })); } else { @@ -650,7 +669,9 @@ public class Matrix if (iter == maxIter) { - throw new Exception ("Too many iterations in tqli2 (max is "+maxIter+")"); + throw new Exception(MessageManager.formatMessage( + "exception.matrix_too_many_iteration", new String[] { + "tqli2", Integer.valueOf(maxIter).toString() })); } else { @@ -731,20 +752,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; @@ -777,85 +797,4 @@ public class Matrix Format.print(ps, "%15.4e", e[j]); } } - - /** - * DOCUMENT ME! - * - * @param args - * DOCUMENT ME! - */ - public static void main(String[] args) throws Exception - { - 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(); - } }