You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by "Phil Steitz (JIRA)" <ji...@apache.org> on 2006/07/06 07:32:30 UTC
[jira] Closed: (MATH-122) New methods in RealMatrixImpl and
changing indexing
[ http://issues.apache.org/jira/browse/MATH-122?page=all ]
Phil Steitz closed MATH-122:
----------------------------
Issue was resolve in 1.0 final.
> New methods in RealMatrixImpl and changing indexing
> ---------------------------------------------------
>
> Key: MATH-122
> URL: http://issues.apache.org/jira/browse/MATH-122
> Project: Commons Math
> Type: Improvement
> Versions: 1.0 Alpha
> Environment: Operating System: All
> Platform: All
> Reporter: Kim van der Linde
> Priority: Minor
>
> Numbering of the rows and columns is as default for an JAVA array, starting with
> 0 with the higest value for either row-1 or column-1. This facilitates
> programming of modules which give back an array to construct subMatrices from
> the original matrix.
> This change affects the folowing old methods:
> getRow(int row)
> getColumn(int column)
> isValidCoordinate(int row, int col)
> setEntry(...)
> getEntry(...)
> /*
> * Copyright 2003-2004 The Apache Software Foundation.
> *
> * Licensed under the Apache License, Version 2.0 (the "License");
> * you may not use this file except in compliance with the License.
> * You may obtain a copy of the License at
> *
> * http://www.apache.org/licenses/LICENSE-2.0
> *
> * Unless required by applicable law or agreed to in writing, software
> * distributed under the License is distributed on an "AS IS" BASIS,
> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> * See the License for the specific language governing permissions and
> * limitations under the License.
> */
> package org.apache.commons.math.linear;
> import java.io.Serializable;
> /**
> * Implementation for RealMatrix using a double[][] array to store entries
> * and <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf">
> * LU decompostion</a> to support linear system
> * solution and inverse.
> * <p>
> * The LU decompostion is performed as needed, to support the following
> operations: <ul>
> * <li>solve</li>
> * <li>isSingular</li>
> * <li>getDeterminant</li>
> * <li>inverse</li> </ul>
> * <p>
> * <strong>Usage note</strong>:<br>
> * The LU decomposition is stored and reused on subsequent calls. If matrix
> * data are modified using any of the public setXxx methods, the saved
> * decomposition is discarded. If data are modified via references to the
> * underlying array obtained using <code>getDataRef()</code>, then the stored
> * LU decomposition will not be discarded. In this case, you need to
> * explicitly invoke <code>LUDecompose()</code> to recompute the decomposition
> * before using any of the methods above.
> *
> * <p> Numbering of the rows and columns is as default for an JAVA array,
> starting with 0
> * with the higest value for either row-1 or column-1. This facilitates
> programming of
> * modules which give back an array to construct subMatrices from the original
> matrix.
> *
> * @version $Revision: 1.26 $ $Date: 2004/08/22 01:42:58 $
> */
> public class RealMatrixImpl implements RealMatrix, Serializable {
> /** Serializable version identifier */
> static final long serialVersionUID = 4237564493130426188L;
> /** Entries of the matrix */
> private double data[][] = null;
> /** Entries of cached LU decomposition.
> * All updates to data (other than luDecompose()) *must* set this to null
> */
> private double lu[][] = null;
> /** Permutation associated with LU decompostion */
> private int[] permutation = null;
> /** Parity of the permutation associated with the LU decomposition */
> private int parity = 1;
> /** Bound to determine effective singularity in LU decomposition */
> protected static double TOO_SMALL = 10E-12;
> /**
> * Creates a matrix with no data
> */
> public RealMatrixImpl() {
> }
> /**
> * Create a new RealMatrix with the supplied row and column dimensions.
> *
> * @param rowDimension the number of rows in the new matrix
> * @param columnDimension the number of columns in the new matrix
> */
> public RealMatrixImpl(int rowDimension, int columnDimension) {
> data = new double[rowDimension][columnDimension];
> lu = null;
> }
> /**
> * Create a new RealMatrix using the <code>data</code> as the underlying
> * data array.
> * <p>
> * The input array is copied, not referenced.
> *
> * @param d data for new matrix
> */
> public RealMatrixImpl(double[][] d) {
> this.copyIn(d);
> lu = null;
> }
> /**
> * Create a new (column) RealMatrix using <code>v</code> as the
> * data for the unique column of the <code>v.length x 1</code> matrix
> * created.
> * <p>
> * The input array is copied, not referenced.
> *
> * @param v column vector holding data for new matrix
> */
> public RealMatrixImpl(double[] v) {
> int nRows = v.length;
> data = new double[nRows][1];
> for (int row = 0; row < nRows; row++) {
> data[row][0] = v[row];
> }
> }
> /**
> * Create a new RealMatrix which is a copy of this.
> *
> * @return the cloned matrix
> */
> public RealMatrix copy() {
> return new RealMatrixImpl(this.copyOut());
> }
> /**
> * Compute the sum of this and <code>m</code>.
> *
> * @param m matrix to be added
> * @return this + m
> * @throws IllegalArgumentException if m is not the same size as this
> */
> public RealMatrix add(RealMatrix m) throws IllegalArgumentException {
> if (this.getColumnDimension() != m.getColumnDimension() ||
> this.getRowDimension() != m.getRowDimension()) {
> throw new IllegalArgumentException("matrix dimension mismatch");
> }
> int rowCount = this.getRowDimension();
> int columnCount = this.getColumnDimension();
> double[][] outData = new double[rowCount][columnCount];
> double[][] mData = m.getData();
> for (int row = 0; row < rowCount; row++) {
> for (int col = 0; col < columnCount; col++) {
> outData[row][col] = data[row][col] + mData[row][col];
> }
> }
> return new RealMatrixImpl(outData);
> }
> /**
> * Compute this minus <code>m</code>.
> *
> * @param m matrix to be subtracted
> * @return this + m
> * @throws IllegalArgumentException if m is not the same size as *this
> */
> public RealMatrix subtract(RealMatrix m) throws IllegalArgumentException {
> if (this.getColumnDimension() != m.getColumnDimension() ||
> this.getRowDimension() != m.getRowDimension()) {
> throw new IllegalArgumentException("matrix dimension mismatch");
> }
> int rowCount = this.getRowDimension();
> int columnCount = this.getColumnDimension();
> double[][] outData = new double[rowCount][columnCount];
> double[][] mData = m.getData();
> for (int row = 0; row < rowCount; row++) {
> for (int col = 0; col < columnCount; col++) {
> outData[row][col] = data[row][col] - mData[row][col];
> }
> }
> return new RealMatrixImpl(outData);
> }
> /**
> * Returns the result of adding d to each entry of this.
> *
> * @param d value to be added to each entry
> * @return d + this
> */
> public RealMatrix scalarAdd(double d) {
> int rowCount = this.getRowDimension();
> int columnCount = this.getColumnDimension();
> double[][] outData = new double[rowCount][columnCount];
> for (int row = 0; row < rowCount; row++) {
> for (int col = 0; col < columnCount; col++) {
> outData[row][col] = data[row][col] + d;
> }
> }
> return new RealMatrixImpl(outData);
> }
> /**
> * Returns the result multiplying each entry of this by <code>d</code>
> * @param d value to multiply all entries by
> * @return d * this
> */
> public RealMatrix scalarMultiply(double d) {
> int rowCount = this.getRowDimension();
> int columnCount = this.getColumnDimension();
> double[][] outData = new double[rowCount][columnCount];
> for (int row = 0; row < rowCount; row++) {
> for (int col = 0; col < columnCount; col++) {
> outData[row][col] = data[row][col] * d;
> }
> }
> return new RealMatrixImpl(outData);
> }
> /**
> * Returns the result of postmultiplying this by <code>m</code>.
> * @param m matrix to postmultiply by
> * @return this*m
> * @throws IllegalArgumentException
> * if columnDimension(this) != rowDimension(m)
> */
> public RealMatrix multiply(RealMatrix m) throws IllegalArgumentException {
> if (this.getColumnDimension() != m.getRowDimension()) {
> throw new IllegalArgumentException("Matrices are not multiplication
> compatible.");
> }
> int nRows = this.getRowDimension();
> int nCols = m.getColumnDimension();
> int nSum = this.getColumnDimension();
> double[][] mData = m.getData();
> double[][] outData = new double[nRows][nCols];
> double sum = 0;
> for (int row = 0; row < nRows; row++) {
> for (int col = 0; col < nCols; col++) {
> sum = 0;
> for (int i = 0; i < nSum; i++) {
> sum += data[row][i] * mData[i][col];
> }
> outData[row][col] = sum;
> }
> }
> return new RealMatrixImpl(outData);
> }
> /**
> * Returns the result premultiplying this by <code>m</code>.
> * @param m matrix to premultiply by
> * @return m * this
> * @throws IllegalArgumentException
> * if rowDimension(this) != columnDimension(m)
> */
> public RealMatrix preMultiply(RealMatrix m) throws IllegalArgumentException {
> return m.multiply(this);
> }
> /**
> * Returns matrix entries as a two-dimensional array.
> * <p>
> * Makes a fresh copy of the underlying data.
> *
> * @return 2-dimensional array of entries
> */
> public double[][] getData() {
> return copyOut();
> }
> /**
> * Overwrites the underlying data for the matrix
> * with a fresh copy of <code>inData</code>.
> *
> * @param inData 2-dimensional array of entries
> */
> public void setData(double[][] inData) {
> copyIn(inData);
> lu = null;
> }
> /**
> * Returns a reference to the underlying data array.
> * <p>
> * Does not make a fresh copy of the underlying data.
> *
> * @return 2-dimensional array of entries
> */
> public double[][] getDataRef() {
> return data;
> }
> /**
> * Overwrites the underlying data for the matrix
> * with a reference to <code>inData</code>.
> * <p>
> * Does not make a fresh copy of <code>data</code>.
> *
> * @param inData 2-dimensional array of entries
> */
> public void setDataRef(double[][] inData) {
> this.data = inData;
> lu = null;
> }
> /**
> *
> * @return norm
> */
> public double getNorm() {
> double maxColSum = 0;
> for (int col = 0; col < this.getColumnDimension(); col++) {
> double sum = 0;
> for (int row = 0; row < this.getRowDimension(); row++) {
> sum += Math.abs(data[row][col]);
> }
> maxColSum = Math.max(maxColSum, sum);
> }
> return maxColSum;
> }
> /**
> * Returns the entries in row number <code>row</code> as an array.
> *
> * @param row the row to be fetched
> * @return array of entries in the row
> * @throws MatrixIndexException if the specified row is greater
> * than the number of rows in this matrix
> */
> public double[] getRow(int row) throws MatrixIndexException {
> if ( !isValidCoordinate( row, 0 ) ) {
> throw new MatrixIndexException("illegal row argument");
> }
> int ncols = this.getColumnDimension();
> double[] out = new double[ncols];
> System.arraycopy(data[row], 0, out, 0, ncols);
> return out;
> }
> /**
> * Returns the entries in row number <code>row</code> as a RealMatrix object.
> *
> * @param row the row to be fetched
> * @return RealMatrix with only one row
> * @throws MatrixIndexException if the specified row is greater
> * than the number of rows in this matrix
> */
> public RealMatrix getRowMatrix(int row) throws MatrixIndexException {
> if ( !isValidCoordinate( row, 0 ) ) {
> throw new MatrixIndexException("illegal row argument");
> }
> int ncols = this.getColumnDimension();
> double[][] out = new double[1][ncols];
> for (int y = 0; y<ncols; y++)
> {
> out[0][y] = data[row][y];
> }
> return new RealMatrixImpl(out);
> }
> /**
> * Returns the entries in column number <code>col</code> as an array.
> *
> * @param col column to fetch
> * @return array of entries in the column
> * @throws MatrixIndexException if the specified column is greater
> * than the number of columns in this matrix
> */
> public double[] getColumn(int col) throws MatrixIndexException {
> if ( !isValidCoordinate(0, col) ) {
> throw new MatrixIndexException("illegal column argument");
> }
> int nRows = this.getRowDimension();
> double[] out = new double[nRows];
> for (int row = 0; row < nRows; row++) {
> out[row] = data[row][col];
> }
> return out;
> }
> /**
> * Returns the entries in column number <code>col</code> as a RealMatrix object.
> *
> * @param col column to fetch
> * @return RealMatrix with only one column
> * @throws MatrixIndexException if the specified column is greater
> * than the number of columns in this matrix
> */
> public RealMatrix getColumnMatrix(int col) throws MatrixIndexException {
> if ( !isValidCoordinate(0, col) ) {
> throw new MatrixIndexException("illegal row argument");
> }
> int nRows = this.getRowDimension();
> double[][] out = new double[nRows][1];
> for (int y = 0; y<nRows ; y++)
> {
> out[y][0] = data[y][col];
> }
> return new RealMatrixImpl(out);
> }
> /**
> * Returns the entry in the specified row and column.
> *
> * @param row row location of entry to be fetched
> * @param column column location of entry to be fetched
> * @return matrix entry in row,column
> * @throws MatrixIndexException if the specified coordinate is outside
> * the dimensions of this matrix
> */
> public double getEntry(int row, int column)
> throws MatrixIndexException {
> if (!isValidCoordinate(row,column)) {
> throw new MatrixIndexException("matrix entry does not exist");
> }
> return data[row][column];
> }
> /**
> * Sets the entry in the specified row and column to the specified value.
> *
> * @param row row location of entry to be set
> * @param column column location of entry to be set
> * @param value value to set
> * @throws MatrixIndexException if the specified coordinate is outside
> * he dimensions of this matrix
> */
> public void setEntry(int row, int column, double value)
> throws MatrixIndexException {
> if (!isValidCoordinate(row,column)) {
> throw new MatrixIndexException("matrix entry does not exist");
> }
> data[row][column] = value;
> lu = null;
> }
> /**
> * Returns the transpose matrix.
> *
> * @return transpose matrix
> */
> public RealMatrix transpose() {
> int nRows = this.getRowDimension();
> int nCols = this.getColumnDimension();
> RealMatrixImpl out = new RealMatrixImpl(nCols, nRows);
> double[][] outData = out.getDataRef();
> for (int row = 0; row < nRows; row++) {
> for (int col = 0; col < nCols; col++) {
> outData[col][row] = data[row][col];
> }
> }
> return out;
> }
> /**
> * Returns the inverse matrix if this matrix is invertible.
> *
> * @return inverse matrix
> * @throws InvalidMatrixException if this is not invertible
> */
> public RealMatrix inverse() throws InvalidMatrixException {
> return solve(getIdentity(this.getRowDimension()));
> }
> /**
> * @return determinant
> * @throws InvalidMatrixException if matrix is not square
> */
> public double getDeterminant() throws InvalidMatrixException {
> if (!isSquare()) {
> throw new InvalidMatrixException("matrix is not square");
> }
> if (isSingular()) { // note: this has side effect of attempting LU
> decomp if lu == null
> return 0d;
> } else {
> double det = parity;
> for (int i = 0; i < this.getRowDimension(); i++) {
> det *= lu[i][i];
> }
> return det;
> }
> }
> /**
> * @return true if the matrix is square (rowDimension = columnDimension)
> */
> public boolean isSquare() {
> return (this.getColumnDimension() == this.getRowDimension());
> }
> /**
> * @return true if the matrix is singular
> */
> public boolean isSingular() {
> if (lu == null) {
> try {
> luDecompose();
> return false;
> } catch (InvalidMatrixException ex) {
> return true;
> }
> } else { // LU decomp must have been successfully performed
> return false; // so the matrix is not singular
> }
> }
> /**
> * @return rowDimension
> */
> public int getRowDimension() {
> return data.length;
> }
> /**
> * @return columnDimension
> */
> public int getColumnDimension() {
> return data[0].length;
> }
> /**
> * @return trace
> * @throws IllegalArgumentException if the matrix is not square
> */
> public double getTrace() throws IllegalArgumentException {
> if (!isSquare()) {
> throw new IllegalArgumentException("matrix is not square");
> }
> double trace = data[0][0];
> for (int i = 1; i < this.getRowDimension(); i++) {
> trace += data[i][i];
> }
> return trace;
> }
> /**
> * @param v vector to operate on
> * @throws IllegalArgumentException if columnDimension != v.length
> * @return resulting vector
> */
> public double[] operate(double[] v) throws IllegalArgumentException {
> if (v.length != this.getColumnDimension()) {
> throw new IllegalArgumentException("vector has wrong length");
> }
> int nRows = this.getRowDimension();
> int nCols = this.getColumnDimension();
> double[] out = new double[v.length];
> for (int row = 0; row < nRows; row++) {
> double sum = 0;
> for (int i = 0; i < nCols; i++) {
> sum += data[row][i] * v[i];
> }
> out[row] = sum;
> }
> return out;
> }
> /**
> * @param v vector to premultiply by
> * @throws IllegalArgumentException if rowDimension != v.length
> * @return resulting matrix
> */
> public double[] preMultiply(double[] v) throws IllegalArgumentException {
> int nRows = this.getRowDimension();
> if (v.length != nRows) {
> throw new IllegalArgumentException("vector has wrong length");
> }
> int nCols = this.getColumnDimension();
> double[] out = new double[nCols];
> for (int col = 0; col < nCols; col++) {
> double sum = 0;
> for (int i = 0; i < nRows; i++) {
> sum += data[i][col] * v[i];
> }
> out[col] = sum;
> }
> return out;
> }
> /**
> * Returns a matrix of (column) solution vectors for linear systems with
> * coefficient matrix = this and constant vectors = columns of
> * <code>b</code>.
> *
> * @param b array of constant forming RHS of linear systems to
> * to solve
> * @return solution array
> * @throws IllegalArgumentException if this.rowDimension != row dimension
> * @throws InvalidMatrixException if this matrix is not square or is singular
> */
> public double[] solve(double[] b) throws IllegalArgumentException,
> InvalidMatrixException {
> int nRows = this.getRowDimension();
> if (b.length != nRows) {
> throw new IllegalArgumentException("constant vector has wrong length");
> }
> RealMatrix bMatrix = new RealMatrixImpl(b);
> double[][] solution = ((RealMatrixImpl) (solve(bMatrix))).getDataRef();
> double[] out = new double[nRows];
> for (int row = 0; row < nRows; row++) {
> out[row] = solution[row][0];
> }
> return out;
> }
> /**
> * Returns a matrix of (column) solution vectors for linear systems with
> * coefficient matrix = this and constant vectors = columns of
> * <code>b</code>.
> *
> * @param b matrix of constant vectors forming RHS of linear systems to
> * to solve
> * @return matrix of solution vectors
> * @throws IllegalArgumentException if this.rowDimension != row dimension
> * @throws InvalidMatrixException if this matrix is not square or is singular
> */
> public RealMatrix solve(RealMatrix b) throws IllegalArgumentException,
> InvalidMatrixException {
> if (b.getRowDimension() != this.getRowDimension()) {
> throw new IllegalArgumentException("Incorrect row dimension");
> }
> if (!this.isSquare()) {
> throw new InvalidMatrixException("coefficient matrix is not square");
> }
> if (this.isSingular()) { // side effect: compute LU decomp
> throw new InvalidMatrixException("Matrix is singular.");
> }
> int nCol = this.getColumnDimension();
> int nColB = b.getColumnDimension();
> int nRowB = b.getRowDimension();
> // Apply permutations to b
> double[][] bv = b.getData();
> double[][] bp = new double[nRowB][nColB];
> for (int row = 0; row < nRowB; row++) {
> for (int col = 0; col < nColB; col++) {
> bp[row][col] = bv[permutation[row]][col];
> }
> }
> bv = null;
> // Solve LY = b
> for (int col = 0; col < nCol; col++) {
> for (int i = col + 1; i < nCol; i++) {
> for (int j = 0; j < nColB; j++) {
> bp[i][j] -= bp[col][j] * lu[i][col];
> }
> }
> }
> // Solve UX = Y
> for (int col = nCol - 1; col >= 0; col--) {
> for (int j = 0; j < nColB; j++) {
> bp[col][j] /= lu[col][col];
> }
> for (int i = 0; i < col; i++) {
> for (int j = 0; j < nColB; j++) {
> bp[i][j] -= bp[col][j] * lu[i][col];
> }
> }
> }
> RealMatrixImpl outMat = new RealMatrixImpl(bp);
> return outMat;
> }
> /**
> * Computes a new
> * <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf">
> * LU decompostion</a> for this matrix, storing the result for use by other
> methods.
> * <p>
> * <strong>Implementation Note</strong>:<br>
> * Uses <a
> href="http://www.damtp.cam.ac.uk/user/fdl/people/sd/lectures/nummeth98/linear.htm">
> * Crout's algortithm</a>, with partial pivoting.
> * <p>
> * <strong>Usage Note</strong>:<br>
> * This method should rarely be invoked directly. Its only use is
> * to force recomputation of the LU decomposition when changes have been
> * made to the underlying data using direct array references. Changes
> * made using setXxx methods will trigger recomputation when needed
> * automatically.
> *
> * @throws InvalidMatrixException if the matrix is non-square or singular.
> */
> public void luDecompose() throws InvalidMatrixException {
> int nRows = this.getRowDimension();
> int nCols = this.getColumnDimension();
> if (nRows != nCols) {
> throw new InvalidMatrixException("LU decomposition requires that the
> matrix be square.");
> }
> lu = this.getData();
> // Initialize permutation array and parity
> permutation = new int[nRows];
> for (int row = 0; row < nRows; row++) {
> permutation[row] = row;
> }
> parity = 1;
> // Loop over columns
> for (int col = 0; col < nCols; col++) {
> double sum = 0;
> // upper
> for (int row = 0; row < col; row++) {
> sum = lu[row][col];
> for (int i = 0; i < row; i++) {
> sum -= lu[row][i] * lu[i][col];
> }
> lu[row][col] = sum;
> }
> // lower
> int max = col; // permutation row
> double largest = 0d;
> for (int row = col; row < nRows; row++) {
> sum = lu[row][col];
> for (int i = 0; i < col; i++) {
> sum -= lu[row][i] * lu[i][col];
> }
> lu[row][col] = sum;
> // maintain best permutation choice
> if (Math.abs(sum) > largest) {
> largest = Math.abs(sum);
> max = row;
> }
> }
> // Singularity check
> if (Math.abs(lu[max][col]) < TOO_SMALL) {
> lu = null;
> throw new InvalidMatrixException("matrix is singular");
> }
> // Pivot if necessary
> if (max != col) {
> double tmp = 0;
> for (int i = 0; i < nCols; i++) {
> tmp = lu[max][i];
> lu[max][i] = lu[col][i];
> lu[col][i] = tmp;
> }
> int temp = permutation[max];
> permutation[max] = permutation[col];
> permutation[col] = temp;
> parity = -parity;
> }
> //Divide the lower elements by the "winning" diagonal elt.
> for (int row = col + 1; row < nRows; row++) {
> lu[row][col] /= lu[col][col];
> }
> }
> }
> /**
> * Gives the means of each row of the matrix.
> * @return the row means
> */
> public double[] rowMeans()
> {
> int rowCount = this.getRowDimension();
> int columnCount = this.getColumnDimension();
> double[] means = new double[rowCount];
> for (int x = 0; x<rowCount; x++)
> {
> for (int y = 0; y<columnCount; y++)
> {
> means[x] += data[x][y]/columnCount;
> }
> }
> return means;
> }
> /**
> * Gives the means of each colums of the matrix.
> * @return the column means
> */
> public double[] columnMeans()
> {
> int rowCount = this.getRowDimension();
> int columnCount = this.getColumnDimension();
> double[] means = new double[columnCount];
> for (int x = 0; x<rowCount; x++)
> {
> for (int y = 0; y<columnCount; y++)
> {
> means[y] += data[x][y]/rowCount;
> }
> }
> return means;
> }
>
> /**
> * Get a submatrix. Rows and columns are indicated counting from 1 to n, NOT
> from 0 to n-1.
> * @param startRow Initial row index
> * @param endRow Final row index
> * @param startColumn Initial column index
> * @param endColumn Final column index
> * @return The subMatrix containing the data of the specified rows and
> columns
> * @exception MatrixIndexException matrix dimension mismatch
> */
> public RealMatrix getSubMatrix (int startRow, int endRow, int startColumn,
> int endColumn)
> throws MatrixIndexException {
> RealMatrixImpl subMatrix = new
> RealMatrixImpl(endRow-startRow+1,endColumn-startColumn+1);
> double[][] subMatrixData = subMatrix.getDataRef();
> try {
> for (int i = startRow; i < endRow; i++) {
> for (int j = startColumn; j < endColumn; j++) {
> subMatrixData[i-startRow][j-startColumn] = data[i][j];
> }
> }
> } catch(ArrayIndexOutOfBoundsException e) {
> throw new MatrixIndexException("matrix dimension mismatch");
> }
> return subMatrix;
> }
> /**
> * Get a submatrix. Rows and columns are indicated counting from 1 to n, NOT
> from 0 to n-1.
> * @param rows Array of row indices.
> * @param columns Array of column indices.
> * @return The subMatrix containing the data of the specified rows and
> columns
> * @exception MatrixIndexException matrix dimension mismatch
> */
> public RealMatrix getSubMatrix (int[] rows, int[] columns)
> throws MatrixIndexException {
> RealMatrixImpl subMatrix = new RealMatrixImpl(rows.length,columns.length);
> double[][] subMatrixData = subMatrix.getDataRef();
> try {
> for (int i = 0; i < rows.length; i++) {
> for (int j = 0; j < columns.length; j++) {
> subMatrixData[i][j] = data[rows[i]][columns[j]];
> }
> }
> } catch(ArrayIndexOutOfBoundsException e) {
> throw new MatrixIndexException("matrix dimension mismatch");
> }
> return subMatrix ;
> }
> /**
> * Get a submatrix. Rows and columns are indicated counting from 1 to n, NOT
> from 0 to n-1.
> * @param startRow Initial row index
> * @param endRow Final row index
> * @param columns Array of column indices.
> * @return The subMatrix containing the data of the specified rows and
> columns
> * @exception MatrixIndexException matrix dimension mismatch
> */
> public RealMatrix getSubMatrix (int startRow, int endRow, int[] columns)
> throws MatrixIndexException {
> RealMatrixImpl subMatrix = new
> RealMatrixImpl(endRow-startRow+1,columns.length);
> double[][] subMatrixData = subMatrix.getDataRef();
> try {
> for (int i = startRow; i < endRow; i++) {
> for (int j = 0; j < columns.length; j++) {
> subMatrixData[i-startRow][j] = data[i][columns[j]];
> }
> }
> } catch(ArrayIndexOutOfBoundsException e) {
> throw new MatrixIndexException("matrix dimension mismatch");
> }
> return subMatrix;
> }
>
> /**
> * Get a submatrix. Rows and columns are indicated counting from 1 to n, NOT
> from 0 to n-1.
> * @param rows Array of row indices.
> * @param startColumn Initial column index
> * @param endColumn Final column index
> * @return The subMatrix containing the data of the specified rows and
> columns
> * @exception MatrixIndexException matrix dimension mismatch
> */
> public RealMatrix getSubMatrix (int[] rows, int startColumn, int endColumn)
> throws MatrixIndexException {
> RealMatrixImpl subMatrix = new
> RealMatrixImpl(rows.length,endColumn-startColumn+1);
> double[][] subMatrixData = subMatrix.getDataRef();
>
> try {
> for (int i = 0; i < rows.length; i++) {
> for (int j = startColumn; j <= endColumn; j++) {
> subMatrixData[i][j-startColumn] = data[rows[i]][j];
> //System.out.println(""+rows[i]+", "+j+": "+data[rows[i]][j]);
> }
> }
> } catch(ArrayIndexOutOfBoundsException e) {
> throw new MatrixIndexException("matrix dimension mismatch");
> }
> return subMatrix;
> }
> /**
> *
> * @see java.lang.Object#toString()
> */
> public String toString() {
> StringBuffer res = new StringBuffer();
> res.append("RealMatrixImpl{");
> for (int i = 0; i < data.length; i++) {
> if (i > 0)
> res.append(",");
> res.append("{");
> for (int j = 0; j < data[0].length; j++) {
> if (j > 0)
> res.append(",");
> res.append(data[i][j]);
> } //for
> res.append("}");
> } //for
> res.append("}");
> return res.toString();
> } //toString
> //------------------------ Protected methods
> /**
> * Returns <code>dimension x dimension</code> identity matrix.
> *
> * @param dimension dimension of identity matrix to generate
> * @return identity matrix
> */
> protected RealMatrix getIdentity(int dimension) {
> RealMatrixImpl out = new RealMatrixImpl(dimension, dimension);
> double[][] d = out.getDataRef();
> for (int row = 0; row < dimension; row++) {
> for (int col = 0; col < dimension; col++) {
> d[row][col] = row == col ? 1d : 0d;
> }
> }
> return out;
> }
> /**
> * Returns the LU decomposition as a RealMatrix.
> * Returns a fresh copy of the cached LU matrix if this has been computed;
> * otherwise the composition is computed and cached for use by other methods.
> * Since a copy is returned in either case, changes to the returned matrix
> do not
> * affect the LU decomposition property.
> * <p>
> * The matrix returned is a compact representation of the LU decomposition.
> * Elements below the main diagonal correspond to entries of the "L" matrix;
> * elements on and above the main diagonal correspond to entries of the "U"
> * matrix.
> * <p>
> * Example: <pre>
> *
> * Returned matrix L U
> * 2 3 1 1 0 0 2 3 1
> * 5 4 6 5 1 0 0 4 6
> * 1 7 8 1 7 1 0 0 8
> * </pre>
> *
> * The L and U matrices satisfy the matrix equation LU = permuteRows(this), <br>
> * where permuteRows reorders the rows of the matrix to follow the order
> determined
> * by the <a href=#getPermutation()>permutation</a> property.
> *
> * @return LU decomposition matrix
> * @throws InvalidMatrixException if the matrix is non-square or singular.
> */
> protected RealMatrix getLUMatrix() throws InvalidMatrixException {
> if (lu == null) {
> luDecompose();
> }
> return new RealMatrixImpl(lu);
> }
> /**
> * Returns the permutation associated with the lu decomposition.
> * The entries of the array represent a permutation of the numbers 0, ... ,
> nRows - 1.
> * <p>
> * Example:
> * permutation = [1, 2, 0] means current 2nd row is first, current third row
> is second
> * and current first row is last.
> * <p>
> * Returns a fresh copy of the array.
> *
> * @return the permutation
> */
> protected int[] getPermutation() {
> int[] out = new int[permutation.length];
> System.arraycopy(permutation, 0, out, 0, permutation.length);
> return out;
> }
> //------------------------ Private methods
> /**
> * Returns a fresh copy of the underlying data array.
> *
> * @return a copy of the underlying data array.
> */
> private double[][] copyOut() {
> int nRows = this.getRowDimension();
> double[][] out = new double[nRows][this.getColumnDimension()];
> // can't copy 2-d array in one shot, otherwise get row references
> for (int i = 0; i < nRows; i++) {
> System.arraycopy(data[i], 0, out[i], 0, data[i].length);
> }
> return out;
> }
> /**
> * Replaces data with a fresh copy of the input array.
> *
> * @param in data to copy in
> */
> private void copyIn(double[][] in) {
> int nRows = in.length;
> int nCols = in[0].length;
> data = new double[nRows][nCols];
> System.arraycopy(in, 0, data, 0, in.length);
> for (int i = 0; i < nRows; i++) {
> System.arraycopy(in[i], 0, data[i], 0, nCols);
> }
> lu = null;
> }
> /**
> * Tests a given coordinate as being valid or invalid
> *
> * @param row the row index.
> * @param col the column index.
> * @return true if the coordinate is with the current dimensions
> */
> private boolean isValidCoordinate(int row, int col) {
> int nRows = this.getRowDimension();
> int nCols = this.getColumnDimension();
> return !(row < 0 || row > (nRows-1) || col < 0 || col > (nCols-1));
> }
> }
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org