📄 matrix.java
字号:
@*/ public void multiply(double factor) { for (int i=1; i <=getNbRows(); i++) { for (int j=1; j <=getNbColumns(); j++) { _array[j-1][i-1] = _array[j-1][i-1]*factor; } } } /** * Divide this matrix by a given factor. * * @param factor * The factor to divide this matrix by. */ /*@ @ public behavior @ @ post (\forall int i; i>=1 && i<= getNbRows(); @ (\forall int j; j>=1 && j<= getNbColumns(); @ elementAt(i,j) == \old(elementAt(i,j)) / factor)); @*/ public void divide(double factor) { for (int i=1; i <=getNbRows(); i++) { for (int j=1; j <=getNbColumns(); j++) { _array[j-1][i-1] = _array[j-1][i-1]/factor; } } } /** * Transpose this matrix. */ /*@ @ public behavior @ @ post getNbColumns() == \old(getNbRows()); @ post getNbRows() == \old(getNbColumns()); @ post (\forall int i; i>=1 && i<=getNbRows(); @ (\forall int j; j>=1 && j<getNbColumns(); @ elementAt(i,j) == \old(elementAt(j,i)))); @*/ public void transpose() { // inefficient : see returnTranspose() double[][] newArray = new double[getNbRows()][getNbColumns()]; int rows=getNbRows(); int columns=getNbColumns(); for (int i= 0; i<rows; i++) { for(int j = 0; j<columns; j++) { newArray[i][j] = _array[j][i]; } } _array=newArray; } /** * <p>Perform a givens rotation on this matrix from the left side with the givens matrix defined by * c, s, i and k as follows (m = getNbRows()).</p> * <pre> * 1 i k m * * 1 1 . . . 0 . . . 0 . . . 0 * . . . . . . . * . . . . . . . * . . . . . . . * i 0 . . . c . . . s . . . 0 * . . . . . . . * . . . . . . . * . . . . . . . * k 0 . . .-s . . . c . . . 0 * . . . . . . . * . . . . . . . * . . . . . . . * m 0 . . . 0 . . . 0 . . . 1 * </pre> * <p> This matrix (<code>A</code>) will be transformed into <code>G*A</code>.</p> * @param c * The value of c * @param c * The value of s * @param i * The value of i * @param k * The value of k */ /*@ @ public behavior @ @ pre (1 <= i) && (i < k) && (k <= getNbRows()); @ @ post getColumn(i).equals(\old(getColumn(i).times(c).minus(getColumn(k).times(s)))); @ post getColumn(k).equals(\old(getColumn(i).times(s).plus(getColumn(k).times(c)))); @*/ public void leftGivens(double c, double s, int i, int k) { //rows 1...i-1, i+1 ... k-1, k+1 ... n remain untouched. Row row_i = getRow(i); Row row_k = getRow(k); setRow(i,row_i.times(c).minus(row_k.times(s)).getRow(1)); setRow(k,row_i.times(s).plus(row_k.times(c)).getRow(1)); } /** * <p>Perform a givens rotation on this matrix from the right side with the givens matrix defined by * c, s, i and k as follows (n = getNbColumns()).</p> * <pre> * 1 i k n * * 1 1 . . . 0 . . . 0 . . . 0 * . . . . . . . * . . . . . . . * . . . . . . . * i 0 . . . c . . . s . . . 0 * . . . . . . . * . . . . . . . * . . . . . . . * k 0 . . .-s . . . c . . . 0 * . . . . . . . * . . . . . . . * . . . . . . . * n 0 . . . 0 . . . 0 . . . 1 * </pre> * <p> This matrix (<code>A</code>) will be transformed into <code>A*G</code>.</p> * @param c * The value of c * @param c * The value of s * @param i * The value of i * @param k * The value of k */ /*@ @ public behavior @ @ pre (1 <= i) && (i < k) && (k <= getNbColumns()); @ @ post getColumn(i).equals(\old(getColumn(i).times(c).minus(getColumn(k).times(s)))); @ post getColumn(k).equals(\old(getColumn(i).times(s).plus(getColumn(k).times(c)))); @*/ public void rightGivens(double c, double s, int i, int k) { //columns 1...i-1, i+1 ... k-1, k+1 ... n remain untouched. Column column_i = getColumn(i); Column column_k = getColumn(k); setColumn(i,column_i.times(c).minus(column_k.times(s)).getColumn(1)); setColumn(k,column_i.times(s).plus(column_k.times(c)).getColumn(1)); } /** * Return the transpose of this matrix. */ /*@ @ public behavior @ @ post \result.sameDimensions(this); @ post (\forall int i; i>0 && i<= getNbRows(); @ (\forall int j; j>0 && j <getNbColumns(); @ elementAt(i,j) == \result.elementAt(j,i))); @*/ public Matrix returnTranspose() { // MvDMvDMvD : very inefficient. It would be better to have a // boolean flag indicating whether the internal // indices are [column][row] or [row][column]. // This however makes other operations slightly less // efficient since a test has to be done. Matrix newMatrix = new Matrix(getNbColumns(), getNbRows()); for (int i=1; i<=getNbRows(); i++) { for(int j=1; j<=getNbColumns(); j++) { newMatrix.setElementAt(j,i,elementAt(i,j)); } } return newMatrix; } /** * Check wether the given matrix has the same dimensions as this one. * * @param other * The other matrix */ /*@ @ public behavior @ @ pre other != null; @ @ post getNbColumns() == other.getNbColumns(); @ post getNbRows() == other.getNbRows(); @*/ public boolean sameDimensions(Matrix other) { return ((getNbColumns() == other.getNbColumns()) && (getNbRows() == other.getNbRows())); }// /**// * Return a reduced QR factorization of this matrix using // * Gram-Schmidt orthogonalization.// */// /*@// @ public behavior// @// @ pre getNbRows() >= getNbColumns()// @*/// public void GramQR() {// Matrix Q = (Matrix) clone();// int columns = getNbColumns();// int rows = getNbRows();// Matrix R = new Matrix(columns, columns);// for (int i=1; i<= columns; i++) {// double norm = Q.getColumn(i).norm(2);// // rii = ||vi||// R.setElementAt(i,i, norm);// // qi = vi/rii// for (int k=1; k<=rows; k++) {// Q.setElementAt(k,i,Q.elementAt(k,i)/norm);// }// for (int j=i+1; j<=columns; j++) {// // qi = vi// // MvDMvDMvD// // very inefficient. getColumn() clones and returnTranspose() clones again.// double r = (Q.getColumn(i).returnTranspose().times(Q.getColumn(j))).elementAt(1,1);// R.setElementAt(i,j,r);// // vj = vj - rij*qi// for (int k=1; k<= rows; k++) {// Q.setElementAt(k,j,(Q.elementAt(k,j) - r*Q.elementAt(k,i)));// }// }// }// System.out.println(Q);// System.out.println(R);// } /** * Return the submatrix starting from (x1,y1) to (x2,y2). * * @param x1 * The row from which to start. * @param y1 * The column from which to start. * @param x2 * The end row. * @param y2 * The end column. */ /*@ @ public behavior @ @ pre validIndex(x1, y1); @ pre validIndex(x2, y2); @ pre x2 >= x1; @ pre y2 >= y1; @ @ post \fresh(\result); @ post \result.getNbRows() == x2 - x1 + 1; @ post \result.getNbColumns() == y2 - y1 + 1; @ post (\forall int i; i>=x1 && i <=x2; @ (\forall int j; j>=y1 && j <=y2; @ \result.elementAt(i - x1 + 1, j - y1 + 1) == elementAt(i, j))); @*/ public Matrix subMatrix(int x1, int y1, int x2, int y2) { Matrix result = new Matrix(x2 - x1 + 1, y2 - y1 + 1); for (int i = x1; i <= x2; i++) { for (int j = y1; j <= y2; j++) { result.setElementAt(i - x1 + 1, j - y1 + 1, elementAt(i, j)); } } return result; } /** * Replace a submatrix of this matrix with the given matrix * at the given coordinates. * * @param row * The row of the top-left element of the submatrix that will be replaced. * @param column * The column of the top-left element of the submatrix that will be replaced. * @param matrix * The matrix to put into this matrix */ /*@ @ public behavior @ @ pre matrix != null; @ pre validIndex(row, column); @ pre validIndex(row + matrix.getNbRows() - 1, column + matrix.getNbColumns() - 1); @ @ post subMatrix(row, column, row + matrix.getNbRows() - 1, column + matrix.getNbColumns() - 1).equals(matrix); @*/ public void setSubMatrix(int row, int column, Matrix matrix) { int rows = matrix.getNbRows(); int columns = matrix.getNbColumns(); for (int i = 1; i <= rows; i++) { for (int j = 1; j <= columns; j++) { setElementAt(i + row - 1, j + column - 1, matrix.elementAt(i, j)); } } } /** * Check whether or not this matrix is upper triangular */ /*@ @ public behavior @ @ post \result == (\forall int i; i>=1 && i<=getNbRows(); @ (\forall int j; j>=1 && j<=getNbColumns(); @ (i < j) ==> elementAt(i,j) == 0)); @*/ public boolean isUpperTriangular() { int rows=getNbRows(); int columns=getNbColumns(); for (int i=1; i<= rows; i++) { for (int j=1; j<= columns && j < i; j++) { if (elementAt(i,j) != 0) { return false; } } } return true; } /** * Check whether or not this matrix is lower triangular */ /*@ @ public behavior @ @ post \result == (\forall int i; i>=1 && i<=getNbRows(); @ (\forall int j; j>=1 && j<=getNbColumns(); @ (i > j) ==> elementAt(i,j) == 0)); @*/ public boolean isLowerTriangular() { int rows=getNbRows(); int columns=getNbColumns(); for (int i=1; i<= rows; i++) { for (int j=i+1; j<= columns; j++) { if (elementAt(i,j) != 0) { return false; } } } return true; } /** * Check whether or not this matrix is a diagonal matrix. */ /*@ @ public behavior @ @ post \result == (\forall int i; i>=1 && i<=getNbRows(); @ (\forall int j; j>=1 && j<=getNbColumns(); @ (j != i) ==> elementAt(i,j) == 0)); @*/ public boolean isDiagonal() { int rows=getNbRows(); int columns=getNbColumns(); for (int i=1; i<= rows; i++) { for (int j=1; j<= columns; j++) { if ((i != j) && (elementAt(i,j) != 0)) { return false; } } } return true; } /** * see superclass */ public String toString() { String result = ""; int columns=getNbColumns(); int rows=getNbRows(); for (int i=1; i<=rows; i++) { for (int j=1; j<=columns - 1; j++) { result += elementAt(i,j)+", "; } result += elementAt(i,columns) +"\n"; } return result; } /** * Return a clone */ /*@ @ also public behavior @ @ post equals(\result); @ post \result instanceof Matrix; @*/ public Object clone() { // MvDMvDMvD // should be made more efficient using a private constructor // which takes double[][] as an argument. Matrix newMatrix = new Matrix(getNbRows(), getNbColumns()); for (int i=1; i<=getNbRows(); i++) { for(int j=1; j<=getNbColumns(); j++) { newMatrix.setElementAt(i,j,elementAt(i,j)); } } return newMatrix; } /** * Check whether the given object is equal to this matrix. */ /*@ @ also public behavior @ @ post !(other instanceof Matrix) ==> false; @ post !(sameDimensions((Matrix)other)) ==> false; @ post (other instanceof Matrix) && (sameDimensions((Matrix)other)) ==> @ \result == (\forall int i; i>=1 && i<=getNbRows(); @ (\forall int j; j>=1 && j<=getNbColumns(); @ ((Matrix)other).elementAt(i,j) == @ elementAt(i,j))); @*/ public boolean equals(Object other) { if (!(other instanceof Matrix)) { return false; } if (!(sameDimensions((Matrix)other))) { return false; } for (int i=1; i<=getNbRows(); i++) { for(int j=1; j<=getNbColumns(); j++) { if(_array[j-1][i-1] != ((Matrix)other).elementAt(i,j)) { return false; } } } return true; } /** * Check whether or not this matrix is square. */ /*@ @ public behavior @ @ post getNbColumns() == getNbRows(); @*/ public boolean isSquare() { return getNbColumns() == getNbRows(); } /** * Check whether or not this matrix is symmetric. */ /*@ @ public behavior @ @ post \result == isSquare() && @ (\forall int i; i>=1 && i<=getNbRows(); @ (\forall int j; j>=1 && j<=getNbColumns(); @ elementAt(i,j) == elementAt(j,i))); @*/ public boolean isSymmetric() { if(! isSquare()) { return false; } boolean result = true; int rows = getNbRows(); int columns = getNbColumns(); // the last row need not be checked, so i<rows for(int i=1; result && i<rows; i++) { for(int j=i+1; result && j<=columns; j++) { result = (elementAt(i,j) == elementAt(j,i)); } } return result; } /** * Check whether or not this matrix is a permutation matrix. */ /*@ @ post \result == isSquare() && @ // 1 non-zero element in each row @ (\forall int i; i>=1 && i<=getNbRows(); @ (\num_of int j; j>=1 && j<=getNbColumns(); elementAt(i,j) != 0) == 1) && @ // 1 non-zero element in each column @ (\forall int i; i>=1 && i<=getNbColumns(); @ (\num_of int j; j>=1 && j<=getNbRows(); elementAt(j,i) != 0) == 1) && @ // each element is 0 or 1 @ (\forall int i; i>=1 && i<=getNbRows(); @ (\forall int j; j>=1 && j<=getNbColumns(); @ elementAt(i,j) == 0 || elementAt(i,j) == 1)); @*/ public boolean isPermutationMatrix() { if(! isSquare()) { return false; } int n = getNbRows(); boolean[] column_found = new boolean[n]; for(int i=1; i<=n; i++) { boolean found = false; for(int j=1; j <= n; j++) { if((elementAt(i,j) != 0) && (elementAt(i,j) != 0)) { return false; } if(elementAt(i,j) == 1) { if(found == true) { // we had already found a 1 on this row. return false; } if(column_found[j-1]) { // we had already found in column j return false; } column_found[j-1] = true; found=true; } } } return true; } /** * The values are put in the array according to the following scheme * [column][row] * This makes it easier to extract a column from the matrix, which is used * more frequently than a column. */ /*@ @ private invariant _array != null; @ private invariant _array.length > 0; @ // All columns have the same length. @ private invariant (\forall int i; i>0 && i<_array.length; @ _array[i].length == _array[i-1].length); @ private invariant _array[0].length > 0; @*/ private double[][] _array;}/*<copyright>Copyright (C) 1997-2002. This software is copyrighted by the people and entities mentioned after the "@author" tags above, on behalf of the JUTIL.ORG Project. The copyright is dated by the dates after the "@date" tags above. All rights reserved.This software is published under the terms of the JUTIL.ORG SoftwareLicense version 1.1 or later, a copy of which has been included withthis distribution in the LICENSE file, which can also be found athttp://www.jutil.org/LICENSE. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the JUTIL.ORG Software License for more details.For more information, please see http://jutil.org/</copyright>*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -