📄 matrix.java
字号:
package org.jutil.math.matrix;/** * A class of 2D matrices. * * This version doesn't try that hard to perform stable calculations. * If you need that, use the non-existing nummath package. If you don't know what it means, * use this version :) * * Matrix also doesn't report any overflow (standard Java behavior). * * @path $Source: /cvsroot/org-jutil/jutil.org/src/org/jutil/math/matrix/Matrix.java,v $ * @version $Revision: 1.19 $ * @date $Date: 2002/08/19 15:54:27 $ * @state $State: Exp $ * @author Marko van Dooren * @release $Name: $ */public class Matrix extends NMatrix { /** * MvDMvDMvD : some operations don't have 2 sensible names for use as a mutator and inspector. * * At this moment, I see have 3 possible naming schemes for tranformations on 2D matrices. * * 1) name() : a mutator which applies the tranformation to this matrix. * if you want a clone, just make it yourself. * * 2) name() : an inspector which returns a new matrix * nameThis() : a mutator which applies the tranformation to this matrix. * * 3) returnName() : an inspector which returns a new matrix * name() : a mutator which applies the tranformation to this matrix. * * Personally, I like 3) the best. It feels like talking to a matrix. If you say "matrix.transpose" * it will transpose itself.If you say "matrix.returnTranspose", it will return a transpose (a new matrix). */ /* The revision of this class */ public final static String CVS_REVISION ="$Revision: 1.19 $";/*@ @ public invariant getNbDimensions() == 2; @*/ /** * Initialize a new Matrix with the given number of rows and columns * * @param columns * The number of columns for the new Matrix. * @param rows * The number of rows for the new Matrix. */ /*@ @ public behavior @ @ post getNbColumns() == columns; @ post getNbRows() == rows; @ post (\forall int i; i>0 && i < getNbRows(); @ (\forall int j; j > 0 && j < getNbColumns(); @ elementAt(i,j) == 0)); @*/ public Matrix(int rows, int columns) { _array = new double[columns][rows]; } /** * Initialize a new Matrix from the given 2D array of doubles. * * @param elements * A 2D array containing the elements of the new Matrix. * The first dimension is for the rows, the second for the columns. */ /*@ @ public behavior @ @ pre elements != null; @ pre elements.length > 0; @ pre (\exists int nbColumns; nbColumns > 0; @ (\forall int i; i>=0 && i<elements.length; @ elements[i] != null && @ elements[i].length == nbColumns)); @ @ post getNbRows() == elements.length; @ post getNbColumns() == elements[0].length; @ post (\forall int i; i>=0 && i<elements.length; @ (\forall int j; j>=0 && j<elements[0].length; @ elements[i][j] == elementAt(i+1,j+1))); @*/ public Matrix(double[][] elements) { _array = new double[elements[0].length][elements.length]; int rows = elements.length; int columns = elements[0].length; for(int i=0; i<rows; i++) { for(int j=0; j<columns; j++) { _array[j][i] = elements[i][j]; } } } /** * Initialize a new diagonal Matrix with the given array of diagonal * element. * * @param elements * An array containing the diagonal elements of the new Matrix. */ /*@ @ public behavior @ @ pre elements != null; @ pre elements.length > 0; @ @ post getNbRows() == elements.length; @ post isSquare(); @ post isDiagonal(); @ post (\forall int i; i>=0 && i<elements.length; @ elements[i] == elementAt(i+1,i+1)); @*/ public Matrix(double[] elements) { _array = new double[elements.length][elements.length]; int rows = elements.length; for(int i=rows; --i>=0;) { _array[i][i] = elements[i]; } } /** * Return a new unity matrix of the given size * * @param size * The number of rows/columns of the matrix */ /*@ @ public behavior @ @ pre size > 0; @ @ post \fresh(\result); @ post \result.getNbRows() == size; @ post \result.getNbColumns() == size; @ post (\forall int i; i>=1 && i<=size; @ (\forall int j; j>=1 && j<=size; @ ((i==j) ==> \result.elementAt(i,j) == 1) && @ ((i!=j) ==> \result.elementAt(i,j) == 0))); @*/ public static Matrix unity(int size) { Matrix result = new Matrix(size, size); for (int i=1; i<=size; i++) { result.setElementAt(i,i,1); } return result; } /** * @see superclass */ public int getNbDimensions() { return 2; } /** * @see superclass */ public int[] getDimensions() { return new int[]{getNbRows(), getNbColumns()}; } /** * Return the number of rows of this matrix. */ /*@ @ public behavior @ @ post \result == getDimensions()[0]; @*/ public int getNbRows() { return _array[0].length; } /** * Return the number of columns of this matrix. */ /*@ @ public behavior @ @ post \result == getDimensions()[1]; @*/ public int getNbColumns() { return _array.length; } /** * @see superclass */ public double elementAt(int[] index) { return _array[index[1] - 1][index[0] - 1]; } /** * Return the element at the given row and column. * * @param row * The row of the element to be retrieved. * @param column * The column of the element to be retrieved. */ /*@ @ public behavior @ @ pre validIndex(row, column); @ @ post \result == elementAt(new int[]{row, column}); @*/ public double elementAt(int row, int column) { return _array[column - 1][row - 1]; } /** * Set the element at the given row and column to * the given value. * * @param row * The row of the element to be retrieved. * @param column * The column of the element to be retrieved. * @param value * The new value for the element at the given row and column. */ /*@ @ public behavior @ @ pre validIndex(row, column); @ @ post elementAt(row, column) == value; @*/ public void setElementAt(int row, int column, double value) { _array[column-1][row-1] = value; } /** * @see superclass */ public void setElementAt(int[] index, double value) { _array[index[1]-1][index[0]-1] = value; } /** * Check whether or not the given row and column point to * a valid position for this Matrix. * * @param row * The row of the position. * @param column * The row of the position. */ /*@ @ public behavior @ @ post \result == (row > 0) && @ (row <= getNbRows()) && @ (column > 0) && @ (column <= getNbColumns()); @*/ public boolean validIndex(int row, int column) { return validIndex(new int[]{row, column}); } /** * Return the column with the given index. * * @param index * The index of the requested column. */ /*@ @ public behavior @ @ pre index > 0 && index <= getNbColumns(); @ @ post \result != null; @ post \result.size() == getNbRows(); @ post (\forall int i; i>0 && i < getNbRows(); @ \result.elementAt(i) == elementAt(i,index)); @*/ public Column getColumn(int index) { return new Column(_array[index-1]); } /** * Set the i-th column of this matrix * * @param i * The index of the column to be set. * @param column * The column which will be the new i-th column of this matrix */ /*@ @ public behavior @ @ pre i>=1 && i<=getNbColumns(); @ pre column != null; @ pre column.size() == getNbRows(); @ @ post getColumn(i).equals(column); @*/ public void setColumn(int i, Column column) { for (int k=1; k<=getNbRows(); k++) { setElementAt(k, i, column.elementAt(k)); } } /** * Return the row with the given index. * * @param index * The index of the requested row. */ /*@ @ public behavior @ @ pre index > 0 && index <= getNbRows(); @ @ post \result != null; @ post \result.size() == getNbColumns(); @ post (\forall int i; i>0 && i < getNbColumns(); @ \result.elementAt(i) == elementAt(index, i)); @*/ public Row getRow(int index) { double[] row = new double[getNbColumns()]; for(int i=0; i<row.length; i++){ row[i] = _array[i][index-1]; } return new Row(row); } /** * Set the i-th row of this matrix * * @param i * The index of the row to be set. * @param column * The row which will be the new i-th row of this matrix */ /*@ @ public behavior @ @ pre i>=1 && i<=getNbRows(); @ pre row != null; @ pre row.size() == getNbColumns(); @ @ post getRow(i).equals(row); @*/ public void setRow(int i, Row row) { for (int k=1; k<=getNbColumns(); k++) { setElementAt(i, k, row.elementAt(k)); } } /** * Add the given matrix to this matrix. * * @param other * The matrix to be added. */ /*@ @ public behavior @ @ pre other != null; @ pre sameDimensions(other); @ @ post (\forall int i; i>=1 && i <= getNbRows(); @ (\forall int j; j>=1 && j <= getNbColumns(); @ elementAt(i,j) == @ \old(elementAt(i,j)) + other.elementAt(i,j))); @*/ public void add(Matrix other) { int rows = getNbRows(); int columns = getNbColumns(); for (int i= 0; i<rows; i++) { for(int j = 0; j<columns; j++) { _array[j][i] = _array[j][i] + other.elementAt(i+1,j+1); } } } /** * Return a new matrix that is the sum of this matrix * and the given matrix * * @param other * The matrix to be added. */ /*@ @ public behavior @ @ pre other != null; @ pre sameDimensions(other); @ @ post \result != null; @ post \result.sameDimensions(this); @ post (\forall int i; i>=1 && i <= getNbRows(); @ (\forall int j; j>=1 && j <= getNbColumns(); @ \result.elementAt(i,j) == @ elementAt(i,j) + other.elementAt(i,j))); @*/ public Matrix plus(Matrix other) { Matrix newMatrix = (Matrix) clone(); newMatrix.add(other); return newMatrix; } /** * Subtract the given matrix from this matrix. * * @param other * The matrix to be added. */ /*@ @ public behavior @ @ pre other != null; @ pre sameDimensions(other); @ @ post (\forall int i; i>=1 && i <= getNbRows(); @ (\forall int j; j>=1 && j <= getNbColumns(); @ elementAt(i,j) == @ \old(elementAt(i,j)) - other.elementAt(i,j))); @*/ public void subtract(Matrix other) { int rows = getNbRows(); int columns = getNbColumns(); for (int i= 0; i<rows; i++) { for(int j = 0; j<columns; j++) { _array[j][i] = _array[j][i] - other.elementAt(i+1,j+1); } } } /** * Return a new matrix that equals this matrix minus * the given matrix. * * @param other * The matrix to be added. */ /*@ @ public behavior @ @ pre other != null; @ pre sameDimensions(other); @ @ post \result != null; @ post \result.sameDimensions(this); @ post (\forall int i; i>=1 && i <= getNbRows(); @ (\forall int j; j>=1 && j <= getNbColumns(); @ \result.elementAt(i,j) == @ elementAt(i,j) - other.elementAt(i,j))); @*/ public Matrix minus(Matrix other) { Matrix newMatrix = (Matrix) clone(); newMatrix.subtract(other); return newMatrix; } /** * Right-multiply this matrix by another. * \result = this * other * * @param other * The matrix to multiply this matrix by. */ /*@ @ public behavior @ @ pre other != null; @ pre other.getNbRows() == getNbColumns(); @ pre other.getNbColumns() == getNbRows(); @ @ post \result != null; @ post (\forall int i; i>=1 && i<= getNbRows(); @ (\forall int j; j>=1 && j<= other.getNbColumns(); @ \result.elementAt(i,j) == @ (\sum int k; k>=1 && k<= getNbColumns(); @ elementAt(i,k) * other.elementAt(k,j)))); @ post \result.getNbRows() == getNbRows(); @ post \result.getNbColumns() == other.getNbColumns(); @ post \fresh(\result); @ @ // MvDMvDMvD We should put this everywhere we return a matrix @ // since matrices are mutable. We don't want to change an existing one. @*/ public Matrix times(Matrix other) { Matrix newMatrix = new Matrix(getNbRows(),other.getNbColumns()); int rows = getNbRows(); int columns = getNbColumns(); int otherColumns = other.getNbColumns(); for (int i=1; i <=rows; i++) { for (int j=1; j <=otherColumns; j++) { double element=0; //double[] terms = new double[columns]; for(int k=1; k <= columns; k++) { //terms[k-1] = elementAt(i,k) * other.elementAt(k,j); element+=elementAt(i,k) * other.elementAt(k,j); } // sorts in ascending order //java.util.Arrays.sort(terms); //for(int k=1; k <= columns; k++) { // element += terms[k-1]; //} newMatrix.setElementAt(i,j,element); } } return newMatrix; } /** * Return a matrix that equals this matrix times a given factor. * * @param factor * The factor to multiply this matrix with. */ /*@ @ public behavior @ @ post \result != null; @ post \result.sameDimensions(this); @ post (\forall int i; i>=1 && i<= getNbRows(); @ (\forall int j; j>=1 && j<= getNbColumns(); @ \result.elementAt(i,j) == elementAt(i,j) * factor)); @*/ public Matrix times(double factor) { 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)*factor); } } return newMatrix; } /** * Multiply this matrix by a given factor. * * @param factor * The factor to multiply this matrix with. */ /*@ @ 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));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -