You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by "Henri Yandell (JIRA)" <ji...@apache.org> on 2007/02/15 10:38:05 UTC

[jira] Reopened: (MATH-122) New methods in RealMatrixImpl and changing indexing

     [ https://issues.apache.org/jira/browse/MATH-122?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Henri Yandell reopened MATH-122:
--------------------------------


> New methods in RealMatrixImpl and changing indexing
> ---------------------------------------------------
>
>                 Key: MATH-122
>                 URL: https://issues.apache.org/jira/browse/MATH-122
>             Project: Commons Math
>          Issue Type: Improvement
>    Affects 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.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org